Skip to content

Commit c333f93

Browse files
Merge remote-tracking branch 'upstream/main'
2 parents 0ae8833 + 2a8ff22 commit c333f93

File tree

15 files changed

+941
-11
lines changed

15 files changed

+941
-11
lines changed

Makefile

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,22 @@ include scripts/init.mk
55

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

8-
# NOTE: This project currently only uses this Makefile as part of CI/CD checks.
8+
# This allows the setup of Playwright by using a single command ready to use, and checks
9+
# if the user is in a virtual environment before running the setup.
10+
11+
.PHONY: check-venv
12+
check-venv: # Checks if in a Python venv / VIRTUALENV before installing a bunch of dependencies
13+
@python -c "import sys, os; \
14+
venv = (hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix) or 'VIRTUAL_ENV' in os.environ); \
15+
import sys; sys.exit(0 if venv else 1)"
16+
17+
setup-playwright: # Install Playwright and associated packages, and create local.env
18+
@echo "Checking for virtual environment..."
19+
$(MAKE) check-venv || (echo "ERROR: Not in a virtual environment, please create before running this command!"; exit 1)
20+
21+
@echo "Install Playwright"
22+
pip install -r requirements.txt
23+
playwright install
24+
25+
@echo "Setup local.env file"
26+
python setup_env_file.py

README.md

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# BCSS Playwright Test Suite
22

