webapp-testing · diff
git:20261007.ab00264 to git:20261007.cf7b93e
66 added, 104 removed. Audit A to A.
---
name: webapp-testing
description: 使用 Playwright 与本地 Web 应用交互和测试的工具包。支持验证前端功能、调试 UI 行为、捕获浏览器截图和查看浏览器日志。
en_description: |-
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
zh_displayName: Web 应用测试
category: 工程实践与质量
en_category: Engineering Practice & Quality
+ license: Complete terms in LICENSE.txt
---
# Web Application Testing
- This skill enables comprehensive testing and debugging of local web applications using Playwright automation.
-
- You should use the Playwright MCP Server to undertake the work if possible. If the MCP Server is unavailable, you can run the code in a local Node.js environment with Playwright installed.
-
- ## When to Use This Skill
-
- Use this skill when you need to:
-
- - Test frontend functionality in a real browser
- - Verify UI behavior and interactions
- - Debug web application issues
- - Capture screenshots for documentation or debugging
- - Inspect browser console logs
- - Validate form submissions and user flows
- - Check responsive design across viewports
-
- ## Prerequisites
-
- - Node.js installed on the system
- - A locally running web application (or accessible URL)
- - Playwright will be installed automatically if not present
-
- ## Core Capabilities
-
- ### 1. Browser Automation
-
- - Navigate to URLs
- - Click buttons and links
- - Fill form fields
- - Select dropdowns
- - Handle dialogs and alerts
-
- ### 2. Verification
-
- - Assert element presence
- - Verify text content
- - Check element visibility
- - Validate URLs
- - Test responsive behavior
-
- ### 3. Debugging
-
- - Capture screenshots
- - View console logs
- - Inspect network requests
- - Debug failed tests
-
- ## Usage Examples
+ To test local web applications, write native Python Playwright scripts.
- ### Example 1: Basic Navigation Test
+ **Helper Scripts Available**:
+ - `scripts/with_server.py` - Manages server lifecycle (supports multiple servers)
- ```javascript
- // Navigate to a page and verify title
- await page.goto("http://localhost:3000");
- const title = await page.title();
- console.log("Page title:", title);
- ```
+ **Always run scripts with `--help` first** to see usage. DO NOT read the source until you try running the script first and find that a customized solution is abslutely necessary. These scripts can be very large and thus pollute your context window. They exist to be called directly as black-box scripts rather than ingested into your context window.
- ### Example 2: Form Interaction
+ ## Decision Tree: Choosing Your Approach
- ```javascript
- // Fill out and submit a form
- await page.fill("#username", "testuser");
- await page.fill("#password", "password123");
- await page.click('button[type="submit"]');
- await page.waitForURL("**/dashboard");
```
-
- ### Example 3: Screenshot Capture
-
- ```javascript
- // Capture a screenshot for debugging
- await page.screenshot({ path: "debug.png", fullPage: true });
+ User task → Is it static HTML?
+ ├─ Yes → Read HTML file directly to identify selectors
+ │ ├─ Success → Write Playwright script using selectors
+ │ └─ Fails/Incomplete → Treat as dynamic (below)
+ │
+ └─ No (dynamic webapp) → Is the server already running?
+ ├─ No → Run: python scripts/with_server.py --help
+ │ Then use the helper + write simplified Playwright script
+ │
+ └─ Yes → Reconnaissance-then-action:
+ 1. Navigate and wait for networkidle
+ 2. Take screenshot or inspect DOM
+ 3. Identify selectors from rendered state
+ 4. Execute actions with discovered selectors
```
- ## Guidelines
-
- 1. **Always verify the app is running** - Check that the local server is accessible before running tests
- 2. **Use explicit waits** - Wait for elements or navigation to complete before interacting
- 3. **Capture screenshots on failure** - Take screenshots to help debug issues
- 4. **Clean up resources** - Always close the browser when done
- 5. **Handle timeouts gracefully** - Set reasonable timeouts for slow operations
- 6. **Test incrementally** - Start with simple interactions before complex flows
- 7. **Use selectors wisely** - Prefer data-testid or role-based selectors over CSS classes
+ ## Example: Using with_server.py
- ## Common Patterns
+ To start a server, run `--help` first, then use the helper:
- ### Pattern: Wait for Element
+ **Single server:**
+ ```bash
+ python scripts/with_server.py --server "npm run dev" --port 5173 -- python your_automation.py
+ ```
- ```javascript
- await page.waitForSelector("#element-id", { state: "visible" });
+ **Multiple servers (e.g., backend + frontend):**
+ ```bash
+ python scripts/with_server.py \
+ --server "cd backend && python server.py" --port 3000 \
+ --server "cd frontend && npm run dev" --port 5173 \
+ -- python your_automation.py
```
- ### Pattern: Check if Element Exists
+ To create an automation script, include only Playwright logic (servers are managed automatically):
+ ```python
+ from playwright.sync_api import sync_playwright
- ```javascript
- const exists = (await page.locator("#element-id").count()) > 0;
+ with sync_playwright() as p:
+ browser = p.chromium.launch(headless=True) # Always launch chromium in headless mode
+ page = browser.new_page()
+ page.goto('http://localhost:5173') # Server already running and ready
+ page.wait_for_load_state('networkidle') # CRITICAL: Wait for JS to execute
+ # ... your automation logic
+ browser.close()
```
- ### Pattern: Get Console Logs
+ ## Reconnaissance-Then-Action Pattern
- ```javascript
- page.on("console", (msg) => console.log("Browser log:", msg.text()));
- ```
+ 1. **Inspect rendered DOM**:
+ ```python
+ page.screenshot(path='/tmp/inspect.png', full_page=True)
+ content = page.content()
+ page.locator('button').all()
+ ```
- ### Pattern: Handle Errors
+ 2. **Identify selectors** from inspection results
- ```javascript
- try {
- await page.click("#button");
- } catch (error) {
- await page.screenshot({ path: "error.png" });
- throw error;
- }
- ```
+ 3. **Execute actions** using discovered selectors
- ## Limitations
+ ## Common Pitfall
- - Requires Node.js environment
- - Cannot test native mobile apps (use React Native Testing Library instead)
- - May have issues with complex authentication flows
- - Some modern frameworks may require specific configuration
+ ❌ **Don't** inspect the DOM before waiting for `networkidle` on dynamic apps
+ ✅ **Do** wait for `page.wait_for_load_state('networkidle')` before inspection
- ## Helper Functions
+ ## Best Practices
- Some helper functions are available in [`test-helper.js`](./assets/test-helper.js) to simplify common tasks like waiting for elements, capturing screenshots, and handling errors. You can import and use these functions in your tests to improve readability and maintainability.
+ - **Use bundled scripts as black boxes** - To accomplish a task, consider whether one of the scripts available in `scripts/` can help. These scripts handle common, complex workflows reliably without cluttering the context window. Use `--help` to see usage, then invoke directly.
+ - Use `sync_playwright()` for synchronous scripts
+ - Always close the browser when done
+ - Use descriptive selectors: `text=`, `role=`, CSS selectors, or IDs
+ - Add appropriate waits: `page.wait_for_selector()` or `page.wait_for_timeout()`
+ ## Reference Files
+
+ - **examples/** - Examples showing common patterns:
+ - `element_discovery.py` - Discovering buttons, links, and inputs on a page
+ - `static_html_automation.py` - Using file:// URLs for local HTML
+ - `console_logging.py` - Capturing console logs during automation