Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
8685f75
initial setup for playwright with basic tests and ci integration
pettinarip May 30, 2025
35555c4
remove webserver option
pettinarip May 30, 2025
4fde76a
update for pnpm
pettinarip Jun 3, 2025
08f13e6
enable chromatic<>playwright instegration
pettinarip Jun 3, 2025
8bc4306
fix workflow syntax
pettinarip Jun 3, 2025
9f3e1b1
fix CHROMATIC_ARCHIVE_LOCATION
pettinarip Jun 3, 2025
0c1eb8d
fix incorrect chromatic path
pettinarip Jun 3, 2025
9eaef72
load chromatic e2e to new project
pettinarip Jun 5, 2025
e1c5f4f
fix desktop only test
pettinarip Jun 6, 2025
bff8b52
feat: add data-testid to SearchButton for improved test targeting
pettinarip Jun 9, 2025
691491c
test: enhance Find Wallet Page tests to verify row count changes
pettinarip Jun 9, 2025
ad1a61c
feat: add data-testid attributes to Filters, MobileFilters, and Prese…
pettinarip Jun 9, 2025
78269a3
adjust test names
pettinarip Jun 9, 2025
abb0f46
remove browser name as it is not necessary in chromatic
pettinarip Jun 9, 2025
f5e9501
cleanup
pettinarip Jun 9, 2025
8965418
Merge branch 'dev' into e2e-tests
pettinarip Jun 11, 2025
4be6c1f
feat: add data-testid to SearchButton and SearchInputButton for impro…
pettinarip Jun 11, 2025
7f1ba21
pick first search button
pettinarip Jun 11, 2025
bffc6cb
fix search button test ids
pettinarip Jun 11, 2025
51ccac6
remove unnecessary sleep time
pettinarip Jun 16, 2025
ca51252
update Playwright config to include additional reporters and set glob…
pettinarip Jun 16, 2025
c04c4af
refactor tests using page object models and add global type tests
pettinarip Jun 16, 2025
5d4653b
add testing docs
pettinarip Jun 16, 2025
86b2ea1
refactor: skip mobile-specific tests when not in mobile viewport
pettinarip Jun 16, 2025
b3bc1a3
docs: add ref
pettinarip Jun 16, 2025
8d98dd8
Merge branch 'dev' into e2e-tests
pettinarip Jun 16, 2025
0a8e4eb
test
pettinarip Jun 16, 2025
e511cba
update wait-for-netlify-action to a new fork that supports max_timeou…
pettinarip Jun 17, 2025
5059db0
bump version
pettinarip Jun 17, 2025
c86e13d
refactor
pettinarip Jun 12, 2025
ffa0016
implement RTL tests
pettinarip Jun 13, 2025
b9a0e1b
create functions for repeated actions
pettinarip Jun 13, 2025
fe8cef1
add test for whitepaper page pdf link
pettinarip Jun 13, 2025
fc32dee
move tests to global file
pettinarip Jun 17, 2025
9967008
reuse methods
pettinarip Jun 17, 2025
4144ef8
refactor: move global locators to base page
pettinarip Jun 17, 2025
8fe00dc
remove test helpers
pettinarip Jun 17, 2025
4a02bc9
refactor: implement MdPage class for whitepaper tests
pettinarip Jun 17, 2025
3fac8c4
remove unused files
pettinarip Jun 17, 2025
c472e15
add 404 tests
pettinarip Jun 17, 2025
246d251
use translations
pettinarip Jun 17, 2025
673693b
update navigation menu items and utilize test data for button names
pettinarip Jun 17, 2025
ff21d93
refactor tests
pettinarip Jun 18, 2025
403d98d
Merge branch 'dev' into e2e-tests
pettinarip Jun 18, 2025
a32112c
fix
pettinarip Jun 18, 2025
9482158
Merge branch 'dev' into e2e-tests
pettinarip Jun 27, 2025
106e1f7
Merge branch 'dev' into e2e-tests
pettinarip Jun 30, 2025
c1e5e3f
Merge branch 'dev' into e2e-tests
pettinarip Jun 30, 2025
e6169bc
clean redundant code
pettinarip Jun 30, 2025
c157b8e
wait for load event (default) instead networkidle that is marked as d…
pettinarip Jun 30, 2025
3d20275
clarify dev server prerequisite in e2e testing docs
pettinarip Jul 3, 2025
d90568e
fix: specify custom report directory for e2e test reports
pettinarip Jul 3, 2025
87f308d
dotenv config
pettinarip Jul 14, 2025
4ce2caf
ensure page is ready before taking snapshot
pettinarip Jul 14, 2025
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
80 changes: 80 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: E2E tests
on:
push:
branches: [master, staging, e2e-tests] # TODO: remove e2e-tests branch after testing
pull_request:
branches: [master, staging, e2e-tests] # TODO: remove e2e-tests branch after testing
jobs:
playwright:
runs-on: ubuntu-latest
env:
CI: true
steps:
- uses: actions/checkout@v4

