Skip to content

Commit 71d791a

Browse files
Subject Demographic Util (#69)
<!-- markdownlint-disable-next-line first-line-heading --> ## Description <!-- Describe your changes in detail. --> This is adding a new util to perform certain actions on the subject demographic page ## Context <!-- Why is this change required? What problem does it solve? --> This was needed as we need certain age ranges for the subjects in compartment 6. This will allow us to get the correct age ranges for all subjects ## Type of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply. --> - [ ] Refactoring (non-breaking change) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would change existing functionality) - [ ] Bug fix (non-breaking change which fixes an issue) ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [x] I am familiar with the [contributing guidelines](https://github.com/nhs-england-tools/playwright-python-blueprint/blob/main/CONTRIBUTING.md) - [x] I have followed the code style of the project - [ ] I have added tests to cover my changes (where appropriate) - [x] I have updated the documentation accordingly - [ ] This PR is a result of pair or mob programming --- ## Sensitive Information Declaration To ensure the utmost confidentiality and protect your and others privacy, we kindly ask you to NOT including [PII (Personal Identifiable Information) / PID (Personal Identifiable Data)](https://digital.nhs.uk/data-and-information/keeping-data-safe-and-benefitting-the-public) or any other sensitive data in this PR (Pull Request) and the codebase changes. We will remove any PR that do contain any sensitive information. We really appreciate your cooperation in this matter. - [x] I confirm that neither PII/PID nor sensitive data are included in this PR and the codebase changes.
1 parent 4062f22 commit 71d791a

File tree

4 files changed

+220
-0
lines changed

4 files changed

+220
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Utility Guide: Subject Demographics
2+
3+
The Subject Demographics utility allows for different updates to subjects to be made.<br>
4+
This includes the following:
5+
6+
1. Updating a subjects DOB to the following age ranges:
7+
1. 50-70
8+
2. 75-100
9+
10+
## Table of Contents
11+
12+
- [Utility Guide: Subject Demographics](#utility-guide-subject-demographics)
13+
- [Table of Contents](#table-of-contents)
14+
- [Using the Subject Demographics class](#using-the-subject-demographics-class)
15+
- [Updating DOB](#updating-dob)
16+
- [Required Args](#required-args)
17+
- [How to use this method](#how-to-use-this-method)
18+
19+
## Using the Subject Demographics class
20+
21+
You can initialise the Subject Demographics class by using the following code in your test file:
22+
23+
from utils.subject_demographics import SubjectDemographicUtil
24+
25+
## Updating DOB
26+
27+
Inside of the SubjectDemographicUtil class there is a method called `update_subject_dob`.<br>
28+
This is used to update the date of birth of a subject to a random age between 50-70 and 75-100 depending on if the argument `younger_subject` is set to True or False.<br>
29+
This method will navigate to the subject demographic page automatically and can be called from any page.
30+
31+
### Required Args
32+
33+
- nhs_no:
34+
- Type: `str`
35+
- This is the NHS number of the subject you want to update
36+
- younger_subject:
37+
- Type: `bool`
38+
- Whether you want the subject to be younger (50-70) or older (75-100).
39+
40+
### How to use this method
41+
42+
To use this method simply import the SubjectDemographicUtil class and call this method, providing the two arguments:
43+
44+
nhs_no = "9468743977"
45+
SubjectDemographicUtil(page).update_subject_dob(nhs_no, False)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
from playwright.sync_api import Page, expect
2+
from pages.base_page import BasePage
3+
from datetime import datetime
4+
from utils.calendar_picker import CalendarPicker
5+
6+
7+
class SubjectDemographicPage(BasePage):
8+
"""Subject Demographic Page locators, and methods for interacting with the page."""
9+
10+
def __init__(self, page: Page):
11+
super().__init__(page)
12+
self.page = page
13+
# Subject Demographic - page filters
14+
self.forename_field = self.page.get_by_role("textbox", name="Forename")
15+
self.surname_field = self.page.get_by_role("textbox", name="Surname")
16+
self.postcode_field = self.page.get_by_role("textbox", name="Postcode")
17+
self.dob_field = self.page.get_by_role("textbox", name="Date of Birth")
18+
self.update_subject_data_button = self.page.get_by_role(
19+
"button", name="Update Subject Data"
20+
)
21+
22+
def is_forename_filled(self) -> bool:
23+
"""
24+
Checks if the forename textbox contains a value.
25+
26+
Returns:
27+
True if the textbox has a non-empty value, False otherwise
28+
"""
29+
forename_value = self.forename_field.input_value()
30+
return bool(forename_value.strip())
31+
32+
def is_surname_filled(self) -> bool:
33+
"""
34+
Checks if the surname textbox contains a value.
35+
36+
Returns:
37+
True if the textbox has a non-empty value, False otherwise
38+
"""
39+
surname_value = self.surname_field.input_value()
40+
return bool(surname_value.strip())
41+
42+
def is_postcode_filled(self) -> bool:
43+
"""
44+
Checks if the postcode textbox contains a value.
45+
46+
Returns:
47+
True if the textbox has a non-empty value, False otherwise
48+
"""
49+
postcode_value = self.postcode_field.input_value()
50+
return bool(postcode_value.strip())
51+
52+
def fill_forename_input(self, name: str) -> None:
53+
"""
54+
Enters a value into the forename input textbox
55+
56+
Args:
57+
name (str): The name you want to enter
58+
"""
59+
self.forename_field.fill(name)
60+
61+
def fill_surname_input(self, name: str) -> None:
62+
"""
63+
Enters a value into the surname input textbox
64+
65+
Args:
66+
name (str): The name you want to enter
67+
"""
68+
self.surname_field.fill(name)
69+
70+
def fill_dob_input(self, date: datetime) -> None:
71+
"""
72+
Enters a value into the date of birth input textbox
73+
74+
Args:
75+
date (datetime): The date you want to enter
76+
"""
77+
date = CalendarPicker(self.page).calendar_picker_ddmmyyyy(date, self.dob_field)
78+
79+
def fill_postcode_input(self, postcode: str) -> None:
80+
"""
81+
Enters a value into the postcode input textbox
82+
83+
Args:
84+
postcode (str): The postcode you want to enter
85+
"""
86+
self.postcode_field.fill(postcode)
87+
88+
def click_update_subject_data_button(self) -> None:
89+
"""Clicks on the 'Update Subject Data' button"""
90+
self.click(self.update_subject_data_button)
91+
92+
def get_dob_field_value(self) -> str:
93+
"""
94+
Returns the value in the date of birth input textbox
95+
96+
Returns:
97+
str: The subject's date of birth as a string
98+
"""
99+
return self.dob_field.input_value()

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ python-dotenv~=1.1.0
88
sqlalchemy>=2.0.38
99
jproperties~=2.1.2
1010
pypdf>=5.3.0
11+
faker>=37.3.0

utils/subject_demographics.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from playwright.sync_api import Page
2+
from datetime import datetime
3+
from faker import Faker
4+
from dateutil.relativedelta import relativedelta
5+
import logging
6+
from pages.base_page import BasePage
7+
from pages.screening_subject_search.subject_screening_search_page import (
8+
SubjectScreeningPage,
9+
SearchAreaSearchOptions,
10+
)
11+
from pages.screening_subject_search.subject_demographic_page import (
12+
SubjectDemographicPage,
13+
)
14+
15+
16+
class SubjectDemographicUtil:
17+
"""The class for holding all the util methods to be used on the subject demographic page"""
18+
19+
def __init__(self, page: Page):
20+
self.page = page
21+
22+
def update_subject_dob(self, nhs_no: str, younger_subject: bool) -> None:
23+
"""
24+
Navigates to the subject demographics page and updates a subject's date of birth.
25+
26+
Args:
27+
nhs_no (str): The NHS number of the subject you want to update.
28+
younger_subject (bool): Whether you want the subject to be younger (50-70) or older (75-100).
29+
"""
30+
if younger_subject:
31+
end_date = datetime.today() - relativedelta(years=50)
32+
start_date = datetime.today() - relativedelta(years=70)
33+
date = self.random_datetime(start_date, end_date)
34+
else:
35+
end_date = datetime.today() - relativedelta(years=75)
36+
start_date = datetime.today() - relativedelta(years=100)
37+
date = self.random_datetime(start_date, end_date)
38+
39+
logging.info(f"Navigating to subject demographic page for: {nhs_no}")
40+
BasePage(self.page).click_main_menu_link()
41+
BasePage(self.page).go_to_screening_subject_search_page()
42+
SubjectScreeningPage(self.page).click_demographics_filter()
43+
SubjectScreeningPage(self.page).click_nhs_number_filter()
44+
SubjectScreeningPage(self.page).nhs_number_filter.fill(nhs_no)
45+
SubjectScreeningPage(self.page).nhs_number_filter.press("Tab")
46+
SubjectScreeningPage(self.page).select_search_area_option(
47+
SearchAreaSearchOptions.SEARCH_AREA_WHOLE_DATABASE.value
48+
)
49+
SubjectScreeningPage(self.page).click_search_button()
50+
postcode_filled = SubjectDemographicPage(self.page).is_postcode_filled()
51+
if not postcode_filled:
52+
fake = Faker("en_GB")
53+
random_postcode = fake.postcode()
54+
SubjectDemographicPage(self.page).fill_postcode_input(random_postcode)
55+
56+
current_dob = SubjectDemographicPage(self.page).get_dob_field_value()
57+
logging.info(f"Current DOB: {current_dob}")
58+
SubjectDemographicPage(self.page).fill_dob_input(date)
59+
SubjectDemographicPage(self.page).click_update_subject_data_button()
60+
updated_dob = SubjectDemographicPage(self.page).get_dob_field_value()
61+
logging.info(f"Updated DOB: {updated_dob}")
62+
63+
def random_datetime(self, start: datetime, end: datetime) -> datetime:
64+
"""
65+
Generate a random datetime between two datetime objects.
66+
67+
Args:
68+
start (datetime): the starting date
69+
end (datetime): The end date
70+
71+
Returns:
72+
datetime: the newly generated date
73+
"""
74+
fake = Faker()
75+
return fake.date_time_between(start, end)

0 commit comments

Comments
 (0)