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
89 changes: 89 additions & 0 deletions .github/workflows/qa-playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
name: Playwright QA

on:
workflow_dispatch:
pull_request:
types: [opened, synchronize, reopened]
paths:
- apps/cowswap-frontend/**
- apps/cowswap-frontend-qa/**
- libs/**
- package.json
- pnpm-lock.yaml
- .github/workflows/qa-playwright.yml

jobs:
qa-playwright:
name: Playwright QA
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
env:
CI: 'true'
FORK_BLOCK: '21000000'
HAS_MAINNET_RPC: ${{ secrets.MAINNET_RPC != '' }}
REACT_APP_NETWORK_URL_1: http://127.0.0.1:8545

steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Install pnpm
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0

- name: Set up node
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 20
cache: pnpm

- name: Install dependencies
run: pnpm run install:ci --frozen-lockfile

- name: Skip Playwright QA when MAINNET_RPC is unavailable
if: env.HAS_MAINNET_RPC != 'true'
run: echo "::notice::Skipping Playwright QA because MAINNET_RPC is not available for this workflow run."

- name: Install Foundry
if: env.HAS_MAINNET_RPC == 'true'
uses: foundry-rs/foundry-toolchain@8789b3e21e6c11b2697f5eb56eddae542f746c10 # v1
with:
version: stable

- name: Cache Playwright browsers
if: env.HAS_MAINNET_RPC == 'true'
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('pnpm-lock.yaml', 'apps/cowswap-frontend-qa/package.json') }}
restore-keys: |
${{ runner.os }}-playwright-

- name: Install Chromium
if: env.HAS_MAINNET_RPC == 'true'
run: pnpm --dir apps/cowswap-frontend-qa exec playwright install --with-deps chromium

- name: Run Playwright QA
if: env.HAS_MAINNET_RPC == 'true'
env:
MAINNET_RPC: ${{ secrets.MAINNET_RPC }}
run: pnpm exec nx run cowswap-frontend-qa:e2e

- name: Upload Playwright report
if: env.HAS_MAINNET_RPC == 'true' && failure()
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
if-no-files-found: ignore
name: playwright-report
path: apps/cowswap-frontend-qa/playwright-report/

- name: Upload Playwright test results
if: env.HAS_MAINNET_RPC == 'true' && failure()
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # v4.6.1
with:
if-no-files-found: ignore
name: playwright-test-results
path: apps/cowswap-frontend-qa/test-results/
3 changes: 3 additions & 0 deletions apps/cowswap-frontend-qa/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
playwright-report/
test-results/
.playwright/
22 changes: 22 additions & 0 deletions apps/cowswap-frontend-qa/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
author: agents
status: normative
last_reviewed: 2026-04-22
---

# cowswap-frontend-qa AGENTS.md

Root rules: [`../../AGENTS.md`](../../AGENTS.md) (global safety, workflow, and verification baseline).
This file: Playwright QA app-specific commands and caveats.

## App commands

- Run e2e: `pnpx nx run cowswap-frontend-qa:e2e`
- Run headed: `pnpx nx run cowswap-frontend-qa:e2e:headed`
- Lint: `pnpx nx run cowswap-frontend-qa:lint`
- Typecheck: `pnpx nx run cowswap-frontend-qa:typecheck`

## Notes

- Set `MAINNET_RPC` before running the QA lane locally.
- This project starts the `cowswap-frontend` preview server and an Anvil mainnet fork as part of the test run.
12 changes: 12 additions & 0 deletions apps/cowswap-frontend-qa/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "@cowprotocol/cowswap-frontend-qa",
"version": "0.0.1",
"private": true,
"dependencies": {
"@cowprotocol/common-const": "workspace:*",
"viem": "^2.47.1"
},
"devDependencies": {
"@playwright/test": "^1.59.1"
}
}
50 changes: 50 additions & 0 deletions apps/cowswap-frontend-qa/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { defineConfig, devices } from '@playwright/test'

const ANVIL_RPC_URL = 'http://127.0.0.1:8545'

export default defineConfig({
testDir: './src/tests',
forbidOnly: Boolean(process.env.CI),
fullyParallel: false,
workers: 1,
timeout: 60_000,
expect: {
timeout: 20_000,
},
reporter: [[process.env.CI ? 'line' : 'list'], ['html', { open: 'never' }]],
use: {
baseURL: 'http://127.0.0.1:3000',
trace: 'retain-on-failure',
screenshot: 'only-on-failure',
video: 'off',
viewport: {
width: 1440,
height: 900,
},
},
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
viewport: {
width: 1440,
height: 900,
},
},
},
],
webServer: {
command: 'pnpm exec nx run cowswap-frontend:preview:production',
env: {
...process.env,
NX_DAEMON: 'false',
REACT_APP_ENABLE_QA_INJECTED_WALLET: 'true',
REACT_APP_NETWORK_URL_1: process.env.REACT_APP_NETWORK_URL_1 || ANVIL_RPC_URL,
REACT_APP_SERVICE_WORKER: 'false',
},
url: 'http://127.0.0.1:3000',
timeout: 600_000,
reuseExistingServer: false,
},
})
37 changes: 37 additions & 0 deletions apps/cowswap-frontend-qa/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"name": "cowswap-frontend-qa",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/cowswap-frontend-qa/src",
"projectType": "application",
"targets": {
"e2e": {
"executor": "nx:run-commands",
"options": {
"cwd": "apps/cowswap-frontend-qa",
"command": "playwright test"
}
},
"e2e:headed": {
"executor": "nx:run-commands",
"options": {
"cwd": "apps/cowswap-frontend-qa",
"command": "playwright test --headed --project=chromium"
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["apps/cowswap-frontend-qa/**/*.{ts,js}"]
}
},
"typecheck": {
"executor": "nx:run-commands",
"options": {
"command": "tsc --noEmit -p apps/cowswap-frontend-qa/tsconfig.json"
}
}
},
"tags": [],
"implicitDependencies": ["cowswap-frontend"]
}
Loading
Loading