[Из песочницы] Создание инструмента для быстрого и эффективного написания автотестов на Selenium

Фундаментальный строительный блок автоматизации — тестирование
Род Джонсон

image

Я не амбассадор автоматизации тестирования веб интерфейсов, однако сей очерк скорее будет полезен камрадам, уже имеющим опыт в этой сфере.

Для совсем новичков также будет полезно, т.к. я предоставляю исходный код, где можно посмотреть, как в конечном продукте организовано взаимодействие с селениумом.

Я расскажу о том, как с нуля, имея небольшой опыт разработки, написал платформу для запуска тестов, и о самой платформе. Сам я считаю, что мой продукт получился весьма эффективным, а значит будет многим полезен и имеет место для рассмотрения.

Концепции


Процесс тестирования зависит от информационной системы.

Для поминания моей концепции, необходимо понять на какие системы я ориентируюсь в первую очередь — это те системы, где обычно существуют конкретные линейные бизнес-процессы, которые и ставятся ключом при проведении регрессионных тестов.

Итак, система типа srm. Ключевая бизнес-сущность — коммерческие предложения поставщика. Ключевое внимание при проведении регрессионного тестирования — целостность бизнес-процесса.
Бизнес-процесс начинается от регистрации поставщика в системе, далее идет создание коммерческого предложения — идет на этап рассмотрения, который производится различными типами внутренних пользователей (и для каждого пользователя уникальный интерфейс) до возврата решения о рассмотрения предложения поставщику.

Получается, что мы проходим через ряд разных интерфейсов, и практически всегда работаем с разными. На деле — если просто взглянуть на это прямо — это похоже на просмотр видеокассеты — т.е. это именно процесс, имеющий начало и конец, и он абсолютно линейный — никаких ветвлений, при написании теста мы всегда знаем ожидаемый результат. Т.е. я хочу сказать, что уже глядя на это картину, можно заключить, что сделать тесты полиморфными вряд ли получится. Ввиду этого при создании платформы для запуска тестов, ключевым фактором я поставил скорость написания тестов.

Концепции, которые я перед собой поставил:

  1. Автотест должен создаваться максимально быстро на сколько это возможно. Если добиться этого качественно, то остальные аспекты, такие как надежность и удобство использования, должны прийти сами собой.
  2. Тесты должны быть объявлены декларативно и жить отдельно от кода. Иного варианта я даже не увидел. Это увеличивает скорость написания, т.к. при наличие готового интерпретатора — нашей платформы, не надо потом ничего дописывать, не надо лезть лишний раз в код — вообще после готовой платформы по IDE можно забыть. Так тесты проще сопровождать. В таком виде их проще научить писать, т.к. не нужны навыки разработки, а лишь понимание языка разметки. В таком виде они понятны всем участникам процесса.


От чего я решил отказаться уже на старте:

  1. НЕ оборачивать свою систему в тестовый фреймворк. Запустить выполнение того или иного процесса можно и без тестового фреймворка. «Ты хочешь изобрести велосипед!», — скажут многие. Я рассуждаю по-другому. Популярные используемые тестовые фреймворки создавались в первую очередь для тестирования кода изнутри, а мы собираемся тестировать внешнюю часть системы снаружи. Это как если у меня есть шоссейный велосипед, а мне нужно спуститься с горы по бездорожью (грубо, но ход мыслей отражает). В общем фреймворк будем писать сами — с блек джеком и … (хотя я в курсе что, например, JUnit 5 уже в гораздо большей степени адаптирован под такого рода задач).
  2. Отказ от использования оберток для селениума. Собственно, ключевая библиотека сама по себе небольшая. Чтобы понять, что нужно использовать 5 процентов ее функциональности, при этом перелопатив ее полностью, потребуется несколько часов. Хватит везде искать способ писать меньше кода и приучать себя к горшку. В современном мире это желание часто приводит к абсурду и почти всегда дает ущерб гибкости (я имею ввиду именно подходы к «написать меньше кода», а не случаи архитектурных фреймворков).
  3. Красивое оформление результатов не нужно. Внес данный пункт, т.к. уже не однократно сталкиваюсь с этим. Когда автотест выполнился, мне нужно знать 2 вещи: общий результат (положительный/отрицательный), и, если была ошибка — где именно. Возможно еще надо вести статистику. Все остальное в плане результатов — АБСОЛЮТНО не существенно. Рассматривать красивое оформление как существенный плюс, либо тратить на это красивое оформление время на начальных этапах — лишние понты.


Немного еще расскажу об уровне разработки в компании и условиях создания инструмента дабы до конца внести в ясность в некоторые детали.

В силу неких конфиденциальных обстоятельств я не раскрываю компанию, где работаю.

В нашей компании разработка существует уже далеко не первый год, и стало быть все процессы уже давно налажены. Однако, они сильно отстают от современных тенденций.
Все представители айти понимают, что надо покрывать код тестами, писать сценарии автотестов в момент согласования требований к будущей функциональности, гибкие технологии существенно экономят время и ресурсы, а CI который просто берет и упрощает жизнь. Но это все пока только медленно доходит до нас…

Так и служба контроля качества ПО — все тесты выполняются мануально, если взглянуть на процесс «сверху» — то это «горлышко бутылки» всего процесса разработки.

Описание сборки


Платформа написана на языке Java с использогванием JDK 12

Основные инфраструктурные инструменты — Selenium Web Driver, OJDBC

Для работы приложения на ПК должен быть установлен браузер FireFox версии выше 52

Состав сборки приложения


image

С приложением в обязательном порядке идет 3 папки и 2 файла:

• папка BuildKit — содержит:

  • jdk12, при помощи которого осуществляется запуск приложения (JVM);
  • geckodriver.exe — для работы Selenium Web Driver с браузером FireFox;
  • SprintAutoTest.jar — непосредственно инстанс приложения


• папка Reports — в нее сохраняются отчеты после завершения выполнения приложением тест кейса. Также должна содержать папку ErrorScreens, куда сохраняется скриншот в случае возникновения ошибки

• папка TestSuite — веб пакеты, яваскрипты, набор тест кейсов (о заполнении данной папке будет подробно рассказано отдельно)

• файл config.properties — содержит конфиг для подключения к БД Oracle и значения явных ожиданий для WebDriverWait

• starter.bat — файлик для запуска приложения (возможен автоматический запуск приложения без ручного указания TestCase если в конце ввести в качестве параметра ввести имя TestCase).

Краткое описание работы приложения


Приложение может быть запущено с параметром (имя TestCase) либо без него — в этом случае необходимо ввести имя тест кейса в консоли самостоятельно.

Пример общего содержания bat файла, для запуска без параметра: start «AutoTest launcher» %cd%\BuildKit\jdk-12\bin\java.exe -Xmx768M -jar --enable-preview %cd%\BuildKit\SprintAutoTest.jar

При общем запуске приложения, оно просматривает xml файлы, находящиеся в директории »\TestSuite\TestCase» (без просмотра содержания вложенных папок). При этом происходит первичная валидация xml файлов на корректность структуры (т.е. что все теги с точки зрения разметки xml указаны верно), и берутся названия, указанные в теге «testCaseName», после чего пользователю предлагается ввести один из возможных вариантов имен имеющихся тест кейсов. В случае ошибочного ввода система попросит ввести имя повторно.

После того как будет получено имя TestCase, выполняется построение внутренней модели, которая представляет из себя связку TestCase (тестовый сценарий) — WebPackage (хранилище элементов) в виде java объектов. После построения модели строится непосредственно TestCase (исполняемый объект программы). На этапе построения TestCase также происходит вторичная валидация — проверяется что все указанные формы в TestCase имеются в связанном WebPackage и что все элементы, указанные в action, имеются в WebPackage в рамках указанных страниц. (О структуре TestCase и WebPackage подробно описано ниже)

После того, как будет построен TestCase, происходит непосредственно запуск сценария

Алгоритм работы сценария (ключевая логика)


TestCase представляет из себя набор сущностей Action, который в свою очередь представляет из себя набор сущностей Event.

