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

Introduce Functional Tests using Playwright and Behave #31

Merged
merged 68 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from 54 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
59f84ec
Initial locally working example tests
AdamHawtin Nov 18, 2024
62122f6
Run in CI Github Action
AdamHawtin Nov 18, 2024
790f571
Matrix the functional tests on browser
AdamHawtin Nov 19, 2024
9b9556d
Record and save traces on test failures
AdamHawtin Nov 19, 2024
e6c4991
Refactor feature steps into a better example structure, add info page…
AdamHawtin Nov 20, 2024
b05c7b3
Add make targets
AdamHawtin Nov 20, 2024
b50c98d
Remove browsers with issues from the actions run
AdamHawtin Nov 21, 2024
9fa4f0e
Use docker compose instead of manual configured postgres
AdamHawtin Nov 21, 2024
c2471b7
Use DSLR instead of postgres client
AdamHawtin Nov 22, 2024
a402663
Add basic README documentation on running the test
AdamHawtin Nov 25, 2024
49b1929
Add scenario for release page
AdamHawtin Nov 25, 2024
9f125fb
Add more docs
AdamHawtin Nov 27, 2024
ffccd06
Make compatible with multi-db configuration
AdamHawtin Nov 27, 2024
efcdf76
Small structural refactor, fix factory imports, update Docs
AdamHawtin Nov 29, 2024
ee027c7
Set the settings module variable in environment.py
AdamHawtin Nov 29, 2024
213592b
Format
AdamHawtin Nov 29, 2024
5870138
Move environment variable setting to the module level
AdamHawtin Nov 29, 2024
e1300b0
Add missing README links
AdamHawtin Nov 29, 2024
c96c3c8
Fix README wording
AdamHawtin Nov 29, 2024
fadc2f7
Fix PR issues, make the test development app a separate compose file
AdamHawtin Dec 2, 2024
c2e5e68
Resolve merge conflicts
AdamHawtin Dec 3, 2024
7c6bd7d
First round or PR comments addressed, WIP on fixing issues
AdamHawtin Dec 3, 2024
9370e8c
Improve code example
AdamHawtin Dec 3, 2024
c39a644
Address more PR comments, tests fix still WIP
AdamHawtin Dec 3, 2024
f743206
Fix markdown that prettier broke
AdamHawtin Dec 3, 2024
ee52031
Fix code example
AdamHawtin Dec 3, 2024
a321408
Format
AdamHawtin Dec 3, 2024
6f85cca
Remove checks for missing titles
AdamHawtin Dec 3, 2024
8a49cbd
Use behave verbose mode to see error logs
AdamHawtin Dec 3, 2024
1e63111
Add a sleep to check if there's a timing issue
AdamHawtin Dec 3, 2024
b85cbac
Check if the issue is related to removing the dev app
AdamHawtin Dec 3, 2024
52f85ac
Try preparing the test database with migrations
AdamHawtin Dec 3, 2024
7b0f1b9
Resolve merge conflicts#
AdamHawtin Dec 4, 2024
2ac9ad0
Fix headings, fix test env initialisation issues, utilise compose ext…
AdamHawtin Dec 4, 2024
67a996d
Use existing factory classes, remove duplication
AdamHawtin Dec 4, 2024
3d0b9ee
README updates and fixes
AdamHawtin Dec 4, 2024
69b7d06
Update functional_tests/steps/home_page.py
AdamHawtin Dec 4, 2024
c5eaff7
Update functional_tests/steps/release_page.py
AdamHawtin Dec 4, 2024
123fbbd
Use readable pylint names instead of codes
AdamHawtin Dec 4, 2024
4768548
Remove verbose flag from CI
AdamHawtin Dec 4, 2024
d71309d
Merge branch 'main' into playwright-functional-tests-CMS-198
AdamHawtin Dec 5, 2024
f6867cc
Intentionally fail a scenario for demonstration purposes
AdamHawtin Dec 5, 2024
d90ad12
Revert intentional fail
AdamHawtin Dec 5, 2024
b9a3a38
Fix incorrect ports in dev app compose
AdamHawtin Dec 5, 2024
bb1d65c
Resolve merge conflicts
AdamHawtin Dec 5, 2024
308d61b
Merge branch 'main' into playwright-functional-tests-CMS-198
AdamHawtin Dec 5, 2024
b133753
Merge branch 'main' into playwright-functional-tests-CMS-198
AdamHawtin Dec 11, 2024
c04240a
Update functional_tests/README.md
AdamHawtin Dec 11, 2024
9edfd43
Update functional_tests/README.md
AdamHawtin Dec 11, 2024
1f91fec
Address review comments
AdamHawtin Dec 11, 2024
f169b8e
Streamline CI steps with make command
AdamHawtin Dec 12, 2024
53161a0
Address review comments, update make targets and comments
AdamHawtin Dec 12, 2024
ef68d7f
Merge branch 'main' into playwright-functional-tests-CMS-198
AdamHawtin Dec 13, 2024
29dc618
More consistent use of settings flag
AdamHawtin Dec 13, 2024
dcf2784
Resolve merge conflicts
AdamHawtin Dec 13, 2024
1395238
Merge branch 'main' into playwright-functional-tests-CMS-198
zerolab Dec 13, 2024
4dc619e
Fix broken auto-format
AdamHawtin Dec 16, 2024
380e4c0
Attempt to fix formatting
AdamHawtin Dec 16, 2024
f21bf5c
Merge branch 'main' into playwright-functional-tests-CMS-198
AdamHawtin Jan 8, 2025
752e218
Format
AdamHawtin Jan 8, 2025
1e93981
Resolve merge conflicts
AdamHawtin Jan 8, 2025
3bfc35e
Resolve merge conflicts
AdamHawtin Jan 8, 2025
090d1fb
Fix table of contents formatting
AdamHawtin Jan 8, 2025
84934cd
Merge branch 'main' into playwright-functional-tests-CMS-198
AdamHawtin Jan 9, 2025
c1e104a
Fix test link location
AdamHawtin Jan 9, 2025
da49c97
Merge branch 'main' into playwright-functional-tests-CMS-198
AdamHawtin Jan 10, 2025
47edc57
Merge branch 'main' into playwright-functional-tests-CMS-198
AdamHawtin Jan 10, 2025
63e996e
Merge branch 'main' into playwright-functional-tests-CMS-198
AdamHawtin Jan 13, 2025
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
50 changes: 50 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,53 @@ jobs:
- uses: actions/checkout@v4
- name: Build Docker Image
run: docker build --target web -t ons .

