Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions .env.generic
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
TEST_USERNAME=
TEST_PASSWORD=
TEST_URL=https://test.mavistesting.com
TEST_URL=https://pentest.mavistesting.com
HEADLESS=false
LOGIN_USERNAME=
LOGIN_PASSWORD=
CAPTURE_SCREENSHOTS=true
PARENTAL_CONSENT_URL=
RESET_ENDPOINT=
NURSE_USERNAME=
NURSE_PASSWORD=
SUPERUSER_USERNAME=
SUPERUSER_PASSWORD=
CAPTURE_SCREENSHOTS=false
RESET_ENDPOINT=https://pentest.mavistesting.com/reset/R1L
API_TOKEN=
5 changes: 3 additions & 2 deletions libs/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class escape_characters:
SINGLE_QUOTE_CLOSE,
TAB,
]
FILE_NAME = [
FILE_NAME: Final[str] = [
SEPARATOR_CHAR,
COLON,
DOUBLE_QUOTE,
Expand All @@ -104,7 +104,7 @@ class escape_characters:


class file_encoding:
ASCII = "ascii"
ASCII: Final[str] = "ascii"


class test_data_file_paths:
Expand All @@ -123,6 +123,7 @@ class test_data_file_paths:
COHORTS_INVALID_STRUCTURE: Final[str] = "COHORTS_INVALID_STRUCTURE"
COHORTS_EMPTY_FILE: Final[str] = "COHORTS_EMPTY_FILE"
COHORTS_HEADER_ONLY: Final[str] = "COHORTS_HEADER_ONLY"
COHORTS_NO_APPROVAL: Final[str] = "COHORTS_NO_APPROVAL"
CHILD_POSITIVE: Final[str] = "CHILD_POSITIVE"
CHILD_NEGATIVE: Final[str] = "CHILD_NEGATIVE"
CHILD_INVALID_STRUCTURE: Final[str] = "CHILD_INVALID_STRUCTURE"
Expand Down
25 changes: 24 additions & 1 deletion pages/pg_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ 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_NHS_LOGO, action=actions.CLICK_LINK)

def verify_all_expected_links(self):
def verify_all_expected_links_for_nurse(self):
self.po.verify(locator=self.LNK_PROGRAMMES, 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)
Expand All @@ -68,3 +68,26 @@ def verify_all_expected_links(self):
value="https://guide.manage-vaccinations-in-schools.nhs.uk/",
exact=True,
)

def verify_all_expected_links_for_superuser(self):
self.po.verify(locator=self.LNK_PROGRAMMES, 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_VACCINES, property=object_properties.VISIBILITY, value=True, exact=True)
self.po.verify(
locator=self.LNK_UNMATCHED_CONSENT_RESPONSES, property=object_properties.VISIBILITY, value=True, exact=True
)
self.po.verify(locator=self.LNK_SCHOOL_MOVES, property=object_properties.VISIBILITY, value=True, exact=True)
self.po.verify(
locator=self.LNK_NOTICES, property=object_properties.VISIBILITY, value=True, exact=True
) # Superuser only
self.po.verify(locator=self.LNK_ORGANISATION, property=object_properties.VISIBILITY, value=True, exact=True)
self.po.verify(
locator=self.LNK_SERVICE_GUIDANCE, property=object_properties.VISIBILITY, value=True, exact=True
)
self.po.verify(
locator=self.LNK_SERVICE_GUIDANCE,
property=object_properties.HREF,
value="https://guide.manage-vaccinations-in-schools.nhs.uk/",
exact=True,
)
54 changes: 21 additions & 33 deletions pages/pg_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,44 +16,32 @@ class pg_login:
LBL_SUPERUSER = "Superuser Superuser"
LBL_PARAGRAPH = "paragraph"

def click_start(self):
self.po.perform_action(locator=self.LNK_START_NOW, action=actions.CLICK_LINK)
def login_as_nurse(self):
self.__login_actions(username=self.ce.nurse_username, password=self.ce.nurse_password)
self.verify_login(is_successful_login=True, verify_text=self.LBL_NURSE)

def enter_username(self, username: str):
self.po.perform_action(locator=self.TXT_EMAIL_ADDRESS, action=actions.FILL, value=username)
def login_as_superuser(self):
self.__login_actions(username=self.ce.superuser_username, password=self.ce.superuser_password)
self.verify_login(is_successful_login=True, verify_text=self.LBL_SUPERUSER)

