Skip to content

Commit 250b4aa

Browse files
playwright base setup [WIP] (#97)
* Add base Playwright setup * Add minor improvements * Frontend E2E reusability refactor * Improve Github Actions * Fix Corepack issues * Update docs --------- Co-authored-by: Kamil Dubiel <[email protected]>
1 parent ceeb439 commit 250b4aa

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1126
-136
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: 🎭 E2E Test Setup
2+
description: 'Setup Playwright and install browsers for E2E testing'
3+
4+
runs:
5+
using: 'composite'
6+
steps:
7+
- name: 💾 Cache Playwright browsers
8+
uses: actions/cache@v4
9+
with:
10+
path: ~/.cache/ms-playwright
11+
key: ${{ runner.os }}-playwright-${{ hashFiles('**/pnpm-lock.yaml') }}
12+
restore-keys: |
13+
${{ runner.os }}-playwright-
14+
15+
- name: 🎭 Install Playwright browsers
16+
run: pnpm e2e:install
17+
shell: bash
18+
19+
- name: 📋 Verify Playwright installation
20+
run: pnpm exec playwright --version
21+
shell: bash

.github/workflows/e2e.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: 🎭 Playwright E2E
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened]
6+
workflow_dispatch:
7+
8+
concurrency:
9+
group: playwright-e2e-${{ github.ref }}
10+
cancel-in-progress: true
11+
12+
permissions:
13+
contents: read
14+
15+
env:
16+
NODE_ENV: test
17+
CI: true
18+
E2E_BASE_URL: http://localhost:3000
19+
20+
jobs:
21+
e2e:
22+
runs-on: ubuntu-24.04
23+
container: mcr.microsoft.com/playwright:v1.57.0-noble
24+
timeout-minutes: 60
25+
steps:
26+
- name: 📥 Checkout
27+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
28+
29+
- name: 💨 Cache turbo
30+
uses: actions/cache@v4
31+
with:
32+
path: |
33+
.turbo
34+
key: ${{ runner.os }}-turbo-${{ hashFiles('pnpm-lock.yaml', 'turbo.json') }}
35+
restore-keys: |
36+
${{ runner.os }}-turbo-
37+
38+
- name: 💻 Node setup
39+
uses: ./.github/actions/node-setup
40+
41+
- name: 🏗️ Build apps
42+
run: pnpm build
43+
shell: bash
44+
45+
- name: 🎭 E2E setup
46+
uses: ./.github/actions/e2e-setup
47+
48+
- name: 🧪 Run E2E (HTML report)
49+
run: pnpm e2e
50+
env:
51+
PWDEBUG: '0'
52+
shell: bash
53+
54+
- name: 📤 Upload Playwright artifacts
55+
if: always()
56+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
57+
with:
58+
name: playwright-artifacts
59+
path: |
60+
apps/*-e2e/playwright-report/
61+
apps/*-e2e/test-results/
62+
apps/*-e2e/reports/
63+
if-no-files-found: ignore

apps/frontend-e2e/.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Playwright artifacts (keep snapshots committed)
2+
/test-results/
3+
/playwright-report/
4+
/reports/
5+
/playwright/.cache/
6+
.last-run.json
7+
/artifacts/

apps/frontend-e2e/.prettierignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Dependencies
2+
node_modules/
3+
4+
# Cache
5+
.turbo/
6+
7+
# Playwright artifacts
8+
**/test-results/
9+
**/playwright-report/
10+
**/reports/

apps/frontend-e2e/.prettierrc.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const baseConfig = require('@infinum/configs/prettier');
2+
3+
/** @type {import('prettier').Config} */
4+
module.exports = {
5+
...baseConfig,
6+
};

apps/frontend-e2e/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# E2E Testing with Playwright
2+
3+
This package contains end-to-end tests for the frontend application using Playwright.
4+
5+
For setup, commands, artifact locations (playwright-report, reports, test-results), and debugging notes, see the central guide:
6+
7+
[`documentation/E2E Testing.md`](../../documentation/E2E%20Testing.md)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import baseConfig from '@infinum/configs/eslint/base';
2+
import playwrightConfig from '@infinum/configs/eslint/playwright';
3+
import typescriptConfig from '@infinum/configs/eslint/typescript';
4+
5+
export default [
6+
...baseConfig,
7+
...typescriptConfig,
8+
...playwrightConfig,
9+
{
10+
files: ['**/*.ts', '**/*.tsx'],
11+
languageOptions: {
12+
parserOptions: {
13+
project: './tsconfig.json',
14+
tsconfigRootDir: import.meta.dirname,
15+
},
16+
},
17+
},
18+
];

apps/frontend-e2e/package.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "@infinum/frontend-e2e",
3+
"version": "0.0.0",
4+
"private": true,
5+
"scripts": {
6+
"check-licenses": "node ../../scripts/check-licenses-workspace.js",
7+
"clean": "rm -rf node_modules .turbo .eslintcache",
8+
"e2e": "playwright test --reporter=html",
9+
"e2e:install": "playwright install",
10+
"e2e:report": "playwright show-report",
11+
"lint": "eslint . --cache",
12+
"lint:fix": "eslint . --cache --fix",
13+
"prettier:check": "prettier --check .",
14+
"prettier:fix": "prettier --write ."
15+
},
16+
"devDependencies": {
17+
"@axe-core/playwright": "catalog:",
18+
"@infinum/configs": "workspace:*",
19+
"@infinum/e2e-utils": "workspace:*",
20+
"@playwright/test": "catalog:",
21+
"@types/node": "catalog:",
22+
"axe-core": "catalog:",
23+
"axe-html-reporter": "catalog:",
24+
"eslint": "catalog:",
25+
"prettier": "catalog:",
26+
"typescript": "catalog:"
27+
}
28+
}

apps/frontend-e2e/pages/login.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { Page, Locator } from '@playwright/test';
2+
import { BasePage } from '@infinum/e2e-utils/pages';
3+
4+
export class LoginPage extends BasePage {
5+
readonly emailInput: Locator;
6+
readonly passwordInput: Locator;
7+
readonly submitButton: Locator;
8+
readonly errorMessage: Locator;
9+
10+
constructor(page: Page) {
11+
super(page);
12+
13+
// Semantic locators
14+
this.emailInput = page.getByLabel('Email');
15+
this.passwordInput = page.getByLabel('Password');
16+
this.submitButton = page.getByRole('button', { name: 'Sign in' });
17+
this.errorMessage = page.getByTestId('login-error');
18+
}
19+
20+
async goto() {
21+
await this.navigateTo('/en/login');
22+
await this.waitForLoad();
23+
}
24+
25+
async login(email: string, password: string) {
26+
// Check if form elements are available
27+
await this.waitForVisible(this.emailInput);
28+
await this.waitForVisible(this.passwordInput);
29+
await this.waitForVisible(this.submitButton);
30+
31+
await this.emailInput.fill(email);
32+
await this.passwordInput.fill(password);
33+
await this.submitButton.click();
34+
35+
// Wait for navigation to complete
36+
await this.waitForNavigation();
37+
}
38+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import baseConfig from '@infinum/configs/playwright/base';
2+
import { defineConfig, devices } from '@playwright/test';
3+
4+
export default defineConfig({
5+
...baseConfig,
6+
testDir: './tests',
7+
projects: [
8+
{
9+
name: 'chromium',
10+
use: {
11+
...devices['Desktop Chrome'],
12+
baseURL: process.env.E2E_BASE_URL ?? 'http://localhost:3000',
13+
},
14+
},
15+
],
16+
webServer: process.env.CI
17+
? {
18+
command: 'pnpm --filter @infinum/frontend start',
19+
port: 3000,
20+
reuseExistingServer: !process.env.CI,
21+
env: {
22+
NODE_OPTIONS: '',
23+
},
24+
}
25+
: undefined,
26+
});

0 commit comments

Comments
 (0)