C# / ATATA / Selenium: использование ControlList для хранения нескольких таблиц
Я создаю объект Page для своей компании, который представляет HTML-страницу, которая содержит много таблиц (и плохо структурирована). Меня интересуют только некоторые таблицы на этой странице, и я хотел бы иметь одну таблицу для ссылки на мой объект страницы для простоты.
Проблемы
- Эта страница является динамичной и загружает различные таблицы.
- "Отображаемая таблица" одного рабочего процесса разделена на 3 таблицы в HTML.
- Таблица 1 содержит уникальный идентификатор.
- Таблица 2 содержит кнопки, которые меня не интересуют.
- Таблица 3 (обернутая в div) содержит фактические данные таблицы, которые мне нужно получить.
- Таблицы не организованы, не сгруппированы или не вложены каким-либо образом.
- Единственная организация - повторяющаяся плоская структура "отображаемой таблицы". Структура не меняется (генерируется из ASP.Net)
цели
- Иметь ControlList, который представляет каждую из "отображаемых таблиц".
- Придерживайтесь ATATA (у меня есть решение Selenium для этого, но большинство наших объектов Page используют ATATA и не хотят отклоняться)
- Сохранить имя рабочего процесса как переменную для каждого из объектов таблицы (переменная WorkflowName)
Вот абстракция HTML-кода, с которым я работаю.
<div>
<table> <!-- Start of Displayed Table. Shows as a single row header -->
<tbody>
<tr>
<td>
<h2 id='WorkflowHeader'> Workflow Identifier </h2>
</td>
</tr>
</tbody>
</table>
<table>
<!-- This table contains buttons that I am not concerned with -->
</table>
<div>
<table> <!-- Start of multi row table that contains data to be retrieved -->
<tr>
<td>Value I want in a table</td>
<td>Value I want in a table</td>
</tr>
</table>
<br /> <!-- End of "Displayed Table" -->
<!-- The above structure repeats for every Workflow type. basic structure below -->
<table></table>
<table></table>
<div>
<table></table>
</div>
<br />
<!-- Basic repeating table structure above -->
</div>
В моем объекте страницы ATATA у меня есть следующее:
using Atata;
using _ = ProjectNameSpace.WorkflowPageObject;
namespace ProjectNameSpace
{
public class WorkflowPageObject : Page<_>
{
public ControlList<WorkflowTable, _> WorkflowTables { get; private set; }
[ControlDefinition("h2[contains(@id, 'WorkflowHeader')]/../../../../following-sibling::div/table", ComponentTypeName = "table")]
public class WorkflowTable: Table<WorkflowRow, _>
{
[FindByXPath("h2[contains(@id, 'WorkflowHeader')]")]
public H2<_> WorkflowName { get; private set; }
}
[ControlDefinition("h2[contains(@id, 'WorkflowHeader')]/../../../../following-sibling::div/table/tbody/tr"), ComponentTypeName = "row")]
public class WorkflowRow: TableRow<_>
{
[FindByColumnHeader(HeaderName1)]
public Content<string, _> TableData1 { get; private set; }
[FindByColumnHeader(HeaderName2)]
public Content<string, _> TableData2 { get; private set; }
[FindByColumnHeader(HeaderName3)]
public Content<string, _> TableData3 { get; private set; }
[FindByColumnHeader(HeaderName4)]
public Content<string, _> TableData4 { get; private set; }
[FindByColumnHeader(HeaderName5)]
public Content<string, _> TableData5 { get; private set; }
[FindByColumnHeader(HeaderName6)]
public Content<string, _> TableData { get; private set; }
}
}
}
Когда я попадаю на эту страницу и пытаюсь получить доступ к любому из TableData, я получаю следующую ошибку:
{"Unable to locate element: By.XPath: (.//h2[contains(@id,
'WorkflowHeader')]/../../../../following-sibling::div/table/tbody/tr)
[1]\r\nContext element:\r\nTag: table\r\nLocation: {X=X,Y=Y}\r\nSize:
{Width=Width, Height=Height}\r\nText: HeaderName1 HeaderName2 HeaderName3
HeaderName4 HeaderName5 HeaderName6\r\nTableData1 TableData2 TableData3
TableData4 TableData5 TableData6"}
Я чувствую, что не правильно использую ControlDefinitions. Мой XPath - это звук и возвращает несколько элементов. Если я извлечу XPath, который используется, чтобы найти элемент и использовать AtataContext.Current.Driver.FindElementsByXPath(".//h2[contains(@id, 'WorkflowHeader')]/../../../../following-sibling::div/table/tbody/tr")[1]
правильные строки возвращаются.
Примечание. Этот код был запутан, и любые ошибки в написании переменных или опечаток наиболее вероятны из-за того, что в этом посте вручную были введены части кода. Код строится и работает.
Любая помощь с благодарностью.
1 ответ
Я предполагаю, что вам не нужно ControlDefinition
в WorkflowRow
учебный класс. Просто удалите его и попробуйте. Когда вы находите строки таблицы, она уже имеет соответствующую область <table>
элемент и ищет дочерние элементы (строки) внутри этого элемента, а не всю страницу.
Я также могу порекомендовать вам обновить ControlDefinition
из WorkflowTable
к следующему:
[ControlDefinition("table[.//h2[contains(@id, 'WorkflowHeader')]]", ComponentTypeName = "table")]