TestCase
→ List{Action}
→ List{Event}

При запуске TestCase происходит последовательный запуск Action (каждый Action возвращает логический результат)

При запуске Action происходит последовательный запуск Event (каждый Event возвращает логический результат)

По результату выполнения каждого Event сохраняется результат

Соответственно тест завершается либо, когда все действия были выполнены успешно, либо если Action вернул false.

*Механизм сбоя

Т.к. моя тестируемая система древняя и имеет отлавливаемые ошибки/глюги, которые не являются ошибками, и некоторые события не срабатывают с первого раза, в платформе реализован механизм, который может отходить от вышеописанной концепции жестко линейного теста (однако он жестко типизирован). При отлавливании таких ошибок предусмотрена возможность повторения кейсов сначала и выполнения дополнительных действий для возможности повтора действий

По окончанию работы приложения происходит формирование отчета, который сохраняется в директорию »\Reports». В случае возникновение ошибки делается скриншот, который сохраняется в »\Reports\ErrorScreens»

Заполнение TestSuite


Итак, описание теста. Как уже говорилось, основной параметр, необходимый для запуска — имя теста, который следует запустить. Это имя хранится в xml файле в директории »/TestSuite/TestCase». В данной директории хранятся все тестовые сценарии. Их здесь может быть сколько угодно. Имя тест кейса берется не из имени файла, а из тега «testCaseName» внутри файла.

В TestCase задается что именно будет делаться — т.е. действия. В директории »/TestSuite/WebPackage» в xml файлах хранятся все локаторы. Т.е. все в лучших традициях — действия хранятся отдельно, локаторы веб форм отдельно.

В TestCase также хранится имя WebPackage в теге «webPackageName».

Итого картина уже есть. Для запуска необходимо наличие 2-ух xml файлов: TestCase и WebPackage. Они составляют связку. WebPackage независим — в качестве идентификатора указывается имя в теге «webPackageName». Соответственно вот и первое правило — имена TestCase и WebPackage должны быть уникальными. Т.е. еще раз — по сути наш тест — это связка файлов TestCase и WepPackage, которые связаны именем WebPackage, которое указывается в TestCase. На практике я автоматизирую одну систему и все свои тест кейсы вяжу к одному WebPackage в котором у меня до кучи описание всех форм.

Следующий слой логической декомпозиции основан на таком паттерне, как Page Object.

Page Object
Page Object — один из наиболее полезных и используемых архитектурных решений в автоматизации. Данный шаблон проектирования помогает инкапсулировать работу с отдельными элементами страницы. Page Object как бы моделирует страницы тестируемого приложения в качестве объектов.

Разделение логики и реализации

Существует большая разница между логикой тестирования (что проверить) и его реализацией (как проверить). Пример тестового сценария: «Пользователь вводит неверный логин или пароль, нажимает кнопку входа, получает сообщение об ошибке». Этот сценарий описывает логику теста, в то время как реализация содержит в себе такие действия как поиск полей ввода на странице, их заполнение, проверку полученной ошибки и т.д. И если, например, измениться способ вывода сообщения об ошибке, то это никак не повлияет на сценарий теста, все также нужно будет ввести неверные данные, нажать кнопку входа и проверить ошибку. Но это напрямую затронет реализацию теста — необходимо будет изменить метод получающий и обрабатывающий сообщение об ошибке. При разделении логики теста от его реализации автотесты становятся более гибкими и их, как правило, легче поддерживать.

*! Нельзя говорить о том, что данный архитектурный подход применен полностью. Речь идет лишь о декомпозиции описания тестового сценария постранично, что помогает писать тесты быстрее и добавлять дополнительные автопроверки на всех страницах, стимулирует к правильному описанию локаторов (чтобы они не были одинаковыми на разных страницах) и строит «красивую» логическую структуру теста. Сама платформа реализована на принципах «Чистой архитектуры»



Далее я постараюсь подробно не расписывать структуру WebPackage и TestCase. Для них я создал DTD схему для WebPackage и XSD 1.1 для TestCase.

! ВАЖНО


