Search code examples
c#automated-testsatata

Atata – Processing table rows is slow


One more question regarding the Atata framework. I've found the loading from tables is slow. There's a table with approx. 1000 rows and whenever I am doing any operation on the retrieved row, it seems that engine loads the table once again.

Example code that is slow:

var row = _page.Inventory.Rows[x => x.Text == "some inventory"];
row.Should.Exist(); // that statement takes the same time as the above one and is slow...

The code I'm using for the table:

[FindByCss(".invGrid")]
public Table<GroupsRow, Page> Inventory { get; set; }

I have tried to find any convenient method to load the data eagerly, but haven't found any.

My questions are:

  1. Is there any way to load the row eagerly?
  2. Is there any way to make the table load faster?

Solution

  • Currently Table.Rows[predicate] works slowly for large tables as it checks each row. It works good for small tables. Probably I will update it to work faster in the future, but it is not so easy, so it is postponed for now. There are another fast approaches that execute single XPath command that you can use:

    1. Use indexer: public TItem this[params string[] cellValues]

      _page.Inventory.Rows["some inventory"]
      

      It will find the first row with the cell containing passed value. But it can be inaccurate as it uses 'contains' predicate and if you have similar string values in the table.

    2. Use method: public TItem GetByXPathCondition(string itemName, string xPathCondition)

      string itemName = "some inventory";
      
      _page.Inventory.Rows.GetByXPathCondition(
          itemName,
          $".//span[contains(concat(' ', normalize-space(@class), ' '), ' item-name ')][normalize-space(.) = '{itemName}']")
      

      The example looks for <tr> that contains <span class="item-name"> with required text.

      This approach is accurate but sytax is more complicated.

    3. You can make the above example easier to use by extracting to extension method:

      public static class TableRowListExtensions
      {
          public static SomePage.GroupsRow GetByName(this TableRowList<SomePage.GroupsRow, SomePage> rowList, string name)
          {
              return rowList.GetByXPathCondition(name, $".//span[contains(concat(' ', normalize-space(@class), ' '), ' item-name ')][normalize-space(.) = '{name}']");
          }
      }
      

      And then use it in the test:

      _page.Inventory.Rows.GetByName("some inventory")
      

      It should be fast and accurate.

    I also recommend you to use [FindByClass("invGrid")] attribute instead of [FindByCss(".invGrid")] when you have CSS selector by single class. FindByCssAttribute works a little bit slower in Atata, as it executes 1 extra WebDriver command comparing to most other find attributes.