SlideShare a Scribd company logo
1 of 141
Download to read offline
Фреймворк 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 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
Код теста
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
Код теста
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
Код теста
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
Код теста
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
Код теста
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
Код теста
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
Код теста
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
Недостатки




             9
Недостатки

      Читаемость
   Переиспользование
      Поддержка

             9
Page Object




          10
Страница




           11
Page Object
public 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
Page Object
public 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
Page Object
public 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
Page Object
public 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
Page Object
public 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
Page Object
public 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
Код теста
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
Код теста
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
Код теста
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
Код теста
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
Код теста
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
Дублирование




         14
Дублирование




         14
Дублирование




         14
Дублирование




         14
Дублирование




         14
Дублирование




         14
Дублирование




         14
Дублирование




         14
Загромождение




         15
Загромождение
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")
Загромождение
     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")
Загромождение
       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")
Отсутствие типизации




           17
Отсутствие типизации




           17
Отсутствие типизации

                      Select
                selectByIndex()
                selectByValue()
                ...

           17
Отсутствие типизации
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
Отсутствие типизации
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
Отсутствие типизации
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
Отсутствие типизации

public class PageWithSelect {
    @FindBy(xpath = "select-xpath")
    private Select select;

    public PageWithSelect(WebDriver driver) {
        PageFactory.initElements(driver, this);
    }

    // Other methods using select
}



                        18
Отсутствие типизации

public class PageWithSelect {
    @FindBy(xpath = "select-xpath")
    private Select select;

    public PageWithSelect(WebDriver driver) {
        PageFactory.initElements(driver, this);
    }

    // Other methods using select
}



                        18
Недостатки




             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 = "text")
    private WebElement requestInput;

    @FindBy(className = "b-form-button__input")
    private WebElement searchButton;

    public void searchFor(String request) {
        requestInput.sendKeys(request);
        searchButton.click();
    }
}

                            24
Поисковая форма

@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
Поисковая форма

                                              Селектор блока
@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
Поисковая форма

                                              Селектор блока
@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
Поисковая форма

                                              Селектор блока
@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
Форма авторизации
@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
Главная страница
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
Главная страница
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
Главная страница
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
Главная страница
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
Главная страница
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
Структура




            27
Контекст поиска
@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
Контекст поиска
                                              Селектор блока
@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
Контекст поиска
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
Контекст поиска
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
Блоки элементов

Типизация элементов

Библиотека матчеров

         30
Типизация




            31
Типизация
    SQA




            31
Типизация
    SQA




            32
Поисковая форма
@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
Поисковая форма
@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
Ленивая инициализация
@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
Ленивая инициализация
@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
Стандартные элементы
        Text Input
         Button
        CheckBox
          Radio
         Select
            35
Добавление элементов
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
Добавление элементов
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
Добавление элементов
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
Добавление элементов
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
Добавление элементов
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
Добавление элементов
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
Конструктор




          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())



                    40
Наши матчеры
      assertThat(element, exists())

assertThat(element, hasText(“SQA Days”))

   assertThat(checkBox, isSelected())

 assertThat(radio, hasSelectedButton(3))

                    40
Матчеры в тестах

@Test
public void shouldSeeSearchResultsWhenLookingUp() {
    searchPage.searchFor("SQA Days");

    assertThat(searchResultsPage.getSearchResultsBlock(),
               exists());
}




                            41
Матчеры в тестах

@Test
public void shouldSeeSearchResultsWhenLookingUp() {
    searchPage.searchFor("SQA Days");

    assertThat(searchResultsPage.getSearchResultsBlock(),
               both(exists()).and(isDisplayed()));
}




                            42
Матчеры в тестах
@Test
public void shouldSeeSearchResultsWhenLookingUp() {
    searchPage.searchFor("SQA Days");

    String message = String.format(
            "Элемент '%s' должен присутсвовать на странице",
            searchResultsPage.getSearchResultsBlock()
    );
    assertThat(message,
               searchResultsPage.getSearchResultsBlock(),
               exists());
}




                             43
Матчеры в тестах
@Test
public 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
Именование элементов
@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
Именование элементов
@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
Именование элементов
@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
Именование элементов
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
Именование элементов
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
Имена в тестах
@Test
public void shouldSeeSearchResultsWhenLookingUp() {
    searchPage.searchFor("SQA Days");

    String message = String.format(
            "Элемент '%s' должен присутсвовать на странице",
            searchResultsPage.getSearchResultsBlock()
    );
    assertThat(message,
               searchResultsPage.getSearchResultsBlock(),
               exists());
}


    Assert: Элемент “Блок результатов поиска”
    должен присутствовать на странице

                             46
