Skip to content

Commit a11e03f

Browse files
committed
Added new Playwright tests to replace the old Selenium tests
1 parent 470fc84 commit a11e03f

46 files changed

Lines changed: 482 additions & 2085 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/Dockerfile

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
FROM ubuntu:22.04
22

3-
ARG GECKODRIVER_VERSION=0.33.0
4-
ARG GECKODRIVER_FILE=geckodriver-v${GECKODRIVER_VERSION}-linux64.tar.gz
5-
ARG GECKODRIVER_LINK=https://github.com/mozilla/geckodriver/releases/download/v${GECKODRIVER_VERSION}/${GECKODRIVER_FILE}
6-
73
ENV DEBIAN_FRONTEND=noninteractive
84

95
RUN apt update -y
@@ -17,9 +13,4 @@ RUN pip install -r requirements.txt
1713
RUN pip install -r requirements_testing.txt
1814
RUN rm requirements.txt requirements_testing.txt
1915

20-
# install geckodriver for selenium
21-
RUN curl -s -L $GECKODRIVER_LINK | tar -xz
22-
RUN chmod +x geckodriver
23-
RUN mv geckodriver /usr/bin/
24-
2516
ENV APLUS_BASE_URL="-"

.github/workflows/tests.yml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,6 @@ jobs:
4141
key: v3-${{ hashFiles('.github/workflows/Dockerfile', 'requirements_testing.txt', 'requirements.txt') }}
4242
- run: docker load -i .docker-img.tar
4343
- run: docker run -v ${{ github.workspace }}:${{ github.workspace }} -w ${{ github.workspace }} testimg bash -c 'python3 manage.py compilemessages && python3 manage.py test'
44-
selenium-tests:
45-
runs-on: ubuntu-latest
46-
needs: docker-build
47-
steps:
48-
- uses: actions/checkout@v3
49-
- uses: actions/cache@v3
50-
with:
51-
path: .docker-img.tar
52-
key: v3-${{ hashFiles('.github/workflows/Dockerfile', 'requirements_testing.txt', 'requirements.txt') }}
53-
- run: docker load -i .docker-img.tar
54-
- run: docker run -v ${{ github.workspace }}:${{ github.workspace }} -w ${{ github.workspace }} testimg bash -c 'python3 manage.py compilemessages && selenium_test/run_servers_and_tests.sh'
5544
playwright-tests:
5645
timeout-minutes: 60
5746
runs-on: ubuntu-latest

.gitignore

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,6 @@ dump.json
3737

3838
test_results/
3939