functional-tests:
runs-on: ubuntu-latest
strategy:
matrix:
browser:
- chromium
needs:
- lint
- lint-front-end
- compile_static

env:
DJANGO_SETTINGS_MODULE: cms.settings.functional_test
SECRET_KEY: fake_secret_key_to_run_tests # pragma: allowlist secret
PLAYWRIGHT_BROWSER: ${{ matrix.browser }}
PLAYWRIGHT_TRACES_DIR: playwright_traces
PLAYWRIGHT_TRACE: 'true'

steps:
- uses: actions/checkout@v4
- name: Install Poetry
run: pipx install poetry==${{ env.POETRY_VERSION }}

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: .python-version
cache: poetry

- name: Install dependencies
run: make install-dev

- name: Playwright Install
run: poetry run python -m playwright install --with-deps ${{ matrix.browser }}

- uses: actions/download-artifact@v4
with:
name: static
path: cms/static_compiled/

- name: Run Functional Tests
run: make functional-tests

- name: Upload Failure Traces
uses: actions/upload-artifact@v4
if: failure()
with:
name: playwright-traces-${{ matrix.browser }}
path: playwright_traces/
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,6 @@ static/

# Media files
/media

# Playwright Traces
/tmp_traces
25 changes: 25 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,28 @@ runserver: ## Run the Django application locally

