W

Webapp Testing Smart

Powerful skill for toolkit, interacting, testing, local. Includes structured workflows, validation checks, and reusable patterns for development.

SkillClipticsdevelopmentv1.0.0MIT
0 views0 copies

Web Application Testing Smart

A practical skill for testing web applications using Python Playwright scripts. Covers browser automation, form interaction, visual verification, network interception, and multi-page workflow testing with server lifecycle management.

When to Use This Skill

Choose this skill when:

  • Testing local web applications with browser automation
  • Verifying form submissions, navigation, and interactive features
  • Running visual regression tests across pages
  • Testing API integrations through the browser
  • Automating multi-step user workflows for verification

Consider alternatives when:

  • Writing unit tests for components → use a component testing skill
  • Testing APIs directly → use an API testing skill
  • Running performance load tests → use a performance testing skill
  • Writing Playwright tests in TypeScript → use a Playwright skill

Quick Start

# Install Playwright for Python pip install playwright playwright install chromium # Basic test script from playwright.sync_api import sync_playwright with sync_playwright() as p: browser = p.chromium.launch(headless=True) page = browser.new_page() # Navigate and verify page.goto('http://localhost:3000') assert page.title() == 'My App' # Fill form and submit page.fill('#email', '[email protected]') page.fill('#password', 'password123') page.click('button[type="submit"]') # Wait for navigation and verify page.wait_for_url('**/dashboard') assert page.is_visible('text=Welcome') browser.close()

Core Concepts

Testing Patterns

PatternWhenExample
Navigation testVerify page routingClick link → check URL and content
Form testVerify form submissionFill fields → submit → check response
Auth testVerify login/logoutLogin → access protected page → logout
CRUD testVerify data operationsCreate → read → update → delete → verify
Error testVerify error handlingSubmit invalid data → check error message
Visual testVerify appearanceScreenshot → compare with baseline

Server Lifecycle Management

# with_server.py — Start server, run tests, stop server import subprocess import time import sys import requests def wait_for_server(url, timeout=30): start = time.time() while time.time() - start < timeout: try: requests.get(url, timeout=2) return True except requests.ConnectionError: time.sleep(0.5) return False def run_with_server(server_cmd, test_func, port=3000): url = f'http://localhost:{port}' # Start server proc = subprocess.Popen(server_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) try: if not wait_for_server(url): raise TimeoutError(f'Server did not start at {url}') # Run tests test_func(url) print('All tests passed!') finally: proc.terminate() proc.wait(timeout=5)

Advanced Testing Patterns

from playwright.sync_api import sync_playwright, expect def test_full_workflow(base_url: str): with sync_playwright() as p: browser = p.chromium.launch() context = browser.new_context( viewport={'width': 1280, 'height': 720}, locale='en-US', ) page = context.new_page() # Intercept API calls api_responses = [] page.on('response', lambda r: api_responses.append(r) if '/api/' in r.url else None) # Login flow page.goto(f'{base_url}/login') page.fill('[name="email"]', '[email protected]') page.fill('[name="password"]', 'testpass') page.click('button:has-text("Sign In")') page.wait_for_url('**/dashboard') # Verify dashboard loaded expect(page.locator('h1')).to_have_text('Dashboard') expect(page.locator('.stats-card')).to_have_count(4) # Take screenshot for visual verification page.screenshot(path='screenshots/dashboard.png', full_page=True) # Test CRUD operation page.click('text=Create New') page.fill('#name', 'Test Item') page.fill('#description', 'Created by automated test') page.click('button:has-text("Save")') # Verify creation expect(page.locator('text=Test Item')).to_be_visible() browser.close()

Configuration

ParameterTypeDefaultDescription
browserstring'chromium'Browser: chromium, firefox, or webkit
headlessbooleantrueRun without visible browser window
viewportobject{width: 1280, height: 720}Browser viewport dimensions
timeoutnumber30000Default action timeout (ms)
screenshotOnFailurebooleantrueCapture screenshot when test fails
serverStartTimeoutnumber30Max seconds to wait for server start

Best Practices

  1. Always wait for conditions, never use sleep — Use page.wait_for_selector(), page.wait_for_url(), or expect().to_be_visible() instead of time.sleep(). Hard sleeps are flaky and slow. Explicit waits are reliable and fast.

  2. Use data-testid attributes for stable selectors — CSS class names and text content change frequently. Add data-testid="submit-button" to elements and select with page.locator('[data-testid="submit-button"]') for resilient tests.

  3. Manage server lifecycle automatically — Start the server before tests and stop it after, even if tests fail. Use the with_server.py helper pattern with try/finally to ensure cleanup.

  4. Capture screenshots on failure for debugging — When a test assertion fails, take a screenshot and save page HTML before the test exits. This provides visual evidence of what the page looked like when the failure occurred.

  5. Isolate tests with fresh browser contexts — Each test should create a new browser context with clean cookies and storage. Shared state between tests causes flaky failures that depend on test execution order.

Common Issues

Tests fail with "element not found" but element exists — The element might be loading asynchronously or hidden behind a modal. Use wait_for_selector with a timeout, check for iframes, and verify the element isn't covered by an overlay.

Server not ready when tests start — The test script launches the server and immediately starts testing before the server finishes starting. Use a polling health check (wait_for_server) that retries until the server responds or a timeout expires.

Tests pass locally but fail in CI — CI environments are slower and may have different screen sizes. Increase timeouts, set explicit viewport sizes, and disable animations with CSS * { animation: none !important; transition: none !important; }.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates