diff --git a/.github/workflows/functional.yaml b/.github/workflows/functional.yaml index 6e80859dd64..f3f05168ce0 100644 --- a/.github/workflows/functional.yaml +++ b/.github/workflows/functional.yaml @@ -1,4 +1,4 @@ -name: Functional tests +name: Functional tests (all devices) on: schedule: @@ -10,6 +10,7 @@ jobs: name: Test strategy: + fail-fast: false matrix: device: - Desktop Chrome diff --git a/.github/workflows/functional_selected_device.yaml b/.github/workflows/functional_selected_device.yaml new file mode 100644 index 00000000000..ad8e7c463b2 --- /dev/null +++ b/.github/workflows/functional_selected_device.yaml @@ -0,0 +1,52 @@ +name: Functional tests (selected device) + +on: + workflow_dispatch: + inputs: + device: + description: 'Device to test (exact name - defaults to "Desktop Chrome")' + required: false + default: 'Desktop Chrome' + pull_request: + +jobs: + test: + name: Test + + permissions: {} + + runs-on: ubuntu-latest + + env: + TZ: "Europe/London" + + steps: + - uses: actions/checkout@v4 + + - name: Set device variable + id: set-device + run: | + if [ "${{ github.event_name }}" = "pull_request" ]; then + echo "device=Desktop Chrome" >> $GITHUB_OUTPUT + else + echo "device=${{ github.event.inputs.device }}" >> $GITHUB_OUTPUT + fi + + - name: Install uv + uses: astral-sh/setup-uv@v6 + + - name: Install Playwright + run: uv run playwright install --with-deps + + - name: Run tests + run: uv run pytest --device "${{ steps.set-device.outputs.device }}" + env: + BASE_URL: ${{ vars.BASE_URL }} + BASIC_AUTH_PASSWORD: ${{ secrets.BASIC_AUTH_PASSWORD }} + BASIC_AUTH_USERNAME: ${{ secrets.BASIC_AUTH_USERNAME }} + + - name: Upload Allure results + uses: actions/upload-artifact@v4 + with: + name: results + path: allure-results diff --git a/mavis/test/pages/children.py b/mavis/test/pages/children.py index 65df823ff07..3ac53669363 100644 --- a/mavis/test/pages/children.py +++ b/mavis/test/pages/children.py @@ -72,17 +72,20 @@ def assert_n_children_found(self, n: int) -> None: @step("Click on record for child {1}") def click_record_for_child(self, child_name: str) -> None: - self.page.get_by_role("link", name=child_name).click() + with self.page.expect_navigation(): + self.page.get_by_role("link", name=child_name).click() @step("Click on {1} vaccination details") def click_vaccination_details(self, school: School) -> None: - self.vaccinations_card_row.filter(has_text=str(school)).get_by_role( - "link" - ).click() + with self.page.expect_navigation(): + self.vaccinations_card_row.filter(has_text=str(school)).get_by_role( + "link" + ).click() @step("Click on Child record") def click_child_record(self) -> None: - self.child_record_link.click() + with self.page.expect_navigation(): + self.child_record_link.click() @step("Click on Change NHS number") def click_change_nhs_no(self) -> None: diff --git a/mavis/test/pages/sessions.py b/mavis/test/pages/sessions.py index 045b2852aeb..dd0559b63a8 100644 --- a/mavis/test/pages/sessions.py +++ b/mavis/test/pages/sessions.py @@ -39,8 +39,8 @@ def __init__( ) self.programme_tab_link = self.page.get_by_role("link", name="Programme") - self.import_class_list_link = self.page.get_by_role( - "link", name="Import class list" + self.import_class_lists_link = self.page.get_by_role( + "link", name="Import class lists" ) self.continue_button = self.page.get_by_role("button", name="Continue") self.file_input = self.page.locator('input[type="file"]') @@ -53,9 +53,6 @@ def __init__( "radio", name="Yes, it’s safe to vaccinate" ) self.save_triage_button = self.page.get_by_role("button", name="Save triage") - self.consent_tab_link = self.page.get_by_role( - "link", name="Consent", exact=True - ) self.assess_gillick_competence_link = self.page.get_by_role( "link", name="Assess Gillick competence" ) @@ -170,14 +167,17 @@ def __get_display_formatted_date(self, date_to_format: str) -> str: @step("Click on Today tab") def click_today(self): self.today_tab_link.click() + self.today_tab_link.get_by_role("strong").wait_for() @step("Click on Scheduled tab") def click_scheduled(self): self.scheduled_tab_link.click() + self.scheduled_tab_link.get_by_role("strong").wait_for() @step("Click on Unscheduled tab") def click_unscheduled(self): self.unscheduled_tab_link.click() + self.unscheduled_tab_link.get_by_role("strong").wait_for() @step("Select No response") def select_no_response(self): @@ -219,14 +219,17 @@ def click_session_activity_and_notes(self): @step("Click on location {1}") def click_location(self, location: str): self.page.get_by_role("link", name=str(location)).click() + expect(self.page.locator("h1", has_text=str(location))).to_be_visible( + timeout=10000 + ) @step("Click on location radio {1}") def check_location_radio(self, location: str): self.page.get_by_role("radio", name=str(location)).check() - @step("Click on Import class list") - def click_import_class_list(self): - self.import_class_list_link.click() + @step("Click on Import class lists") + def click_import_class_lists(self): + self.import_class_lists_link.click() @step("Click on Continue") def click_continue_button(self): @@ -238,9 +241,10 @@ def choose_file_child_records(self, file_path: str): @step("Click on child {1}") def click_child(self, child_name: str): - self.page.get_by_role("heading", name=child_name).get_by_role( - "link" - ).first.click() + with self.page.expect_navigation(): + self.page.get_by_role("heading", name=child_name).get_by_role( + "link" + ).first.click() @step("Search and click on {1}") def search_and_click_child(self, child_name: str): @@ -261,7 +265,7 @@ def click_save_triage(self): @step("Click on Consent tab") def click_consent_tab(self): - self.consent_tab_link.click() + self._click_tab("Consent") @step("Click on Assess Gillick competence") def click_assess_gillick_competence(self): @@ -559,7 +563,7 @@ def navigate_to_scheduled_sessions(self, location: str): self.click_location(location) def navigate_to_class_list_import(self): - self.click_import_class_list() + self.click_import_class_lists() self.select_year_groups(8, 9, 10, 11) def schedule_a_valid_session(self, location: str, for_today: bool = False): diff --git a/mavis/test/pages/vaccines.py b/mavis/test/pages/vaccines.py index 36b8c870ba3..9828d755980 100644 --- a/mavis/test/pages/vaccines.py +++ b/mavis/test/pages/vaccines.py @@ -92,4 +92,4 @@ def click_change_batch(self, vaccine: Vaccine, batch_name: str): @step("Archive {2} batch for {1}") def click_archive_batch(self, vaccine: Vaccine, batch_name: str): name = f"Archive {batch_name} batch of {vaccine}" - self.page.get_by_role("link", name=name).click() + self.page.get_by_role("link", name=name).click(force=True) diff --git a/tests/test_school_moves.py b/tests/test_school_moves.py index d140cc0a35f..a54c3ffaa30 100644 --- a/tests/test_school_moves.py +++ b/tests/test_school_moves.py @@ -21,7 +21,7 @@ def setup_confirm_and_ignore( ) def upload_class_list(): - sessions_page.click_import_class_list() + sessions_page.click_import_class_lists() sessions_page.select_year_groups(8, 9, 10, 11) sessions_page.choose_file_child_records(input_file_path) sessions_page.click_continue_button()