From 2ae7bd3b359c3720d61efe13d28ba10b6170a0c2 Mon Sep 17 00:00:00 2001 From: Lucy Jemutai <130601439+lucyjemutai@users.noreply.github.com> Date: Fri, 22 Nov 2024 11:53:52 +0300 Subject: [PATCH] (test) O3-2902: Setup playwright for automated tests in Stock Management (#231) --- .eslintrc | 10 +- .github/workflows/e2e.yml | 102 ++++++++++++++++++++ .github/workflows/node.js.yml | 2 + .gitignore | 6 ++ e2e/README.md | 117 +++++++++++++++++++++++ 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/chart-page.ts | 11 +++ e2e/pages/home-page.ts | 9 ++ e2e/pages/index.ts | 2 + e2e/specs/stock-overview-test.spec.ts | 19 ++++ e2e/support/github/Dockerfile | 34 +++++++ e2e/support/github/docker-compose.yml | 24 +++++ e2e/support/github/run-e2e-docker-env.sh | 49 ++++++++++ example.env | 6 ++ jest.config.js | 6 +- package.json | 5 +- playwright.config.ts | 34 +++++++ yarn.lock | 63 ++++++++++++ 22 files changed, 576 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/e2e.yml 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/chart-page.ts create mode 100644 e2e/pages/home-page.ts create mode 100644 e2e/pages/index.ts create mode 100644 e2e/specs/stock-overview-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/.eslintrc b/.eslintrc index 8987e825..f60dd60a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -48,5 +48,13 @@ ] } ] - } + }, + "overrides": [ + { + "files": ["e2e/**/*.spec.ts"], + "rules": { + "testing-library/prefer-screen-queries": "off" + } + } + ] } diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml new file mode 100644 index 00000000..9bb0e398 --- /dev/null +++ b/.github/workflows/e2e.yml @@ -0,0 +1,102 @@ +name: E2E Tests + +on: + push: + branches: + - main + pull_request: + branches: + - main + +env: + TURBO_API: 'http://127.0.0.1:9080' + TURBO_TOKEN: 'turbo-token' + TURBO_TEAM: ${{ github.repository_owner }} + +jobs: + run_e2e_tests: + runs-on: ubuntu-latest + steps: + - name: ๐Ÿ“ฅ Checkout repo + uses: actions/checkout@v4 + + - name: ๐Ÿ“ Copy test environment variables + run: cp example.env .env + + - name: ๐Ÿ› ๏ธ Setup node + uses: actions/setup-node@v4 + with: + node-version: 18 + + - name: ๐Ÿ’พ Cache dependencies + id: cache-dependencies + uses: actions/cache@v4 + with: + path: '**/node_modules' + key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} + + - name: ๐Ÿ“ฆ Install dependencies + if: steps.cache-dependencies.outputs.cache-hit != 'true' + run: yarn install --immutable + + - name: ๐ŸŽญ Get installed Playwright version + id: playwright-version + run: echo "PLAYWRIGHT_VERSION=$(grep '@playwright/test@' yarn.lock | sed -n 's/.*npm:\([^":]*\).*/\1/p' | head -n 1)" >> $GITHUB_ENV + + - name: ๐Ÿ’พ Cache Playwright binaries + id: playwright-cache + uses: actions/cache@v4 + with: + path: | + ~/.cache/ms-playwright + key: ${{ runner.os }}-playwright-${{ env.PLAYWRIGHT_VERSION }} + + - name: ๐ŸŽญ Install Playwright Browsers + run: npx playwright install chromium --with-deps + if: steps.playwright-cache.outputs.cache-hit != 'true' + + - name: ๐Ÿš€ Setup local cache server for Turborepo + uses: felixmosh/turborepo-gh-artifacts@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + server-token: ${{ env.TURBO_TOKEN }} + + - 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@v4 + if: '!cancelled()' + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 + overwrite: true + + - name: ๐Ÿ“ Capture Server Logs + if: always() + uses: jwalton/gh-docker-logs@v2 + with: + dest: './logs' + + - name: ๐Ÿ“ค Upload Logs as Artifact + uses: actions/upload-artifact@v4 + if: always() + with: + name: server-logs + path: './logs' + retention-days: 2 + overwrite: true diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index d3b2b8e3..499ebe93 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -54,6 +54,8 @@ jobs: dist overwrite: true + + pre_release: runs-on: ubuntu-latest needs: build diff --git a/.gitignore b/.gitignore index 3617d0b9..3ccee9e0 100644 --- a/.gitignore +++ b/.gitignore @@ -80,6 +80,12 @@ dist/ !.yarn/sdks !.yarn/versions +# Playwright and e2e tests +/test-results/ +/playwright-report/ +/playwright/.cache/ +e2e/storageState.json + # Turborepo .turbo /*.idea/ diff --git a/e2e/README.md b/e2e/README.md new file mode 100644 index 00000000..32a0d90c --- /dev/null +++ b/e2e/README.md @@ -0,0 +1,117 @@ +# 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 +``` + +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: + +```sh +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) `.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 Actions 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 00000000..74897499 --- /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: { + Accept: '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 00000000..607718c2 --- /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 00000000..dd3e40bb --- /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 00000000..6afd8d59 --- /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 00000000..b1c13e73 --- /dev/null +++ b/e2e/fixtures/index.ts @@ -0,0 +1 @@ +export * from './api'; diff --git a/e2e/pages/chart-page.ts b/e2e/pages/chart-page.ts new file mode 100644 index 00000000..cd5191a4 --- /dev/null +++ b/e2e/pages/chart-page.ts @@ -0,0 +1,11 @@ +import { type Page } from '@playwright/test'; + +export class ChartPage { + constructor(readonly page: Page) {} + + readonly formsTable = () => this.page.getByRole('table', { name: /forms/i }); + + async goTo(patientUuid: string) { + await this.page.goto('/openmrs/spa/patient/' + patientUuid + '/chart'); + } +} diff --git a/e2e/pages/home-page.ts b/e2e/pages/home-page.ts new file mode 100644 index 00000000..37f4fe8a --- /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 gotoHome() { + await this.page.goto('/openmrs/spa/login'); + } +} diff --git a/e2e/pages/index.ts b/e2e/pages/index.ts new file mode 100644 index 00000000..4be01a0d --- /dev/null +++ b/e2e/pages/index.ts @@ -0,0 +1,2 @@ +export * from './home-page'; +export * from './chart-page'; diff --git a/e2e/specs/stock-overview-test.spec.ts b/e2e/specs/stock-overview-test.spec.ts new file mode 100644 index 00000000..e938717e --- /dev/null +++ b/e2e/specs/stock-overview-test.spec.ts @@ -0,0 +1,19 @@ +import { test, expect } from '@playwright/test'; +import dotenv from 'dotenv'; +import { HomePage } from '../pages'; + +dotenv.config(); +//This is a sample test which can be deleted +test.describe('Overview Page Test', () => { + test('should navigate to the Overview page and verify sections', async ({ page }) => { + const homePage = new HomePage(page); + + await test.step('When I visit the home page', async () => { + await homePage.gotoHome(); + }); + + await test.step('Then I should be at the home page', async () => { + await expect(page).toHaveURL(`${process.env.E2E_BASE_URL}spa/login`); + }); + }); +}); diff --git a/e2e/support/github/Dockerfile b/e2e/support/github/Dockerfile new file mode 100644 index 00000000..68236032 --- /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 00000000..6a829764 --- /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 00000000..8ea68c5c --- /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("form-engine-app")) 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 00000000..f9d05699 --- /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/jest.config.js b/jest.config.js index 5b3017cc..08ac9a1c 100644 --- a/jest.config.js +++ b/jest.config.js @@ -5,7 +5,7 @@ const path = require('path'); module.exports = { clearMocks: true, - collectCoverageFrom: ['**/src/**/*.component.tsx', '!**/node_modules/**', '!**/src/declarations.d.ts'], + collectCoverageFrom: ['**/src/**/*.component.tsx', '!**/node_modules/**', '!**/src/declarations.d.ts', '!**/e2e/**'], transform: { '^.+\\.tsx?$': ['@swc/jest'], }, @@ -23,4 +23,8 @@ module.exports = { testEnvironmentOptions: { url: 'http://localhost/', }, + testPathIgnorePatterns: [ + "/node_modules/", + "/e2e/" // Ignore the e2e directory containing Playwright tests + ] }; diff --git a/package.json b/package.json index 13899536..88e7be22 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "coverage": "yarn test --coverage", "prepare": "husky install", "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.tsx' --config ./i18next-parser.config.js", - "postinstall": "husky" + "postinstall": "husky", + "test-e2e": "playwright test" }, "browserslist": [ "extends browserslist-config-openmrs" @@ -43,6 +44,8 @@ "dependencies": { "@carbon/react": "^1.33.1", "@hookform/resolvers": "^3.3.0", + "@playwright/test": "^1.48.0", + "dotenv": "^16.4.5", "file-saver": "^2.0.5", "lodash-es": "^4.17.21", "react-hook-form": "^7.45.4", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 00000000..d9041080 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,34 @@ +import { devices, type PlaywrightTestConfig } from '@playwright/test'; +import { config as dotenvConfig } from 'dotenv'; +import { resolve } from 'node:path'; +dotenvConfig({ path: resolve(process.cwd(), '.env') }); +dotenvConfig(); + +// 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/stock-management`, + storageState: 'e2e/storageState.json', + video: 'retain-on-failure', + }, + projects: [ + { + name: 'chromium', + use: { + ...devices['Desktop Chrome'], + }, + }, + ], +}; + +export default config; diff --git a/yarn.lock b/yarn.lock index 3d87a7cc..3e7b87f4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4145,6 +4145,7 @@ __metadata: "@hookform/resolvers": "npm:^3.3.0" "@openmrs/esm-framework": "npm:next" "@openmrs/esm-styleguide": "npm:next" + "@playwright/test": "npm:^1.48.0" "@swc/cli": "npm:^0.1.62" "@swc/core": "npm:^1.3.68" "@swc/jest": "npm:^0.2.26" @@ -4164,6 +4165,7 @@ __metadata: cross-env: "npm:^7.0.3" css-loader: "npm:^6.8.1" dayjs: "npm:^1.11.9" + dotenv: "npm:^16.4.5" eslint: "npm:^8.44.0" eslint-plugin-react-hooks: "npm:^4.6.2" eslint-plugin-testing-library: "npm:^6.3.0" @@ -4317,6 +4319,17 @@ __metadata: languageName: node linkType: hard +"@playwright/test@npm:^1.48.0": + version: 1.48.0 + resolution: "@playwright/test@npm:1.48.0" + dependencies: + playwright: "npm:1.48.0" + bin: + playwright: cli.js + checksum: 10/8845ed0f0b303e10ee0a0f04562ef83be3f9123fac91d722f697ad964a119af74cd5fb08e1139f1b20b27396479456c984bfdc699fadedd92af9c0490fb4c7c0 + 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" @@ -12016,6 +12029,13 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:^16.4.5": + version: 16.4.5 + resolution: "dotenv@npm:16.4.5" + checksum: 10/55a3134601115194ae0f924e54473459ed0d9fc340ae610b676e248cca45aa7c680d86365318ea964e6da4e2ea80c4514c1adab5adb43d6867fb57ff068f95c8 + languageName: node + linkType: hard + "downshift@npm:8.1.0": version: 8.1.0 resolution: "downshift@npm:8.1.0" @@ -13664,6 +13684,16 @@ __metadata: languageName: node linkType: hard +"fsevents@npm:2.3.2": + version: 2.3.2 + resolution: "fsevents@npm:2.3.2" + dependencies: + node-gyp: "npm:latest" + checksum: 10/6b5b6f5692372446ff81cf9501c76e3e0459a4852b3b5f1fc72c103198c125a6b8c72f5f166bdd76ffb2fca261e7f6ee5565daf80dca6e571e55bcc589cc1256 + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": version: 2.3.3 resolution: "fsevents@npm:2.3.3" @@ -13674,6 +13704,15 @@ __metadata: languageName: node linkType: hard +"fsevents@patch:fsevents@npm%3A2.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: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" @@ -19727,6 +19766,30 @@ __metadata: languageName: node linkType: hard +"playwright-core@npm:1.48.0": + version: 1.48.0 + resolution: "playwright-core@npm:1.48.0" + bin: + playwright-core: cli.js + checksum: 10/644489b4de9cc181e83eb639a283d3c4f8e4c3b1b1759d7c93b72fd0373b5a66ba376ee6a5ee3eca67f1b773bf15c5e01b6aeedd43c94c355bf4fc0d110713bc + languageName: node + linkType: hard + +"playwright@npm:1.48.0": + version: 1.48.0 + resolution: "playwright@npm:1.48.0" + dependencies: + fsevents: "npm:2.3.2" + playwright-core: "npm:1.48.0" + dependenciesMeta: + fsevents: + optional: true + bin: + playwright: cli.js + checksum: 10/85b06ae8d0ab7a5a8c9a0d416007b18f35a59455fad40438bda98cbe07c48f338e97b98b1d9214e27f08d6ac284eba0eaab722f5684cd17dd4a47f5b69d004b9 + languageName: node + linkType: hard + "pngjs@npm:^3.0.0, pngjs@npm:^3.3.3": version: 3.4.0 resolution: "pngjs@npm:3.4.0"