Доброго времени суток.
Лично я в своей работе использую собственные классы элементов со всеми вытекающими плюсами из этого.
Для этого нужно написать свой декоратор.
В классе вертикальной таблицы у меня определяются элементы следующим образом:
1) Все строки:
public virtual IList<IWebElement> Rows => FindElements(By.CssSelector("tbody tr"));
2) Все столбцы:
public virtual IList<IWebElement> Columns => FindElements(By.CssSelector("tr:first-child th"));
3) Все ячейки:
public virtual IList<IWebElement> Cells => FindElements(By.CssSelector("tbody tr td"));
Здесь надо учитывать то, что поиск элементов происходит от родительского.
Так же использую свой фреймворк, где у меня работают следующие атрибуты:
[BlockTitle("Модальное окно с заказом")]
[FindBy(XPath = "//div[@class = \'modal-content\']")]
[TimeToSearch("block_waiting_timing")]
public class OrderModalBlock : ABlock
{
[FindBy(XPath = "(.//table[preceding::*[contains(text(), \'Заказ\')]]) [1]", ParentElement = "Модальное окно с заказом")]
[ElementTitle("Заказ")]
private AHorizontalTable _orderTable;
...../
}
Соответственно, таблица является дочерним элементом блока элементов.
А элементы внутри таблицы - соответственно дочерними элементами самой таблицы.
Сам локатор для поиска текста в ячейке такой (точка в начале Xpath означает, что поиск нужно осуществлять внутри родительского элемента - это важно, если у вас на странице не одна таблица):
var element = FindElement(By.XPath($".//tbody//tr[{rowId}]//td[contains(text(), \'{textInRow}\')]|.//tbody//tr[{rowId}]//td[*[contains(text(), \'{textInRow}\')]]"));
Такой xpath либо найдет текст в самой ячейке, либо в любом элементе в этой ячейке.
В моём примере, ячейка хранит ссылку, т.е. <td><a...></a></td> - и текст нужно было искать именно в элементе <a>.
Если вам нужно искать текст не смотря на регистр, и у вас XPath 1.0, то можно воспользоваться вспомогательным методом.
Например таким:
public static string ContainsTextIgnoreCase(string text)
{
return
$"text()[contains(translate(., \'ABCDEFGHIJKLMNOPQRSTUVWXYZЙФЯЦЫЧУВСКАМЕПИНРТГОЬШЛБЩДЮЗЖХЭЪ\', \'abcdefghijklmnopqrstuvwxyzйфяцычувскамепинртгоьшлбщдюзжхэъ\'), \'{text.ToLower()}\')]/parent::*";
}