From 32125cf15fd3a1193e9d0c30255e84724d6e88eb Mon Sep 17 00:00:00 2001 From: Randila Premarathne Date: Sun, 10 Dec 2023 18:31:25 +0530 Subject: [PATCH 1/2] Set up esm-home repo for e2e testing --- .gitignore | 6 ++++++ package.json | 2 ++ yarn.lock | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 520b3f351..1f3ebb806 100644 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,9 @@ dist # i18next parser creating moduleName folder when parsing index.ts moduleName + +# Playwright and e2e tests +/test-results/ +/playwright-report/ +/playwright/.cache/ +e2e/storageState.json diff --git a/package.json b/package.json index fa349f70e..24e4488f0 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@babel/core": "^7.22.17", "@carbon/react": "^1.37.0", "@openmrs/esm-framework": "next", + "@playwright/test": "^1.30.0", "@swc/cli": "^0.1.62", "@swc/core": "^1.3.84", "@swc/jest": "^0.2.29", @@ -36,6 +37,7 @@ "concurrently": "^8.2.1", "cross-env": "^7.0.3", "css-loader": "^6.8.1", + "dotenv": "^16.0.3", "eslint": "^8.49.0", "eslint-config-prettier": "^9.0.0", "eslint-config-ts-react-important-stuff": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index 75db5ba68..0c690cdb4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3320,6 +3320,7 @@ __metadata: "@babel/core": "npm:^7.22.17" "@carbon/react": "npm:^1.37.0" "@openmrs/esm-framework": "npm:next" + "@playwright/test": "npm:^1.30.0" "@swc/cli": "npm:^0.1.62" "@swc/core": "npm:^1.3.84" "@swc/jest": "npm:^0.2.29" @@ -3336,6 +3337,7 @@ __metadata: concurrently: "npm:^8.2.1" cross-env: "npm:^7.0.3" css-loader: "npm:^6.8.1" + dotenv: "npm:^16.0.3" eslint: "npm:^8.49.0" eslint-config-prettier: "npm:^9.0.0" eslint-config-ts-react-important-stuff: "npm:^3.0.0" @@ -3496,6 +3498,17 @@ __metadata: languageName: node linkType: hard +"@playwright/test@npm:^1.30.0": + version: 1.40.1 + resolution: "@playwright/test@npm:1.40.1" + dependencies: + playwright: "npm:1.40.1" + bin: + playwright: cli.js + checksum: 77bfc3d4a101fd996309de3a67256117f671952764404727e520a4d512ba2e528d8f9e0b28ef9b2851664a651a5d002a0b05993e313077a2fa640bb430f38b25 + languageName: node + linkType: hard + "@pnpm/config.env-replace@npm:^1.1.0": version: 1.1.0 resolution: "@pnpm/config.env-replace@npm:1.1.0" @@ -8604,6 +8617,13 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^16.0.3": + version: 16.3.1 + resolution: "dotenv@npm:16.3.1" + checksum: dbb778237ef8750e9e3cd1473d3c8eaa9cc3600e33a75c0e36415d0fa0848197f56c3800f77924c70e7828f0b03896818cd52f785b07b9ad4d88dba73fbba83f + languageName: node + linkType: hard + "downshift@npm:8.1.0": version: 8.1.0 resolution: "downshift@npm:8.1.0" @@ -9916,7 +9936,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": +"fsevents@npm:2.3.2, fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": version: 2.3.2 resolution: "fsevents@npm:2.3.2" dependencies: @@ -9926,7 +9946,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": +"fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": version: 2.3.2 resolution: "fsevents@patch:fsevents@npm%3A2.3.2#optional!builtin::version=2.3.2&hash=df0bf1" dependencies: @@ -14146,6 +14166,30 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.40.1": + version: 1.40.1 + resolution: "playwright-core@npm:1.40.1" + bin: + playwright-core: cli.js + checksum: b8945a5eec68a2772be537219c81f74b8fbd1545650c908c41fdcb2b9eb40f488968d1fb59c61ca58afb923af1e390dd621bba3099521fcd3d9a63ef3645a203 + languageName: node + linkType: hard + +"playwright@npm:1.40.1": + version: 1.40.1 + resolution: "playwright@npm:1.40.1" + dependencies: + fsevents: "npm:2.3.2" + playwright-core: "npm:1.40.1" + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 95cf79f1574accbff18fac4b876aa3811640314ee74cf4cd1c249398cd49824e55dc664039342a18d2d2fa4f5ad460ce91a97cb15942ab5d71c8ab04f442dc32 + languageName: node + linkType: hard + "pngjs@npm:^3.0.0, pngjs@npm:^3.3.3": version: 3.4.0 resolution: "pngjs@npm:3.4.0" From 95398926b328443e7d91d6cc2f8571620135f3ec Mon Sep 17 00:00:00 2001 From: Randila Premarathne Date: Sun, 10 Dec 2023 18:35:22 +0530 Subject: [PATCH 2/2] Add files --- .github/workflows/e2e.yml | 63 +++++++++++++ e2e/.DS_Store | Bin 0 -> 6148 bytes e2e/README.md | 115 +++++++++++++++++++++++ e2e/core/global-setup.ts | 32 +++++++ e2e/core/index.ts | 1 + e2e/core/test.ts | 20 ++++ e2e/fixtures/api.ts | 26 +++++ e2e/fixtures/index.ts | 1 + e2e/pages/home-page.ts | 9 ++ e2e/pages/index.ts | 1 + e2e/specs/sample-test.spec.ts | 10 ++ e2e/support/github/Dockerfile | 34 +++++++ e2e/support/github/docker-compose.yml | 24 +++++ e2e/support/github/run-e2e-docker-env.sh | 49 ++++++++++ example.env | 6 ++ playwright.config.ts | 32 +++++++ 16 files changed, 423 insertions(+) create mode 100644 .github/workflows/e2e.yml create mode 100644 e2e/.DS_Store create mode 100644 e2e/README.md create mode 100644 e2e/core/global-setup.ts create mode 100644 e2e/core/index.ts create mode 100644 e2e/core/test.ts create mode 100644 e2e/fixtures/api.ts create mode 100644 e2e/fixtures/index.ts create mode 100644 e2e/pages/home-page.ts create mode 100644 e2e/pages/index.ts create mode 100644 e2e/specs/sample-test.spec.ts create mode 100644 e2e/support/github/Dockerfile create mode 100644 e2e/support/github/docker-compose.yml create mode 100644 e2e/support/github/run-e2e-docker-env.sh create mode 100644 example.env create mode 100644 playwright.config.ts diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 000000000..62dddab1c --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,63 @@ +name: E2E Tests + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + main: + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Copy test environment variables + run: cp example.env .env + + - name: Setup node + uses: actions/setup-node@v3 + with: + node-version: "16.x" + + - name: Cache dependencies + id: cache + uses: actions/cache@v3 + with: + path: '**/node_modules' + key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} + + - name: Install dependencies + if: steps.cache.outputs.cache-hit != 'true' + run: yarn install --immutable + + - name: Install Playwright Browsers + run: npx playwright install chromium --with-deps + + - name: Build apps + run: yarn turbo run build --color --concurrency=5 + + - name: Run dev server + run: bash e2e/support/github/run-e2e-docker-env.sh + + - name: Wait for OpenMRS instance to start + run: while [[ "$(curl -s -o /dev/null -w ''%{http_code}'' http://localhost:8080/openmrs/login.htm)" != "200" ]]; do sleep 10; done + + - name: Run E2E tests + run: yarn test-e2e + + - name: Stop dev server + if: "!cancelled()" + run: docker stop $(docker ps -a -q) + + - name: Upload report + uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 diff --git a/e2e/.DS_Store b/e2e/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..382de84b229851bc05f58701b31a01266f0d71df GIT binary patch literal 6148 zcmeHLy-EW?5T1>v22+?u30C_ErVs=XPKmt`I~$Gh4~!S00Xy#ndPgRU#^*Fh*mj3XJ_+a#pe} zHK39))@h&Gbg;KwZ|0&yLr@?n@Y@vNcehL%lu!pB=l$JCI$cAyGG7$aNg9pTUeaRU z>~rnmV(xmOIIjJzxb9B9ndQ_NiX!3FqfK5vMVBKCQ0Y*M!HQZzsv}7y13X z)10?VTeM3@bVz+dcC(&k`G+oxVq6}NF9ROAv0Of1#reE6^BSfuW@tOlsI=^RT`sRD zH>E2xH%@<-MRA0mUvwF!12EXctjG$VDKb7O`3GJ%|J}Kh--*a(r8vURuaSU8k-rZH zT|BKlI`p54=prBC@;IBAdOMzxXXC>-t`?t1`FyI(=dT;~Y_@X6V5oxvL4lyaKmlGK zGzw#EF*PVl2P!!N03$Su;ab*4pymc(Y%w*67MLzE*kvU;6y~?{^B{f&xK-f2Dwm8qLNcZprSg yxtrs?R->$;uyI^!P`aS9+p%2mR?Pn^h{31%0vKCN4Wb1Weh7#Rp$ZE8r~>bY)5~uF literal 0 HcmV?d00001 diff --git a/e2e/README.md b/e2e/README.md new file mode 100644 index 000000000..6dc4986f3 --- /dev/null +++ b/e2e/README.md @@ -0,0 +1,115 @@ +# E2E Tests + +This directory contains an E2E test suite using the [Playwright](https://playwright.dev) +framework. + +## Getting Started + +Please ensure that you have followed the basic installation guide in the +[root README](../README.md). +Once everything is set up, make sure the dev server is running by using: + +```sh +yarn start --sources 'packages/esm-*-app/' +``` +Then, in a separate terminal, run: + +```sh +yarn test-e2e --headed +``` + +By default, the test suite will run against the http://localhost:8080. +You can override this by exporting `E2E_BASE_URL` environment variables beforehand: + +```sh +# Ex: Set the server URL to dev3: +export E2E_BASE_URL=https://dev3.openmrs.org/openmrs + +# Run all e2e tests: +yarn test-e2e --headed +``` +To run a specific test by title: +```sh +yarn test-e2e --headed -g "title of the test" +``` +Check [this documentation](https://playwright.dev/docs/running-tests#command-line) for more running options. + +It is also highly recommended to install the companion VS Code extension: +https://playwright.dev/docs/getting-started-vscode + + +## Writing New Tests + +In general, it is recommended to read through the official [Playwright docs](https://playwright.dev/docs/intro) +before writing new test cases. The project uses the official Playwright test runner and, +generally, follows a very simple project structure: + +``` +e2e +|__ commands +| ^ Contains "commands" (simple reusable functions) that can be used in test cases/specs, +| e.g. generate a random patient. +|__ core +| ^ Contains code related to the test runner itself, e.g. setting up the custom fixtures. +| You probably need to touch this infrequently. +|__ fixtures +| ^ Contains fixtures (https://playwright.dev/docs/test-fixtures) which are used +| to run reusable setup/teardown tasks +|__ pages +| ^ Contains page object model classes for interacting with the frontend. +| See https://playwright.dev/docs/test-pom for details. +|__ specs +| ^ Contains the actual test cases/specs. New tests should be placed in this folder. +|__ support + ^ Contains support files that requires to run e2e tests, e.g. docker compose files. +``` + +When you want to write a new test case, start by creating a new spec in `./specs`. +Depending on what you want to achieve, you might want to create new fixtures and/or +page object models. To see examples, have a look at the existing code to see how these +different concepts play together. + +## Open reports from GitHub Actions / Bamboo + +To download the report from the GitHub action/Bamboo plan, follow these steps: + +1. Go to the artifact section of the action/plan and locate the report file. +2. Download the report file and unzip it using a tool of your choice. +3. Open the index.html file in a web browser to view the report. + +The report will show you a full summary of your tests, including information on which +tests passed, failed, were skipped, or were flaky. You can filter the report by browser +and explore the details of individual tests, including any errors or failures, video +recordings, and the steps involved in each test. Simply click on a test to view its details. + +## Debugging Tests + +Refer to [this documentation](https://playwright.dev/docs/debug) on how to debug a test. + +## Configuration + +This is very much underdeveloped/WIP. At the moment, there exists a (git-shared) `example.env` +file which can be used for configuring certain test attributes. This is most likely +about to change in the future. Stay tuned for updates! + + +## Github Action integration +The e2e.yml workflow is made up of two jobs: one for running on pull requests (PRs) and +one for running on commits. + +1. When running on PRs, the workflow will start the dev server, use dev3.openmrs.org as the backend, +and run tests only on chromium. This is done in order to quickly provide feedback to the developer. +The tests are designed to generate their own data and clean up after themselves once they are finished. +This ensures that the tests will have minimum effect from changes made to dev3 by other developers. +In the future, we plan to use a docker container to run the tests in an isolated environment once we +figure out a way to spin up the container within a small amount of time. +2. When running on commits, the workflow will spin up a docker container and run the dev server against +it in order to provide a known and isolated environment. In addition, tests will be run on multiple +browsers (chromium, firefox, and WebKit) to ensure compatibility. + +## Troubleshooting tips + +On MacOS, you might run into the following error: +```browserType.launch: Executable doesn't exist at /Users//Library/Caches/ms-playwright/chromium-1015/chrome-mac/Chromium.app/Contents/MacOS/Chromium``` +In order to fix this, you can attempt to force the browser reinstallation by running: +```PLAYWRIGHT_BROWSERS_PATH=/Users/$USER/Library/Caches/ms-playwright npx playwright install``` diff --git a/e2e/core/global-setup.ts b/e2e/core/global-setup.ts new file mode 100644 index 000000000..4238f7bb3 --- /dev/null +++ b/e2e/core/global-setup.ts @@ -0,0 +1,32 @@ +import { request } from '@playwright/test'; +import * as dotenv from 'dotenv'; + +dotenv.config(); + +/** + * This configuration is to reuse the signed-in state in the tests + * by log in only once using the API and then skip the log in step for all the tests. + * + * https://playwright.dev/docs/auth#reuse-signed-in-state + */ + +async function globalSetup() { + const requestContext = await request.newContext(); + const token = Buffer.from(`${process.env.E2E_USER_ADMIN_USERNAME}:${process.env.E2E_USER_ADMIN_PASSWORD}`).toString( + 'base64', + ); + await requestContext.post(`${process.env.E2E_BASE_URL}/ws/rest/v1/session`, { + data: { + sessionLocation: process.env.E2E_LOGIN_DEFAULT_LOCATION_UUID, + locale: 'en', + }, + headers: { + 'Content-Type': 'application/json', + Authorization: `Basic ${token}`, + }, + }); + await requestContext.storageState({ path: 'e2e/storageState.json' }); + await requestContext.dispose(); +} + +export default globalSetup; diff --git a/e2e/core/index.ts b/e2e/core/index.ts new file mode 100644 index 000000000..607718c2a --- /dev/null +++ b/e2e/core/index.ts @@ -0,0 +1 @@ +export * from './test'; diff --git a/e2e/core/test.ts b/e2e/core/test.ts new file mode 100644 index 000000000..dd3e40bb4 --- /dev/null +++ b/e2e/core/test.ts @@ -0,0 +1,20 @@ +import { APIRequestContext, Page, test as base } from '@playwright/test'; +import { api } from '../fixtures'; + +// This file sets up our custom test harness using the custom fixtures. +// See https://playwright.dev/docs/test-fixtures#creating-a-fixture for details. +// If a spec intends to use one of the custom fixtures, the special `test` function +// exported from this file must be used instead of the default `test` function +// provided by playwright. + +export interface CustomTestFixtures { + loginAsAdmin: Page; +} + +export interface CustomWorkerFixtures { + api: APIRequestContext; +} + +export const test = base.extend({ + api: [api, { scope: 'worker' }], +}); diff --git a/e2e/fixtures/api.ts b/e2e/fixtures/api.ts new file mode 100644 index 000000000..6afd8d59e --- /dev/null +++ b/e2e/fixtures/api.ts @@ -0,0 +1,26 @@ +import { APIRequestContext, PlaywrightWorkerArgs, WorkerFixture } from '@playwright/test'; + +/** + * A fixture which initializes an [`APIRequestContext`](https://playwright.dev/docs/api/class-apirequestcontext) + * that is bound to the configured OpenMRS API server. The context is automatically authenticated + * using the configured admin account. + * + * Use the request context like this: + * ```ts + * test('your test', async ({ api }) => { + * const res = await api.get('patient/1234'); + * await expect(res.ok()).toBeTruthy(); + * }); + * ``` + */ +export const api: WorkerFixture = async ({ playwright }, use) => { + const ctx = await playwright.request.newContext({ + baseURL: `${process.env.E2E_BASE_URL}/ws/rest/v1/`, + httpCredentials: { + username: process.env.E2E_USER_ADMIN_USERNAME, + password: process.env.E2E_USER_ADMIN_PASSWORD, + }, + }); + + await use(ctx); +}; diff --git a/e2e/fixtures/index.ts b/e2e/fixtures/index.ts new file mode 100644 index 000000000..b1c13e734 --- /dev/null +++ b/e2e/fixtures/index.ts @@ -0,0 +1 @@ +export * from './api'; diff --git a/e2e/pages/home-page.ts b/e2e/pages/home-page.ts new file mode 100644 index 000000000..94aa54847 --- /dev/null +++ b/e2e/pages/home-page.ts @@ -0,0 +1,9 @@ +import { Page } from '@playwright/test'; + +export class HomePage { + constructor(readonly page: Page) {} + + async goto() { + await this.page.goto(`home`); + } +} diff --git a/e2e/pages/index.ts b/e2e/pages/index.ts new file mode 100644 index 000000000..5778f2f1e --- /dev/null +++ b/e2e/pages/index.ts @@ -0,0 +1 @@ +export * from './home-page'; diff --git a/e2e/specs/sample-test.spec.ts b/e2e/specs/sample-test.spec.ts new file mode 100644 index 000000000..9335091d0 --- /dev/null +++ b/e2e/specs/sample-test.spec.ts @@ -0,0 +1,10 @@ +import { test, expect } from '@playwright/test'; +import { HomePage } from '../pages'; + +// This test is a sample E2E test. You can delete it. + +test('Sample test', async ({ page }) => { + const homePage = new HomePage(page); + await homePage.goto(); + await expect(homePage.page.getByRole('link', { name: 'Home' })).toBeVisible(); +}); diff --git a/e2e/support/github/Dockerfile b/e2e/support/github/Dockerfile new file mode 100644 index 000000000..682360321 --- /dev/null +++ b/e2e/support/github/Dockerfile @@ -0,0 +1,34 @@ +# syntax=docker/dockerfile:1.3 +FROM --platform=$BUILDPLATFORM node:18-alpine as dev + +ARG APP_SHELL_VERSION=next + +RUN mkdir -p /app +WORKDIR /app + +COPY . . + +RUN npm_config_legacy_peer_deps=true npm install -g openmrs@${APP_SHELL_VERSION:-next} +ARG CACHE_BUST +RUN npm_config_legacy_peer_deps=true openmrs assemble --manifest --mode config --config spa-assemble-config.json --target ./spa + +FROM --platform=$BUILDPLATFORM openmrs/openmrs-reference-application-3-frontend:nightly as frontend +FROM nginx:1.23-alpine + +RUN apk update && \ + apk upgrade && \ + # add more utils for sponge to support our startup script + apk add --no-cache moreutils + +# clear any default files installed by nginx +RUN rm -rf /usr/share/nginx/html/* + +COPY --from=frontend /etc/nginx/nginx.conf /etc/nginx/nginx.conf +# this assumes that NOTHING in the framework is in a subdirectory +COPY --from=frontend /usr/share/nginx/html/* /usr/share/nginx/html/ +COPY --from=frontend /usr/local/bin/startup.sh /usr/local/bin/startup.sh +RUN chmod +x /usr/local/bin/startup.sh + +COPY --from=dev /app/spa/ /usr/share/nginx/html/ + +CMD ["/usr/local/bin/startup.sh"] diff --git a/e2e/support/github/docker-compose.yml b/e2e/support/github/docker-compose.yml new file mode 100644 index 000000000..6a8297642 --- /dev/null +++ b/e2e/support/github/docker-compose.yml @@ -0,0 +1,24 @@ +# This docker compose file is used to create a backend environment for the e2e.yml workflow. +version: "3.7" + +services: + gateway: + image: openmrs/openmrs-reference-application-3-gateway:${TAG:-nightly} + ports: + - "8080:80" + + frontend: + build: + context: . + environment: + SPA_PATH: /openmrs/spa + API_URL: /openmrs + + backend: + image: openmrs/openmrs-reference-application-3-backend:nightly-with-data + depends_on: + - db + + # MariaDB + db: + image: openmrs/openmrs-reference-application-3-db:nightly-with-data diff --git a/e2e/support/github/run-e2e-docker-env.sh b/e2e/support/github/run-e2e-docker-env.sh new file mode 100644 index 000000000..ffcce967e --- /dev/null +++ b/e2e/support/github/run-e2e-docker-env.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash -eu + +# get the dir containing the script +script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +# create a temporary working directory +working_dir=$(mktemp -d "${TMPDIR:-/tmp/}openmrs-e2e-frontends.XXXXXXXXXX") +# get a list of all the apps in this workspace +apps=$(yarn workspaces list --json | jq -r 'if ((.location == ".") or (.location | test("-app") | not)) then halt else .name end') +# this array will hold all of the packed app names +app_names=() + +echo "Creating packed archives of apps..." +# for each app +for app in $apps +do + # @openmrs/esm-whatever -> _openmrs_esm_whatever + app_name=$(echo "$app" | tr '[:punct:]' '_'); + # add to our array + app_names+=("$app_name.tgz"); + # run yarn pack for our app and add it to the working directory + yarn workspace "$app" pack -o "$working_dir/$app_name.tgz" >/dev/null; +done; +echo "Created packed app archives" + +echo "Creating dynamic spa-assemble-config.json..." +# dynamically assemble our list of frontend modules, prepending the login app and +# primary navigation apps; apps will all be in the /app directory of the Docker +# container +jq -n \ + --arg apps "$apps" \ + --arg app_names "$(echo ${app_names[@]})" \ + '{"@openmrs/esm-primary-navigation-app": "next", "@openmrs/esm-home-app": "next"} + ( + ($apps | split("\n")) as $apps | ($app_names | split(" ") | map("/app/" + .)) as $app_files + | [$apps, $app_files] + | transpose + | map({"key": .[0], "value": .[1]}) + | from_entries + )' | jq '{"frontendModules": .}' > "$working_dir/spa-assemble-config.json" +echo "Created dynamic spa-assemble-config.json" + +echo "Copying Docker configuration..." +cp "$script_dir/Dockerfile" "$working_dir/Dockerfile" +cp "$script_dir/docker-compose.yml" "$working_dir/docker-compose.yml" + +cd $working_dir +echo "Starting Docker containers..." +# CACHE_BUST to ensure the assemble step is always run +docker compose build --build-arg CACHE_BUST=$(date +%s) frontend +docker compose up -d diff --git a/example.env b/example.env new file mode 100644 index 000000000..e1bb001ab --- /dev/null +++ b/example.env @@ -0,0 +1,6 @@ +# This is an example environment file for configuring dynamic values. +E2E_BASE_URL=http://localhost:8080/openmrs +E2E_USER_ADMIN_USERNAME=admin +E2E_USER_ADMIN_PASSWORD=Admin123 +E2E_LOGIN_DEFAULT_LOCATION_UUID=44c3efb0-2583-4c80-a79e-1f756a03c0a1 +# The above location UUID is for the "Outpatient Clinic" location in the reference application diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 000000000..d61b8cd27 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,32 @@ +import { devices, PlaywrightTestConfig } from '@playwright/test'; +import * as dotenv from 'dotenv'; +dotenv.config(); + +// See https://playwright.dev/docs/test-configuration. +const config: PlaywrightTestConfig = { + testDir: './e2e/specs', + timeout: 3 * 60 * 1000, + expect: { + timeout: 40 * 1000, + }, + fullyParallel: true, + forbidOnly: !!process.env.CI, + retries: 0, + reporter: process.env.CI ? [['junit', { outputFile: 'results.xml' }], ['html']] : [['html']], + globalSetup: require.resolve('./e2e/core/global-setup'), + use: { + baseURL: `${process.env.E2E_BASE_URL}/spa/`, + storageState: 'e2e/storageState.json', + video: 'retain-on-failure', + }, + projects: [ + { + name: 'chromium', + use: { + ...devices['Desktop Chrome'], + }, + }, + ], +}; + +export default config;