AI студия Владимира Ломтева
УСЛУГИПРОЕКТЫСТАТЬИБАЗА ЗНАНИЙМаркетплейсПолезные сервисы

Оставьте заявку,
чтобы обсудить проект

Напишите ваш вопрос, не забудьте указать телефон. Мы перезвоним и все расскажем.

Контакты

Москва

Работаем по всей России
и миру (онлайн)

+7 (999) 760-24-41

Ежедневно с 9:00 до 21:00

lamooof@gmail.com

По вопросам сотрудничества

TelegramWhatsApp

Есть предложение?

Напишите нам в мессенджеры

© 2025 AI студия Владимира Ломтева

Политика конфиденциальностиСогласие на обработку ПДн|ИНН 623412173261

    E2e Testing

    End to end testing patterns with Playwright for full stack Python/React applications. Use when writing E2E tests for complete user workflows (login, CRUD, navigation), critical path regression tests, or cross browser validation. Covers test structure, page object model, selector strategy (data testid role label), wait strategies, auth state reuse, test data management, and CI integration. Does NOT cover unit tests or component tests (use pytest patterns or react testing patterns).

    Скиллы для разработки#GitHub#hieutrtr/ai1-skills#skills.sh
    Скачивания
    0
    В избранном
    0
    Комментарии
    0
    Просмотры
    2

    Установить скилл

    Добавьте инструмент одной командой или скачайте проверенный архив версии.

    npx skills add hieutrtr/ai1-skills --skill e2e-testing
    Скачать ZIP
    Версия
    1.0.0+d8244c1acdb4
    Автор
    Владимир Ломтев
    Репозиторий
    hieutrtr/ai1-skills
    GitHub: hieutrtr/ai1-skills

    Как установить

    1. 1Скопируйте команду из блока установки.
    2. 2Запустите её в терминале из каталога проекта.

    Документация

    E2E Testing

    When to Use

    Activate this skill when:

    • Writing E2E tests for complete user workflows (login, CRUD operations, multi-page flows)
    • Creating critical path regression tests that validate the full stack
    • Testing cross-browser compatibility (Chromium, Firefox, WebKit)
    • Validating authentication flows end-to-end
    • Testing file upload/download workflows
    • Writing smoke tests for deployment verification

    Do NOT use this skill for:

    • React component unit tests (use react-testing-patterns)
    • Python backend unit/integration tests (use pytest-patterns)
    • TDD workflow enforcement (use tdd-workflow)
    • API contract testing without a browser (use pytest-patterns with httpx)

    Instructions

    Test Structure

    e2e/
    ├── playwright.config.ts         # Global Playwright configuration
    ├── fixtures/
    │   ├── auth.fixture.ts          # Authentication state setup
    │   └── test-data.fixture.ts     # Test data creation/cleanup
    ├── pages/
    │   ├── base.page.ts             # Base page object with shared methods
    │   ├── login.page.ts            # Login page object
    │   ├── users.page.ts            # Users list page object
    │   └── user-detail.page.ts     # User detail page object
    ├── tests/
    │   ├── auth/
    │   │   ├── login.spec.ts
    │   │   └── logout.spec.ts
    │   ├── users/
    │   │   ├── create-user.spec.ts
    │   │   ├── edit-user.spec.ts
    │   │   └── list-users.spec.ts
    │   └── smoke/
    │       └── critical-paths.spec.ts
    └── utils/
        ├── api-helpers.ts           # Direct API calls for test setup
        └── test-constants.ts        # Shared constants
    

    Naming conventions:

    • Test files: <feature>.spec.ts
    • Page objects: <page-name>.page.ts
    • Fixtures: <concern>.fixture.ts
    • Test names: human-readable sentences describing the user action and expected outcome

    Page Object Model

    Every page gets a page object class that encapsulates selectors and actions. Tests never interact with selectors directly.

    Base page object:

    // e2e/pages/base.page.ts
    import { type Page, type Locator } from "@playwright/test";
    
    export abstract class BasePage {
      constructor(protected readonly page: Page) {}
    
      /** Navigate to the page's URL. */
      abstract goto(): Promise<void>;
    
      /** Wait for the page to be fully loaded. */
      async waitForLoad(): Promise<void> {
        await this.page.waitForLoadState("networkidle");
      }
    
      /** Get a toast/notification message. */
      get toast(): Locator {
        return this.page.getByRole("alert");
      }
    
      /** Get the page heading. */
      get heading(): Locator {
        return this.page.getByRole("heading", { level: 1 });
      }
    }
    

    Concrete page object:

    // e2e/pages/users.page.ts
    import { type Page, type Locator } from "@playwright/test";
    import { BasePage } from "./base.page";
    
    export class UsersPage extends BasePage {
      // ─── Locators ─────────────────────────────────────────
      readonly createButton: Locator;
      readonly searchInput: Locator;
      readonly userTable: Locator;
    
      constructor(page: Page) {
        super(page);
        this.createButton = page.getByTestId("create-user-btn");
        this.searchInput = page.getByRole("searchbox", { name: /search users/i });
        this.userTable = page.getByRole("table");
      }
    
      // ─── Actions ──────────────────────────────────────────
      async goto(): Promise<void> {
        await this.page.goto("/users");
        await this.waitForLoad();
      }
    
      async searchFor(query: string): Promise<void> {
        await this.searchInput.fill(query);
        // Wait for search results to update (debounced)
        await this.page.waitForResponse("**/api/v1/users?*");
      }
    
      async clickCreateUser(): Promise<void> {
        await this.createButton.click();
      }
    
      async getUserRow(email: string): Promise<Locator> {
        return this.userTable.getByRole("row").filter({ hasText: email });
      }
    
      async getUserCount(): Promise<number> {
        // Subtract 1 for header row
        return (await this.userTable.getByRole("row").count()) - 1;
      }
    }
    

    Rules for page objects:

    • One page object per page or major UI section
    • Locators are public readonly properties
    • Actions are async methods
    • Page objects never contain assertions -- tests assert
    • Page objects handle waits internally after actions

    Selector Strategy

    Priority order (highest to lowest):

    Priority Selector Example When to Use
    1 data-testid getByTestId("submit-btn") Interactive elements, dynamic content
    2 Role getByRole("button", { name: /save/i }) Buttons, links, headings, inputs
    3 Label getByLabel("Email") Form inputs with labels
    4 Placeholder getByPlaceholder("Search...") Search inputs
    5 Text getByText("Welcome back") Static text content

    NEVER use:

    • CSS selectors (.class-name, #id) -- brittle, break on styling changes
    • XPath (//div[@class="foo"]) -- unreadable, extremely brittle
    • DOM structure selectors (div > span:nth-child(2)) -- break on layout changes

    Adding data-testid attributes:

    // In React components -- add data-testid to interactive elements
    <button data-testid="create-user-btn" onClick={handleCreate}>
      Create User
    </button>
    
    // Convention: kebab-case, descriptive
    // Pattern: <action>-<entity>-<element-type>
    // Examples: create-user-btn, user-email-input, delete-confirm-dialog
    

    Wait Strategies

    NEVER use hardcoded waits:

    // BAD: Hardcoded wait -- flaky, slow
    await page.waitForTimeout(3000);
    
    // BAD: Sleep
    await new Promise((resolve) => setTimeout(resolve, 2000));
    

    Use explicit wait conditions:

    // GOOD: Wait for a specific element to appear
    await page.getByRole("heading", { name: "Dashboard" }).waitFor();
    
    // GOOD: Wait for navigation
    await page.waitForURL("/dashboard");
    
    // GOOD: Wait for API response
    await page.waitForResponse(
      (response) =>
        response.url().includes("/api/v1/users") && response.status() === 200,
    );
    
    // GOOD: Wait for network to settle
    await page.waitForLoadState("networkidle");
    
    // GOOD: Wait for element state
    await page.getByTestId("submit-btn").waitFor({ state: "visible" });
    await page.getByTestId("loading-spinner").waitFor({ state: "hidden" });
    

    Auto-waiting: Playwright auto-waits for elements to be actionable before clicking, filling, etc. Explicit waits are needed only for assertions or complex state transitions.

    Auth State Reuse

    Avoid logging in before every test. Save auth state and reuse it.

    Setup auth state once:

    // e2e/fixtures/auth.fixture.ts
    import { test as base } from "@playwright/test";
    import path from "path";
    
    const AUTH_STATE_PATH = path.resolve("e2e/.auth/user.json");
    
    export const setup = base.extend({});
    
    setup("authenticate", async ({ page }) => {
      // Perform real login
      await page.goto("/login");
      await page.getByLabel("Email").fill("testuser@example.com");
      await page.getByLabel("Password").fill("TestPassword123!");
      await page.getByRole("button", { name: /sign in/i }).click();
    
      // Wait for auth to complete
      await page.waitForURL("/dashboard");
    
      // Save signed-in state
      await page.context().storageState({ path: AUTH_STATE_PATH });
    });
    

    Reuse in tests:

    // playwright.config.ts
    export default defineConfig({
      projects: [
        // Setup project runs first and saves auth state
        { name: "setup", testDir: "./e2e/fixtures", testMatch: "auth.fixture.ts" },
        {
          name: "chromium",
          use: {
            storageState: "e2e/.auth/user.json",  // Reuse auth state
          },
          dependencies: ["setup"],
        },
      ],
    });
    

    Test Data Management

    Principles:

    • Tests create their own data (never depend on pre-existing data)
    • Tests clean up after themselves (or use API to reset)
    • Use API calls for setup, not UI interactions (faster, more reliable)

    API helpers for test data:

    // e2e/utils/api-helpers.ts
    import { type APIRequestContext } from "@playwright/test";
    
    export class TestDataAPI {
      constructor(private request: APIRequestContext) {}
    
      async createUser(data: { email: string; displayName: string }) {
        const response = await this.request.post("/api/v1/users", { data });
        return response.json();
      }
    
      async deleteUser(userId: number) {
        await this.request.delete(`/api/v1/users/${userId}`);
      }
    
      async createOrder(userId: number, items: Array<Record<string, unknown>>) {
        const response = await this.request.post("/api/v1/orders", {
          data: { user_id: userId, items },
        });
        return response.json();
      }
    }
    

    Usage in tests:

    test("edit user name", async ({ page, request }) => {
      const api = new TestDataAPI(request);
    
      // Setup: create user via API (fast)
      const user = await api.createUser({
        email: "edit-test@example.com",
        displayName: "Before Edit",
      });
    
      try {
        // Test: edit via UI
        const usersPage = new UsersPage(page);
        await usersPage.goto();
        // ... perform edit via UI ...
      } finally {
        // Cleanup: remove test data
        await api.deleteUser(user.id);
      }
    });
    

    Debugging Flaky Tests

    1. Use trace viewer for failures:

    // playwright.config.ts
    use: {
      trace: "on-first-retry",  // Capture trace only on retry
    }
    

    View trace: npx playwright show-trace trace.zip

    2. Run in headed mode for debugging:

    npx playwright test --headed --debug tests/users/create-user.spec.ts
    

    3. Common causes of flaky tests:

    Cause Fix
    Hardcoded waits Use explicit wait conditions
    Shared test data Each test creates its own data
    Animation interference Set animations: "disabled" in config
    Race conditions Wait for API responses before assertions
    Viewport-dependent behavior Set explicit viewport in config
    Session leaks between tests Use storageState correctly, clear cookies

    4. Retry strategy:

    // playwright.config.ts
    export default defineConfig({
      retries: process.env.CI ? 2 : 0,  // Retry in CI only
    });
    

    CI Configuration

    ## .github/workflows/e2e.yml
    name: E2E Tests
    on:
      push:
        branches: [main]
      pull_request:
        branches: [main]
    
    jobs:
      e2e:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: actions/setup-node@v4
            with:
              node-version: 20
              cache: npm
    
          - name: Install dependencies
            run: npm ci
    
          - name: Install Playwright browsers
            run: npx playwright install --with-deps chromium
    
          - name: Start application
            run: |
              docker compose up -d
              npx wait-on http://localhost:3000 --timeout 60000
    
          - name: Run E2E tests
            run: npx playwright test
    
          - name: Upload test report
            if: always()
            uses: actions/upload-artifact@v4
            with:
              name: playwright-report
              path: playwright-report/
              retention-days: 14
    
          - name: Upload traces on failure
            if: failure()
            uses: actions/upload-artifact@v4
            with:
              name: test-traces
              path: test-results/
    

    Use scripts/run-e2e-with-report.sh to run Playwright with HTML report output locally.

    Examples

    See references/page-object-template.ts for annotated page object class. See references/e2e-test-template.ts for annotated E2E test. See references/playwright-config-example.ts for production Playwright config.

    Требования и возможности

    Источник пакета
    https://github.com/hieutrtr/ai1-skills/tree/d8244c1acdb4e4fac55de84dd49887e91bf7b941/skills/e2e-testing

    Файлы версии

    ПутьРазмерSHA256
    SKILL.md12476d43d4ab0d740a1ce...
    references/e2e-test-template.ts7242bc4589eeb0b12bf3...
    references/page-object-template.ts6664f9eb943581bce461...
    references/playwright-config-example.ts4740d50cb8dea71d4d82...
    scripts/run-e2e-with-report.sh396605130dc5c2102192...

    Частые вопросы

    Как установить E2e Testing?
    Используйте команду npx skills add hieutrtr/ai1-skills --skill e2e-testing или скачайте ZIP-архив.
    Можно ли скачать E2e Testing бесплатно?
    Да, опубликованную версию можно скачать из маркетплейса бесплатно.

    Похожие инструменты

    Смотреть все
    React DoctorUse when finishing a feature, fixing a bug, before committing React code, or when the user types `/doctor`, asks to scan, triage, or clean up React diagnostics. Covers lint, accessibility, bundle size, architecture. Includes a regression check and a full local-triage workflow that fetches the canonical playbook.Argent Android Emulator SetupSet up and connect to an Android emulator using argent MCP tools. Use when starting a new session on Android, booting an emulator, getting a device serial, or before any UI interaction task.Fireworks Tech GraphCreate technical diagrams such as software architecture, data flow, flowcharts, sequence diagrams, C4 reviews, cloud deployments, event streams, observability investigations, agent/memory systems, UML, ER, network topology, timelines, and technical concept maps, then export SVG, PNG, focused semantic SVG-to-GIF motion, or offline interactive HTML. Treat direct requests such as "Generate a GIF", "生成 GIF", or "制作 GIF" as motion requests, and use this skill when the user asks to visualize a system or engineering concept. Do not use for photos, raster artwork, or quantitative data charts.
    Комментарии

    Войдите, чтобы оставить комментарий.

    Комментариев пока нет.

    Установить скилл

    Добавьте инструмент одной командой или скачайте проверенный архив версии.

    npx skills add hieutrtr/ai1-skills --skill e2e-testing
    Скачать ZIP
    Версия
    1.0.0+d8244c1acdb4
    Автор
    Владимир Ломтев
    Репозиторий
    hieutrtr/ai1-skills
    GitHub: hieutrtr/ai1-skills
    Modern Web GuidanceSearch tool for modern web development best practices. MANDATORY: Execute FIRST for all HTML/CSS and clientside JS tasks. Do NOT skip — web APIs evolve rapidly and training weights contain obsolete patterns.
    E2e Testing — Скилл для ИИ-агентов | AI Рассвет