def enter_password(self, password: str):
self.po.perform_action(locator=self.TXT_PASSWORD, action=actions.FILL, value=password)
def try_invalid_login(self, user: str, pwd: str, expected_message: str) -> str:
self.__login_actions(username=user, password=pwd)
self.verify_login(is_successful_login=False, verify_text=expected_message)

def click_login(self):
self.po.perform_action(locator=self.BTN_LOGIN, action=actions.CLICK_BUTTON)
def logout_of_mavis(self):
self.po.perform_action(locator=self.BTN_LOGOUT, action=actions.CLICK_BUTTON)

def verify_login_successful(self):
self.po.verify(locator=self.LBL_BANNER, property=object_properties.TEXT, value=self.LBL_NURSE)
def verify_login(self, is_successful_login: bool = True, verify_text: str = ""):
if is_successful_login:
self.po.verify(locator=self.LBL_BANNER, property=object_properties.TEXT, value=verify_text)
else:
self.po.verify(locator=self.LBL_PARAGRAPH, property=object_properties.TEXT, value=verify_text)

def login_as_nurse(self):
self.click_start()
self.enter_username(username=self.ce.nurse_username)
self.enter_password(password=self.ce.nurse_password)
self.click_login()
self.verify_login_successful()

def login_as_superuser(self):
self.click_start()
self.enter_username(username=self.ce.superuser_username)
self.enter_password(password=self.ce.superuser_password)
self.click_login()
self.verify_login_successful()

def perform_invalid_login(self, user: str, pwd: str, expected_message: str) -> str:
self.click_start()
self.enter_username(username=user)
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)
def __login_actions(self, username: str, password: str) -> None:
self.po.perform_action(locator=self.LNK_START_NOW, action=actions.CLICK_LINK)
self.po.perform_action(locator=self.TXT_EMAIL_ADDRESS, action=actions.FILL, value=username)
self.po.perform_action(locator=self.TXT_PASSWORD, action=actions.FILL, value=password)
self.po.perform_action(locator=self.BTN_LOGIN, action=actions.CLICK_BUTTON)

def go_to_url(self, url: str) -> None:
_full_url = f"{self.ce.service_url.replace('/start','')}{url}" if url.startswith("/") else url
Expand Down
29 changes: 27 additions & 2 deletions pages/pg_parental_consent.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,15 @@ class pg_parental_consent:
RDO_PERSONAL_CHOICE = "Personal choice"
RDO_OTHER = "Other"
RDO_ONLINE = "Online"
RDO_IN_PERSON = "In person"
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"
LBL_CONSENT_RECORDED = "Consent recorded for CF"
LBL_MAIN = "main"
RDO_PARENT1_DAD = "Parent1 (Dad)"
RDO_PARENT2_MUM = "Parent2 (Mum)"

def click_start_now(self):
self.po.perform_action(locator=self.BTN_START_NOW, action=actions.CLICK_BUTTON)
Expand Down Expand Up @@ -192,7 +195,7 @@ 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)

def service_give_consent(self):
self.po.perform_action(locator="Parent1 (Dad)", action=actions.RADIO_BUTTON_SELECT)
self.po.perform_action(locator=self.RDO_PARENT1_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)
Expand Down Expand Up @@ -226,7 +229,7 @@ def service_give_consent(self):
self.po.perform_action(locator=self.BTN_CONFIRM, action=actions.CLICK_BUTTON)

def service_refuse_consent(self):
self.po.perform_action(locator="Parent1 (Dad)", action=actions.RADIO_BUTTON_SELECT)
self.po.perform_action(locator=self.RDO_PARENT1_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)
Expand All @@ -242,3 +245,25 @@ def service_refuse_consent(self):
self.po.verify(
locator=self.LBL_MAIN, property=object_properties.TEXT, value=self.LBL_CONSENT_RECORDED, exact=False
)

def parent_1_verbal_no_response(self):
self.po.perform_action(locator=self.RDO_PARENT1_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_IN_PERSON, action=actions.RADIO_BUTTON_SELECT)
self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON)
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)
self.po.perform_action(locator=self.BTN_CONFIRM, action=actions.CLICK_BUTTON)

