Skip to content

Commit 01245c6

Browse files
Custom filename support for Axe reporting (#29)
<!-- markdownlint-disable-next-line first-line-heading --> ## Description <!-- Describe your changes in detail. --> This adds custom filename support for Axe reporting, so a user can just specify the name rather than rely on the auto-generated URL value. ## Context <!-- Why is this change required? What problem does it solve? --> If someone wants to run the same tests across multiple environments, the filenames will remain consistent. ## Type of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply. --> - [ ] Refactoring (non-breaking change) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would change existing functionality) - [ ] Bug fix (non-breaking change which fixes an issue) ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [ ] I am familiar with the [contributing guidelines](../docs/CONTRIBUTING.md) - [x] I have followed the code style of the project - [x] I have added tests to cover my changes - [x] I have updated the documentation accordingly - [ ] This PR is a result of pair or mob programming --- ## Sensitive Information Declaration To ensure the utmost confidentiality and protect your and others privacy, we kindly ask you to NOT including [PII (Personal Identifiable Information) / PID (Personal Identifiable Data)](https://digital.nhs.uk/data-and-information/keeping-data-safe-and-benefitting-the-public) or any other sensitive data in this PR (Pull Request) and the codebase changes. We will remove any PR that do contain any sensitive information. We really appreciate your cooperation in this matter. - [x] I confirm that neither PII/PID nor sensitive data are included in this PR and the codebase changes.
1 parent 7fffadc commit 01245c6

File tree

4 files changed

+41
-13
lines changed

4 files changed

+41
-13
lines changed

docs/utility-guides/Axe.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ The `Axe.run(page)` has the following optional arguments that can be passed in:
3939

4040
|Argument|Format|Supported Values|Default Value|Description|
4141
|--------|------|----------------|-------------|-----------|
42-
|`ruleset` |list (strings)|Any provided by [axe-core](https://www.deque.com/axe/core-documentation/api-documentation/)|['wcag2a', 'wcag21a', 'wcag2aa', 'wcag21aa', 'best-practice']|The tags that axe-core uses to filter specific checks. Defaulted to rules used for the WCAG 2.2 AA standard.|
43-
|`report_on_violation_only`|`bool`|True, False|False|If True, HTML and JSON reports will only be generated if at least one violation is found.|
44-
|`strict_mode`|`bool`|True, False|False|If True, when a violation is found an AxeAccessibilityException is raised, causing a test failure.|
45-
|`html_report_generated`|`bool`|True, False|True|If True, a HTML report will be generated summarising the axe-core findings.|
46-
|`json_report_generated`|`bool`|True, False|True|If True, a JSON report will be generated with the full axe-core findings.|
42+
|`ruleset` |`list[str]`|Any provided by [axe-core](https://www.deque.com/axe/core-documentation/api-documentation/)|`['wcag2a', 'wcag21a', 'wcag2aa', 'wcag21aa', 'best-practice']`|The tags that axe-core uses to filter specific checks. Defaulted to rules used for the WCAG 2.2 AA standard.|
43+
|`filename`|`str`|A string valid for a filename (e.g. `test_report`)||If provided, HTML and JSON reports will save with the filename provided. If not provided (default), the URL of the page under test will be used as the filename.|
44+
|`report_on_violation_only`|`bool`|`True`, `False`|`False`|If True, HTML and JSON reports will only be generated if at least one violation is found.|
45+
|`strict_mode`|`bool`|`True`, `False`|`False`|If True, when a violation is found an AxeAccessibilityException is raised, causing a test failure.|
46+
|`html_report_generated`|`bool`|`True`, `False`|`True`|If True, a HTML report will be generated summarising the axe-core findings.|
47+
|`json_report_generated`|`bool`|`True`, `False`|`True`|If True, a JSON report will be generated with the full axe-core findings.|
4748

4849
## Example usage
4950

tests/__init__.py

Whitespace-only changes.

tests_utils/test_axe.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,22 @@
11
import pytest
2+
import os
23
from pathlib import Path
34
from utils.axe import Axe
45

56
pytestmark = [pytest.mark.utils]
67

8+
AXE_REPORTS_DIR = Path(__file__).parent.parent / "axe-reports"
9+
TEST_JSON_DEFAULT_FILENAME = "www_test_com__1.json"
10+
TEST_JSON_CUSTOM_FILENAME = "test_json_file.json"
11+
TEST_HTML_DEFAULT_FILENAME = "www_test_com__1.html"
12+
TEST_HTML_CUSTOM_FILENAME = "test_html_file.html"
13+
14+
@pytest.fixture(scope="session", autouse=True)
15+
def remove_files_before_test() -> None:
16+
for file in [TEST_JSON_DEFAULT_FILENAME, TEST_JSON_CUSTOM_FILENAME, TEST_HTML_DEFAULT_FILENAME, TEST_HTML_CUSTOM_FILENAME]:
17+
if os.path.isfile(AXE_REPORTS_DIR / file):
18+
os.remove(AXE_REPORTS_DIR / file)
19+
720
def test_build_run_command() -> None:
821
assert Axe._build_run_command(['test']) == "run({runOnly: { type: 'tag', values: ['test'] }})"
922

@@ -15,9 +28,15 @@ def test_create_path_for_report() -> None:
1528

1629
def test_create_json_report() -> None:
1730
test_data = {"url": "https://www.test.com/1"}
31+
32+
# Default generation
1833
Axe._create_json_report(test_data)
34+
with open(AXE_REPORTS_DIR / TEST_JSON_DEFAULT_FILENAME, 'r') as file:
35+
assert file.read() == '{"url": "https://www.test.com/1"}'
1936

20-
with open(Path(__file__).parent.parent / "axe-reports" / "www_test_com__1.json", 'r') as file:
37+
# With custom filename
38+
Axe._create_json_report(test_data, TEST_JSON_CUSTOM_FILENAME.replace(".json", ""))
39+
with open(AXE_REPORTS_DIR / TEST_JSON_CUSTOM_FILENAME, 'r') as file:
2140
assert file.read() == '{"url": "https://www.test.com/1"}'
2241

2342
def test_create_html_report() -> None:
@@ -34,9 +53,15 @@ def test_create_html_report() -> None:
3453
"violations": [{"id": "test", "impact": None, "tags": ["cat.keyboard", "best-practice"], "description": "test", "help": "test", "helpUrl": "test", "nodes": []}]
3554
}
3655
expected_file_data = Axe._generate_html(test_data)
56+
57+
# Default generation
3758
Axe._create_html_report(test_data)
59+
with open(AXE_REPORTS_DIR / TEST_HTML_DEFAULT_FILENAME, 'r') as file:
60+
assert file.read() == expected_file_data
3861

39-
with open(Path(__file__).parent.parent / "axe-reports" / "www_test_com__1.html", 'r') as file:
62+
# With custom filename
63+
Axe._create_html_report(test_data, TEST_HTML_CUSTOM_FILENAME.replace(".html", ""))
64+
with open(AXE_REPORTS_DIR / TEST_HTML_CUSTOM_FILENAME, 'r') as file:
4065
assert file.read() == expected_file_data
4166

4267
def test_generate_html() -> None:

utils/axe.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class Axe:
1818

1919
@staticmethod
2020
def run(page: Page,
21+
filename: str = "",
2122
ruleset: list = ['wcag2a', 'wcag21a', 'wcag2aa', 'wcag21aa', 'best-practice'],
2223
report_on_violation_only: bool = False,
2324
strict_mode: bool = False,
@@ -28,6 +29,7 @@ def run(page: Page,
2829
2930
Args:
3031
page (playwright.sync_api.Page): The page object to execute axe-core against.
32+
filename (str): The filename to use for the outputted reports. If not provided, defaults to the URL under test.
3133
ruleset (list[str]): [Optional] If provided, a list of strings to denote the ruleset tags axe-core should use. If not provided, defaults to the WCAG 2.2 AA standard (uses tags: 'wcag2a', 'wcag21a', 'wcag2aa', 'wcag21aa', 'best-practice').
3234
report_on_violation_only (bool): [Optional] If true, only generates an Axe report if a violation is detected. If false (default), always generate a report.
3335
strict_mode (bool): [Optional] If true, raise an exception if a violation is detected. If false (default), proceed with test execution.
@@ -46,9 +48,9 @@ def run(page: Page,
4648
violations_detected = len(response["violations"]) > 0
4749
if not report_on_violation_only or (report_on_violation_only and violations_detected):
4850
if html_report_generated:
49-
Axe._create_html_report(response)
51+
Axe._create_html_report(response, filename)
5052
if json_report_generated:
51-
Axe._create_json_report(response)
53+
Axe._create_json_report(response, filename)
5254

5355
if violations_detected and strict_mode:
5456
raise AxeAccessibilityException(f"Axe Accessibility Violation detected on page: {response["url"]}")
@@ -77,8 +79,8 @@ def _create_path_for_report(filename: str) -> Path:
7779
return PATH_FOR_REPORT / filename
7880

7981
@staticmethod
80-
def _create_json_report(data: dict) -> Path:
81-
filename = f"{Axe._modify_filename_for_report(data["url"])}.json"
82+
def _create_json_report(data: dict, filename_overide: str = "") -> None:
83+
filename = f"{Axe._modify_filename_for_report(data["url"])}.json" if filename_overide == "" else f"{filename_overide}.json"
8284
full_path = Axe._create_path_for_report(filename)
8385

8486
with open(full_path, 'w') as file:
@@ -87,8 +89,8 @@ def _create_json_report(data: dict) -> Path:
8789
logging.info(f"JSON report generated: {full_path}")
8890

8991
@staticmethod
90-
def _create_html_report(data: dict) -> None:
91-
filename = f"{Axe._modify_filename_for_report(data["url"])}.html"
92+
def _create_html_report(data: dict, filename_overide: str = "") -> None:
93+
filename = f"{Axe._modify_filename_for_report(data["url"])}.html" if filename_overide == "" else f"{filename_overide}.html"
9294
full_path = Axe._create_path_for_report(filename)
9395

9496
with open(full_path, 'w') as file:

0 commit comments

Comments
 (0)