За счет ведения DTD и XSD схем осуществляется концепция быстрого написания теста.

При написании непосредственно WebPackage и TestCase необходимо использовать xml Editor со встроенными функциями валидации DTD и XSD в реальном времени с автогенерацией тегов, что сделает сам процесс написания авто теста в значительной мере автоматизированным (все обязательные теги будут подставлены автоматически, для значений атрибутов будут выданы выпадающие списки возможных значений, под тип ивента будут сгенерированы соответствующие теги)

.

Когда эти схемы «прикручиваются» к самому xml файлу, то можно забыть про корректность структуры xml файла, если использовать специальную среду. Мой выбор пал на oXygen XLM Editor. Еще раз — без использования подобной проги, вы не поймете суть скорости написания. Idea для этого не очень подходит т.к. в ней не обрабатывается конструкция XSD 1.1 «alternative», которое имеет ключевое значение для TestCase.

WebPackage


WebPackaege — xml файл, описывающий элементы веб форм, находится в директории »\TestSuite\WebPackage». (может быть сколько угодно много файлов. Название файлов может быть любым — значение имеет только содержание).

DTD (вставляется в начало документа):

        
        
            
            
            
                
                
                
                
                
                
        ]>


В общем виде выглядит примерно

    уникальное_название
    
        
пустая_форма_авторизации_при_открытии_тестового_приложения наименование_элемента .//div/form/div/div/form/table/tbody/tr/td[text()="Логин"]/following-sibling::td/input наименование_другого_элемента .//div/form/div/div/form/table/tbody/tr/td[text()="Логин"]/following-sibling::td/input .......
.......


Как уже говорилось, чтобы элементы были не в кучи — все декомпозировано по веб формам

Ключевой сущностью является


Тег element имеет 2 атрибута:

  • type
  • alwaysVisible


Атрибут type является обязательным и задает тип элемента. В платформе задается типом byte

На текущей момент конкретно для себя в платформе реализовал следующие типы:

• 0 — не имеет функционального смысла, обычно какая-то надпись
• 1 — кнопка (button)
• 2 — поле ввода (input)
• 3 — чекбокс (checkBox)
• 4 — выпадающий список (select) — на самом деле не реализован, но место под него оставил
• 5 — для выпадающего списка srm: пишем название, дожидаемся появления значения — выбираем по конкретному xpath шаблону — тип конкретно под мою систему
• 6 — srm select — используется на типовых функциях типа поиска и т.д. — тип конкретно под мою систему

Атрибут alwaysVisible — необязательный — показывает присутствует ли элемент на форме всегда, может использоваться при начальной/конечной валидации Action (т.е. в автоматическом режиме можно проверить, что при открытии формы на ней присутствуют все элементы, которые есть на ней всегда, при закрытии формы, все эти элементы исчезли)

Возможные значения:

  • 0 — по умолчанию (или если атрибут не задан) — элемент может отсутствовать на странице (не валидировать)
  • 1 — элемент всегда присутствует на странице


Дополнительный необязательный атрибут type реализован у тега locator

Возможные значения:

  • 1 — поиск элемента по id (соответственно в локаторе указать только id)
  • 2 — по умолчанию (или если атрибут не задан) — поиск по xpath — рекомендуется использовать только поиск по xpath, т.к. данный метод сочетает в себе практически все преимущества остальных и является универсальным


TestCase


TestCase — xml файл, описывающих непосредственно сценарий тестирования, находится в директории »\TestSuite\TestCase» (может быть сколько угодно много файлов. Название файлов может быть любым — значение имеет только содержание).

