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 / カスタム) |