cucumber

GUI Automation Framework. Based on Selenium WebDriver and AllureReporter

License

License

Categories

Categories

Cucumber Application Testing & Monitoring
GroupId

GroupId

ru.iopump.pumpfw
ArtifactId

ArtifactId

cucumber
Last Version

Last Version

0.2.1
Release Date

Release Date

Type

Type

jar
Description

Description

cucumber
GUI Automation Framework. Based on Selenium WebDriver and AllureReporter
Project URL

Project URL

https://github.com/kochetkov-ma/pump-fw
Source Code Management

Source Code Management

https://github.com/kochetkov-ma/pump-fw

Download cucumber

How to add to project

<!-- https://jarcasting.com/artifacts/ru.iopump.pumpfw/cucumber/ -->
<dependency>
    <groupId>ru.iopump.pumpfw</groupId>
    <artifactId>cucumber</artifactId>
    <version>0.2.1</version>
</dependency>
// https://jarcasting.com/artifacts/ru.iopump.pumpfw/cucumber/
implementation 'ru.iopump.pumpfw:cucumber:0.2.1'
// https://jarcasting.com/artifacts/ru.iopump.pumpfw/cucumber/
implementation ("ru.iopump.pumpfw:cucumber:0.2.1")
'ru.iopump.pumpfw:cucumber:jar:0.2.1'
<dependency org="ru.iopump.pumpfw" name="cucumber" rev="0.2.1">
  <artifact name="cucumber" type="jar" />
</dependency>
@Grapes(
@Grab(group='ru.iopump.pumpfw', module='cucumber', version='0.2.1')
)
libraryDependencies += "ru.iopump.pumpfw" % "cucumber" % "0.2.1"
[ru.iopump.pumpfw/cucumber "0.2.1"]

Dependencies

compile (22)

Group / Artifact Type Version
com.google.inject : guice jar 4.2.2
io.appium : java-client jar 6.1.0
joda-time : joda-time jar 2.10.1
com.google.code.findbugs : jsr305 jar 3.0.2
org.apache.httpcomponents : httpclient jar 4.5.6
org.reflections : reflections jar 0.9.11
commons-collections : commons-collections jar 3.2.2
com.google.guava : guava jar 27.0.1-jre
org.apache.commons : commons-lang3 jar 3.8.1
commons-io : commons-io jar 2.6
org.apache.commons : commons-text jar 1.6
ch.qos.logback : logback-classic jar 1.2.3
ch.qos.logback : logback-core jar 1.2.3
org.seleniumhq.selenium : selenium-java jar 3.141.59
io.qameta.allure : allure-java-commons jar 2.8.1
net.sf.trove4j : trove4j jar 3.0.3
io.cucumber : cucumber-guice jar 4.2.2
io.cucumber : cucumber-java8 jar 4.2.2
junit : junit jar 4.12
io.qameta.allure : allure-cucumber3-jvm jar 2.8.1
ru.iopump.pumpfw : web jar 0.2.1
ru.iopump.pumpfw : commons jar 0.2.1

test (5)

Group / Artifact Type Version
org.junit.jupiter : junit-jupiter-api jar 5.3.2
org.assertj : assertj-core jar 3.11.1
org.mockito : mockito-core jar 2.23.4
io.cucumber : cucumber-junit jar 4.2.2
org.junit.jupiter : junit-jupiter-engine jar 5.3.2

Project Modules

There are no modules declared in this project.

Pump FW

Описание

Фреймворк для автоматизации тестирования web приложений основанный на Selenium WebDriver Является дополнительным слоем между пользователем фреймворка и WebDriver Полностью исключает работу с WebDriver и предоставляет интерфейс для взаимодействия с браузером и веб элементами Включает модель работы со станицами Page Object

Организация проекта

Монорепозиторий

На текущи момент содержит 2 под-проекта

  • Под-проект commons, который содержит общие классы не привязанные к web
  • Под-проект web, который содержит Функционал для взаимодействия с браузером, страницей и реализации основных web элементов

Система сборки - gradle

Юнит-тесты junit5, web тестируется на PhantomJS и Chrome. На самом деле почти все тесты интеграционные

Используются Idea аннотации @Nullable и @NonNull

Логгер Logback

Особенности

Под-проект commons включает все необходимые модули и зависимости для быстрого создания автотестов

  • Reporter - реализация на основе Allure
  • Verifier - замена ассертов, постинг сообщений в Reporter
  • Waiter - ожидания, которые возвращают параметризованный WaitResult. Замена ожиданий Selenium
  • PumpException - собственная реализация Исключений
  • PumpMessage - Форматированные сообщения для вывода в консоль
  • ConfigurationsLoader - удобная загрзка конфигурация из properties с маппингом на java объект

