[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EMASPZWNKEKXKXZ234QNWB":3,"skill-same:01M6EMASPZWNKEKXKXZ234QNWB":149},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":34,"publishedAt":55,"linkOnly":56,"markdownContent":57,"markdownBody":58,"frontMatter":59,"refName":60,"commitSha":61,"skillDirectory":62,"forksCount":63,"repositoryHtmlUrl":64,"repositoryHomepageUrl":65,"ownerHtmlUrl":66,"ownerBlogUrl":6,"ownerDescription":67,"updatedAt":68,"install":69,"resources":82},"01M6EMASPZWNKEKXKXZ234QNWB","webapp-testing",null,"Professional web application testing and automation using Playwright with support for multiple browsers, mobile emulation, screenshot capture, network interception, and comprehensive test assertions. Use for: (1) E2E testing across browsers, (2) UI automation, (3) Form testing and validation, (4) Visual regression testing, (5) API mocking and interception, (6) Mobile responsive testing","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002FSKILL.md",[18,23,26,29],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":30,"categoryName":31,"taxonomyType":32,"taxonomyTypeDesc":33},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54],"webapp testing","testing","webapp","mocking","form","professional","responsive","across","visual regression","screenshot capture","mobile","use","regression","api","e2e","network","ui","screenshot","automation","support","2026-11-10 10:12:30",false,"---\nname: webapp-testing\ndescription: \"Professional web application testing and automation using Playwright with support for multiple browsers, mobile emulation, screenshot capture, network interception, and comprehensive test assertions. Use for: (1) E2E testing across browsers, (2) UI automation, (3) Form testing and validation, (4) Visual regression testing, (5) API mocking and interception, (6) Mobile responsive testing\"\n---\n\n# Web Application Testing with Playwright\n\n## Overview\n\nPlaywright is a powerful framework for web testing and automation that supports all modern browsers (Chromium, Firefox, WebKit). It provides reliable, fast, and capable automation with auto-waiting, network control, and comprehensive testing capabilities.\n\nUse this skill when you need to:\n- Create end-to-end tests for web applications\n- Automate browser interactions and workflows\n- Test across multiple browsers and devices\n- Verify UI\u002FUX functionality and accessibility\n- Mock APIs and intercept network requests\n- Capture screenshots and videos for debugging\n\n## Core Capabilities\n\n### Multi-Browser Testing\n- Chromium (Chrome, Edge, Brave)\n- Firefox (Mozilla Firefox)\n- WebKit (Safari engine)\n- Cross-browser compatibility testing\n- Parallel execution across browsers\n\n### Element Interaction\n- Click, double-click, right-click\n- Type text with realistic keyboard simulation\n- Select dropdowns and checkboxes\n- Hover and focus interactions\n- Drag and drop operations\n- File uploads and downloads\n\n### Assertions & Verification\n- Element visibility and state checks\n- Text content verification\n- Attribute validation\n- URL and navigation assertions\n- Custom expect matchers\n- Soft assertions for multiple checks\n\n### Screenshot & Video Capture\n- Full page screenshots\n- Element-specific captures\n- Video recording of test sessions\n- Visual comparison testing\n- Trace files for debugging\n\n### Network Interception\n- Mock API responses\n- Intercept and modify requests\n- Monitor network traffic\n- Test offline scenarios\n- Performance monitoring\n\n### Mobile Device Emulation\n- 100+ device presets (iPhone, Pixel, iPad, etc.)\n- Custom viewport configurations\n- Touch event simulation\n- Geolocation testing\n- Orientation changes\n\n## Core Testing Workflow\n\n### 1. Basic Test Setup\n\nCreate a simple test with Playwright's auto-waiting:\n\n```python\nimport pytest\nfrom playwright.sync_api import Page, expect\n\ndef test_homepage_loads(page: Page):\n    \"\"\"Test that homepage loads successfully.\"\"\"\n    page.goto(\"https:\u002F\u002Fexample.com\")\n    expect(page).to_have_title(\"Example Domain\")\n    expect(page.locator(\"h1\")).to_contain_text(\"Example Domain\")\n\ndef test_navigation(page: Page):\n    \"\"\"Test navigation between pages.\"\"\"\n    page.goto(\"https:\u002F\u002Fexample.com\")\n    page.click(\"text=More information\")\n    expect(page).to_have_url(\"https:\u002F\u002Fwww.iana.org\u002Fdomains\u002Freserved\")\n```\n\n### 2. Form Interactions\n\nTest form filling, validation, and submission:\n\n```python\ndef test_login_form(page: Page):\n    \"\"\"Test login form submission.\"\"\"\n    page.goto(\"https:\u002F\u002Fexample.com\u002Flogin\")\n\n    # Fill form fields\n    page.fill(\"#username\", \"testuser@example.com\")\n    page.fill(\"#password\", \"SecurePassword123\")\n    page.check(\"#remember-me\")\n\n    # Submit and verify\n    page.click(\"button[type='submit']\")\n    expect(page).to_have_url(\"https:\u002F\u002Fexample.com\u002Fdashboard\")\n    expect(page.locator(\".welcome-message\")).to_be_visible()\n```\n\n### 3. API Mocking\n\nMock API responses for controlled testing:\n\n```python\ndef test_with_mocked_api(page: Page):\n    \"\"\"Test with mocked API response.\"\"\"\n    # Mock API response\n    page.route(\"**\u002Fapi\u002Fuser\", lambda route: route.fulfill(\n        status=200,\n        content_type=\"application\u002Fjson\",\n        body='{\"name\": \"Test User\", \"premium\": true}'\n    ))\n\n    page.goto(\"https:\u002F\u002Fexample.com\u002Fprofile\")\n    expect(page.locator(\".user-name\")).to_contain_text(\"Test User\")\n```\n\n### 4. Mobile Emulation\n\nTest responsive designs on mobile devices:\n\n```python\n@pytest.fixture\ndef mobile_page(playwright):\n    \"\"\"Create mobile browser context.\"\"\"\n    iphone = playwright.devices['iPhone 12']\n    browser = playwright.chromium.launch()\n    context = browser.new_context(**iphone)\n    page = context.new_page()\n    yield page\n    context.close()\n    browser.close()\n\ndef test_mobile_menu(mobile_page: Page):\n    \"\"\"Test mobile navigation.\"\"\"\n    mobile_page.goto(\"https:\u002F\u002Fexample.com\")\n    expect(mobile_page.locator(\".hamburger-menu\")).to_be_visible()\n    mobile_page.click(\".hamburger-menu\")\n    expect(mobile_page.locator(\".mobile-menu\")).to_be_visible()\n```\n\n### 5. Visual Regression\n\nCapture screenshots for visual comparison:\n\n```python\ndef test_homepage_screenshot(page: Page):\n    \"\"\"Capture homepage screenshot.\"\"\"\n    page.goto(\"https:\u002F\u002Fexample.com\")\n\n    # Full page screenshot\n    page.screenshot(path=\"screenshots\u002Fhomepage.png\", full_page=True)\n\n    # Element screenshot\n    page.locator(\"header\").screenshot(path=\"screenshots\u002Fheader.png\")\n\n    # Screenshot with masks for dynamic content\n    page.screenshot(\n        path=\"screenshots\u002Fdashboard.png\",\n        mask=[page.locator(\".timestamp\"), page.locator(\".session-id\")]\n    )\n```\n\n## Key Testing Principles\n\n### Use Reliable Selectors\n\n```python\n# ✅ GOOD: Test IDs and semantic selectors\npage.click(\"[data-testid='submit-button']\")\npage.click(\"button:text('Submit')\")\npage.click(\"role=button[name='Submit']\")\n\n# ❌ BAD: Fragile structural selectors\npage.click(\"div > div > button:nth-child(3)\")\n```\n\n### Leverage Auto-Waiting\n\n```python\n# ✅ GOOD: Playwright auto-waits\npage.click(\"button\")\nexpect(page.locator(\".result\")).to_be_visible()\n\n# ⚠️ Avoid: Manual waits\ntime.sleep(2)  # Only when absolutely necessary\n```\n\n### Ensure Test Isolation\n\n```python\n# ✅ GOOD: Clean state between tests\n@pytest.fixture(autouse=True)\ndef clear_state(page: Page):\n    yield\n    page.context.clear_cookies()\n    page.evaluate(\"localStorage.clear()\")\n```\n\n### Handle Flaky Tests\n\n```python\n# ✅ GOOD: Wait for specific conditions\npage.click(\"button\")\npage.wait_for_selector(\".result\")\nresult = page.locator(\".result\").text_content()\n\n# ✅ GOOD: Use soft assertions\nexpect.soft(page.locator(\".title\")).to_be_visible()\nexpect.soft(page.locator(\".price\")).to_contain_text(\"$\")\n```\n\n## Page Object Model\n\nOrganize tests using the Page Object pattern for maintainability:\n\n```python\nclass LoginPage:\n    \"\"\"Login page object.\"\"\"\n\n    def __init__(self, page: Page):\n        self.page = page\n        self.username_input = page.locator(\"#username\")\n        self.password_input = page.locator(\"#password\")\n        self.submit_button = page.locator(\"button[type='submit']\")\n\n    def login(self, username: str, password: str):\n        \"\"\"Perform login.\"\"\"\n        self.username_input.fill(username)\n        self.password_input.fill(password)\n        self.submit_button.click()\n\n# Use in tests\ndef test_login(page: Page):\n    login_page = LoginPage(page)\n    login_page.login(\"test@example.com\", \"password123\")\n    expect(page).to_have_url(\"\u002Fdashboard\")\n```\n\n## Common Test Patterns\n\n### Authentication\n\n```python\n@pytest.fixture\ndef authenticated_page(page: Page):\n    \"\"\"Provide authenticated session.\"\"\"\n    page.goto(\"https:\u002F\u002Fexample.com\u002Flogin\")\n    page.fill(\"#username\", \"test@example.com\")\n    page.fill(\"#password\", \"password\")\n    page.click(\"button[type='submit']\")\n    page.wait_for_url(\"**\u002Fdashboard\")\n    yield page\n```\n\n### File Operations\n\n```python\n# Upload\npage.set_input_files(\"#file-input\", \"path\u002Fto\u002Ffile.pdf\")\n\n# Download\nwith page.expect_download() as download_info:\n    page.click(\"a:text('Download')\")\ndownload = download_info.value\ndownload.save_as(\"downloads\u002Ffile.pdf\")\n```\n\n### Network Monitoring\n\n```python\nrequests = []\npage.on(\"request\", lambda req: requests.append(req))\npage.goto(\"https:\u002F\u002Fexample.com\")\n\n# Verify API calls were made\napi_requests = [r for r in requests if \"\u002Fapi\u002F\" in r.url]\nassert len(api_requests) > 0\n```\n\n## Running Tests\n\n### Basic Commands\n\n```bash\n# Install Playwright\npip install playwright pytest-playwright\nplaywright install\n\n# Run all tests\npytest tests\u002F\n\n# Run specific browser\npytest --browser chromium --browser firefox\n\n# Run in headed mode (see browser)\npytest --headed\n\n# Debug mode\nPWDEBUG=1 pytest tests\u002Ftest_login.py\n\n# Parallel execution\npytest -n auto\n\n# Generate test code\nplaywright codegen https:\u002F\u002Fexample.com\n```\n\n### Configuration\n\nSee `references\u002Fsetup-configuration.md` for:\n- Complete installation instructions\n- Project structure setup\n- pytest.ini configuration\n- playwright.config.ts for TypeScript\n- CI\u002FCD integration examples\n\n## Quality Standards\n\nEnsure tests meet these criteria:\n- Tests are independent and can run in any order\n- Selectors are reliable (test IDs, semantic selectors)\n- Proper error handling and assertions\n- Screenshots\u002Fvideos captured on failure\n- No hardcoded waits (use auto-waiting)\n- Clean state management between tests\n\n## Additional Resources\n\n### Detailed Documentation\n- [Setup & Configuration](.\u002Freferences\u002Fsetup-configuration.md) - Installation, project structure, and configuration\n- [Best Practices](.\u002Freferences\u002Fbest-practices.md) - Selector strategies, wait patterns, flaky test prevention\n- [Common Pitfalls](.\u002Freferences\u002Fcommon-pitfalls.md) - Race conditions, selector brittleness, cleanup issues\n- [CI\u002FCD Integration](.\u002Freferences\u002Fci-cd-integration.md) - GitHub Actions, Docker, deployment pipelines\n\n### Code Examples\n- [Login Testing](.\u002Fexamples\u002Flogin-testing.md) - Authentication flows and session management\n- [Form Testing](.\u002Fexamples\u002Fform-testing.md) - Form validation, file uploads, dropdowns\n- [E-commerce Testing](.\u002Fexamples\u002Fecommerce-testing.md) - Shopping cart, checkout flows, coupons\n- [API Mocking](.\u002Fexamples\u002Fapi-mocking.md) - Network interception, mocking, monitoring\n- [Mobile Testing](.\u002Fexamples\u002Fmobile-testing.md) - Device emulation, touch events, responsive design\n- [Page Object Model](.\u002Fexamples\u002Fpage-object-model.md) - POM pattern implementation\n\n### Helper Scripts\n- [Playwright Helper](.\u002Fscripts\u002Fplaywright_helper.py) - Utility functions for common Playwright operations\n- [Test Examples](.\u002Fscripts\u002Ftest_examples.py) - Complete test suite examples\n\n### External Resources\n- Official Documentation: https:\u002F\u002Fplaywright.dev\n- Python API: https:\u002F\u002Fplaywright.dev\u002Fpython\u002Fdocs\u002Fintro\n- TypeScript API: https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Fintro\n- Best Practices: https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Fbest-practices\n- Community Discord: https:\u002F\u002Faka.ms\u002Fplaywright\u002Fdiscord\n\n## Troubleshooting\n\n**Tests are flaky:**\n- Use Playwright's auto-waiting instead of manual sleeps\n- Ensure proper wait conditions (`wait_for_selector`, `wait_for_url`)\n- Use `expect()` assertions which auto-retry\n\n**Selectors not finding elements:**\n- Verify element exists with browser DevTools\n- Use Playwright Inspector: `PWDEBUG=1 pytest test.py`\n- Try multiple selector strategies (text, role, test-id)\n\n**Tests slow in CI:**\n- Enable parallel execution: `pytest -n auto`\n- Use headed mode only for debugging\n- Consider browser context reuse for related tests\n\nFor more troubleshooting tips, see [Common Pitfalls](.\u002Freferences\u002Fcommon-pitfalls.md).\n","# Web Application Testing with Playwright\n\n## Overview\n\nPlaywright is a powerful framework for web testing and automation that supports all modern browsers (Chromium, Firefox, WebKit). It provides reliable, fast, and capable automation with auto-waiting, network control, and comprehensive testing capabilities.\n\nUse this skill when you need to:\n- Create end-to-end tests for web applications\n- Automate browser interactions and workflows\n- Test across multiple browsers and devices\n- Verify UI\u002FUX functionality and accessibility\n- Mock APIs and intercept network requests\n- Capture screenshots and videos for debugging\n\n## Core Capabilities\n\n### Multi-Browser Testing\n- Chromium (Chrome, Edge, Brave)\n- Firefox (Mozilla Firefox)\n- WebKit (Safari engine)\n- Cross-browser compatibility testing\n- Parallel execution across browsers\n\n### Element Interaction\n- Click, double-click, right-click\n- Type text with realistic keyboard simulation\n- Select dropdowns and checkboxes\n- Hover and focus interactions\n- Drag and drop operations\n- File uploads and downloads\n\n### Assertions & Verification\n- Element visibility and state checks\n- Text content verification\n- Attribute validation\n- URL and navigation assertions\n- Custom expect matchers\n- Soft assertions for multiple checks\n\n### Screenshot & Video Capture\n- Full page screenshots\n- Element-specific captures\n- Video recording of test sessions\n- Visual comparison testing\n- Trace files for debugging\n\n### Network Interception\n- Mock API responses\n- Intercept and modify requests\n- Monitor network traffic\n- Test offline scenarios\n- Performance monitoring\n\n### Mobile Device Emulation\n- 100+ device presets (iPhone, Pixel, iPad, etc.)\n- Custom viewport configurations\n- Touch event simulation\n- Geolocation testing\n- Orientation changes\n\n## Core Testing Workflow\n\n### 1. Basic Test Setup\n\nCreate a simple test with Playwright's auto-waiting:\n\n```python\nimport pytest\nfrom playwright.sync_api import Page, expect\n\ndef test_homepage_loads(page: Page):\n    \"\"\"Test that homepage loads successfully.\"\"\"\n    page.goto(\"https:\u002F\u002Fexample.com\")\n    expect(page).to_have_title(\"Example Domain\")\n    expect(page.locator(\"h1\")).to_contain_text(\"Example Domain\")\n\ndef test_navigation(page: Page):\n    \"\"\"Test navigation between pages.\"\"\"\n    page.goto(\"https:\u002F\u002Fexample.com\")\n    page.click(\"text=More information\")\n    expect(page).to_have_url(\"https:\u002F\u002Fwww.iana.org\u002Fdomains\u002Freserved\")\n```\n\n### 2. Form Interactions\n\nTest form filling, validation, and submission:\n\n```python\ndef test_login_form(page: Page):\n    \"\"\"Test login form submission.\"\"\"\n    page.goto(\"https:\u002F\u002Fexample.com\u002Flogin\")\n\n    # Fill form fields\n    page.fill(\"#username\", \"testuser@example.com\")\n    page.fill(\"#password\", \"SecurePassword123\")\n    page.check(\"#remember-me\")\n\n    # Submit and verify\n    page.click(\"button[type='submit']\")\n    expect(page).to_have_url(\"https:\u002F\u002Fexample.com\u002Fdashboard\")\n    expect(page.locator(\".welcome-message\")).to_be_visible()\n```\n\n### 3. API Mocking\n\nMock API responses for controlled testing:\n\n```python\ndef test_with_mocked_api(page: Page):\n    \"\"\"Test with mocked API response.\"\"\"\n    # Mock API response\n    page.route(\"**\u002Fapi\u002Fuser\", lambda route: route.fulfill(\n        status=200,\n        content_type=\"application\u002Fjson\",\n        body='{\"name\": \"Test User\", \"premium\": true}'\n    ))\n\n    page.goto(\"https:\u002F\u002Fexample.com\u002Fprofile\")\n    expect(page.locator(\".user-name\")).to_contain_text(\"Test User\")\n```\n\n### 4. Mobile Emulation\n\nTest responsive designs on mobile devices:\n\n```python\n@pytest.fixture\ndef mobile_page(playwright):\n    \"\"\"Create mobile browser context.\"\"\"\n    iphone = playwright.devices['iPhone 12']\n    browser = playwright.chromium.launch()\n    context = browser.new_context(**iphone)\n    page = context.new_page()\n    yield page\n    context.close()\n    browser.close()\n\ndef test_mobile_menu(mobile_page: Page):\n    \"\"\"Test mobile navigation.\"\"\"\n    mobile_page.goto(\"https:\u002F\u002Fexample.com\")\n    expect(mobile_page.locator(\".hamburger-menu\")).to_be_visible()\n    mobile_page.click(\".hamburger-menu\")\n    expect(mobile_page.locator(\".mobile-menu\")).to_be_visible()\n```\n\n### 5. Visual Regression\n\nCapture screenshots for visual comparison:\n\n```python\ndef test_homepage_screenshot(page: Page):\n    \"\"\"Capture homepage screenshot.\"\"\"\n    page.goto(\"https:\u002F\u002Fexample.com\")\n\n    # Full page screenshot\n    page.screenshot(path=\"screenshots\u002Fhomepage.png\", full_page=True)\n\n    # Element screenshot\n    page.locator(\"header\").screenshot(path=\"screenshots\u002Fheader.png\")\n\n    # Screenshot with masks for dynamic content\n    page.screenshot(\n        path=\"screenshots\u002Fdashboard.png\",\n        mask=[page.locator(\".timestamp\"), page.locator(\".session-id\")]\n    )\n```\n\n## Key Testing Principles\n\n### Use Reliable Selectors\n\n```python\n# ✅ GOOD: Test IDs and semantic selectors\npage.click(\"[data-testid='submit-button']\")\npage.click(\"button:text('Submit')\")\npage.click(\"role=button[name='Submit']\")\n\n# ❌ BAD: Fragile structural selectors\npage.click(\"div > div > button:nth-child(3)\")\n```\n\n### Leverage Auto-Waiting\n\n```python\n# ✅ GOOD: Playwright auto-waits\npage.click(\"button\")\nexpect(page.locator(\".result\")).to_be_visible()\n\n# ⚠️ Avoid: Manual waits\ntime.sleep(2)  # Only when absolutely necessary\n```\n\n### Ensure Test Isolation\n\n```python\n# ✅ GOOD: Clean state between tests\n@pytest.fixture(autouse=True)\ndef clear_state(page: Page):\n    yield\n    page.context.clear_cookies()\n    page.evaluate(\"localStorage.clear()\")\n```\n\n### Handle Flaky Tests\n\n```python\n# ✅ GOOD: Wait for specific conditions\npage.click(\"button\")\npage.wait_for_selector(\".result\")\nresult = page.locator(\".result\").text_content()\n\n# ✅ GOOD: Use soft assertions\nexpect.soft(page.locator(\".title\")).to_be_visible()\nexpect.soft(page.locator(\".price\")).to_contain_text(\"$\")\n```\n\n## Page Object Model\n\nOrganize tests using the Page Object pattern for maintainability:\n\n```python\nclass LoginPage:\n    \"\"\"Login page object.\"\"\"\n\n    def __init__(self, page: Page):\n        self.page = page\n        self.username_input = page.locator(\"#username\")\n        self.password_input = page.locator(\"#password\")\n        self.submit_button = page.locator(\"button[type='submit']\")\n\n    def login(self, username: str, password: str):\n        \"\"\"Perform login.\"\"\"\n        self.username_input.fill(username)\n        self.password_input.fill(password)\n        self.submit_button.click()\n\n# Use in tests\ndef test_login(page: Page):\n    login_page = LoginPage(page)\n    login_page.login(\"test@example.com\", \"password123\")\n    expect(page).to_have_url(\"\u002Fdashboard\")\n```\n\n## Common Test Patterns\n\n### Authentication\n\n```python\n@pytest.fixture\ndef authenticated_page(page: Page):\n    \"\"\"Provide authenticated session.\"\"\"\n    page.goto(\"https:\u002F\u002Fexample.com\u002Flogin\")\n    page.fill(\"#username\", \"test@example.com\")\n    page.fill(\"#password\", \"password\")\n    page.click(\"button[type='submit']\")\n    page.wait_for_url(\"**\u002Fdashboard\")\n    yield page\n```\n\n### File Operations\n\n```python\n# Upload\npage.set_input_files(\"#file-input\", \"path\u002Fto\u002Ffile.pdf\")\n\n# Download\nwith page.expect_download() as download_info:\n    page.click(\"a:text('Download')\")\ndownload = download_info.value\ndownload.save_as(\"downloads\u002Ffile.pdf\")\n```\n\n### Network Monitoring\n\n```python\nrequests = []\npage.on(\"request\", lambda req: requests.append(req))\npage.goto(\"https:\u002F\u002Fexample.com\")\n\n# Verify API calls were made\napi_requests = [r for r in requests if \"\u002Fapi\u002F\" in r.url]\nassert len(api_requests) > 0\n```\n\n## Running Tests\n\n### Basic Commands\n\n```bash\n# Install Playwright\npip install playwright pytest-playwright\nplaywright install\n\n# Run all tests\npytest tests\u002F\n\n# Run specific browser\npytest --browser chromium --browser firefox\n\n# Run in headed mode (see browser)\npytest --headed\n\n# Debug mode\nPWDEBUG=1 pytest tests\u002Ftest_login.py\n\n# Parallel execution\npytest -n auto\n\n# Generate test code\nplaywright codegen https:\u002F\u002Fexample.com\n```\n\n### Configuration\n\nSee `references\u002Fsetup-configuration.md` for:\n- Complete installation instructions\n- Project structure setup\n- pytest.ini configuration\n- playwright.config.ts for TypeScript\n- CI\u002FCD integration examples\n\n## Quality Standards\n\nEnsure tests meet these criteria:\n- Tests are independent and can run in any order\n- Selectors are reliable (test IDs, semantic selectors)\n- Proper error handling and assertions\n- Screenshots\u002Fvideos captured on failure\n- No hardcoded waits (use auto-waiting)\n- Clean state management between tests\n\n## Additional Resources\n\n### Detailed Documentation\n- [Setup & Configuration](.\u002Freferences\u002Fsetup-configuration.md) - Installation, project structure, and configuration\n- [Best Practices](.\u002Freferences\u002Fbest-practices.md) - Selector strategies, wait patterns, flaky test prevention\n- [Common Pitfalls](.\u002Freferences\u002Fcommon-pitfalls.md) - Race conditions, selector brittleness, cleanup issues\n- [CI\u002FCD Integration](.\u002Freferences\u002Fci-cd-integration.md) - GitHub Actions, Docker, deployment pipelines\n\n### Code Examples\n- [Login Testing](.\u002Fexamples\u002Flogin-testing.md) - Authentication flows and session management\n- [Form Testing](.\u002Fexamples\u002Fform-testing.md) - Form validation, file uploads, dropdowns\n- [E-commerce Testing](.\u002Fexamples\u002Fecommerce-testing.md) - Shopping cart, checkout flows, coupons\n- [API Mocking](.\u002Fexamples\u002Fapi-mocking.md) - Network interception, mocking, monitoring\n- [Mobile Testing](.\u002Fexamples\u002Fmobile-testing.md) - Device emulation, touch events, responsive design\n- [Page Object Model](.\u002Fexamples\u002Fpage-object-model.md) - POM pattern implementation\n\n### Helper Scripts\n- [Playwright Helper](.\u002Fscripts\u002Fplaywright_helper.py) - Utility functions for common Playwright operations\n- [Test Examples](.\u002Fscripts\u002Ftest_examples.py) - Complete test suite examples\n\n### External Resources\n- Official Documentation: https:\u002F\u002Fplaywright.dev\n- Python API: https:\u002F\u002Fplaywright.dev\u002Fpython\u002Fdocs\u002Fintro\n- TypeScript API: https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Fintro\n- Best Practices: https:\u002F\u002Fplaywright.dev\u002Fdocs\u002Fbest-practices\n- Community Discord: https:\u002F\u002Faka.ms\u002Fplaywright\u002Fdiscord\n\n## Troubleshooting\n\n**Tests are flaky:**\n- Use Playwright's auto-waiting instead of manual sleeps\n- Ensure proper wait conditions (`wait_for_selector`, `wait_for_url`)\n- Use `expect()` assertions which auto-retry\n\n**Selectors not finding elements:**\n- Verify element exists with browser DevTools\n- Use Playwright Inspector: `PWDEBUG=1 pytest test.py`\n- Try multiple selector strategies (text, role, test-id)\n\n**Tests slow in CI:**\n- Enable parallel execution: `pytest -n auto`\n- Use headed mode only for debugging\n- Consider browser context reuse for related tests\n\nFor more troubleshooting tips, see [Common Pitfalls](.\u002Freferences\u002Fcommon-pitfalls.md).\n",{"name":5,"description":7},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":70,"prompt":80,"zipAvailable":81},[71,74,77],{"tool":72,"command":73},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill webapp-testing",{"tool":75,"command":76},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill webapp-testing",{"tool":78,"command":79},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill webapp-testing","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002FSKILL.md",true,[83,89,95,99,103,107,111,115,119,123,127,131,135,141,145],{"path":84,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":87,"sourceHtmlUrl":88},"customize.toml","OTHER","其他",254,"https:\u002F\u002Fgithub.com\u002Fcarl0sfelipe\u002FBTC-Daytrade-Tycoon\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fbmad-prfaq\u002Fcustomize.toml",{"path":90,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":93,"sourceHtmlUrl":94},"examples\u002Fapi-mocking.md","REFERENCE","参考文档",2521,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Fexamples\u002Fapi-mocking.md",{"path":96,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":97,"sourceHtmlUrl":98},"examples\u002Fecommerce-testing.md",3092,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Fexamples\u002Fecommerce-testing.md",{"path":100,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":101,"sourceHtmlUrl":102},"examples\u002Fform-testing.md",4147,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Fexamples\u002Fform-testing.md",{"path":104,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":105,"sourceHtmlUrl":106},"examples\u002Flogin-testing.md",4423,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Fexamples\u002Flogin-testing.md",{"path":108,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":109,"sourceHtmlUrl":110},"examples\u002Fmobile-testing.md",2187,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Fexamples\u002Fmobile-testing.md",{"path":112,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":113,"sourceHtmlUrl":114},"examples\u002Fpage-object-model.md",3575,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Fexamples\u002Fpage-object-model.md",{"path":116,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":117,"sourceHtmlUrl":118},"README.md",9420,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002FREADME.md",{"path":120,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":121,"sourceHtmlUrl":122},"references\u002Fbest-practices.md",6920,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Freferences\u002Fbest-practices.md",{"path":124,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":125,"sourceHtmlUrl":126},"references\u002Fci-cd-integration.md",1877,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Freferences\u002Fci-cd-integration.md",{"path":128,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":129,"sourceHtmlUrl":130},"references\u002Fcommon-pitfalls.md",2955,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Freferences\u002Fcommon-pitfalls.md",{"path":132,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":133,"sourceHtmlUrl":134},"references\u002Fsetup-configuration.md",2457,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Freferences\u002Fsetup-configuration.md",{"path":136,"resourceType":137,"resourceTypeDesc":138,"sizeBytes":139,"sourceHtmlUrl":140},"scripts\u002Fplaywright_helper.py","SCRIPT","脚本",19026,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Fscripts\u002Fplaywright_helper.py",{"path":142,"resourceType":137,"resourceTypeDesc":138,"sizeBytes":143,"sourceHtmlUrl":144},"scripts\u002Ftest_examples.py",29313,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Fscripts\u002Ftest_examples.py",{"path":146,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":147,"sourceHtmlUrl":148},"skill-report.json",12026,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fautumnsgrove\u002Fwebapp-testing\u002Fskill-report.json",[150,160,170,179,185,192],{"skillNo":151,"name":152,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":153,"categories":154,"keywords":156,"publishedAt":55},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[155],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[157,158,159],"model","model hierarchy","model hierarchy skill",{"skillNo":161,"name":162,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":166,"publishedAt":55},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[165],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[167,168,169],"MCP","zoom","zoom mcp",{"skillNo":171,"name":172,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":173,"categories":174,"keywords":175,"publishedAt":55},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[176,177,178,168],"sdk","zoom apps sdk","apps",{"skillNo":180,"name":181,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":182,"categories":183,"keywords":184,"publishedAt":55},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[181],{"skillNo":186,"name":187,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":188,"categories":189,"keywords":191,"publishedAt":55},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[190],{"categoryNo":27,"categoryName":28,"taxonomyType":21,"taxonomyTypeDesc":22},[187],{"skillNo":193,"name":194,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":195,"categories":196,"keywords":197,"publishedAt":55},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[194]]