如何使用量角器在表中进行迭代以查找特定文本?

时间:2019-03-24 05:22:13

标签: angularjs selenium selenium-webdriver css-selectors protractor

我有一个动态表,该表有2列和n行。在第一列中将有一个标题,在第二列中将是进入该标题详细信息的按钮。

我想遍历每一行以查找特定的文本标题,然后单击该标题的第二列按钮。

我尝试了多种搜索google的方法,但是找不到任何东西。

HTML中的AngularJS代码如下。

    let elm = element.all(by.repeater('registration in myRegistrations'));
    let index;
    elm.getText().then(function(text){
        console.log(text);
        for(var i=0; i<text.length; i++){
            if(text[i] == 'protractor-testing Enter community'){
                index = i;
                console.log('Community found :: ' + text[i]);
            }    
        }

    });

    console.log("Index :: " + index);

如上表所示,有三行。我想按名称选择假设“ test1”的行,并单击同一行的第二列按钮。

在这里,通过编写以下代码,我得到了要查找的特定文本的索引。

// An example configuration file
var Jasmine2HtmlReporter = require('protractor-jasmine2-html-reporter');
exports.config = {
    // The address of a running selenium server.
    seleniumAddress: 'http://localhost:4444/wd/hub',

    baseUrl: 'http://localhost:' + (process.env.PORT || '9000'),
    // Capabilities to be passed to the webdriver instance.
    capabilities: {
      browserName: 'chrome'
    },

    params: {
      Firstname: 'virus',
      Lastname: 'virus',
      Email: 'virus@email.com',
      Username: 'virus',
      Password: 'virus',
      TempUsername : 'temp',
      TempPassword: 'temp',
      AdminUsername: 'admin',
      AdminPassword: 'admin',
      CreateTitle: 'protractor-testing',
      CreateKey: 'protractor-testing'
    },
    // Spec patterns are relative to the configuration file location passed
    // to protractor (in this example conf.js).
    // They may include glob patterns.
    // specs: ['../spec/2 Login/spec.js'],
    suites: {
      login: '../spec/2 Login/spec.js'
    },

    // Options to be passed to Jasmine-node.
    jasmineNodeOpts: {
      showColors: true, // Use colors in the command line report.
    },

    // onPrepare: function(){
    //   jasmine.getEnv().addReporter(new Jasmine2HtmlReporter({
    //     savePath: '../test/reports'
    //   })
    //   );
    // },
  };

现在,通过该索引,我可以单击表row =索引和同一行的第二列中的按钮吗?

下面是我的整个剧本。

conf.js文件..

describe('Testing', function(){
    it('perform login', function() {}
        browser.get(browser.baseUrl);
        browser.manage().window().maximize();
        console.log("Admin :: " + browser.params.AdminUsername + " " + browser.params.AdminPassword);
        element(by.model('user.userName')).sendKeys(browser.params.AdminUsername);
        element(by.model('user.password')).sendKeys(browser.params.AdminPassword);
        browser.sleep('2000');
        element(by.buttonText('Login')).click();
        element(by.model("newCommunity.title")).sendKeys(browser.params.CreateTitle);
        element(by.model("newCommunity.key")).sendKeys(browser.params.CreateKey);
        let buttons = element.all(by.css("button.ng-binding"));
        let tds = element.all(by.css("td.ng-binding"));
        console.log("Buttons :: " + buttons);
        console.log("tds :: " + tds);
        // var buttons = driver.findElements(By.css("button.ng-binding"));
        // var tds = driver.findElements(By.css("td.ng-binding"));
        for (var i = 0; i < tds.length; i++) {
            console.log("get text for index " + i + " Value :: " + tds[i].getText());
            if (tds[i].getText() == 'protractor-testing') {
                console.log("Got the actual community at : " + i);
                console.log("Clicking button :: " + buttons[i]);
                buttons[i].click();
                break;
            }
        }

    });
})

下面是我的spec.js文件

import ssl

try:
   _create_unverified_https_context = ssl._create_unverified_context
except AttributeError:
    # Legacy Python that doesn't verify HTTPS certificates by default
    pass
else:
    # Handle target environment that doesn't support HTTPS verification
    ssl._create_default_https_context = _create_unverified_https_context

请注意,我不想使用xPath。

4 个答案:

答案 0 :(得分:1)

一件事,如果可以控制的话,我个人不会在同一页面上具有相同的元素(就HTML而言)。但是要使您的元素显示在显示的HTML上,应该可以进行以下操作:                           (由于您的量角器标签,我正在编写Javascript,我假设那是您编写测试的方式)

buttons = driver.findElements(By.xpath("//button"))
buttons[1].click();

但是,如果您想按名称(对于任何用例)专门找到它,

buttonWithText1 = driver.findElement(By.xpath("//td[text()[contains(., 'test1')]]/following-sibling::td/button");
buttonWithText1.click();

正如@Sers指出的,xpath //td[.='test1']/following-sibling::td/button也可以使用,并且是最干净的。或至少最短。

如果您想动态地使用该xpath通过该文本查找按钮,则可以使用:

var myText = "test1"
driver.findElement(By.xpath("//td[.='" + myText + "']/following-sibling::td/button).click()

编辑

用户已经说过,他们不想使用xpath。根据HTML,您可以使用CSS选择器来选择字符串myText旁边的按钮。

var buttons = browser.findElements(By.css(‘button.ng-binding’))
var tds = browser.findElements(By.css(‘td.ng-binding’))
for (i = 0; i < tds.length; i++) {
    if (tds[i].getText()==myText) {
        buttons[i].click()
        break;
    }
}

答案 1 :(得分:1)

您不使用xpath的要求似乎非常严格,因为到目前为止,这是针对您的用例的最佳方法,主要是因为基于CSS定位不允许您对标记文本进行精确匹配,您的标题是<td>

要使用CSS实现此目的,您将必须使用一些可能不可靠的链式定位器,例如

element(by.cssContainingText('tr','test')).element(by.css('button'));

我说这是不可靠的,因为该定位器实际上会识别出您的所有三个按钮,因为您的所有三个标题标签都包含字符“ test”。在这种情况下可以使用,但可能会在实际测试中引起问题。

我将强烈建议不要使用xpath并建议使用C Peck提供的以下同级答案,因为这将是最可靠的长期方法。

答案 2 :(得分:-1)

您可以使用xpath实现您的目标:

//tr[contains(@class,'tableRow') and ./td[.='test']]//button

您可以找到更多示例here

答案 3 :(得分:-1)

您不想使用并限制innerHTML的引用<td>节点的所有其他属性值是相同的。现在不支持innerHTML,因此要在文本为 test1 的元素旁边找到 button ,可以使用以下 css-选择器

"table>tbody tr:nth-child(2) td:nth-child(2)>button"