Блоки элементов

Типизация элементов

Библиотека матчеров

         47
Жизнь стала такой
         48
Будущее


   49
Библиотека элементов




           50
Библиотека элементов




           50
Динамические селекторы
@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
Динамические селекторы
@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
Динамические селекторы




            52
Динамические селекторы




            53
Понятные логи




         54
Понятные логи
1.Ввожу в элемент “Поисковая строка”
текст “SQA Days”...




                    54
Понятные логи
1.Ввожу в элемент “Поисковая строка”
текст “SQA Days”...
2.Кликаю на элемент “Кнопка ‘Найти’”...




                    54
Понятные логи
1.Ввожу в элемент “Поисковая строка”
текст “SQA Days”...
2.Кликаю на элемент “Кнопка ‘Найти’”...
3.Проверяю наличие элемента “Блок
результатов поиска”...




                    54
Понятные логи
1.Ввожу в элемент “Поисковая строка”
текст “SQA Days”...
2.Кликаю на элемент “Кнопка ‘Найти’”...
3.Проверяю наличие элемента “Блок
результатов поиска”...

Assert: Элемент “Блок результатов поиска”
должен присутствовать на странице


                    54
Генерация блоков




          55
Генерация блоков




  Страница

             55
Генерация блоков

                  @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
И другое многое
   будет там




             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

More Related Content

What's hot

Android Fast Track CRUD Android PHP MySql
Android Fast Track CRUD Android PHP MySqlAndroid Fast Track CRUD Android PHP MySql
Android Fast Track CRUD Android PHP MySqlAgus Haryanto
 
Generic asynchronous HTTP utility for android
Generic asynchronous HTTP utility for androidGeneric asynchronous HTTP utility for android
Generic asynchronous HTTP utility for androidSomenath Mukhopadhyay
 
jQuery sans jQuery
jQuery sans jQueryjQuery sans jQuery
jQuery sans jQuerygoldoraf
 
Jak zabít několik much jednou ranou přechodem na fragmenty
Jak zabít několik much jednou ranou přechodem na fragmentyJak zabít několik much jednou ranou přechodem na fragmenty
Jak zabít několik much jednou ranou přechodem na fragmentyDavid Vávra
 
Jquery Introduction Hebrew
Jquery Introduction HebrewJquery Introduction Hebrew
Jquery Introduction HebrewAlex Ivy
 

What's hot (9)

Android Fast Track CRUD Android PHP MySql
Android Fast Track CRUD Android PHP MySqlAndroid Fast Track CRUD Android PHP MySql
Android Fast Track CRUD Android PHP MySql
 
Get more votes!
Get more votes!Get more votes!
Get more votes!
 
Web2.0 with jQuery
Web2.0 with jQueryWeb2.0 with jQuery
Web2.0 with jQuery
 
Best Fried Chicken
Best Fried ChickenBest Fried Chicken
Best Fried Chicken
 
Generic asynchronous HTTP utility for android
Generic asynchronous HTTP utility for androidGeneric asynchronous HTTP utility for android
Generic asynchronous HTTP utility for android
 
jQuery sans jQuery
jQuery sans jQueryjQuery sans jQuery
jQuery sans jQuery
 
Jak zabít několik much jednou ranou přechodem na fragmenty
Jak zabít několik much jednou ranou přechodem na fragmentyJak zabít několik much jednou ranou přechodem na fragmenty
Jak zabít několik much jednou ranou přechodem na fragmenty
 
Jquery Introduction Hebrew
Jquery Introduction HebrewJquery Introduction Hebrew
Jquery Introduction Hebrew
 
jQuery for beginners
jQuery for beginnersjQuery for beginners
jQuery for beginners
 

Viewers also liked

Webium: Page Objects in Python
Webium: Page Objects in PythonWebium: Page Objects in Python
Webium: Page Objects in PythonIgor Khrol
 
Фреймворк Html Elements
Фреймворк Html ElementsФреймворк Html Elements
Фреймворк Html ElementsSQALab
 
CodeFest 2013. Ерошенко А. — Фреймворк Html Elements или как удобно взаимодей...
CodeFest 2013. Ерошенко А. — Фреймворк Html Elements или как удобно взаимодей...CodeFest 2013. Ерошенко А. — Фреймворк Html Elements или как удобно взаимодей...
CodeFest 2013. Ерошенко А. — Фреймворк Html Elements или как удобно взаимодей...CodeFest
 