Под-проект web предоставляет сущности для создания тестов web на основе подхода Page Object

Пакет ru.mk.pump.web.browsers
  • Browser и AbstractBrowser - Интерфейс и реализация для доступа к браузеру. Изолирует работу с WebDriver от пользователя
  • Browsers - менеджер браузеров
  • AbstractDriverBuilder - билдер для создания экземпляра WebDriver. Можно расширять кол-во поддерживаемых реализаци WebDriver
Пакет ru.mk.pump.web.elements - Доступ к элементам на web странице.
  • Element и BaseElement - Интерфейс и реализация для доступа элементам. Автоматизирует все проверки перед выполнением действия над элементом и упрощает взаимодействие. Обеспечивает логирование и репортинг с помощью слушателей.
    Все пользовательские элементы необходимо наследовать от BaseElement
    Все пользователькие интерфейсы элементов необходимо наследовать от Element
  • api.annotations - Аннотации-маркеры для выбора из нескольких реализаций одного интерфейса элемента
  • ActionListener и StateListener - Слушатели для статусов элементов и действий над элементами
  • ElementFactory - Фабрика элементов для использования в Page Object инициализации. Расширяемая
Пакет ru.mk.pump.web.page - web Страница. Автоматизирует проверки статуса загрузки старницы и упрощает работу со страницей для пользователя
  • ru.mk.pump.web.page.api.Page и BasePage - Интерфейс старницы и базовая реализация для наследования
  • ru.mk.pump.web.page.api.PageLoader и PageLoader - Все ожидания вынесены в отдельный интерфейс с базовой реализацией. Инстанс хранится в BasePage
ru.mk.pump.web.component - общие сущности для возможности создания неограниченной иерархии вложенных элементов (и списков элементов) в странице
ru.mk.pump.web.common - поддержка page object
  • Initializer - реализация org.openqa.selenium.support.pagefactory.FieldDecorator для иницализации элементов страницы. Без использования java.lang.reflect.Proxy (это плюс)
  • api.annotations - аннотации для полей с элементами на странице, в том числе аналоги FindBy и FindBys
  • ru.mk.pump.web.common.api.PageItemImplDispatcher - Диспетчер реализаций элементов. Загрущает и хранит интефрйсы и их реализации. Поддерживате возможность добавления пользовательских реализаций

Для настройки элементов используются параметры вида Parameters

  • В паттерне Page Object для передачи параметров в элемент необходимо воспользоваться аннотациями из пакета ru.mk.pump.web.common.api.annotations
  • либо методом ru.mk.pump.web.elements.internal.BaseElement.withParams
  • элемент сам выбирает поддерживаемые параметры и записывает их в свои поля для дальнейшего использования
  • параметры описаны в ru.mk.pump.web.constants.ElementParams и в java-doc если присутствует аннотация ru.mk.pump.web.elements.internal.DocParameters

Для настройки элементов используются параметры вида Parameters

Ожидает реализации

  • менеджер страниц
  • менеджер конфигураций фреймворка
  • отдельный проект - интеграция с cucumber
  • отдельный проект - параллельный раннер для cucumber и перезапуск проваленных тестов
  • дополнение юнит-тестов
  • поддержка сборки под Windows и Linux без установленных браузеров Chrome и PhantomJS (для юнит-тестов)

Quick Start

Добавить в зависимости

maven

не реализовано

gradle

не реализовано

