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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ venv/
# Local
logs/pytest.log
main.py

reports/*
working/*
.vscode/*
8 changes: 6 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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
Expand Down
82 changes: 67 additions & 15 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -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 *


Expand All @@ -12,31 +12,83 @@ 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:
if ce.capture_screenshot_flag:
_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()
137 changes: 6 additions & 131 deletions libs/__init__.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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")
Expand All @@ -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)
Loading
Loading