XSD схема:

	
	
		
			
				
				
				
			
		
	
	
	
		
			
		
	
	
	
		
			
			
			
		
	
	
	
		
			
			
			
			
		
		
			
				
					
					
				
			
		
		
			
				
					
					
				
			
		
	
	
	
		
			
		
		
			
				
					
					
					
					
					
					
					
					
					
					
					
					
				
			
		
		
			
				
					
					
				
			
		
		
			
				
					
					
				
			
		
	
	
	
		
			
				
				
				
				
				
				
				
				
				
				
				
				
			
		
	
	
	
	
	
		
			
				
					
				
			
		
	
	
	
		
			
				
					
				
			
		
	
	
	
		
			
				
					
				
			
		
	
	
	
		
			
				
					
				
			
		
	
	
	
		
			
				
					
				
			
		
	
	
	
		
			
				
					
				
			
		
	
	
	
		
			
				
					
					
				
			
		
	
	
	
	
	
		
			
				
					
						
						
					
				
			
		
	
	
	
		
			
				
					
						
						
					
				
			
		
	
	
	
		
			
				
					
						
							
							
							
						
					
				
			
		
	



Общий вид:



    уникальное_наименование_testCase
    название_webPackage_из_webPackageName
    
        
        
            Вход через пустую форму авторизации в интерфейс КМа для инициализации приложения
            10
            
                пустая_форма_авторизации_при_открытии_тестового_приложения
                
                    
                        10
                        &srmURL;
                    
                    .......        
                
            
        
    .......
    


Вот в этой строчке видно как прикрутить xsd схему чтобы XML Editor ее видел:


В TestCase я также использую сущности DTD, которые хранятся отдельно в той же директории — файлик с расширением .dtd. В нем я храню практически все данные — константы. Также я построил логику таким образом, что чтобы запустить новый тест, и по ходу всего теста создавались новые уникальные сущности, регистрировался новый КА, достаточно поменять 1 цифру в этом файле.

Структура его очень проста — приведу пример:





В значение тега такие константы вставляются так:

&srmURL;


— можно комбинировать.

! Рекомендация — при написании testCase следует указывать эти сущности DTD внутри документа, и уже после того, как все стабильно заработает, переносить в отдельный файлик. У моего xml editor-а с этим сложности — он не может найти DTD и не берет во внимание XSD, поэтому рекомендую так

testCase

testCase — самый родительский тег содержит:

  • testCaseName — имя нашего тест кейса, именно этот параметр передается на вход приложению
  • webPackageName — имя WebPackage, которое указано в webPackageName (см пп выше о WebPackage)
  • actions — контейнер сущностей action


action

Содержит:

  • name — имя — рекомендуется указывать имя формы и ключевые действия — что и зачем
  • orderNumber — порядковый номер — параметр необходимый для сортировки action (введен в связи с тем, что при разборе xml в java при использовании определенных инструментов разбор может быть осуществлен в многопоточной среде, в связи с чем порядок может поехать) — при указании следующего action можно перепрыгивать — т.е. имеет при сортировке имеет значение только «больше/меньше», а так можно доставлять action между уже описанными без необходимости менять всю нумерацию
  • runConfiguration — собственно описание того, что будет происходить в рамках action


runConfiguration

Содержит:

  • атрибут openValidation — необязательный, по умолчанию »0»
    • 0 — не проводить начальную валидацию формы
    • 1 — произвести начальную валидацию формы
  • атрибут closeValidation — необязательный, по умолчанию »0»
    • 0 — не проводить конечную валидацию формы
    • 1 — произвести конечную валидацию формы
  • formName — имя формы в рамках которой будут проводиться действия — значение formName из WebPackage
  • repeatsOnError — необязательный, указывается какое количество повторов необходимо произвести в случае сбоя
  • events — контейнер сущностей event
  • exceptionBlock — необязательный — контейнер сущностей event, которые выполняются в случае ошибки


event

Минимальная структурная единичка — данная сущность показывает, какие действия совершаются

Каждый event особенный, может иметь уникальные теги и атрибуты.

Базовый тип содержит:

  • атрибут type — указывается тип элемента
  • атрибут hasExceptionBlock — необязательный атрибут, по умолчанию »0» — необходим для реализации механизма сбоя — атрибут говорит о том, что на этом ивенте мы можем ожидать ошибку
    • 0 — не ожидается ошибка
    • 1 — ожидается возможная ошибка на действии
  • атрибут invertResult — необязательный атрибут, по умолчанию »0» — атрибут говорит о том, что необходимо поменять результат ивента
    • 0 — оставить результат выполнения ивента по факту
    • 1 — изменить результат ивента на противоположный