Создать класс Страницы Web Приложения унаследованный от ru.mk.pump.web.page.BasePage

    /**
     * Страница наследуется от {@link BasePage}.
     * Все приватные поля - это элементы либо компоненты
     */
    @Title(value = "Регистрация", desc = "Страница регистрации Цифровая Ипотека")
    class RegPage extends BasePage {

        /**
         * Элемент TextArea.
         * Стандартная аннотация FindBy.
         * Аннотация {@link Title} определяет заголовок (имя) элемента и описание.
         */
        @FindBy(tagName = "h2")
        @Title(value = "Заголовок", desc = "Главный заголовок страницы")
        @Getter
        private TextArea pageTitle;

        /**
         * Элемент наследник BaseComponent. Это отдельный класс - кусок страницы, который объединяет несколько элементов.
         * Для него доступны все методы {@link Element}
         * Стандартная аннотация FindBy.
         * Аннотация {@link Title} определяет заголовок (имя) элемента (компонента) и описание.
         */
        @Title("Форма")
        @FindBy(className = "mainlayout")
        @Getter
        private RegMainForm mainForm;

        /**
         * Элемент общего интерфейса Element. Когда не важен конкретный класс элемента.
         * Стандартная аннотация FindBy.
         * Аннотация {@link Title} определяет заголовок (имя) элемента и описание.
         * Этот элемент не существует на реальной странице, но удачно будет инициализирован.
         * Ошибок не возникнет до взаимодействия.
         */
        @Title("Не существующий")
        @FindBy(className = "mainlayout11")
        @Getter
        private Element notExists;

        /**
         * Конcтруктор страницы. PUBLIC. Все конструкторы страниц, компонентов и элементов - PUBLIC!!!
         * @param browser Браузер
         */
        public RegPage(Browser browser) {
            super(browser);
            setName("Регистрация");
            /*установить url*/
            setUrl(DMUrls.REG_PAGE_URL);
            /*установить проверку с ожиданием на присутствие в DOM элемента после открытия*/
            getPageLoader().addExistsElements(pageTitle);
            /*установить проверку с ожиданием на отображение элементов после открытия*/
            getPageLoader().addDisplayedElements(pageTitle, mainForm);
        }

        /**
         * Класс компонента. Наследуется от {@link BaseComponent} - это часть страницы. Объекдиняет несколько элементов.
         * В данном случае это форма с множеством полей ввода и кнопок. Но описано только несколько.
         * Аннотация {@link Title} читается не из класса компонента, а из поля, в котором он объявлен на странице!
         * Не забываем про static для внутренних классов!
         */
        static class RegMainForm extends BaseComponent {

            /**
             * Список компонентов - это несколько зон в главной форме
             */
            @FindBy(xpath = "//div[@class='squished row form-group']")
            @Getter
            private List<RegFormZone> regFormZones;

            public RegMainForm(By avatarBy, Page page) {
                super(avatarBy, page);
            }
        }

        /**
         * Класс компонента. Наследуется от {@link BaseComponent} - это часть страницы. Объекдиняет несколько элементов.
         * В данном случае это одна из зон основной формы
         */
        static class RegFormZone extends BaseComponent {

            /**
             * Список компонентов - это несколько колонок в каждой зоне основной формы
             */
            @FindBy(xpath = "//div[contains(@class, 'column')]")
            @Getter
            private List<RegFormZoneColumn> regFormZoneColumns;

            public RegFormZone(By avatarBy, InternalElement parentElement) {
                super(avatarBy, parentElement);
            }
        }

        /**
         * Колонка в каждой из зон формы
         */
        static class RegFormZoneColumn extends BaseComponent {

            /**
             * Список элементов
             */
            @FindBy(tagName = "input")
            @Getter
            private List<Input> inputs;

            /**
             * Конечный элемент
             */
            @FindBy(className = "group-header")
            @Getter
            private TextArea header;

            @FindBy(id = "regionAutocompleteId")
            @Title(value = "Регион", desc = "Выбор региона из выпадающего списка")
            /*аннотация для определяния нескольких СТРОКОВЫХ параметров элемента*/
            @PStrings({
                /*один СТРОКОВЫЙ параметр*/
                @PString(name = "testParam1", value = "paramValue1"),
                @PString(name = "testParam2", value = "paramValue2")
            })
            /*аннотация для определяния нескольких параметров элемента типа Локатор*/
            @PFindBys({
                /*один параметр Локатор*/
                @PFindBy(name = "extraBy", value = {@FindBy(xpath = "//div")}),
                @PFindBy(name = "iddInputBy", value = {@FindBy(tagName = "input")}),
                @PFindBy(name = "iddDropDownBy", value = {@FindBy(xpath = ".")})
            })
            @Getter
            private InputDropDown inputDropDownRegions;

            public RegFormZoneColumn(By avatarBy, InternalElement parentElement) {
                super(avatarBy, parentElement);
            }
        }
    }

Создать браузер

Browsers browsers = new Browsers();
BrowserConfig config = new BrowserConfig(false, Size.of(true), BrowserType.CHROME);
Browser browser = browsers.newBrowser(config);

Создать страницу

RegPage page = new RegPage(browser);

Запустить браузер и открыть страницу

browser.start();
page.open();

Взаимодействие с элементом

/*Получить элемент Поле ввода*/
Input input = page.getMainForm().getRegFormZones().get(0).getRegFormZoneColumns().get(1).getInputs().get(2);
/*Информация об элементе - имя*/
input.info().getName();
/*Информация об элементе - описание*/
input.info().getDescription();
/*Ввод значения*/
input.type("MAX");
/*Получить текст*/
input.getText();
/*Получить элемент Выпадающий список с вводом*/
InputDropDown inputDropDown = page.getMainForm().getRegFormZones().get(2).getRegFormZoneColumns().get(1).getInputDropDownRegions();
/*Ввод текста и выбор из выпадающего списка введенного значения*/
inputDropDown.typeAndSelect("Москва");

Чтобы запустить из IDE со включенным логгером :
-javaagent:./../libs/aspectjweaver.jar

Versions

Version
0.2.1
0.2
0.1