Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 14 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,17 @@ jobs:
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID || '' }}
AZURE_SUBSCRIPTION: ${{ secrets.AZURE_SUBSCRIPTION_ID || '' }}
AZURE_ACA_CLIENT_ID: ${{ secrets.ACA_CLIENT_ID || '' }}

playwright-tests:
name: Run Playwright Tests
needs: [set-env, build-import-deploy]
if: |
endsWith(needs.set-env.outputs.environment, '-development') ||
endsWith(needs.set-env.outputs.environment, '-test')
uses: ./.github/workflows/playwright-tests.yml
with:
application: ${{ needs.set-env.outputs.application }}
environment: ${{ needs.set-env.outputs.environment }}
secrets:
SERVICE_API_KEY: ${{ secrets.SERVICE_API_KEY }}
TEAMS_WEBHOOK_URL: ${{ secrets.TEAMS_WEBHOOK_URL }}
30 changes: 30 additions & 0 deletions .github/workflows/playwright-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Playwright test linting

on:
pull_request:
paths:
- src/Tests/DfE.ExternalApplications.PlaywrightTests/**
types: [ opened, synchronize ]

jobs:
lint:
runs-on: ubuntu-latest
defaults:
run:
working-directory: src/Tests/DfE.ExternalApplications.PlaywrightTests
steps:
- name: Checkout code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4

- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
cache: npm
cache-dependency-path: src/Tests/DfE.ExternalApplications.PlaywrightTests/package-lock.json

- name: Lint and format check
run: |
npm ci --ignore-scripts
npm run lint
npm run format:check
77 changes: 77 additions & 0 deletions .github/workflows/playwright-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: Playwright UI Tests

on:
workflow_call:
inputs:
application:
required: true
type: string
environment:
required: true
type: string
secrets:
SERVICE_API_KEY:
required: false
TEAMS_WEBHOOK_URL:
required: true

concurrency:
group: ${{ github.workflow }}-${{ inputs.application }}-${{ inputs.environment }}

jobs:
playwright-tests:
name: Run Playwright Tests
timeout-minutes: 20
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
defaults:
run:
working-directory: src/Tests/DfE.ExternalApplications.PlaywrightTests
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
ref: ${{ github.ref }}

- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: 22
cache: npm
cache-dependency-path: src/Tests/DfE.ExternalApplications.PlaywrightTests/package-lock.json

- name: Install dependencies
run: npm ci --ignore-scripts

- name: Install Playwright browsers
run: npx playwright install --with-deps chromium

- name: Run tests
env:
SERVICE: ${{ inputs.application }}
ENVIRONMENT: ${{ inputs.environment }}
SERVICE_API_KEY: ${{ secrets.SERVICE_API_KEY }}
run: npm run pl:run

- name: Upload test results
if: ${{ failure() }}
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: test-results-${{ inputs.environment }}
path: src/Tests/DfE.ExternalApplications.PlaywrightTests/test-results

- name: Upload report
if: always()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: reports-${{ inputs.environment }}
path: |
src/Tests/DfE.ExternalApplications.PlaywrightTests/playwright-report
src/Tests/DfE.ExternalApplications.PlaywrightTests/reports

- name: Report results to Teams
if: always()
run: node scripts/send-teams-notification.js
env:
TEAMS_WEBHOOK_URL: ${{ secrets.TEAMS_WEBHOOK_URL }}
ENVIRONMENT: ${{ inputs.environment }}
INFORMATION_LINK: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SERVICE_API_KEY=
12 changes: 12 additions & 0 deletions src/Tests/DfE.ExternalApplications.PlaywrightTests/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Environment variables
.env
!.env.example

# Playwright
node_modules/
/test-results/
/playwright-report/
/reports/
/blob-report/
/playwright/.cache/
/playwright/.auth/
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
playwright-report/
test-results/
reports/
package-lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 120
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const eslint = require('@eslint/js');
const { defineConfig, globalIgnores } = require('eslint/config');
const tseslint = require('typescript-eslint');
const playwright = require('eslint-plugin-playwright');
const eslintConfigPrettier = require('eslint-config-prettier');
const globals = require('globals');

module.exports = defineConfig(
globalIgnores(['node_modules/', 'playwright-report/', 'test-results/', 'reports/', 'eslint.config.cjs']),
eslint.configs.recommended,
...tseslint.configs.recommended,
eslintConfigPrettier,
{
files: ['tests/**/*.ts', 'fixtures/**/*.ts'],
extends: [playwright.configs['flat/recommended']],
rules: {
'playwright/expect-expect': ['warn', { assertFunctionPatterns: ['^expect'] }],
},
},
{
files: ['scripts/**/*.js'],
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'commonjs',
globals: globals.node,
},
rules: {
'@typescript-eslint/no-require-imports': 'off',
'no-console': 'off',
},
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { test as base } from '@playwright/test';
import { registerAuthentication } from '../support/authenticationInterceptor';
import { getServiceConfigFromEnv } from '../support/test-config';
import type { Terminology } from '../support/types';
import { DashboardPage } from '../pages/DashboardPage';
import { ContributorsPage } from '../pages/ContributorsPage';
import { ContributorsInvitePage } from '../pages/ContributorsInvitePage';

interface Fixtures {
terminology: Terminology;
dashboardPage: DashboardPage;
contributorsPage: ContributorsPage;
contributorsInvitePage: ContributorsInvitePage;
}

export const test = base.extend<Fixtures>({
page: async ({ page }, use) => {
// Skip SignalR when running under Cypress to avoid WebSocket proxy issues
await page.addInitScript('window.Cypress = true');
await use(page);
},
context: async ({ context }, use) => {
const serviceConfig = getServiceConfigFromEnv();
await registerAuthentication(context, serviceConfig);
await use(context);
},
terminology: async ({}, use) => {
await use(getServiceConfigFromEnv().terminology);
},
dashboardPage: async ({ page, terminology }, use) => {
await use(new DashboardPage(page, terminology));
},
contributorsPage: async ({ page, terminology }, use) => {
await use(new ContributorsPage(page, terminology));
},
contributorsInvitePage: async ({ page, terminology }, use) => {
await use(new ContributorsInvitePage(page, terminology));
},
});

export { expect } from '@playwright/test';
Loading
Loading