manen.page_object_model
¶
This module provides an implementation of the Page Object design pattern
described in Selenium documentation. By combining the classes
Page
and Component
,
you can easily describe any web pages and access all the DOM elements in a simple
way through a Python class.
Let’s say that you want, given a query, to get all the packages information from
the website PyPi (e.g.: “selenium”). The first step to
work with manen.page_object_model
is to define the Python classes which
will describe the web pages you are working on. Here we will define all the
classes in an external file called pypi_pom.py
.
from datetime import datetime
from typing import Annotated
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.webdriver import WebDriver
from manen.page_object_model.component import Page, Component
from manen.page_object_model.config import CSS, Attribute, DatetimeFormat, XPath
from manen.page_object_model.types import input_value
class HomePage(Page):
class SearchForm(Form):
query: Annotated[input_value, CSS("input[name='q']")]
search: Annotated[SearchForm, CSS("form.search-form")]
class SearchResultPage(Page):
class Result(Component):
name: Annotated[str, CSS("h3 span.package-snippet__name")]
version: Annotated[str, CSS("h3 span.package-snippet__version")]
link: Annotated[href, CSS("a.package-snippet")]
description: Annotated[str, CSS("p.package-snippet__description")]
release_datetime: A[
datetime,
DatetimeFormat("%Y-%m-%dT%H:%M:%S%z"),
Attribute("datetime"),
CSS("span.package-snippet__created time"),
]
nb_results_label: Annotated[
str,
XPath("//*[@id='content']//form/div[1]/div[1]/p"),
]
results: Annotated[
list[Result],
CSS("ul[aria-label='Search results'] li"),
]
Once you have defined all the classes describing the web pages, you can start
interacting by instantiating the Page
subclass
with an instance of WebDriver
. Here
we will suppose that you have an instance of
WebDriver
stored in the variable
driver
.
>>> from pypi_pom import HomePage, SearchResultPage
>>> home_page = HomePage(driver)
>>> home_page.search.query = "selenium"
>>> home_page.search.submit()
# This will direct you to a search result page of PyPI.
>>> page = SearchResultPage(driver)
>>> page.nb_results_label
'2,571 projects for "selenium"'
>>> len(page.results)
20
>>> result = page.results[0]
<pypi_pom.SearchResultPage.Result>
>>> result.name
'selenium'
>>> result.release_datetime
datetime.datetime(2024, 9, 20, 15, 4, 46, tzinfo=datetime.timezone.utc)
>>> result.model_dump()
{'name': 'selenium',
'version': '4.25.0',
'link': 'https://pypi.org/project/selenium/',
'description': 'Official Python bindings for Selenium WebDriver',
'release_datetime': datetime.datetime(2024, 9, 20, 15, 4, 46, tzinfo=datetime.timezone.utc)}
This is a preview of what you can do with page_object_model
. See the
documentation of each objects to check all the features provided by the module.