Skip to main content

web-testing

Web testing patterns and best practices using Playwright for automated testing

Quellinformationen

Repository
code-yeongyu/sisyphus-private
Letzte Quellaktivität
20. Oktober 2025 um 01:49
Erkannte Sprache von SKILL.md
Englisch
Sterne
19
Forks
2

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
web-testing
description
Web testing patterns and best practices using Playwright for automated testing
# Web Testing with Playwright This skill covers comprehensive web testing patterns using Playwright, including test structure, assertions, mocking, and best practices for reliable automated testing. ## Test Structure ### Basic Test Organization ```javascript import { test, expect } from '@playwright/test'; test.describe('User Authentication', () => { test.beforeEach(async ({ page }) => { await page.goto('https://example.com/login'); }); test('should login with valid credentials', async ({ page }) => { const username = 'testuser@example.com'; const password = 'SecurePass123'; await page.fill('input[name="email"]', username); await page.fill('input[name="password"]', password); await page.click('button[type="submit"]'); await expect(page).toHaveURL(/.*dashboard/); await expect(page.locator('.welcome-message')).toBeVisible(); }); test('should show error with invalid credentials', async ({ page }) => { await page.fill('input[name="email"]', 'wrong@example.com'); await page.fill('input[name="password"]', 'wrongpass'); await page.click('button[type="submit"]'); await expect(page.locator('.error-message')).toContainText('Invalid credentials'); }); }); ``` ### Test Hooks and Lifecycle ```javascript import { test } from '@playwright/test'; test.describe('E-commerce Checkout', () => { test.beforeAll(async ({ browser }) => { console.log('Setting up test database'); }); test.beforeEach(async ({ page }) => { await page.goto('https://example.com'); await page.fill('input[name="email"]', 'test@example.com'); await page.fill('input[name="password"]', 'password123'); await page.click('button[type="submit"]'); }); test.afterEach(async ({ page }) => { await page.click('[data-testid="clear-cart"]'); }); test.afterAll(async () => { console.log('Cleaning up test database'); }); test('should add item to cart', async ({ page }) => { await page.click('[data-product-id="123"]'); await page.click('button:has-text("Add to Cart")'); await expect(page.locator('.cart-count')).toHaveText('1'); }); }); ``` ### Parameterized Tests ```javascript import { test, expect } from '@playwright/test'; const testData = [ { input: 'john@example.com', expected: true }, { input: 'invalid-email', expected: false }, { input: 'another@test.co.uk', expected: true }, { input: '@nodomain.com', expected: false } ]; testData.forEach(({ input, expected }) => { test(`should validate email: ${input}`, async ({ page }) => { await page.goto('https://example.com/signup'); await page.fill('input[name="email"]', input); await page.click('button[type="submit"]'); if (expected) { await expect(page.locator('.error-message')).not.toBeVisible(); } else { await expect(page.locator('.error-message')).toBeVisible(); } }); }); ``` ### Test Fixtures ```javascript import { test as base, expect } from '@playwright/test'; const test = base.extend({ authenticatedPage: async ({ page }, use) => { await page.goto('https://example.com/login'); await page.fill('input[name="email"]', 'test@example.com'); await page.fill('input[name="password"]', 'password123'); await page.click('button[type="submit"]'); await page.waitForURL('**/dashboard'); await use(page); await page.click('[data-testid="logout"]'); } }); test('should access protected resource', async ({ authenticatedPage }) => { await authenticatedPage.goto('https://example.com/profile'); await expect(authenticatedPage.locator('h1')).toContainText('My Profile'); }); ``` ## Assertions ### Element Visibility Assertions ```javascript import { test, expect } from '@playwright/test'; test('element visibility checks', async ({ page }) => { await page.goto('https://example.com'); await expect(page.locator('.header')).toBeVisible(); await expect(page.locator('.modal')).toBeHidden(); await expect(page.locator('.hidden-div')).toBeAttached(); await expect(page.locator('.removed-element')).not.toBeAttached(); }); ``` ### Text Content Assertions ```javascript test('text content checks', async ({ page }) => { await page.goto('https://example.com'); await expect(page.locator('h1')).toHaveText('Welcome'); await expect(page.locator('.description')).toContainText('product'); await expect(page.locator('.price')).toHaveText(/\$\d+\.\d{2}/); await expect(page.locator('.item-title')).toHaveText([ 'Item 1', 'Item 2', 'Item 3' ]); }); ``` ### Attribute and State Assertions ```javascript test('attribute and state checks', async ({ page }) => { await page.goto('https://example.com/form'); await expect(page.locator('input[name="email"]')).toHaveAttribute('type', 'email'); await expect(page.locator('.button')).toHaveClass(/primary/); await expect(page.locator('.list-item')).toHaveCount(5); await expect(page.locator('input[name="username"]')).toHaveValue('john.doe'); await expect(page.locator('input[type="checkbox"]')).toBeChecked(); await expect(page.locator('input[type="checkbox"]')).not.toBeChecked(); await expect(page.locator('button[type="submit"]')).toBeEnabled(); await expect(page.locator('button.disabled')).toBeDisabled(); await expect(page.locator('input[name="email"]')).toBeEditable(); }); ``` ### URL and Page Assertions ```javascript test('URL and page checks', async ({ page }) => { await page.goto('https://example.com/products'); await expect(page).toHaveURL('https://example.com/products'); await expect(page).toHaveURL(/.*products/); await expect(page).toHaveTitle('Products - Example Store'); await expect(page).toHaveTitle(/Products/); }); ``` ### Custom Assertions ```javascript test('custom assertions', async ({ page }) => { await page.goto('https://example.com/cart'); const cartTotal = await page.locator('.cart-total').textContent(); expect(parseFloat(cartTotal.replace('$', ''))).toBeGreaterThan(0); await expect.soft(page.locator('.item')).toHaveCount(3); await expect.soft(page.locator('.discount-badge')).toBeVisible(); const element = page.locator('.product'); await expect(element).toBeVisible(); await expect(element).toContainText('Special Offer'); await expect(element).toHaveClass('highlighted'); }); ``` ## Mocking ### Network Request Interception ```javascript import { test, expect } from '@playwright/test'; test('mock API response', async ({ page }) => { await page.route('**/api/products', route => { route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify([ { id: 1, name: 'Mocked Product 1', price: 19.99 }, { id: 2, name: 'Mocked Product 2', price: 29.99 } ]) }); }); await page.goto('https://example.com/products'); await expect(page.locator('.product').first()).toContainText('Mocked Product 1'); }); ``` ### Conditional Mocking ```javascript test('conditional network mocking', async ({ page }) => { await page.route('**/api/**', route => { const url = route.request().url(); if (url.includes('/api/slow-endpoint')) { route.fulfill({ status: 200, body: JSON.stringify({ data: 'fast response' }) }); } else if (url.includes('/api/error-prone')) { route.fulfill({ status: 500 }); } else { route.continue(); } }); await page.goto('https://example.com'); }); ``` ### Request Modification ```javascript test('modify outgoing requests', async ({ page }) => { await page.route('**/api/data', route => { const headers = { ...route.request().headers(), 'Authorization': 'Bearer mock-token-123' }; route.continue({ headers }); }); await page.goto('https://example.com/dashboard'); }); ``` ### Response Delays ```javascript test('simulate slow network', async ({ page }) => { await page.route('**/api/products', async route => { await new Promise(resolve => setTimeout(resolve, 3000)); await route.fulfill({ status: 200, body: JSON.stringify({ products: [] }) }); }); await page.goto('https://example.com/products'); await expect(page.locator('.loading-spinner')).toBeVisible(); }); ``` ## Best Practices ### Reliable Selectors ```javascript // GOOD: Use test IDs
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen