Фреймворк Html Elements      или как удобно   взаимодействовать свеб-интерфейсами в тестах      Александр Толмачев
Yandex QA Tools          2
Yandex QA Tools          2
3
WebDriver    3
WebDriver         Бонус  Java    3
Эволюция   4
Пример теста          5
Пример теста   SQA Days              5
Пример теста   SQA Days              5
Пример теста          6
Пример теста          6
Первый тест         7
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    @Before    public void loa...
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    @Before    public void loa...
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    @Before    public void loa...
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    @Before    public void loa...
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    @Before    public void loa...
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    @Before    public void loa...
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    @Before    public void loa...
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    @Before    public void loa...
Недостатки             9
Недостатки      Читаемость   Переиспользование      Поддержка             9
Page Object          10
Страница           11
Page Objectpublic class SearchPage {    @FindBy(id = "text")    private WebElement requestInput;    @FindBy(xpath = "//inp...
Page Objectpublic class SearchPage {    @FindBy(id = "text")    private WebElement requestInput;    @FindBy(xpath = "//inp...
Page Objectpublic class SearchPage {    @FindBy(id = "text")    private WebElement requestInput;    @FindBy(xpath = "//inp...
Page Objectpublic class SearchPage {    @FindBy(id = "text")    private WebElement requestInput;    @FindBy(xpath = "//inp...
Page Objectpublic class SearchPage {    @FindBy(id = "text")    private WebElement requestInput;    @FindBy(xpath = "//inp...
Page Objectpublic class SearchPage {    @FindBy(id = "text")    private WebElement requestInput;    @FindBy(xpath = "//inp...
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    private SearchPage searchP...
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    private SearchPage searchP...
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    private SearchPage searchP...
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    private SearchPage searchP...
Код тестаpublic class SearchResultsTest {    private WebDriver driver = new FirefoxDriver();    private SearchPage searchP...
Дублирование         14
Дублирование         14
Дублирование         14
Дублирование         14
Дублирование         14
Дублирование         14
Дублирование         14
Дублирование         14
Загромождение         15
Загромождениеpublic class AutoHomePage {    @FindBy(name = "text")    private WebElement requestInput;    @FindBy(xpath = ...
Загромождение     public class AutoHomePage {         @FindBy(name = "text")         private WebElement requestInput;     ...
Загромождение       public class AutoHomePage {           @FindBy(name = "text")           private WebElement requestInput...
Отсутствие типизации           17
Отсутствие типизации           17
Отсутствие типизации                      Select                selectByIndex()                selectByValue()            ...
Отсутствие типизацииpublic class PageWithSelect {    @FindBy(xpath = "select-xpath")    private WebElement select;    publ...
Отсутствие типизацииpublic class PageWithSelect {    @FindBy(xpath = "select-xpath")    private WebElement select;    publ...
Отсутствие типизацииpublic class PageWithSelect {    @FindBy(xpath = "select-xpath")    private WebElement select;    publ...
Отсутствие типизацииpublic class PageWithSelect {    @FindBy(xpath = "select-xpath")    private Select select;    public P...
Отсутствие типизацииpublic class PageWithSelect {    @FindBy(xpath = "select-xpath")    private Select select;    public P...
Недостатки             19
Недостатки    Дублирование кода             19
Недостатки    Дублирование кода     Загромождение             19
Недостатки    Дублирование кода     Загромождение   Отсутствие типизации             19
20
Html Elements      20
Блоки элементовТипизация элементовБиблиотека матчеров         21
Блоки элементовТипизация элементовБиблиотека матчеров         22
Структура страницы          23
Структура страницы          23
Поисковая форма@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement {    @FindBy(id = ...
Поисковая форма@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement {    @FindBy(id = ...
Поисковая форма                                              Селектор блока@Block(@FindBy(className = "b-head-search"))pub...
Поисковая форма                                              Селектор блока@Block(@FindBy(className = "b-head-search"))pub...
Поисковая форма                                              Селектор блока@Block(@FindBy(className = "b-head-search"))pub...
Форма авторизации@Block(@FindBy(className = "b-domik"))public class AuthorizationForm extends HtmlElement {    @FindBy(nam...
Главная страницаpublic class SearchPage {    private SearchArrow searchArrow;    private AuthorizationForm authorizationFo...
Главная страницаpublic class SearchPage {    private SearchArrow searchArrow;    private AuthorizationForm authorizationFo...
Главная страницаpublic class SearchPage {    private SearchArrow searchArrow;    private AuthorizationForm authorizationFo...
Главная страницаpublic class SearchPage {    private SearchArrow searchArrow;    private AuthorizationForm authorizationFo...
Главная страницаpublic class SearchPage {    private SearchArrow searchArrow;    private AuthorizationForm authorizationFo...
Структура            27
Контекст поиска@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement {    @FindBy(id = ...
Контекст поиска                                              Селектор блока@Block(@FindBy(className = "b-head-search"))pub...
Контекст поискаpublic class SearchResultsPage {    @FindBy(className = "b-search")    private SearchArrow searchArrow;    ...
Контекст поискаpublic class SearchResultsPage {                                          Переопределение    @FindBy(classN...
Блоки элементовТипизация элементовБиблиотека матчеров         30
Типизация            31
Типизация    SQA            31
Типизация    SQA            32
Поисковая форма@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement {    @FindBy(id = ...
Поисковая форма@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement {    @FindBy(id = ...
Ленивая инициализация@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement {    @FindBy...
Ленивая инициализация@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement {    @FindBy...
Стандартные элементы        Text Input         Button        CheckBox          Radio         Select            35
Добавление элементовpublic class Suggest extends TypifiedElement {    public Suggest(WebElement wrappedElement) {        s...
Добавление элементовpublic class Suggest extends TypifiedElement {    public Suggest(WebElement wrappedElement) {        s...
Добавление элементовpublic class Suggest extends TypifiedElement {    public Suggest(WebElement wrappedElement) {        s...
Добавление элементовpublic class Suggest extends TypifiedElement {    public Suggest(WebElement wrappedElement) {        s...
Добавление элементовpublic class Suggest extends TypifiedElement {    public Suggest(WebElement wrappedElement) {        s...
Добавление элементовpublic class Suggest extends TypifiedElement {    public Suggest(WebElement wrappedElement) {        s...
Конструктор          37
КонструкторТипизированные   элементы                 37
Конструктор             Page-объектТипизированные   элементы                     37
Блоки элементовТипизация элементовБиблиотека матчеров         38
Матчеры          39
МатчерыassertThat(audience, isPayingAttention())                    39
МатчерыassertThat(audience, isPayingAttention())assertThat(audience, is(not(sleeping())))                    39
Наши матчеры         40
Наши матчеры   assertThat(element, exists())                 40
Наши матчеры      assertThat(element, exists())assertThat(element, hasText(“SQA Days”))                    40
Наши матчеры      assertThat(element, exists())assertThat(element, hasText(“SQA Days”))   assertThat(checkBox, isSelected(...
Наши матчеры      assertThat(element, exists())assertThat(element, hasText(“SQA Days”))   assertThat(checkBox, isSelected(...
Матчеры в тестах@Testpublic void shouldSeeSearchResultsWhenLookingUp() {    searchPage.searchFor("SQA Days");    assertTha...
Матчеры в тестах@Testpublic void shouldSeeSearchResultsWhenLookingUp() {    searchPage.searchFor("SQA Days");    assertTha...
Матчеры в тестах@Testpublic void shouldSeeSearchResultsWhenLookingUp() {    searchPage.searchFor("SQA Days");    String me...
Матчеры в тестах@Testpublic void shouldSeeSearchResultsWhenLookingUp() {    searchPage.searchFor("SQA Days");    String me...
Именование элементов@Name("Форма поиска")@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends Html...
Именование элементов@Name("Форма поиска")@Block(@FindBy(className = "b-head-search"))       Имя поpublic class SearchArrow...
Именование элементов@Name("Форма поиска")@Block(@FindBy(className = "b-head-search"))       Имя поpublic class SearchArrow...
Именование элементовpublic class SearchResultsPage {    @FindBy(className = "b-search")    private SearchArrow searchArrow...
Именование элементовpublic class SearchResultsPage {    @FindBy(className = "b-search")    private SearchArrow searchArrow...
Имена в тестах@Testpublic void shouldSeeSearchResultsWhenLookingUp() {    searchPage.searchFor("SQA Days");    String mess...
Блоки элементовТипизация элементовБиблиотека матчеров         47
Жизнь стала такой         48
Будущее   49
Библиотека элементов           50
Библиотека элементов           50
Динамические селекторы@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement {    @FindB...
Динамические селекторы@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement {    @FindB...
Динамические селекторы            52
Динамические селекторы            53
Понятные логи         54
Понятные логи1.Ввожу в элемент “Поисковая строка”текст “SQA Days”...                    54
Понятные логи1.Ввожу в элемент “Поисковая строка”текст “SQA Days”...2.Кликаю на элемент “Кнопка ‘Найти’”...               ...
Понятные логи1.Ввожу в элемент “Поисковая строка”текст “SQA Days”...2.Кликаю на элемент “Кнопка ‘Найти’”...3.Проверяю нали...
Понятные логи1.Ввожу в элемент “Поисковая строка”текст “SQA Days”...2.Кликаю на элемент “Кнопка ‘Найти’”...3.Проверяю нали...
Генерация блоков          55
Генерация блоков  Страница             55
Генерация блоков                  @Block(@FindBy(className = "b-head-search"))                    @Block(@FindBy(className...
И другое многое   будет там             56
57
https://github.com/yandex-qatools/htmlelements                      57
https://github.com/yandex-qatools/htmlelements           qa-tools@yandex-team.ru                      57
Cпасибо   starlight@yandex-team.ru      @alex_tolmachev
Upcoming SlideShare
Loading in …5
×

Фреймворк Html Elements или как удобно взаимодействовать с веб-интерфейсами в тестах

23,914 views
24,973 views

Published on

Презентация с конференции SQA Days-12 о решении недостатков Page Object в WebDriver с помощью фреймворка с открытым исходным кодом Html Elements.

3 Comments
3 Likes
Statistics
Notes
No Downloads
Views
Total views
23,914
On SlideShare
0
From Embeds
0
Number of Embeds
21,691
Actions
Shares
0
Downloads
33
Comments
3
Likes
3
Embeds 0
No embeds

No notes for slide

Фреймворк Html Elements или как удобно взаимодействовать с веб-интерфейсами в тестах

  1. 1. Фреймворк Html Elements или как удобно взаимодействовать свеб-интерфейсами в тестах Александр Толмачев
  2. 2. Yandex QA Tools 2
  3. 3. Yandex QA Tools 2
  4. 4. 3
  5. 5. WebDriver 3
  6. 6. WebDriver Бонус Java 3
  7. 7. Эволюция 4
  8. 8. Пример теста 5
  9. 9. Пример теста SQA Days 5
  10. 10. Пример теста SQA Days 5
  11. 11. Пример теста 6
  12. 12. Пример теста 6
  13. 13. Первый тест 7
  14. 14. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { driver.findElement(By.id("text")).sendKeys("SQA Days"); driver.findElement(By.className("b-form-button__input")).click(); assertTrue(driver.findElement(By.className("b-serp-list")). isDisplayed()); } @After public void closeDriver() { driver.quit(); }} 8
  15. 15. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { driver.findElement(By.id("text")).sendKeys("SQA Days"); driver.findElement(By.className("b-form-button__input")).click(); assertTrue(driver.findElement(By.className("b-serp-list")). isDisplayed()); } @After public void closeDriver() { driver.quit(); }} 8
  16. 16. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { driver.findElement(By.id("text")).sendKeys("SQA Days"); driver.findElement(By.className("b-form-button__input")).click(); assertTrue(driver.findElement(By.className("b-serp-list")). isDisplayed()); } @After public void closeDriver() { driver.quit(); }} 8
  17. 17. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { driver.findElement(By.id("text")).sendKeys("SQA Days"); driver.findElement(By.className("b-form-button__input")).click(); assertTrue(driver.findElement(By.className("b-serp-list")). isDisplayed()); } @After public void closeDriver() { driver.quit(); }} 8
  18. 18. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { driver.findElement(By.id("text")).sendKeys("SQA Days"); driver.findElement(By.className("b-form-button__input")).click(); assertTrue(driver.findElement(By.className("b-serp-list")). isDisplayed()); } @After public void closeDriver() { driver.quit(); }} 8
  19. 19. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { driver.findElement(By.id("text")).sendKeys("SQA Days"); driver.findElement(By.className("b-form-button__input")).click(); assertTrue(driver.findElement(By.className("b-serp-list")). isDisplayed()); } @After public void closeDriver() { driver.quit(); }} 8
  20. 20. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { driver.findElement(By.id("text")).sendKeys("SQA Days"); driver.findElement(By.className("b-form-button__input")).click(); assertTrue(driver.findElement(By.className("b-serp-list")). isDisplayed()); } @After public void closeDriver() { driver.quit(); }} 8
  21. 21. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { driver.findElement(By.id("text")).sendKeys("SQA Days"); driver.findElement(By.className("b-form-button__input")).click(); assertTrue(driver.findElement(By.className("b-serp-list")). isDisplayed()); } @After public void closeDriver() { driver.quit(); }} 8
  22. 22. Недостатки 9
  23. 23. Недостатки Читаемость Переиспользование Поддержка 9
  24. 24. Page Object 10
  25. 25. Страница 11
  26. 26. Page Objectpublic class SearchPage { @FindBy(id = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; public SearchPage(WebDriver driver) { PageFactory.initElements(driver, this); } public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); }} 12
  27. 27. Page Objectpublic class SearchPage { @FindBy(id = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; public SearchPage(WebDriver driver) { PageFactory.initElements(driver, this); } public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); }} 12
  28. 28. Page Objectpublic class SearchPage { @FindBy(id = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; public SearchPage(WebDriver driver) { PageFactory.initElements(driver, this); } public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); }} 12
  29. 29. Page Objectpublic class SearchPage { @FindBy(id = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; public SearchPage(WebDriver driver) { PageFactory.initElements(driver, this); } public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); }} 12
  30. 30. Page Objectpublic class SearchPage { @FindBy(id = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; public SearchPage(WebDriver driver) { PageFactory.initElements(driver, this); } public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); }} 12
  31. 31. Page Objectpublic class SearchPage { @FindBy(id = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; public SearchPage(WebDriver driver) { PageFactory.initElements(driver, this); } public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); }} 12
  32. 32. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); private SearchPage searchPage = new SearchPage(driver); private SearchResultsPage searchResultsPage = new SearchResultsPage(driver); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); assertTrue(searchResultsPage.isSearchResultsBlockDisplayed()); } @After public void closeDriver() { driver.quit(); }} 13
  33. 33. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); private SearchPage searchPage = new SearchPage(driver); private SearchResultsPage searchResultsPage = new SearchResultsPage(driver); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); assertTrue(searchResultsPage.isSearchResultsBlockDisplayed()); } @After public void closeDriver() { driver.quit(); }} 13
  34. 34. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); private SearchPage searchPage = new SearchPage(driver); private SearchResultsPage searchResultsPage = new SearchResultsPage(driver); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); assertTrue(searchResultsPage.isSearchResultsBlockDisplayed()); } @After public void closeDriver() { driver.quit(); }} 13
  35. 35. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); private SearchPage searchPage = new SearchPage(driver); private SearchResultsPage searchResultsPage = new SearchResultsPage(driver); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); assertTrue(searchResultsPage.isSearchResultsBlockDisplayed()); } @After public void closeDriver() { driver.quit(); }} 13
  36. 36. Код тестаpublic class SearchResultsTest { private WebDriver driver = new FirefoxDriver(); private SearchPage searchPage = new SearchPage(driver); private SearchResultsPage searchResultsPage = new SearchResultsPage(driver); @Before public void loadPage() { driver.get("http://www.yandex.ru"); } @Test public void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); assertTrue(searchResultsPage.isSearchResultsBlockDisplayed()); } @After public void closeDriver() { driver.quit(); }} 13
  37. 37. Дублирование 14
  38. 38. Дублирование 14
  39. 39. Дублирование 14
  40. 40. Дублирование 14
  41. 41. Дублирование 14
  42. 42. Дублирование 14
  43. 43. Дублирование 14
  44. 44. Дублирование 14
  45. 45. Загромождение 15
  46. 46. Загромождениеpublic class AutoHomePage { @FindBy(name = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; @FindBy(name = "login") private WebElement loginInput; @FindBy(name = "passwd") private WebElement passwordInput; @FindBy(xpath = "//div[@class=b-domik__button]//input") private WebElement loginButton; @FindBy(name = "twoweeks") private WebElement rememberMeCheckBox; 16 @FindBy(name = "text")
  47. 47. Загромождение public class AutoHomePage { @FindBy(name = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; @FindBy(name = "login") private WebElement loginInput; @FindBy(name = "passwd") private WebElement passwordInput; @FindBy(xpath = "//div[@class=b-domik__button]//input") private WebElement loginButton; @FindBy(name = "twoweeks") private WebElement rememberMeCheckBox; @FindBy(name = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; @FindBy(name = "login") private WebElement loginInput; @FindBy(name = "passwd") private WebElement passwordInput; @FindBy(xpath = "//div[@class=b-domik__button]//input") private WebElement loginButton; @FindBy(name = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; @FindBy(name = "login") private WebElement loginInput; @FindBy(name = "passwd") private WebElement passwordInput; @FindBy(xpath = "//div[@class=b-domik__button]//input") private WebElement loginButton; 16 @FindBy(name = "text")
  48. 48. Загромождение public class AutoHomePage { @FindBy(name = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; @FindBy(name = "login") private WebElement loginInput; @FindBy(name = "passwd") private WebElement passwordInput; @FindBy(xpath = "//div[@class=b-domik__button]//input") private WebElement loginButton; @FindBy(name = "twoweeks") private WebElement rememberMeCheckBox; @FindBy(name = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; @FindBy(name = "login") private WebElement loginInput; @FindBy(name = "passwd") private WebElement passwordInput; @FindBy(xpath = "//div[@class=b-domik__button]//input") private WebElement loginButton; @FindBy(name = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; @FindBy(name = "login") private WebElement loginInput; @FindBy(name = "passwd") private WebElement passwordInput; @FindBy(xpath = "//div[@class=b-domik__button]//input") private WebElement loginButton; @FindBy(name = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; @FindBy(name = "login") private WebElement loginInput; @FindBy(name = "passwd") private WebElement passwordInput; @FindBy(xpath = "//div[@class=b-domik__button]//input") private WebElement loginButton; @FindBy(name = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; @FindBy(name = "login") private WebElement loginInput; @FindBy(name = "passwd") private WebElement passwordInput; @FindBy(xpath = "//div[@class=b-domik__button]//input") private WebElement loginButton; @FindBy(name = "text") private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; @FindBy(name = "login") private WebElement loginInput; @FindBy(name = "passwd") private WebElement passwordInput; @FindBy(xpath = "//div[@class=b-domik__button]//input") private WebElement loginButton; @FindBy(name = "text") 16 private WebElement requestInput; @FindBy(xpath = "//input[@type=submit]") private WebElement searchButton; @FindBy(name = "login")
  49. 49. Отсутствие типизации 17
  50. 50. Отсутствие типизации 17
  51. 51. Отсутствие типизации Select selectByIndex() selectByValue() ... 17
  52. 52. Отсутствие типизацииpublic class PageWithSelect { @FindBy(xpath = "select-xpath") private WebElement select; public PageWithSelect(WebDriver driver) { PageFactory.initElements(driver, this); } private Select getSelect() { return new Select(select); } // Other methods using getSelect() method} 18
  53. 53. Отсутствие типизацииpublic class PageWithSelect { @FindBy(xpath = "select-xpath") private WebElement select; public PageWithSelect(WebDriver driver) { PageFactory.initElements(driver, this); } private Select getSelect() { return new Select(select); } // Other methods using getSelect() method} 18
  54. 54. Отсутствие типизацииpublic class PageWithSelect { @FindBy(xpath = "select-xpath") private WebElement select; public PageWithSelect(WebDriver driver) { PageFactory.initElements(driver, this); } private Select getSelect() { return new Select(select); } // Other methods using getSelect() method} 18
  55. 55. Отсутствие типизацииpublic class PageWithSelect { @FindBy(xpath = "select-xpath") private Select select; public PageWithSelect(WebDriver driver) { PageFactory.initElements(driver, this); } // Other methods using select} 18
  56. 56. Отсутствие типизацииpublic class PageWithSelect { @FindBy(xpath = "select-xpath") private Select select; public PageWithSelect(WebDriver driver) { PageFactory.initElements(driver, this); } // Other methods using select} 18
  57. 57. Недостатки 19
  58. 58. Недостатки Дублирование кода 19
  59. 59. Недостатки Дублирование кода Загромождение 19
  60. 60. Недостатки Дублирование кода Загромождение Отсутствие типизации 19
  61. 61. 20
  62. 62. Html Elements 20
  63. 63. Блоки элементовТипизация элементовБиблиотека матчеров 21
  64. 64. Блоки элементовТипизация элементовБиблиотека матчеров 22
  65. 65. Структура страницы 23
  66. 66. Структура страницы 23
  67. 67. Поисковая форма@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") private WebElement requestInput; @FindBy(className = "b-form-button__input") private WebElement searchButton; public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); }} 24
  68. 68. Поисковая форма@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") Блок private WebElement requestInput; @FindBy(className = "b-form-button__input") private WebElement searchButton; public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); }} 24
  69. 69. Поисковая форма Селектор блока@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") Блок private WebElement requestInput; @FindBy(className = "b-form-button__input") private WebElement searchButton; public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); }} 24
  70. 70. Поисковая форма Селектор блока@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") Блок private WebElement requestInput; @FindBy(className = "b-form-button__input") Элементы private WebElement searchButton; public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); }} 24
  71. 71. Поисковая форма Селектор блока@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") Блок private WebElement requestInput; @FindBy(className = "b-form-button__input") Элементы private WebElement searchButton; public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); Логика }} взаимодействия 24
  72. 72. Форма авторизации@Block(@FindBy(className = "b-domik"))public class AuthorizationForm extends HtmlElement { @FindBy(name = "login") WebElement loginFiled; @FindBy(name = "passwd") WebElement passwordFiled; @FindBy(className = "b-form-button__input") WebElement submitButton; public void login(String login, String password) { loginFiled.sendKeys(login); passwordFiled.sendKeys(password); submitButton.click(); }} 25
  73. 73. Главная страницаpublic class SearchPage { private SearchArrow searchArrow; private AuthorizationForm authorizationForm; // ... public SearchPage(WebDriver driver) { HtmlElementLoader.populatePageObject(this, driver); } public void searchFor(String request) { searchArrow.searchFor(request); } public void login(String login, String password) { authorizationForm.login(login, password); } // ...} 26
  74. 74. Главная страницаpublic class SearchPage { private SearchArrow searchArrow; private AuthorizationForm authorizationForm; // ... public SearchPage(WebDriver driver) { HtmlElementLoader.populatePageObject(this, driver); } public void searchFor(String request) { searchArrow.searchFor(request); } public void login(String login, String password) { authorizationForm.login(login, password); } // ...} 26
  75. 75. Главная страницаpublic class SearchPage { private SearchArrow searchArrow; private AuthorizationForm authorizationForm; // ... public SearchPage(WebDriver driver) { HtmlElementLoader.populatePageObject(this, driver); } public void searchFor(String request) { searchArrow.searchFor(request); } public void login(String login, String password) { authorizationForm.login(login, password); } // ...} 26
  76. 76. Главная страницаpublic class SearchPage { private SearchArrow searchArrow; private AuthorizationForm authorizationForm; // ... public SearchPage(WebDriver driver) { HtmlElementLoader.populatePageObject(this, driver); } public void searchFor(String request) { searchArrow.searchFor(request); } public void login(String login, String password) { authorizationForm.login(login, password); } // ...} 26
  77. 77. Главная страницаpublic class SearchPage { private SearchArrow searchArrow; private AuthorizationForm authorizationForm; // ... public SearchPage(WebDriver driver) { HtmlElementLoader.populatePageObject(this, driver); } public void searchFor(String request) { searchArrow.searchFor(request); } public void login(String login, String password) { authorizationForm.login(login, password); } // ...} 26
  78. 78. Структура 27
  79. 79. Контекст поиска@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") private WebElement requestInput; @FindBy(className = "b-form-button__input") private WebElement searchButton; public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); }} 28
  80. 80. Контекст поиска Селектор блока@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") private WebElement requestInput; @FindBy(className = "b-form-button__input") private WebElement searchButton; Отностиельные public void searchFor(String request) { requestInput.sendKeys(request); селекторы searchButton.click(); }} 28
  81. 81. Контекст поискаpublic class SearchResultsPage { @FindBy(className = "b-search") private SearchArrow searchArrow; private SearchResultsBlock searchResultsBlock; public SearchResultsPage(WebDriver driver) { HtmlElementLoader.populatePageObject(this, driver); } public void searchFor(String request) { searchArrow.searchFor(request); } public boolean isSearchResultsBlockDisplayed() { return searchResultsBlock.isDisplayed(); }} 29
  82. 82. Контекст поискаpublic class SearchResultsPage { Переопределение @FindBy(className = "b-search") селектора private SearchArrow searchArrow; private SearchResultsBlock searchResultsBlock; public SearchResultsPage(WebDriver driver) { HtmlElementLoader.populatePageObject(this, driver); } public void searchFor(String request) { searchArrow.searchFor(request); } public boolean isSearchResultsBlockDisplayed() { return searchResultsBlock.isDisplayed(); }} 29
  83. 83. Блоки элементовТипизация элементовБиблиотека матчеров 30
  84. 84. Типизация 31
  85. 85. Типизация SQA 31
  86. 86. Типизация SQA 32
  87. 87. Поисковая форма@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") private WebElement requestInput; @FindBy(className = "b-form-button__input") private WebElement searchButton; @FindBy(xpath = "//div[@class=i-popup__content]//li") private List<WebElement> suggest; public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); } public void searchBySuggest(String request, int suggestItemNumber) { requestInput.sendKeys(request); suggest.get(suggestItemNumber).click(); }} 33
  88. 88. Поисковая форма@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") private WebElementrequestInput; TextInput requestInput; @FindBy(className = "b-form-button__input") private WebElement searchButton; Button searchButton; @FindBy(className = "i-popup__content") @FindBy(xpath = "//div[@class=i-popup__content]//li") private List<WebElement> suggest; Suggest suggest; public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); } public void searchBySuggest(String request, int suggestItemNumber) { requestInput.sendKeys(request); suggest.selectByIndex(suggestItemNumber); suggest.get(suggestItemNumber).click(); }} 33
  89. 89. Ленивая инициализация@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") private TextInput requestInput; @FindBy(className = "b-form-button__input") private Button searchButton; @FindBy(className = "i-popup__content") private Suggest suggest; public void searchBySuggest(String request, int suggestItemNumber) { requestInput.sendKeys(request); suggest.selectByIndex(suggestItemNumber); }} 34
  90. 90. Ленивая инициализация@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") private TextInput requestInput; @FindBy(className = "b-form-button__input") private Button searchButton; @FindBy(className = "i-popup__content") private Suggest suggest; Элемент public void searchBySuggest(String request, int suggestItemNumber) { requestInput.sendKeys(request); suggest.selectByIndex(suggestItemNumber); }} Поиск при обращении 34
  91. 91. Стандартные элементы Text Input Button CheckBox Radio Select 35
  92. 92. Добавление элементовpublic class Suggest extends TypifiedElement { public Suggest(WebElement wrappedElement) { super(wrappedElement); } private List<WebElement> getItems() { return getWrappedElement().findElements(By.xpath("//li")); } public void selectByIndex(int itemIndex) { getItems().get(itemIndex).click(); } public void selectByValue(String itemValue) { for (WebElement item : getItems()) { if (itemValue.equals(item.getText())) { item.click(); return; } } throw new NoSuchElementException(); }} 36
  93. 93. Добавление элементовpublic class Suggest extends TypifiedElement { public Suggest(WebElement wrappedElement) { super(wrappedElement); } private List<WebElement> getItems() { return getWrappedElement().findElements(By.xpath("//li")); } public void selectByIndex(int itemIndex) { getItems().get(itemIndex).click(); } public void selectByValue(String itemValue) { for (WebElement item : getItems()) { if (itemValue.equals(item.getText())) { item.click(); return; } } throw new NoSuchElementException(); }} 36
  94. 94. Добавление элементовpublic class Suggest extends TypifiedElement { public Suggest(WebElement wrappedElement) { super(wrappedElement); } private List<WebElement> getItems() { return getWrappedElement().findElements(By.xpath("//li")); } public void selectByIndex(int itemIndex) { getItems().get(itemIndex).click(); } public void selectByValue(String itemValue) { for (WebElement item : getItems()) { if (itemValue.equals(item.getText())) { item.click(); return; } } throw new NoSuchElementException(); }} 36
  95. 95. Добавление элементовpublic class Suggest extends TypifiedElement { public Suggest(WebElement wrappedElement) { super(wrappedElement); } private List<WebElement> getItems() { return getWrappedElement().findElements(By.xpath("//li")); } public void selectByIndex(int itemIndex) { getItems().get(itemIndex).click(); } public void selectByValue(String itemValue) { for (WebElement item : getItems()) { if (itemValue.equals(item.getText())) { item.click(); return; } } throw new NoSuchElementException(); }} 36
  96. 96. Добавление элементовpublic class Suggest extends TypifiedElement { public Suggest(WebElement wrappedElement) { super(wrappedElement); } private List<WebElement> getItems() { return getWrappedElement().findElements(By.xpath("//li")); } public void selectByIndex(int itemIndex) { getItems().get(itemIndex).click(); } public void selectByValue(String itemValue) { for (WebElement item : getItems()) { if (itemValue.equals(item.getText())) { item.click(); return; } } throw new NoSuchElementException(); }} 36
  97. 97. Добавление элементовpublic class Suggest extends TypifiedElement { public Suggest(WebElement wrappedElement) { super(wrappedElement); } private List<WebElement> getItems() { return getWrappedElement().findElements(By.xpath("//li")); } public void selectByIndex(int itemIndex) { getItems().get(itemIndex).click(); } public void selectByValue(String itemValue) { for (WebElement item : getItems()) { if (itemValue.equals(item.getText())) { item.click(); return; } } throw new NoSuchElementException(); }} 36
  98. 98. Конструктор 37
  99. 99. КонструкторТипизированные элементы 37
  100. 100. Конструктор Page-объектТипизированные элементы 37
  101. 101. Блоки элементовТипизация элементовБиблиотека матчеров 38
  102. 102. Матчеры 39
  103. 103. МатчерыassertThat(audience, isPayingAttention()) 39
  104. 104. МатчерыassertThat(audience, isPayingAttention())assertThat(audience, is(not(sleeping()))) 39
  105. 105. Наши матчеры 40
  106. 106. Наши матчеры assertThat(element, exists()) 40
  107. 107. Наши матчеры assertThat(element, exists())assertThat(element, hasText(“SQA Days”)) 40
  108. 108. Наши матчеры assertThat(element, exists())assertThat(element, hasText(“SQA Days”)) assertThat(checkBox, isSelected()) 40
  109. 109. Наши матчеры assertThat(element, exists())assertThat(element, hasText(“SQA Days”)) assertThat(checkBox, isSelected()) assertThat(radio, hasSelectedButton(3)) 40
  110. 110. Матчеры в тестах@Testpublic void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); assertThat(searchResultsPage.getSearchResultsBlock(), exists());} 41
  111. 111. Матчеры в тестах@Testpublic void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); assertThat(searchResultsPage.getSearchResultsBlock(), both(exists()).and(isDisplayed()));} 42
  112. 112. Матчеры в тестах@Testpublic void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); String message = String.format( "Элемент %s должен присутсвовать на странице", searchResultsPage.getSearchResultsBlock() ); assertThat(message, searchResultsPage.getSearchResultsBlock(), exists());} 43
  113. 113. Матчеры в тестах@Testpublic void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); String message = String.format( "Элемент %s должен присутсвовать на странице", searchResultsPage.getSearchResultsBlock() ); assertThat(message, searchResultsPage.getSearchResultsBlock(), exists());} Assert: Элемент ‘[FirefoxDriver: firefox on MAC (e63b162c-853a-a243-999e-2266c9d52499)]’ должен присутсвовать на странице 43
  114. 114. Именование элементов@Name("Форма поиска")@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @Name("Поисковая строка") @FindBy(id = "text") private TextInput requestInput; @Name("Кнопка Haйти") @FindBy(className = "b-form-button__input") private Button searchButton; @FindBy(className = "i-popup__content") private Suggest suggest; // ... 44
  115. 115. Именование элементов@Name("Форма поиска")@Block(@FindBy(className = "b-head-search")) Имя поpublic class SearchArrow extends HtmlElement { аннотации @Name("Поисковая строка") @FindBy(id = "text") private TextInput requestInput; @Name("Кнопка Haйти") @FindBy(className = "b-form-button__input") private Button searchButton; @FindBy(className = "i-popup__content") private Suggest suggest; // ... 44
  116. 116. Именование элементов@Name("Форма поиска")@Block(@FindBy(className = "b-head-search")) Имя поpublic class SearchArrow extends HtmlElement { аннотации @Name("Поисковая строка") @FindBy(id = "text") private TextInput requestInput; @Name("Кнопка Haйти") @FindBy(className = "b-form-button__input") private Button searchButton; @FindBy(className = "i-popup__content") Имя по private Suggest suggest; названию поля // ... 44
  117. 117. Именование элементовpublic class SearchResultsPage { @FindBy(className = "b-search") private SearchArrow searchArrow; @Name("Блок результатов поиска") private SearchResultsBlock searchResultsBlock; public SearchResultsPage(WebDriver driver) { HtmlElementLoader.populatePageObject(this, driver); } public void searchFor(String request) { searchArrow.searchFor(request); } public SearchResultsBlock getSearchResultsBlock() { return searchResultsBlock; }} 45
  118. 118. Именование элементовpublic class SearchResultsPage { @FindBy(className = "b-search") private SearchArrow searchArrow; Переопределение имени @Name("Блок результатов поиска") private SearchResultsBlock searchResultsBlock; public SearchResultsPage(WebDriver driver) { HtmlElementLoader.populatePageObject(this, driver); } public void searchFor(String request) { searchArrow.searchFor(request); } public SearchResultsBlock getSearchResultsBlock() { return searchResultsBlock; }} 45
  119. 119. Имена в тестах@Testpublic void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); String message = String.format( "Элемент %s должен присутсвовать на странице", searchResultsPage.getSearchResultsBlock() ); assertThat(message, searchResultsPage.getSearchResultsBlock(), exists());} Assert: Элемент “Блок результатов поиска” должен присутствовать на странице 46
  120. 120. Блоки элементовТипизация элементовБиблиотека матчеров 47
  121. 121. Жизнь стала такой 48
  122. 122. Будущее 49
  123. 123. Библиотека элементов 50
  124. 124. Библиотека элементов 50
  125. 125. Динамические селекторы@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") private TextInput requestInput; @FindBy(className = "b-form-button__input") private Button searchButton; @FindBy(className = "i-popup__content") private Suggest suggest; public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); } public void searchBySuggest(String request, int suggestItemNumber) { requestInput.sendKeys(request); suggest.selectByIndex(suggestItemNumber); }} 51
  126. 126. Динамические селекторы@Block(@FindBy(className = "b-head-search"))public class SearchArrow extends HtmlElement { @FindBy(id = "text") private TextInput requestInput; @FindBy(className = "b-form-button__input") Статические селекторы private Button searchButton; @FindBy(className = "i-popup__content") private Suggest suggest; public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); } public void searchBySuggest(String request, int suggestItemNumber) { requestInput.sendKeys(request); suggest.selectByIndex(suggestItemNumber); }} 51
  127. 127. Динамические селекторы 52
  128. 128. Динамические селекторы 53
  129. 129. Понятные логи 54
  130. 130. Понятные логи1.Ввожу в элемент “Поисковая строка”текст “SQA Days”... 54
  131. 131. Понятные логи1.Ввожу в элемент “Поисковая строка”текст “SQA Days”...2.Кликаю на элемент “Кнопка ‘Найти’”... 54
  132. 132. Понятные логи1.Ввожу в элемент “Поисковая строка”текст “SQA Days”...2.Кликаю на элемент “Кнопка ‘Найти’”...3.Проверяю наличие элемента “Блокрезультатов поиска”... 54
  133. 133. Понятные логи1.Ввожу в элемент “Поисковая строка”текст “SQA Days”...2.Кликаю на элемент “Кнопка ‘Найти’”...3.Проверяю наличие элемента “Блокрезультатов поиска”...Assert: Элемент “Блок результатов поиска”должен присутствовать на странице 54
  134. 134. Генерация блоков 55
  135. 135. Генерация блоков Страница 55
  136. 136. Генерация блоков @Block(@FindBy(className = "b-head-search")) @Block(@FindBy(className = "b-head-search")) public class SearchArrow extends HtmlElement { @Block(@FindBy(className = "b-head-search")) public class SearchArrow extends HtmlElement { @FindBy(id = "text") @Block(@FindBy(className = "b-head-search")) public class SearchArrow extends HtmlElement { private class=SearchArrow extends HtmlElement { @FindBy(id "text") public WebElement requestInput; @Block(@FindBy(className = "b-head-search")) @FindBy(id = "text") private class SearchArrow extends HtmlElement { public WebElement requestInput; @FindBy(id = "text") private WebElement requestInput; @FindBy(className == "text") @FindBy(id "b-form-button__input") private WebElement requestInput; @FindBy(className = "b-form-button__input") private WebElement searchButton; private WebElement requestInput; @FindBy(className = "b-form-button__input") private WebElement searchButton; @FindBy(className = "b-form-button__input") private WebElement searchButton; public @FindBy(className searchButton; { private searchFor(String request) void WebElement = "b-form-button__input") public void searchFor(String request) { requestInput.sendKeys(request); private WebElement searchButton; public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); public void searchFor(String request) { requestInput.sendKeys(request); searchButton.click(); } public void searchFor(String request) { requestInput.sendKeys(request); } searchButton.click(); } requestInput.sendKeys(request); searchButton.click(); } } } searchButton.click(); } } } } Страница Блоки 55
  137. 137. И другое многое будет там 56
  138. 138. 57
  139. 139. https://github.com/yandex-qatools/htmlelements 57
  140. 140. https://github.com/yandex-qatools/htmlelements qa-tools@yandex-team.ru 57
  141. 141. Cпасибо starlight@yandex-team.ru @alex_tolmachev

×