3-
[![CI/CD Pull Request](https://github.com/nhs-england-tools/repository-template/actions/workflows/cicd-1-pull-request.yaml/badge.svg)](https://github.com/nhs-england-tools/playwright-python-blueprint/actions/workflows/cicd-1-pull-request.yaml)
3+
[![CI/CD Pull Request](https://github.com/nhs-england-tools/playwright-python-blueprint/actions/workflows/cicd-1-pull-request.yaml/badge.svg)](https://github.com/nhs-england-tools/playwright-python-blueprint/actions/workflows/cicd-1-pull-request.yaml)
44

55
This repository contains the automated UI test suite for the BCSS application, built using [Playwright Python](https://playwright.dev/python/). It provides a structured framework and reusable utilities to support consistent, maintainable test development across the project.
66

@@ -48,7 +48,8 @@ Note: This project is actively maintained and evolving.
4848
- [3. Best Practices](#3-best-practices)
4949
- [4. Blueprint Utilities](#4-blueprint-utilities)
5050
- [5. BCSS Project Specific Utilities](#5-bcss-project-specific-utilities)
51-
- [Contributing](#contributing)
51+
- [Using the Jira Upload Script](#using-the-jira-upload-script)
52+
- [Contributing](#contributing)
5253
- [Contacts](#contacts)
5354
- [Licence](#licence)
5455

@@ -379,7 +380,57 @@ These utilities have been created specifically for the bcss playwright project:
379380
| [Table Utility](.docs/utility-guides/TableUtil.md) | Provides helper methods for interacting with HTML tables, including row selection, column indexing, and data extraction. |
380381
| [User Tools](.docs/utility-guides/UserTools.md) | Manages test user credentials via `users.json`, supports login automation, and retrieves user metadata for role-based testing. |
381382

382-
### Contributing
383+
## Using the Jira Upload Script
384+
385+
Included with this code is a Jira Upload utility that will allow for the uploading of artifacts from test runs to
386+
a Jira ticket directly. The script itself ([`jira_upload.py`](jira_upload.py)) can be invoked using the following
387+
command:
388+
389+
```shell
390+
python jira_upload.py
391+
```
392+
393+
For this to work, you need to set the follow environment variables (which you can do via local.env):
394+
395+
| Key | Required | Description |
396+
| --------------------- | -------- | ------------------------------------------------------------------------------------------------------ |
397+
| `JIRA_URL` | Yes | The Jira instance url to connect to |
398+
| `JIRA_PROJECT_KEY` | Yes | The project key for the Jira project to upload to |
399+
| `JIRA_API_KEY` | Yes | The Jira API key for your user, which can be generated in Jira via Profile > Personal Access Tokens |
400+
| `JIRA_TICKET_REFERENCE` | No | The Jira ticket you want to default to, if required. Can be left blank to use branch-based referencing |
401+
402+
This command will do the following actions:
403+
404+
1. Work out the Jira ticket to upload to and confirm it is a valid reference, by using the following logic:
405+
1. If a `--jira-ref` value has been provided, use that value.
406+
2. If a `JIRA_TICKET_REFERENCE` environment variable exists, use that value.
407+
3. If none of the above, check if you are in a feature branch and if so, compiles the Jira ticket reference by combining the project key and the end of the feature branch (when in the format `feature/<shortcode>-<jira_ticket_number>`).
408+
2. Check the `test-results/` directory (or custom directory if specified) for appropriate files under 10MB (Jira's file limit), specifically:
409+
1. HTML files (e.g. `report.html` generated by `pytest`).
410+
2. Trace Files (e.g. `test_name/trace.zip` generated by Playwright).
411+
3. Screenshots (e.g. `test_screenshot.png` generated by Playwright).
412+
4. CSV Files (e.g. `results.csv` generated during test execution from the UI).
413+
3. Prompt the user to confirm that they are updating the correct ticket and the correct files are being uploaded. If files already exist on the ticket with a matching name, a unique name will be provided unless `--overwrite-files` is provided.
414+
4. If `y` is selected, upload the files and add a comment (unless `--no-comment` is provided) to Jira outlining the files uploaded and if possible, the environment information from the test run (unless `--no-env-data` is provided).
415+
416+
You can also pass in the following arguments which will have the noted effects:
417+
418+
| Argument | Description |
419+
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
420+
| `--jira-ref <Jira Reference>` | The Jira ticket to upload to. Will take precedence over auto-deriving from branch name and the set environment variable. |
421+
| `--results-dir <Directory>` | The directory to point to. If not set, points to `test-results/` (the default directory for test results in this repository). |
422+
| `--no-html` | Don't include HTML files in the upload. |
423+
| `--no-trace` | Don't include Trace files (.zip) in the upload. |
424+
| `--no-csv` | Don't include CSV files in the upload. |
425+
| `--no-screenshots` | Don't include screenshots (.png) in the upload. |
426+
| `--no-comment` | Don't add a Jira comment highlighting the results. |
427+
| `--no-env-data` | Don't include environment data in the Jira comment (if getting environment data has been configured). |
428+
| `--overwrite-files` | If a filename exists on the ticket that matches those in the results directory, overwrite them. |
429+
| `--auto-confirm` | Will not ask if you want to proceed if provided, and will assume that yes has been pressed. |
430+
431+
Further information on the available actions for this logic can be found in the [Jira Confluence Utility utility guide](./docs/utility-guides/JiraConfluenceUtil.md).
432+
433+
## Contributing
383434

384435
Further guidance on contributing to this project can be found in our [contribution](./CONTRIBUTING.md) page.
385436

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
# Utility Guide: JiraConfluenceUtil
2+
3+
The `JiraConfluenceUtil` utility provides methods for interacting with Jira and Confluence, specifically for uploading Playwright test results and metadata to Jira tickets.
4+
5+
> NOTE: For most use cases, you should use the [jira_upload.py](../../jira_upload.py) script as outlined in the [README](../../README.md).
6+
> This guide is for developers who want to use the utility directly in custom workflows or scripts.
7+
8+
## Table of Contents
9+
10+
- [Utility Guide: JiraConfluenceUtil](#utility-guide-jiraconfluenceutil)
11+
- [Table of Contents](#table-of-contents)
12+
- [Using the JiraConfluenceUtil class](#using-the-jiraconfluenceutil-class)
13+
- [Required Environment Variables](#required-environment-variables)
14+
- [Initialise the class](#initialise-the-class)
15+
- [Public Methods](#public-methods)
16+
- [`get_issue_data`](#get_issue_data)
17+
- [`get_issue_summary_in_issue_data`](#get_issue_summary_in_issue_data)
18+
- [`check_attachment_exists_in_issue_data`](#check_attachment_exists_in_issue_data)
19+
- [`is_valid_jira_reference`](#is_valid_jira_reference)
20+
- [`determine_jira_reference_local`](#determine_jira_reference_local)
21+
- [`get_environment_metadata_if_available`](#get_environment_metadata_if_available)
22+
- [`is_file_is_less_than_jira_file_limit`](#is_file_is_less_than_jira_file_limit)
23+
- [`upload_test_results_dir_to_jira`](#upload_test_results_dir_to_jira)
24+
- [Example Usage](#example-usage)
25+
26+
## Using the JiraConfluenceUtil class
27+
28+
### Required Environment Variables
29+
30+
The following environment variables need to be set (in local.env if running locally) for any Jira-based actions:
31+
32+
- **JIRA_URL**: The Jira instance to upload to.
33+
- **JIRA_PROJECT_KEY**: The Jira project key that should be uploaded to.
34+
- **JIRA_API_KEY**: The API key to use to complete actions. Locally you should generate your own key, and use a bot in a pipeline/workflow.
35+
36+
The following environment variables are optional:
37+
38+
- **JIRA_TICKET_REFERENCE**: The Jira ticket to push to if set. If not, will attempt to derive the value from the git branch.
39+
40+
The following environment variables need to be set for any Confluence-based actions:
41+
42+
- **CONFLUENCE_URL**: The Confluence instance to upload to.
43+
- **CONFLUENCE_API_KEY**: The API key to use to complete actions. Locally you should generate your own key, and use a bot in a pipeline/workflow.
44+
45+
### Initialise the class
46+
47+
You can initialise the class by importing and creating an instance:
48+
49+
```python
50+
from utils.jira_confluence_util import JiraConfluenceUtil
51+
52+
util = JiraConfluenceUtil()
53+
```
54+
55+
You can also specify a custom results directory:
56+
57+
```python
58+
util = JiraConfluenceUtil(results_dir="path/to/results")
59+
```
60+
61+
## Public Methods
62+
63+
### `get_issue_data`
64+
65+
```python
66+
get_issue_data(ticket_id: str) -> dict | None
67+
```
68+
69+
Checks if a Jira issue exists and returns its data as a dictionary, or `None` if not found.
70+
71+
---
72+
73+
### `get_issue_summary_in_issue_data`
74+
75+
```python
76+
get_issue_summary_in_issue_data(issue_data: dict) -> str | None
77+
```
78+
79+
Returns a summary string for the given Jira issue data in the format "[Ticket]: [Summary Line]", or `None` if not available.
80+
81+
---
82+
83+
### `check_attachment_exists_in_issue_data`
84+
85+
```python
86+
check_attachment_exists_in_issue_data(issue_data: dict, filename: str) -> bool
87+
```
88+
89+
Checks if a Jira issue already has an attachment with the specified filename.
90+
91+
---
92+
93+
### `is_valid_jira_reference`
94+
95+
```python
96+
is_valid_jira_reference(ticket_id: str) -> bool
97+
```
98+
99+
Validates that the Jira ticket reference is in the expected format (e.g., `SCM-1234` or `BSS2-5678`).
100+
101+
---
102+
103+
### `determine_jira_reference_local`
104+
105+
```python
106+
determine_jira_reference_local() -> str
107+
```
108+
109+
Determines the Jira ticket reference from the current git branch or if `JIRA_TICKET_REFERENCE` has been set.
110+
111+
This is currently configured to search for the format `feature/[Jira Reference]`, so for example:
112+
113+
- `feature/TEST-1234` would return `TEST-1234`.
114+
- `feature/TEST-2345-feature-name` would return `TEST-2345`.
115+
116+
> NOTE: Depending on your projects branch naming strategy, you may want to modify this method to suit your needs
117+
> accordingly.
118+
119+
---
120+
121+
### `get_environment_metadata_if_available`
122+
123+
```python
124+
get_environment_metadata_if_available() -> str
125+
```
126+
127+
This is method designed to return metadata for the environment under test. In this project, it is a stub method
128+
designed to be overwritten.
129+
130+
> NOTE: You will need to populate this method with the code required to get the metadata for your environment.
131+
> It is heavily recommended that you populate `results.json` with the data required, and then read the file
132+
> using this method to extract the data required.
133+
134+
---
135+
136+
### `is_file_is_less_than_jira_file_limit`
137+
138+
```python
139+
is_file_is_less_than_jira_file_limit(file_path: Path) -> bool
140+
```
141+
142+
Checks if the file size is below the Jira upload limit (10MB).
143+
144+
---
145+
146+
### `upload_test_results_dir_to_jira`
147+
148+
```python
149+
upload_test_results_dir_to_jira(
150+
ticket_id: str,
151+
overwrite_files: bool = True,
152+
include_html: bool = True,
153+
include_trace_files: bool = True,
154+
include_screenshots: bool = True,
155+
include_csv: bool = True,
156+
include_env_metadata: bool = True,
157+
add_comment: bool = True,
158+
automatically_accept: bool = False,
159+
) -> None
160+
```
161+
162+
Uploads files from the results directory to the specified Jira ticket.
163+
Options allow you to control which file types are included, whether to overwrite existing files, add a comment, and auto-confirm the upload.
164+
165+
For any files over 10MB, they will **not** be uploaded using this method as they will exceed the default file size limit
166+
set for Jira.
167+
168+
Each of the following arguments relate to the following actions:
169+
170+
- `overwrite_files` = If the file already exists on Jira, it will overwrite the file and use the same name if True. If false, it'll generate a unique filename based on the date/time of the upload.
171+
- `include_html` = Will check for any `.html` files in the root of the `results_dir` provided and include them if under 10MB if True.
172+
- `include_trace_files` = Will check for any `.zip` files in subdirectories of the `results_dir` provided and include them if under 10MB if True, renaming the file to include the subdirectory name.
173+
- `include_screenshots` = Will check for any `.png` files in the rood directory `results_dir` provided and the `screenshot/` subdirectory and include them if under 10MB if True.
174+
- `include_csv` = Will check for any `.csv` files in the root of the `results_dir` provided and include them if under 10MB if True.
175+
- `include_env_metadata` = Will check for any environment metadata generated by `get_environment_metadata_if_available` and include it in the comment if True.
176+
- `add_comment` = Will add a comment to Jira summarizing all the attachments and environment metadata if True.
177+
- `automatically_accept` = Will bypass generating a terminal message that needs to be accepted and assume the answer was `y` if True.
178+
179+
---
180+
181+
## Example Usage
182+
183+
```python
184+
from utils.jira_confluence_util import JiraConfluenceUtil
185+
186+
util = JiraConfluenceUtil()
187+
ticket_id = util.determine_jira_reference_local()
188+
if util.is_valid_jira_reference(ticket_id):
189+
util.upload_test_results_dir_to_jira(
190+
ticket_id=ticket_id,
191+
overwrite_files=True,
192+
include_html=True,
193+
include_trace_files=True,
194+
include_screenshots=True,
195+
include_csv=True,
196+
include_env_metadata=True,
197+
add_comment=True,
198+
automatically_accept=False
199+
)
200+
```

0 commit comments

Comments
 (0)