Skip to content

Commit 86f2b95

Browse files
committed
ci(playwright): use playwright for tests instead of selenium
Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
1 parent 61d852d commit 86f2b95

37 files changed

Lines changed: 357 additions & 136 deletions

.github/workflows/test_and_release.yml

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,6 @@ jobs:
5656
with:
5757
python-version: ${{ matrix.python-version }}
5858

59-
- name: Install Chrome
60-
run: |
61-
sudo apt install google-chrome-stable
62-
63-
- name: Check the console scripts interface
64-
run: |
65-
pip install seleniumbase
66-
seleniumbase
67-
sbase
68-
69-
- name: Install chromedriver
70-
run: |
71-
seleniumbase install chromedriver
72-
7359
- name: Set Up Node
7460
uses: actions/setup-node@v4
7561
with:
@@ -91,11 +77,13 @@ jobs:
9177
run: |
9278
pip install .
9379
pip install -r tests/requirements.txt
80+
# Install playwright requirements
81+
playwright install
9482
# Run the tests with coverage so we get a coverage report too
9583
pip install coverage
96-
# coverage run --source . -m pytest -s .
84+
coverage run --source . -m pytest -s .
9785
# Print the coverage report
98-
# coverage report -m
86+
coverage report -m
9987
10088
- name: Upload Coverage to Codecov
10189
uses: codecov/codecov-action@v3

examples/vue3/js_call.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from trame.app import get_server
2-
from trame_client.widgets import client, html
2+
from trame.widgets import client, html
33
from trame_client.ui.html import DivLayout
44
from trame_client.utils.testing import enable_testing
55

tests/conftest.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66
HELPER = FixtureHelper(ROOT_PATH)
77

88

9-
@pytest.fixture()
10-
def baseline_image():
11-
HELPER.remove_page_urls()
12-
yield
13-
HELPER.remove_page_urls()
9+
@pytest.fixture
10+
def ref_dir() -> Path:
11+
return Path(__file__).parent / "refs"
1412

1513

1614
@pytest.fixture

tests/refs/simple_count_1.html

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<!DOCTYPE html><html lang="en" data-app-name="trame" data-launcher-retry="[]"><head>
2+
<base href=".">
3+
<meta charset="UTF-8">
4+
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1">
5+
<meta name="description" content="Application built with trame, a product from Kitware">
6+
<meta name="keywords" content="trame, OpenSource, Stateful Python Application, Kitware">
7+
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
8+
<meta http-equiv="Pragma" content="no-cache">
9+
<meta http-equiv="Expires" content="0">
10+
<link rel="icon" href="logo.png">
11+
<title>trame is built by Kitware</title>
12+
<script src="vue.global.js"></script>
13+
<script type="module" crossorigin="" src="./assets/index-5f6ebc8d.js"></script>
14+
<link rel="stylesheet" href="./assets/index-e80c1ba5.css">
15+
</head>
16+
<body>
17+
<noscript>
18+
<strong
19+
>We're sorry but trame built by Kitware doesn't work properly without
20+
JavaScript enabled. Please enable it to continue.</strong
21+
>
22+
</noscript>
23+
<div id="app"><style>
24+
.text-no-select {
25+
-webkit-user-select: none;
26+
-moz-user-select: none;
27+
-ms-user-select: none;
28+
user-select: none;
29+
}
30+
.trame__loader {
31+
display: block;
32+
position: relative;
33+
left: 50%;
34+
top: calc(50% - 50px);
35+
width: 150px;
36+
height: 150px;
37+
margin: -75px 0 0 -75px;
38+
border-radius: 50%;
39+
border: 10px solid transparent;
40+
border-top-color: #ac262c;
41+
42+
-webkit-animation: spin 2s linear infinite; /* Chrome, Opera 15+, Safari 5+ */
43+
animation: spin 2s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */
44+
}
45+
46+
.trame__loader:before {
47+
content: "";
48+
position: absolute;
49+
top: 5px;
50+
left: 5px;
51+
right: 5px;
52+
bottom: 5px;
53+
border-radius: 50%;
54+
border: 10px solid transparent;
55+
border-top-color: #258e44;
56+
57+
-webkit-animation: spin 3s linear infinite; /* Chrome, Opera 15+, Safari 5+ */
58+
animation: spin 3s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */
59+
}
60+
61+
.trame__loader:after {
62+
content: "";
63+
position: absolute;
64+
top: 20px;
65+
left: 20px;
66+
right: 20px;
67+
bottom: 20px;
68+
border-radius: 50%;
69+
border: 10px solid transparent;
70+
border-top-color: #1c4678;
71+
72+
-webkit-animation: spin 1.5s linear infinite; /* Chrome, Opera 15+, Safari 5+ */
73+
animation: spin 1.5s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */
74+
}
75+
76+
.trame__message {
77+
position: absolute;
78+
text-align: center;
79+
width: 100%;
80+
top: calc(50% + 50px);
81+
font-size: 200%;
82+
user-select: none;
83+
}
84+
85+
@-webkit-keyframes spin {
86+
0% {
87+
-webkit-transform: rotate(0deg); /* Chrome, Opera 15+, Safari 3.1+ */
88+
-ms-transform: rotate(0deg); /* IE 9 */
89+
transform: rotate(0deg); /* Firefox 16+, IE 10+, Opera */
90+
}
91+
100% {
92+
-webkit-transform: rotate(360deg); /* Chrome, Opera 15+, Safari 3.1+ */
93+
-ms-transform: rotate(360deg); /* IE 9 */
94+
transform: rotate(360deg); /* Firefox 16+, IE 10+, Opera */
95+
}
96+
}
97+
@keyframes spin {
98+
0% {
99+
-webkit-transform: rotate(0deg); /* Chrome, Opera 15+, Safari 3.1+ */
100+
-ms-transform: rotate(0deg); /* IE 9 */
101+
transform: rotate(0deg); /* Firefox 16+, IE 10+, Opera */
102+
}
103+
100% {
104+
-webkit-transform: rotate(360deg); /* Chrome, Opera 15+, Safari 3.1+ */
105+
-ms-transform: rotate(360deg); /* IE 9 */
106+
transform: rotate(360deg); /* Firefox 16+, IE 10+, Opera */
107+
}
108+
}
109+
</style>
110+
<div style="position:absolute;top:0;left:0;width:100%;height:100%;z-index:1000;">
111+
<div class="trame__loader"></div>
112+
<div class="trame__message">Loading...</div>
113+
</div>
114+
</div>
115+
<script>
116+
fetch("./loading.tpl")
117+
.then((r) => r.text())
118+
.then((c) => (document.querySelector("#app").innerHTML = c));
119+
</script>
120+
121+
122+
123+
</body></html>

