diff --git a/.github/workflows/accessibility-tests.yml b/.github/workflows/accessibility-tests.yml new file mode 100644 index 0000000..7dcce71 --- /dev/null +++ b/.github/workflows/accessibility-tests.yml @@ -0,0 +1,35 @@ +name: Accessibility Tests + +on: + pull_request: + branches: + - gh-pages + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + ref: ${{ github.head_ref }} + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python3 -m pip install --upgrade pip + pip install -r requirements.txt + pip install axe-core-python pytest playwright axe-playwright-python + + - name: Install Playwright browsers + run: | + playwright install + + - name: Run accessibility tests + run: | + python3 -m pytest tests/ diff --git a/requirements.txt b/requirements.txt index bbcc2a8..70e8d03 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,3 +13,5 @@ python-frontmatter ephemeral_port_reserve pytest-playwright pytest-xprocess +axe-core-python==0.1.0 +axe-playwright-python==0.1.4 \ No newline at end of file diff --git a/tests/test.py b/tests/test.py index 3c068dc..431a7ce 100644 --- a/tests/test.py +++ b/tests/test.py @@ -7,6 +7,9 @@ from playwright.sync_api import Page, expect, sync_playwright +from axe_core_python.sync_playwright import Axe + + @pytest.fixture(scope="module") def page_url(xprocess, url_port): """Returns the url of the live server""" @@ -43,6 +46,19 @@ class Starter(ProcessStarter): xprocess.getinfo("page_url").terminate() +def test_accessibility(page_url: tuple[Page, str]): + """Run accessibility tests on the homepage""" + page, live_server_url = page_url + page.goto(f"{live_server_url}/") + + axe = Axe() + results = axe.run(page) + + assert ( + len(results["violations"]) == 0 + ), f"Accessibility violations found: {results['violations']}" + + def test_destination( loaded_route: str, page_url: tuple[Page, str], @@ -79,6 +95,13 @@ def test_headers_in_language(page_url: tuple[Page, str], route: str) -> None: ] # urls start with the language if not en assert doc_lang == lang + axe = Axe() + results = axe.run(page) + + assert ( + len(results["violations"]) == 0 + ), f"Accessibility violations found: {results['violations']}" + @pytest.mark.parametrize( "title, url", @@ -96,6 +119,13 @@ def test_bpdevs_title_en(page_url: tuple[Page, str], title: str, url: str) -> No page.goto(f"{live_server_url}{url}") expect(page).to_have_title(f"Black Python Devs | {title}") + axe = Axe() + results = axe.run(page) + + assert ( + len(results["violations"]) == 0 + ), f"Accessibility violations found: {results['violations']}" + def test_mailto_bpdevs(page_url: tuple[Page, str]) -> None: page, live_server_url = page_url @@ -103,6 +133,13 @@ def test_mailto_bpdevs(page_url: tuple[Page, str]) -> None: mailto = page.get_by_role("link", name="email") expect(mailto).to_have_attribute("href", "mailto:contact@blackpythondevs.com") + axe = Axe() + results = axe.run(page) + + assert ( + len(results["violations"]) == 0 + ), f"Accessibility violations found: {results['violations']}" + @pytest.mark.parametrize( "url", @@ -115,6 +152,13 @@ def test_page_description_in_index_and_blog(page_url: tuple[Page, str], url: str expect(page.locator("p.post-description").first).to_be_visible() expect(page.locator("p.post-description").first).not_to_be_empty() + axe = Axe() + results = axe.run(page) + + assert ( + len(results["violations"]) == 0 + ), f"Accessibility violations found: {results['violations']}" + def stem_description( path: pathlib.Path, @@ -146,3 +190,10 @@ def test_page_blog_posts( page.locator('meta[name="description"]').get_attribute("content") == frontmatter["description"] ) + + axe = Axe() + results = axe.run(page) + + assert ( + len(results["violations"]) == 0 + ), f"Accessibility violations found: {results['violations']}"