forked from opencrvs/opencrvs-countryconfig
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add some initial structure for test cases (#989)
* add some initial structure for test cases * convert fetch to xhr file to typescript * add tooling for manipulating redux directly * use playwright to run e2e * make tests run in parallel * debug * remove debug * allow empty test directories * add temporary build trigger from this branch * disable rate limiting in development * implement technical helper for logging in * also build docker image temporarily from this branch * add new branch prefix e2e/ for triggering pipelines * add example of birth event test creation * add a new plain e2e pipeline that triggers from e2e/ branches * update e2e command to use playwright * update commands to deprecate cypress
- Loading branch information
Showing
20 changed files
with
448 additions
and
38 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
name: E2E | ||
name: Deploy & run E2E | ||
run-name: Deploy to ${{ github.event.inputs.environment }} and E2E | ||
on: | ||
repository_dispatch: | ||
|
@@ -30,6 +30,7 @@ concurrency: | |
|
||
jobs: | ||
get-core-commit: | ||
name: Resolve latest core tag | ||
runs-on: ubuntu-latest | ||
outputs: | ||
latest_commit_sha: ${{ steps.get_latest_commit.outputs.commit_sha }} | ||
|
@@ -46,6 +47,7 @@ jobs: | |
run: echo "::set-output name=commit_sha::$(git rev-parse HEAD | cut -c 1-7)" | ||
|
||
get-country-config-commit: | ||
name: Resolve latest Farajaland tag | ||
runs-on: ubuntu-latest | ||
needs: get-core-commit | ||
outputs: | ||
|
@@ -69,33 +71,63 @@ jobs: | |
reset: 'true' | ||
secrets: inherit | ||
|
||
discover-tests: | ||
name: Discover test directories | ||
runs-on: ubuntu-22.04 | ||
outputs: | ||
test_matrix: ${{ steps.list-tests.outputs.test_matrix }} | ||
steps: | ||
- name: Check out code | ||
uses: actions/checkout@v4 | ||
|
||
- name: List Test Directories | ||
id: list-tests | ||
run: | | ||
test_dirs=$(find ./e2e/testcases -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | jq -R -s -c 'split("\n")[:-1]') | ||
echo "Test directories: $test_dirs" | ||
echo "test_matrix=$test_dirs" >> $GITHUB_OUTPUT | ||
echo "test_matrix=$test_dirs" | ||
test: | ||
needs: deploy | ||
runs-on: ubuntu-20.04 | ||
needs: [deploy, discover-tests] | ||
runs-on: ubuntu-22.04 | ||
environment: ${{ github.event.inputs.environment || 'development' }} | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
test_dir: ${{ fromJson(needs.discover-tests.outputs.test_matrix) }} | ||
steps: | ||
- name: Checking out git repo | ||
uses: actions/checkout@v2 | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-node@v4 | ||
with: | ||
fetch-depth: 1 | ||
node-version: 18 | ||
|
||
- name: Use Node.js 18.19 | ||
uses: actions/setup-node@v2 | ||
with: | ||
node-version: '18.19' | ||
cache: 'npm' | ||
- name: Check for Spec Files | ||
id: check-specs | ||
run: | | ||
if ls ./e2e/testcases/${{ matrix.test_dir }}/*.spec.ts > /dev/null 2>&1; then | ||
echo "::set-output name=has_spec_files::true" | ||
else | ||
echo "::set-output name=has_spec_files::false" | ||
fi | ||
- name: Runs dependency installation | ||
- name: Install Dependencies | ||
if: steps.check-specs.outputs.has_spec_files == 'true' | ||
run: yarn | ||
|
||
- name: Run tests | ||
uses: cypress-io/[email protected] | ||
- name: Install Playwright Browsers | ||
if: steps.check-specs.outputs.has_spec_files == 'true' | ||
run: npx playwright install --with-deps | ||
|
||
- name: Run Playwright Tests | ||
if: steps.check-specs.outputs.has_spec_files == 'true' | ||
run: npx playwright test ./e2e/testcases/${{ matrix.test_dir }} | ||
env: | ||
CYPRESS_RECORD_KEY: '${{ secrets.CYPRESS_RECORD_KEY }}' | ||
CYPRESS_COUNTRYCONFIG_URL: 'https://countryconfig.${{ vars.DOMAIN }}/' | ||
CYPRESS_GATEWAY_URL: 'https://gateway.${{ vars.DOMAIN }}/' | ||
CYPRESS_LOGIN_URL: 'https://login.${{ vars.DOMAIN }}/' | ||
CYPRESS_CLIENT_URL: 'https://register.${{ vars.DOMAIN }}/' | ||
CYPRESS_AUTH_URL: 'https://auth.${{ vars.DOMAIN }}/' | ||
DOMAIN: '${{ vars.DOMAIN }}' | ||
|
||
- uses: actions/upload-artifact@v4 | ||
if: steps.check-specs.outputs.has_spec_files == 'true' | ||
with: | ||
record: true | ||
name: playwright-report-${{ matrix.test_dir }} | ||
path: playwright-report/ | ||
retention-days: 30 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
name: E2E | ||
run-name: Deploy to ${{ github.event.inputs.environment }} and E2E | ||
on: | ||
push: | ||
branches: | ||
- e2e/* | ||
workflow_dispatch: | ||
inputs: | ||
environment: | ||
type: choice | ||
description: Environment to deploy to | ||
required: true | ||
default: 'development' | ||
options: | ||
- development | ||
|
||
jobs: | ||
discover-tests: | ||
name: Discover test directories | ||
runs-on: ubuntu-22.04 | ||
outputs: | ||
test_matrix: ${{ steps.list-tests.outputs.test_matrix }} | ||
steps: | ||
- name: Check out code | ||
uses: actions/checkout@v4 | ||
|
||
- name: List Test Directories | ||
id: list-tests | ||
run: | | ||
test_dirs=$(find ./e2e/testcases -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | jq -R -s -c 'split("\n")[:-1]') | ||
echo "Test directories: $test_dirs" | ||
echo "test_matrix=$test_dirs" >> $GITHUB_OUTPUT | ||
echo "test_matrix=$test_dirs" | ||
test: | ||
needs: [discover-tests] | ||
runs-on: ubuntu-22.04 | ||
environment: ${{ github.event.inputs.environment || 'development' }} | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
test_dir: ${{ fromJson(needs.discover-tests.outputs.test_matrix) }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: actions/setup-node@v4 | ||
with: | ||
node-version: 18 | ||
|
||
- name: Check for Spec Files | ||
id: check-specs | ||
run: | | ||
if ls ./e2e/testcases/${{ matrix.test_dir }}/*.spec.ts > /dev/null 2>&1; then | ||
echo "::set-output name=has_spec_files::true" | ||
else | ||
echo "::set-output name=has_spec_files::false" | ||
fi | ||
- name: Install Dependencies | ||
if: steps.check-specs.outputs.has_spec_files == 'true' | ||
run: yarn | ||
|
||
- name: Install Playwright Browsers | ||
if: steps.check-specs.outputs.has_spec_files == 'true' | ||
run: npx playwright install --with-deps | ||
|
||
- name: Run Playwright Tests | ||
if: steps.check-specs.outputs.has_spec_files == 'true' | ||
run: npx playwright test ./e2e/testcases/${{ matrix.test_dir }} | ||
env: | ||
DOMAIN: '${{ vars.DOMAIN }}' | ||
|
||
- uses: actions/upload-artifact@v4 | ||
if: steps.check-specs.outputs.has_spec_files == 'true' | ||
with: | ||
name: playwright-report-${{ matrix.test_dir }} | ||
path: playwright-report/ | ||
retention-days: 30 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ on: | |
- master | ||
- develop | ||
- main | ||
- e2e/* | ||
workflow_dispatch: | ||
inputs: | ||
branch_name: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export const DOMAIN = process.env.DOMAIN || 'farajaland-dev.opencrvs.org' | ||
export const LOGIN_URL = 'https://login.' + DOMAIN | ||
export const AUTH_URL = 'https://auth.' + DOMAIN | ||
export const CLIENT_URL = 'https://register.' + DOMAIN |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { Page, expect } from '@playwright/test' | ||
import { AUTH_URL, CLIENT_URL } from './constants' | ||
type Store = { | ||
getState: () => any | ||
dispatch: (action: any) => void | ||
} | ||
|
||
export function dispatchAction(page: Page, reduxAction: any) { | ||
return page.evaluate<Store>((reduxAction) => { | ||
const root = window.document.getElementById('root')! | ||
const container = Object.entries(root).find(([x]) => | ||
x.includes('reactContainer') | ||
)![1] | ||
|
||
if (!container) { | ||
throw new Error('React container not found') | ||
} | ||
|
||
const store = container.memoizedState?.element?.props?.store | ||
|
||
if (!store) { | ||
throw new Error('Redux store not found') | ||
} | ||
|
||
store.dispatch(reduxAction) | ||
return store | ||
}, reduxAction) | ||
} | ||
|
||
export async function login(page: Page, username: string, password: string) { | ||
const token = await getToken(username, password) | ||
await page.goto(`${CLIENT_URL}?token=${token}`) | ||
await expect(page.locator('#appSpinner')).toBeVisible() | ||
} | ||
|
||
export async function createPIN(page: Page) { | ||
await page.click('#pin-input') | ||
for (let i = 1; i <= 8; i++) { | ||
await page.type('#pin-input', `${i % 2}`) | ||
} | ||
} | ||
|
||
async function getToken(username: string, password: string) { | ||
const authUrl = `${AUTH_URL}/authenticate` | ||
const verifyUrl = `${AUTH_URL}/verifyCode` | ||
|
||
const authResponse = await fetch(authUrl, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json' | ||
}, | ||
body: JSON.stringify({ | ||
username: username, | ||
password: password | ||
}) | ||
}) | ||
|
||
const authBody = await authResponse.json() | ||
const verifyResponse = await fetch(verifyUrl, { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json' | ||
}, | ||
body: JSON.stringify({ | ||
nonce: authBody.nonce, | ||
code: '000000' | ||
}) | ||
}) | ||
|
||
const verifyBody = await verifyResponse.json() | ||
return verifyBody.token | ||
} |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { expect, test } from '@playwright/test' | ||
import { createPIN, login } from '../../helpers' | ||
|
||
test.describe('1. Birth event declaration', () => { | ||
test.beforeEach(async ({ page }) => { | ||
await login(page, 'k.mweene', 'test') | ||
await createPIN(page) | ||
}) | ||
|
||
test('1.1. Navigate to the birth event declaration page', async ({ | ||
page | ||
}) => { | ||
await page.click('#header_new_event') | ||
await page.waitForSelector('#continue') | ||
}) | ||
|
||
test('1.2. Validate event selection page', async ({ page }) => { | ||
await page.click('#header_new_event') | ||
|
||
await test.step('1.2.1 Validate the contents of the event type page', async () => { | ||
/* | ||
* Expected result: should show | ||
* - Radio buttons of the events | ||
* - Continue button | ||
* - Exit button | ||
*/ | ||
await expect(page.locator('#select_birth_event')).toBeVisible() | ||
await expect(page.locator('#select_death_event')).toBeVisible() | ||
await expect(page.locator('#select_marriage_event')).toBeVisible() | ||
await expect(page.locator('#goBack')).toBeVisible() | ||
await expect(page.locator('#continue')).toBeVisible() | ||
}) | ||
|
||
await test.step('1.2.2 Click the "Continue" button without selecting any event', async () => { | ||
await page.click('#continue') | ||
/* | ||
* Expected result: should throw an error as below: | ||
* "Please select the type of event" | ||
*/ | ||
await expect(page.locator('#require-error')).toBeVisible() | ||
}) | ||
|
||
await test.step('1.2.3 Select the "Birth" event and click "Continue" button', async () => { | ||
await page.click('#select_birth_event') | ||
await page.click('#continue') | ||
/* | ||
* Expected result: User should navigate to the "Introduction" page | ||
*/ | ||
await expect( | ||
page.locator('#form_section_id_information-group') | ||
).toBeVisible() | ||
}) | ||
}) | ||
}) |
Empty file.
Oops, something went wrong.