Page object with selenide
Page object with selenidePage object with selenide
Page object with selenideCOMAQA.BY
 
Grail - CodeFest'2015
Grail - CodeFest'2015Grail - CodeFest'2015
Grail - CodeFest'2015Igor Khrol
 
Test Automation Wargaming SQA Days 17
Test Automation Wargaming SQA Days 17Test Automation Wargaming SQA Days 17
Test Automation Wargaming SQA Days 17Igor Khrol
 
CodeFest 2013. Хозя А. — Как screenshot-based средство автоматизации нам стро...
CodeFest 2013. Хозя А. — Как screenshot-based средство автоматизации нам стро...CodeFest 2013. Хозя А. — Как screenshot-based средство автоматизации нам стро...
CodeFest 2013. Хозя А. — Как screenshot-based средство автоматизации нам стро...CodeFest
 
Читабельные отчеты для автоматизации на C# / Gallio / BDDfy
Читабельные отчеты для автоматизации на C# / Gallio / BDDfyЧитабельные отчеты для автоматизации на C# / Gallio / BDDfy
Читабельные отчеты для автоматизации на C# / Gallio / BDDfyDmytro Zharii
 
Tolmachev Alexander Web Search Engines
Tolmachev Alexander Web Search EnginesTolmachev Alexander Web Search Engines
Tolmachev Alexander Web Search EnginesAlexanderTolmachev
 
Каким будет Selenium 3.0 и Selenium 4.0
Каким будет Selenium 3.0 и Selenium 4.0Каким будет Selenium 3.0 и Selenium 4.0
Каким будет Selenium 3.0 и Selenium 4.0SQALab
 
Framework for Web Automation Testing
Framework for Web Automation TestingFramework for Web Automation Testing
Framework for Web Automation TestingTaras Lytvyn
 
HtmlElements – естественное расширение PageObject
HtmlElements – естественное расширение PageObjectHtmlElements – естественное расширение PageObject
HtmlElements – естественное расширение PageObjectSQALab
 
автоматизация тестирования с помощью Selenium
автоматизация тестирования с помощью Seleniumавтоматизация тестирования с помощью Selenium
автоматизация тестирования с помощью Seleniumvyacheslavmaslov
 
Cовременный контроль качества: давай сделаем это по-быстрому...
Cовременный контроль качества: давай сделаем это по-быстрому...Cовременный контроль качества: давай сделаем это по-быстрому...
Cовременный контроль качества: давай сделаем это по-быстрому...Igor Khrol
 
Автоматизированное тестирование UI на C# + Selenium WebDriver
Автоматизированное тестирование UI на C# + Selenium WebDriverАвтоматизированное тестирование UI на C# + Selenium WebDriver
Автоматизированное тестирование UI на C# + Selenium WebDriverPavel Tsukanov
 
Web driver история одной миграции
Web driver   история одной миграцииWeb driver   история одной миграции
Web driver история одной миграцииIgor Khrol
 
автоматизация Flex приложений с помощью selenium rc
автоматизация Flex приложений с помощью selenium rcавтоматизация Flex приложений с помощью selenium rc
автоматизация Flex приложений с помощью selenium rcIgor Khrol
 
Повышаем надёжность тестов через JavaScript
Повышаем надёжность тестов через JavaScriptПовышаем надёжность тестов через JavaScript
Повышаем надёжность тестов через JavaScriptIgor Khrol
 
СОЗДАЙ РОБОТА С НУЛЯ
СОЗДАЙ РОБОТА С НУЛЯСОЗДАЙ РОБОТА С НУЛЯ
СОЗДАЙ РОБОТА С НУЛЯPavel Tsukanov
 
Docker + Selenium Webdriver в рамках Continuous Integration
Docker + Selenium Webdriver в рамках Continuous IntegrationDocker + Selenium Webdriver в рамках Continuous Integration
Docker + Selenium Webdriver в рамках Continuous IntegrationSQALab
 

Viewers also liked (20)

Webium: Page Objects in Python
Webium: Page Objects in PythonWebium: Page Objects in Python
Webium: Page Objects in Python
 
Фреймворк Html Elements
Фреймворк Html ElementsФреймворк Html Elements
Фреймворк Html Elements
 
