Skip to content

Commit 9732e72

Browse files
Env File Support (#52)
<!-- markdownlint-disable-next-line first-line-heading --> ## Description <!-- Describe your changes in detail. --> This adds functionality to support .env files for sensitive values, including a new script to automatically generate a local.env file and a fixture to run before all tests within the project and populate environment variables from this file when code is running. ## Context <!-- Why is this change required? What problem does it solve? --> This allows for anyone using this framework to store sensitive values locally for testing purposes, without the need of saving or committing any values to the codebase. ## 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 2711395 commit 9732e72

File tree

5 files changed

+99
-10
lines changed

5 files changed

+99
-10
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
*.code-workspace
1111
!project.code-workspace
1212

13-
# Please, add your custom content below!
13+
# Specific to this blueprint
1414

1515
__pycache__/
1616
.pytest_cache/
1717
test-results/
1818
axe-reports/
19+
local.env
20+
21+
# Please, add your custom content below!

README.md

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ This project is designed to provide a blueprint to allow for development teams t
1515
- [Configuration](#configuration)
1616
- [Getting Started](#getting-started)
1717
- [Utilities](#utilities)
18+
- [Using Environment Variables For Secrets](#using-environment-variables-for-secrets)
1819
- [Contributing](#contributing)
1920
- [Contacts](#contacts)
2021
- [Licence](#licence)
@@ -33,8 +34,6 @@ To utilise the blueprint code, you will need to have the following installed:
3334

3435
- [Python](https://www.python.org/downloads/) 3.12 or greater
3536

36-
> NOTE: There are currently known issues with Python 3.13 and Playwright, so if you encounter issues running this project whilst using Python 3.13 it is recommended to downgrade to Python 3.12 in the interim.
37-
3837
Whilst not required to get started, you may also want to [configure a Python virtual environment for your project](https://docs.python.org/3/library/venv.html) before proceeding with
3938
the configuration. If you are using an IDE such as Visual Studio Code or PyCharm, you will normally be prompted to do this automatically.
4039

@@ -73,14 +72,44 @@ For additional reading and guidance on writing tests, we also recommend reviewin
7372

7473
## Utilities
7574

76-
This blueprint also provides the following utility classes, that can be used to aid in testing:
75+
This blueprint provides the following utility classes, that can be used to aid in testing:
76+
77+
| Utility | Description |
78+
| ------------------------------------------------------------- | -------------------------------------------- |
79+
| [Axe](./docs/utility-guides/Axe.md) | Accessibility scanning using axe-core. |
80+
| [Date Time Utility](./docs/utility-guides/DateTimeUtility.md) | Basic functionality for managing date/times. |
81+
| [NHSNumberTools](./docs/utility-guides/NHSNumberTools.md) | Basic tools for working with NHS numbers. |
82+
| [User Tools](./docs/utility-guides/UserTools.md) | Basic user management tool. |
83+
84+
## Using Environment Variables For Secrets
85+
86+
This blueprint provides functionality for saving secret / sensitive values that you would not want present
87+
in the codebase, but require to execute tests locally (such as passwords or API keys). A local.env file can
88+
be generated by running the [following script](./setup_env_file.py):
89+
90+
```shell
91+
python ./setup_env_file.py
92+
```
93+
94+
This script file is design to be amended / updated as your project evolves, so as more sensitive values are required
95+
for executing tests, the list of keys provided can be updated so for subsequent runs of the script, all the expected
96+
keys are populated within the local.env file (which will need their values setting manually). The intent is that this
97+
script can be run to onboard new team members and provide a local file with all the variables they need to populate.
98+
99+
The local.env file (if present), is read at the start of any test session (via the [conftest.py file](./conftest.py))
100+
and any variables can be accessed by using the Python os library like so:
101+
102+
```python
103+
# Import the OS library
104+
import os
105+
106+
# Access environment variable
107+
os.getenv('<key_from_local.env>')
108+
```
109+
110+
The local.env file is set in the [.gitignore file](./.gitignore), so by default it will not commit if amended.
77111

78-
|Utility|Description|
79-
|-------|-----------|
80-
|[Axe](./docs/utility-guides/Axe.md)|Accessibility scanning using axe-core.|
81-
|[Date Time Utility](./docs/utility-guides/DateTimeUtility.md)|Basic functionality for managing date/times.|
82-
|[NHSNumberTools](./docs/utility-guides/NHSNumberTools.md)|Basic tools for working with NHS numbers.|
83-
|[User Tools](./docs/utility-guides/UserTools.md)|Basic user management tool.|
112+
> NOTE: You should never commit this file or any secrets in the codebase directly.
84113
85114
## Contributing
86115

conftest.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
This is a conftest.py file for pytest, which is used to set up fixtures and hooks for testing.
3+
This file is used to define fixtures that can be used across multiple test files.
4+
It is also used to define hooks that can be used to modify the behavior of pytest.
5+
"""
6+
7+
import pytest
8+
import os
9+
from dotenv import load_dotenv
10+
from pathlib import Path
11+
12+
LOCAL_ENV_PATH = Path(os.getcwd()) / 'local.env'
13+
14+
15+
@pytest.fixture(autouse=True, scope="session")
16+
def import_local_env_file() -> None:
17+
"""
18+
This fixture is used to import the local.env file into the test environment (if the file is present),
19+
and will populate the environment variables prior to any tests running.
20+
If environment variables are set in a different way when running (e.g. via cli), this will
21+
prioritise those values over the local.env file.
22+
23+
NOTE: You should not use this logic to read a .env file in a pipeline or workflow to set sensitive values.
24+
"""
25+
if Path.is_file(LOCAL_ENV_PATH):
26+
load_dotenv(LOCAL_ENV_PATH, override=False)

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ pytest-playwright>=0.5.1
22
pytest-html>=4.1.1
33
pytest-json-report>=1.5.0
44
pytest-playwright-axe>=4.10.3
5+
python-dotenv>=1.1.0

setup_env_file.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""
2+
This script creates a local.env file that can be used to populate secrets such as passwords or API keys
3+
locally. This is useful for local development and testing, as it allows you to keep sensitive information
4+
out of your codebase.
5+
6+
This is designed to be generated when setting up this project, so if new variables are required, these
7+
should be added to the REQUIRED_KEYS list below to automatically populate the local.env file with the
8+
keys required to run this project.
9+
"""
10+
11+
import os
12+
from pathlib import Path
13+
14+
REQUIRED_KEYS = ["USER_PASS"]
15+
DEFAULT_LOCAL_ENV_PATH = Path(os.getcwd()) / 'local.env'
16+
17+
def create_env_file():
18+
"""
19+
Create a local.env file with the required keys.
20+
"""
21+
with open(DEFAULT_LOCAL_ENV_PATH, 'w') as f:
22+
f.write("# Use this file to populate secrets without committing them to the codebase (as this file is set in .gitignore).\n")
23+
f.write("# To retrieve values as part of your tests, use os.getenv('VARIABLE_NAME').\n")
24+
f.write("# Note: When running in a pipeline or workflow, you should pass these variables in at runtime.\n\n")
25+
for key in REQUIRED_KEYS:
26+
f.write(f'{key}=\n')
27+
28+
29+
if __name__ == "__main__":
30+
create_env_file()

0 commit comments

Comments
 (0)