Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@ var/
constraints*.txt
requirements*.txt
.coverage*
/.python-version
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ check: format lint ## Check and fix code base according to Plone standards
############################################
.PHONY: test
test: $(VENV_FOLDER) ## run tests
@uv run playwright install
@uv run pytest

.PHONY: test-coverage
Expand Down
59 changes: 59 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,65 @@ def test_get_vocabulary(get_vocabulary):

```

### portal_factory

| | |
| --- | --- |
| Description | Factory to get portal with applied user roles. |
| Required Fixture | **acceptance** |
| Scope | **Function** |

```python
import pytest
from playwright.sync_api import expect
from plone.app.testing.interfaces import (
TEST_USER_NAME,
TEST_USER_PASSWORD,
)


class TestPwEvents:
@pytest.fixture(autouse=True)
def setup(self, portal_factory):
self.portal = portal_factory(username=TEST_USER_NAME, roles=['Member', 'Contributor'])
self.plone_url = self.portal.absolute_url()

def test_events_listing(self) -> None:
```


### playwright_page_factory

| | |
| --- | --- |
| Description | Factory to get a Playwright page with a logged-in user. |
| Required Fixture | **acceptance** |
| Scope | **Function** |

```python
import pytest
from playwright.sync_api import expect
from plone.app.testing.interfaces import (
TEST_USER_NAME,
TEST_USER_PASSWORD,
)


class TestPwEvents:
@pytest.fixture(autouse=True)
def setup(self, portal_factory, playwright_page_factory):
self.page = playwright_page_factory(username=TEST_USER_NAME, password=TEST_USER_PASSWORD)
self.portal = portal_factory(username=TEST_USER_NAME, roles=['Member', 'Contributor'])
self.plone_url = self.portal.absolute_url()

def test_events_listing(self) -> None:
page = self.page
page.goto(f"{self.plone_url}")
page.get_by_role("link", name="Add new…").click()
page.get_by_role("link", name="Folder").click()
```


### setup_tool

| | |
Expand Down
2 changes: 2 additions & 0 deletions news/34.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add two fixtures (portal_factory, playwright_page_factory) supporting test in Playwright
[MrTango]
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ classifiers = [
]
dependencies = [
"pytest<8.0.0",
"pytest-playwright",
"zope.pytestlayer",
"plone.api",
"plone.app.testing",
Expand Down
4 changes: 4 additions & 0 deletions src/pytest_plone/fixtures/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from .content import get_behaviors
from .content import get_fti
from .env import generate_mo
from .playwright import playwright_page_factory
from .playwright import portal_factory
from .vocabularies import get_vocabulary


Expand All @@ -24,7 +26,9 @@
"get_vocabulary",
"http_request",
"installer",
"playwright_page_factory",
"portal",
"portal_factory",
"profile_last_version",
"setup_tool",
]
61 changes: 61 additions & 0 deletions src/pytest_plone/fixtures/playwright.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from playwright.sync_api import Page
from plone import api
from plone.app.testing.interfaces import SITE_OWNER_NAME
from plone.app.testing.interfaces import SITE_OWNER_PASSWORD
from plone.app.testing.interfaces import TEST_USER_NAME
from zope.component.hooks import setSite

import base64
import pytest
import transaction


def generate_basic_authentication_header_value(username: str, password: str) -> str:
token = base64.b64encode(f"{username}:{password}".encode()).decode("ascii")
return f"Basic {token}"


@pytest.fixture()
def portal_factory(acceptance, request):
def factory(roles: list, username: str = TEST_USER_NAME):
if not roles:
roles = ["Member"]
portal = acceptance["portal"]
setSite(portal)
with api.env.adopt_roles(["Manager", "Member"]):
api.user.grant_roles(
username=username,
roles=roles,
)
transaction.commit()

def cleanup():
with api.env.adopt_roles(["Manager", "Member"]):
api.user.revoke_roles(
username=username,
roles=roles,
)
transaction.commit()

request.addfinalizer(cleanup)
return portal

return factory


@pytest.fixture()
def playwright_page_factory(new_context):
def factory(
username: str = SITE_OWNER_NAME, password: str = SITE_OWNER_PASSWORD
) -> Page:
context = new_context(
extra_http_headers={
"Authorization": generate_basic_authentication_header_value(
username, password
),
}
)
page = context.new_page()
return page

return factory
5 changes: 5 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ def testdir(pytester: Pytester) -> Pytester:
"""
from Products.CMFPlone.testing import PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING
from Products.CMFPlone.testing import PRODUCTS_CMFPLONE_INTEGRATION_TESTING
from Products.CMFPlone.testing import PRODUCTS_CMFPLONE_ROBOT_TESTING

from pytest_plone import fixtures_factory

pytest_plugins = ["pytest_plone"]
Expand All @@ -23,6 +25,7 @@ def testdir(pytester: Pytester) -> Pytester:
(
(PRODUCTS_CMFPLONE_FUNCTIONAL_TESTING, "functional"),
(PRODUCTS_CMFPLONE_INTEGRATION_TESTING, "integration"),
(PRODUCTS_CMFPLONE_ROBOT_TESTING, "acceptance"),
)
)
)
Expand All @@ -42,7 +45,9 @@ def testdir(pytester: Pytester) -> Pytester:
"get_vocabulary",
"http_request",
"installer",
"playwright_page_factory",
"portal",
"portal_factory",
"profile_last_version",
"setup_tool",
]
Expand Down
Loading