мы используем protractorjs и узел для нашей автоматизации тестирования. так как у нас есть два веб-приложения, одно с обращением к клиенту, которое является приложением ReactJS, которое имеет очень реактивные элементы по отношению к тем, которые мы используем в этой среде. В приложении, обращенном к агенту, у нас есть страница с обычной HTML-таблицей. я пытался сопоставить текст по своему выбору и дважды щелкнуть по нему, чтобы открыть окно модели. мне удалось найти количество строк в таблице, но я не смог найти точную строку по своему выбору. может ли кто-нибудь помочь мне в этом с любыми функциями protractorjs.
в этом случае мне нужно перейти к «ETHBTC» и дважды щелкнуть по нему, чтобы открыть его детали в новом всплывающем окне модели.
Элемент страницы
<table class="table">
<thead>
<tr>
<th>Instrument ID</th>
<th>Symbol</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>BTCUSD</td>
<td>Running</td>
<tr>
<td>2</td>
<td>ETHBTC</td>
<td>Running</td>
<tr>
<td>3</td>
<td>ETHGBP</td>
<td>Running</td>
</tr>
</tbody>
</table>
изображение на экране

Код:
после получения количества строк не знаю, как пройти к нужной строке и выбрать ее. я знаю, что мы должны использовать цикл для обхода, но не знаю, как соответствовать ожидаемому.
const service_table = element(by.css('.table'))
let table_rows = service_table.element.all(by.tagName('tbody')).all(by.tagName('tr'))
let rows_count = table_rows.count()
ОБНОВЛЕНО
вот мой полный метод для двойного щелчка по активности в строке таблицы
async open_exchange_service(data) {
await browser.sleep(1000)
const service_table = await element(by.css('.table'));
const table_row = await service_table.element(by.cssContainingText('tbody tr td', data));
try {
console.log('i am in tryyyyyyyy loooppppp')
await browser.actions().click(table_row).perform().then(() => browser.actions().click(table_row).perform());
// await browser.actions().
// mouseMove(table_row).
// doubleClick().
// perform();
// await browser.actions().
// mouseMove(table_row).
// doubleClick().
// perform();
} catch (error) {
console.log('i am in catchhhhhh looppppp')
const service_table = await element(by.css('.table'));
const table_row = await service_table.element(by.cssContainingText('tbody tr td', data));
await browser.actions().click(table_row).perform().then(() => browser.actions().click(table_row).perform());
// await browser.actions().
// mouseMove(table_row).
// doubleClick().
// perform();
// await browser.actions().
// mouseMove(table_row).
// doubleClick().
// perform();
}
}
async open_exchange_instrument(data) {
await browser.sleep(1000)
const service_table = await element(by.css('.table'));
const table_row = await service_table.element(by.cssContainingText('tbody tr td', data));
try {
console.log('i am in tryyyyyyyy loooppppp')
await browser.actions().click(table_row).perform().then(() => browser.actions().click(table_row).perform());
// await browser.actions().doubleClick(table_row).perform();
// await browser.actions().doubleClick(table_row).perform();
} catch (error) {
console.log('i am in catchhhhhh looppppp')
await browser.sleep(500)
const service_table = await element(by.css('.table'));
const table_row = await service_table.element(by.cssContainingText('tbody tr td', data));
await browser.executeScript('arguments[0].scrollIntoView(true);', table_row);
await browser.actions().click(table_row).perform().then(() => browser.actions().click(table_row).perform());
// await browser.actions().doubleClick(table_row).perform();
// await browser.actions().doubleClick(table_row).perform();
}
}