Plugin for running pyppeteer in pytest.
Project description
pytest-pyppeteer
Test with pyppeteer in pytest.
Installation
Requirements
pytest-pyppeteer work with Python >=3.6.
Install pytest-pyppeteer
pip install pytest-pyppeteer
or install latest one:
pip install git+https://github.com/luizyao/pytest-pyppeteer.git
Quickstart
For example, compare the scores of a book and its movie on Douban.
--nptp, --new-pyppeteer-test-project
Create a new pyppeteer test project in the specified path.
pytest --nptp=douban
The directory structure:
├── desc
├── pyproject.toml
└── test_douban.py
1 directory, 2 files
Configuration
desc
Create two files douban_movie.desc
and douban_book.desc
in desc
directory.
[HomePage]
is required.
# douban_movie.desc
[HomePage]
#CSS
search_input = '#inp-query'
search_apply = '.inp-btn > input:nth-child(1)'
[SearchResultsPage]
# {} indicates that this part can be replaced by the custom parameter
# CSS
result = '#root > div > div > div > div > div:nth-child({}) > div.item-root a.cover-link'
[DetailPage]
rating = '#interest_sectl > div.rating_wrap.clearbox > div.rating_self.clearfix > strong'
# douban_book.desc
[HomePage]
#CSS
search_input = '#inp-query'
search_apply = '.inp-btn > input:nth-child(1)'
[SearchResultsPage]
# {} indicates that this part can be replaced by the custom parameter
# Xpath
result = '(//*[@class="item-root"])[{}]/a'
[DetailPage]
rating = '#interest_sectl > div > div.rating_self.clearfix > strong'
pyproject.toml
Add target
:
[tool.pytest.pyppeteer.targets]
[tool.pytest.pyppeteer.targets.target1]
name = "douban_movie"
base_url = "https://movie.douban.com/"
[tool.pytest.pyppeteer.targets.target2]
name = "douban_book"
base_url = "https://book.douban.com/"
Path executablePath
to a Chromium or Chrome executable.
[tool.pytest.pyppeteer.options]
executablePath = "/Applications/Chrome.app/Contents/MacOS/Google Chrome"
Write tests
# test_douban.py
import asyncio
from functools import partial
import pytest
from pytest_pyppeteer.models import Pyppeteer
async def query_rating(target: Pyppeteer, movie_or_book_name: str):
await target.open(goto_base_url=True)
await target.input("search_input", text=movie_or_book_name)
await target.click("search_apply")
# Into search results page
target.switch_page("SearchResultsPage")
# Click the first result
await target.click("result", custom_parameter=(1,))
# Into detail page
target.switch_page("DetailPage")
rating: str = await target.get_value("rating")
await target.close()
return rating
@pytest.mark.parametrize("target", [("target1", "target2")], indirect=True)
async def test_shawshank_rating(target):
target1, target2 = target
shawshank_rating = partial(
query_rating, movie_or_book_name="The Shawshank Redemption"
)
movie_rating, book_rating = await asyncio.gather(
shawshank_rating(target1), shawshank_rating(target2)
)
assert movie_rating == book_rating
Execute tests screenshot
Usage
Locator
CSS
selector
[SearchResultsPage]
# {} indicates that this part can be replaced by the custom parameter
# CSS
result = '#root > div > div > div > div > div:nth-child({}) > div.item-root a.cover-link'
XPath
[SearchResultsPage]
# {} indicates that this part can be replaced by the custom parameter
# XPath
result = '(//*[@class="item-root"])[{}]/a'
Use XPath locate element via element certain content. e.g. contains(text(), "{}")
:
details_item = '//*[@class="overview-info"]//div[@class="item-label"][contains(text(), "{}")]/following-sibling::div[@class="item-content"]'
CSS doesn't support content selector, refer to https://www.w3.org/TR/selectors-3/#content-selectors
Replace {}
with custom parameter:
# Get the first result
await target.click("result", custom_parameter=(1,))
If only one custom parameter:
# Get the first result
await target.click("result", custom_parameter=1)
Target
One target
Direct to use target
in test script:
@pytest.mark.parametrize("target", ["target1"], indirect=True)
async def test_001(target: Pyppeteer):
await target.open(goto_base_url=True)
Multiple targets
@pytest.mark.parametrize("target", [("target1", "target2")], indirect=True)
async def test_shawshank_rating(target):
target1, target2 = target
Clear before input
await target.input("search_input", text="The Shawshank Redemption", clear=True)
Screenshot
await target.screenshot(Path(__file__).parent / "screenshot_binary.png")
Hooks
pytest_pyppeteer_targets_setup
Called to setup target before execute a test item.
e.g. Open browser and goto base url.
async def pytest_pyppeteer_targets_setup(item: Item) -> None:
targets: Dict[str, Pyppeteer] = item.targets # type: ignore
async def setup(target: Pyppeteer):
await target.open(goto_base_url=True)
await asyncio.gather(*map(setup, targets.values()))
pytest_pyppeteer_targets_teardown
Called to teardown target after execute a test item.
e.g. Take a screenshot for all target used when test failed.
async def pytest_pyppeteer_targets_teardown(item: Item) -> None:
targets: Dict[str, Pyppeteer] = item.targets # type: ignore
async def teardown(name: str, target: Pyppeteer):
if item.res_call.failed:
await asyncio.sleep(1)
screenshot_base64 = await target.screenshot(type_="png", encoding="base64")
allure.attach(
base64.b64decode(screenshot_base64),
name=name,
attachment_type=allure.attachment_type.PNG,
)
await asyncio.gather(*[teardown(name, target) for name, target in targets.items()])
pytest_pyppeteer_all_targets_teardown
Called to teardown all targets after execute all test items.
e.g. Make sure to close all targets.
async def pytest_pyppeteer_all_targets_teardown(targets: Pyppeteer) -> None:
async def teardown(target: Pyppeteer):
await target.close()
await asyncio.gather(*map(teardown, targets))
License
Changelog
0.1.3 (2020-09-02)
Added
- ✨ support to get the inner text or value of each element in a list one time [9dae46b]
Fixed
0.1.2 (2020-08-26)
Added
- ✨ support for the same target sharing the same browser instance throughout the test session [5e51d75]
- ✨ add screenshot function [310f848]
Fixed
0.1.1 (2020-08-22)
Added
- ✨ add target.hover function [c0fe87e]
Fixed
More details refer to CHANGELOG.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for pytest_pyppeteer-0.1.3-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | e759c7b92b850a433c3b9b822bee3867a544585db4ed8dda52bc94755bd21886 |
|
MD5 | 2e7f986f42ff9ab5694fb675911ea2e8 |
|
BLAKE2b-256 | 6ec967dd0c0f87fcf5cdc87eea4f81742d16969e6c39d145e2ded390ac715a7b |