playwright端对端测试
在vite安装的项目下 安装playwright
npm install @playwright/test -D
npm install eslint-plugin-playwright -D
添加playwright.config.ts
import process from 'node:process'
import { defineConfig, devices } from '@playwright/test'
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: './test',
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000
},
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: 'html',
globalSetup: 'global.setup.ts',
globalTeardown: 'global-teardown.ts',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
// actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
// baseURL: process.env.CI ? 'http://localhost:4173' : 'http://localhost:5173',
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry'
/* Only on CI systems run the tests headless */
// headless: !!process.env.CI
},
/* 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: {
// channel: 'msedge',
// },
// },
// {
// name: 'Google Chrome',
// use: {
// channel: 'chrome',
// },
// },
],
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
// outputDir: 'test-results/',
/* Run your local dev server before starting the tests */
webServer: {
/**
* Use the dev server by default for faster feedback loop.
* Use the preview server on CI for more realistic testing.
* Playwright will re-use the local server if there is already a dev-server running.
*/
command: process.env.CI ? 'npm run preview' : 'npm run dev',
port: process.env.CI ? 4173 : 5173,
reuseExistingServer: !process.env.CI
}
})
测试的内容放在test文件夹内
packages.json中添加运行脚本
{
"scripts":{
"test": "playwright test",
"test:ui": "playwright test --ui",
}
}
运行脚本即可看到效果
添加覆盖率 V8
添加依赖monocart-coverage-reports
npm install monocart-coverage-reports -D
新增文件mcr.config.ts、global.setup.ts、global-teardown.ts、fixtures.ts
mcr.config.ts
// mcr.config.ts
import { CoverageReportOptions } from 'monocart-coverage-reports'
// https://github.com/cenfun/monocart-coverage-reports
const coverageOptions: CoverageReportOptions = {
name: 'My Playwright Coverage Report',
reports: ['console-details', 'v8', 'lcovonly'],
// entryFilter: {
// '**/node_modules/**': false,
// '**/*.js': true
// },
// sourceFilter: {
// '**/node_modules/**': false,
// '**/*.js': true
// },
outputDir: './coverage-reports'
}
export default coverageOptions
global.setup.ts
// global.setup.ts
import MCR from 'monocart-coverage-reports'
import coverageOptions from './mcr.config'
import { type FullConfig } from '@playwright/test'
async function globalSetup(config: FullConfig) {
const mcr = MCR(coverageOptions)
await mcr.cleanCache()
}
export default globalSetup
global-teardown.ts
// global-teardown.ts
import MCR from 'monocart-coverage-reports'
import coverageOptions from './mcr.config'
import { type FullConfig } from '@playwright/test'
async function globalTeardown(config: FullConfig) {
const mcr = MCR(coverageOptions)
await mcr.generate()
}
export default globalTeardown
fixtures.ts
// fixtures.ts
import { test as testBase, Page } from '@playwright/test'
import MCR from 'monocart-coverage-reports'
import coverageOptions from './mcr.config'
// fixtures
const test = testBase.extend<{
autoTestFixture: string
}>({
autoTestFixture: [
async ({ context }, use) => {
const isChromium = test.info().project.name === 'chromium'
const handlePageEvent = async (page: Page) => {
await Promise.all([
page.coverage.startJSCoverage({
resetOnNavigation: false
}),
page.coverage.startCSSCoverage({
resetOnNavigation: false
})
])
}
// console.log('autoTestFixture setup...');
// coverage API is chromium only
if (isChromium) {
context.on('page', handlePageEvent)
}
await use('autoTestFixture')
// console.log('autoTestFixture teardown...');
if (isChromium) {
context.off('page', handlePageEvent)
const coverageList = await Promise.all(
context.pages().map(async (page) => {
const jsCoverage = await page.coverage.stopJSCoverage()
const cssCoverage = await page.coverage.stopCSSCoverage()
return [...jsCoverage, ...cssCoverage]
})
)
// console.log(coverageList.map((item) => item.url));
const mcr = MCR(coverageOptions)
await mcr.add(coverageList.flat())
}
},
{
scope: 'test',
auto: true
}
]
})
export { test }
测试文件添加依赖
test文件夹内每个测试文件需添加fixtures中test依赖覆盖原来的test方法
import {
// test,
expect } from '@playwright/test'
import { test } from '../fixtures' // 将test 覆盖原来的test
test('xxx', async ({ page }) => {
await page.goto('http://localhost:5173/')
await page.locator('button.login-btn').click()
await page.waitForTimeout(1000)
await expect(page.url()).toContain('/user')
})
package.json添加脚本
{
"scripts":{
"test:ui":"playwright test --ui",
"test": "npx playwright test",
}
}
录制测试用例,自动生成代码
生成的测试用例无断言,需自行添加断言
npx playwright codegen // 需启动服务之后运行,或者测试生产环境