Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New: [AEA-4609] - Move UI tests into existing regression test pack #182

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
1 change: 1 addition & 0 deletions .github/workflows/regression_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ on:
description: 'The product we are testing'
type: choice
options:
- CPTS-UI
- EPS-FHIR
- EPS-FHIR-PRESCRIBING
- EPS-FHIR-DISPENSING
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@ repos:
language: system

fail_fast: false
default_stages: [pre-commit, commit]
default_stages: [pre-commit, pre-commit]
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Change the `env` variable accordingly to either `INT` or `INTERNAL-DEV`.
If you wish to test a different product i.e. `PFP-APIGEE` then you must change `product=` and `--tags` respectively.

### Method 5:
Run the tests by pushing changes to github in a pull request and running the regression tests job.
Run the tests by pushing changes to github in a pull request and running the regression tests job.
You can do this by the browser or by running this
```
BRANCH=fix_tests_take_2
Expand Down Expand Up @@ -114,12 +114,20 @@ This process will stop after the first program detects an error or if Black modi
You may need to run this multiple times to ensure everything is ok before committing.


### Generating the allure report from a github test run
To generate and view the results of a github test run, first authenticate to github by running this and following instructions
### Generating the allure report from a GitHub test run
To generate and view the results of a GitHub test run, first authenticate to GitHub by running this and following instructions
```
gh auth login
```
Then download the alluere results by noting the github run id in a browser and running this
Then download the allure results by noting the GitHub run ID in a browser and running this
```
GITHUB_RUN_ID=11523235428 make download-allure-report
GITHUB_RUN_ID=11523235428 make download-allure-report
```

# UI testing
This pack has recently been updated to include UI-based testing using Playwright for CPTS-UI. It will run headless using the Chrome browser

## Recording new tests:
Playwright contains a handy (but not perfect) feature which will record actions you make and give you the code for them
to begin, run the command: <br />
`playwright codegen`
6 changes: 6 additions & 0 deletions features/cpts_ui/home_page.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@cpts_ui @home @regression @blocker @smoke @ui
@allure.tms:https://nhsd-jira.digital.nhs.uk/browse/AEA-4460
Feature: I can visit the Clinical Prescription Tracker Service Website
Scenario: user can navigate to the Clinical Prescription Tracker Service Website homepage
When I go to the homepage
Then I am on the homepage
124 changes: 97 additions & 27 deletions features/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,29 @@

from behave.model import Scenario
from dotenv import load_dotenv

from playwright.sync_api import sync_playwright
from methods.api import eps_api_methods

load_dotenv(override=True)

global _page
INTERNAL_QA_BASE_URL = "https://internal-qa.api.service.nhs.uk/"
INTERNAL_DEV_BASE_URL = "https://internal-dev.api.service.nhs.uk/"
INT_BASE_URL = "https://int.api.service.nhs.uk/"
SANDBOX_DEV_BASE_URL = "https://internal-dev-sandbox.api.service.nhs.uk/"
SANDBOX_INT_BASE_URL = "https://sandbox.api.service.nhs.uk/"
REF_BASE_URL = "https://ref.api.service.nhs.uk/"

AWS_BASE_URL = ".eps.national.nhs.uk/"
PFP_AWS_PR_URL = "https://pfp-{{aws_pull_request_id}}.dev.eps.national.nhs.uk/"
PFP_AWS_SANDBOX_PR_URL = (
"https://pfp-{{aws_pull_request_id}}-sandbox.dev.eps.national.nhs.uk/"
)
CPTS_UI_PR_URL = "https://cpt-ui-{{aws_pull_request_id}}.dev.eps.national.nhs.uk/"
CPTS_UI_SANDBOX_PR_URL = (
"https://cpt-ui-{{aws_pull_request_id}}sandbox.dev.eps.national.nhs.uk/"
)


ENVS = {
APIGEE_ENVS = {
"INTERNAL-DEV": INTERNAL_DEV_BASE_URL,
"INTERNAL-QA": INTERNAL_QA_BASE_URL,
"INT": INT_BASE_URL,
Expand All @@ -32,15 +36,26 @@
"SANDBOX": SANDBOX_INT_BASE_URL,
}

AWS_ENVS = {
"INTERNAL-DEV": f".dev{AWS_BASE_URL}",
"INTERNAL-QA": f".qa{AWS_BASE_URL}",
"INT": f".int{AWS_BASE_URL}",
"REF": f".ref{AWS_BASE_URL}",
"INTERNAL-DEV-SANDBOX": f".sandbox{AWS_BASE_URL}",
"SANDBOX": f".sandbox.dev{AWS_BASE_URL}",
}

CIS2_USERS = {
"prescriber": {"user_id": "656005750107", "role_id": "555254242105"},
"dispenser": {"user_id": "555260695103", "role_id": "555265434108"},
}
LOGIN_USERS = {"user_id": "9449304130"}

REPOS = {
"CPTS-UI": "https://github.com/NHSDigital/eps-prescription-tracker-ui",
"EPS-FHIR": "https://github.com/NHSDigital/electronic-prescription-service-api",
# TODO Add EPS Dispensing and Prescribing repo URLs
"EPS-FHIR-PRESCRIBING": "https://github.com/NHSDigital/electronic-prescription-service-api",
"EPS-FHIR-DISPENSING": "https://github.com/NHSDigital/electronic-prescription-service-api",
"PFP-APIGEE": "https://github.com/NHSDigital/prescriptions-for-patients",
"PFP-AWS": "https://github.com/NHSDigital/prescriptionsforpatients",
"PSU": "https://github.com/NHSDigital/eps-prescription-status-update-api",
Expand All @@ -54,6 +69,7 @@
JWT_PRIVATE_KEY = os.getenv("JWT_PRIVATE_KEY")
JWT_KID = os.getenv("JWT_KID")

CPTS_UI_PREFIX = "cpt-ui"
EPS_FHIR_SUFFIX = "electronic-prescriptions"
EPS_FHIR_PRESCRIBING_SUFFIX = "fhir-prescribing"
EPS_FHIR_DISPENSING_SUFFIX = "fhir-dispensing"
Expand All @@ -76,25 +92,41 @@ def count_of_scenarios_to_run(context):


def before_all(context):
product = context.config.userdata["product"].upper()
if count_of_scenarios_to_run(context) != 0:
env = context.config.userdata["env"].upper()
product = context.config.userdata["product"].upper()
context.eps_fhir_base_url = os.path.join(select_base_url(env), EPS_FHIR_SUFFIX)
context.cpts_ui_base_url = f"https://{CPTS_UI_PREFIX}" + select_aws_base_url(
env
)
context.eps_fhir_base_url = os.path.join(
select_apigee_base_url(env), EPS_FHIR_SUFFIX
)
context.eps_fhir_prescribing_base_url = os.path.join(
select_base_url(env), EPS_FHIR_PRESCRIBING_SUFFIX
select_apigee_base_url(env), EPS_FHIR_PRESCRIBING_SUFFIX
)
context.eps_fhir_dispensing_base_url = os.path.join(
select_base_url(env), EPS_FHIR_DISPENSING_SUFFIX
select_apigee_base_url(env), EPS_FHIR_DISPENSING_SUFFIX
)
context.pfp_base_url = os.path.join(select_base_url(env), PFP_SUFFIX)
context.psu_base_url = os.path.join(select_base_url(env), PSU_SUFFIX)
context.pfp_base_url = os.path.join(select_apigee_base_url(env), PFP_SUFFIX)
context.psu_base_url = os.path.join(select_apigee_base_url(env), PSU_SUFFIX)
if PULL_REQUEST_ID:
pull_request_id = PULL_REQUEST_ID.lower()
if "pr-" in pull_request_id:
get_url_with_pr(context, env, product)
else:
raise RuntimeError("no tests to run. Check your tags and try again")
if product == "CPTS-UI":
global _page
playwright = sync_playwright().start()
browser = playwright.chromium.launch(
headless=True, slow_mo=1000, channel="chrome"
)
context.page = browser.new_page()
_page = context.page
set_page(context, _page)

eps_api_methods.calculate_eps_fhir_base_url(context)
print("CPTS-UI: ", context.cpts_ui_base_url)
print("EPS: ", context.eps_fhir_base_url)
print("EPS-PRESCRIBING: ", context.eps_fhir_prescribing_base_url)
print("EPS-DISPENSING: ", context.eps_fhir_dispensing_base_url)
Expand All @@ -120,23 +152,44 @@ def get_url_with_pr(context, env, product):
context.pfp_base_url = os.path.join(
INTERNAL_DEV_BASE_URL, f"{PFP_SUFFIX}-{PULL_REQUEST_ID}"
)
if product == "PFP-AWS":
context.pfp_base_url = os.path.join(
INTERNAL_DEV_BASE_URL, f"{PFP_SUFFIX}-{PULL_REQUEST_ID}"
)
if env == "INTERNAL-DEV":
context.pfp_base_url = PFP_AWS_PR_URL.replace(
"{{aws_pull_request_id}}", PULL_REQUEST_ID
)
if env == "INTERNAL-DEV-SANDBOX":
context.pfp_base_url = PFP_AWS_SANDBOX_PR_URL.replace(
"{{aws_pull_request_id}}", PULL_REQUEST_ID
)

if product == "PSU":
context.psu_base_url = os.path.join(
INTERNAL_DEV_BASE_URL, f"{PSU_SUFFIX}-{PULL_REQUEST_ID}"
)
if product == "PFP-AWS":
handle_pfp_aws_pr_url(context, env)
if product == "CPTS-UI":
handle_cpt_ui_pr_url(context, env)


def handle_cpt_ui_pr_url(context, env):
assert PULL_REQUEST_ID is not None
context.cpts_ui_base_url = (
f"https://{CPTS_UI_PREFIX}-{PULL_REQUEST_ID}{select_apigee_base_url(env)}"
)
if env == "INTERNAL-DEV":
context.cpts_ui_base_url = CPTS_UI_PR_URL.replace(
"{{aws_pull_request_id}}", PULL_REQUEST_ID
)
if env == "INTERNAL-DEV-SANDBOX":
context.cpts_ui_base_url = CPTS_UI_SANDBOX_PR_URL.replace(
"{{aws_pull_request_id}}", PULL_REQUEST_ID
)


def handle_pfp_aws_pr_url(context, env):
assert PULL_REQUEST_ID is not None
context.pfp_base_url = os.path.join(
INTERNAL_DEV_BASE_URL, f"{PFP_SUFFIX}-{PULL_REQUEST_ID}"
)
if env == "INTERNAL-DEV":
context.pfp_base_url = PFP_AWS_PR_URL.replace(
"{{aws_pull_request_id}}", PULL_REQUEST_ID
)
if env == "INTERNAL-DEV-SANDBOX":
context.pfp_base_url = PFP_AWS_SANDBOX_PR_URL.replace(
"{{aws_pull_request_id}}", PULL_REQUEST_ID
)


def after_all(context):
Expand Down Expand Up @@ -167,6 +220,8 @@ def after_all(context):
if os.path.exists(directory_path) and os.path.isdir(directory_path):
print(f"Directory '{directory_path}' exists. Deleting...")
shutil.rmtree(directory_path)
if _page:
_page.close()


def setup_logging(level: int = logging.INFO):
Expand All @@ -179,9 +234,16 @@ def setup_logging(level: int = logging.INFO):
)


def select_base_url(env):
if env in ENVS:
return ENVS[env]
def select_apigee_base_url(env):
if env in APIGEE_ENVS:
return APIGEE_ENVS[env]
else:
raise ValueError(f"Unknown environment or missing base URL for: {env} .")


def select_aws_base_url(env):
if env in AWS_ENVS:
return AWS_ENVS[env]
else:
raise ValueError(f"Unknown environment or missing base URL for: {env} .")

Expand All @@ -199,3 +261,11 @@ def write_properties_file(file_path, properties_dict):
with open(file_path, "w") as file:
for key, value in properties_dict.items():
file.write(f"{key}={value}\n")


def get_page(self):
return self._page


def set_page(self, _page):
self._page = _page
14 changes: 14 additions & 0 deletions features/steps/home_page_steps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# pylint: disable=no-name-in-module
from behave import when, then # pyright: ignore [reportAttributeAccessIssue]
from pages.home_page import HomePage


@when("I go to the homepage")
def goto_page(context):
context.page.goto(context.cpts_ui_base_url + "site/")


@then("I am on the homepage")
def verify_on_page(context):
home_page = HomePage(context.page)
home_page.verify_header_link()
12 changes: 12 additions & 0 deletions pages/home_page.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from playwright.sync_api import Page, expect


class HomePage:

def __init__(self, page: Page):
self.page = page

def verify_header_link(self):
expect(
self.page.get_by_role("link", name="Clinical prescription")
).to_be_visible()
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pytest-nhsd-apim = "^3.3.15"
requests-oauthlib = "^2.0.0"
nhs-number-generator = {git = "https://github.com/Iain-S/nhs_number_generator.git"}
pyright = "^1.1.377"
playwright = "^1.48.0"


[tool.poetry.group.dev.dependencies]
Expand Down