From db5e7ea3a45dd81dae184cedaaeabebfa175dd4a Mon Sep 17 00:00:00 2001 From: Joshua Frost Date: Thu, 2 Oct 2025 11:38:00 +0100 Subject: [PATCH 1/3] add accessibility checks to consent responses --- mavis/test/pages/consent_responses.py | 7 +++++ tests/test_consent_responses.py | 42 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/mavis/test/pages/consent_responses.py b/mavis/test/pages/consent_responses.py index 6ad0d743d80..c70a1aa04c5 100644 --- a/mavis/test/pages/consent_responses.py +++ b/mavis/test/pages/consent_responses.py @@ -111,6 +111,10 @@ def __init__(self, page: Page) -> None: @step("Match consent response with {1}") def match(self, child: Child) -> None: + self.search_for_child_with_all_filters(child) + self.click_link_response_with_record() + + def search_for_child_with_all_filters(self, child: Child) -> None: filter_locators = [ self.archived_records_checkbox, self.children_aged_out_of_programmes_checkbox, @@ -134,4 +138,7 @@ def match(self, child: Child) -> None: filter_locator.uncheck() self.page.get_by_role("link", name=str(child)).click() + + @step("Click Link response with record") + def click_link_response_with_record(self) -> None: self.link_button.click() diff --git a/tests/test_consent_responses.py b/tests/test_consent_responses.py index d520249286b..c9f37ab568d 100644 --- a/tests/test_consent_responses.py +++ b/tests/test_consent_responses.py @@ -213,3 +213,45 @@ def test_create_child_record_from_consent_without_nhs_number( dashboard_page.click_mavis() dashboard_page.click_children() children_page.verify_activity_log_for_created_or_matched_child(child) + + +@pytest.mark.accessibility +def test_accessibility( + give_online_consent, + go_to_unmatched_consent_responses, + accessibility_helper, + children, + dashboard_page, + programmes_page, + import_records_page, + match_consent_response_page, + consent_response_page, + unmatched_consent_responses_page, +): + """ + Test: Check accessibility of consent response pages. + Steps: + 1. Navigate to the consent response page. + 2. Verify each page passes accessibility checks. + Verification: + - Accessibility checks pass on all relevant pages. + """ + child = children[Programme.HPV][0] + + dashboard_page.click_mavis() + dashboard_page.click_programmes() + programmes_page.navigate_to_cohort_import(Programme.HPV) + import_records_page.import_class_list(CohortsFileMapping.FIXED_CHILD) + + dashboard_page.click_mavis() + dashboard_page.click_unmatched_consent_responses() + accessibility_helper.check_accessibility() + + unmatched_consent_responses_page.click_parent_on_consent_record_for_child(child) + accessibility_helper.check_accessibility() + + consent_response_page.click_match() + accessibility_helper.check_accessibility() + + match_consent_response_page.search_for_child_with_all_filters(child) + accessibility_helper.check_accessibility() From c55a0e1dcac3d4f4ef5eaa9794c7ac038ec01092 Mon Sep 17 00:00:00 2001 From: Joshua Frost Date: Thu, 2 Oct 2025 11:38:11 +0100 Subject: [PATCH 2/3] add accessibility checks to online consent responses --- mavis/test/pages/online_consent.py | 20 +++++---- tests/test_online_consent_school_moves.py | 50 +++++++++++++++++++++++ 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/mavis/test/pages/online_consent.py b/mavis/test/pages/online_consent.py index aabad13dbf6..5f615ac23de 100644 --- a/mavis/test/pages/online_consent.py +++ b/mavis/test/pages/online_consent.py @@ -151,17 +151,23 @@ def select_child_school(self, school: School) -> None: name = str(school) if name == self.displayed_school_name.inner_text().strip(): - self.confirm_school_radio.click() + self.confirm_school_radio.check() else: - self.select_different_school_radio.click() - self.click_continue() - - self.page.wait_for_load_state() + self.click_no_they_go_to_a_different_school() - self.school_name_combobox.fill(name) - self.page.get_by_role("option", name=name).click() + self.fill_school_name(name) + self.click_continue() + @step("Click No, they go to a different school") + def click_no_they_go_to_a_different_school(self) -> None: + self.select_different_school_radio.check() self.click_continue() + self.page.wait_for_load_state() + + @step("Fill school name") + def fill_school_name(self, school_name: str) -> None: + self.school_name_combobox.fill(school_name) + self.page.get_by_role("option", name=school_name).click() @step("Click on {1} radio button") def click_radio_button(self, name: str) -> None: diff --git a/tests/test_online_consent_school_moves.py b/tests/test_online_consent_school_moves.py index a4b3c944a90..437a539ed68 100644 --- a/tests/test_online_consent_school_moves.py +++ b/tests/test_online_consent_school_moves.py @@ -179,3 +179,53 @@ def test_online_consent_school_moves_with_new_patient( ) log_in_page.log_out() + + +@pytest.mark.accessibility +def test_accessibility( + start_consent_with_session_scheduled, + online_consent_page, + schools, + children, + accessibility_helper, +): + """ + Test: Validate accessibility of online consent pages when changing schools. + Steps: + 1. Go through submitting online consent, checking accessibility on each page. + Verification: + - No accessibility violations found. + """ + child = children[Programme.FLU][0] + schools = schools[Programme.FLU] + + online_consent_page.fill_child_name_details(*child.name) + accessibility_helper.check_accessibility() + + online_consent_page.fill_child_date_of_birth(child.date_of_birth) + accessibility_helper.check_accessibility() + + online_consent_page.click_no_they_go_to_a_different_school() + accessibility_helper.check_accessibility() + + online_consent_page.fill_school_name(str(schools[1])) + online_consent_page.click_continue() + accessibility_helper.check_accessibility() + + online_consent_page.fill_parent_details(child.parents[0]) + accessibility_helper.check_accessibility() + + online_consent_page.agree_to_flu_vaccination(consent_option=ConsentOption.BOTH) + accessibility_helper.check_accessibility() + + online_consent_page.fill_address_details(*child.address) + accessibility_helper.check_accessibility() + + online_consent_page.answer_health_questions( + online_consent_page.get_number_of_health_questions_for_flu(ConsentOption.BOTH), + yes_to_health_questions=False, + ) + accessibility_helper.check_accessibility() + + online_consent_page.click_confirm() + accessibility_helper.check_accessibility() From f3e1cc7edbcddd50d936beb7b7180ae82e9f0b1e Mon Sep 17 00:00:00 2001 From: Joshua Frost Date: Thu, 2 Oct 2025 11:52:18 +0100 Subject: [PATCH 3/3] add a new workflow for accessibility tests --- .../actions/run-functional-tests/action.yml | 16 +- .github/workflows/accessibility.yaml | 141 ++++++++++++++++++ 2 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/accessibility.yaml diff --git a/.github/actions/run-functional-tests/action.yml b/.github/actions/run-functional-tests/action.yml index 7e9727c4db9..6e35ffbb988 100644 --- a/.github/actions/run-functional-tests/action.yml +++ b/.github/actions/run-functional-tests/action.yml @@ -1,8 +1,10 @@ name: "Run Tests" -description: "Execute Functional tests" +description: "Execute tests" inputs: tests: default: '' + accessibility_tests: + default: 'false' device: required: true base_url: @@ -34,8 +36,18 @@ runs: run: uv run playwright install-deps webkit shell: bash + - name: Choose test suite to run + id: marker + run: | + if [ "${{ inputs.accessibility_tests }}" = "true" ]; then + echo "marker=accessibility" >> $GITHUB_OUTPUT + else + echo "marker=not accessibility" >> $GITHUB_OUTPUT + fi + shell: bash + - name: Run tests - run: uv run pytest --reruns 2 --device "${{ inputs.device }}" ${{ inputs.tests }} + run: uv run pytest --reruns 2 -m "${{ steps.marker.outputs.marker }}" --device "${{ inputs.device }}" ${{ inputs.tests }} shell: bash env: BASE_URL: ${{ inputs.base_url }} diff --git a/.github/workflows/accessibility.yaml b/.github/workflows/accessibility.yaml new file mode 100644 index 00000000000..c9ede17aee8 --- /dev/null +++ b/.github/workflows/accessibility.yaml @@ -0,0 +1,141 @@ +name: Accessibility tests + +on: + schedule: + - cron: "0 2 * * *" + workflow_dispatch: + inputs: + tests: + description: 'Tests to run (leave blank to run all tests!)' + required: false + default: '' + device: + description: 'Device to test' + required: true + default: 'Desktop Chrome' + type: choice + options: + - Desktop Chrome + - Desktop Edge + - Desktop Firefox + - Desktop Safari + - Galaxy S9+ + - Pixel 7 + - iPad (gen 7) landscape + - iPhone 15 + programmes: + description: 'Programmes to use (HPV, MENACWY, TD_IPV, FLU)' + required: true + default: 'HPV,MENACWY,TD_IPV,FLU' + environment: + description: 'Environment to run tests on' + required: true + default: 'qa' + type: choice + options: + - qa + - training + - sandbox-alpha + - sandbox-beta + screenshot_all_steps: + description: 'Take screenshots for all steps (in addition to failures)' + required: true + default: 'false' + type: choice + options: + - true + - false + set_feature_flags: + description: 'Set feature flags in the flipper page before running tests (affects all users of the environment being tested!)' + required: true + default: 'false' + type: choice + options: + - true + - false + additional_feature_flags: + description: '(If enabled above) Additional feature flags to set. api, basic_auth, dev_tools will be set by default' + required: false + default: '' + +jobs: + test: + permissions: + contents: write + + name: Functional tests + runs-on: ubuntu-latest + + env: + TZ: "Europe/London" + + steps: + - name: Set variables + id: set-variables + run: | + declare -A env_map=( + [qa]="https://qa.mavistesting.com" + [training]="https://training.manage-vaccinations-in-schools.nhs.uk" + [sandbox-alpha]="https://sandbox-alpha.mavistesting.com" + [sandbox-beta]="https://sandbox-beta.mavistesting.com" + ) + if [ "${{ github.event_name }}" = "pull_request" ]; then + echo "tests=" >> $GITHUB_OUTPUT + echo "device=Desktop Chrome" >> $GITHUB_OUTPUT + echo "environment=${env_map[qa]}" >> $GITHUB_OUTPUT + echo "programmes=HPV,MENACWY,TD_IPV,FLU" >> $GITHUB_OUTPUT + echo "set_feature_flags=false" >> $GITHUB_OUTPUT + echo "additional_feature_flags=" >> $GITHUB_OUTPUT + echo "deploy_report=false" >> $GITHUB_OUTPUT + echo "screenshot_all_steps=false" >> $GITHUB_OUTPUT + else + echo "tests=${{ github.event.inputs.tests }}" >> $GITHUB_OUTPUT + echo "device=${{ github.event.inputs.device }}" >> $GITHUB_OUTPUT + + input_env="${{ github.event.inputs.environment }}" + url="${env_map[$input_env]:-${env_map[qa]}}" + echo "environment=$url" >> $GITHUB_OUTPUT + + echo "programmes=${{ github.event.inputs.programmes }}" >> $GITHUB_OUTPUT + echo "set_feature_flags=${{ github.event.inputs.set_feature_flags }}" >> $GITHUB_OUTPUT + echo "additional_feature_flags=${{ github.event.inputs.additional_feature_flags }}" >> $GITHUB_OUTPUT + echo "deploy_report=true" >> $GITHUB_OUTPUT + echo "screenshot_all_steps=${{ github.event.inputs.screenshot_all_steps }}" >> $GITHUB_OUTPUT + fi + + - uses: actions/checkout@v5 + + - name: Cache Playwright browsers + uses: actions/cache@v4 + id: playwright-cache + with: + path: /home/runner/.cache/ms-playwright + key: playwright-${{ runner.os }}-${{ hashFiles('**/pyproject.toml') }} + + - name: Run tests + uses: ./.github/actions/run-functional-tests + with: + tests: ${{ steps.set-variables.outputs.tests }} + accessibility_tests: 'true' + device: ${{ steps.set-variables.outputs.device }} + base_url: ${{ steps.set-variables.outputs.environment }} + programmes_enabled: ${{ steps.set-variables.outputs.programmes }} + screenshot_all_steps: ${{ steps.set-variables.outputs.screenshot_all_steps }} + set_feature_flags: ${{ steps.set-variables.outputs.set_feature_flags }} + additional_feature_flags: ${{ steps.set-variables.outputs.additional_feature_flags }} + playwright_cache_hit: ${{ steps.playwright-cache.outputs.cache-hit }} + env: + BASIC_AUTH_TOKEN: ${{ secrets.HTTP_AUTH_TOKEN_FOR_TESTS }} + IMMS_BASE_URL: ${{ vars.IMMS_BASE_URL }} + IMMS_API_KEY: ${{ secrets.IMMS_API_KEY }} + IMMS_API_KID: ${{ secrets.IMMS_API_KID }} + IMMS_API_PEM: ${{ secrets.IMMS_API_PEM }} + + - name: Process reports + if: always() && steps.set-variables.outputs.deploy_report == 'true' + uses: ./.github/actions/deploy-reports + with: + device: ${{ steps.set-variables.outputs.device }} + environment: ${{ github.event.inputs.environment }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}