tests/refs/simple_count_5.html

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<!DOCTYPE html><html lang="en" data-app-name="trame" data-launcher-retry="[]"><head>
2+
<base href=".">
3+
<meta charset="UTF-8">
4+
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1">
5+
<meta name="description" content="Application built with trame, a product from Kitware">
6+
<meta name="keywords" content="trame, OpenSource, Stateful Python Application, Kitware">
7+
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
8+
<meta http-equiv="Pragma" content="no-cache">
9+
<meta http-equiv="Expires" content="0">
10+
<link rel="icon" href="logo.png">
11+
<title>Trame</title>
12+
<script src="vue.global.js"></script>
13+
<script type="module" crossorigin="" src="./assets/index-5f6ebc8d.js"></script>
14+
<link rel="stylesheet" href="./assets/index-e80c1ba5.css">
15+
</head>
16+
<body>
17+
<noscript>
18+
<strong
19+
>We're sorry but trame built by Kitware doesn't work properly without
20+
JavaScript enabled. Please enable it to continue.</strong
21+
>
22+
</noscript>
23+
<div id="app" data-v-app=""><div><div class="countValue" style="padding: 20px; background: red;">5</div><button class="plusButton">Add to count</button></div></div>
24+
<script>
25+
fetch("./loading.tpl")
26+
.then((r) => r.text())
27+
.then((c) => (document.querySelector("#app").innerHTML = c));
28+
</script>
29+
30+
31+
32+
</body></html>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html><html lang="" data-app-name="trame"><head><base href="."><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1"><meta name="description" content="Application built with trame, a product from Kitware"><meta name="keywords" content="trame, OpenSource, Stateful Python Application, Kitware"><meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"><meta http-equiv="Pragma" content="no-cache"><meta http-equiv="Expires" content="0"><link rel="icon" href="logo.png"><script src="vue.global.js"></script><title>Trame</title><script defer="defer" src="js/chunk-vendors.c3c88821.js"></script><script defer="defer" src="js/app.c98d1f1d.js"></script><link href="css/app.0b077e70.css" rel="stylesheet"></head><body style="margin: 0; padding: 0;"><noscript><strong>We're sorry but trame built by Kitware doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div><div class="staticDiv">
2+
Static text 6
3+
</div> <div class="countDiv">
4+
count = 6
5+
</div> <div class="ttsDiv">
6+
tts = 2
7+
</div> <button class="updateBtn">
8+
Update template
9+
</button> <button class="plusBtn">
10+
count++
11+
</button></div><script>fetch("./loading.tpl").then((r) => r.text()).then((c) => document.querySelector("#app").innerHTML = c)</script></body></html>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<!DOCTYPE html><html lang="" data-app-name="trame"><head><base href="."><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1"><meta name="description" content="Application built with trame, a product from Kitware"><meta name="keywords" content="trame, OpenSource, Stateful Python Application, Kitware"><meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"><meta http-equiv="Pragma" content="no-cache"><meta http-equiv="Expires" content="0"><link rel="icon" href="logo.png"><script src="vue.global.js"></script><title>trame is built by Kitware</title><script defer="defer" src="js/chunk-vendors.c3c88821.js"></script><script defer="defer" src="js/app.c98d1f1d.js"></script><link href="css/app.0b077e70.css" rel="stylesheet"></head><body style="margin: 0; padding: 0;"><noscript><strong>We're sorry but trame built by Kitware doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"><style>
2+
.text-no-select {
3+
-webkit-user-select: none;
4+
-moz-user-select: none;
5+
-ms-user-select: none;
6+
user-select: none;
7+
}
8+
.trame__loader {
9+
display: block;
10+
position: relative;
11+
left: 50%;
12+
top: calc(50% - 50px);
13+
width: 150px;
14+
height: 150px;
15+
margin: -75px 0 0 -75px;
16+
border-radius: 50%;
17+
border: 10px solid transparent;
18+
border-top-color: #ac262c;
19+
20+
-webkit-animation: spin 2s linear infinite; /* Chrome, Opera 15+, Safari 5+ */
21+
animation: spin 2s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */
22+
}
23+
24+
.trame__loader:before {
25+
content: "";
26+
position: absolute;
27+
top: 5px;
28+
left: 5px;
29+
right: 5px;
30+
bottom: 5px;
31+
border-radius: 50%;
32+
border: 10px solid transparent;
33+
border-top-color: #258e44;
34+
35+
-webkit-animation: spin 3s linear infinite; /* Chrome, Opera 15+, Safari 5+ */
36+
animation: spin 3s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */
37+
}
38+
39+
.trame__loader:after {
40+
content: "";
41+
position: absolute;
42+
top: 20px;
43+
left: 20px;
44+
right: 20px;
45+
bottom: 20px;
46+
border-radius: 50%;
47+
border: 10px solid transparent;
48+
border-top-color: #1c4678;
49+
50+
-webkit-animation: spin 1.5s linear infinite; /* Chrome, Opera 15+, Safari 5+ */
51+
animation: spin 1.5s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */
52+
}
53+
54+
.trame__message {
55+
position: absolute;
56+
text-align: center;
57+
width: 100%;
58+
top: calc(50% + 50px);
59+
font-size: 200%;
60+
user-select: none;
61+
}
62+
63+
@-webkit-keyframes spin {
64+
0% {
65+
-webkit-transform: rotate(0deg); /* Chrome, Opera 15+, Safari 3.1+ */
66+
-ms-transform: rotate(0deg); /* IE 9 */
67+
transform: rotate(0deg); /* Firefox 16+, IE 10+, Opera */
68+
}
69+
100% {
70+
-webkit-transform: rotate(360deg); /* Chrome, Opera 15+, Safari 3.1+ */
71+
-ms-transform: rotate(360deg); /* IE 9 */
72+
transform: rotate(360deg); /* Firefox 16+, IE 10+, Opera */
73+
}
74+
}
75+
@keyframes spin {
76+
0% {
77+
-webkit-transform: rotate(0deg); /* Chrome, Opera 15+, Safari 3.1+ */
78+
-ms-transform: rotate(0deg); /* IE 9 */
79+
transform: rotate(0deg); /* Firefox 16+, IE 10+, Opera */
80+
}
81+
100% {
82+
-webkit-transform: rotate(360deg); /* Chrome, Opera 15+, Safari 3.1+ */
83+
-ms-transform: rotate(360deg); /* IE 9 */
84+
transform: rotate(360deg); /* Firefox 16+, IE 10+, Opera */
85+
}
86+
}
87+
</style>
88+
<div style="position:absolute;top:0;left:0;width:100%;height:100%;z-index:1000;">
89+
<div class="trame__loader"></div>
90+
<div class="trame__message">Loading...</div>
91+
</div>
92+
</div><script>fetch("./loading.tpl").then((r) => r.text()).then((c) => document.querySelector("#app").innerHTML = c)</script></body></html>

