Package: core-page
core-pageБиблиотека для автоматической работы с любыми веб-страницами и их элементами на базе Selenium.
Вдохновлена статьёй наХабри упрощает написание автоматических тестов
с реализацией паттернаPageObject. Ускорьте написание кода, а также сделайте его лаконичнее и яснее.ОписаниеЗачем нужна эта библиотека, если есть Selenium из коробки, который и предоставляет методы для работы со страницами веб-сайтов?
В процессе написания тестов, разработчик регулярно ищет элементы на странице, переходит на другие страницы,
получает аттрибуты и т.д.. Все это, как правило, оборачивается в ожидания, чтобы избежать внезапных ошибок.
Библиотека предоставляет базовый класс, методы которого позволяют скрыть часть этой логики, а также комбинируют в себе
различные инструменты базового Selenium, тем самым расширяя функциональность.
Благодаря этому, ускоряется написание тестов, их понимание и последующая поддержка.Преимущества перед использованием Selenium из коробки:Простое использование, путем наследования от базового класса в классы конкретных страниц.Возможность установить настройки для теста, просто передав их в аргументах класса.Базовые методы поиска элементов расширены и включают в себя явное ожидание.ОглавлениеУстановкаБыстрый стартДокументация классаСоздание объектаМетод go_to_siteМетод find_elementМетод find_elementsМетод custom_wait_untilМетод move_to_elementИспользование в PageObjectУстановкаУстановите core-page через pip:pipinstallcore-pageИспользование библиотеки подразумевает, что на вашем компьютере уже имеется chromedriver.
Если нет, то следует ознакомиться сруководством.Быстрый старт:Cоздаем файл для тестируемой страницы и импортируем класс BasePage.Создаем класс страницы и наследуемся от BasePage. Теперь нам доступны всеметодыбазового класса.# main_page.pyfrombase_page.base_pageimportBasePageclassMainPage(BasePage):passДалее, можем создать экземпляр нашего класса MainPage в тест-кейсе и передать необходимыенастройки.# test_main_page.pyfrompage_objectsimportMainPagedeftest_main_page_title():page=MainPage(base_url='https://example.com',window_size=(1366,768))page.go_to_site()...С более подробным примером можно ознакомится вразделе про Page Object.Документация классаСоздание объектаВсе возможные аргументы класса:driver- объект WebDriver.driver_fabric- класс WebDriver.base_url- адрес страницы без относительного пути.Перед адресом страницы должен быть указан протокол!Пример:https://google.comwindow_size- размер страницы браузера в формате(ширина, высота). По умолчанию установлено значение (1920, 1080).url_suffix- относительный путь к конкретной странице сайта. По умолчанию относительный путь отсутствует.При создании объекта есть два варианта:Без передачи собственного драйвера. В этом случае драйвер создается в конструкторе.page=MainPage(base_url='https://google.com')Обязательные аргументы:base_url;Необязательные аргументы:driver_fabric;window_size;url_suffix;По умолчанию будет создан драйвер для Chrome без опций. Если хотите использовать свой объект WebDriver,
то воспользуйтесь следующим вариантом.С передачей собственного объекта WebDriver.Для примера создадим свой объект WebDriver и передадим ему опции:fromseleniumimportwebdriveroptions=webdriver.ChromeOptions()options.add_argument('--headless')driver=webdriver.Chrome(options=options)page=MainPage.with_driver(driver=driver,base_url='https://google.com')Обязательные аргументы:driver;base_url;Необязательные аргументы:window_size;url_suffix;Метод go_to_siteОсуществляет переход по полному URL страницы (после объединенияbase_urlиurl_suffix).
Методgo_to_siteничего не принимает и не возвращает.frompage_objectsimportMainPagedeftest_some_element():page=MainPage(base_url='https://google.com',url_suffix='/doodles')page.go_to_site()# Переход на сайт https://google.com/doodlesМетод find_elementМетодfind_elementищет элемент на странице полокаторув течение определенного времени. Если элемент найден, то возвращает его.
Иначе выбрасывает TimeoutException.Принимает следующие аргументы:locator -локаторэлемента. Значения по умолчанию нет.duration - время в секундах, в течение которого будет осуществляться поиск элемента. Значение по умолчанию - 5 секунд.frompage_objectsimportMainPagedeftest_some_element():page=MainPage(base_url='https://google.com',url_suffix='/doodles')page.go_to_site()element=page.find_element(locator,duration=10)Метод find_elementsМетодfind_elementищет все элементы на странице полокаторув течение определенного времени. Если элементы найдены, то возвращает список из этих элементов.
Иначе выбрасывает TimeoutException.Принимает следующие аргументы:locator -локаторэлементов. Значения по умолчанию нет.duration - время в секундах, в течение которого будет осуществляться поиск элементов. Значение по умолчанию - 5 секунд.frompage_objectsimportMainPagedeftest_some_element():page=MainPage(base_url='https://google.com',url_suffix='/doodles')page.go_to_site()element=page.find_elements(locator)Метод custom_wait_untilМетодcustom_wait_untilпозволяет задавать ожидания на основе пользовательских условий. В случае, когда условие
ожидания, которое нам нужно, не предусмотрено Selenium, пользователь может сам задать условие ожидания на основе какой-либо функции.Принимает следующие аргументы:func_condition - функция предикат, в которой задано условие ожидания.duration - время в секундах, в течение которого будет выполняться ожидание.frompage_objectsimportMainPagedeftest_some_element():page=MainPage(base_url='https://google.com',url_suffix='/doodles')page.go_to_site()some_link=page.find_element(locator).click()page.custom_wait_until(lambdabrowser:browser.current_url!=page.url)Метод move_to_elementМетодmove_to_elementимитирует наведение мыши на элемент. Комбинирует внутри себя создание объектаActionChains,
наведение на элемент и выполнение действия (метод perform).Метод принимает один аргумент:element - объектWebElement, на который нужно выполнить наведение мыши.frompage_objectsimportMainPagedeftest_some_element():page=MainPage(base_url='https://google.com',url_suffix='/doodles')page.go_to_site()dropdown_menu=page.find_element(locator)page.move_to_element(dropdown_menu)...Использование вPageObjectИспользование паттернаPageObjectпозволяет упростить написание, поддержку
и масштабирование тестов. Базовый класс может в этом помочь.Допустим, нужно протестировать сайтhttps://www.python.org/. Он содержит множество страниц и элементов.
Паттерн подразумевает, что каждая страница будет представлена как отдельный класс с методами страницы.В таком случае, структура проекта может выглядеть следующим образом:project/
├── page_object/
│   ├── __init__.py
│   ├── main_page.py
│   └── about_page.py
├── tests/
│   ├── __init__.py
│   ├── test_main_page.py
│   └── test_about_page.py
├── ...
└── ...Рассмотрим файлabout_page.py. Он должен описывать методы, содержащие поиск элементов и взаимодействие с ними.Над классом страницы можно описать класс, содержащий локаторы элементов на странице.
В нашем случае, протестируем наличие поля для поиска по сайту.# about_page.pyfrombase_page.base_pageimportBasePagefromselenium.webdriver.common.byimportByfromselenium.common.exceptionsimportTimeoutExceptionclassAboutPageLocators:LOCATOR_SEARCH_FIELD=(By.ID,"id-search-field")classAboutPage(BasePage):defis_search_field(self):try:self.find_element(AboutPageLocators.LOCATOR_SEARCH_FIELD)returnTrueexceptTimeoutException:returnFalseПерейдем в файлtest_about_page.py. Здесь мы создаем тест-кейс, в котором проверяем сценарий, описанный в классе страницы.# test_about_page.pyfrompage_object.about_pageimportAboutPagedeftest_search_field_exist():page=AboutPage(base_url='https://www.python.org',url_suffix='/about',)page.go_to_site()search_field_exist=page.is_search_field()assertsearch_field_existБлагодаря такой структуре проекта и использованию паттерна, мы можем легко поддерживать и писать гибкие сценарии.
Даже при значительных изменениях тестируемой страницы, исправление тестов не займет много времени.