diff --git a/.gitignore b/.gitignore index e7cef02d024..061de9b122f 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,6 @@ venv/ # Local logs/pytest.log main.py - +reports/* +working/* +.vscode/* diff --git a/.vscode/settings.json b/.vscode/settings.json index b2542c2670e..20555ff2fdc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,10 +10,14 @@ "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, "cSpell.words": [ - "dotenv" + "dotenv", + "downcasting", + "fillna", + "venv" ], "[python]": { "editor.defaultFormatter": "ms-python.black-formatter", "editor.formatOnSave": true, - } + }, + "python.analysis.autoImportCompletions": true } diff --git a/README.md b/README.md index eb75e585335..2a233d306a5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Manage vaccinations in schools + [![Run MAVIS tests on TEST](https://github.com/NHSDigital/manage-vaccinations-in-schools-testing/actions/workflows/MAVIS_TEST.yml/badge.svg)](https://github.com/NHSDigital/manage-vaccinations-in-schools-testing/actions/workflows/MAVIS_TEST.yml) ## Introduction @@ -13,7 +14,7 @@ This test pack requires Python 3.10 installed on the system or greater to run. To execute the tests from your system, please follow the 4 easy steps below: -1. Clone the repo to any local folder +1. Clone the repository to any local folder ```console git clone https://github.com/NHSDigital/manage-vaccinations-in-schools-testing.git diff --git a/conftest.py b/conftest.py index 07e6e6cefde..d698190b49c 100644 --- a/conftest.py +++ b/conftest.py @@ -1,8 +1,8 @@ import pytest +from playwright.sync_api import sync_playwright from libs import CurrentExecution as ce from libs import file_ops as fo -from libs.constants import workflow_type from libs.wrappers import * @@ -12,27 +12,36 @@ def pytest_addoption(parser): @pytest.fixture(scope="session") def start_exe_session(request): - _browser_name = request.config.getoption("browser_or_device") - ce.current_browser_name = _browser_name ce.get_env_values() + ce.reset_environment() ce.session_screenshots_dir = create_session_screenshot_dir() - ce.start_browser(browser_name=_browser_name) - yield - ce.quit_browser() + ce.current_browser_name = request.config.getoption("browser_or_device") -@pytest.fixture -def create_browser_page(start_exe_session): - ce.start_test(w_type=workflow_type.APPLICATION) - yield ce.page - ce.end_test() +@pytest.fixture(scope="session") +def start_playwright(): + with sync_playwright() as _playwright: + _playwright.selectors.set_test_id_attribute("data-qa") + yield _playwright + + +@pytest.fixture() +def start_mavis(start_exe_session, start_playwright): + _browser, _context = start_browser(pw=start_playwright, browser_or_device=ce.current_browser_name) + ce.browser = _browser + ce.page = _context.new_page() + ce.page.goto(url=ce.service_url) + yield + close_browser(browser=_browser, page=ce.page) @pytest.fixture -def start_consent_workflow(start_exe_session): - ce.start_test(w_type=workflow_type.PARENTAL_CONSENT) - yield ce.page - ce.end_test() +def start_consent_workflow(start_exe_session, start_playwright): + _browser, _context = start_browser(pw=start_playwright, browser_or_device=ce.current_browser_name) + ce.page = _context.new_page() + ce.page.goto(url=ce.parental_consent_url) + yield + close_browser(browser=_browser, page=ce.page) def create_session_screenshot_dir() -> str: @@ -40,3 +49,46 @@ def create_session_screenshot_dir() -> str: _session_name = f"{get_new_datetime()}-{ce.current_browser_name}" fo.file_operations().create_dir(dir_path=f"screenshots/{_session_name}") return f"screenshots/{_session_name}" + + +def start_browser(pw, browser_or_device: str): + _http_credentials = { + "username": ce.base_auth_username, + "password": ce.base_auth_password, + } + try: + match browser_or_device.lower(): + case "iphone_12": + _browser = pw.webkit.launch(headless=ce.headless_mode) + _context = _browser.new_context(**pw.devices["iPhone 12"], http_credentials=_http_credentials) + case "iphone_11": + _browser = pw.chromium.launch(channel="chrome", headless=ce.headless_mode) + _context = _browser.new_context(**pw.devices["iPhone 11"], http_credentials=_http_credentials) + case "pixel_5": + _browser = pw.webkit.launch(headless=ce.headless_mode) + _context = _browser.new_context(**pw.devices["Pixel 5"], http_credentials=_http_credentials) + case "s9+": + _browser = pw.chromium.launch(channel="chromium", headless=ce.headless_mode) + _context = _browser.new_context(**pw.devices["Galaxy S9+"], http_credentials=_http_credentials) + case "chrome": + _browser = pw.chromium.launch(channel="chrome", headless=ce.headless_mode) + _context = _browser.new_context(http_credentials=_http_credentials) + case "msedge": + _browser = pw.chromium.launch(channel="msedge", headless=ce.headless_mode) + _context = _browser.new_context(http_credentials=_http_credentials) + case "firefox": + _browser = pw.firefox.launch(headless=ce.headless_mode) + _context = _browser.new_context(http_credentials=_http_credentials) + case _: # Desktop Chromium for all other cases + _browser = pw.chromium.launch(headless=ce.headless_mode) + _context = _browser.new_context(http_credentials=_http_credentials) + return _browser, _context + except Exception as e: + raise AssertionError(f"Error launching {browser_or_device}: {e}") + + +def close_browser(browser, page): + if page.get_by_role("button", name="Log out").is_visible(): + page.get_by_role("button", name="Log out").click() + page.close() + browser.close() diff --git a/libs/__init__.py b/libs/__init__.py index e9d35425a5f..5abe9ea2d30 100644 --- a/libs/__init__.py +++ b/libs/__init__.py @@ -1,19 +1,18 @@ import os from dotenv import load_dotenv -from playwright.sync_api import sync_playwright -from libs.constants import workflow_type +from libs import api_ops class CurrentExecution: page = None - environment = None + browser = None + service_url: str = "" base_auth_username: str = "" base_auth_password: str = "" current_browser_name: str = "" headless_mode: bool = False - playwright: bool = None session_screenshots_dir: str = "" screenshot_sequence: int = 0 capture_screenshot_flag: bool = False @@ -23,18 +22,10 @@ class CurrentExecution: reset_endpoint: str = "" api_token: str = "" - @staticmethod - def start_test(w_type: workflow_type): - CurrentExecution.start_page(w_type=w_type) - - @staticmethod - def end_test(): - CurrentExecution.close_page() - @staticmethod def get_env_values(): load_dotenv() - CurrentExecution.environment = os.getenv("TEST_URL") + CurrentExecution.service_url = os.getenv("TEST_URL") CurrentExecution.base_auth_username = os.getenv("TEST_USERNAME") CurrentExecution.base_auth_password = os.getenv("TEST_PASSWORD") CurrentExecution.login_username = os.getenv("LOGIN_USERNAME") @@ -46,122 +37,6 @@ def get_env_values(): CurrentExecution.api_token = os.getenv("API_TOKEN") @staticmethod - def start_browser(browser_name: str): - CurrentExecution.playwright = sync_playwright().start() - CurrentExecution.playwright.selectors.set_test_id_attribute("data-qa") - match browser_name.lower(): - case "chromium": - CurrentExecution.launch_chromium() - case "msedge": - CurrentExecution.launch_edge() - case "firefox": - CurrentExecution.launch_firefox() - case "chrome": # Google Chrome for all other cases - CurrentExecution.launch_chrome() - case _: # Mobile browsers - CurrentExecution.launch_mobile_browser(device_name=browser_name) - - @staticmethod - def start_page(w_type: workflow_type): - CurrentExecution.context = CurrentExecution.browser.new_context( - http_credentials={ - "username": CurrentExecution.base_auth_username, - "password": CurrentExecution.base_auth_password, - } - ) - CurrentExecution.page = CurrentExecution.context.new_page() - match w_type.lower(): - case workflow_type.PARENTAL_CONSENT: - CurrentExecution.page.goto(url=CurrentExecution.parental_consent_url) - case _: - CurrentExecution.reset_upload_data() - CurrentExecution.page.goto(url=CurrentExecution.environment) - - @staticmethod - def quit_browser(): - CurrentExecution.browser.close() - - @staticmethod - def close_page(): - CurrentExecution.page.close() - - @staticmethod - def launch_chromium(): - try: - CurrentExecution.browser = CurrentExecution.playwright.chromium.launch( - headless=CurrentExecution.headless_mode, args=["--fullscreen"] - ) - except Exception as e: - raise AssertionError(f"Error launching Chromium: {e}") - - @staticmethod - def launch_edge(): - try: - CurrentExecution.browser = CurrentExecution.playwright.chromium.launch( - channel="msedge", headless=CurrentExecution.headless_mode, args=["--fullscreen"] - ) - except Exception as e: - raise AssertionError(f"Error launching Edge: {e}") - - @staticmethod - def launch_firefox(): - try: - CurrentExecution.browser = CurrentExecution.playwright.firefox.launch( - headless=CurrentExecution.headless_mode, args=["--fullscreen"] - ) - except Exception as e: - raise AssertionError(f"Error launching Firefox: {e}") - - @staticmethod - def launch_chrome(): - try: - CurrentExecution.browser = CurrentExecution.playwright.chromium.launch( - channel="chrome", headless=CurrentExecution.headless_mode, args=["--fullscreen"] - ) - except Exception as e: - raise AssertionError(f"Error launching Chrome: {e}") - - @staticmethod - def launch_mobile_browser(device_name: str): - _http_credentials = { - "username": CurrentExecution.base_auth_username, - "password": CurrentExecution.base_auth_password, - } - try: - match device_name.lower(): - case "iphone_12": - CurrentExecution.browser = CurrentExecution.playwright.webkit.launch( - headless=CurrentExecution.headless_mode - ) - CurrentExecution.context = CurrentExecution.browser.new_context( - **CurrentExecution.playwright.devices["iPhone 12"], http_credentials=_http_credentials - ) - case "iphone_11": - CurrentExecution.browser = CurrentExecution.playwright.chromium.launch( - channel="chrome", headless=CurrentExecution.headless_mode - ) - CurrentExecution.context = CurrentExecution.browser.new_context( - **CurrentExecution.playwright.devices["iPhone 11"], http_credentials=_http_credentials - ) - case "pixel_5": - CurrentExecution.browser = CurrentExecution.playwright.webkit.launch( - headless=CurrentExecution.headless_mode - ) - CurrentExecution.context = CurrentExecution.browser.new_context( - **CurrentExecution.playwright.devices["Pixel 5"], http_credentials=_http_credentials - ) - case _: - CurrentExecution.browser = CurrentExecution.playwright.chromium.launch( - channel="chromium", headless=CurrentExecution.headless_mode - ) - CurrentExecution.context = CurrentExecution.browser.new_context( - **CurrentExecution.playwright.devices["Galaxy S9+"], http_credentials=_http_credentials - ) - CurrentExecution.page = CurrentExecution.context.new_page() - except Exception as e: - raise AssertionError(f"Error launching device browser {device_name}: {e}") - - @staticmethod - def reset_upload_data(): + def reset_environment(): _headers = {"Authorization": CurrentExecution.api_token} - # _ = api_ops.api_operations().api_get(endpoint=CurrentExecution.reset_endpoint, header=_headers, param=None) + _ = api_ops.api_operations().api_get(endpoint=CurrentExecution.reset_endpoint, header=_headers, param=None) diff --git a/libs/constants.py b/libs/constants.py index e13d936a03c..6e39ce9b3b3 100644 --- a/libs/constants.py +++ b/libs/constants.py @@ -1,72 +1,77 @@ +from typing import Final + + class object_properties: - TEXT = "text" - VISIBILITY = "visibility" + TEXT: Final[str] = "text" + VISIBILITY: Final[str] = "visibility" class actions: - CLICK_LINK = "click_link" - CLICK_BUTTON = "click_button" - CLICK_LABEL = "click_label" - FILL = "fill" - TYPE = "type" - RADIO_BUTTON_SELECT = "radio_select" - SELECT_FILE = "select_file" - SELECT_FROM_LIST = "select_from_list" - CHECKBOX_CHECK = "checkbox_check" - CLICK_LINK_INDEX_FOR_ROW = "click_link_index_for_row" + CLICK_LINK: Final[str] = "click_link" + CLICK_BUTTON: Final[str] = "click_button" + CLICK_LABEL: Final[str] = "click_label" + FILL: Final[str] = "fill" + TYPE: Final[str] = "type" + RADIO_BUTTON_SELECT: Final[str] = "radio_select" + SELECT_FILE: Final[str] = "select_file" + SELECT_FROM_LIST: Final[str] = "select_from_list" + CHECKBOX_CHECK: Final[str] = "checkbox_check" + CLICK_LINK_INDEX_FOR_ROW: Final[str] = "click_link_index_for_row" + CLICK_WILDCARD: Final[str] = "click_wildcard" + CHAIN_LOCATOR_ACTION: Final[str] = "chain_locator" class screenshot_types: - JPEG = "jpeg" + JPEG: Final[str] = "jpeg" class file_mode: - READ = "r" - WRITE = "w" - APPEND = "a" + READ: Final[str] = "r" + WRITE: Final[str] = "w" + APPEND: Final[str] = "a" class api_constants: - API_SUCCESS_STATUS_CODE_MIN = 200 - API_SUCCESS_STATUS_CODE_MAX = 299 + API_SUCCESS_STATUS_CODE_MIN: Final[int] = 200 + API_SUCCESS_STATUS_CODE_MAX: Final[int] = 299 class workflow_type: - APPLICATION = "application" - PARENTAL_CONSENT = "parental_consent" + APPLICATION: Final[str] = "application" + PARENTAL_CONSENT: Final[str] = "parental_consent" class data_values: - EMPTY = "" + EMPTY: Final[str] = "" class playwright_roles: - LINK = "link" - BUTTON = "button" - OPTION = "option" - ROW = "row" + LINK: Final[str] = "link" + BUTTON: Final[str] = "button" + OPTION: Final[str] = "option" + ROW: Final[str] = "row" class wait_time: - MIN = "3s" - MED = "10s" - MAX = "30s" + MIN: Final[str] = "3s" + MED: Final[str] = "10s" + MAX: Final[str] = "30s" class escape_characters: - SEPARATOR = "||" # Used only in code - SPACE = " " - NEW_LINE = "\n" - CARRIAGE_RETURN = "\r" - NEW_LINE_CARRIAGE_RETURN = "\r\n" - SINGLE_QUOTE_OPEN_UNICODE = "’" - SINGLE_QUOTE_CLOSE_UNICODE = "‘" - SINGLE_QUOTE_OPEN = "‘" - SINGLE_QUOTE_CLOSE = "’" - TAB = "\t" - COLON = ":" - BACKSLASH = "\\" - STROKE = "/" + SEPARATOR: Final[str] = "||" # Used only in code + SPACE: Final[str] = " " + NEW_LINE: Final[str] = "\n" + CARRIAGE_RETURN: Final[str] = "\r" + NEW_LINE_CARRIAGE_RETURN: Final[str] = "\r\n" + SINGLE_QUOTE_OPEN_UNICODE: Final[str] = "’" + SINGLE_QUOTE_CLOSE_UNICODE: Final[str] = "‘" + SINGLE_QUOTE_OPEN: Final[str] = "‘" + SINGLE_QUOTE_CLOSE: Final[str] = "’" + TAB: Final[str] = "\t" + COLON: Final[str] = ":" + BACKSLASH: Final[str] = "\\" + STROKE: Final[str] = "/" UI_FORMATTING = [ SPACE, NEW_LINE, @@ -82,42 +87,66 @@ class escape_characters: class test_data_file_paths: - PARENTAL_CONSENT = "test_data/ParentalConsent.xlsx" - VACCS_HPV_POSITIVE = f"test_data/hpv/i_positive.csv{escape_characters.SEPARATOR}test_data/hpv/o_positive.csv" - VACCS_HPV_NEGATIVE = f"test_data/hpv/i_negative.csv{escape_characters.SEPARATOR}test_data/hpv/o_negative.csv" - VACCS_HPV_DUP_1 = f"test_data/hpv/i_dup_1.csv{escape_characters.SEPARATOR}test_data/hpv/o_dup_1.csv" - VACCS_HPV_DUP_2 = f"test_data/hpv/i_dup_2.csv{escape_characters.SEPARATOR}test_data/hpv/o_dup_2.csv" - VACCS_HPV_INVALID_STRUCTURE = ( + PARENTAL_CONSENT: Final[str] = "test_data/ParentalConsent.xlsx" + VACCS_HPV_POSITIVE: Final[str] = ( + f"test_data/hpv/i_positive.csv{escape_characters.SEPARATOR}test_data/hpv/o_positive.csv" + ) + VACCS_HPV_NEGATIVE: Final[str] = ( + f"test_data/hpv/i_negative.csv{escape_characters.SEPARATOR}test_data/hpv/o_negative.csv" + ) + VACCS_HPV_DUP_1: Final[str] = f"test_data/hpv/i_dup_1.csv{escape_characters.SEPARATOR}test_data/hpv/o_dup_1.csv" + VACCS_HPV_DUP_2: Final[str] = f"test_data/hpv/i_dup_2.csv{escape_characters.SEPARATOR}test_data/hpv/o_dup_2.csv" + VACCS_HPV_INVALID_STRUCTURE: Final[str] = ( f"test_data/hpv/i_invalid_structure.csv{escape_characters.SEPARATOR}test_data/hpv/o_invalid_structure.csv" ) - VACCS_HPV_EMPTY_FILE = f"test_data/hpv/i_empty.csv{escape_characters.SEPARATOR}test_data/hpv/o_empty.csv" - VACCS_HPV_HEADER_ONLY = ( + VACCS_HPV_EMPTY_FILE: Final[str] = ( + f"test_data/hpv/i_empty.csv{escape_characters.SEPARATOR}test_data/hpv/o_empty.csv" + ) + VACCS_HPV_HEADER_ONLY: Final[str] = ( f"test_data/hpv/i_header_only.csv{escape_characters.SEPARATOR}test_data/hpv/o_header_only.csv" ) - COHORTS_POSITIVE = f"test_data/cohorts/i_positive.csv{escape_characters.SEPARATOR}test_data/cohorts/o_positive.csv" - COHORTS_NEGATIVE = f"test_data/cohorts/i_negative.csv{escape_characters.SEPARATOR}test_data/cohorts/o_negative.csv" - COHORTS_INVALID_STRUCTURE = f"test_data/cohorts/i_invalid_structure.csv{escape_characters.SEPARATOR}test_data/cohorts/o_invalid_structure.csv" - COHORTS_EMPTY_FILE = f"test_data/cohorts/i_empty.csv{escape_characters.SEPARATOR}test_data/cohorts/o_empty.csv" - COHORTS_HEADER_ONLY = ( + COHORTS_POSITIVE: Final[str] = ( + f"test_data/cohorts/i_positive.csv{escape_characters.SEPARATOR}test_data/cohorts/o_positive.csv" + ) + COHORTS_NEGATIVE: Final[str] = ( + f"test_data/cohorts/i_negative.csv{escape_characters.SEPARATOR}test_data/cohorts/o_negative.csv" + ) + COHORTS_INVALID_STRUCTURE: Final[str] = ( + f"test_data/cohorts/i_invalid_structure.csv{escape_characters.SEPARATOR}test_data/cohorts/o_invalid_structure.csv" + ) + COHORTS_EMPTY_FILE: Final[str] = ( + f"test_data/cohorts/i_empty.csv{escape_characters.SEPARATOR}test_data/cohorts/o_empty.csv" + ) + COHORTS_HEADER_ONLY: Final[str] = ( f"test_data/cohorts/i_header_only.csv{escape_characters.SEPARATOR}test_data/cohorts/o_header_only.csv" ) - CHILD_POSITIVE = f"test_data/child/i_positive.csv{escape_characters.SEPARATOR}test_data/child/o_positive.csv" - CHILD_NEGATIVE = f"test_data/child/i_negative.csv{escape_characters.SEPARATOR}test_data/child/o_negative.csv" - CHILD_INVALID_STRUCTURE = ( + CHILD_POSITIVE: Final[str] = ( + f"test_data/child/i_positive.csv{escape_characters.SEPARATOR}test_data/child/o_positive.csv" + ) + CHILD_NEGATIVE: Final[str] = ( + f"test_data/child/i_negative.csv{escape_characters.SEPARATOR}test_data/child/o_negative.csv" + ) + CHILD_INVALID_STRUCTURE: Final[str] = ( f"test_data/child/i_invalid_structure.csv{escape_characters.SEPARATOR}test_data/child/o_invalid_structure.csv" ) - CHILD_EMPTY_FILE = f"test_data/child/i_empty.csv{escape_characters.SEPARATOR}test_data/child/o_empty.csv" - CHILD_HEADER_ONLY = ( + CHILD_EMPTY_FILE: Final[str] = ( + f"test_data/child/i_empty.csv{escape_characters.SEPARATOR}test_data/child/o_empty.csv" + ) + CHILD_HEADER_ONLY: Final[str] = ( f"test_data/child/i_header_only.csv{escape_characters.SEPARATOR}test_data/child/o_header_only.csv" ) - CLASS_POSITIVE = ( + CLASS_POSITIVE: Final[str] = ( f"test_data/class_list/i_positive.csv{escape_characters.SEPARATOR}test_data/class_list/o_positive.csv" ) - CLASS_NEGATIVE = ( + CLASS_NEGATIVE: Final[str] = ( f"test_data/class_list/i_negative.csv{escape_characters.SEPARATOR}test_data/class_list/o_negative.csv" ) - CLASS_INVALID_STRUCTURE = f"test_data/class_list/i_invalid_structure.csv{escape_characters.SEPARATOR}test_data/class_list/o_invalid_structure.csv" - CLASS_EMPTY_FILE = f"test_data/class_list/i_empty.csv{escape_characters.SEPARATOR}test_data/class_list/o_empty.csv" - CLASS_HEADER_ONLY = ( + CLASS_INVALID_STRUCTURE: Final[str] = ( + f"test_data/class_list/i_invalid_structure.csv{escape_characters.SEPARATOR}test_data/class_list/o_invalid_structure.csv" + ) + CLASS_EMPTY_FILE: Final[str] = ( + f"test_data/class_list/i_empty.csv{escape_characters.SEPARATOR}test_data/class_list/o_empty.csv" + ) + CLASS_HEADER_ONLY: Final[str] = ( f"test_data/class_list/i_header_only.csv{escape_characters.SEPARATOR}test_data/class_list/o_header_only.csv" ) diff --git a/libs/playwright_ops.py b/libs/playwright_ops.py index b9f2133973b..9f5ad8e3ef1 100644 --- a/libs/playwright_ops.py +++ b/libs/playwright_ops.py @@ -163,3 +163,7 @@ def perform_action(self, locator, action, value=None, exact: bool = False) -> No ) elem.scroll_into_view_if_needed() elem.click() + case actions.CLICK_WILDCARD: + elem = self.ce.page.click(f"text={locator}") + case actions.CHAIN_LOCATOR_ACTION: + eval(f"self.ce.page.{locator}") diff --git a/libs/testdata_ops.py b/libs/testdata_ops.py index b13840e0995..553e98fc36e 100644 --- a/libs/testdata_ops.py +++ b/libs/testdata_ops.py @@ -13,14 +13,16 @@ class testdata_operations: def create_file_from_template(self, template_path: str) -> str: _template_text = self.fo.get_file_text(file_path=template_path) _file_text = [] - _ctr = 0 + _ctr = -1 + _dt = get_new_datetime() for _ln in _template_text.split(escape_characters.NEW_LINE): - _ctr += 1 - _ln = _ln.replace("<>", self.get_new_nhs_no(valid=True)) + _ln = _ln.replace("<>", f"9{self.get_new_nhs_no(valid=True)[:9]}") _ln = _ln.replace("<>", self.get_new_nhs_no(valid=False)) - _ln = _ln.replace("<>", f"F{get_new_datetime()}{_ctr}") - _ln = _ln.replace("<>", f"L{get_new_datetime()}{_ctr}") + _ln = _ln.replace("<>", f"F{_dt}{_ctr}") + _ln = _ln.replace("<>", f"L{_dt}{_ctr}") + _ln = _ln.replace("<>", _dt[:8]) _file_text.append(_ln) + _ctr += 1 return self.fo.create_file(content=escape_characters.NEW_LINE.join(_file_text)) def get_new_nhs_no(self, valid=True) -> str: @@ -47,6 +49,8 @@ def clean_df(self, df: pd.DataFrame) -> pd.DataFrame: return _df def split_file_paths(self, file_paths: str) -> tuple[str, str]: - _i = self.create_file_from_template(template_path=file_paths.split(escape_characters.SEPARATOR)[0]) - _o = file_paths.split(escape_characters.SEPARATOR)[1] - return _i, _o + _input_file_path = self.create_file_from_template( + template_path=file_paths.split(escape_characters.SEPARATOR)[0] + ) + _output_file_path = file_paths.split(escape_characters.SEPARATOR)[1] + return _input_file_path, _output_file_path diff --git a/libs/wrappers.py b/libs/wrappers.py index 08be6b3cd68..22488cdc2c1 100644 --- a/libs/wrappers.py +++ b/libs/wrappers.py @@ -58,6 +58,7 @@ def clean_file_name(file_name: str) -> str: def get_future_date(offset_days: int) -> str: _future_date = datetime.now() + timedelta(days=offset_days) - while _future_date.weekday() >= 5: - _future_date = _future_date + timedelta(days=1) + if offset_days != 0: + while _future_date.weekday() >= 5: + _future_date = _future_date + timedelta(days=1) return _future_date.strftime("%Y%m%d") diff --git a/pages/pg_dashboard.py b/pages/pg_dashboard.py index 9f3fb123d18..b07c1dd6c7a 100644 --- a/pages/pg_dashboard.py +++ b/pages/pg_dashboard.py @@ -1,5 +1,6 @@ from libs import playwright_ops -from libs.constants import actions, escape_characters, object_properties +from libs.constants import actions, escape_characters, object_properties, wait_time +from libs.wrappers import wait class pg_dashboard: @@ -32,11 +33,12 @@ def click_your_organisation(self): self.po.perform_action(locator=self.LNK_ORGANISATION, action=actions.CLICK_LINK) def go_to_dashboard(self): + wait(timeout=wait_time.MIN) # Scripts sometimes error out without this wait when called as a teardown action self.po.perform_action(locator=self.LNK_DASHBOARD, action=actions.CLICK_LINK) def verify_all_expected_links(self): self.po.verify(locator=self.LNK_PROGRAMMES, property=object_properties.VISIBILITY, value=True, exact=True) - # self.po.verify(locator=self.LNK_VACCINES, property=object_properties.VISIBILITY, value=True, exact=True) # Out of scope for 1a + self.po.verify(locator=self.LNK_VACCINES, property=object_properties.VISIBILITY, value=True, exact=True) self.po.verify(locator=self.LNK_SESSIONS, property=object_properties.VISIBILITY, value=True, exact=True) self.po.verify(locator=self.LNK_CHILDREN, property=object_properties.VISIBILITY, value=True, exact=True) self.po.verify(locator=self.LNK_NOTICES, property=object_properties.VISIBILITY, value=True, exact=True) diff --git a/pages/pg_login.py b/pages/pg_login.py index 52c4579c5db..95efe663d3a 100644 --- a/pages/pg_login.py +++ b/pages/pg_login.py @@ -10,6 +10,7 @@ class pg_login: TXT_EMAIL_ADDRESS = "Email address" TXT_PASSWORD = "Password" BTN_LOGIN = "Log in" + BTN_LOGOUT = "Log out" LBL_BANNER = "banner" LBL_USER = "Nurse Joy" LBL_PARAGRAPH = "paragraph" @@ -42,3 +43,6 @@ def perform_invalid_login(self, user: str, pwd: str, expected_message: str) -> s self.enter_password(password=pwd) self.click_login() self.po.verify(locator=self.LBL_PARAGRAPH, property=object_properties.TEXT, value=expected_message, exact=True) + + def perform_logout(self): + self.po.perform_action(locator=self.BTN_LOGOUT, action=actions.CLICK_BUTTON) diff --git a/pages/pg_parental_consent.py b/pages/pg_parental_consent.py index db477db834e..5e68242738a 100644 --- a/pages/pg_parental_consent.py +++ b/pages/pg_parental_consent.py @@ -49,6 +49,11 @@ class pg_parental_consent: RDO_VACCINE_MEDICAL_REASONS = "Medical reasons" RDO_PERSONAL_CHOICE = "Personal choice" RDO_OTHER = "Other" + RDO_ONLINE = "Online" + RDO_YES_THEY_AGREE = "Yes, they agree" + RDO_NO_THEY_DO_NOT_AGREE = "No, they do not agree" + RDO_NO_RESPONSE = "No response" + RDO_YES_SAFE_TO_VACCINATE = "Yes, it’s safe to vaccinate" def click_start_now(self): self.po.perform_action(locator=self.BTN_START_NOW, action=actions.CLICK_BUTTON) @@ -175,3 +180,39 @@ def select_consent_not_given_reason(self, reason: str, reason_details: str) -> N self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON) self.po.perform_action(locator=self.TXT_DETAILS, action=actions.FILL, value=reason_details) self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON) + + def service_give_consent(self): + from libs import CurrentExecution as ce + + self.po.perform_action(locator="Parent1Name1 (Dad)", action=actions.RADIO_BUTTON_SELECT) + self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON) + self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON) # Parent contact details page + self.po.perform_action(locator=self.RDO_ONLINE, action=actions.RADIO_BUTTON_SELECT) + self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON) + self.po.perform_action(locator=self.RDO_YES_THEY_AGREE, action=actions.RADIO_BUTTON_SELECT) + # self.po.perform_action(locator=self.RDO_NO_THEY_DO_NOT_AGREE , action=actions.RADIO_BUTTON_SELECT) + # self.po.perform_action(locator=self.RDO_NO_RESPONSE , action=actions.RADIO_BUTTON_SELECT) + self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON) + # page.get_by_role("group", name="Does your child have any severe allergies?").get_by_label("Yes").check() + # page.get_by_role("textbox", name="Give details").click() + # page.get_by_role("textbox", name="Give details").fill("asdfaf") + self.po.perform_action( + locator="get_by_role('group', name='Does your child have any severe allergies?').get_by_label('No').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action( + locator="get_by_role('group', name='Does your child have any medical conditions for which they receive treatment?').get_by_label('No').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action( + locator="get_by_role('group', name='Has your child ever had a').get_by_label('No').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action( + locator="get_by_role('group', name='Does your child need extra').get_by_label('No').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON) + self.po.perform_action(locator=self.RDO_YES_SAFE_TO_VACCINATE, action=actions.RADIO_BUTTON_SELECT) + self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON) + self.po.perform_action(locator=self.BTN_CONFIRM, action=actions.CLICK_BUTTON) diff --git a/pages/pg_programmes.py b/pages/pg_programmes.py index a7e892bd9cd..ca0afc69a0f 100644 --- a/pages/pg_programmes.py +++ b/pages/pg_programmes.py @@ -23,31 +23,31 @@ class pg_programmes: LBL_PARAGRAPH = "paragraph" LBL_MAIN = "main" - def click_HPV(self): + def click_hpv(self): self.po.perform_action(locator=self.LNK_HPV, action=actions.CLICK_LINK) - def click_Imports(self): + def click_imports(self): self.po.perform_action(locator=self.LNK_IMPORTS, action=actions.CLICK_LINK) - def click_Cohorts(self): + def click_cohorts(self): self.po.perform_action(locator=self.LNK_COHORTS, action=actions.CLICK_LINK) - def click_ImportRecords(self): + def click_import_records(self): self.po.perform_action(locator=self.LNK_IMPORT_RECORDS, action=actions.CLICK_LINK) - def click_ImportCohortRecords(self): + def click_import_cohort_records(self): self.po.perform_action(locator=self.LNK_IMPORT_CHILD_RECORDS, action=actions.CLICK_LINK) - def select_ChildRecords(self): + def select_child_records(self): self.po.perform_action(locator=self.RDO_CHILD_RECORDS, action=actions.RADIO_BUTTON_SELECT) - def select_VaccinationRecords(self): + def select_vaccination_records(self): self.po.perform_action(locator=self.RDO_VACCINATION_RECORDS, action=actions.RADIO_BUTTON_SELECT) - def click_Continue(self): + def click_continue(self): self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON) - def click_ChooseFile_ChildRecords(self): + def click_choose_file_child_records(self): self.po.perform_action(locator=self.LBL_CHOOSE_COHORT_FILE, action=actions.CLICK_LABEL) def choose_file_child_records(self, file_path: str): @@ -57,7 +57,7 @@ def choose_file_child_records(self, file_path: str): value=file_path, ) - def click_ChooseFile_VaccinationRecords(self): + def click_choose_file_vaccination_records(self): self.po.perform_action(locator=self.LBL_CHOOSE_COHORT_FILE, action=actions.CLICK_LABEL) def choose_file_vaccination_records(self, file_path: str): @@ -67,7 +67,7 @@ def choose_file_vaccination_records(self, file_path: str): value=file_path, ) - def verify_Import_Processing_Started(self): + def verify_import_processing_started(self): self.po.verify(locator=self.LBL_PARAGRAPH, property=object_properties.TEXT, value=self.LBL_IMPORT_STARTED) def click_uploaded_file_datetime(self): @@ -84,75 +84,75 @@ def verify_upload_output(self, file_path: str): def upload_hpv_vaccination_records(self, file_paths: str): _input_file_path, _output_file_path = self.tdo.split_file_paths(file_paths=file_paths) - self.click_HPV() - self.click_Imports() - self.click_ImportRecords() - self.select_VaccinationRecords() - self.click_Continue() + self.click_hpv() + self.click_imports() + self.click_import_records() + self.select_vaccination_records() + self.click_continue() self.choose_file_vaccination_records(file_path=_input_file_path) - self.click_Continue() + self.click_continue() self.record_upload_time() wait(timeout=wait_time.MED) - self.click_Imports() + self.click_imports() wait(timeout=wait_time.MIN) # Required for Firefox self.click_uploaded_file_datetime() self.verify_upload_output(file_path=_output_file_path) def upload_hpv_child_records(self, file_paths: str): _input_file_path, _output_file_path = self.tdo.split_file_paths(file_paths=file_paths) - self.click_HPV() - self.click_Imports() - self.click_ImportRecords() - self.select_ChildRecords() - self.click_Continue() + self.click_hpv() + self.click_imports() + self.click_import_records() + self.select_child_records() + self.click_continue() self.choose_file_child_records(file_path=_input_file_path) - self.click_Continue() + self.click_continue() self.record_upload_time() wait(timeout=wait_time.MED) - self.click_Imports() + self.click_imports() self.click_uploaded_file_datetime() self.verify_upload_output(file_path=_output_file_path) def upload_cohorts(self, file_paths: str): _input_file_path, _output_file_path = self.tdo.split_file_paths(file_paths=file_paths) - self.click_HPV() - self.click_Cohorts() - self.click_ImportCohortRecords() + self.click_hpv() + self.click_cohorts() + self.click_import_cohort_records() self.choose_file_child_records(file_path=_input_file_path) - self.click_Continue() + self.click_continue() self.record_upload_time() wait(timeout=wait_time.MED) - self.click_Imports() + self.click_imports() self.click_uploaded_file_datetime() self.verify_upload_output(file_path=_output_file_path) def upload_invalid_files(self, file_paths: str): _input_file_path, _output_file_path = self.tdo.split_file_paths(file_paths=file_paths) - self.click_HPV() - self.click_Imports() - self.click_ImportRecords() - self.select_VaccinationRecords() - self.click_Continue() + self.click_hpv() + self.click_imports() + self.click_import_records() + self.select_vaccination_records() + self.click_continue() self.choose_file_vaccination_records(file_path=_input_file_path) - self.click_Continue() + self.click_continue() self.verify_upload_output(file_path=_output_file_path) def upload_invalid_cohorts(self, file_paths: str): _input_file_path, _output_file_path = self.tdo.split_file_paths(file_paths=file_paths) - self.click_HPV() - self.click_Cohorts() - self.click_ImportCohortRecords() + self.click_hpv() + self.click_cohorts() + self.click_import_cohort_records() self.choose_file_child_records(file_path=_input_file_path) - self.click_Continue() + self.click_continue() self.verify_upload_output(file_path=_output_file_path) def upload_invalid_hpv_child_records(self, file_paths: str): _input_file_path, _output_file_path = self.tdo.split_file_paths(file_paths=file_paths) - self.click_HPV() - self.click_Imports() - self.click_ImportRecords() - self.select_ChildRecords() - self.click_Continue() + self.click_hpv() + self.click_imports() + self.click_import_records() + self.select_child_records() + self.click_continue() self.choose_file_child_records(file_path=_input_file_path) - self.click_Continue() + self.click_continue() self.verify_upload_output(file_path=_output_file_path) diff --git a/pages/pg_sessions.py b/pages/pg_sessions.py index f8586965cc4..6449842ea4f 100644 --- a/pages/pg_sessions.py +++ b/pages/pg_sessions.py @@ -5,7 +5,7 @@ from libs import CurrentExecution, file_ops, playwright_ops, testdata_ops from libs.constants import actions, object_properties, wait_time from libs.wrappers import * -from pages import pg_dashboard +from pages import pg_dashboard, pg_parental_consent class pg_sessions: @@ -14,24 +14,28 @@ class pg_sessions: tdo = testdata_ops.testdata_operations() fo = file_ops.file_operations() dashboard_page = pg_dashboard.pg_dashboard() + consent_page = pg_parental_consent.pg_parental_consent() - LNK_SCHEDULED = "Scheduled" - LNK_UNSCHEDULED = "Unscheduled" - # LNK_SCHOOL = "The Ruiz Centre" - LNK_SCHOOL = "Grange School" + LNK_SCHOOL_1 = "Bohunt School Wokingham" + LNK_SCHOOL_2 = "Bothal Middle School" + + LNK_TAB_TODAY = "Today" + LNK_TAB_SCHEDULED = "Scheduled" + LNK_TAB_UNSCHEDULED = "Unscheduled" + LNK_TAB_ACTIVITY_LOG = "Activity log" LNK_IMPORT_CLASS_LIST = "Import class list" - # LBL_CHOOSE_COHORT_FILE = "The Ruiz CentreImport class" - LBL_CHOOSE_COHORT_FILE = "Grange SchoolImport class" + LBL_CHOOSE_COHORT_FILE_1 = f"{LNK_SCHOOL_1}Import class" + LBL_CHOOSE_COHORT_FILE_2 = f"{LNK_SCHOOL_2}Import class" BTN_CONTINUE = "Continue" LNK_ADD_SESSION_DATES = "Add session dates" LNK_RECORD_VACCINATIONS = "Record vaccinations" - LNK_CHILD_FULL_NAME = "ChildFirst28 ChildLast28" + LNK_CHILD_FULL_NAME = "CF" LNK_UPDATE_TRIAGE_OUTCOME = "Update triage outcome" LNK_SCHEDULE_SESSIONS = "Schedule sessions" RDO_YES_SAFE_TO_VACCINATE = "Yes, it’s safe to vaccinate" BTN_SAVE_TRIAGE = "Save triage" LBL_PARAGRAPH = "paragraph" - LBL_TRIAGE_UPDATED_MESSAGE = "Triage outcome updated for ChildFirst28 ChildLast28" + LBL_TRIAGE_UPDATED_MESSAGE = "Triage outcome updated for CF" LBL_MAIN = "main" TXT_DAY = "Day" TXT_MONTH = "Month" @@ -39,15 +43,29 @@ class pg_sessions: LNK_EDIT_SESSION = "Edit session" LNK_CHANGE_SESSION_DATES = "Change session dates" BTN_DELETE = "Delete" - LNK_CANCEL = "Cancel" + LNK_BACK = "Back" LNK_CONTINUE = "Continue" + LNK_CONSENT_FORM = "View parental consent form (opens in new tab)" + BTN_CHECK_CONSENT_RESPONSES = "Check consent responses" + LNK_ASSESS_GILLICK_COMPETENT = "Assess Gillick competence" + RDO_YES_GILLICK_COMPETENT = "Yes, they are Gillick competent" + RDO_NO_GILLICK_COMPETENT = "No" + TXT_GILLICK_ASSESSMENT_DETAILS = "Assessment notes (optional)" + BTN_SAVE_CHANGES = "Save changes" + LBL_ACTIVITY_LOG_ENTRY = f"Triaged decision: Safe to vaccinate" + BTN_GET_CONSENT_RESPONSES = "Get consent response" + BTN_COMPLETE_GILLICK_ASSESSMENT = "Complete your assessment" + LBL_CHILD_COMPETENT = "Child assessed as Gillick competent" + LBL_CHILD_NOT_COMPETENT = "Child assessed as not Gillick competent" + LNK_EDIT_GILLICK_COMPETENCE = "Edit Gillick competence" + BTN_UPDATE_GILLICK_ASSESSMENT = "Update your assessment" - def get_display_formatted_date(self, date_to_format: str) -> str: + def __get_display_formatted_date(self, date_to_format: str) -> str: _parsed_date = datetime.strptime(date_to_format, "%Y%m%d") _formatted_date = _parsed_date.strftime("%A %d %B %Y").replace(" 0", " ") return _formatted_date - def record_upload_time(self): + def __record_upload_time(self): self.upload_time = get_link_formatted_date_time() def click_uploaded_file_datetime(self): @@ -59,44 +77,128 @@ def verify_upload_output(self, file_path: str): for _msg in _expected_errors: self.po.verify(locator=self.LBL_MAIN, property=object_properties.TEXT, value=_msg, exact=False) - def click_Scheduled(self): - self.po.perform_action(locator=self.LNK_SCHEDULED, action=actions.CLICK_LINK, exact=True) + def click_today(self): + self.po.perform_action(locator=self.LNK_TAB_TODAY, action=actions.CLICK_LINK, exact=True) + + def click_scheduled(self): + self.po.perform_action(locator=self.LNK_TAB_SCHEDULED, action=actions.CLICK_LINK, exact=True) + + def click_unscheduled(self): + self.po.perform_action(locator=self.LNK_TAB_UNSCHEDULED, action=actions.CLICK_LINK, exact=True) - def click_Unscheduled(self): - self.po.perform_action(locator=self.LNK_UNSCHEDULED, action=actions.CLICK_LINK, exact=True) + def click_activity_log(self): + self.po.perform_action(locator=self.LNK_TAB_ACTIVITY_LOG, action=actions.CLICK_LINK, exact=True) - def click_School(self): - self.po.perform_action(locator=self.LNK_SCHOOL, action=actions.CLICK_LINK) + def click_school1(self): + self.po.perform_action(locator=self.LNK_SCHOOL_1, action=actions.CLICK_LINK) - def click_Import_Class_List(self): + def click_school2(self): + self.po.perform_action(locator=self.LNK_SCHOOL_2, action=actions.CLICK_LINK) + + def click_import_class_list(self): self.po.perform_action(locator=self.LNK_IMPORT_CLASS_LIST, action=actions.CLICK_LINK) - def click_Continue(self): + def click_continue(self): self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON) def choose_file_child_records(self, file_path: str): self.po.perform_action( - locator=self.LBL_CHOOSE_COHORT_FILE, + locator=self.LBL_CHOOSE_COHORT_FILE_1, action=actions.SELECT_FILE, value=file_path, ) - def click_Record_Vaccinations(self): + def click_record_vaccinations(self): self.po.perform_action(locator=self.LNK_RECORD_VACCINATIONS, action=actions.CLICK_LINK) def click_child_full_name(self): - self.po.perform_action(locator=self.LNK_CHILD_FULL_NAME, action=actions.CLICK_LINK) + self.po.perform_action(locator=self.LNK_CHILD_FULL_NAME, action=actions.CLICK_WILDCARD) - def click_Update_Triage_Outcome(self): + def click_update_triage_outcome(self): self.po.perform_action(locator=self.LNK_UPDATE_TRIAGE_OUTCOME, action=actions.CLICK_LINK) - def select_Yes_Safe_To_Vaccinate(self): + def select_yes_safe_to_vaccinate(self): self.po.perform_action(locator=self.RDO_YES_SAFE_TO_VACCINATE, action=actions.RADIO_BUTTON_SELECT) - def click_Save_Triage(self): + def click_save_triage(self): self.po.perform_action(locator=self.BTN_SAVE_TRIAGE, action=actions.CLICK_BUTTON) - def __schedule_session(self, future_date: str, expect_error: bool = False): + def click_check_consent_responses(self): + self.po.perform_action(locator=self.BTN_CHECK_CONSENT_RESPONSES, action=actions.CLICK_LINK) + + def click_assess_gillick_competent(self): + self.po.perform_action(locator=self.LNK_ASSESS_GILLICK_COMPETENT, action=actions.CLICK_LINK) + + def click_edit_gillick_competence(self): + self.po.perform_action(locator=self.LNK_EDIT_GILLICK_COMPETENCE, action=actions.CLICK_LINK) + + def add_gillick_competence(self, is_competent: bool, competence_details: str) -> None: + self.__set_gillick_consent(is_add=True, is_competent=is_competent, competence_details=competence_details) + + def edit_gillick_competence(self, is_competent: bool, competence_details: str) -> None: + self.__set_gillick_consent(is_add=False, is_competent=is_competent, competence_details=competence_details) + + def __set_gillick_consent(self, is_add: bool, is_competent: bool, competence_details: str) -> None: + if is_competent: + self.po.perform_action( + locator="get_by_role('group', name='The child knows which vaccination they will have').get_by_label('Yes').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action( + locator="get_by_role('group', name='The child knows which disease').get_by_label('Yes').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action( + locator="get_by_role('group', name='The child knows what could').get_by_label('Yes').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action( + locator="get_by_role('group', name='The child knows how the').get_by_label('Yes').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action( + locator="get_by_role('group', name='The child knows which side').get_by_label('Yes').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + else: + self.po.perform_action( + locator="get_by_role('group', name='The child knows which vaccination they will have').get_by_label('No').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action( + locator="get_by_role('group', name='The child knows which disease').get_by_label('No').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action( + locator="get_by_role('group', name='The child knows what could').get_by_label('No').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action( + locator="get_by_role('group', name='The child knows how the').get_by_label('No').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action( + locator="get_by_role('group', name='The child knows which side').get_by_label('No').check()", + action=actions.CHAIN_LOCATOR_ACTION, + ) + self.po.perform_action( + locator=self.TXT_GILLICK_ASSESSMENT_DETAILS, action=actions.FILL, value=competence_details + ) + if is_add: + self.po.perform_action(locator=self.BTN_COMPLETE_GILLICK_ASSESSMENT, action=actions.CLICK_BUTTON) + else: + self.po.perform_action(locator=self.BTN_UPDATE_GILLICK_ASSESSMENT, action=actions.CLICK_BUTTON) + if is_competent: + self.po.verify( + locator=self.LBL_MAIN, property=object_properties.TEXT, value=self.LBL_CHILD_COMPETENT, exact=False + ) + else: + self.po.verify( + locator=self.LBL_MAIN, property=object_properties.TEXT, value=self.LBL_CHILD_NOT_COMPETENT, exact=False + ) + self.po.verify(locator=self.LBL_MAIN, property=object_properties.TEXT, value=competence_details, exact=False) + + def schedule_session(self, future_date: str, expect_error: bool = False): _day = future_date[-2:] _month = future_date[4:6] _year = future_date[:4] @@ -112,84 +214,122 @@ def __schedule_session(self, future_date: str, expect_error: bool = False): locator=self.LBL_MAIN, property=object_properties.TEXT, value=_expected_message, exact=False ) - def __delete_all_sessions(self): + def __delete_sessions(self): self.po.perform_action(locator=self.LNK_EDIT_SESSION, action=actions.CLICK_LINK) self.po.perform_action(locator=self.LNK_CHANGE_SESSION_DATES, action=actions.CLICK_LINK) self.po.perform_action(locator=self.BTN_DELETE, action=actions.CLICK_BUTTON) - self.po.perform_action(locator=self.LNK_CANCEL, action=actions.CLICK_LINK) + self.po.perform_action(locator=self.LNK_BACK, action=actions.CLICK_LINK) self.po.perform_action(locator=self.LNK_CONTINUE, action=actions.CLICK_LINK) - # TODO: Use the common verify function + # FIXME: Use the common verify function expect( self.ce.page.locator("div") .filter(has_text=re.compile(r"^Session datesNot provided$")) .get_by_role("definition") ).to_be_visible() - def verify_Triage_Updated(self): + def verify_triage_updated(self): self.po.verify( locator=self.LBL_PARAGRAPH, property=object_properties.TEXT, value=self.LBL_TRIAGE_UPDATED_MESSAGE, - exact=True, + exact=False, + ) + + def verify_activity_log_entry(self): + self.po.verify( + locator=self.LBL_MAIN, property=object_properties.TEXT, value=self.LBL_ACTIVITY_LOG_ENTRY, exact=False ) def verify_scheduled_date(self, message: str): self.po.verify(locator=self.LBL_MAIN, property=object_properties.TEXT, value=message, exact=False) + self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_LINK) + + def click_get_consent_responses(self): + self.po.perform_action(locator=self.BTN_GET_CONSENT_RESPONSES, action=actions.CLICK_BUTTON) + + def upload_valid_class_list(self, file_paths: str): + _input_file_path, _ = self.tdo.split_file_paths(file_paths=file_paths) + self.click_scheduled() + self.click_school1() + self.click_import_class_list() + self.choose_file_child_records(file_path=_input_file_path) + self.click_continue() def update_triage_outcome_positive(self, file_paths): _input_file_path, _ = self.tdo.split_file_paths(file_paths=file_paths) - self.click_Scheduled() - self.click_School() - self.click_Import_Class_List() + self.click_scheduled() + self.click_school1() + self.click_import_class_list() self.choose_file_child_records(file_path=_input_file_path) - self.click_Continue() + self.click_continue() + self.dashboard_page.go_to_dashboard() + self.dashboard_page.click_sessions() + self.click_scheduled() + self.click_school1() + self.click_check_consent_responses() + self.click_child_full_name() + self.click_get_consent_responses() + self.consent_page.service_give_consent() self.dashboard_page.go_to_dashboard() self.dashboard_page.click_sessions() - self.click_Scheduled() - self.click_School() - self.click_Record_Vaccinations() + self.click_scheduled() + self.click_school1() + self.click_record_vaccinations() + self.click_child_full_name() + self.click_update_triage_outcome() + self.select_yes_safe_to_vaccinate() + self.click_save_triage() + self.verify_triage_updated() self.click_child_full_name() - self.click_Update_Triage_Outcome() - self.select_Yes_Safe_To_Vaccinate() - self.click_Save_Triage() - self.verify_Triage_Updated() - - def schedule_a_valid_session(self): - _future_date = get_future_date(offset_days=10) - _expected_message = f"Session dates {self.get_display_formatted_date(date_to_format=_future_date)}" - self.click_Unscheduled() - self.click_School() - self.__schedule_session(future_date=_future_date, expect_error=False) + self.click_activity_log() + self.verify_activity_log_entry() + + def schedule_a_valid_session(self, for_today: bool = False): + _future_date = get_future_date(offset_days=0) if for_today else get_future_date(offset_days=10) + _expected_message = f"Session dates {self.__get_display_formatted_date(date_to_format=_future_date)}" + self.click_unscheduled() + self.click_school1() + self.schedule_session(future_date=_future_date) self.verify_scheduled_date(message=_expected_message) def delete_all_sessions(self): - self.click_Scheduled() - self.click_School() - self.__delete_all_sessions() + self.click_scheduled() + self.click_school1() + self.__delete_sessions() def create_invalid_session(self): _future_date = "20241332" - self.click_Unscheduled() - self.click_School() - self.__schedule_session(future_date=_future_date, expect_error=True) + self.click_unscheduled() + self.click_school2() + self.schedule_session(future_date=_future_date, expect_error=True) def upload_class_list(self, file_paths: str): _input_file_path, _output_file_path = self.tdo.split_file_paths(file_paths=file_paths) - self.click_Unscheduled() - self.click_School() - self.click_Import_Class_List() + self.click_scheduled() + self.click_school1() + self.click_import_class_list() self.choose_file_child_records(file_path=_input_file_path) - self.click_Continue() - self.record_upload_time() + self.click_continue() + self.__record_upload_time() wait(timeout=wait_time.MED) self.click_uploaded_file_datetime() self.verify_upload_output(file_path=_output_file_path) def upload_invalid_class_list_records(self, file_paths: str): _input_file_path, _output_file_path = self.tdo.split_file_paths(file_paths=file_paths) - self.click_Unscheduled() - self.click_School() - self.click_Import_Class_List() + self.click_scheduled() + self.click_school1() + self.click_import_class_list() self.choose_file_child_records(file_path=_input_file_path) - self.click_Continue() + self.click_continue() self.verify_upload_output(file_path=_output_file_path) + + def set_gillick_competence_for_student(self): + self.click_today() + self.click_school1() + self.click_check_consent_responses() + self.click_child_full_name() + self.click_assess_gillick_competent() + self.add_gillick_competence(is_competent=True, competence_details="Gillick competent") + self.click_edit_gillick_competence() + self.edit_gillick_competence(is_competent=False, competence_details="Not Gillick competent") diff --git a/pytest.ini b/pytest.ini index ccf4337bafe..edff0dfd839 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,6 +1,6 @@ [pytest] -addopts = -vs -rf --alluredir=./reports/ --html-report=./reports/ +addopts = -vs -rf --alluredir=./reports/ #-n auto --dist=loadfile log_file = logs/pytest.log @@ -12,6 +12,7 @@ log_file_level = INFO testpaths = tests markers = + mobile smoke regression order diff --git a/requirements.txt b/requirements.txt index c0f9b943371..73aad58cc67 100644 Binary files a/requirements.txt and b/requirements.txt differ diff --git a/test_data/ParentalConsent.xlsx b/test_data/ParentalConsent.xlsx index 731e129cc9d..1f6f331f9c7 100644 Binary files a/test_data/ParentalConsent.xlsx and b/test_data/ParentalConsent.xlsx differ diff --git a/test_data/cohorts/i_negative.csv b/test_data/cohorts/i_negative.csv index cb4303e9c47..525c6204ae1 100644 --- a/test_data/cohorts/i_negative.csv +++ b/test_data/cohorts/i_negative.csv @@ -1,5 +1,4 @@ CHILD_FIRST_NAME,CHILD_LAST_NAME,CHILD_COMMON_NAME,CHILD_DATE_OF_BIRTH,CHILD_SCHOOL_URN,CHILD_NHS_NUMBER,CHILD_ADDRESS_LINE_1,CHILD_ADDRESS_LINE_2,CHILD_TOWN,CHILD_POSTCODE,PARENT_1_NAME,PARENT_1_RELATIONSHIP,PARENT_1_EMAIL,PARENT_1_PHONE,PARENT_2_NAME,PARENT_2_RELATIONSHIP,PARENT_2_EMAIL,PARENT_2_PHONE -C<>,C<>,ChildCommon,1-1-2010,110158,<>,Addr1,Add2,City,AA1 1AA,Parent1Name,Dad,dad@example.com,,Parent2Name,Mum,mum@example.com, ,C<>,ChildCommon,1-1-2010,110158,<>,Addr1,Add2,City,AA1 1AA,Parent1Name,Dad,dad@example.com,,Parent2Name,Mum,mum@example.com, C<>,,ChildCommon,1-1-2010,110158,<>,Addr1,Add2,City,AA1 1AA,Parent1Name,Dad,dad@example.com,,Parent2Name,Mum,mum@example.com, C<>,C<>,,1-1-2010,110158,<>,Addr1,Add2,City,AA1 1AA,Parent1Name,Dad,dad@example.com,,Parent2Name,Mum,mum@example.com, @@ -10,3 +9,5 @@ C<>,C<>,ChildCommon,1-1-2010,ABCDEF,,Addr1,Add2,City,AA1 1AA,Paren C<>,C<>,ChildCommon,1-1-2010,110158,<>,Addr1,Add2,City,,Parent1Name,Dad,dad@example.com,,Parent2Name,Mum,mum@example.com, C<>,C<>,ChildCommon,1-1-2010,110158,<>,Addr1,Add2,City,AA1 1AA,Parent1Name,Dad,example.com,,Parent2Name,Mum,mum@example.com, C<>,C<>,ChildCommon,1-1-2010,110158,<>,Addr1,Add2,City,AA1 1AA,Parent1Name,Dad,dad@example.com,,Parent2Name,Mum,example.com, +C<>,C<>,ChildCommon,1-1-2000,110158,<>,Addr1,Add2,City,AA1 1AA,Parent1Name,Dad,dad@example.com,,Parent2Name,Mum,mum@example.com, +C<>,C<>,ChildCommon,1-1-2010,110158,<>,Addr1,Add2,City,ABC DEF,Parent1Name,Dad,dad@example.com,,Parent2Name,Mum,mum@example.com, diff --git a/test_data/cohorts/i_positive.csv b/test_data/cohorts/i_positive.csv index a3b75801c79..4da02d19644 100644 --- a/test_data/cohorts/i_positive.csv +++ b/test_data/cohorts/i_positive.csv @@ -1,2 +1,2 @@ CHILD_FIRST_NAME,CHILD_LAST_NAME,CHILD_COMMON_NAME,CHILD_DATE_OF_BIRTH,CHILD_SCHOOL_URN,CHILD_NHS_NUMBER,CHILD_ADDRESS_LINE_1,CHILD_ADDRESS_LINE_2,CHILD_TOWN,CHILD_POSTCODE,PARENT_1_NAME,PARENT_1_RELATIONSHIP,PARENT_1_EMAIL,PARENT_1_PHONE,PARENT_2_NAME,PARENT_2_RELATIONSHIP,PARENT_2_EMAIL,PARENT_2_PHONE -C<>,C<>,ChildCommon,1-1-2009,134522,<>,Addr1,Add2,City,AA1 1AA,Parent1Name1,Dad,dad1@example.com,,Parent2Name1,Mum,mum1@example.com, +C<>,C<>,ChildCommon,1-1-2009,148419,<>,Addr1,Add2,City,AA1 1AA,Parent1Name1,Dad,dad1@example.com,,Parent2Name1,Mum,mum1@example.com, diff --git a/test_data/cohorts/o_negative.csv b/test_data/cohorts/o_negative.csv index c90daad83f4..f78cc7c8858 100644 --- a/test_data/cohorts/o_negative.csv +++ b/test_data/cohorts/o_negative.csv @@ -1,8 +1,11 @@ -Row 2 CHILD_FIRST_NAME: is required but missing -Row 3 CHILD_LAST_NAME: is required but missing -Row 5 CHILD_DATE_OF_BIRTH: is required but missing +Records could not be imported +Row 1 CHILD_FIRST_NAME: is required but missing +Row 2 CHILD_LAST_NAME: is required but missing +Row 4 CHILD_DATE_OF_BIRTH: is required but missing +Row 6 CHILD_SCHOOL_URN: is not included in the list Row 7 CHILD_SCHOOL_URN: is not included in the list -Row 8 CHILD_SCHOOL_URN: is not included in the list -Row 9 CHILD_POSTCODE: is required but missing -Row 10 PARENT_1_EMAIL: ‘example.com’ should be a valid email address, like j.doe@example.com -Row 11 PARENT_2_EMAIL: ‘example.com’ should be a valid email address, like j.doe@example.com +Row 8 CHILD_POSTCODE: is required but missing +Row 9 PARENT_1_EMAIL: ‘example.com’ should be a valid email address, like j.doe@example.com +Row 10 PARENT_2_EMAIL: ‘example.com’ should be a valid email address, like j.doe@example.com +Row 11 Year group: is not part of this programme +Row 12 CHILD_POSTCODE: Enter a valid postcode, such as SW1A 1AA diff --git a/test_data/hpv/i_negative.csv b/test_data/hpv/i_negative.csv index 11bb02a5a65..dda14a75c99 100644 --- a/test_data/hpv/i_negative.csv +++ b/test_data/hpv/i_negative.csv @@ -1,31 +1,36 @@ -TEST_DESC_IGNORED,ORGANISATION_CODE,SCHOOL_URN,SCHOOL_NAME,NHS_NUMBER,PERSON_FORENAME,PERSON_SURNAME,PERSON_DOB,PERSON_GENDER_CODE,PERSON_POSTCODE,DATE_OF_VACCINATION,VACCINE_GIVEN,BATCH_NUMBER,BATCH_EXPIRY_DATE,ANATOMICAL_SITE,DOSE_SEQUENCE,CARE_SETTING,PERFORMING_PROFESSIONAL_FORENAME,PERFORMING_PROFESSIONAL_SURNAME -N_InvalidODSCode,MAVIS,110158,Eton College,9729852545,BERT,BOYES,20100811,Male,DN9 1PB,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptyOrgCode,,110158,Eton College,5558849673,JEROME,COPE,20100805,Not Known,NP13 1UR,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptySchoolURN,R1L,,Eton College,9650974318,BOB,JERMEY,20100819,Male,DN38 6JP,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_NotKnownSchoolEmpty,R1L,888888,,9454259520,XAVIERA,ARFAOUI,20100821,Female,CA23 3DQ,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptyNHSNumber,R1L,110158,Eton College,,MURRAY,MARQUARDT,20100808,Male,N8 7RE,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_LongNHSNumber,R1L,110158,Eton College,94477948901,ROXANNA,GROSTON,20100806,Female,DN17 2SP,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_ShortNHSNumber,R1L,110158,Eton College,947310353,AMRIT,GHAI,20100815,Female,S61 4NR,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptyForename,R1L,110158,Eton College,9461217986,,HART-DAVIS,20100818,Female,HD9 2DD,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptyLastname,R1L,110158,Eton College,9472608035,CANDACE,,20100828,Female,LA1 2PP,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptyDOB,R1L,110158,Eton College,9474527474,CHARITA,MALLAH,,Female,NE24 2HH,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_InvalidFormatDOB,R1L,110158,Eton College,9650861971,ELIZA,BOOKER,20102608,Not Known,DN31 1QL,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_FutureDOB,R1L,110158,Eton College,5991075735,SVETLANA,SCHOWALTER,20300819,Female,ZZ99 4QZ,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_NonLeapYearDOB,R1L,110158,Eton College,9450867372,SUE,ALTAN,20100229,Female,DN31 2RS,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptyGender,R1L,110158,Eton College,9691398613,JONI,FALVEY,20100802,,DN16 2RT,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_InvalidGender,R1L,110158,Eton College,5991294623,OAKLEY,RUSSEL,20100828,Transgender,N8 7RE,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptyPostCode,R1L,110158,Eton College,5991818460,HARPER,KERR,20100823,Male,,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_InvalidPostCode,R1L,110158,Eton College,9448251165,ANDRIANA,MACLULICH,20100813,Female,1AA AA1,20240514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptyVaccDate,R1L,110158,Eton College,5991350906,SHERILYN,MOORE,20100820,Female,ZZ99 3AZ,,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_FutureVaccDate,R1L,110158,Eton College,9694580307,LERON,KUFAKI,20100811,Male,DN34 4SE,20340514,Gardasil9,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptyVaccGiven,R1L,110158,Eton College,9691243067,AMBER,ORRELL,20100810,Not specified,B6 5JN,20240514,,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_FluVaccGiven,R1L,110158,Eton College,9693366719,ROGER,DIXON,20100802,Male,SW16 5DQ,20240514,AstraZeneca Fluenz Tetra LAIV,123013325,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptyBatchNumber,R1L,110158,Eton College,9485296975,MONA,RODEN,20100806,Female,LA2 9LN,20240514,Gardasil9,,20220730,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptyExpiryDate,R1L,110158,Eton College,5991056250,FAY,WILLIAMS,20100811,Male,N8 7RE,20240514,Gardasil9,123013325,,Left Thigh,1,1,PerformingForename,PerformingSurname -N_EmptyAnatomicalSite,R1L,110158,Eton College,9658065309,NORA,AVISON,20100821,Not Known,LS22 5DF,20240514,Gardasil9,123013325,20220730,,1,1,PerformingForename,PerformingSurname -N_InvalidAnatomicalSite,R1L,110158,Eton College,9460860354,MATTIE,MERRIGAN,20100831,Male,TS8 9EF,20240514,Gardasil9,123013325,20220730,Nasal,1,1,PerformingForename,PerformingSurname -N_EmptyDoseSeq,R1L,110158,Eton College,9485525729,WALTER,TEAT,20100827,Male,LA10 5TE,20240514,Gardasil9,123013325,20220730,Left Thigh,,1,PerformingForename,PerformingSurname -N_InvalidDoseSeq,R1L,110158,Eton College,9454370456,MANLEY,BARWICK,20100822,Male,DN16 2JS,20240514,Gardasil9,123013325,20220730,Left Thigh,10,1,PerformingForename,PerformingSurname -N_EmptyCareSetting,R1L,110158,Eton College,9486526532,OTIS,MCNATH,20100810,Male,DN9 1DD,20240514,Gardasil9,123013325,20220730,Left Thigh,1,,PerformingForename,PerformingSurname -N_InvalidCareSetting,R1L,110158,Eton College,9485236786,JONATHAN,SCHIFF,20100818,Male,LA14 1AR,20240514,Gardasil9,123013325,20220730,Left Thigh,1,10,PerformingForename,PerformingSurname -N_Site_Nasal,R1L,110158,Eton College,9726851416,NAOMI,DILLON,20100818,Female,BH25 6ST,20240514,Gardasil9,123013325,20220730,Nasal,1,1,PerformingForename,PerformingSurname +TEST_DESC_IGNORED,ORGANISATION_CODE,SCHOOL_URN,SCHOOL_NAME,NHS_NUMBER,PERSON_FORENAME,PERSON_SURNAME,PERSON_DOB,PERSON_GENDER_CODE,PERSON_POSTCODE,DATE_OF_VACCINATION,VACCINE_GIVEN,BATCH_NUMBER,BATCH_EXPIRY_DATE,ANATOMICAL_SITE,DOSE_SEQUENCE,VACCINATED,CARE_SETTING,PERFORMING_PROFESSIONAL_FORENAME,PERFORMING_PROFESSIONAL_SURNAME,PERFORMING_PROFESSIONAL_EMAIL,CLINIC_NAME,TIME_OF_VACCINATION,REASON_NOT_VACCINATED +N_InvalidODSCode,MAVIS,142181,Bohunt School Wokingham,<>,<>,<>,20100811,Male,DN9 1PB,<>,Gardasil9,AutoBatch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyOrgCode,,142181,Bohunt School Wokingham,<>,<>,<>,20100811,Male,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptySchoolURN,R1L,,Bohunt School Wokingham,<>,<>,<>,20100811,Male,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_NotKnownSchoolEmpty,R1L,888888,,<>,<>,<>,20100811,Male,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_LongNHSNumber,R1L,142181,Bohunt School Wokingham,<>1,<>,<>,20100811,Male,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_ShortNHSNumber,R1L,142181,Bohunt School Wokingham,947310353,<>,<>,20100811,Male,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyForename,R1L,142181,Bohunt School Wokingham,<>,,<>,20100811,Male,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyLastname,R1L,142181,Bohunt School Wokingham,<>,<>,,20100811,Male,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyDOB,R1L,142181,Bohunt School Wokingham,<>,<>,<>,,Male,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_InvalidFormatDOB,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20102608,Male,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_FutureDOB,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20300628,Male,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_NonLeapYearDOB,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100229,Male,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyGender,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_InvalidGender,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Transgender,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyPostCode,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_InvalidPostCode,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,1AA AA1,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyVaccDate,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_FutureVaccDate,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,20301231,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyVaccGiven,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_FluVaccGiven,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,AstraZeneca Fluenz Tetra LAIV,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyBatchNumber,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyExpiryDate,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,,left thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyAnatomicalSite,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_InvalidAnatomicalSite,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,Nasal,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyDoseSeq,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_InvalidDoseSeq,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,10,Y,1,,,nurse.joy@example.com,Clinic,12:00, +N_EmptyCareSetting,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,,,,nurse.joy@example.com,Clinic,12:00, +N_InvalidProfFName,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,ProfFName,,,Clinic,12:00, +N_InvalidProfSName,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,ProfSName,,Clinic,12:00, +N_InvalidProfEmail,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@invalid-example.com,Clinic,12:00, +N_InvalidClinic,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,2,,,nurse.joy@example.com,Invalid Clinic,12:00, +N_InvalidTime,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,,32:00, +N_InvalidReason,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,1,,,nurse.joy@example.com,,32:00,Did not attend1 +N_InvalidVaccinatedFlag,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,X,1,,,nurse.joy@example.com,,32:00, +N_InvalidCareSetting,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100228,Female,DN9 1PB,<>,Gardasil9,Batch1,20301231,left thigh,1,Y,10,,,nurse.joy@example.com,,32:00, diff --git a/test_data/hpv/i_positive.csv b/test_data/hpv/i_positive.csv index 102392085e9..33f110332f6 100644 --- a/test_data/hpv/i_positive.csv +++ b/test_data/hpv/i_positive.csv @@ -1,17 +1,10 @@ -TEST_DESC_IGNORED,ORGANISATION_CODE,SCHOOL_URN,SCHOOL_NAME,NHS_NUMBER,PERSON_FORENAME,PERSON_SURNAME,PERSON_DOB,PERSON_GENDER_CODE,PERSON_POSTCODE,DATE_OF_VACCINATION,VACCINE_GIVEN,BATCH_NUMBER,BATCH_EXPIRY_DATE,ANATOMICAL_SITE,DOSE_SEQUENCE,LOCAL_PATIENT_ID,LOCAL_PATIENT_ID_URI,CARE_SETTING,VACCINATED -P_Gardasil9,R1L,110158,Eton College,<>,<>,<>,20100811,Male,DN9 1PB,20240514,Gardasil9,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y -P_Gardasil,R1L,110158,Eton College,<>,<>,<>,20100819,Male,DN38 6JP,20240514,Gardasil,123013325,20220730,Left Thigh,2,LocalPatient3,www.LocalPatient3,1,Y -P_Cervarix,R1L,110158,Eton College,<>,<>,<>,20100808,Male,N8 7RE,20240514,Cervarix,123013325,20220730,Left Thigh,3,LocalPatient3,www.LocalPatient3,1,Y -P_Gardasil9,R1L,888888,Test-Auto School,<>,<>,<>,20100818,Female,HD9 2DD,20240514,Gardasil9,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y -P_Gardasil,R1L,999999,Homeschooled,<>,<>,<>,20100813,Female,DN17 1UE,20240514,Gardasil,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y -P_Cervarix,R1L,110158,Eton College,<>,<>,<>,20100817,Female,LA22 9SJ,20240514,Cervarix,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y -P_NFA,R1L,110158,Eton College,<>,<>,<>,20100811,Male,ZZ99 3VZ,20240514,Gardasil9,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y -P_Add_Not_Known,R1L,110158,Eton College,<>,<>,<>,20100811,Male,ZZ99 3WZ,20240514,Gardasil9,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y -P_Site_LB,R1L,110158,Eton College,<>,<>,<>,20100811,Male,DN34 4SE,20240514,Gardasil9,123013325,20220730,Left Buttock,1,LocalPatient3,www.LocalPatient3,1,Y -P_Site_RB,R1L,110158,Eton College,<>,<>,<>,20100831,Male,TS8 9EF,20240514,Gardasil9,123013325,20220730,Right Buttock,1,LocalPatient3,www.LocalPatient3,1,Y -P_Site_LT,R1L,110158,Eton College,<>,<>,<>,20100829,Not Known,HU5 3SG,20240514,Gardasil9,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y -P_Site_LUA,R1L,110158,Eton College,<>,<>,<>,20100821,Female,ZZ99 3AZ,20240514,Gardasil9,123013325,20220730,Left Upper Arm,1,LocalPatient3,www.LocalPatient3,1,Y -P_Site_RUA,R1L,110158,Eton College,<>,<>,<>,20100830,Male,NE39 1AD,20240514,Gardasil9,123013325,20220730,Right Upper Arm,1,LocalPatient3,www.LocalPatient3,1,Y -P_Site_RT,R1L,110158,Eton College,<>,<>,<>,20100808,Male,SK16 4HT,20240514,Gardasil9,123013325,20220730,Right Thigh,1,LocalPatient3,www.LocalPatient3,1,Y -P_AllowPastExpiryDate,R1L,110158,Eton College,<>,<>,<>,20100827,Female,BH23 8BY,20240514,Gardasil9,123013325,20120730,Left Thigh,1,www.LocalPatient3,www.LocalPatient3,1,Y -P_NotVaccinated,R1L,110158,Eton College,<>,<>,<>,20100827,Female,BH23 8BY,20240514,Gardasil9,123013325,20120730,Left Thigh,1,www.LocalPatient3,www.LocalPatient3,1,N +TEST_DESC_IGNORED,ORGANISATION_CODE,SCHOOL_URN,SCHOOL_NAME,NHS_NUMBER,PERSON_FORENAME,PERSON_SURNAME,PERSON_DOB,PERSON_GENDER_CODE,PERSON_POSTCODE,DATE_OF_VACCINATION,VACCINE_GIVEN,BATCH_NUMBER,BATCH_EXPIRY_DATE,ANATOMICAL_SITE,DOSE_SEQUENCE,VACCINATED,CARE_SETTING,PERFORMING_PROFESSIONAL_FORENAME,PERFORMING_PROFESSIONAL_SURNAME,PERFORMING_PROFESSIONAL_EMAIL,CLINIC_NAME,TIME_OF_VACCINATION,REASON_NOT_VACCINATED +P_Gardasil9,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100811,Male,DN9 1PB,<>,Gardasil9,AutoBatch1,20301231,Left Thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +P_Gardasil,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100811,Male,DN9 1PB,<>,Gardasil,AutoBatch1,20301231,Right Thigh,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +P_Cervarix,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100811,Male,DN9 1PB,<>,Cervarix,AutoBatch1,20301231,left upper arm,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +P_NFA,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100811,Male,ZZ99 3VZ,<>,Cervarix9,AutoBatch1,20301231,left arm (upper position),1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +P_Add_Not_Known,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100811,Male,ZZ99 3WZ,<>,Cervarix9,AutoBatch1,20301231,left arm (lower position),1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +P_AllowPastExpiryDate,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100811,Male,ZZ99 3WZ,<>,Cervarix9,AutoBatch1,20120730,right upper arm,1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +P_SiteRAU,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100811,Male,ZZ99 3WZ,<>,Cervarix9,AutoBatch1,20320730,right arm (upper position),1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +P_SiteRAL,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100811,Male,ZZ99 3WZ,<>,Cervarix9,AutoBatch1,20320730,right arm (lower position),1,Y,1,,,nurse.joy@example.com,Clinic,12:00, +P_NotVaccinated,R1L,142181,Bohunt School Wokingham,<>,<>,<>,20100811,Male,ZZ99 3WZ,<>,Cervarix9,AutoBatch1,20320730,right arm (upper position),1,N,1,,,nurse.joy@example.com,Clinic,12:00,Did not attend diff --git a/test_data/hpv/i_positive_old.csv b/test_data/hpv/i_positive_old.csv new file mode 100644 index 00000000000..102392085e9 --- /dev/null +++ b/test_data/hpv/i_positive_old.csv @@ -0,0 +1,17 @@ +TEST_DESC_IGNORED,ORGANISATION_CODE,SCHOOL_URN,SCHOOL_NAME,NHS_NUMBER,PERSON_FORENAME,PERSON_SURNAME,PERSON_DOB,PERSON_GENDER_CODE,PERSON_POSTCODE,DATE_OF_VACCINATION,VACCINE_GIVEN,BATCH_NUMBER,BATCH_EXPIRY_DATE,ANATOMICAL_SITE,DOSE_SEQUENCE,LOCAL_PATIENT_ID,LOCAL_PATIENT_ID_URI,CARE_SETTING,VACCINATED +P_Gardasil9,R1L,110158,Eton College,<>,<>,<>,20100811,Male,DN9 1PB,20240514,Gardasil9,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y +P_Gardasil,R1L,110158,Eton College,<>,<>,<>,20100819,Male,DN38 6JP,20240514,Gardasil,123013325,20220730,Left Thigh,2,LocalPatient3,www.LocalPatient3,1,Y +P_Cervarix,R1L,110158,Eton College,<>,<>,<>,20100808,Male,N8 7RE,20240514,Cervarix,123013325,20220730,Left Thigh,3,LocalPatient3,www.LocalPatient3,1,Y +P_Gardasil9,R1L,888888,Test-Auto School,<>,<>,<>,20100818,Female,HD9 2DD,20240514,Gardasil9,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y +P_Gardasil,R1L,999999,Homeschooled,<>,<>,<>,20100813,Female,DN17 1UE,20240514,Gardasil,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y +P_Cervarix,R1L,110158,Eton College,<>,<>,<>,20100817,Female,LA22 9SJ,20240514,Cervarix,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y +P_NFA,R1L,110158,Eton College,<>,<>,<>,20100811,Male,ZZ99 3VZ,20240514,Gardasil9,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y +P_Add_Not_Known,R1L,110158,Eton College,<>,<>,<>,20100811,Male,ZZ99 3WZ,20240514,Gardasil9,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y +P_Site_LB,R1L,110158,Eton College,<>,<>,<>,20100811,Male,DN34 4SE,20240514,Gardasil9,123013325,20220730,Left Buttock,1,LocalPatient3,www.LocalPatient3,1,Y +P_Site_RB,R1L,110158,Eton College,<>,<>,<>,20100831,Male,TS8 9EF,20240514,Gardasil9,123013325,20220730,Right Buttock,1,LocalPatient3,www.LocalPatient3,1,Y +P_Site_LT,R1L,110158,Eton College,<>,<>,<>,20100829,Not Known,HU5 3SG,20240514,Gardasil9,123013325,20220730,Left Thigh,1,LocalPatient3,www.LocalPatient3,1,Y +P_Site_LUA,R1L,110158,Eton College,<>,<>,<>,20100821,Female,ZZ99 3AZ,20240514,Gardasil9,123013325,20220730,Left Upper Arm,1,LocalPatient3,www.LocalPatient3,1,Y +P_Site_RUA,R1L,110158,Eton College,<>,<>,<>,20100830,Male,NE39 1AD,20240514,Gardasil9,123013325,20220730,Right Upper Arm,1,LocalPatient3,www.LocalPatient3,1,Y +P_Site_RT,R1L,110158,Eton College,<>,<>,<>,20100808,Male,SK16 4HT,20240514,Gardasil9,123013325,20220730,Right Thigh,1,LocalPatient3,www.LocalPatient3,1,Y +P_AllowPastExpiryDate,R1L,110158,Eton College,<>,<>,<>,20100827,Female,BH23 8BY,20240514,Gardasil9,123013325,20120730,Left Thigh,1,www.LocalPatient3,www.LocalPatient3,1,Y +P_NotVaccinated,R1L,110158,Eton College,<>,<>,<>,20100827,Female,BH23 8BY,20240514,Gardasil9,123013325,20120730,Left Thigh,1,www.LocalPatient3,www.LocalPatient3,1,N diff --git a/test_data/hpv/o_negative.csv b/test_data/hpv/o_negative.csv index b5aca8e0671..34b9f1e699f 100644 --- a/test_data/hpv/o_negative.csv +++ b/test_data/hpv/o_negative.csv @@ -2,26 +2,29 @@ Row 1 ORGANISATION_CODE: Enter an organisation code that matches the current org Row 2 ORGANISATION_CODE: Enter an organisation code that matches the current organisation. Row 3 SCHOOL_URN: The school URN is not recognised. If you’ve checked the URN, and you believe it’s valid, contact our support organisation. Row 4 SCHOOL_NAME: Enter a school name. +Row 5 NHS_NUMBER: Enter an NHS number with 10 characters. Row 6 NHS_NUMBER: Enter an NHS number with 10 characters. -Row 7 NHS_NUMBER: Enter an NHS number with 10 characters. -Row 8 PERSON_FORENAME: Enter a first name. -Row 9 PERSON_SURNAME: Enter a last name. +Row 7 PERSON_FORENAME: Enter a first name. +Row 8 PERSON_SURNAME: Enter a last name. +Row 9 PERSON_DOB: Enter a date of birth in the correct format. Row 10 PERSON_DOB: Enter a date of birth in the correct format. -Row 11 PERSON_DOB: Enter a date of birth in the correct format. -Row 12 PERSON_DOB: is not part of this programme -Row 13 PERSON_DOB: Enter a date of birth in the correct format. +Row 11 PERSON_DOB: is not part of this programme +Row 12 PERSON_DOB: Enter a date of birth in the correct format. +Row 13 PERSON_GENDER_CODE/PERSON_GENDER: Enter a gender or gender code. Row 14 PERSON_GENDER_CODE/PERSON_GENDER: Enter a gender or gender code. -Row 15 PERSON_GENDER_CODE/PERSON_GENDER: Enter a gender or gender code. +Row 15 PERSON_POSTCODE: Enter a valid postcode, such as SW1A 1AA Row 16 PERSON_POSTCODE: Enter a valid postcode, such as SW1A 1AA -Row 17 PERSON_POSTCODE: Enter a valid postcode, such as SW1A 1AA -Row 18 DATE_OF_VACCINATION: Enter a date in the correct format. -Row 19 DATE_OF_VACCINATION: The vaccination date is outside the programme. Enter a date before today. -Row 20 VACCINATED: You need to record whether the child was vaccinated or not. Enter ‘Y’ or ‘N’ in the ‘vaccinated’ column. -Row 21 VACCINE_GIVEN: Enter a valid vaccine, eg Gardasil 9. -Row 22 BATCH_NUMBER: Enter a batch number. -Row 23 BATCH_EXPIRY_DATE: Enter a batch expiry date. -Row 24 ANATOMICAL_SITE: Enter an anatomical site. -Row 26 DOSE_SEQUENCE: The dose sequence number cannot be greater than 3. Enter a dose sequence number, for example, 1, 2 or 3. -Row 27 DOSE_SEQUENCE: must be less than or equal to 3 -Row 28 CARE_SETTING: Enter a care setting. -Row 29 CARE_SETTING: Enter a valid care setting. +Row 17 DATE_OF_VACCINATION: Enter a date in the correct format +Row 18 DATE_OF_VACCINATION: The vaccination date is outside the programme. Enter a date before today. +Row 19 VACCINE_GIVEN: Enter a valid vaccine, eg Gardasil 9. +Row 20 VACCINE_GIVEN: Enter a valid vaccine, eg Gardasil 9. +Row 21 BATCH_NUMBER: Enter a batch number. +Row 22 BATCH_EXPIRY_DATE: Enter a batch expiry date. +Row 23 ANATOMICAL_SITE: Enter an anatomical site. +Row 25 DOSE_SEQUENCE: The dose sequence number cannot be greater than 3. Enter a dose sequence number, for example, 1, 2 or 3. +Row 26 DOSE_SEQUENCE: must be less than or equal to 3 +Row 27 CARE_SETTING: Enter a care setting. +Row 28 CARE_SETTING: Enter a valid care setting. +Row 32 PERFORMING_PROFESSIONAL_EMAIL: Enter a valid email address +Row 34 TIME_OF_VACCINATION: Enter a time in the correct format +Row 35 REASON_NOT_VACCINATED: Enter a reason diff --git a/tests/test_0_smoke.py b/tests/test_00_smoke.py similarity index 95% rename from tests/test_0_smoke.py rename to tests/test_00_smoke.py index 2a4769fa8cc..2dbb8080765 100644 --- a/tests/test_0_smoke.py +++ b/tests/test_00_smoke.py @@ -35,7 +35,7 @@ def test_smoke_verify_packages(self): # CHECK APPLICATION ACCESS @pytest.mark.smoke @pytest.mark.order(3) - def test_smoke_homepage_loads(self, create_browser_page): + def test_smoke_homepage_loads(self, start_mavis): self.po.verify( locator="heading", property=object_properties.TEXT, diff --git a/tests/test_1_login.py b/tests/test_01_login.py similarity index 74% rename from tests/test_1_login.py rename to tests/test_01_login.py index 06e9a3dd517..d0e0ef17f4d 100644 --- a/tests/test_1_login.py +++ b/tests/test_01_login.py @@ -5,7 +5,7 @@ class Test_Regression_Login: login_page = pg_login.pg_login() - home_page = pg_dashboard.pg_dashboard() + dashboard_page = pg_dashboard.pg_dashboard() test_parameters = [ ("invalid_user", "invalid_password", "Invalid Email or password."), @@ -17,12 +17,12 @@ class Test_Regression_Login: @pytest.mark.mobile @pytest.mark.order(101) @pytest.mark.parametrize("user,pwd,expected_message", test_parameters) - def test_reg_invalid_login(self, create_browser_page, user, pwd, expected_message): + def test_reg_invalid_login(self, start_mavis, user, pwd, expected_message): self.login_page.perform_invalid_login(user=user, pwd=pwd, expected_message=expected_message) @pytest.mark.login @pytest.mark.mobile @pytest.mark.order(102) - def test_reg_home_page_links(self, create_browser_page): + def test_reg_home_page_links(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.verify_all_expected_links() + self.dashboard_page.verify_all_expected_links() diff --git a/tests/test_2_sessions.py b/tests/test_02_sessions.py similarity index 80% rename from tests/test_2_sessions.py rename to tests/test_02_sessions.py index be6298385c9..ce5dcac32ab 100644 --- a/tests/test_2_sessions.py +++ b/tests/test_02_sessions.py @@ -10,21 +10,21 @@ class Test_Regression_Sessions: @pytest.mark.sessions @pytest.mark.order(201) - def test_reg_create_valid_session(self, create_browser_page): + def test_reg_create_valid_session(self, start_mavis): self.login_page.perform_valid_login() self.dashboard_page.click_sessions() self.sessions_page.schedule_a_valid_session() @pytest.mark.sessions @pytest.mark.order(202) - def test_reg_delete_all_sessions(self, create_browser_page): + def test_reg_delete_all_sessions(self, start_mavis): self.login_page.perform_valid_login() self.dashboard_page.click_sessions() self.sessions_page.delete_all_sessions() @pytest.mark.sessions @pytest.mark.order(203) - def test_reg_create_invalid_schedule(self, create_browser_page): + def test_reg_create_invalid_session(self, start_mavis): self.login_page.perform_valid_login() self.dashboard_page.click_sessions() self.sessions_page.create_invalid_session() diff --git a/tests/test_03_class_list_upload.py b/tests/test_03_class_list_upload.py new file mode 100644 index 00000000000..c416aae8bbc --- /dev/null +++ b/tests/test_03_class_list_upload.py @@ -0,0 +1,47 @@ +import pytest + +from libs.constants import test_data_file_paths +from pages import pg_dashboard, pg_login, pg_sessions + + +class Test_Regression_Class_List_Upload: + login_page = pg_login.pg_login() + dashboard_page = pg_dashboard.pg_dashboard() + sessions_page = pg_sessions.pg_sessions() + + @pytest.fixture() + def create_session(self, start_mavis: None): + self.login_page.perform_valid_login() + self.dashboard_page.click_sessions() + self.sessions_page.schedule_a_valid_session() + self.dashboard_page.go_to_dashboard() + self.dashboard_page.click_sessions() + yield + self.dashboard_page.go_to_dashboard() + self.dashboard_page.click_sessions() + self.sessions_page.delete_all_sessions() + + @pytest.mark.classlist + @pytest.mark.order(301) + def test_reg_class_list_file_upload_positive(self, create_session: None): + self.sessions_page.upload_class_list(file_paths=test_data_file_paths.CLASS_POSITIVE) + + @pytest.mark.classlist + @pytest.mark.order(302) + def test_reg_class_list_file_upload_negative(self, create_session: None): + self.sessions_page.upload_class_list(file_paths=test_data_file_paths.CLASS_NEGATIVE) + + @pytest.mark.classlist + @pytest.mark.order(303) + def test_reg_class_list_file_structure(self, create_session: None): + self.sessions_page.upload_invalid_class_list_records(file_paths=test_data_file_paths.CLASS_INVALID_STRUCTURE) + + @pytest.mark.classlist + @pytest.mark.order(304) + def test_reg_class_list_no_record(self, create_session: None): + self.sessions_page.upload_invalid_class_list_records(file_paths=test_data_file_paths.CLASS_HEADER_ONLY) + + @pytest.mark.classlist + @pytest.mark.order(305) + def test_reg_class_list_empty_file(self, create_session: None): + self.sessions_page.upload_invalid_class_list_records(file_paths=test_data_file_paths.CLASS_EMPTY_FILE) diff --git a/tests/test_4_cohorts.py b/tests/test_04_cohorts.py similarity index 68% rename from tests/test_4_cohorts.py rename to tests/test_04_cohorts.py index 52e0c424b65..2ee39060f11 100644 --- a/tests/test_4_cohorts.py +++ b/tests/test_04_cohorts.py @@ -6,40 +6,40 @@ class Test_Regression_Cohorts: login_page = pg_login.pg_login() - home_page = pg_dashboard.pg_dashboard() + dashboard_page = pg_dashboard.pg_dashboard() programmes_page = pg_programmes.pg_programmes() @pytest.mark.cohorts @pytest.mark.order(401) - def test_reg_cohort_upload_positive(self, create_browser_page): + def test_reg_cohort_upload_positive(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_programmes() + self.dashboard_page.click_programmes() self.programmes_page.upload_cohorts(file_paths=test_data_file_paths.COHORTS_POSITIVE) @pytest.mark.cohorts @pytest.mark.order(402) - def test_reg_cohort_upload_negative(self, create_browser_page): + def test_reg_cohort_upload_negative(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_programmes() + self.dashboard_page.click_programmes() self.programmes_page.upload_cohorts(file_paths=test_data_file_paths.COHORTS_NEGATIVE) @pytest.mark.cohorts @pytest.mark.order(403) - def test_reg_cohorts_file_structure(self, create_browser_page): + def test_reg_cohorts_file_structure(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_programmes() + self.dashboard_page.click_programmes() self.programmes_page.upload_invalid_cohorts(file_paths=test_data_file_paths.COHORTS_INVALID_STRUCTURE) @pytest.mark.cohorts @pytest.mark.order(404) - def test_reg_cohorts_no_record(self, create_browser_page): + def test_reg_cohorts_no_record(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_programmes() + self.dashboard_page.click_programmes() self.programmes_page.upload_invalid_cohorts(file_paths=test_data_file_paths.COHORTS_HEADER_ONLY) @pytest.mark.cohorts @pytest.mark.order(405) - def test_reg_cohorts_empty_file(self, create_browser_page): + def test_reg_cohorts_empty_file(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_programmes() + self.dashboard_page.click_programmes() self.programmes_page.upload_invalid_cohorts(file_paths=test_data_file_paths.COHORTS_EMPTY_FILE) diff --git a/tests/test_5_child_list_upload.py b/tests/test_05_child_list_upload.py similarity index 68% rename from tests/test_5_child_list_upload.py rename to tests/test_05_child_list_upload.py index 9b6f203c2b6..3e2622d9954 100644 --- a/tests/test_5_child_list_upload.py +++ b/tests/test_05_child_list_upload.py @@ -6,40 +6,40 @@ class Test_Regression_Child_List_Upload: login_page = pg_login.pg_login() - home_page = pg_dashboard.pg_dashboard() + dashboard_page = pg_dashboard.pg_dashboard() programmes_page = pg_programmes.pg_programmes() @pytest.mark.childlist @pytest.mark.order(501) - def test_reg_child_list_file_upload_positive(self, create_browser_page): + def test_reg_child_list_file_upload_positive(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_programmes() + self.dashboard_page.click_programmes() self.programmes_page.upload_hpv_child_records(file_paths=test_data_file_paths.CHILD_POSITIVE) @pytest.mark.childlist @pytest.mark.order(502) - def test_reg_child_list_file_upload_negative(self, create_browser_page): + def test_reg_child_list_file_upload_negative(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_programmes() + self.dashboard_page.click_programmes() self.programmes_page.upload_hpv_child_records(file_paths=test_data_file_paths.CHILD_NEGATIVE) @pytest.mark.childlist @pytest.mark.order(503) - def test_reg_child_list_file_structure(self, create_browser_page): + def test_reg_child_list_file_structure(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_programmes() + self.dashboard_page.click_programmes() self.programmes_page.upload_invalid_hpv_child_records(file_paths=test_data_file_paths.CHILD_INVALID_STRUCTURE) @pytest.mark.childlist @pytest.mark.order(504) - def test_reg_child_list_no_record(self, create_browser_page): + def test_reg_child_list_no_record(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_programmes() + self.dashboard_page.click_programmes() self.programmes_page.upload_invalid_hpv_child_records(file_paths=test_data_file_paths.CHILD_HEADER_ONLY) @pytest.mark.childlist @pytest.mark.order(505) - def test_reg_child_list_empty_file(self, create_browser_page): + def test_reg_child_list_empty_file(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_programmes() + self.dashboard_page.click_programmes() self.programmes_page.upload_invalid_hpv_child_records(file_paths=test_data_file_paths.CHILD_EMPTY_FILE) diff --git a/tests/test_6_vaccs_batch.py b/tests/test_06_vaccs_batch.py similarity index 60% rename from tests/test_6_vaccs_batch.py rename to tests/test_06_vaccs_batch.py index cf601a8710f..0c4c7a9b974 100644 --- a/tests/test_6_vaccs_batch.py +++ b/tests/test_06_vaccs_batch.py @@ -5,45 +5,41 @@ class Test_Regression_Cohorts: login_page = pg_login.pg_login() - home_page = pg_dashboard.pg_dashboard() + dashboard_page = pg_dashboard.pg_dashboard() vaccines_page = pg_vaccines.pg_vaccines() @pytest.mark.vaccsbatch @pytest.mark.mobile @pytest.mark.order(601) - @pytest.mark.skip(reason="Out of scope for 1a") - def test_reg_batch_add_batch(self, create_browser_page): + def test_reg_batch_add_batch(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_vaccines() + self.dashboard_page.click_vaccines() self.vaccines_page.add_batch() @pytest.mark.vaccsbatch @pytest.mark.mobile @pytest.mark.order(602) - @pytest.mark.skip(reason="Out of scope for 1a") - def test_reg_batch_change_batch(self, create_browser_page): + def test_reg_batch_change_batch(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_vaccines() + self.dashboard_page.click_vaccines() self.vaccines_page.add_batch() self.vaccines_page.change_batch() @pytest.mark.vaccsbatch @pytest.mark.mobile @pytest.mark.order(603) - @pytest.mark.skip(reason="Out of scope for 1a") - def test_reg_batch_archive_batch(self, create_browser_page): + def test_reg_batch_archive_batch(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_vaccines() + self.dashboard_page.click_vaccines() self.vaccines_page.add_batch() self.vaccines_page.archive_batch() @pytest.mark.vaccsbatch @pytest.mark.mobile @pytest.mark.order(604) - @pytest.mark.skip(reason="Out of scope for 1a") - def test_reg_batch_add_change_archive_batch(self, create_browser_page): + def test_reg_batch_add_change_archive_batch(self, start_mavis): self.login_page.perform_valid_login() - self.home_page.click_vaccines() + self.dashboard_page.click_vaccines() self.vaccines_page.add_batch() self.vaccines_page.change_batch() self.vaccines_page.archive_batch() diff --git a/tests/test_07_record_a_vaccine_using_ui.py b/tests/test_07_record_a_vaccine_using_ui.py new file mode 100644 index 00000000000..7fa7c147890 --- /dev/null +++ b/tests/test_07_record_a_vaccine_using_ui.py @@ -0,0 +1,28 @@ +import pytest + +from libs.constants import test_data_file_paths +from pages import pg_dashboard, pg_login, pg_sessions + + +class Test_Regression_Record_a_Vaccine_Using_UI: + login_page = pg_login.pg_login() + dashboard_page = pg_dashboard.pg_dashboard() + sessions_page = pg_sessions.pg_sessions() + + @pytest.fixture() + def create_session(self, start_mavis: None): + self.login_page.perform_valid_login() + self.dashboard_page.click_sessions() + self.sessions_page.schedule_a_valid_session() + self.dashboard_page.go_to_dashboard() + self.dashboard_page.click_sessions() + yield + self.dashboard_page.go_to_dashboard() + self.dashboard_page.click_sessions() + self.sessions_page.delete_all_sessions() + self.login_page.perform_logout() + + @pytest.mark.rav + @pytest.mark.order(701) + def test_reg_rav_triage_positive(self, create_session): + self.sessions_page.update_triage_outcome_positive(file_paths=test_data_file_paths.COHORTS_POSITIVE) diff --git a/tests/test_8_vaccs_upload.py b/tests/test_08_vaccs_upload.py similarity index 62% rename from tests/test_8_vaccs_upload.py rename to tests/test_08_vaccs_upload.py index 22aa0ab5941..7c7dba44ddb 100644 --- a/tests/test_8_vaccs_upload.py +++ b/tests/test_08_vaccs_upload.py @@ -1,33 +1,40 @@ import pytest from libs.constants import test_data_file_paths -from pages import pg_dashboard, pg_login, pg_programmes +from pages import pg_dashboard, pg_login, pg_programmes, pg_sessions class Test_Regression_Vaccinations_Upload: login_page = pg_login.pg_login() dashboard_page = pg_dashboard.pg_dashboard() programmes_page = pg_programmes.pg_programmes() + sessions_page = pg_sessions.pg_sessions() - @pytest.mark.vaccinations - @pytest.mark.order(801) - def test_reg_hpv_positive_file_upload(self, create_browser_page): + @pytest.fixture() + def create_session(self, start_mavis: None): self.login_page.perform_valid_login() + self.dashboard_page.click_sessions() + self.sessions_page.schedule_a_valid_session(for_today=True) + self.dashboard_page.go_to_dashboard() self.dashboard_page.click_programmes() + yield + self.dashboard_page.go_to_dashboard() + self.dashboard_page.click_sessions() + self.sessions_page.delete_all_sessions() + + @pytest.mark.vaccinations + @pytest.mark.order(801) + def test_reg_hpv_positive_file_upload(self, start_mavis): self.programmes_page.upload_hpv_vaccination_records(file_paths=test_data_file_paths.VACCS_HPV_POSITIVE) @pytest.mark.vaccinations @pytest.mark.order(802) - def test_reg_hpv_negative_file_upload(self, create_browser_page): - self.login_page.perform_valid_login() - self.dashboard_page.click_programmes() + def test_reg_hpv_negative_file_upload(self, create_session): self.programmes_page.upload_hpv_vaccination_records(file_paths=test_data_file_paths.VACCS_HPV_NEGATIVE) @pytest.mark.vaccinations @pytest.mark.order(803) - def test_reg_hpv_duplicate_record_upload(self, create_browser_page): - self.login_page.perform_valid_login() - self.dashboard_page.click_programmes() + def test_reg_hpv_duplicate_record_upload(self, start_mavis): self.programmes_page.upload_hpv_vaccination_records(file_paths=test_data_file_paths.VACCS_HPV_DUP_1) self.dashboard_page.go_to_dashboard() self.dashboard_page.click_programmes() @@ -35,21 +42,15 @@ def test_reg_hpv_duplicate_record_upload(self, create_browser_page): @pytest.mark.vaccinations @pytest.mark.order(804) - def test_reg_hpv_file_structure(self, create_browser_page): - self.login_page.perform_valid_login() - self.dashboard_page.click_programmes() + def test_reg_hpv_file_structure(self, start_mavis): self.programmes_page.upload_invalid_files(file_paths=test_data_file_paths.VACCS_HPV_INVALID_STRUCTURE) @pytest.mark.vaccinations @pytest.mark.order(805) - def test_reg_hpv_no_record(self, create_browser_page): - self.login_page.perform_valid_login() - self.dashboard_page.click_programmes() + def test_reg_hpv_no_record(self, start_mavis): self.programmes_page.upload_invalid_files(file_paths=test_data_file_paths.VACCS_HPV_HEADER_ONLY) @pytest.mark.vaccinations @pytest.mark.order(806) - def test_reg_hpv_empty_file(self, create_browser_page): - self.login_page.perform_valid_login() - self.dashboard_page.click_programmes() + def test_reg_hpv_empty_file(self, start_mavis): self.programmes_page.upload_invalid_files(file_paths=test_data_file_paths.VACCS_HPV_EMPTY_FILE) diff --git a/tests/test_10_consent.py b/tests/test_10_consent.py new file mode 100644 index 00000000000..da5672af913 --- /dev/null +++ b/tests/test_10_consent.py @@ -0,0 +1,42 @@ +import pytest + +from libs.constants import test_data_file_paths +from pages import pg_dashboard, pg_login, pg_parental_consent, pg_sessions +from tests.helpers import parental_consent_helper + + +class Test_Regression_Consent: + pc = pg_parental_consent.pg_parental_consent() + helper = parental_consent_helper.parental_consent_helper() + login_page = pg_login.pg_login() + dashboard_page = pg_dashboard.pg_dashboard() + sessions_page = pg_sessions.pg_sessions() + + @pytest.fixture() + def create_session(self, start_mavis: None): + self.login_page.perform_valid_login() + self.dashboard_page.click_sessions() + self.sessions_page.schedule_a_valid_session(for_today=True) + self.dashboard_page.go_to_dashboard() + self.dashboard_page.click_sessions() + self.sessions_page.upload_valid_class_list(file_paths=test_data_file_paths.COHORTS_POSITIVE) + self.dashboard_page.go_to_dashboard() + self.dashboard_page.click_sessions() + yield + self.dashboard_page.go_to_dashboard() + self.dashboard_page.click_sessions() + self.sessions_page.delete_all_sessions() + + @pytest.mark.consent + @pytest.mark.mobile + @pytest.mark.order(1001) + @pytest.mark.parametrize("scenario_data", helper.df.iterrows(), ids=[_tc[0] for _tc in helper.df.iterrows()]) + def test_reg_parental_consent_workflow(self, start_consent_workflow, scenario_data): + self.helper.read_data_for_scenario(scenario_data=scenario_data) + self.helper.enter_details() + + @pytest.mark.consent + @pytest.mark.mobile + @pytest.mark.order(1002) + def test_reg_gillick_competence(self, create_session): + self.sessions_page.set_gillick_competence_for_student() diff --git a/tests/test_3_parental_consent.py b/tests/test_3_parental_consent.py deleted file mode 100644 index 96c5c28d2f7..00000000000 --- a/tests/test_3_parental_consent.py +++ /dev/null @@ -1,17 +0,0 @@ -import pytest - -from pages import pg_parental_consent -from tests.helpers import parental_consent_helper - - -class Test_Regression_Consent: - pc = pg_parental_consent.pg_parental_consent() - helper = parental_consent_helper.parental_consent_helper() - - @pytest.mark.consent - @pytest.mark.mobile - @pytest.mark.order(301) - @pytest.mark.parametrize("scenario_", helper.df.iterrows()) - def test_reg_parental_consent_workflow(self, start_consent_workflow, scenario_): - self.helper.read_data_for_scenario(scenario_data=scenario_) - self.helper.enter_details() diff --git a/tests/test_50_bugs.py b/tests/test_50_bugs.py index a67c15fef74..1690e23d585 100644 --- a/tests/test_50_bugs.py +++ b/tests/test_50_bugs.py @@ -10,7 +10,7 @@ class Test_Regression_Bugs: @pytest.mark.bugs @pytest.mark.order(5001) - def test_reg_children_page(self, create_browser_page): + def test_reg_children_page(self, start_mavis): self.login_page.perform_valid_login() self.dashboard_page.click_children() self.children_page.verify_headers() diff --git a/tests/test_7_record_a_vaccine_using_ui.py b/tests/test_7_record_a_vaccine_using_ui.py deleted file mode 100644 index be372c52975..00000000000 --- a/tests/test_7_record_a_vaccine_using_ui.py +++ /dev/null @@ -1,18 +0,0 @@ -import pytest - -from libs.constants import test_data_file_paths -from pages import pg_dashboard, pg_login, pg_sessions - - -class Test_Regression_Record_a_Vaccine_Using_UI: - login_page = pg_login.pg_login() - home_page = pg_dashboard.pg_dashboard() - sessions_page = pg_sessions.pg_sessions() - - @pytest.mark.rav - @pytest.mark.order(701) - @pytest.mark.skip(reason="Out of scope for 1a") - def test_reg_rav_triage_positive(self, create_browser_page): - self.login_page.perform_valid_login() - self.home_page.click_sessions() - self.sessions_page.update_triage_outcome_positive(file_paths=test_data_file_paths.COHORTS_POSITIVE) diff --git a/tests/test_9_class_list_upload.py b/tests/test_9_class_list_upload.py deleted file mode 100644 index 65c14e7f0ff..00000000000 --- a/tests/test_9_class_list_upload.py +++ /dev/null @@ -1,45 +0,0 @@ -import pytest - -from libs.constants import test_data_file_paths -from pages import pg_dashboard, pg_login, pg_sessions - - -class Test_Regression_Class_List_Upload: - login_page = pg_login.pg_login() - home_page = pg_dashboard.pg_dashboard() - sessions_page = pg_sessions.pg_sessions() - - @pytest.mark.classlist - @pytest.mark.order(901) - def test_reg_class_list_file_upload_positive(self, create_browser_page): - self.login_page.perform_valid_login() - self.home_page.click_sessions() - self.sessions_page.upload_class_list(file_paths=test_data_file_paths.CLASS_POSITIVE) - - @pytest.mark.classlist - @pytest.mark.order(902) - def test_reg_class_list_file_upload_negative(self, create_browser_page): - self.login_page.perform_valid_login() - self.home_page.click_sessions() - self.sessions_page.upload_class_list(file_paths=test_data_file_paths.CLASS_NEGATIVE) - - @pytest.mark.classlist - @pytest.mark.order(903) - def test_reg_class_list_file_structure(self, create_browser_page): - self.login_page.perform_valid_login() - self.home_page.click_sessions() - self.sessions_page.upload_invalid_class_list_records(file_paths=test_data_file_paths.CLASS_INVALID_STRUCTURE) - - @pytest.mark.classlist - @pytest.mark.order(904) - def test_reg_class_list_no_record(self, create_browser_page): - self.login_page.perform_valid_login() - self.home_page.click_sessions() - self.sessions_page.upload_invalid_class_list_records(file_paths=test_data_file_paths.CLASS_HEADER_ONLY) - - @pytest.mark.classlist - @pytest.mark.order(905) - def test_reg_class_list_empty_file(self, create_browser_page): - self.login_page.perform_valid_login() - self.home_page.click_sessions() - self.sessions_page.upload_invalid_class_list_records(file_paths=test_data_file_paths.CLASS_EMPTY_FILE)