feat: add playwright e2e testing framework (#4468)
* feat: add playwright e2e testing framework
This commit is contained in:
20
playground/__tests__/e2e/auth-login.spec.ts
Normal file
20
playground/__tests__/e2e/auth-login.spec.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
import { authLogin } from './common/auth';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.goto('/');
|
||||
});
|
||||
|
||||
test.describe('Auth Login Page Tests', () => {
|
||||
test('check title and page elements', async ({ page }) => {
|
||||
// 获取页面标题并断言标题包含 'Vben Admin'
|
||||
const title = await page.title();
|
||||
expect(title).toContain('Vben Admin');
|
||||
});
|
||||
|
||||
// 测试用例: 成功登录
|
||||
test('should successfully login with valid credentials', async ({ page }) => {
|
||||
await authLogin(page);
|
||||
});
|
||||
});
|
46
playground/__tests__/e2e/common/auth.ts
Normal file
46
playground/__tests__/e2e/common/auth.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import type { Page } from '@playwright/test';
|
||||
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
export async function authLogin(page: Page) {
|
||||
// 确保登录表单正常
|
||||
const usernameInput = await page.locator(`input[name='username']`);
|
||||
await expect(usernameInput).toBeVisible();
|
||||
|
||||
const passwordInput = await page.locator(`input[name='password']`);
|
||||
await expect(passwordInput).toBeVisible();
|
||||
|
||||
const sliderCaptcha = await page.locator(`div[name='captcha']`);
|
||||
const sliderCaptchaAction = await page.locator(`div[name='captcha-action']`);
|
||||
await expect(sliderCaptcha).toBeVisible();
|
||||
await expect(sliderCaptchaAction).toBeVisible();
|
||||
|
||||
// 拖动验证码滑块
|
||||
// 获取拖动按钮的位置
|
||||
const sliderCaptchaBox = await sliderCaptcha.boundingBox();
|
||||
if (!sliderCaptchaBox) throw new Error('滑块未找到');
|
||||
|
||||
const actionBoundingBox = await sliderCaptchaAction.boundingBox();
|
||||
if (!actionBoundingBox) throw new Error('要拖动的按钮未找到');
|
||||
|
||||
// 计算起始位置和目标位置
|
||||
const startX = actionBoundingBox.x + actionBoundingBox.width / 2; // div 中心的 x 坐标
|
||||
const startY = actionBoundingBox.y + actionBoundingBox.height / 2; // div 中心的 y 坐标
|
||||
|
||||
const targetX = startX + sliderCaptchaBox.width + actionBoundingBox.width; // 向右拖动容器的宽度
|
||||
const targetY = startY; // y 坐标保持不变
|
||||
|
||||
// 模拟鼠标拖动
|
||||
await page.mouse.move(startX, startY); // 移动到 action 的中心
|
||||
await page.mouse.down(); // 按下鼠标
|
||||
await page.mouse.move(targetX, targetY, { steps: 20 }); // 拖动到目标位置
|
||||
await page.mouse.up(); // 松开鼠标
|
||||
|
||||
// 在拖动后进行断言,检查action是否在预期位置,
|
||||
const newActionBoundingBox = await sliderCaptchaAction.boundingBox();
|
||||
expect(newActionBoundingBox?.x).toBeGreaterThan(actionBoundingBox.x);
|
||||
|
||||
// 到这里已经校验成功,点击进行登录
|
||||
await page.waitForTimeout(300);
|
||||
await page.getByRole('button', { name: 'login' }).click();
|
||||
}
|
@@ -20,7 +20,10 @@
|
||||
"build:analyze": "pnpm vite build --mode analyze",
|
||||
"dev": "pnpm vite --mode development",
|
||||
"preview": "vite preview",
|
||||
"typecheck": "vue-tsc --noEmit --skipLibCheck"
|
||||
"typecheck": "vue-tsc --noEmit --skipLibCheck",
|
||||
"test:e2e": "playwright test",
|
||||
"test:e2e-ui": "playwright test --ui",
|
||||
"test:e2e-codegen": "playwright codegen"
|
||||
},
|
||||
"imports": {
|
||||
"#/*": "./src/*"
|
||||
|
108
playground/playwright.config.ts
Normal file
108
playground/playwright.config.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import type { PlaywrightTestConfig } from '@playwright/test';
|
||||
|
||||
import { devices } from '@playwright/test';
|
||||
|
||||
/**
|
||||
* Read environment variables from file.
|
||||
* https://github.com/motdotla/dotenv
|
||||
*/
|
||||
// require('dotenv').config();
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
const config: PlaywrightTestConfig = {
|
||||
expect: {
|
||||
/**
|
||||
* Maximum time expect() should wait for the condition to be met.
|
||||
* For example in `await expect(locator).toHaveText();`
|
||||
*/
|
||||
timeout: 5000,
|
||||
},
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
|
||||
outputDir: 'node_modules/.e2e/test-results/',
|
||||
/* 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',
|
||||
// },
|
||||
// },
|
||||
],
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: [
|
||||
['list'],
|
||||
['html', { outputFolder: 'node_modules/.e2e/test-results' }],
|
||||
],
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
testDir: './__tests__/e2e',
|
||||
/* Maximum time one test can run for. */
|
||||
timeout: 30 * 1000,
|
||||
/* 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: 'http://localhost:5555',
|
||||
/* Only on CI systems run the tests headless */
|
||||
headless: !!process.env.CI,
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: 'retain-on-failure',
|
||||
},
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: {
|
||||
command: process.env.CI ? 'pnpm preview --port 5555' : 'pnpm dev',
|
||||
port: 5555,
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
};
|
||||
|
||||
export default config;
|
Reference in New Issue
Block a user