40-
selenium_test/aplus.out
41-
selenium_test/example_grader.out
42-
selenium_test/server.ports
43-
selenium_test/grader/db.sqlite3
44-
4540
*~
4641
*.swp
4742
*.swo

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ The [doc/GRADERS.md](doc/GRADERS.md) describes the assessment protocol supported
2828
Additionally, there is a minimal example grader in [doc/example_grader.py](doc/example_grader.py), which can be used to start a new service.
2929
A list of existing assessment services and other tools can be found in [the project github page](https://apluslms.github.io/components/).
3030

31-
The [selenium_test/](selenium_test) offers an integration test suite using the Selenium Firefox driver.
31+
The [e2e_tests/](e2e_tests) folder offers an integration test suite using Playwright.
3232

3333
Code Organization
3434
-----------------

doc/README.md

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,6 @@ Therefore they are run and updated outside the containers, within a virtual envi
139139

140140
### Prerequisities
141141

142-
- For Selenium tests:
143-
* Firefox browser installed
144-
* xvfb virtual framebuffer installed (`sudo apt-get install xvfb` or `aptdcon --install xvfb`)
145142
- python3 installed
146143
- [Python module venv (or virtualenv)](https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/#installing-virtualenv) installed
147144
- For translations: gettext (`aptdcon --install gettext` or `sudo apt-get install gettext`)
@@ -193,44 +190,6 @@ If you need to be able to login or use the admin-page while running the code wit
193190
$ python3 manage.py test
194191
```
195192

196-
### Selenium integration tests
197-
198-
Selenium tests check end-to-end -functioning from a user-perspective.
199-
The tests will automatically open and direct Firefox browser windows.
200-
Currently, the tests depend on a Unix type shell and are run within a virtual environment created above.
201-
202-
1. Install the necessary requirements:
203-
204-
```sh
205-
$ pip3 install -r requirements_testing.txt
206-
```
207-
208-
2. Download the latest release of geckodriver (choose the appropriate tar.gz file based on your machine) from https://github.com/mozilla/geckodriver/releases and extract it.
209-
210-
3. Check the path to your extracted geckodriver and add it to PATH:
211-
212-
```sh
213-
$ export PATH=$PATH:/path-to-your-extracted-geckodriver/
214-
```
215-
216-
4. To setup the servers and run all the tests at one go:
217-
218-
```sh
219-
$ selenium_test/run_servers_and_tests.sh
220-
```
221-
222-
5. Alternatively you can run individual tests:
223-
224-
```sh
225-
$ cd selenium_test/test/
226-
$ ../run_servers.sh
227-
228-
$ python3 login_test.py
229-
$ python3 home_page_test.py
230-
231-
$ ../kill_servers.sh
232-
```
233-
234193
### Updating translations for Finnish and English versions
235194

236195
Before creating a pull request, you need to ensure that the [English strings](https://github.com/apluslms/a-plus/blob/master/locale/en/LC_MESSAGES/django.po) and [Finnish translations](https://github.com/apluslms/a-plus/blob/master/locale/fi/LC_MESSAGES/django.po) are up-to-date.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import re
2+
from playwright.sync_api import Page, expect
3+
from e2e_tests.helpers import navigate_to_default_course, login
4+
5+
def test_should_not_count_empty_submit(page: Page):
6+
page.goto("http://localhost:8000/?hl=en")
7+
login(page, "student", "student")
8+
navigate_to_default_course(page)
9+
page.get_by_role("link", name="Course materials").click()
10+
first_link = page.get_by_role("link", name="AJAX exercises: grading in browser JavaScript").first
11+
first_link.click()
12+
page.get_by_role("button", name="Submit").click()
13+
14+
submissions = page.get_by_role("button", name=re.compile("My submissions"))
15+
expect(submissions).to_contain_text("0 / 20")
16+
#empty submit should not count as submission
17+
18+
points = page.locator('#chapter-exercise-1').get_by_role("button", name=re.compile("Points"))
19+
expect(points).to_contain_text("0 / 10")
20+
21+
22+
def test_should_give_full_points_on_correct_answer(page: Page):
23+
page.goto("http://localhost:8000/?hl=en")
24+
login(page, "student", "student")
25+
navigate_to_default_course(page)
26+
page.get_by_role("link", name="Course materials").click()
27+
first_link = page.get_by_role("link", name="AJAX exercises: grading in browser JavaScript").first
28+
first_link.click()
29+
30+
page.get_by_role("textbox").fill("abc")
31+
page.get_by_role("button", name="Submit").click()
32+
33+
submissions = page.get_by_role("button", name=re.compile("My submissions"))
34+
expect(submissions).to_contain_text("1 / 20")
35+
36+
points = page.locator('#chapter-exercise-1').get_by_role("button", name=re.compile("Points"))
37+
expect(points).to_contain_text("10 / 10")

e2e_tests/test_compare_submissions.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ def test_compare_submissions(page: Page) -> None:
3535
first_link.click()
3636
page.get_by_label("6.3.6 Wallet").get_by_role(
3737
"button", name="View all submissions").click()
38-
page.locator("#submission-2").get_by_role("link", name="Inspect").click()
38+
39+
latest_submission = page.locator('[id^="submission-"]').first
40+
latest_submission.get_by_role("link", name="Inspect").click()
3941

4042
def assert_line(filename: str, line_number: int, text: str, color: str):
4143
line = page.get_by_test_id(f"{filename}-line-{line_number}")
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import re
2+
from playwright.sync_api import Page, expect
3+
from e2e_tests.helpers import navigate_to_default_course, login
4+
5+
6+
def test_should_not_submit_without_files(page: Page):
7+
page.goto("http://localhost:8000/?hl=en")
8+
login(page, "student", "student")
9+
navigate_to_default_course(page)
10+
page.get_by_role("link", name="Course materials").click()
11+
first_link = page.get_by_role("link", name="Exercises with Python grader utils").first
12+
first_link.click()
13+
14+
exercise = page.locator('#chapter-exercise-1')
15+
16+
exercise.get_by_role("button", name="Submit").click()
17+
18+
submissions = exercise.get_by_role("button", name=re.compile("My submissions"))
19+
points = exercise.get_by_role("button", name=re.compile("Points"))
20+
21+
expect(submissions).to_contain_text("0 / 10")
22+
#clicking submit without files will not result in a submission
23+
expect(points).to_contain_text("0 / 10")
24+
25+
#TODO more tests ?
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import re
22
from playwright.sync_api import Page, expect
3-
from e2e_tests.helpers import navigate_to_default_course
3+
from e2e_tests.helpers import navigate_to_default_course, login
44

55

6-
def test_frontpage_has_title(page: Page):
6+
def test_homepage(page: Page):
77
page.goto("http://localhost:8000/?hl=en")
88
expect(page).to_have_title(re.compile("A+"))
99

10-
11-
def test_course_has_heading(page: Page) -> None:
12-
page.goto("http://localhost:8000/?hl=en")
10+
login(page, "student", "student")
1311
navigate_to_default_course(page)
1412
expect(page.get_by_role("heading", name="A+ Manual")).to_be_visible()
13+
#TODO figure out more testing for the homepage

e2e_tests/test_login.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import re
2+
from playwright.sync_api import Page, expect
3+
from e2e_tests.helpers import login
4+
5+
6+
def test_login(page: Page):
7+
page.goto("http://localhost:8000/?hl=en")
8+
login(page, "student", "student")
9+
expect(page).to_have_title(re.compile("A+"))
10+
expect(page.get_by_label("Main")).to_contain_text("Stacy Student")
11+
12+
def test_false_login(page: Page):
13+
page.goto("http://localhost:8000/?hl=en")
14+
login(page, "fake", "fake")
15+
expect(page).to_have_title(re.compile("Log in to A+ | A+"))
16+
17+
error_message = "Please enter a correct username and password. Note that both fields may be case-sensitive."
18+
expect(
19+
page.locator("div.alert.alert-danger.alert-dismissible")
20+
).to_contain_text(error_message)

0 commit comments

Comments
 (0)