Skip to content

Commit d75bc81

Browse files
committed
add basic playwright tests
1 parent 4316175 commit d75bc81

File tree

10 files changed

+261
-56
lines changed

10 files changed

+261
-56
lines changed

.github/workflows/deploy-dev.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,8 @@ jobs:
9292
run: make dev_health_check
9393
- name: Run live testing
9494
run: make test_live_integration
95+
- name: Run E2E testing
96+
run: make test_e2e
97+
env:
98+
PLAYWRIGHT_USERNAME: ${{ secrets.PLAYWRIGHT_USERNAME }}
99+
PLAYWRIGHT_PASSWORD: ${{ secrets.PLAYWRIGHT_PASSWORD }}

.github/workflows/deploy-prod.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ jobs:
9090
python-version: 3.11
9191
- name: Run live testing
9292
run: make test_live_integration
93+
- name: Run E2E testing
94+
run: make test_e2e
95+
env:
96+
PLAYWRIGHT_USERNAME: ${{ secrets.PLAYWRIGHT_USERNAME }}
97+
PLAYWRIGHT_PASSWORD: ${{ secrets.PLAYWRIGHT_PASSWORD }}
9398

9499
deploy-prod:
95100
runs-on: ubuntu-latest

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,7 @@ dist_ui/
137137

138138
*.pyc
139139
__pycache__
140+
/test-results/
141+
/playwright-report/
142+
/blob-report/
143+
/playwright/.cache/

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ test_unit: install_test_deps
7474
yarn prettier
7575
yarn test:unit
7676

77+
test_e2e: install_test_deps
78+
yarn test:e2e
79+
7780
dev_health_check:
7881
curl -f https://$(application_key).aws.qa.acmuiuc.org/api/v1/healthz && curl -f https://manage.qa.acmuiuc.org
7982

e2e/base.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { test as base } from '@playwright/test';
2+
import {
3+
SecretsManagerClient,
4+
GetSecretValueCommand,
5+
} from "@aws-sdk/client-secrets-manager";
6+
7+
export const getSecretValue = async (
8+
secretId: string,
9+
): Promise<Record<string, string | number | boolean> | null> => {
10+
const smClient = new SecretsManagerClient();
11+
const data = await smClient.send(
12+
new GetSecretValueCommand({ SecretId: secretId }),
13+
);
14+
if (!data.SecretString) {
15+
return null;
16+
}
17+
try {
18+
return JSON.parse(data.SecretString) as Record<
19+
string,
20+
string | number | boolean
21+
>;
22+
} catch {
23+
return null;
24+
}
25+
};
26+
27+
async function getSecrets() {
28+
let response = { PLAYWRIGHT_USERNAME: '', PLAYWRIGHT_PASSWORD: '' }
29+
let keyData;
30+
if (!process.env.PLAYWRIGHT_USERNAME || !process.env.PLAYWRIGHT_PASSWORD || !process.env.JwtSigningKey) {
31+
keyData = await getSecretValue('infra-core-api-config')
32+
}
33+
response['PLAYWRIGHT_USERNAME'] = process.env.PLAYWRIGHT_USERNAME || keyData ? keyData['playwright_username'] : '';
34+
response['PLAYWRIGHT_PASSWORD'] = process.env.PLAYWRIGHT_PASSWORD || keyData ? keyData['playwright_password'] : '';
35+
return response;
36+
}
37+
38+
const secrets = await getSecrets();
39+
40+
async function becomeUser(page) {
41+
await page.goto('https://manage.qa.acmuiuc.org/login');
42+
await page.getByRole('button', { name: 'Sign in with Illinois NetID' }).click();
43+
await page.getByPlaceholder('[email protected]').click();
44+
await page.getByPlaceholder('[email protected]').fill(secrets['PLAYWRIGHT_USERNAME']);
45+
await page.getByPlaceholder('[email protected]').press('Enter');
46+
await page.getByPlaceholder('Password').click();
47+
await page.getByPlaceholder('Password').fill(secrets['PLAYWRIGHT_PASSWORD']);
48+
await page.getByRole('button', { name: 'Sign in' }).click();
49+
await page.getByRole('button', { name: 'No' }).click();
50+
}
51+
52+
export const test = base.extend<{ becomeUser: (page) => Promise<void> }>({
53+
becomeUser: async ({ }, use) => {
54+
use(becomeUser)
55+
},
56+
});

