-
Notifications
You must be signed in to change notification settings - Fork 5.3k
e2e tests playwright & chromatic #15550
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+1,744
−44
Merged
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 35555c4
remove webserver option
pettinarip 4fde76a
update for pnpm
pettinarip 08f13e6
enable chromatic<>playwright instegration
pettinarip 8bc4306
fix workflow syntax
pettinarip 9f3e1b1
fix CHROMATIC_ARCHIVE_LOCATION
pettinarip 0c1eb8d
fix incorrect chromatic path
pettinarip 9eaef72
load chromatic e2e to new project
pettinarip e1c5f4f
fix desktop only test
pettinarip bff8b52
feat: add data-testid to SearchButton for improved test targeting
pettinarip 691491c
test: enhance Find Wallet Page tests to verify row count changes
pettinarip ad1a61c
feat: add data-testid attributes to Filters, MobileFilters, and Prese…
pettinarip 78269a3
adjust test names
pettinarip abb0f46
remove browser name as it is not necessary in chromatic
pettinarip f5e9501
cleanup
pettinarip 8965418
Merge branch 'dev' into e2e-tests
pettinarip 4be6c1f
feat: add data-testid to SearchButton and SearchInputButton for impro…
pettinarip 7f1ba21
pick first search button
pettinarip bffc6cb
fix search button test ids
pettinarip 51ccac6
remove unnecessary sleep time
pettinarip ca51252
update Playwright config to include additional reporters and set glob…
pettinarip c04c4af
refactor tests using page object models and add global type tests
pettinarip 5d4653b
add testing docs
pettinarip 86b2ea1
refactor: skip mobile-specific tests when not in mobile viewport
pettinarip b3bc1a3
docs: add ref
pettinarip 8d98dd8
Merge branch 'dev' into e2e-tests
pettinarip 0a8e4eb
test
pettinarip e511cba
update wait-for-netlify-action to a new fork that supports max_timeou…
pettinarip 5059db0
bump version
pettinarip c86e13d
refactor
pettinarip ffa0016
implement RTL tests
pettinarip b9a0e1b
create functions for repeated actions
pettinarip fe8cef1
add test for whitepaper page pdf link
pettinarip fc32dee
move tests to global file
pettinarip 9967008
reuse methods
pettinarip 4144ef8
refactor: move global locators to base page
pettinarip 8fe00dc
remove test helpers
pettinarip 4a02bc9
refactor: implement MdPage class for whitepaper tests
pettinarip 3fac8c4
remove unused files
pettinarip c472e15
add 404 tests
pettinarip 246d251
use translations
pettinarip 673693b
update navigation menu items and utilize test data for button names
pettinarip ff21d93
refactor tests
pettinarip 403d98d
Merge branch 'dev' into e2e-tests
pettinarip a32112c
fix
pettinarip 9482158
Merge branch 'dev' into e2e-tests
pettinarip 106e1f7
Merge branch 'dev' into e2e-tests
pettinarip c1e5e3f
Merge branch 'dev' into e2e-tests
pettinarip e6169bc
clean redundant code
pettinarip c157b8e
wait for load event (default) instead networkidle that is marked as d…
pettinarip 3d20275
clarify dev server prerequisite in e2e testing docs
pettinarip d90568e
fix: specify custom report directory for e2e test reports
pettinarip 87f308d
dotenv config
pettinarip 4ce2caf
ensure page is ready before taking snapshot
pettinarip File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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] | ||
| 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__ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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: | ||
pettinarip marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| ```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) | ||
| }) | ||
| ``` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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", | ||
|
|
@@ -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", | ||
|
|
@@ -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", | ||
|
|
@@ -152,5 +158,5 @@ | |
| "unist-util-visit": "^5.0.0", | ||
| "xml2js": "^0.6.2" | ||
| }, | ||
| "packageManager": "[email protected].3+sha512.467df2c586056165580ad6dfb54ceaad94c5a30f80893ebdec5a44c5aa73c205ae4a5bb9d5ed6bb84ea7c249ece786642bbb49d06a307df218d03da41c317417" | ||
| "packageManager": "[email protected].4" | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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"] }, | ||
| }, | ||
| ], | ||
| }) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
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