Skip to content

Commit c9ab743

Browse files
mav 1080 (#151)
* mav 1080 * Merge remote-tracking branch 'origin/main' into C20250515
1 parent 823c64b commit c9ab743

33 files changed

+200
-152
lines changed

conftest.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from libs import CurrentExecution as ce
77
from libs import file_ops as fo
8-
from libs.generic_constants import audit_log_paths, file_mode, fixture_scope
8+
from libs.generic_constants import audit_log_paths, file_mode
99
from libs.mavis_constants import browsers_and_devices, playwright_constants
1010
from libs.wrappers import *
1111

@@ -14,7 +14,7 @@ def pytest_addoption(parser):
1414
parser.addoption("--browser_or_device", action="store", default=browsers_and_devices.CHROMIUM)
1515

1616

17-
@pytest.fixture(scope=fixture_scope.SESSION)
17+
@pytest.fixture(scope="session")
1818
def start_playwright_session(request):
1919
ce.get_env_values()
2020
ce.reset_environment()
@@ -26,7 +26,7 @@ def start_playwright_session(request):
2626
# ce.reset_environment() # Clean up the environment after execution
2727

2828

29-
@pytest.fixture(scope=fixture_scope.FUNCTION)
29+
@pytest.fixture(scope="function")
3030
def start_mavis(start_playwright_session):
3131
_browser, _context = start_browser(pw=start_playwright_session, browser_or_device=ce.current_browser_name)
3232
ce.browser = _browser
@@ -42,6 +42,8 @@ def create_session_screenshot_dir() -> str:
4242
_session_name = f"{get_current_datetime()}-{ce.current_browser_name}"
4343
fo.file_operations().create_dir(dir_path=f"screenshots/{_session_name}")
4444
return f"screenshots/{_session_name}"
45+
else:
46+
return ""
4547

4648

4749
def start_browser(pw, browser_or_device: str):

libs/__init__.py

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,26 @@
1010
class CurrentExecution:
1111
page = None
1212
browser = None
13-
service_url: str = ""
14-
base_auth_username: str = ""
15-
base_auth_password: str = ""
16-
current_browser_name: str = ""
17-
headless_mode: bool = False
18-
session_screenshots_dir: str = ""
13+
service_url: str | None = ""
14+
base_auth_username: str | None = ""
15+
base_auth_password: str | None = ""
16+
current_browser_name: str | None = ""
17+
headless_mode: bool | None = False
18+
session_screenshots_dir: str | None = ""
19+
20+
capture_screenshot_flag: bool | None = False
21+
nurse_username: str | None = ""
22+
nurse_password: str | None = ""
23+
superuser_username: str | None = ""
24+
superuser_password: str | None = ""
25+
admin_username: str | None = ""
26+
admin_password: str | None = ""
27+
reset_endpoint: str | None = ""
28+
api_token: str | None = ""
29+
reset_env_before_execution: bool | None = False
30+
slow_motion: int | None = 0
31+
1932
screenshot_sequence: int = 0
20-
capture_screenshot_flag: bool = False
21-
nurse_username: str = ""
22-
nurse_password: str = ""
23-
superuser_username: str = ""
24-
superuser_password: str = ""
25-
admin_username: str = ""
26-
admin_password: str = ""
27-
reset_endpoint: str = ""
28-
api_token: str = ""
29-
reset_env_before_execution: bool = False
30-
slow_motion: int = 0
3133
child_list: list[str] = []
3234
file_record_count: int = 0
3335
session_id: str = ""
@@ -44,12 +46,12 @@ def get_env_values():
4446
CurrentExecution.superuser_password = os.getenv("SUPERUSER_PASSWORD")
4547
CurrentExecution.admin_username = os.getenv("ADMIN_USERNAME")
4648
CurrentExecution.admin_password = os.getenv("ADMIN_PASSWORD")
47-
CurrentExecution.headless_mode = os.getenv("HEADLESS").lower() == "true"
48-
CurrentExecution.capture_screenshot_flag = os.getenv("CAPTURE_SCREENSHOTS").lower() == "true"
49+
CurrentExecution.headless_mode = os.getenv("HEADLESS", "True").lower() == "true"
50+
CurrentExecution.capture_screenshot_flag = os.getenv("CAPTURE_SCREENSHOTS", "True").lower() == "true"
4951
CurrentExecution.reset_endpoint = f"{CurrentExecution.service_url}{os.getenv('RESET_ENDPOINT')}"
5052
CurrentExecution.api_token = os.getenv("API_TOKEN")
51-
CurrentExecution.reset_env_before_execution = os.getenv("RESET_ENV_BEFORE_EXECUTION").lower() == "true"
52-
CurrentExecution.slow_motion = int(os.getenv("SLOW_MOTION"))
53+
CurrentExecution.reset_env_before_execution = os.getenv("RESET_ENV_BEFORE_EXECUTION", "True").lower() == "true"
54+
CurrentExecution.slow_motion = int(os.getenv("SLOW_MOTION", 0))
5355

5456
@staticmethod
5557
def reset_environment():
@@ -80,5 +82,5 @@ def set_session_id(session_id: str):
8082
CurrentExecution.session_id = session_id
8183

8284
@staticmethod
83-
def get_session_id() -> int:
85+
def get_session_id() -> str:
8486
return CurrentExecution.session_id

libs/file_ops.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,10 @@ def get_file_text(self, file_path: str) -> str:
4949
str: Text content of the file.
5050
"""
5151
if self.check_if_path_exists(file_or_folder_path=file_path):
52-
with open(file=file_path, mode=file_mode.READ) as f:
52+
with open(file=file_path, mode=file_mode.READ, encoding="utf-8") as f:
5353
return f.read()
54+
else:
55+
assert False, f"Cannot read file. File not found: {file_path}"
5456

5557
def read_csv_to_df(self, file_path: str) -> pd.DataFrame:
5658
"""
@@ -64,6 +66,8 @@ def read_csv_to_df(self, file_path: str) -> pd.DataFrame:
6466
"""
6567
if self.check_if_path_exists(file_or_folder_path=file_path):
6668
return pd.read_csv(filepath_or_buffer=file_path)
69+
else:
70+
assert False, f"Cannot read CSV file. File not found: {file_path}"
6771

6872
def read_excel_to_df(self, file_path: str, sheet_name: str) -> pd.DataFrame:
6973
"""
@@ -93,6 +97,6 @@ def create_file(self, content: str, file_name_prefix: str = "") -> str:
9397
str: Path to the created file.
9498
"""
9599
_file_name = f"working/{file_name_prefix}{get_current_datetime()}.csv"
96-
with open(file=_file_name, mode=file_mode.WRITE) as f:
100+
with open(file=_file_name, mode=file_mode.WRITE, encoding="utf-8") as f:
97101
f.writelines(content)
98102
return _file_name

libs/generic_constants.py

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,34 @@
1+
from enum import Enum, auto
12
from typing import Final
23

34

4-
class fixture_scope:
5-
SESSION: Final[str] = "session"
6-
FUNCTION: Final[str] = "function"
7-
8-
9-
class element_properties:
10-
TEXT: Final[str] = "text"
11-
VISIBILITY: Final[str] = "visibility"
12-
HREF: Final[str] = "href"
13-
ELEMENT_EXISTS: Final[str] = "element_exists"
14-
PAGE_URL: Final[str] = "page_url"
15-
CHECKBOX_CHECKED: Final[str] = "checked"
16-
17-
18-
class framework_actions:
19-
CLICK_LINK: Final[str] = "click_link"
20-
CLICK_BUTTON: Final[str] = "click_button"
21-
CLICK_LABEL: Final[str] = "click_label"
22-
CLICK_TEXT: Final[str] = "click_text"
23-
FILL: Final[str] = "fill"
24-
TYPE: Final[str] = "type"
25-
RADIO_BUTTON_SELECT: Final[str] = "radio_select"
26-
SELECT_FILE: Final[str] = "select_file"
27-
SELECT_FROM_LIST: Final[str] = "select_from_list"
28-
CHECKBOX_CHECK: Final[str] = "checkbox_check"
29-
CHECKBOX_UNCHECK: Final[str] = "checkbox_uncheck"
30-
CLICK_LINK_INDEX_FOR_ROW: Final[str] = "click_link_index_for_row"
31-
CLICK_WILDCARD: Final[str] = "click_wildcard"
32-
CHAIN_LOCATOR_ACTION: Final[str] = "chain_locator"
33-
DOWNLOAD_FILE_USING_LINK: Final[str] = "download_file_using_link"
34-
DOWNLOAD_FILE_USING_BUTTON: Final[str] = "download_file_using_button"
35-
WAIT: Final[str] = "wait"
5+
class element_properties(Enum):
6+
TEXT = auto()
7+
VISIBILITY = auto()
8+
HREF = auto()
9+
ELEMENT_EXISTS = auto()
10+
PAGE_URL = auto()
11+
CHECKBOX_CHECKED = auto()
12+
13+
14+
class framework_actions(Enum):
15+
CLICK_LINK = auto()
16+
CLICK_BUTTON = auto()
17+
CLICK_LABEL = auto()
18+
CLICK_TEXT = auto()
19+
FILL = auto()
20+
TYPE = auto()
21+
RADIO_BUTTON_SELECT = auto()
22+
SELECT_FILE = auto()
23+
SELECT_FROM_LIST = auto()
24+
CHECKBOX_CHECK = auto()
25+
CHECKBOX_UNCHECK = auto()
26+
CLICK_LINK_INDEX_FOR_ROW = auto()
27+
CLICK_WILDCARD = auto()
28+
CHAIN_LOCATOR_ACTION = auto()
29+
DOWNLOAD_FILE_USING_LINK = auto()
30+
DOWNLOAD_FILE_USING_BUTTON = auto()
31+
WAIT = auto()
3632

3733

3834
class screenshot_actions:

libs/mavis_constants.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from enum import Enum, auto
12
from typing import Final
23

34

@@ -34,11 +35,11 @@ class programmes:
3435

3536

3637
class vaccines:
37-
GARDASIL9: Final[str] = ("Gardasil9", 0) # HPV
38-
MENQUADFI: Final[str] = ("MenQuadfi", 1) # MenACWY
39-
MENVEO: Final[str] = ("Menveo", 2) # MenACWY
40-
NIMENRIX: Final[str] = ("Nimenrix", 3) # MenACWY
41-
REVAXIS: Final[str] = ("Revaxis", 4) # Td/IPV
38+
GARDASIL9: Final[tuple[str, int]] = ("Gardasil9", 0) # HPV
39+
MENQUADFI: Final[tuple[str, int]] = ("MenQuadfi", 1) # MenACWY
40+
MENVEO: Final[tuple[str, int]] = ("Menveo", 2) # MenACWY
41+
NIMENRIX: Final[tuple[str, int]] = ("Nimenrix", 3) # MenACWY
42+
REVAXIS: Final[tuple[str, int]] = ("Revaxis", 4) # Td/IPV
4243

4344

4445
class test_data_values:
@@ -49,12 +50,12 @@ class test_data_values:
4950
EMPTY: Final[str] = "<empty>"
5051

5152

52-
class mavis_file_types:
53-
CHILD_LIST: Final[str] = "childlist"
54-
COHORT: Final[str] = "cohort"
55-
CLASS_LIST: Final[str] = "classlist"
56-
VACCS_MAVIS: Final[str] = "vaccsmavis"
57-
VACCS_SYSTMONE: Final[str] = "vaccssystmone"
53+
class mavis_file_types(Enum):
54+
CHILD_LIST = auto()
55+
COHORT = auto()
56+
CLASS_LIST = auto()
57+
VACCS_MAVIS = auto()
58+
VACCS_SYSTMONE = auto()
5859

5960

6061
class record_limit:
@@ -80,6 +81,8 @@ class test_data_file_paths:
8081
VACCS_SYSTMONE_POSITIVE: Final[str] = "VACCS_SYSTMONE_POSITIVE"
8182
VACCS_SYSTMONE_NEGATIVE: Final[str] = "VACCS_SYSTMONE_NEGATIVE"
8283
VACCS_SYSTMONE_HIST_NEGATIVE: Final[str] = "VACCS_SYSTMONE_HIST_NEGATIVE"
84+
VACCS_MAV_1080: Final[str] = "VACCS_MAV_1080"
85+
VACCS_SYSTMONE_MAV_1080: Final[str] = "VACCS_SYSTMONE_MAV_1080"
8386
COHORTS_POSITIVE: Final[str] = "COHORTS_POSITIVE"
8487
COHORTS_NEGATIVE: Final[str] = "COHORTS_NEGATIVE"
8588
COHORTS_INVALID_STRUCTURE: Final[str] = "COHORTS_INVALID_STRUCTURE"
@@ -102,6 +105,7 @@ class test_data_file_paths:
102105
CLASS_SINGLE_VACC: Final[str] = "CLASS_SINGLE_VACC"
103106
CLASS_MAV_854: Final[str] = "CLASS_MAV_854"
104107
CLASS_MAV_965: Final[str] = "CLASS_MAV_965"
108+
CLASS_MAV_1080: Final[str] = "CLASS_MAV_1080"
105109
COHORTS_NO_CONSENT: Final[str] = "COHORTS_NO_CONSENT"
106110
COHORTS_CONFLICTING_CONSENT: Final[str] = "COHORTS_CONFLICTING_CONSENT"
107111
COHORTS_E2E_1: Final[str] = "COHORTS_E2E_1"
@@ -119,7 +123,7 @@ class test_data_file_paths:
119123

120124
class report_headers:
121125
CAREPLUS: Final[str] = (
122-
"NHS Number,Surname,Forename,Date of Birth,Address Line 1,Person Giving Consent,Ethnicity,Date Attended,Time Attended,Venue Type,Venue Code,Staff Type,Staff Code,Attended,Reason Not Attended,Suspension End Date,Vaccine 1,Dose 1,Reason Not Given 1,Site 1,Manufacturer 1,Batch No 1,Vaccine 2,Dose 2,Reason Not Given 2,Site 2,Manufacturer 2,Batch No 2,Vaccine 3,Dose 3,Reason Not Given 3,Site 3,Manufacturer 3,Batch No 3,Vaccine 4,Dose 4,Reason Not Given 4,Site 4,Manufacturer 4,Batch No 4,Vaccine 5,Dose 5,Reason Not Given 5,Site 5,Manufacturer 5,Batch No 5"
126+
"NHS Number,Surname,Forename,Date of Birth,Address Line 1,Person Giving Consent,Ethnicity,Date Attended,Time Attended,Venue Type,Venue Code,Staff Type,Staff Code,Attended,Reason Not Attended,Suspension End Date,Vaccine 1,Vaccine Code 1,Dose 1,Reason Not Given 1,Site 1,Manufacturer 1,Batch No 1,Vaccine 2,Vaccine Code 2,Dose 2,Reason Not Given 2,Site 2,Manufacturer 2,Batch No 2,Vaccine 3,Vaccine Code 3,Dose 3,Reason Not Given 3,Site 3,Manufacturer 3,Batch No 3,Vaccine 4,Vaccine Code 4,Dose 4,Reason Not Given 4,Site 4,Manufacturer 4,Batch No 4,Vaccine 5,Vaccine Code 5,Dose 5,Reason Not Given 5,Site 5,Manufacturer 5,Batch No 5"
123127
)
124128
CSV: Final[str] = (
125129
"ORGANISATION_CODE,SCHOOL_URN,SCHOOL_NAME,CARE_SETTING,CLINIC_NAME,PERSON_FORENAME,PERSON_SURNAME,PERSON_DATE_OF_BIRTH,PERSON_DATE_OF_DEATH,YEAR_GROUP,PERSON_GENDER_CODE,PERSON_ADDRESS_LINE_1,PERSON_POSTCODE,NHS_NUMBER,NHS_NUMBER_STATUS_CODE,GP_ORGANISATION_CODE,GP_NAME,CONSENT_STATUS,CONSENT_DETAILS,HEALTH_QUESTION_ANSWERS,TRIAGE_STATUS,TRIAGED_BY,TRIAGE_DATE,TRIAGE_NOTES,GILLICK_STATUS,GILLICK_ASSESSMENT_DATE,GILLICK_ASSESSED_BY,GILLICK_ASSESSMENT_NOTES,GILLICK_NOTIFY_PARENTS,VACCINATED,DATE_OF_VACCINATION,TIME_OF_VACCINATION,PROGRAMME_NAME,VACCINE_GIVEN,PERFORMING_PROFESSIONAL_EMAIL,PERFORMING_PROFESSIONAL_FORENAME,PERFORMING_PROFESSIONAL_SURNAME,BATCH_NUMBER,BATCH_EXPIRY_DATE,ANATOMICAL_SITE,ROUTE_OF_VACCINATION,DOSE_SEQUENCE,REASON_NOT_VACCINATED,LOCAL_PATIENT_ID,SNOMED_PROCEDURE_CODE,REASON_FOR_INCLUSION,RECORD_CREATED,RECORD_UPDATED"

libs/playwright_ops.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def capture_screenshot(self, identifier: str, action: str) -> None:
4343
)
4444
self.ce.page.screenshot(path=_ss_path, type=screenshot_file_types.JPEG, full_page=True)
4545

46-
def verify(self, locator: str, property: str, expected_value: str, **kwargs) -> None:
46+
def verify(self, locator: str, property: element_properties, expected_value: str, **kwargs) -> None:
4747
"""
4848
Verify a property of a web element.
4949
@@ -61,7 +61,7 @@ def verify(self, locator: str, property: str, expected_value: str, **kwargs) ->
6161
actual_value = self.get_element_property(
6262
locator=locator, property=property, by_test_id=by_test_id, chain_locator=chain_locator
6363
)
64-
match property.lower():
64+
match property:
6565
case element_properties.TEXT:
6666
if expected_value != "":
6767
self._verify_text(
@@ -72,7 +72,7 @@ def verify(self, locator: str, property: str, expected_value: str, **kwargs) ->
7272
case element_properties.CHECKBOX_CHECKED:
7373
self._verify_checkbox(locator=locator, expected_value=expected_value, actual_value=actual_value)
7474

75-
def get_element_property(self, locator: str, property: str, **kwargs) -> str:
75+
def get_element_property(self, locator: str, property: element_properties, **kwargs) -> str:
7676
"""
7777
Get a property of a web element.
7878
@@ -105,7 +105,7 @@ def get_element_property(self, locator: str, property: str, **kwargs) -> str:
105105
case element_properties.PAGE_URL:
106106
return self.ce.page.url
107107

108-
def act(self, locator, action, value=None, **kwargs) -> None:
108+
def act(self, locator: str | None, action: framework_actions, value: str | None = None, **kwargs) -> None:
109109
"""
110110
Perform an action on a web element.
111111
@@ -115,11 +115,16 @@ def act(self, locator, action, value=None, **kwargs) -> None:
115115
value (str, optional): Value to use for the action.
116116
**kwargs: Additional options (e.g., exact match, index).
117117
"""
118+
# Error check
119+
if locator is None:
120+
locator = ""
121+
if value is None:
122+
value = ""
118123
# Unpack keyword arguments
119124
exact: bool = kwargs.get("exact", False)
120125
index: int = kwargs.get("index", 0)
121126
# Act
122-
match action.lower():
127+
match action:
123128
case framework_actions.CLICK_LINK:
124129
self._click_link(locator=locator, exact=exact, index=index)
125130
case framework_actions.CLICK_BUTTON:

libs/testdata_ops.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ def create_file_from_template(self, template_path: str, file_name_prefix: str) -
4444
_ln = _ln.replace("<<SCHOOL_2_NAME>>", test_data_values.SCHOOL_2_NAME)
4545
_ln = _ln.replace("<<SCHOOL_1_URN>>", test_data_values.SCHOOL_1_URN)
4646
_ln = _ln.replace("<<ORG_CODE>>", test_data_values.ORG_CODE)
47-
# _ln = _ln.replace("<<NHS_NO>>", f"9{self.get_new_nhs_no(valid=True)[:9]}")
4847
_ln = _ln.replace("<<NHS_NO>>", self.get_new_nhs_no(valid=True))
4948
_ln = _ln.replace("<<INVALID_NHS_NO>>", self.get_new_nhs_no(valid=False))
5049
_ln = _ln.replace("<<FNAME>>", f"F{_dt}{_ctr}")
@@ -76,7 +75,7 @@ def get_new_nhs_no(self, valid=True) -> str:
7675
"""
7776
return nhs_number.generate(valid=valid, for_region=nhs_number.REGION_ENGLAND, quantity=1)[0]
7877

79-
def get_expected_errors(self, file_path: str) -> list[str]:
78+
def get_expected_errors(self, file_path: str):
8079
"""
8180
Get expected errors from a file.
8281
@@ -157,13 +156,13 @@ def create_child_list_from_file(self, file_path: str, file_type: str):
157156
match file_type:
158157
case mavis_file_types.CHILD_LIST | mavis_file_types.COHORT | mavis_file_types.CLASS_LIST:
159158
_child_list = _file_df[["CHILD_FIRST_NAME", "CHILD_LAST_NAME"]]
160-
return _child_list["CHILD_LAST_NAME"] + " " + _child_list["CHILD_FIRST_NAME"].values.tolist()
159+
return _child_list["CHILD_LAST_NAME"] + ", " + _child_list["CHILD_FIRST_NAME"].values.tolist()
161160
case mavis_file_types.VACCS_MAVIS:
162161
_child_list = _file_df[["PERSON_FORENAME", "PERSON_SURNAME"]]
163-
return _child_list["PERSON_SURNAME"] + " " + _child_list["PERSON_FIRSTNAME"].values.tolist()
162+
return _child_list["PERSON_SURNAME"] + ", " + _child_list["PERSON_FIRSTNAME"].values.tolist()
164163
case mavis_file_types.VACCS_SYSTMONE:
165164
_child_list = _file_df[["First name", "Surname"]]
166-
return _child_list["Surname"] + " " + _child_list["First name"].values.tolist()
165+
return _child_list["Surname"] + ", " + _child_list["First name"].values.tolist()
167166
case _:
168167
return None
169168

libs/wrappers.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ def get_dob_from_year(year_group: str) -> str:
146146

147147
# Generate a random date between start_date and end_date
148148
random_date = start_date + timedelta(days=random.randint(0, (end_date - start_date).days))
149-
return random_date.strftime("%Y%m%d")
149+
return random_date.strftime("%Y-%m-%d")
150150

151151

152152
def get_project_root() -> str:
@@ -190,7 +190,7 @@ def get_base64_decoded_string(encoded_string: str) -> str:
190190
return base64.b64decode(base64_bytes).decode(file_encoding.ASCII)
191191

192192

193-
def run_shell_command(command: str) -> str:
193+
def run_shell_command(command: str):
194194
"""
195195
Execute a shell command.
196196

pages/pg_children.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def verify_filter(self):
4444
self.po.act(locator=None, action=framework_actions.WAIT, value=wait_time.MIN)
4545
self.po.verify(locator=self.LBL_MAIN, property=element_properties.TEXT, expected_value=self.LBL_CHILD_RECORD)
4646

47-
def verify_child_has_been_uploaded(self, child_list: list[str]) -> None:
47+
def verify_child_has_been_uploaded(self, child_list) -> None:
4848
if len(child_list) >= 1:
4949
self.dashboard_page.go_to_dashboard()
5050
self.dashboard_page.click_children()

0 commit comments

Comments
 (0)