Skip to content

Commit fb4fc2d

Browse files
committed
Rewrite playwright test as StaticLiveServerTestCase
Unfortunately playwright requires DJANGO_ALLOW_ASYNC_UNSAFE to be set. I think that this interferes with other async tests. I cannot find a way just to set it for the individual test with pytest. It is possible using StaticLiveServerTestCase, so refactored to this.
1 parent 8ea3320 commit fb4fc2d

4 files changed

Lines changed: 104 additions & 127 deletions

File tree

app/tests/conftest.py

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import os
2-
import warnings
32
import zipfile
43
from collections import namedtuple
54
from pathlib import Path
@@ -84,15 +83,6 @@ def django_db_setup(django_db_setup, django_db_blocker):
8483
site.save()
8584

8685

87-
def pytest_itemcollected(item):
88-
if item.get_closest_marker("playwright") is not None:
89-
# See https://github.com/microsoft/playwright-pytest/issues/29
90-
warnings.warn( # noqa: B028
91-
"Setting DJANGO_ALLOW_ASYNC_UNSAFE for playwright support"
92-
)
93-
os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"
94-
95-
9686
class ChallengeSet(NamedTuple):
9787
challenge: ChallengeFactory
9888
creator: UserFactory
Lines changed: 103 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import json
2+
import os
23

3-
import pytest
4+
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
45
from django.urls import reverse
56
from django.views.generic import TemplateView
7+
from playwright.sync_api import sync_playwright
68

79

810
class SessionControlView(TemplateView):
@@ -17,66 +19,103 @@ class SessionCreationView(TemplateView):
1719
template_name = "new_session.html"
1820

1921