tests/requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
pytest
22
pytest-asyncio
3-
seleniumbase
3+
pytest-playwright
44
pixelmatch
55
Pillow
66
pytest-xprocess
77
trame>=3.6
8-
trame-server>=3
8+
trame-server>=3

tests/test_reactivity.py

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,32 @@
1+
from playwright.sync_api import expect
12
import pytest
2-
from seleniumbase import SB
3+
4+
from trame_client.utils.testing import assert_html_matches
35

46

57
@pytest.mark.parametrize("server_path", ["examples/test/reactivity.py"])
6-
def test_reactivity(server, baseline_image):
7-
with SB() as sb:
8-
url = f"http://127.0.0.1:{server.port}/"
9-
sb.open(url)
10-
sb.check_window(name="simple_count_1", level=3)
11-
sb.assert_exact_text("1", ".countValue")
12-
assert server.get("count") == 1
13-
sb.click(".plusButton")
14-
sb.assert_exact_text("2", ".countValue")
15-
assert server.get("count") == 2
16-
sb.click(".plusButton")
17-
sb.click(".plusButton")
18-
sb.assert_exact_text("4", ".countValue")
19-
assert server.get("count") == 4
20-
sb.click(".plusButton")
21-
sb.assert_exact_text("5", ".countValue")
22-
assert server.get("count") == 5
23-
sb.check_window(name="simple_count_5", level=3)
8+
def test_reactivity(server, page, ref_dir):
9+
url = f"http://127.0.0.1:{server.port}/"
10+
page.goto(url)
11+
12+
ref_path = ref_dir / "simple_count_1.html"
13+
assert_html_matches(page.content(), ref_path)
14+
15+
plus_button = page.locator(".plusButton")
16+
count_value = page.locator(".countValue")
17+
18+
expect(count_value).to_have_text("1")
19+
assert server.get("count") == 1
20+
plus_button.click()
21+
expect(count_value).to_have_text("2")
22+
assert server.get("count") == 2
23+
plus_button.click()
24+
plus_button.click()
25+
expect(count_value).to_have_text("4")
26+
assert server.get("count") == 4
27+
plus_button.click()
28+
expect(count_value).to_have_text("5")
29+
assert server.get("count") == 5
30+
31+
ref_path = ref_dir / "simple_count_5.html"
32+
assert_html_matches(page.content(), ref_path)

0 commit comments

Comments
 (0)