Уровни абстракции. Создание кастомных элементов.

Уровни абстракции

В автоматизации часто применяются следующие абстракции:
  • Page Object
  • Page Element
Паттерн Page Object хорошо зарекомендовал себя в автоматизации. Основная идея – инкапсулировать логику поведения страницы в классе страницы. Таким образом, тесты будут работать не с низкоуровневым кодом, а с высокоуровневой абстракцией.
Плюсы Page Object:
  • Разделение полномочий: вся логика страницы описывается в Page Object классах, а тестовые классы лишь используют их публичные методы и проверяют результат.
  • DRY – все локаторы помещаются в одном месте
  • Инкапсуляция работы с драйвером. Полезно при кросс-браузерном тестировании
  • Page Objects позволяет записать локаторы в декларативном стиле
В классическом варианте паттерн предполагает создание одного класса на одну страницу. Это может быть неудобно в ряде случаев:
  • Использование кастомных элементов при создании веб-приложений
  • Присутствие кастомных элементов на многих страницах
В решении этой проблемы может помочь использование наследования, но агрегация видится предпочтительнее. Поэтому лучше воспользоваться паттерном – Page Element. Page Elements – позволяет дробить страницу на более мелкие составляющие – блоки, виджеты и т.д. После чего эти блоки можно переиспользовать в нескольких страницах.

Кастомные элементы

WebDriver очень мощный инструмент, который позволяет выполнять различные действия над элементами страниц. Для этого используется класс WebElement. Но, как и всегда, не все так просто и замечательно. На практике автоматизаторы сталкиваются с тем, что разработчики используют кастомные элементы, с которыми класс WebElement не работает. К примеру, возьмем написание тестов для таблиц. Стандартные классы WebDriver не работают с таблицами, потому нам нужно написать свой, в котором мы опишем работу с элементами таблицы (ячейки, строки и т. д.).
1
import java.util.List;
2
3
public class WebTable {
4
private WebElement _webTable;
5
6
public WebTable(WebElement webTable)
7
{
8
set_webTable(webTable);
9
}
10
11
public WebElement get_webTable() {
12
return _webTable;
13
}
14
15
public void set_webTable(WebElement _webTable) {
16
this._webTable = _webTable;
17
}
18
19
public int getRowCount() {
20
List<WebElement> tableRows = _webTable.findElements(By.tagName("tr"));
21
return tableRows.size();
22
}
23
24
public int getColumnCount() {
25
List<WebElement> tableRows = _webTable.findElements(By.tagName("tr"));
26
WebElement headerRow = tableRows.get(0);
27
List<WebElement> tableCols = headerRow.findElements(By.tagName("td"));
28
return tableCols.size();
29
}
30
31
public WebElement getCellEditor(int rowIdx, int colIdx, int editorIdx) {
32
try {
33
List<WebElement> tableRows = _webTable.findElements(By.tagName("tr"));
34
WebElement currentRow = tableRows.get(rowIdx-1);
35
List<WebElement> tableCols = currentRow.findElements(By.tagName("td"));
36
WebElement cell = tableCols.get(colIdx-1);
37
WebElement cellEditor = cell.findElements(By.tagName("input")).get(editorIdx);
38
return cellEditor;
39
} catch (NoSuchElementException e) {
40
throw new NoSuchElementException("Failed to get cell editor");
41
}
42
}
43
}
Copied!