Skills Plugins MCP Prompt Model 博客 我的中心
開発 #writing #testing

e2e-testing

Playwright E2E testing patterns, Page Object Model, configuration, CI/CD integration, artifact management, and flaky test strategies. Use when writing Playwright tests, structuring page objects, or fixing flaky E2E runs in CI.

DeepseekModel キュレーション済みスキル 品質 優秀 · 90 v1.0.0

取得

https://deepseekmodel.com/api/download.php?id=affaan-m-ecc-agents-skills-e2e-testing-skill-md&format=skill
ダウンロード .skill 標準形式。system_prompt と model_config を収録し、任意の Agent で利用可能
.skill ファイルの system_prompt フィールドの実際の内容。
name e2e-testing description Playwright E2E testing patterns, Page Object Model, configuration, CI/CD integration, artifact management, and flaky test strategies. Use when writing Playwright tests, structuring page objects, or fixing flaky E2E runs in CI. E2E Testing Patterns Comprehensive Playwright patterns for building stable, fast, and maintainable E2E test suites. Test File Organization 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 Page Object Model (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 () } } Test Structure 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 Configuration 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 , }, }) Flaky Test Patterns Quarantine 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... }) Identify Flakiness npx playwright test tests/search.spec.ts --repeat-each=10 npx playwright test tests/search.spec.ts --retries=3 Common Causes & Fixes Race conditions: // Bad: assumes element is ready await page. click ( '[data-testid="button"]' ) // Good: auto-wait locator await page. locator ( '[data-testid="button"]' ). click () Network timing: // Bad: arbitrary timeout await page. waitForTimeout ( 5000 ) // Good: wait for specific condition await page. waitForResponse ( resp => resp. url (). includes ( '/api/data' )) Animation timing: // 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 () Artifact Management Screenshots 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' }) Traces await browser. startTracing (page, { path : 'artifacts/trace.json' , screenshots : true , snapshots : true , }) // ... test actions ... await browser. stopTracing () Video // In playwright.config.ts use : { video : 'retain-on-failure' , videosPath : 'artifacts/videos/' } CI/CD Integration # .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 Test Report Template # E2E Test Report **Date:** YYYY-MM-DD HH:MM **Duration:** Xm Ys **Status:** PASSING / FAILING ## Summary - Total: X | Passed: Y (Z%) | Failed: A | Flaky: B | Skipped: C ## Failed Tests ### test-name **File:** `tests/e2e/feature.spec.ts:45` **Error:** Expected element to be visible **Screenshot:** artifacts/failed.png **Recommended Fix:** [description] ## Artifacts - HTML Report: playwright-report/index.html - Screenshots: artifacts/ *.png - Videos: artifacts/videos/* .webm - Traces: artifacts/ *.zip Wallet / Web3 Testing 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' ) }) Financial / Critical Flow Testing 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 () })
このスキルを起動するキーワード。クリックでコピーできます。

このスキルにはトリガーワードがありません。

ダウンロードした .skill に含まれるフィールド。
フィールド 説明
formatフォーマット識別子(skill/v1)
skill_idスキル固有 ID
nameスキル名
versionバージョン
description説明
categoryカテゴリ(配列)
trigger_wordsトリガーワード
tagsタグ
sourceソース
source_urlソース URL(本ページ)
exported_atエクスポート日時(ダウンロード毎)
system_promptシステムプロンプト本文
model_configモデル設定:provider / model / temperature / max_tokens / top_p
examplesサンプル
install_guide各プラットフォームの導入説明(Coze / Dify / Claude / カスタム)
同じスキルを各プラットフォーム形式で出力できます。
.skill 標準形式。system_prompt と model_config を収録し、任意の Agent で利用可能 ダウンロード
.skillpro 拡張形式。scripts / tools / dependencies / hooks を含む ダウンロード
.json 純粋な JSON 出力。system_prompt とモデル設定のみ ダウンロード
Coze frontmatter 付き Markdown。Coze へのインポート用 ダウンロード
Dify Dify DSL。アプリ作成後にそのままインポート ダウンロード

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

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

验证码 --

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

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