Skip to main content

Утилита для расширенного взаимодействия с любым веб-сайтом и его страницами

Project description

core-page

lib-tests PyPI version codecov

Библиотека для автоматической работы с любыми веб-страницами и их элементами на базе Selenium. Вдохновлена статьёй на Хабр и упрощает написание автоматических тестов с реализацией паттерна PageObject. Ускорьте написание кода, а также сделайте его лаконичнее и яснее.

Описание

Зачем нужна эта библиотека, если есть Selenium из коробки, который и предоставляет методы для работы со страницами веб-сайтов? В процессе написания тестов, разработчик регулярно ищет элементы на странице, переходит на другие страницы, получает аттрибуты и т.д.. Все это, как правило, оборачивается в ожидания, чтобы избежать внезапных ошибок. Библиотека предоставляет базовый класс, методы которого позволяют скрыть часть этой логики, а также комбинируют в себе различные инструменты базового Selenium, тем самым расширяя функциональность. Благодаря этому, ускоряется написание тестов, их понимание и последующая поддержка.

Преимущества перед использованием Selenium из коробки:

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

Оглавление

Установка

Установите core-page через pip:

pip install core-page

Использование библиотеки подразумевает, что на вашем компьютере уже имеется chromedriver. Если нет, то следует ознакомиться с руководством.

Быстрый старт:

Cоздаем файл для тестируемой страницы и импортируем класс BasePage.
Создаем класс страницы и наследуемся от BasePage. Теперь нам доступны все методы базового класса.

# main_page.py

from base_page.base_page import BasePage

class MainPage(BasePage):
    pass

Далее, можем создать экземпляр нашего класса MainPage в тест-кейсе и передать необходимые настройки.

# test_main_page.py

from page_objects import MainPage


def test_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.com
  • window_size - размер страницы браузера в формате (ширина, высота). По умолчанию установлено значение (1920, 1080).
  • url_suffix - относительный путь к конкретной странице сайта. По умолчанию относительный путь отсутствует.

При создании объекта есть два варианта:

  • Без передачи собственного драйвера. В этом случае драйвер создается в конструкторе.

    page = MainPage(base_url='https://google.com')
    

    Обязательные аргументы:

    • base_url;

    Необязательные аргументы:

    • driver_fabric;
    • window_size;
    • url_suffix;

    По умолчанию будет создан драйвер для Chrome без опций. Если хотите использовать свой объект WebDriver, то воспользуйтесь следующим вариантом.

  • С передачей собственного объекта WebDriver.
    Для примера создадим свой объект WebDriver и передадим ему опции:

    from selenium import webdriver
    
    
    options = 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 ничего не принимает и не возвращает.

from page_objects import MainPage


def test_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 секунд.
from page_objects import MainPage


def test_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 секунд.
from page_objects import MainPage


def test_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 - время в секундах, в течение которого будет выполняться ожидание.
from page_objects import MainPage


def test_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(lambda browser: browser.current_url != page.url)

Метод move_to_element

Метод move_to_element имитирует наведение мыши на элемент. Комбинирует внутри себя создание объекта ActionChains, наведение на элемент и выполнение действия (метод perform).

Метод принимает один аргумент:

  • element - объект WebElement, на который нужно выполнить наведение мыши.
from page_objects import MainPage


def test_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.py

from base_page.base_page import BasePage
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException


class AboutPageLocators:
    LOCATOR_SEARCH_FIELD = (By.ID, "id-search-field")

    
class AboutPage(BasePage):
    def is_search_field(self):
        try:
          self.find_element(AboutPageLocators.LOCATOR_SEARCH_FIELD)
          return True
        except TimeoutException:
          return False

Перейдем в файл test_about_page.py. Здесь мы создаем тест-кейс, в котором проверяем сценарий, описанный в классе страницы.

# test_about_page.py

from page_object.about_page import AboutPage


def test_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()
    assert search_field_exist

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

core_page-0.1.1.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

core_page-0.1.1-py3-none-any.whl (8.4 kB view details)

Uploaded Python 3

File details

Details for the file core_page-0.1.1.tar.gz.

File metadata

  • Download URL: core_page-0.1.1.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.4

File hashes

Hashes for core_page-0.1.1.tar.gz
Algorithm Hash digest
SHA256 aee58158903a19ced71bf37a966b96d7fd89af144c65b86a9a4df9eed5baf213
MD5 62f4f7bf9843b8767e31e563fcca3cd3
BLAKE2b-256 a40a0ed6d5ba4354ea39e025cfadbf6953899e53f7d520160becec28c1baea86

See more details on using hashes here.

File details

Details for the file core_page-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: core_page-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 8.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.4

File hashes

Hashes for core_page-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 eb562f57c83070fb373c2315c6b57e0050626d01710e90ad16c81f9da066e8dc
MD5 13569f79afc7bf814d9a81e69626fe24
BLAKE2b-256 0584d3a820bc42faa40c1f3422246b9b6f048e66a8283fa1e4bcafd177d11bd7

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page