*! Механизм описания ожидаемой ошибки
Приведу банальный пример где это было использовано мной в первый раз и что сделать, чтобы он сработал.

Кейс: ввод капчи. Данный момент я не смог автоматизировать, так сказать проверка на робота пока подкашивает — не пишут мне тестовый сервис капчи (а мне самому уже проще сделать нейросеть для распознавания))) Так вот, мы можем ошибиться при вводе. На этот случай я делаю контрольный ивент, в котором проверяю, что у нас отсутствует элемент — уведомление о неверном контрольном коде, ставлю на нем атрибут hasExceptionBlock. Предварительно я задал на action, что у нас может быть несколько повторений (5) и после всего прописал exceptionBlock, в котором прописал, что надо нажать кнопку выхода из уведомления, после чего action повторяется.

Примеры из моего контекста.

Вот я как я прописал ивент:


	57
	
		
			уведомление_неверный_контрольный_код
		
	

А вот exceptionBlock после ивентов
 
	
		10
		кнопка_ок_для_выхода_из_уведомления
	

И да, действия на одной странице можно декомпозировать на несколько action.

+ кто заметил в конфиге 2 параметра: defaultTimeOutsForWebDriverWait, lowTimeOutsForWebDriverWait. Так вот зачем они. Т.к. весь веб драйвер у меня в синглтоне, и я не захотел создавать каждый раз новый WebDriverWait, то у меня 1 быстрый, и он на случай ошибки (ну или если вы просто поставите hasExceptionBlock=»1», то он тупо будет с меньшим количеством времени явного ожидания) — ну согласитесь, ждать минуту чтобы убедиться, что сообщение не вылезло не комильфо, как и создавать каждый раз новый WebDriverWait. Ну и эта ситуация с какой стороны не ткнись требует костылька — я решил сделать так.


Типы event


Здесь я приведу минимальный набор моих ивентов, типа набора бойскаута, с помощью которых я по своей системе могу протестить практически все.

И теперь плавненько к коду для понимания что такое ивент и как он строится. В коде по сути реализован фреймворк. У меня есть 2 класса — DataBaseWrapper и SeleniumWrapper. В этих классах описано взаимодействие с инфраструктурными компонентами, а также отражаются особенности платформы. Приведу интерфейс, который реализует SeleniumWrapper

package logic.selenium;

import models.ElementWithStringValue;
import models.webpackage.Element;
import org.openqa.selenium.WebElement;


public interface SeleniumService {
    void initialization(boolean webDriverWait);

    void nacigateTo(String url);
    void refreshPage();
    boolean checkElementNotPresent(Element element);
    WebElement findSingleVisibleElement(Element element);
    WebElement findSingleElementInDOM(Element element);
    void enterSingleValuesToWebField(ElementWithStringValue element);
    void click(Element element);
    String getInputValue(Element element);
    Object jsReturnsValue(String jsFunction);
    //Actions actions
    void doubleClick(Element element);
    void moveMouseToElement(Element element);
    void pressKey(CharSequence charSequence);
    void getScreenShot(String storage);
}


В нем описываются все возможности селениума и накладываются фишки платформы — ну собственно основная фишка — это метод «enterSingleValuesToWebField». Помните, что мы в WebPackage указываем тип элемента. Так вот, то как на этот тип реагировать при заполнении полей прописано тут. Пишем 1 раз и забываем. Вышеуказанный метод стоит поправить под себя в первую очередь. К примеру типы 5 и 6, ныне действующие — подходят только для моей системы. А если у вас есть такая штука как фильтр и надо много фильтровать, и он типовой (в вашем веб приложении), но, чтобы им воспользоваться надо сначала навести мышку на поле, дождаться появления каких-то полей, перейти на какое-то, дождаться там чего-то, затем перейти туда и ввести… Тупо прописываете механизм действия 1 раз, даете уникальный тип этому всему в конструкции switch — далее не заморачиваетесь — получаете полиморфный метод на все аналогичные фильтры приложения.

