Skip to content

Commit bec3356

Browse files
authored
Use playwright for functional tests (#1163)
## Description of Changes _Cherry-picked from https://github.com/OrcaCollective/OpenOversight/pull/537__ Switch to Playwright for functional tests. The Playwright API seems easier to use in many ways than Selenium ## Notes for Deployment None! This only applies to tests ## Screenshots (if appropriate) N/A ## Testing instructions Run `just test` ## Checks - [x] I have rebased my changes on `main` - [x] `just lint` passes - [x] `just test` passes
1 parent e2adc6b commit bec3356

File tree

10 files changed

+174
-309
lines changed

10 files changed

+174
-309
lines changed

.github/workflows/test_prs.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ jobs:
1717
- uses: actions/checkout@v3
1818
- name: Run tests
1919
run: PYTHON_VERSION=${{ matrix.python-version }} make test_with_version
20+
# Upload playwright traces if tests fail
21+
- uses: actions/upload-artifact@v4
22+
if: ${{ !cancelled() }}
23+
with:
24+
name: playwright-traces
25+
path: build/test-results/
2026
pre-commit:
2127
runs-on: ubuntu-latest
2228
steps:

CONTRIB.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ We use [pre-commit](https://pre-commit.com/) for automated linting and style che
2323

2424
You can run `pre-commit run --all-files` or `make lint` to run pre-commit over your local codebase, or `pre-commit run` to run it only over the currently stages files.
2525

26+
## Testing
27+
28+
To run tests, run `make test` once your containers are up and running.
29+
30+
We use Playwright for functional testing. If functional tests fail locally, you can find per-test traces in the `build/test-results` directory. In the Lint and Test GitHub action, traces are uploaded as an artifact you can download via the "Upload Artifact" step. Once you have your trace, you can upload it to the [Playwright Trace Viewer](https://trace.playwright.dev/) tool for debugging.
31+
2632
### Accessibility
2733
Keep in mind when adding images that `alt` tags are required for screen readers. If text outside of the image explains what the image is or is referring to, the tag can be an empty string (`alt=""`). The tag can also be empty if the image is decoration and does not add information or context. If the image has text or important information, use the present tense to describe what is happening in the image.
2834

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ build_with_version: create_empty_secret create_default_env
1414
.PHONY: test_with_version
1515
test_with_version: build_with_version
1616
touch OpenOversight/tests/coverage.xml
17-
docker compose run --rm web-test pytest --cov=OpenOversight --cov-report xml:OpenOversight/tests/coverage.xml --doctest-modules -n 4 --dist=loadfile -v OpenOversight/tests/
17+
docker compose run --rm web-test pytest --cov-report xml:OpenOversight/tests/coverage.xml -n 4 --dist=loadfile -v OpenOversight/tests/
1818

1919
# Run containers
2020
.PHONY: start
@@ -70,9 +70,9 @@ populate: create_db
7070
.PHONY: test
7171
test: start
7272
if [ -z "$(name)" ]; then \
73-
docker compose run --rm web-test pytest --cov --doctest-modules -n auto --dist=loadfile -v OpenOversight/tests/; \
73+
docker compose run --rm web-test pytest -n auto --dist=loadfile -v OpenOversight/tests/; \
7474
else \
75-
docker compose run --rm web-test pytest --cov --doctest-modules -v OpenOversight/tests/ -k $(name); \
75+
docker compose run --rm web-test pytest -v OpenOversight/tests/ -k $(name); \
7676
fi
7777

7878
.PHONY: lint

OpenOversight/app/static/js/find_officer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ $(document).ready(function() {
3434
$('#current-uii').text(deptUiidLabel);
3535
$('#uii-question').show();
3636
} else {
37+
$('#unique_internal_identifier').text('');
3738
$('#uii-question').hide();
3839
}
3940
});

OpenOversight/pytest.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[pytest]
2+
addopts = --cov --doctest-modules --tracing=retain-on-failure --output=/test-results

OpenOversight/tests/conftest.py

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,14 @@
88
from datetime import date, datetime, time, timedelta, timezone
99
from io import BytesIO
1010
from pathlib import Path
11-
from time import sleep
1211
from typing import List, Optional
1312

1413
import pytest
1514
from faker import Faker
1615
from flask import current_app
1716
from PIL import Image as Pimage
18-
from selenium import webdriver
19-
from selenium.webdriver.firefox.options import Options
20-
from selenium.webdriver.firefox.service import Service
17+
from playwright.sync_api import Page
2118
from sqlalchemy.orm import scoped_session, sessionmaker
22-
from xvfbwrapper import Xvfb
2319

2420
from OpenOversight.app import create_app
2521
from OpenOversight.app.models.database import (
@@ -895,28 +891,15 @@ def server_port(worker_number):
895891

896892

897893
@pytest.fixture(scope="session")
898-
def browser(app, server_port):
894+
def server(app, server_port):
899895
# start server
900896
port = server_port
901897
print("Starting server at port {port}")
902898
threading.Thread(
903899
target=app.run, daemon=True, kwargs={"debug": False, "port": port}
904900
).start()
905-
# give the server a few seconds to ensure it is up
906-
sleep(10)
907-
908-
# start headless webdriver
909-
visual_display = Xvfb()
910-
visual_display.start()
911-
options = Options()
912-
options.add_argument("--headless")
913-
driver = webdriver.Firefox(
914-
options=options, service=Service(log_path="/tmp/geckodriver.log")
915-
)
916-
# wait for browser to start up
917-
sleep(3)
918-
yield driver
919901

920-
# shutdown headless webdriver
921-
driver.quit()
922-
visual_display.stop()
902+
903+
@pytest.fixture
904+
def page(app, server, page: Page):
905+
yield page

0 commit comments

Comments
 (0)