e2e/tests/login.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
2+
import { expect } from '@playwright/test';
3+
import { test } from '../base';
4+
import { describe } from 'node:test';
5+
6+
describe("Login tests", () => {
7+
test('A user can login and view the home screen', async ({ page, becomeUser }) => {
8+
await becomeUser(page);
9+
await expect(page.locator('a').filter({ hasText: 'Management Portal DEV ENV' })).toBeVisible();
10+
await expect(page.locator('a').filter({ hasText: 'Events' })).toBeVisible();
11+
await expect(page.locator('a').filter({ hasText: 'Ticketing/Merch' })).toBeVisible();
12+
await expect(page.locator('a').filter({ hasText: 'IAM' })).toBeVisible();
13+
await expect(page.getByRole('link', { name: 'ACM Logo Management Portal' })).toBeVisible();
14+
await expect(page.getByRole('link', { name: 'P', exact: true })).toBeVisible();
15+
await page.getByRole('link', { name: 'P', exact: true }).click();
16+
await expect(page.getByLabel('PMy Account')).toContainText('Name Playwright Core User');
17+
await expect(page.getByLabel('PMy Account')).toContainText('[email protected]');
18+
expect(page.url()).toEqual('https://manage.qa.acmuiuc.org/home');
19+
});
20+
})

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121
"test:unit-ui": "yarn test:unit --ui",
2222
"test:unit-watch": "vitest tests/unit",
2323
"test:live": "vitest tests/live",
24-
"test:live-ui": "yarn test:live --ui"
24+
"test:live-ui": "yarn test:live --ui",
25+
"test:e2e": "playwright test",
26+
"test:e2e-ui": "playwright test --ui"
2527
},
2628
"dependencies": {
2729
"@aws-sdk/client-dynamodb": "^3.624.0",
@@ -49,6 +51,7 @@
4951
},
5052
"devDependencies": {
5153
"@eslint/compat": "^1.1.1",
54+
"@playwright/test": "^1.49.1",
5255
"@tsconfig/node20": "^20.1.4",
5356
"@types/node": "^22.1.0",
5457
"@types/pluralize": "^0.0.33",

playwright.config.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { defineConfig, devices } from '@playwright/test';
2+
3+
export default defineConfig({
4+
testDir: './e2e/tests',
5+
/* Run tests in files in parallel */
6+
fullyParallel: false,
7+
/* Fail the build on CI if you accidentally left test.only in the source code. */
8+
forbidOnly: !!process.env.CI,
9+
/* Retry on CI only */
10+
retries: process.env.CI ? 2 : 0,
11+
/* Opt out of parallel tests on CI. */
12+
workers: process.env.CI ? 1 : undefined,
13+
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
14+
reporter: 'html',
15+
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
16+
use: {
17+
/* Base URL to use in actions like `await page.goto('/')`. */
18+
// baseURL: 'http://127.0.0.1:3000',
19+
20+
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
21+
trace: 'on-first-retry',
22+
},
23+
24+
/* Configure projects for major browsers */
25+
projects: [
26+
{
27+
name: 'chromium',
28+
use: { ...devices['Desktop Chrome'] },
29+
},
30+
31+
{
32+
name: 'firefox',
33+
use: { ...devices['Desktop Firefox'] },
34+
},
35+
],
36+
37+
/* Run your local dev server before starting the tests */
38+
// webServer: {
39+
// command: 'npm run start',
40+
// url: 'http://127.0.0.1:3000',
41+
// reuseExistingServer: !process.env.CI,
42+
// },
43+
});

src/common/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ const environmentConfig: EnvironmentConfigType = {
7070
},
7171
UserRoleMapping: {
7272
"[email protected]": [AppRoles.TICKETS_SCANNER],
73+
"kLkvWTYwNnJfBkIK7mBi4niXXHYNR7ygbV8utlvFxjw": allAppRoles
7374
},
7475
AzureRoleMapping: { AutonomousWriters: [AppRoles.EVENTS_MANAGER] },
7576
ValidCorsOrigins: [

0 commit comments

Comments
 (0)