def parent_2_verbal_refuse_consent(self):
self.po.perform_action(locator=self.RDO_PARENT2_MUM, 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_IN_PERSON, action=actions.RADIO_BUTTON_SELECT)
self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON)
self.po.perform_action(locator=self.RDO_NO_THEY_DO_NOT_AGREE, action=actions.RADIO_BUTTON_SELECT)
self.po.perform_action(locator=self.BTN_CONTINUE, action=actions.CLICK_BUTTON)
self.po.perform_action(locator=self.RDO_PERSONAL_CHOICE, 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)
66 changes: 60 additions & 6 deletions pages/pg_sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class pg_sessions:
LNK_TAB_TODAY = "Today"
LNK_TAB_SCHEDULED = "Scheduled"
LNK_TAB_UNSCHEDULED = "Unscheduled"
LNK_TAB_NO_RESPONSE = "No response"
LNK_TAB_ACTIVITY_LOG = "Activity log"
LNK_IMPORT_CLASS_LIST = "Import class list"
LBL_CHOOSE_COHORT_FILE_1 = f"{LNK_SCHOOL_1}Import class"
Expand All @@ -26,6 +27,7 @@ class pg_sessions:
LNK_ADD_SESSION_DATES = "Add session dates"
LNK_RECORD_VACCINATIONS = "Record vaccinations"
LNK_CHILD_FULL_NAME = "CF"
LNK_CHILD_NO_CONSENT = "NoConsent1 NoConsent1"
LNK_UPDATE_TRIAGE_OUTCOME = "Update triage outcome"
LNK_SCHEDULE_SESSIONS = "Schedule sessions"
RDO_YES_SAFE_TO_VACCINATE = "Yes, it’s safe to vaccinate"
Expand All @@ -42,15 +44,15 @@ class pg_sessions:
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_CONSENT_GIVEN = "Triaged decision: Safe to vaccinate"
LBL_ACTIVITY_LOG_ENTRY_CONSENT_REFUSED = "Consent refused by Parent1 (Dad)"
BTN_GET_CONSENT_RESPONSES = "Get consent response"
BTN_GET_CONSENT_RESPONSE = "Get consent response"
LNK_CHECK_CONSENT_RESPONSES = "Check consent responses"
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"
Expand All @@ -59,6 +61,9 @@ class pg_sessions:
LNK_CONSENT_FORM = "View parental consent form ("
LNK_COULD_NOT_VACCINATE = "Could not vaccinate"
LNK_CONSENT_REFUSED = "Consent refused"
LNK_MARK_AS_INVALID = "Mark as invalid"
LNK_PARENT2 = "Parent2"
TXT_NOTES = "Notes"

def __get_display_formatted_date(self, date_to_format: str) -> str:
_parsed_date = datetime.strptime(date_to_format, "%Y%m%d")
Expand Down Expand Up @@ -86,6 +91,9 @@ def click_scheduled(self):
def click_unscheduled(self):
self.po.perform_action(locator=self.LNK_TAB_UNSCHEDULED, action=actions.CLICK_LINK, exact=True)

def click_no_response(self):
self.po.perform_action(locator=self.LNK_TAB_NO_RESPONSE, action=actions.CLICK_LINK, exact=False)

def click_activity_log(self):
self.po.perform_action(locator=self.LNK_TAB_ACTIVITY_LOG, action=actions.CLICK_LINK, exact=True)

Expand Down Expand Up @@ -114,6 +122,9 @@ def click_record_vaccinations(self):
def click_child_full_name(self):
self.po.perform_action(locator=self.LNK_CHILD_FULL_NAME, action=actions.CLICK_WILDCARD)

def click_child_no_consent(self):
self.po.perform_action(locator=self.LNK_CHILD_NO_CONSENT, action=actions.CLICK_LINK)

def click_update_triage_outcome(self):
self.po.perform_action(locator=self.LNK_UPDATE_TRIAGE_OUTCOME, action=actions.CLICK_LINK)

Expand All @@ -124,7 +135,7 @@ def click_save_triage(self):
self.po.perform_action(locator=self.BTN_SAVE_TRIAGE, action=actions.CLICK_BUTTON)

def click_check_consent_responses(self):
self.po.perform_action(locator=self.BTN_CHECK_CONSENT_RESPONSES, action=actions.CLICK_LINK)
self.po.perform_action(locator=self.LNK_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)
Expand Down Expand Up @@ -280,12 +291,30 @@ def verify_activity_log_entry(self, consent_given: bool):
exact=False,
)