CodeFest 2013. Ерошенко А. — Фреймворк Html Elements или как удобно взаимодей...
CodeFest 2013. Ерошенко А. — Фреймворк Html Elements или как удобно взаимодей...CodeFest 2013. Ерошенко А. — Фреймворк Html Elements или как удобно взаимодей...
CodeFest 2013. Ерошенко А. — Фреймворк Html Elements или как удобно взаимодей...
 
Page object with selenide
Page object with selenidePage object with selenide
Page object with selenide
 
Grail - CodeFest'2015
Grail - CodeFest'2015Grail - CodeFest'2015
Grail - CodeFest'2015
 
Test Automation Wargaming SQA Days 17
Test Automation Wargaming SQA Days 17Test Automation Wargaming SQA Days 17
Test Automation Wargaming SQA Days 17
 
CodeFest 2013. Хозя А. — Как screenshot-based средство автоматизации нам стро...
CodeFest 2013. Хозя А. — Как screenshot-based средство автоматизации нам стро...CodeFest 2013. Хозя А. — Как screenshot-based средство автоматизации нам стро...
CodeFest 2013. Хозя А. — Как screenshot-based средство автоматизации нам стро...
 
Читабельные отчеты для автоматизации на C# / Gallio / BDDfy
Читабельные отчеты для автоматизации на C# / Gallio / BDDfyЧитабельные отчеты для автоматизации на C# / Gallio / BDDfy
Читабельные отчеты для автоматизации на C# / Gallio / BDDfy
 
Tolmachev Alexander Web Search Engines
Tolmachev Alexander Web Search EnginesTolmachev Alexander Web Search Engines
Tolmachev Alexander Web Search Engines
 
Каким будет Selenium 3.0 и Selenium 4.0
Каким будет Selenium 3.0 и Selenium 4.0Каким будет Selenium 3.0 и Selenium 4.0
Каким будет Selenium 3.0 и Selenium 4.0
 
Framework for Web Automation Testing
Framework for Web Automation TestingFramework for Web Automation Testing
Framework for Web Automation Testing
 
HtmlElements – естественное расширение PageObject
HtmlElements – естественное расширение PageObjectHtmlElements – естественное расширение PageObject
HtmlElements – естественное расширение PageObject
 
автоматизация тестирования с помощью Selenium
автоматизация тестирования с помощью Seleniumавтоматизация тестирования с помощью Selenium
автоматизация тестирования с помощью Selenium
 
Cовременный контроль качества: давай сделаем это по-быстрому...
Cовременный контроль качества: давай сделаем это по-быстрому...Cовременный контроль качества: давай сделаем это по-быстрому...
Cовременный контроль качества: давай сделаем это по-быстрому...
 
Автоматизированное тестирование UI на C# + Selenium WebDriver
Автоматизированное тестирование UI на C# + Selenium WebDriverАвтоматизированное тестирование UI на C# + Selenium WebDriver
Автоматизированное тестирование UI на C# + Selenium WebDriver
 
Web driver история одной миграции
Web driver   история одной миграцииWeb driver   история одной миграции
Web driver история одной миграции
 
автоматизация Flex приложений с помощью selenium rc
автоматизация Flex приложений с помощью selenium rcавтоматизация Flex приложений с помощью selenium rc
автоматизация Flex приложений с помощью selenium rc
 
Повышаем надёжность тестов через JavaScript
Повышаем надёжность тестов через JavaScriptПовышаем надёжность тестов через JavaScript
Повышаем надёжность тестов через JavaScript
 
СОЗДАЙ РОБОТА С НУЛЯ
СОЗДАЙ РОБОТА С НУЛЯСОЗДАЙ РОБОТА С НУЛЯ
СОЗДАЙ РОБОТА С НУЛЯ
 