20-
@pytest.mark.playwright
21-
def test_viewer_session_control(live_server, page, settings):
22-
settings.WORKSTATIONS_EXTRA_BROADCAST_DOMAINS = [live_server.url]
23-
session_create_view = f"{live_server}{reverse('new-session-test')}"
24-
session_control_view = f"{live_server}{reverse('session-control-test')}"
25-
mock_workstation_view = f"{live_server}{reverse('workstation-mock')}"
26-
page.goto(session_control_view)
27-
28-
# Test if a fresh click opens up a new page
29-
with page.expect_popup() as viewer_page_info:
30-
page.get_by_role("button", name="Launch new Session").click()
31-
viewer_page = viewer_page_info.value
32-
viewer_page.get_by_text(SessionCreationView.template_name).wait_for()
33-
34-
# Setup mock acknowledge
35-
viewer_page.goto(mock_workstation_view)
36-
viewer_page.evaluate("enableMockAcks()")
37-
38-
# Test if pressing launch indeed sends a session control message
39-
page.get_by_role("button", name="Launch new Session").click()
40-
received_msg = json.loads(
41-
viewer_page.locator("#messages :nth-child(1)").inner_text()
42-
)
43-
assert "id" in received_msg["sessionControl"]["meta"]
44-
45-
# check that ack message is returned
46-
sent_msg = json.loads(
47-
viewer_page.locator("#acks :nth-child(1)").inner_text()
48-
)
49-
assert "acknowledge" in sent_msg["sessionControl"]["meta"]
50-
51-
# check that an ack with the wrong id is ignored
52-
viewer_page.goto(mock_workstation_view)
53-
viewer_page.evaluate("enableIncorrectMockAck()")
54-
page.get_by_role("button", name="Launch new Session").click()
55-
received_msg2 = json.loads(
56-
viewer_page.locator("#messages :nth-child(1)").inner_text()
57-
)
58-
sent_msg2 = json.loads(
59-
viewer_page.locator("#acks :nth-child(1)").inner_text()
60-
)
61-
assert (
62-
received_msg2["sessionControl"]["meta"]["id"]
63-
!= sent_msg2["sessionControl"]["meta"]["acknowledge"]["id"]
64-
)
65-
viewer_page.get_by_text(SessionCreationView.template_name).wait_for()
66-
assert viewer_page.url.startswith(session_create_view)
67-
68-
# Set timeout to 0, test that a new session will be created
69-
viewer_page.goto(mock_workstation_view)
70-
page.get_by_role("button", name="Test timeout").click()
71-
viewer_page.get_by_text(SessionCreationView.template_name).wait_for()
72-
assert viewer_page.url.startswith(session_create_view)
73-
74-
# Test if disabling the acknowledgment will result in a new session being created
75-
viewer_page.goto(mock_workstation_view)
76-
viewer_page.evaluate("disableMockAcks()")
77-
page.get_by_role("button", name="Launch new Session").click()
78-
viewer_page.get_by_text(SessionCreationView.template_name).wait_for()
79-
assert viewer_page.url.startswith(session_create_view)
80-
81-
# Clean up
82-
page.close()
22+
class PlaywrightTests(StaticLiveServerTestCase):
23+
@classmethod
24+
def setUpClass(cls):
25+
# See https://github.com/microsoft/playwright-pytest/issues/29
26+
os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"
27+
28+
super().setUpClass()
29+
30+
cls.playwright = sync_playwright().start()
31+
cls.browser = cls.playwright.chromium.launch()
32+
33+
@classmethod
34+
def tearDownClass(cls):
35+
super().tearDownClass()
36+
37+
cls.browser.close()
38+
cls.playwright.stop()
39+
40+
del os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"]
41+
42+
def test_viewer_session_control(self):
43+
with self.settings(
44+
WORKSTATIONS_EXTRA_BROADCAST_DOMAINS=[self.live_server_url],
45+
):
46+
page = self.browser.new_page()
47+
48+
session_create_view = (
49+
f"{self.live_server_url}{reverse('new-session-test')}"
50+
)
51+
session_control_view = (
52+
f"{self.live_server_url}{reverse('session-control-test')}"
53+
)
54+
mock_workstation_view = (
55+
f"{self.live_server_url}{reverse('workstation-mock')}"
56+
)
57+
page.goto(session_control_view)
58+
59+
# Test if a fresh click opens up a new page
60+
with page.expect_popup() as viewer_page_info:
61+
page.get_by_role("button", name="Launch new Session").click()
62+
viewer_page = viewer_page_info.value
63+
viewer_page.get_by_text(
64+
SessionCreationView.template_name
65+
).wait_for()
66+
67+
# Setup mock acknowledge
68+
viewer_page.goto(mock_workstation_view)
69+
viewer_page.evaluate("enableMockAcks()")
70+
71+
# Test if pressing launch indeed sends a session control message
72+
page.get_by_role("button", name="Launch new Session").click()
73+
received_msg = json.loads(
74+
viewer_page.locator("#messages :nth-child(1)").inner_text()
75+
)
76+
assert "id" in received_msg["sessionControl"]["meta"]
77+
78+
# check that ack message is returned
79+
sent_msg = json.loads(
80+
viewer_page.locator("#acks :nth-child(1)").inner_text()
81+
)
82+
assert "acknowledge" in sent_msg["sessionControl"]["meta"]
83+
84+
# check that an ack with the wrong id is ignored
85+
viewer_page.goto(mock_workstation_view)
86+
viewer_page.evaluate("enableIncorrectMockAck()")
87+
page.get_by_role("button", name="Launch new Session").click()
88+
received_msg2 = json.loads(
89+
viewer_page.locator("#messages :nth-child(1)").inner_text()
90+
)
91+
sent_msg2 = json.loads(
92+
viewer_page.locator("#acks :nth-child(1)").inner_text()
93+
)
94+
assert (
95+
received_msg2["sessionControl"]["meta"]["id"]
96+
!= sent_msg2["sessionControl"]["meta"]["acknowledge"]["id"]
97+
)
98+
viewer_page.get_by_text(
99+
SessionCreationView.template_name
100+
).wait_for()
101+
assert viewer_page.url.startswith(session_create_view)
102+
103+
# Set timeout to 0, test that a new session will be created
104+
viewer_page.goto(mock_workstation_view)
105+
page.get_by_role("button", name="Test timeout").click()
106+
viewer_page.get_by_text(
107+
SessionCreationView.template_name
108+
).wait_for()
109+
assert viewer_page.url.startswith(session_create_view)
110+
111+
# Test if disabling the acknowledgment will result in a new session being created
112+
viewer_page.goto(mock_workstation_view)
113+
viewer_page.evaluate("disableMockAcks()")
114+
page.get_by_role("button", name="Launch new Session").click()
115+
viewer_page.get_by_text(
116+
SessionCreationView.template_name
117+
).wait_for()
118+
assert viewer_page.url.startswith(session_create_view)
119+
120+
# Clean up
121+
page.close()

pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ dev = [
9191
"amass",
9292
"watchfiles",
9393
"playwright",
94-
"pytest-playwright",
9594
"pytest-rerunfailures",
9695
"sphinx-exec-code",
9796
]

uv.lock

Lines changed: 1 addition & 52 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)