Skip to content

Commit e00653b

Browse files
Getting Started Guides (#34)
<!-- markdownlint-disable-next-line first-line-heading --> ## Description <!-- Describe your changes in detail. --> This adds getting started documentation. ## Context <!-- Why is this change required? What problem does it solve? --> This provides an initial reference point if new people to this framework aren't sure where to start. ## Type of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply. --> - [x] 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. --> - [ ] I am familiar with the [contributing guidelines](../docs/CONTRIBUTING.md) - [x] I have followed the code style of the project - [ ] I have added tests to cover my changes - [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 6c7ae0d commit e00653b

File tree

14 files changed

+263
-40
lines changed

14 files changed

+263
-40
lines changed

.vscode/extensions.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
"recommendations": [
33
"alefragnani.bookmarks",
44
"davidanson.vscode-markdownlint",
5-
"dbaeumer.vscode-eslint",
65
"donjayamanne.githistory",
76
"eamodio.gitlens",
87
"editorconfig.editorconfig",
9-
"esbenp.prettier-vscode",
108
"github.codespaces",
119
"github.github-vscode-theme",
1210
"github.remotehub",
1311
"github.vscode-github-actions",
1412
"github.vscode-pull-request-github",
1513
"hediet.vscode-drawio",
14+
"howardzuo.vscode-favorites",
1615
"johnpapa.vscode-peacock",
1716
"mhutchie.git-graph",
1817
"ms-azuretools.vscode-docker",
18+
"ms-python.python",
1919
"ms-vscode-remote.remote-containers",
2020
"ms-vscode-remote.remote-wsl",
2121
"ms-vscode.hexeditor",

.vscode/settings.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,13 @@
33
"MD013": false,
44
"MD024": { "siblings_only": true },
55
"MD033": false
6-
}
6+
},
7+
"cSpell.words": [
8+
"addopts",
9+
"codegen",
10+
"pytest",
11+
"utilise",
12+
"utilised",
13+
"Utilising"
14+
]
715
}

Makefile

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,4 @@ include scripts/init.mk
55

66
# ==============================================================================
77