Docker + Selenium Webdriver в рамках Continuous Integration
Docker + Selenium Webdriver в рамках Continuous IntegrationDocker + Selenium Webdriver в рамках Continuous Integration
Docker + Selenium Webdriver в рамках Continuous Integration
 

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

  • 1. Фреймворк Html Elements или как удобно взаимодействовать с веб-интерфейсами в тестах Александр Толмачев
  • 4. 3
  • 6. WebDriver Бонус Java 3
  • 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. Код теста 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. Код теста 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. Код теста 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. Код теста 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. Код теста 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. Код теста 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. Код теста 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
  • 23. Недостатки Читаемость Переиспользование Поддержка 9
  • 26. Page Object public 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. Page Object public 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. Page Object public 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. Page Object public 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. Page Object public 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. Page Object public 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. Код теста 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. Код теста 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. Код теста 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. Код теста 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. Код теста 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
  • 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. Загромождение 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. Загромождение 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")
  • 51. Отсутствие типизации Select selectByIndex() selectByValue() ... 17
  • 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. Отсутствие типизации 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. Отсутствие типизации 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. Отсутствие типизации public class PageWithSelect { @FindBy(xpath = "select-xpath") private Select select; public PageWithSelect(WebDriver driver) { PageFactory.initElements(driver, this); } // Other methods using select } 18
  • 56. Отсутствие типизации public class PageWithSelect { @FindBy(xpath = "select-xpath") private Select select; public PageWithSelect(WebDriver driver) { PageFactory.initElements(driver, this); } // Other methods using select } 18
  • 58. Недостатки Дублирование кода 19
  • 59. Недостатки Дублирование кода Загромождение 19
  • 60. Недостатки Дублирование кода Загромождение Отсутствие типизации 19
  • 61. 20
  • 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. Поисковая форма @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. Поисковая форма Селектор блока @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. Поисковая форма Селектор блока @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. Поисковая форма Селектор блока @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. Форма авторизации @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. Главная страница 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. Главная страница 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. Главная страница 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. Главная страница 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. Главная страница 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
  • 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. Контекст поиска Селектор блока @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. Контекст поиска 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. Контекст поиска 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
  • 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. Поисковая форма @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. Ленивая инициализация @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. Ленивая инициализация @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. Стандартные элементы Text Input Button CheckBox Radio Select 35
  • 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. Добавление элементов 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. Добавление элементов 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. Добавление элементов 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. Добавление элементов 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. Добавление элементов 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
  • 100. Конструктор Page-объект Типизированные элементы 37
  • 106. Наши матчеры assertThat(element, exists()) 40
  • 107. Наши матчеры assertThat(element, exists()) assertThat(element, hasText(“SQA Days”)) 40
  • 108. Наши матчеры assertThat(element, exists()) assertThat(element, hasText(“SQA Days”)) assertThat(checkBox, isSelected()) 40
  • 109. Наши матчеры assertThat(element, exists()) assertThat(element, hasText(“SQA Days”)) assertThat(checkBox, isSelected()) assertThat(radio, hasSelectedButton(3)) 40
  • 110. Матчеры в тестах @Test public void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); assertThat(searchResultsPage.getSearchResultsBlock(), exists()); } 41
  • 111. Матчеры в тестах @Test public void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); assertThat(searchResultsPage.getSearchResultsBlock(), both(exists()).and(isDisplayed())); } 42
  • 112. Матчеры в тестах @Test public void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); String message = String.format( "Элемент '%s' должен присутсвовать на странице", searchResultsPage.getSearchResultsBlock() ); assertThat(message, searchResultsPage.getSearchResultsBlock(), exists()); } 43
  • 113. Матчеры в тестах @Test public 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. Именование элементов @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. Именование элементов @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. Именование элементов @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. Именование элементов 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. Именование элементов 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. Имена в тестах @Test public void shouldSeeSearchResultsWhenLookingUp() { searchPage.searchFor("SQA Days"); String message = String.format( "Элемент '%s' должен присутсвовать на странице", searchResultsPage.getSearchResultsBlock() ); assertThat(message, searchResultsPage.getSearchResultsBlock(), exists()); } Assert: Элемент “Блок результатов поиска” должен присутствовать на странице 46
  • 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. Динамические селекторы @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
  • 130. Понятные логи 1.Ввожу в элемент “Поисковая строка” текст “SQA Days”... 54
  • 131. Понятные логи 1.Ввожу в элемент “Поисковая строка” текст “SQA Days”... 2.Кликаю на элемент “Кнопка ‘Найти’”... 54
  • 132. Понятные логи 1.Ввожу в элемент “Поисковая строка” текст “SQA Days”... 2.Кликаю на элемент “Кнопка ‘Найти’”... 3.Проверяю наличие элемента “Блок результатов поиска”... 54
  • 133. Понятные логи 1.Ввожу в элемент “Поисковая строка” текст “SQA Days”... 2.Кликаю на элемент “Кнопка ‘Найти’”... 3.Проверяю наличие элемента “Блок результатов поиска”... Assert: Элемент “Блок результатов поиска” должен присутствовать на странице 54
  • 135. Генерация блоков Страница 55
  • 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. И другое многое будет там 56
  • 138. 57
  • 140. https://github.com/yandex-qatools/htmlelements qa-tools@yandex-team.ru 57
  • 141. Cпасибо starlight@yandex-team.ru @alex_tolmachev