Skip to content

Commit

Permalink
feat: add playwright
Browse files Browse the repository at this point in the history
  • Loading branch information
qinsong77 committed Apr 18, 2024
1 parent d1f63ea commit 3467d20
Show file tree
Hide file tree
Showing 9 changed files with 323 additions and 7 deletions.
4 changes: 4 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ module.exports = {
files: ['**/*.test.ts', '**/*.test.tsx'],
extends: ['plugin:vitest/recommended', 'plugin:testing-library/react'],
},
{
files: ['e2e/**/*.spec.ts'],
extends: ['plugin:playwright/recommended'],
},
],
ignorePatterns: ['node_modules/', '.next/', 'public/', 'components/ui'],
}
27 changes: 27 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
run: npm install -g pnpm && pnpm install
- name: Install Playwright Browsers
run: pnpm exec playwright install --with-deps
- name: Run Playwright tests
run: pnpm exec playwright test
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 30
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,8 @@ next-env.d.ts

# IDE
.idea

/e2e-results/
/playwright-report/
/blob-report/
/playwright/.cache/
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ This is a [Next.js](https://nextjs.org/) 14 Boilerplate project base on [`create
- [next-international](https://github.com/QuiiBz/next-international) seems better, but not compatible with Not found page
- Maybe the best choice is official Example: [app-dir-i18n-routing](https://github.com/vercel/next.js/tree/canary/examples/app-dir-i18n-routing)
- Docker
- Playwright: Write end-to-end tests like a pro or cypress -TBD
- Playwright: Write end-to-end tests like a pro or cypress
- Github actions/CI

## TODO

Expand Down
40 changes: 40 additions & 0 deletions e2e/app.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { expect, test } from '@playwright/test'

test('should navigate to the dashboard page', async ({ page }) => {
// Start from the index page (the baseURL is set via the webServer in the playwright.config.ts)
await page.goto('/')
// Find an element with the text 'About' and click on it
await page.click('text=dashboard')
// The new URL should be "/about" (baseURL is used there)
await expect(page).toHaveURL('/dashboard')
// The new page should contain an h1 with "About"
await expect(page.locator('h2')).toContainText('Dashboard')
})

test('app journey', async ({ page }) => {
await page.goto('/')
const footerText = page.locator('footer p')
await expect(footerText).toBeVisible()

const navLinks = page.locator('nav a')
const expectedLinksText = ['Loading', 'dashboard', 'todo demos', 'GitHub']

for (let i = 0; i < expectedLinksText.length; i++) {
const linkText = await navLinks.nth(i).textContent()
expect(linkText).toContain(expectedLinksText[i])
}

await navLinks.nth(0).click()
await expect(page).toHaveURL('/loading-and-streaming')

await expect(
page.getByRole('heading', { name: 'Show loading UI and streaming' }),
).toBeVisible()

await navLinks.nth(2).click()
await expect(page).toHaveURL('/todo')
await expect(
page.getByRole('heading', { name: 'Todo demo with RCC' }),
).toBeVisible()
// todo test submit
})
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,16 @@
"build": "next build",
"build-analyze": "cross-env ANALYZE=true pnpm run build",
"check-types": "tsc --noEmit --pretty",
"coverage": "vitest run --coverage",
"dev": "next dev | pino-pretty",
"dev:turbo": "next dev --turbo | pino-pretty",
"preinstall": "npx only-allow pnpm",
"lint": "next lint",
"lint-fix": "next lint --fix && pnpm run prettier:fix",
"prepare": "husky",
"prettier:fix": "prettier '**/*.{js,jsx,ts,tsx,json,md}' --write",
"preview": "next build && cp -r dist/static dist/standalone/dist/static && cp -r public dist/standalone/public && node dist/standalone/server.js",
"start": "next start",
"start": "next build && cp -r dist/static dist/standalone/dist/static && cp -r public dist/standalone/public && node dist/standalone/server.js",
"test": "vitest run",
"test:coverage": "vitest run --coverage",
"test:e2e": "playwright test",
"test:watch": "vitest"
},
Expand Down Expand Up @@ -56,6 +55,7 @@
"@commitlint/config-conventional": "^19.1.0",
"@commitlint/types": "^19.0.3",
"@next/bundle-analyzer": "^14.2.2",
"@playwright/test": "^1.43.1",
"@testing-library/jest-dom": "^6.4.2",
"@testing-library/react": "^15.0.2",
"@testing-library/user-event": "^14.5.2",
Expand All @@ -69,6 +69,7 @@
"eslint": "^8",
"eslint-config-next": "^14.2.2",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-playwright": "^1.6.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-simple-import-sort": "^12.1.0",
"eslint-plugin-tailwindcss": "^3.15.1",
Expand Down
105 changes: 105 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { defineConfig, devices } from '@playwright/test'
import path from 'path'

/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();

// Use process.env.PORT by default and fallback to port 3000
const PORT = process.env.PORT || 3000

// Set webServer.url and use.baseURL with the location of the WebServer respecting the correct set port
const baseURL = `http://localhost:${PORT}`

/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
// Timeout per test
timeout: 30 * 1000,
// Test directory
testDir: path.join(__dirname, 'e2e'),
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: process.env.CI ? 'github' : 'html',
// Artifacts folder where screenshots, videos, and traces are stored.
outputDir: 'e2e-results/',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */

// Run your local dev server before starting the tests:
// https://playwright.dev/docs/test-advanced#launching-a-development-web-server-during-the-tests
webServer: {
command: process.env.CI ? 'pnpm run start' : 'pnpm run dev:turbo',
url: baseURL,
timeout: 2 * 60 * 1000,
reuseExistingServer: !process.env.CI,
},
use: {
// Use baseURL so to make navigations relative.
// More information: https://playwright.dev/docs/api/class-testoptions#test-options-base-url
baseURL,

// Retry a test if its failing with enabled tracing. This allows you to analyze the DOM, console logs, network traffic etc.
// More information: https://playwright.dev/docs/trace-viewer
trace: 'retry-with-trace',

// All available context options: https://playwright.dev/docs/api/class-browser#browser-new-context
// contextOptions: {
// ignoreHTTPSErrors: true,
// },
},

/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},

// {
// name: 'firefox',
// use: { ...devices['Desktop Firefox'] },
// },
//
// {
// name: 'webkit',
// use: { ...devices['Desktop Safari'] },
// },

/* Test against mobile viewports. */
// {
// name: 'Mobile Chrome',
// use: { ...devices['Pixel 5'] },
// },
// {
// name: 'Mobile Safari',
// use: { ...devices['iPhone 12'] },
// },

/* Test against branded browsers. */
// {
// name: 'Microsoft Edge',
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
// },
// {
// name: 'Google Chrome',
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
// },
],

/* Run your local dev server before starting the tests */
// webServer: {
// command: 'npm run start',
// url: 'http://127.0.0.1:3000',
// reuseExistingServer: !process.env.CI,
// },
})
Loading

0 comments on commit 3467d20

Please sign in to comment.