diff --git a/.github/workflows/code_quality.yml b/.github/workflows/code_quality.yml index ea01484d8..da2d67fa5 100644 --- a/.github/workflows/code_quality.yml +++ b/.github/workflows/code_quality.yml @@ -377,6 +377,11 @@ jobs: docker compose -f docker-compose.tests.yml \ run --rm --entrypoint /bin/sh integration-test \ -c "python -m unittest" + - name: Run Playwright Test + run: | + docker compose -f docker-compose.tests.yml run --rm --build \ + --entrypoint "npx playwright test -c playwright.config.ts" \ + playwright-test # code quality formatting run-bash-script-linter: diff --git a/README.md b/README.md index c5884e99e..0889e1e2f 100644 --- a/README.md +++ b/README.md @@ -214,3 +214,14 @@ be available on their page, or you can visit http://localhost:6543/?embed=1&cont | `batch_process` | Given a list id argument run parse, geocode, and match via the batch_process Django management command | | `devhealthcheck.sh` | Simulate application load balancer health checks in development | | `postfacilitiescsv.py` | POST the rows of a CSV containing facility information to the facilities API | + + +## Running e2e (Playwright) and integration tests + +### Playwright Tests + +To run the Playwright tests, use the following command: +``` +docker compose -f docker-compose.tests.yml run --rm --build --entrypoint "npx playwright test -c playwright.config.ts" playwright-test +``` + diff --git a/doc/release/RELEASE-NOTES.md b/doc/release/RELEASE-NOTES.md index 4d4f18cf6..bfac7607b 100644 --- a/doc/release/RELEASE-NOTES.md +++ b/doc/release/RELEASE-NOTES.md @@ -25,6 +25,11 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html * [OSDEV-1335](https://opensupplyhub.atlassian.net/browse/OSDEV-1335) - The new "moderation events" Logstash pipeline has been configured and implemented to collect moderation event data from the current PostgreSQL database and save it to OpenSearch. This setup allows for fast searches on the moderation events data. * [OSDEV-1387](https://opensupplyhub.atlassian.net/browse/OSDEV-1387) - The SQL query for generating tiles from PostgreSQL+PostGIS has been reimplemented to avoid using the JOIN + GROUP BY clause. This change reduces the number of subqueries and their asymptotic complexity. Additionally, an option to set an upper limit on facility counts in the 'count' clause has been introduced, capped at 100, which doubles the query's performance. Throttling has been removed for tile generation endpoints. * [OSDEV-1171](https://opensupplyhub.atlassian.net/browse/OSDEV-1171) - RDS instances for `staging` and `test` have beed decreased to `db.t3.large` +* Playwright has been introduced as the main framework for end-to-end testing: + * Added a new Playwright testing service to the Docker configuration + * Implemented initial test cases to verify core functionality + * Integrated Playwright tests into the CI pipeline via GitHub Actions + * Added necessary configuration files and dependencies for the e2e testing project ### Bugfix * [OSDEV-1335](https://opensupplyhub.atlassian.net/browse/OSDEV-1335) - Fixed the assertion in the test for the `country.rb` filter of the "production locations" Logstash pipeline. The main issue was with the evaluation of statements in the Ruby block. Since only the last statement is evaluated in a Ruby block, all the checks were grouped into one chain of logical statements and returned as a `result` variable at the end. diff --git a/docker-compose.tests.yml b/docker-compose.tests.yml index 108022634..7e145cbf5 100644 --- a/docker-compose.tests.yml +++ b/docker-compose.tests.yml @@ -18,3 +18,12 @@ services: command: uvicorn main:app --host 0.0.0.0 --port 84 networks: - my-proxy-net + + playwright-test: + build: + context: ./src/e2e + dockerfile: Dockerfile + environment: + - CI=$CI + networks: + - my-proxy-net diff --git a/src/e2e/.gitignore b/src/e2e/.gitignore new file mode 100644 index 000000000..68c5d18f0 --- /dev/null +++ b/src/e2e/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/src/e2e/Dockerfile b/src/e2e/Dockerfile new file mode 100644 index 000000000..72254a440 --- /dev/null +++ b/src/e2e/Dockerfile @@ -0,0 +1,7 @@ +FROM mcr.microsoft.com/playwright:v1.48.1 + +COPY package.json package-lock.json playwright.config.ts ./ +COPY ./tests ./tests +RUN npm ci --ignore-scripts + +ENTRYPOINT [ "npx", "playwright", "test" ] \ No newline at end of file diff --git a/src/e2e/package-lock.json b/src/e2e/package-lock.json new file mode 100644 index 000000000..9fd9a6d4a --- /dev/null +++ b/src/e2e/package-lock.json @@ -0,0 +1,97 @@ +{ + "name": "e2e", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "e2e", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@playwright/test": "^1.48.1", + "@types/node": "^22.7.8" + } + }, + "node_modules/@playwright/test": { + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.1.tgz", + "integrity": "sha512-s9RtWoxkOLmRJdw3oFvhFbs9OJS0BzrLUc8Hf6l2UdCNd1rqeEyD4BhCJkvzeEoD1FsK4mirsWwGerhVmYKtZg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.48.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@types/node": { + "version": "22.7.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.8.tgz", + "integrity": "sha512-a922jJy31vqR5sk+kAdIENJjHblqcZ4RmERviFsER4WJcEONqxKcjNOlk0q7OUfrF5sddT+vng070cdfMlrPLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/playwright": { + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.1.tgz", + "integrity": "sha512-j8CiHW/V6HxmbntOfyB4+T/uk08tBy6ph0MpBXwuoofkSnLmlfdYNNkFTYD6ofzzlSqLA1fwH4vwvVFvJgLN0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.48.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.48.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.1.tgz", + "integrity": "sha512-Yw/t4VAFX/bBr1OzwCuOMZkY1Cnb4z/doAFSwf4huqAGWmf9eMNjmK7NiOljCdLmxeRYcGPPmcDgU0zOlzP0YA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/src/e2e/package.json b/src/e2e/package.json new file mode 100644 index 000000000..bc4a6a7e3 --- /dev/null +++ b/src/e2e/package.json @@ -0,0 +1,19 @@ +{ + "name": "e2e", + "version": "1.0.0", + "main": "index.js", + "directories": { + "test": "tests" + }, + "scripts": { + "test": "playwright test" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "devDependencies": { + "@playwright/test": "^1.48.1", + "@types/node": "^22.7.8" + } +} diff --git a/src/e2e/playwright.config.ts b/src/e2e/playwright.config.ts new file mode 100644 index 000000000..ac962a353 --- /dev/null +++ b/src/e2e/playwright.config.ts @@ -0,0 +1,44 @@ +import { defineConfig, devices } from '@playwright/test'; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// import dotenv from 'dotenv'; +// import path from 'path'; +// dotenv.config({ path: path.resolve(__dirname, '.env') }); + +/** + * See https://playwright.dev/docs/test-configuration. + */ + +export default defineConfig({ + testDir: './tests', + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: process.env.CI ? 2 : 0, + workers: process.env.CI ? 1 : 5, + reporter: process.env.CI ? 'dot' : 'list', + use: { + baseURL: 'http://react:6543/', + trace: 'on-first-retry', + }, + + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] }, + }, + + { + name: 'firefox', + use: { ...devices['Desktop Firefox'] }, + }, + + { + name: 'webkit', + use: { ...devices['Desktop Safari'] }, + }, + ], + +}); diff --git a/src/e2e/tests/home.page.spec.ts b/src/e2e/tests/home.page.spec.ts new file mode 100644 index 000000000..de7c1b22e --- /dev/null +++ b/src/e2e/tests/home.page.spec.ts @@ -0,0 +1,11 @@ +import { test, expect } from '@playwright/test'; + + +/** + * @description Verifies that the home page loads with the correct title + */ +test('Home page loads with the correct title', async ({ page }) => { + await page.goto('/'); + + await expect(page).toHaveTitle('Open Supply Hub');; +});