Как перебрать <td>в таблице, чтобы найти конкретный текст с помощью транспортира? - PullRequest
0 голосов
/ 24 марта 2019

У меня есть динамическая таблица с 2 столбцами и n числом строк. В первом столбце будет заголовок, а во втором столбце будет кнопка для перехода к деталям этого заголовка.

Я хочу пройтись по каждой строке, чтобы найти конкретный текстовый заголовок, и нажать на кнопку второго столбца с этим заголовком.

Я пробовал много способов поиска в Google, но ничего не смог найти.

Код AngularJS для этого в HTML такой, как показано ниже.

<table>
        <tbody>
            <tr ng-repeat="registration in Registrations | orderBy:'title'" class="tableRow ng-scope">
                <td style="padding-left: 20px;" ng-if="reg.title != 'Jabc'" class="ng-binding ng-scope">test</td>
            <td style="padding-left: 20px;">
                <button ng-click="enter(registration)" class="ng-binding">Enter community</button>
            </td>


            <tr ng-repeat="registration in Registrations | orderBy:'title'" class="tableRow ng-scope">
                <td style="padding-left: 20px;" ng-if="reg.title != 'Jabc'" class="ng-binding ng-scope">test1</td>
            <td style="padding-left: 20px;">
                <button ng-click="enter(registration)" class="ng-binding">Enter community</button>
            </td>



            <tr ng-repeat="registration in Registrations | orderBy:'title'" class="tableRow ng-scope">
                <td style="padding-left: 20px;" ng-if="reg.title != 'Jabc'" class="ng-binding ng-scope">test2</td>
            <td style="padding-left: 20px;">
                <button ng-click="enter(registration)" class="ng-binding">Enter community</button>
            </td>
    </tbody>
</table>

Как показано в приведенной выше таблице, есть три строки.Я хочу выбрать строку по имени для предположения «test1» и хочу нажать на кнопку второго столбца той же строки.

Здесь я получил индекс конкретного текста, который я ищу, написавкод ниже.

    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);

Теперь по этому индексу я могу нажать на кнопку из строки таблицы = индекс и второй столбец той же строки?

Ниже весь мой сценарий.

Файл conf.js ..

// 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'
    //   })
    //   );
    // },
  };

Ниже приведен мой файл spec.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;
            }
        }

    });
})

Обратите внимание, что я не хочу использовать xPath.

Ответы [ 4 ]

1 голос
/ 25 марта 2019

Ваше требование не использовать xpath кажется очень ограничительным, так как это, безусловно, лучший метод для вашего случая использования, в основном потому, что определение местоположения на основе css не позволяет вам точно сопоставить текст тега , вв вашем случае заголовок <td> s.

Для достижения этой цели с помощью CSS вы должны будете использовать некоторые потенциально ненадежные цепочечные локаторы, такие как

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

Я говорю ненадежно, так как этот локатор будет фактически идентифицироватьвсе три ваши кнопки из-за того, что все три ваших тега заголовка содержат символы «тест».Это работает в этом случае, но может вызвать проблемы в ваших реальных тестах.

Я бы настоятельно рекомендовал отменить это требование xpath и перейти к следующему братскому ответу, предоставленному C Peck, поскольку это будет наиболее надежный долгосрочный период.

1 голос
/ 24 марта 2019

Ну, во-первых, я бы лично не имел идентичных элементов (с точки зрения 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;
    }
}
0 голосов
/ 25 марта 2019

Вы не хотите использовать и, за исключением innerHTML, все остальные значения атрибутов ссылочных <td> узлов идентичны. Теперь не поддерживает innerHTML, поэтому, чтобы найти кнопку рядом с элементом с текстом как test1 , вы можете использовать следующее CSS-селекторы

"table>tbody tr:nth-child(2) td:nth-child(2)>button"
0 голосов
/ 24 марта 2019

Вы можете использовать xpath для достижения своей цели:

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

Вы можете найти больше примеров здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...