def invalidate_parent2_refusal(self):
self.po.perform_action(locator=self.LNK_PARENT2, action=actions.CLICK_LINK)
self.po.perform_action(locator=self.LNK_MARK_AS_INVALID, action=actions.CLICK_LINK)
self.po.perform_action(locator=self.TXT_NOTES, action=actions.FILL, value="Invalidation notes.")
self.po.perform_action(locator=self.LNK_MARK_AS_INVALID, action=actions.CLICK_BUTTON)
self.po.verify(locator=self.LBL_MAIN, property=object_properties.TEXT, value="Consent refusedInvalid")
self.po.verify(locator=self.LBL_MAIN, property=object_properties.TEXT, value="Invalidation notes.")
self.po.perform_action(locator=self.LNK_BACK, action=actions.CLICK_LINK)
self.po.verify(locator=self.LBL_MAIN, property=object_properties.TEXT, value="Consent refusedInvalid")
self.po.verify(
locator=self.LBL_MAIN,
property=object_properties.TEXT,
value="No-one responded to our requests for consent.",
)

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_response(self):
self.po.perform_action(locator=self.BTN_GET_CONSENT_RESPONSE, action=actions.CLICK_BUTTON)

def click_get_consent_responses(self):
self.po.perform_action(locator=self.BTN_GET_CONSENT_RESPONSES, action=actions.CLICK_BUTTON)
self.po.perform_action(locator=self.LNK_CHECK_CONSENT_RESPONSES, action=actions.CLICK_BUTTON)

def upload_valid_class_list(self, file_paths: str):
_input_file_path, _ = self.tdo.get_file_paths(file_paths=file_paths)
Expand All @@ -308,7 +337,7 @@ def update_triage_outcome_positive(self, file_paths):
self.click_school1()
self.click_check_consent_responses()
self.click_child_full_name()
self.click_get_consent_responses()
self.click_get_consent_response()
self.consent_page.service_give_consent()
self.dashboard_page.go_to_dashboard()
self.dashboard_page.click_sessions()
Expand Down Expand Up @@ -337,7 +366,7 @@ def update_triage_outcome_consent_refused(self, file_paths):
self.click_school1()
self.click_check_consent_responses()
self.click_child_full_name()
self.click_get_consent_responses()
self.click_get_consent_response()
self.consent_page.service_refuse_consent()
self.click_consent_refused()
self.click_child_full_name()
Expand Down Expand Up @@ -404,3 +433,28 @@ def set_gillick_competence_for_student(self):

def get_consent_url(self) -> str:
return self.po.get_object_property(locator=self.LNK_CONSENT_FORM, property=object_properties.HREF)

def disparate_consent_scenario(self):
self.click_no_response()
self.click_child_no_consent()
self.click_get_consent_response()
self.consent_page.parent_1_verbal_no_response()
self.click_no_response()
self.click_child_no_consent()
self.click_get_consent_response()
self.consent_page.parent_2_verbal_refuse_consent()
self.click_consent_refused()
self.click_child_no_consent()
self.invalidate_parent2_refusal()
self.click_activity_log()
wait(timeout=wait_time.MIN)
# FIXME: Make the following generic
self.po.verify(
locator=self.LBL_MAIN, property=object_properties.TEXT, value="Consent from Parent2 invalidated"
)
self.po.verify(
locator=self.LBL_MAIN, property=object_properties.TEXT, value="Consent refused by Parent2 (Mum)"
)
self.po.verify(
locator=self.LBL_MAIN, property=object_properties.TEXT, value="Consent not_provided by Parent1 (Dad)"
)
2 changes: 2 additions & 0 deletions test_data/cohorts/i_no_consent.csv
Original file line number Diff line number Diff line change
@@ -0,0 +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
NoConsent1,NoConsent1,ChildCommon,1-1-2009,142181,<<NHS_NO>>,Addr1,Add2,City,AA1 1AA,Parent1,Dad,[email protected],,Parent2,Mum,[email protected],
1 change: 1 addition & 0 deletions test_data/file_mapping.csv
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ COHORTS_NEGATIVE,test_data/cohorts/i_negative.csv,test_data/cohorts/o_negative.c
COHORTS_INVALID_STRUCTURE,test_data/cohorts/i_invalid_structure.csv,test_data/cohorts/o_invalid_structure.csv,cohort
COHORTS_EMPTY_FILE,test_data/cohorts/i_empty.csv,test_data/cohorts/o_empty.csv,cohort
COHORTS_HEADER_ONLY,test_data/cohorts/i_header_only.csv,test_data/cohorts/o_header_only.csv,cohort
COHORTS_NO_APPROVAL,test_data/cohorts/i_no_consent.csv,,cohort
CHILD_POSITIVE,test_data/child/i_positive.csv,test_data/child/o_positive.csv,child
CHILD_NEGATIVE,test_data/child/i_negative.csv,test_data/child/o_negative.csv,child
CHILD_INVALID_STRUCTURE,test_data/child/i_invalid_structure.csv,test_data/child/o_invalid_structure.csv,child
Expand Down
Loading
Loading