- name: Wait for Netlify Deploy
id: netlify_deploy
uses: pettinarip/[email protected]
Copy link
Member Author

@pettinarip pettinarip Jun 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to fork the GH action to adjust the timeout constants as one of them was hardcoded and caused the job to fail if the build took more than 15min. https://github.com/pettinarip/wait-for-netlify-action/tree/v1.0.2

with:
site_id: "e8f2e766-888b-4954-8500-1b647d84db99"
max_timeout: 3600
env:
NETLIFY_TOKEN: ${{ secrets.NETLIFY_TOKEN }}

- uses: actions/setup-node@v4
with:
node-version: lts/*

- name: Setup pnpm
uses: pnpm/action-setup@v2

- name: Install dependencies
run: pnpm install

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

- name: Run E2E Tests on Netlify URL
run: pnpm test:e2e
env:
PLAYWRIGHT_TEST_BASE_URL: ${{ steps.netlify_deploy.outputs.url }}

- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: ./tests/e2e/__results__
retention-days: 7

chromatic:
name: chromatic
needs: playwright
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 22.12.0
- name: Setup pnpm
uses: pnpm/action-setup@v2

- name: Install dependencies
run: pnpm install

- name: Download Playwright test results
uses: actions/download-artifact@v4
with:
name: playwright-report
path: ./tests/e2e/__results__

- name: Run Chromatic
uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_E2E_TOKEN }}
playwright: true
exitZeroOnChanges: true
storybookBaseDir: .
env:
CHROMATIC_ARCHIVE_LOCATION: ./tests/e2e/__results__
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,5 @@ src/data/crowdin/bucketsAwaitingReviewReport.csv

# Storybook
build-storybook.log
build-archive.log
storybook-static
6 changes: 0 additions & 6 deletions chromatic.config.json

This file was deleted.

152 changes: 152 additions & 0 deletions docs/e2e-testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# E2E Testing with Playwright

## Overview

This project uses [Playwright](https://playwright.dev/) for end-to-end testing with [Chromatic](https://www.chromatic.com/) integration for visual regression testing.

## Quick Start

### Running Tests Locally

```bash
# Install dependencies (if not already done)
pnpm install

# Install Playwright browsers
npx playwright install

# Start development server (in a separate terminal)
pnpm dev

# Run all e2e tests
pnpm test:e2e

# Run tests with UI (interactive mode)
pnpm test:e2e:ui

# Run tests in debug mode
pnpm test:e2e:debug

# View test report
pnpm test:e2e:report
```

### Development Server: Choosing the Best Mode for E2E Testing

By default, Playwright tests run against `http://localhost:3000`. Before running tests, ensure your development server is up and running. You can start it in development mode with:

```bash
pnpm dev
```

**Note:** Running in dev mode (`pnpm dev`) is convenient for rapid iteration, but it can be significantly slower than production builds. As a result, you may encounter Playwright timeout errors if pages take too long to load or build on demand.

#### Tips to Avoid Timeout Issues

- **Preload pages:** Manually visit the routes you plan to test in your browser before running the tests. This triggers Next.js to build those pages ahead of time, reducing load times during testing.
- **Increase Playwright timeouts:** If you must use dev mode, consider increasing Playwright's default timeouts to accommodate slower builds (see Playwright config docs).
- **Use a production build for reliability:** For the fastest and most stable E2E test runs, use a production build. This ensures all pages are prebuilt and served at optimal speed:

```bash
pnpm build
pnpm start
```

This will serve your app at `http://localhost:3000` in production mode, minimizing the risk of timeouts and making your tests more reliable.

> **Summary:**
>
> - Use `pnpm dev` for quick local development and debugging, but expect slower performance and possible timeouts.
> - For CI or full test runs, prefer `pnpm build && pnpm start` for best results.

## Directory Layout

```
tests/e2e/
├── __results__/ # Test results (gitignored)
├── __report__/ # HTML reports (gitignored)
├── fixtures/ # Test data and fixtures
├── pages/ # Page Object Model classes
├── utils/ # Test utilities and helpers
├── *.spec.ts # Test files
└── .gitignore
```

## Writing Tests

### Best Practices

#### 1. Use Page Object Model

Create reusable page objects for common interactions. For more details, see the [Playwright Page Object Model documentation](https://playwright.dev/docs/pom):

```typescript
// pages/HomePage.ts
export class HomePage {
constructor(private page: Page) {}

async goto() {
await this.page.goto("/")
}

async searchFor(query: string) {
const isMobile = await this.isMobileViewport()
if (isMobile) {
await this.page.getByTestId("search-button").first().click()
} else {
await this.page.getByTestId("search-input-button").first().click()
}
await this.page.getByPlaceholder("Search").fill(query)
}

private async isMobileViewport() {
const viewport = this.page.viewportSize()
return viewport && viewport.width <= 768
}
}
```

#### 2. Robust Selectors

Prefer `data-testid` attributes over CSS selectors:

```typescript
// Good
await page.getByTestId("search-button")

// Better for accessibility
await page.getByRole("button", { name: "Search" })

// Avoid fragile selectors
await page.locator(".search-btn-class") // Fragile
```

#### 3. Responsive Testing

Handle different viewport sizes appropriately:

```typescript
test("search functionality", async ({ page }) => {
const viewport = page.viewportSize()
const isMobile = viewport && viewport.width <= breakpointAsNumber.md

if (isMobile) {
// Mobile-specific logic
} else {
// Desktop-specific logic
}
})
```

#### 4. Visual Testing

Use Chromatic snapshots for visual regression testing:

```typescript
import { takeSnapshot } from "@chromatic-com/playwright"

test("visual regression", async ({ page }, testInfo) => {
await page.goto("/")
await takeSnapshot(page, "homepage-initial", testInfo)
})
```
12 changes: 9 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@
"events-import": "ts-node -O '{ \"module\": \"commonjs\" }' src/scripts/events-import.ts",
"crowdin-needs-review": "ts-node -O '{ \"module\": \"commonjs\" }' src/scripts/crowdin/reports/generateReviewReport.ts",
"update-tutorials": "ts-node -O '{ \"module\": \"commonjs\" }' src/scripts/update-tutorials-list.ts",
"prepare": "husky"
"prepare": "husky",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:debug": "playwright test --debug",
"test:e2e:report": "playwright show-report tests/e2e/__report__"
},
"dependencies": {
"@crowdin/crowdin-api-client": "^1.25.0",
Expand Down Expand Up @@ -97,8 +101,10 @@
"yaml-loader": "^0.8.0"
},
"devDependencies": {
"@chromatic-com/playwright": "^0.12.4",
"@chromatic-com/storybook": "1.5.0",
"@netlify/plugin-nextjs": "^5.10.0",
"@playwright/test": "^1.52.0",
"@storybook/addon-essentials": "8.6.14",
"@storybook/addon-interactions": "8.6.14",
"@storybook/addon-links": "8.6.14",
Expand All @@ -120,7 +126,7 @@
"@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0",
"autoprefixer": "^10.4.19",
"chromatic": "10.9.6",
"chromatic": "12.0.0",
"decompress": "^4.2.1",
"dotenv": "^16.5.0",
"eslint": "^8.57.1",
Expand Down Expand Up @@ -152,5 +158,5 @@
"unist-util-visit": "^5.0.0",
"xml2js": "^0.6.2"
},
"packageManager": "[email protected].3+sha512.467df2c586056165580ad6dfb54ceaad94c5a30f80893ebdec5a44c5aa73c205ae4a5bb9d5ed6bb84ea7c249ece786642bbb49d06a307df218d03da41c317417"
"packageManager": "[email protected].4"
}
61 changes: 61 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import path from "path"

import dotenv from "dotenv"
import type { ChromaticConfig } from "@chromatic-com/playwright"
import { defineConfig, devices } from "@playwright/test"

dotenv.config({ path: path.resolve(__dirname, ".env.local") })

export default defineConfig<ChromaticConfig>({
testDir: "./tests/e2e",
outputDir: "./tests/e2e/__results__",
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : 3,
reporter: [
["html", { outputFolder: "./tests/e2e/__report__" }],
["line"],
process.env.CI ? ["github"] : ["list"],
],
use: {
baseURL: process.env.PLAYWRIGHT_TEST_BASE_URL || "http://localhost:3000",
trace: "on-first-retry",
screenshot: "only-on-failure",

// Global test timeout
actionTimeout: 10000,
navigationTimeout: 30000,

// Chromatic settings
disableAutoSnapshot: true,
},

// Global test timeout
timeout: 30000,

// Expect timeout
expect: {
timeout: 10000,
},
projects: [
/* Test against desktop browsers */
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},
{
name: "webkit",
use: { ...devices["Desktop Safari"] },
},
/* Test against mobile viewports. */
{
name: "Mobile Chrome",
use: { ...devices["Pixel 5"] },
},
{
name: "Mobile Safari",
use: { ...devices["iPhone 12"] },
},
],
})
Loading
Loading