C# / ATATA / Selenium: использование ControlList для хранения нескольких таблиц

Я создаю объект Page для своей компании, который представляет HTML-страницу, которая содержит много таблиц (и плохо структурирована). Меня интересуют только некоторые таблицы на этой странице, и я хотел бы иметь одну таблицу для ссылки на мой объект страницы для простоты.

Проблемы

  1. Эта страница является динамичной и загружает различные таблицы.
  2. "Отображаемая таблица" одного рабочего процесса разделена на 3 таблицы в HTML.
    1. Таблица 1 содержит уникальный идентификатор.
    2. Таблица 2 содержит кнопки, которые меня не интересуют.
    3. Таблица 3 (обернутая в div) содержит фактические данные таблицы, которые мне нужно получить.
  3. Таблицы не организованы, не сгруппированы или не вложены каким-либо образом.
    1. Единственная организация - повторяющаяся плоская структура "отображаемой таблицы". Структура не меняется (генерируется из ASP.Net)

цели

  1. Иметь ControlList, который представляет каждую из "отображаемых таблиц".
  2. Придерживайтесь ATATA (у меня есть решение Selenium для этого, но большинство наших объектов Page используют ATATA и не хотят отклоняться)
  3. Сохранить имя рабочего процесса как переменную для каждого из объектов таблицы (переменная 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")]
Другие вопросы по тегам