Skip to content

Commit 91b54ee

Browse files
authored
Add playwright e2e tests (#27)
1 parent 8bf6931 commit 91b54ee

File tree

6 files changed

+205
-17
lines changed

6 files changed

+205
-17
lines changed

.github/workflows/playwright.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Playwright Tests
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Set up Python
16+
uses: actions/setup-python@v5
17+
with:
18+
python-version: '3.12'
19+
cache: 'pip'
20+
21+
- name: Install dependencies
22+
run: |
23+
python -m pip install --upgrade pip
24+
pip install -e ".[tests]"
25+
playwright install --with-deps chromium
26+
27+
- name: Run Django server and Playwright tests
28+
run: |
29+
cd tests
30+
python manage.py migrate
31+
pytest ../tests/testapp/test_prose_editor_e2e.py -v --browser chromium

.github/workflows/tests.yml

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: Tests
33
on:
44
push:
55
branches:
6-
- main
6+
- main
77
pull_request:
88

99
jobs:
@@ -14,21 +14,21 @@ jobs:
1414
fail-fast: false
1515
matrix:
1616
python-version:
17-
- "3.10"
18-
- "3.11"
19-
- "3.12"
20-
- "3.13"
17+
- '3.10'
18+
- '3.11'
19+
- '3.12'
20+
- '3.13'
2121

2222
steps:
23-
- uses: actions/checkout@v3
24-
- name: Set up Python ${{ matrix.python-version }}
25-
uses: actions/setup-python@v4
26-
with:
27-
python-version: ${{ matrix.python-version }}
28-
- name: Install dependencies
29-
run: |
30-
python -m pip install --upgrade pip tox
31-
- name: Run tox targets for ${{ matrix.python-version }}
32-
run: |
33-
ENV_PREFIX=$(tr -C -d "0-9" <<< "${{ matrix.python-version }}")
34-
TOXENV=$(tox --listenvs | grep "^py$ENV_PREFIX" | tr '\n' ',') python -m tox
23+
- uses: actions/checkout@v4
24+
- name: Set up Python ${{ matrix.python-version }}
25+
uses: actions/setup-python@v5
26+
with:
27+
python-version: ${{ matrix.python-version }}
28+
- name: Install dependencies
29+
run: |
30+
python -m pip install --upgrade pip tox
31+
- name: Run tox targets for ${{ matrix.python-version }}
32+
run: |
33+
ENV_PREFIX=$(tr -C -d "0-9" <<< "${{ matrix.python-version }}")
34+
TOXENV=$(tox --listenvs | grep "^py$ENV_PREFIX" | tr '\n' ',') python -m tox

README.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,32 @@ The pre-commit configuration includes a hook that prevents committing files
273273
with source map references, ensuring that development artifacts don't make it
274274
into the repository.
275275

276+
Browser Testing with Playwright
277+
------------------------------
278+
279+
This project uses Playwright for browser-based testing of the prose editor.
280+
281+
To run the browser tests:
282+
283+
1. Install the dependencies:
284+
285+
.. code-block:: shell
286+
287+
pip install -e ".[tests]"
288+
playwright install
289+
290+
2. Run the tests using tox:
291+
292+
.. code-block:: shell
293+
294+
tox -e playwright
295+
296+
Or directly with pytest:
297+
298+
.. code-block:: shell
299+
300+
pytest tests/testapp/test_prose_editor_e2e.py -v --browser chromium
301+
276302
Code Style and Linting
277303
---------------------
278304

pyproject.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,13 @@ optional-dependencies.sanitize = [
4343
"nh3",
4444
]
4545
optional-dependencies.tests = [
46+
"asgiref",
4647
"coverage",
4748
"nh3",
49+
"pytest",
50+
"pytest-asyncio",
51+
"pytest-django",
52+
"pytest-playwright",
4853
]
4954
urls.Documentation = "https://django-prose-editor.readthedocs.io/"
5055

@@ -116,3 +121,14 @@ lint.per-file-ignores."*/migrat*/*" = [
116121
lint.isort.combine-as-imports = true
117122
lint.isort.lines-after-imports = 2
118123
lint.mccabe.max-complexity = 15
124+
125+
[tool.pytest.ini_options]
126+
DJANGO_SETTINGS_MODULE = "testapp.settings"
127+
python_files = "test_*.py"
128+
addopts = "--strict-markers"
129+
testpaths = [ "tests" ]
130+
asyncio_mode = "strict"
131+
asyncio_default_fixture_loop_scope = "function"
132+
markers = [
133+
"e2e: End-to-end browser tests",
134+
]
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import os
2+
3+
import pytest
4+
from playwright.sync_api import expect
5+
6+
from testapp.models import ProseEditorModel
7+
8+
9+
# Set Django async unsafe to allow database operations in tests
10+
os.environ.setdefault("DJANGO_ALLOW_ASYNC_UNSAFE", "true")
11+
12+
13+
@pytest.mark.django_db
14+
@pytest.mark.e2e
15+
def test_prose_editor_admin_form(page, live_server):
16+
"""Test that the prose editor loads and works in the admin."""
17+
# Login first
18+
from django.contrib.auth.models import User
19+
20+
User.objects.create_superuser("admin", "[email protected]", "password")
21+
22+
# Visit the login page
23+
page.goto(f"{live_server.url}/admin/login/")
24+
25+
# Fill in the login form
26+
page.fill("#id_username", "admin")
27+
page.fill("#id_password", "password")
28+
29+
# Submit the form
30+
page.click("input[type=submit]")
31+
32+
# Wait for the admin index page to load
33+
page.wait_for_url(f"{live_server.url}/admin/")
34+
35+
# Go to the add page
36+
page.goto(f"{live_server.url}/admin/testapp/proseeditormodel/add/")
37+
38+
# Check that the prose editor is loaded
39+
editor_container = page.locator(".prose-editor")
40+
expect(editor_container).to_be_visible()
41+
42+
# Check that the toolbar is visible
43+
toolbar = page.locator(".prose-menubar")
44+
expect(toolbar).to_be_visible()
45+
46+
# Type some content into the editor
47+
editor = page.locator(".ProseMirror")
48+
editor.click()
49+
editor.type("Hello, Playwright!")
50+
51+
# Save the form
52+
page.click("input[name='_save']")
53+
54+
# Check that we've been redirected to the changelist page
55+
expect(page).to_have_url(f"{live_server.url}/admin/testapp/proseeditormodel/")
56+
57+
# Check that the model was created
58+
model = ProseEditorModel.objects.first()
59+
assert model is not None
60+
assert "Hello, Playwright!" in model.description
61+
62+
63+
@pytest.mark.django_db
64+
@pytest.mark.e2e
65+
def test_prose_editor_formatting(page, live_server):
66+
"""Test formatting functionality in the prose editor."""
67+
# Login first
68+
from django.contrib.auth.models import User
69+
70+
User.objects.create_superuser("admin", "[email protected]", "password")
71+
72+
# Visit the login page
73+
page.goto(f"{live_server.url}/admin/login/")
74+
75+
# Fill in the login form
76+
page.fill("#id_username", "admin")
77+
page.fill("#id_password", "password")
78+
79+
# Submit the form
80+
page.click("input[type=submit]")
81+
82+
# Go to the add page
83+
page.goto(f"{live_server.url}/admin/testapp/proseeditormodel/add/")
84+
85+
# Click in the editor
86+
editor = page.locator(".ProseMirror")
87+
editor.click()
88+
editor.type("Format this text")
89+
90+
# Select the text
91+
editor.press("Control+a")
92+
93+
# Make it bold
94+
bold_button = page.locator(".prose-menubar__button[title='bold']")
95+
bold_button.click()
96+
97+
# Save the form
98+
page.click("input[name='_save']")
99+
100+
# Check the model content contains bold formatting
101+
model = ProseEditorModel.objects.first()
102+
assert model is not None
103+
assert "<strong>Format this text</strong>" in model.description

tox.ini

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@ deps =
1616
dj52: Django>=5.2a1,<6.0
1717
djmain: https://github.com/django/django/archive/main.tar.gz
1818

19+
[testenv:playwright]
20+
usedevelop = true
21+
extras = all,tests
22+
passenv =
23+
HOME
24+
PYTHONPATH
25+
DISPLAY
26+
XAUTHORITY
27+
commands =
28+
playwright install chromium
29+
pytest tests/testapp/test_prose_editor_e2e.py -v --browser chromium
30+
1931
[testenv:docs]
2032
deps =
2133
-r docs/requirements.txt

0 commit comments

Comments
 (0)