Skills Plugins MCP Prompt Model 博客 我的中心

e2e-testing

Playwright E2E 测试模式、页面对象模型、配置、CI/CD 集成、工件管理和不稳定测试策略。

DeepseekModel Curated skill Quality Excellent · 90 v1.0.0

Get

https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-docs-zh-cn-skills-e2e-testing-skill-md&format=skill
Download .skill Standard format with system_prompt and model_config, ready for any agent framework
The actual content of the system_prompt field in the .skill file.
name e2e-testing description Playwright E2E 测试模式、页面对象模型、配置、CI/CD 集成、工件管理和不稳定测试策略。 origin ECC E2E 测试模式 用于构建稳定、快速且可维护的 E2E 测试套件的全面 Playwright 模式。 测试文件组织 tests/ ├── e2e/ │ ├── auth/ │ │ ├── login.spec.ts │ │ ├── logout.spec.ts │ │ └── register.spec.ts │ ├── features/ │ │ ├── browse.spec.ts │ │ ├── search.spec.ts │ │ └── create.spec.ts │ └── api/ │ └── endpoints.spec.ts ├── fixtures/ │ ├── auth.ts │ └── data.ts └── playwright.config.ts 页面对象模型 (POM) import { Page , Locator } from '@playwright/test' export class ItemsPage { readonly page : Page readonly searchInput : Locator readonly itemCards : Locator readonly createButton : Locator constructor ( page : Page ) { this . page = page this . searchInput = page. locator ( '[data-testid="search-input"]' ) this . itemCards = page. locator ( '[data-testid="item-card"]' ) this . createButton = page. locator ( '[data-testid="create-btn"]' ) } async goto ( ) { await this . page . goto ( '/items' ) await this . page . waitForLoadState ( 'networkidle' ) } async search ( query : string ) { await this . searchInput . fill (query) await this . page . waitForResponse ( resp => resp. url (). includes ( '/api/search' )) await this . page . waitForLoadState ( 'networkidle' ) } async getItemCount ( ) { return await this . itemCards . count () } } 测试结构 import { test, expect } from '@playwright/test' import { ItemsPage } from '../../pages/ItemsPage' test. describe ( 'Item Search' , () => { let itemsPage : ItemsPage test. beforeEach ( async ({ page }) => { itemsPage = new ItemsPage (page) await itemsPage. goto () }) test ( 'should search by keyword' , async ({ page }) => { await itemsPage. search ( 'test' ) const count = await itemsPage. getItemCount () expect (count). toBeGreaterThan ( 0 ) await expect (itemsPage. itemCards . first ()). toContainText ( /test/i ) await page. screenshot ({ path : 'artifacts/search-results.png' }) }) test ( 'should handle no results' , async ({ page }) => { await itemsPage. search ( 'xyznonexistent123' ) await expect (page. locator ( '[data-testid="no-results"]' )). toBeVisible () expect ( await itemsPage. getItemCount ()). toBe ( 0 ) }) }) Playwright 配置 import { defineConfig, devices } from '@playwright/test' export default defineConfig ({ testDir : './tests/e2e' , fullyParallel : true , forbidOnly : !!process. env . CI , retries : process. env . CI ? 2 : 0 , workers : process. env . CI ? 1 : undefined , reporter : [ [ 'html' , { outputFolder : 'playwright-report' }], [ 'junit' , { outputFile : 'playwright-results.xml' }], [ 'json' , { outputFile : 'playwright-results.json' }] ], use : { baseURL : process. env . BASE_URL || 'http://localhost:3000' , trace : 'on-first-retry' , screenshot : 'only-on-failure' , video : 'retain-on-failure' , actionTimeout : 10000 , navigationTimeout : 30000 , }, projects : [ { name : 'chromium' , use : { ...devices[ 'Desktop Chrome' ] } }, { name : 'firefox' , use : { ...devices[ 'Desktop Firefox' ] } }, { name : 'webkit' , use : { ...devices[ 'Desktop Safari' ] } }, { name : 'mobile-chrome' , use : { ...devices[ 'Pixel 5' ] } }, ], webServer : { command : 'npm run dev' , url : 'http://localhost:3000' , reuseExistingServer : !process. env . CI , timeout : 120000 , }, }) 不稳定测试模式 隔离 test ( 'flaky: complex search' , async ({ page }) => { test. fixme ( true , 'Flaky - Issue #123' ) // test code... }) test ( 'conditional skip' , async ({ page }) => { test. skip (process. env . CI , 'Flaky in CI - Issue #123' ) // test code... }) 识别不稳定性 npx playwright test tests/search.spec.ts --repeat-each=10 npx playwright test tests/search.spec.ts --retries=3 常见原因与修复 竞态条件: // Bad: assumes element is ready await page. click ( '[data-testid="button"]' ) // Good: auto-wait locator await page. locator ( '[data-testid="button"]' ). click () 网络时序: // Bad: arbitrary timeout await page. waitForTimeout ( 5000 ) // Good: wait for specific condition await page. waitForResponse ( resp => resp. url (). includes ( '/api/data' )) 动画时序: // Bad: click during animation await page. click ( '[data-testid="menu-item"]' ) // Good: wait for stability await page. locator ( '[data-testid="menu-item"]' ). waitFor ({ state : 'visible' }) await page. waitForLoadState ( 'networkidle' ) await page. locator ( '[data-testid="menu-item"]' ). click () 产物管理 截图 await page. screenshot ({ path : 'artifacts/after-login.png' }) await page. screenshot ({ path : 'artifacts/full-page.png' , fullPage : true }) await page. locator ( '[data-testid="chart"]' ). screenshot ({ path : 'artifacts/chart.png' }) 跟踪记录 await browser. startTracing (page, { path : 'artifacts/trace.json' , screenshots : true , snapshots : true , }) // ... test actions ... await browser. stopTracing () 视频 // In playwright.config.ts use : { video : 'retain-on-failure' , videosPath : 'artifacts/videos/' } CI/CD 集成 # .github/workflows/e2e.yml name: E2E Tests on: [ push , pull_request ] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 - run: npm ci - run: npx playwright install --with-deps - run: npx playwright test env: BASE_URL: ${{ vars.STAGING_URL }} - uses: actions/upload-artifact@v4 if: always() with: name: playwright-report path: playwright-report/ retention-days: 30 测试报告模板 # E2E 测试报告 **日期:** YYYY-MM-DD HH:MM **持续时间:** Xm Ys **状态:** 通过 / 失败 ## 概要 - 总计:X | 通过:Y (Z%) | 失败:A | 不稳定:B | 跳过:C ## 失败的测试 ### test-name **文件:** `tests/e2e/feature.spec.ts:45` **错误:** 期望元素可见 **截图:** artifacts/failed.png **建议修复:** [description] ## 产物 - HTML 报告:playwright-report/index.html - 截图:artifacts/ *.png - 视频:artifacts/videos/* .webm - 追踪文件:artifacts/ *.zip 钱包 / Web3 测试 test ( 'wallet connection' , async ({ page, context }) => { // Mock wallet provider await context. addInitScript ( () => { window . ethereum = { isMetaMask : true , request : async ({ method }) => { if (method === 'eth_requestAccounts' ) return [ '0x1234567890123456789012345678901234567890' ] if (method === 'eth_chainId' ) return '0x1' } } }) await page. goto ( '/' ) await page. locator ( '[data-testid="connect-wallet"]' ). click () await expect (page. locator ( '[data-testid="wallet-address"]' )). toContainText ( '0x1234' ) }) 金融 / 关键流程测试 test ( 'trade execution' , async ({ page }) => { // Skip on production — real money test. skip (process. env . NODE_ENV === 'production' , 'Skip on production' ) await page. goto ( '/markets/test-market' ) await page. locator ( '[data-testid="position-yes"]' ). click () await page. locator ( '[data-testid="trade-amount"]' ). fill ( '1.0' ) // Verify preview const preview = page. locator ( '[data-testid="trade-preview"]' ) await expect (preview). toContainText ( '1.0' ) // Confirm and wait for blockchain await page. locator ( '[data-testid="confirm-trade"]' ). click () await page. waitForResponse ( resp => resp. url (). includes ( '/api/trade' ) && resp. status () === 200 , { timeout : 30000 } ) await expect (page. locator ( '[data-testid="trade-success"]' )). toBeVisible () })
Keywords that activate this skill. Click one to copy it.

This skill does not provide trigger words.

The downloaded .skill package contains the following fields.
Field Description
formatFormat tag (skill/v1)
skill_idUnique skill ID
nameSkill name
versionVersion
descriptionDescription
categoryCategories (array)
trigger_wordsTrigger words
tagsTags
sourceSource
source_urlSource URL (this page)
exported_atExported at (set per download)
system_promptSystem prompt body
model_configModel config: provider / model / temperature / max_tokens / top_p
examplesExamples
install_guideImport guide for Coze / Dify / Claude / custom frameworks
The same skill can be exported in different platform formats.
.skill Standard format with system_prompt and model_config, ready for any agent framework Download
.skillpro Enhanced format with scripts, tools, dependencies and hooks Download
.json Plain JSON export with system_prompt and model parameters only Download
Coze Markdown with frontmatter, for Coze platform import Download
Dify Dify DSL, import directly after creating an app Download

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。