.PHONY: dev-init
dev-init: load-design-system-templates collectstatic makemigrations migrate createsuperuser ## Run the pre-run setup scripts

.PHONY: functional-tests-up
functional-tests-up: ## Start the functional tests docker compose dependencies
docker compose -f functional_tests/docker-compose.yml up -d

.PHONY: functional-tests-dev-up
functional-tests-dev-up: ## Start the functional tests docker compose dependencies and dev app
docker compose -f functional_tests/docker-compose-dev.yml up -d

.PHONY: functional-tests-down
functional-tests-down: ## Stop the functional tests docker compose dependencies (and dev app if running)
docker compose -f functional_tests/docker-compose-dev.yml down

.PHONY: functional-tests-run
functional-tests-run: load-design-system-templates collectstatic ## Only run the functional tests (dependencies must be run separately)
# Run migrations to work around Django bug (#35967)
poetry run ./manage.py migrate --noinput --settings cms.settings.functional_test
poetry run behave functional_tests

.PHONY: functional-tests
functional-tests: functional-tests-up functional-tests-run functional-tests-down ## Run the functional tests with dependencies (all in one)

.PHONY: playwright-install
playwright-install: ## Install Playwright dependencies
poetry run playwright install --with-deps
80 changes: 74 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ The Wagtail CMS for managing and publishing content for the Office for National
- [Front-end tooling](#front-end-tooling)
- [Adding Python packages](#adding-python-packages)
- [Run Tests with Coverage](#run-tests-with-coverage)
- [Functional Tests](#functional-tests)
- [Linting and Formatting](#linting-and-formatting)
- [Python](#python)
- [Front-end](#front-end)
Expand All @@ -36,6 +37,7 @@ The Wagtail CMS for managing and publishing content for the Office for National
- [Django Migrations](#django-migrations)
- [Contributing](#contributing)
- [License](#license)

<!-- markdown-link-check-enable -->

For further developer documentation see [docs](docs/index.md)
Expand All @@ -52,9 +54,12 @@ Ensure you have the following installed:
managing Python versions.
2. **[Poetry](https://python-poetry.org/)**: This is used to manage package dependencies and virtual
environments.
3. **[Colima](https://github.com/ONSdigital/dp-compose/blob/main/setting-up-colima-locally.md)** for running the project in Docker containers.
4. **[PostgreSQL](https://www.postgresql.org/)** for the database. Provided as container via `docker-compose.yml` when using the Docker setup.
5. **[Node](https://nodejs.org/en)** and **[`nvm` (Node Version Manager)](https://github.com/nvm-sh/nvm)** for front-end tooling.
3. **[Colima](https://github.com/ONSdigital/dp-compose/blob/main/setting-up-colima-locally.md)** for running the project
in Docker containers.
4. **[PostgreSQL](https://www.postgresql.org/)** for the database. Provided as container via `docker-compose.yml` when
using the Docker setup.
5. **[Node](https://nodejs.org/en)** and **[`nvm` (Node Version Manager)](https://github.com/nvm-sh/nvm)** for front-end
tooling.
6. **[JQ](https://jqlang.github.io/jq/)** for the step in the build that installs the design system templates
7. **Operation System**: Ubuntu/MacOS

Expand Down Expand Up @@ -119,8 +124,8 @@ Follow these steps to set up and run the project using Docker.

Once the containers are running, you need to manually start Django from within the web container. This allows for running both the Django server and any additional background services (e.g., schedulers).

> ⚠️ WARNING
> The `honcho` command will pick up your local mounted `.env` file when running via `docker-compose`. Ensure that you comment out any variables in the `.env` file which might cause clashes in the container context as they will take precedence when running `honcho start`.
> ⚠️ WARNING
> The `honcho` command will pick up your local mounted `.env` file when running via `docker-compose`. Ensure that you comment out any variables in the `.env` file which might cause clashes in the container context as they will take precedence when running `honcho start`.

```bash
# Start both Django and the scheduler using Honcho
Expand Down Expand Up @@ -164,6 +169,7 @@ make compose-dev-up
- generating and applying database migrations,
- creating a superuser with:
- username: `admin`
<!-- pragma: allowlist nextline secret) -->
- password: `changeme`

```
Expand Down Expand Up @@ -225,7 +231,69 @@ To run the tests and check coverage, run:
make test
```

During tests, the `cms.settings.test` settings module is used. When running test without using `make test`, ensure this settings module is used.
During tests, the `cms.settings.test` settings module is used. When running test without using `make test`, ensure this
settings module is used.

### Functional Tests

Our suite of functional browser driven tests uses [Behave](https://behave.readthedocs.io/en/latest/),
[Playwright](https://playwright.dev/python/docs/intro) and
[Django Live Server Test Cases](https://docs.djangoproject.com/en/stable/topics/testing/tools/#liveservertestcase) to
run BDD Cucumber feature tests against the app from a browser.

#### Installation

Install the Playwright dependencies (including its browser drivers) with:

```shell
make playwright-install
```

#### Run the Functional Tests

You can run the tests as an all-in-one command with:

```shell
make functional-tests
```

This will start and stop the docker compose services with the relevant tests.

To run the docker compose dependencies (database and redis) separately, e.g. if you want to run individual functional
tests yourself for development, start the docker compose dependencies with:

```shell
make functional-tests-up
```

This will start the dependent services in the background, allowing you to then run the tests separately.

Then once you are finished testing, stop the dependencies with:

```shell
make functional-tests-down
```

#### Showing the Tests Browser

By default, the tests will run in headless mode with no visible browser window.

To disable headless mode and show the browser, set `PLAYWRIGHT_HEADLESS=False` in the environment from which you are
running the tests. In this circumstance, you will probably also find it helpful to enable "slow mo" mode, which slows
down the automated browser interactions to make it possible to follow what the tests are doing. You can configure it
using the `PLAYWRIGHT_SLOW_MO` environment variable, passing it a value of milliseconds by which to slow each
interaction, e.g. `PLAYWRIGHT_SLOW_MO=1000` will cause each individual browser interaction from the tests to be delayed
by 1 second.

For example, you can run the tests with visible browser and each interaction slowed by a second by running:

```shell
PLAYWRIGHT_HEADLESS=False PLAYWRIGHT_SLOW_MO=1000 make functional-tests
```

#### Developing Functional Tests

Refer to the detailed [functional tests development docs](./functional_tests/README.md)

### Linting and Formatting

Expand Down
10 changes: 10 additions & 0 deletions cms/settings/functional_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import copy

from .test import * # noqa: F403 # pylint: disable=wildcard-import,unused-wildcard-import

DATABASES = {
"default": dj_database_url.config(default="postgres://ons:ons@localhost:15432/ons"), # noqa: F405
}
DATABASES["read_replica"] = copy.deepcopy(DATABASES["default"])

REDIS_URL = "redis://localhost:16379"
8 changes: 4 additions & 4 deletions cms/users/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Meta:

@factory.post_generation
def access_admin(self, create, extracted, **kwargs):
"""Creates BundlePage instances for the bundle.
"""Allows the group access to the Wagtail Admin interface.

Usage:
# Create a Django generic_user group
Expand Down Expand Up @@ -42,13 +42,13 @@ class Meta:

@factory.post_generation
def access_admin(self, create, extracted, **kwargs):
"""Creates BundlePage instances for the bundle.
"""Allows the user access to the Wagtail Admin interface.

Usage:
# Create a Django generic_user group
# Create a Django generic_user user
generic_user = UserFactory()

# Create a Django generic_user group with Wagtail admin access
# Create a Django generic_user user with Wagtail admin access
generic_user = UserFactory(access_admin=True)
"""
if not create:
Expand Down
Loading
Loading