8-
# Example CI/CD targets are: dependencies, build, publish, deploy, clean, etc.
9-
10-
dependencies: # Install dependencies needed to build and test the project @Pipeline
11-
# TODO: Implement installation of your project dependencies
12-
13-
build: # Build the project artefact @Pipeline
14-
# TODO: Implement the artefact build step
15-
16-
publish: # Publish the project artefact @Pipeline
17-
# TODO: Implement the artefact publishing step
18-
19-
deploy: # Deploy the project artefact to the target environment @Pipeline
20-
# TODO: Implement the artefact deployment step
21-
22-
clean:: # Clean-up project resources (main) @Operations
23-
# TODO: Implement project resources clean-up step
24-
25-
config:: # Configure development environment (main) @Configuration
26-
# TODO: Use only 'make' targets that are specific to this project, e.g. you may not need to install Node.js
27-
make _install-dependencies
28-
29-
# ==============================================================================
30-
31-
${VERBOSE}.SILENT: \
32-
build \
33-
clean \
34-
config \
35-
dependencies \
36-
deploy \
8+
# NOTE: This project currently only uses this Makefile as part of CI/CD checks.
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,179 @@
11
# Getting Started #1: Understanding Playwright Python
2+
3+
This guide outlines how Playwright works in Python, and how to start writing tests in the format this blueprint recommends.
4+
5+
## Contents
6+
7+
- [Getting Started #1: Understanding Playwright Python](#getting-started-1-understanding-playwright-python)
8+
- [Contents](#contents)
9+
- [The Basics](#the-basics)
10+
- [How Does pytest Work](#how-does-pytest-work)
11+
- [Executing Tests](#executing-tests)
12+
- [Using pytest Logic](#using-pytest-logic)
13+
- [Utilising Playwright `codegen`](#utilising-playwright-codegen)
14+
- [Utilising Playwright `show-trace`](#utilising-playwright-show-trace)
15+
- [Further Reading](#further-reading)
16+
- [Appendix](#appendix)
17+
- [Info: What Is Chromium](#info-what-is-chromium)
18+
19+
## The Basics
20+
21+
For Python, Playwright is treated as a plugin for a unit testing framework called [pytest](https://docs.pytest.org/en/stable/) and
22+
expands the functionality provided by pytest to allow for interaction with browsers (and allow us to write UI tests using the same logic)
23+
along with other testing utilities. Because of this, in this blueprint you will see references to pytest regularly, as it is the engine
24+
that drives the test execution.
25+
26+
## How Does pytest Work
27+
28+
In the case of this blueprint, pytest works by
29+
[scanning directories within the code base to discover tests](https://docs.pytest.org/en/stable/explanation/goodpractices.html#test-discovery),
30+
where by default it looks for any files in the format of `test_*.py` or `*_test.py`. Once the files have been discovered, it'll check for any
31+
functions in the file starting with `test_` and if found, will execute that function as a test and collect the result.
32+
33+
pytest will spin up any utilities it needs to execute tests (including any we choose to define), which for this framework includes a number of
34+
Playwright-specific objects we would likely want to utilise, including:
35+
36+
- `page`: The Playwright page object, which we use to interact with a browser page during tests. You'll likely use this object for every test.
37+
- `browser`: The Playwright browser object, which we use to create and manage the browser directly and create new pages if required. It's unlikely you'll need to include this unless you have a very specific browser test.
38+
- `playwright`: The Playwright object, which we can use to manage the Playwright instance during testing. It's extremely unlikely you'll need this when pytest is the test executor.
39+
40+
For further reading on pytest, it's recommended to read the [full documentation](https://docs.pytest.org/en/stable/).
41+
42+
## Executing Tests
43+
44+
Because pytest is the engine in this blueprint, we use the pytest command to initiate any test execution. This can be done as simply by using
45+
the following command in the command line against this blueprint (once the initial setup has been completed):
46+
47+
pytest
48+
49+
When using this command, it will run any tests with the default configuration provided by pytest and Playwright (which in the case of UI testing,
50+
normally means that it'll run all tests against the [Chromium](#info-what-is-chromium) browser that was installed).
51+
52+
If you want to execute tests with specific settings, such as a specific browser or to specify specific tests to run, these can be passed in on the
53+
command line after the pytest command or via the [pytest.ini](../../pytest.ini) file (using the `addopts` section).
54+
55+
For further reading on the kinds of settings you can apply with pytest, take a look at our [Quick Reference Guide](./Quick_Reference_Guide.md).
56+
57+
## Using pytest Logic
58+
59+
When we use Playwright with pytest, a number of objects that we may want to interact with are automatically generated, but the most pertinent
60+
of these is the `page` object, which represents the browser page object we want to interact with. Because it's provided automatically when we
61+
start a test run, we do not need to do any specific configuration with the test other than add a reference to this page object in the function
62+
arguments for the test like so:
63+
64+
# Doing an import like this for the page object isn't required, but is considered good practice
65+
from playwright.sync_api import Page
66+
67+
# An example call showing how the page object is brought into a test, and how it can be used
68+
def test_example(page: Page) -> None:
69+
page.goto("https://github.com/nhs-england-tools/playwright-python-blueprint")
70+
71+
As you can see from the example, the only setup for the `page` object here is in the function arguments, and we can use it as needed in the test.
72+
We can also use this logic to create utilities and resources that can be utilised by our tests, and easily pass them in to be used as needed.
73+
74+
The `page` object is an example of a fixture, which are actions that can be run before or after any tests we want to execute (these are known as
75+
hooks in other test automation frameworks). A fixture is normally defined at the start of a set of tests, in a format like so:
76+
77+
# Doing an import like this for the page object isn't required, but is considered good practice
78+
from playwright.sync_api import Page
79+
80+
# An example fixture, which runs before the start of every test in this module
81+
@pytest.fixture(autouse=True)
82+
def go_to_page(page: Page) -> None:
83+
page.goto("https://github.com/nhs-england-tools/playwright-python-blueprint")
84+
85+
# An example test which continues on from the fixture above
86+
def test_example(page: Page) -> None:
87+
page.get_by_placeholder("Go to file").fill("test_example.py")
88+
page.get_by_label("tests/test_example.").click()
89+
expect(page.locator("#file-name-id-wide")).to_contain_text("test_example.py")
90+
91+
This allows for easy reuse of steps and reducing overall test maintenance going forward. Fixtures can play a powerful part in how you design
92+
your tests, including creating utilities available for global use, or just adding repeatable actions in a way that can overall reduce the
93+
maintenance effort of your tests going forward.
94+
95+
Further reading on fixtures can be found in the [Playwright documentation](https://playwright.dev/python/docs/test-runners#fixtures).
96+
97+
## Utilising Playwright `codegen`
98+
99+
If you're new to Playwright, Python or automating tests generally, then
100+
[Playwright provides a code generation tool](https://playwright.dev/python/docs/codegen#recording-a-test) that allows you to manually navigate
101+
through a browser to generate the code for a test. You can access the `codegen` tool by using the following command:
102+
103+
# Load a empty browser window
104+
playwright codegen
105+
106+
This will bring up a browser window, with the Playwright code generator running alongside, like so:
107+
108+
<!-- vale off -->
109+
![An image of the Playwright codegen tool](./img/1-codegen.png "Playwright codegen")
110+
<!-- vale on -->
111+
112+
When using the `codegen` tool, it is recommended to do the following:
113+
114+
- Pass in a starting URL where possible to set the window at your starting location (e.g. `playwright codegen https://github.com/nhs-england-tools/playwright-python-blueprint`)
115+
- When using the Playwright Inspector window, set the target value to Pytest as it'll automatically format any generated tests into the pytest format we recommend using in this blueprint
116+
117+
The `codegen` tool is particularly powerful, as it also allows you to consider assertions on the page you are hoping to test. Currently, you can do the following
118+
basic assertions using the `codegen` tool:
119+
120+
- Assert visibility of an element on the page
121+
- Assert specific text is present within an element on the page
122+
- Assert an element on the page has a specific value
123+
124+
These are accessible via the floating menu when using the `codegen` tool, as highlighted in green here:
125+
126+
<!-- vale off -->
127+
![An image of the Playwright codegen options](./img/2-codegen_tools.png "Playwright codegen tools")
128+
<!-- vale on -->
129+
130+
Whilst the `codegen` tool will provide you with the basic code to get started, it's recommended that once you've got a working test, you consider refactoring any
131+
code that has been provided and refine as needed. Having the ability to generate the code in this fashion allows you to create tests quickly and build up
132+
understanding of how to construct tests using Playwright Python, but you will soon discover that they may not be the most efficient in their raw state!
133+
134+
## Utilising Playwright `show-trace`
135+
136+
If you encounter issues when trying to execute your newly created tests,
137+
[Playwright also provides a trace functionality](https://playwright.dev/python/docs/trace-viewer-intro) that records each action a test
138+
undertakes and outlines where any issues or errors have occurred. This can be useful for a number of reasons, including:
139+
140+
- Easily pinpointing problems within a test, including functional and performance concerns
141+
- Generating evidence to show stakeholders what a test actually does during execution
142+
- The ZIP file generated can be opened on any machine, or via a [browser utility provided by Playwright](https://trace.playwright.dev/)
143+
144+
To open a trace file, use the following command (replacing `<path-to-file>` with the actual path to the trace.zip file generated):
145+
146+
# Opens a trace file
147+
playwright show-trace <path-to-file>
148+
149+
A trace file when opened looks like this:
150+
151+
<!-- vale off -->
152+
![An image of the Playwright trace file](./img/3-show_trace.png "Playwright trace file view")
153+
<!-- vale on -->
154+
155+
The primary information provided within the trace is:
156+
157+
- A timeline of events with screenshots (at the top of the report)
158+
- A summary of each action undertaken (on the left side of the report)
159+
- A screenshot of the selected action (on the right side of the report)
160+
- The network and test activity (at the bottom of the report)
161+
162+
As you can see, it provides a lot of information to work with to help demonstrate what a test is doing, and diagnosing
163+
any issues when something goes wrong.
164+
165+
## Further Reading
166+
167+
Here are some useful links for further reading beyond these guides:
168+
169+
- [Playwright Python documentation](https://playwright.dev/python/docs/intro)
170+
- [pytest documentation](https://docs.pytest.org/en/stable/index.html)
171+
172+
## Appendix
173+
174+
### Info: What Is Chromium
175+
176+
[Chromium](https://www.chromium.org/Home/) is one of the open source browser that comes bundled with Playwright on install (if using the instructions
177+
within the [README](../../README.md) of this blueprint) but also more importantly, serves as the base code for both Google Chrome and Microsoft Edge.
178+
Whilst this doesn't replace the need to test in independent browsers as required, Chromium provides the opportunity to do some initial broad testing
179+
which should largely be representative of the user experience with Chrome and Edge respectively.
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,68 @@
11
# Getting Started #2: Blueprint File Breakdown
2+
3+
This guide outlines the breakdown of this blueprint, and specifically the files of importance for running Playwright Pytest.
4+
5+
## Contents
6+
7+
- [Getting Started #2: Blueprint File Breakdown](#getting-started-2-blueprint-file-breakdown)
8+
- [Contents](#contents)
9+
- [Directories \& Files Directly Impacting Tests](#directories--files-directly-impacting-tests)
10+
- [`requirements.txt`](#requirementstxt)
11+
- [`pytest.ini`](#pytestini)
12+
- [`tests/`](#tests)
13+
- [`pages/`](#pages)
14+
- [`utils/`](#utils)
15+
- [Directories \& Files Specific For This Repository](#directories--files-specific-for-this-repository)
16+
17+
## Directories & Files Directly Impacting Tests
18+
19+
The files in this section cover the files that impact your ability to execute tests.
20+
21+
### `requirements.txt`
22+
23+
This file outlines the packages required from the Python Package Index (PyPI) to execute this project. This should be regularly maintained to ensure that we have the most up-to-date versions of any packages we intend to use.
24+
25+
### `pytest.ini`
26+
27+
This file outlines the configuration of pytest, and ultimately how Playwright also executes. A couple of things to note:
28+
29+
- The `log_cli` section covers default logging provided by pytest - we have defaulted this to on at INFO level, but this can be amended as needed.
30+
- The `addopts` section will run any commands you want to run by default for each execution and can be overwritten using the appropriate options via the command line. For example, you can override the `--tracing` level to on by executing pytest using: `pytest --tracing=on`. The options we have turned on by default are:
31+
- Do not run the tests marked utils by default (these are the unit tests for this project and do not use Playwright)
32+
- Generate a HTML report in a single file, and output it in the `test-results` directory with the name `report.html`
33+
- Generate a JSON report, omitting some collection data and then output it in the `test-results` directory with the name `results.json`
34+
- Only generate Playwright stack-trace files when a test fails
35+
- The `markers` section is for organizing any marks (or tags) you want to apply to your tests, for example by a business area or a testing type. If you don't include your marks in this list, pytest will give you a warning until they have either been added here or programmatically within the code.
36+
37+
Any configuration you want to apply to all of your test executions should be placed in this file where possible, to ensure easy maintenance.
38+
39+
### `tests/`
40+
41+
This directory is designed to house all of your tests intended for execution.
42+
43+
Because we want to treat this directory as a [Python package](https://docs.python.org/3/tutorial/modules.html#packages), there is a blank `__init__.py` file present in this directory that should remain present.
44+
45+
### `pages/`
46+
47+
This directory is designed to house all of your [page object model](https://playwright.dev/python/docs/pom) classes, to facilitate reusable code and easy to maintain tests.
48+
49+
We want this directory to be treated as a [Python package](https://docs.python.org/3/tutorial/modules.html#packages), so there is a blank `__init__.py` file present in this directory that should remain present.
50+
51+
### `utils/`
52+
53+
This directory is designed to house any utility classes that would assist in test execution. We provide some utility classes as part of this blueprint, but as you begin testing your own applications you may find that these utilities may need to be expanded or you need something different from what has been provided. For example, you may create a utility class for logging into your application - that code should go in this directory.
54+
55+
We want this directory to be treated as a [Python package](https://docs.python.org/3/tutorial/modules.html#packages), so there is a blank `__init__.py` file present in this directory that should remain present.
56+
57+
> NOTE: If you write a utility class for your own project that you think other projects may benefit from and can be applied in a generic way, please raise a [Feature Request](https://github.com/nhs-england-tools/playwright-python-blueprint/issues/new/choose) as we welcome any contributions of this fashion.
58+
59+
## Directories & Files Specific For This Repository
60+
61+
The following directories and files are specific for this repository, and may require modification or removal if transferring this code into a new repository.
62+
63+
- `.github/`: This directory has the code used to manage our repository and pipelines including CI/CD checks. You may find some useful for your own repository, especially if you are using GitHub to manage your code.
64+
- `.vscode/`: This directory houses the default recommended configuration and settings for VSCode, if you use it as an IDE.
65+
- `docs/`: This directory houses the documentation for this repository (including documents like this one).
66+
- `scripts/`: This directory houses the scripts used by this repository, primarily as part of the CI/CD checks.
67+
- `tests_utils/`: This directory houses the unit tests for the utilities provided by this repository. You may want to copy these over if you want to ensure utilities are behaving as expected.
68+
- `.editorconfig`, `.gitattributes`, `.gitignore`, `.gitleaks.toml`, `.gitleaksignore`: These files are configuration for git, and quality and security checks provided via the CI/CD checks.
36.1 KB
Loading
115 KB
Loading
124 KB
Loading

infrastructure/modules/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)