Skip to content
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

feat: add playwright e2e testing framework #4468

Merged
merged 4 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .gitpod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ ports:
onOpen: open-preview
tasks:
- init: corepack enable && pnpm install
command: pnpm run dev
command: pnpm run dev:play
4 changes: 4 additions & 0 deletions README.ja-JP.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ pnpm build

<a style="display: block;width: 100px;height: 50px;line-height: 50px; color: #fff;text-align: center; background: #408aed;border-radius: 4px;" href="https://www.paypal.com/paypalme/cvvben">Paypal Me</a>

## スター歴史

[![Star History Chart](https://api.star-history.com/svg?repos=vbenjs/vue-vben-admin&type=Date)](https://star-history.com/#vbenjs/vue-vben-admin&Date)

## 貢献者

<a href="https://github.com/vbenjs/vue-vben-admin/graphs/contributors">
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ If you think this project is helpful to you, you can help the author buy a cup o

<a style="display: block;width: 100px;height: 50px;line-height: 50px; color: #fff;text-align: center; background: #408aed;border-radius: 4px;" href="https://www.paypal.com/paypalme/cvvben">Paypal Me</a>

## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=vbenjs/vue-vben-admin&type=Date)](https://star-history.com/#vbenjs/vue-vben-admin&Date)

## Contributor

<a href="https://github.com/vbenjs/vue-vben-admin/graphs/contributors">
Expand Down
4 changes: 4 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ pnpm build

[CHANGELOG](https://github.com/vbenjs/vue-vben-admin/releases)

## Star History

[![Star History Chart](https://api.star-history.com/svg?repos=vbenjs/vue-vben-admin&type=Date)](https://star-history.com/#vbenjs/vue-vben-admin&Date)

## Contributor

<a href="https://github.com/vbenjs/vue-vben-admin/graphs/contributors">
Expand Down
6 changes: 2 additions & 4 deletions docs/src/en/guide/essentials/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ The execution command is: `pnpm run [script]` or `npm run [script]`.
```json
{
"scripts": {
// Install dependencies
"bootstrap": "pnpm install",
// Build the project
"build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 turbo build",
// Build the project with analysis
Expand Down Expand Up @@ -107,9 +105,9 @@ The execution command is: `pnpm run [script]` or `npm run [script]`.
// Package specification check
"publint": "vsh publint",
// Delete all node_modules, yarn.lock, package.lock.json, and reinstall dependencies
"reinstall": "pnpm clean --del-lock && pnpm bootstrap",
"reinstall": "pnpm clean --del-lock && pnpm install",
// Run vitest unit tests
"test:unit": "vitest",
"test:unit": "vitest run --dom",
// Update project dependencies
"update:deps": " pnpm update --latest --recursive",
// Changeset generation and versioning
Expand Down
6 changes: 2 additions & 4 deletions docs/src/guide/essentials/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ npm 脚本是项目常见的配置,用于执行一些常见的任务,比如
```json
{
"scripts": {
// 安装依赖
"bootstrap": "pnpm install",
// 构建项目
"build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 turbo build",
// 构建项目并分析
Expand Down Expand Up @@ -107,9 +105,9 @@ npm 脚本是项目常见的配置,用于执行一些常见的任务,比如
// 包规范检查
"publint": "vsh publint",
// 删除所有的node_modules、yarn.lock、package.lock.json,重新安装依赖
"reinstall": "pnpm clean --del-lock && pnpm bootstrap",
"reinstall": "pnpm clean --del-lock && pnpm install",
// 运行 vitest 单元测试
"test:unit": "vitest",
"test:unit": "vitest run --dom",
// 更新项目依赖
"update:deps": " pnpm update --latest --recursive",
// changeset生成提交集
Expand Down
1 change: 1 addition & 0 deletions internal/lint-configs/eslint-config/src/configs/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export async function node(): Promise<Linter.Config[]> {
'vite',
'@vue/test-utils',
'@vben/tailwind-config',
'@playwright/test',
],
},
],
Expand Down
8 changes: 8 additions & 0 deletions internal/lint-configs/eslint-config/src/custom-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ const customConfig: Linter.Config[] = [
'unicorn/prefer-module': 'off',
},
},
{
files: ['**/**/playwright.config.ts'],
rules: {
'n/prefer-global/buffer': 'off',
'n/prefer-global/process': 'off',
'no-console': 'off',
},
},
{
files: ['internal/**/**'],
rules: {
Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@
},
"type": "module",
"scripts": {
"bootstrap": "pnpm install",
"build": "cross-env NODE_OPTIONS=--max-old-space-size=8192 turbo build",
"build:analyze": "turbo build:analyze",
"build:docker": "./build-local-docker-image.sh",
"build:antd": "pnpm run build --filter=@vben/web-antd",
"build:docker": "./build-local-docker-image.sh",
"build:docs": "pnpm run build --filter=@vben/docs",
"build:ele": "pnpm run build --filter=@vben/web-ele",
"build:naive": "pnpm run build --filter=@vben/web-naive",
Expand All @@ -55,15 +54,16 @@
"prepare": "is-ci || husky",
"preview": "turbo-run preview",
"publint": "vsh publint",
"reinstall": "pnpm clean --del-lock && pnpm bootstrap",
"test:unit": "vitest",
"reinstall": "pnpm clean --del-lock && pnpm install",
"test:unit": "vitest run --dom",
"test:e2e": "turbo run test:e2e",
"update:deps": "pnpm update --latest --recursive",
"version": "pnpm exec changeset version && pnpm install --no-frozen-lockfile"
},
"devDependencies": {
"@changesets/changelog-github": "catalog:",
"@changesets/cli": "catalog:",
"@types/jsdom": "catalog:",
"@playwright/test": "catalog:",
"@types/node": "catalog:",
"@vben/commitlint-config": "workspace:*",
"@vben/eslint-config": "workspace:*",
Expand All @@ -80,10 +80,11 @@
"autoprefixer": "catalog:",
"cross-env": "catalog:",
"cspell": "catalog:",
"happy-dom": "catalog:",
"husky": "catalog:",
"is-ci": "catalog:",
"jsdom": "catalog:",
"lint-staged": "catalog:",
"playwright": "catalog:",
"rimraf": "catalog:",
"tailwindcss": "catalog:",
"turbo": "catalog:",
Expand Down Expand Up @@ -113,8 +114,7 @@
},
"neverBuiltDependencies": [
"canvas",
"node-gyp",
"playwright"
"node-gyp"
]
}
}
8 changes: 4 additions & 4 deletions packages/@core/ui-kit/shadcn-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"name": "@vben-core/shadcn-ui",
"version": "5.3.0",
"#main": "./dist/index.mjs",
"#module": "./dist/index.mjs",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {
Expand All @@ -20,16 +22,14 @@
"sideEffects": [
"**/*.css"
],
"#main": "./dist/index.mjs",
"main": "./src/index.ts",
"#module": "./dist/index.mjs",
"module": "./src/index.ts",
"exports": {
".": {
"types": "./src/index.ts",
"development": "./src/index.ts",
"//default": "./dist/index.mjs",
"default": "./src/index.ts"
"default": "./src/index.ts",
"//default": "./dist/index.mjs"
}
},
"publishConfig": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ defineExpose({
}"
:style="style"
class="bg-background dark:bg-accent absolute left-0 top-0 flex h-full cursor-move items-center justify-center px-3.5 shadow-md"
name="captcha-action"
>
<Slot :is-passing="isPassing" class="text-foreground/60 size-4">
<slot name="icon">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ function goToLogin() {
:class="{
'cursor-wait': loading,
}"
aria-label="submit"
class="mt-2 w-full"
@click="handleSubmit"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ onMounted(() => {
'cursor-wait': loading,
}"
:loading="loading"
aria-label="login"
class="w-full"
@click="handleSubmit"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ function goToLogin() {
'cursor-wait': loading,
}"
:loading="loading"
aria-label="register"
class="mt-2 w-full"
@click="handleSubmit"
>
Expand Down
20 changes: 20 additions & 0 deletions playground/__tests__/e2e/auth-login.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect, test } from '@playwright/test';

import { authLogin } from './common/auth';

test.beforeEach(async ({ page }) => {
await page.goto('/');
});
anncwb marked this conversation as resolved.
Show resolved Hide resolved

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 changes: 46 additions & 0 deletions playground/__tests__/e2e/common/auth.ts
Original file line number Diff line number Diff line change
@@ -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();
}
5 changes: 4 additions & 1 deletion playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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/*"
Expand Down
Loading