Итак, в пакете «package logic.testcase.events» есть абстрактный класс, описывающий общие действия ивента. Для того чтобы создать свой уникальный ивент, необходимо создать новый класс, унаследоваться от этого абстрактного класса, и у вас уже в комплекте есть и dataBaseService и seleniumService –, а далее вы определяете какие данные вам нужны и что с ними делать. Как-то так. Ну и соответственно, после создания нового ивента надо допилить класс-фабрику TestCaseActionFactory и по возможности XSD схему. Ну и, если добавляется новый атрибут — доработать саму модель. На деле это очень легко и быстро.

Итак, набор бойскаута.

goToURL — обычно первое действие — переход по указанной ссылке

Пример:

	10
	testURL


fillingFields — Заполнение указанных элементов

Специальные теги:

  • fields — контейнер сущности fiel
    • field — содержит тег element
      • element — указывается имя элемента из webPackage
      • value — какое значение указать, имеет необязательный атрибут type (если елемент чекбокс, то указывается одно из значений: «check» или «uncheck»)


  • атрибут type — указывается каким образом взять значение, необязательный, значение по умолчанию — »1»
    • 1 — берется указанное значение
    • 2 — в этом случае выполняется указанная JS функция из директории »\TestSuite\JS»! ВАЖНО — указывается название txt файла, без ».txt» (и я пока нашел применения js функциям пока только в таком виде — использую в одном месте для генерации случайного инн, однако спектр возможного применения широк)
    • 3 — в этом случае указывается в качестве значения указывается запрос в БД, а программа подставляет в 1-ый результат данного запроса


Пример:

	10
	
		
			test
			test
		
	


checkElementsVisibility — проверяется, что указанные элементы присутствуют на форме (именно видимые, а не просто в DOM). В атрибуте field может быть указан или элемент из WebPackage или непосредственно xpath

Пример:

	10
	
		
			test
		
		
			test
		
	


checkElementsInVisibility — аналогичный checkElementsVisibility, но наоборот

clickElement — клик по указанному элементу

Пример:

	10
	test


checkInputValues — проверка введенных значений

Пример:

	10
	
		
			test
			test
		
	


dbUpdate — выполнить апдейт в базе (oXygen странно реагирует на 1 ивент типа dbUpdate — не знаю что с ним сделать и не понимаю почему)

Пример:

	10
	update что-то там


CheckQueryResultWithUtilityValue — проверка введенного пользователем значения с значением из БД

Пример:

	10
	select ...
	test


checkFieldsPresenceByQueryResult — проверка наличия элементов на форме по xpath по паттерну. Если желаемы паттерн не указан, то поиск произойдет по паттерну .//*[text ()[contains (normalize-space (.),»$»)]], где вместо »$» будет значение из БД. При описании собственного паттерна, на то место, куда следует поставить значение из БД — надо указать »$». В моей системе есть так называемые гриды в которых бывают значения, которые как правило формируются из какой-то вьюхи. Этот ивент для проверки таких гридов

Пример:

	10
	test
	


Wait — все просто — ожидание указанного количества милисекунд. К сожалению, хоть это и принято считать костылем, скажу точно — иногда без него невозможно обойтись

Пример:

	10
	1000


scrollDown — скрол вниз от указанного элемента. Делается так: кликается по указанному элементу и типа нажимается клавиша «PgDn». В моих кейсах, где мне надо было скрольнуть вниз работает отлично:

Пример:

	10
	test


userInput — ввод значения в указанный элемент. Единственный полуавтомат в моей автоматизации, используется только для капчи. Указывается элемент, в который надо ввести значение. Значение вводится в всплывшее диалоговое окошко.

Пример:

	10
	capch_input


Про код


Значит, я старался сделать платформу в соответствии с принципами Чистой архитектуры дядюшки Боба.

Пакеты:

application — инициализация и запуск + конфиги и отчет (не ругайте меня за класс Report — вот что максимально на скорую руку, то максимально на скорую руку)

logic — ключевая логика + сервисы Селениума и БД. Тут же ивенты.

models — POJO на XML и все вспомогательные классы-объекты

utils

© Habrahabr.ru