Skip to main content

web-testing

Web testing patterns and best practices using Playwright for automated testing

معلومات المصدر

المستودع
code-yeongyu/sisyphus-private
آخر نشاط في المصدر
٢٠ أكتوبر ٢٠٢٥ في ٠١:٤٩
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
١٩
التفرعات
٢

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
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
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub