How do I automate form submissions using Playwright?

How to Automate Form Submissions Using Playwright

Playwright is a powerful web automation library that enables you to interact with forms programmatically. This guide covers form automation in both Python and JavaScript with practical examples and best practices.

Installation

Python Setup

pip install playwright
playwright install

JavaScript/Node.js Setup

npm install playwright
# Browser binaries are downloaded automatically

Basic Form Automation

Python Example

from playwright.sync_api import sync_playwright

def submit_form(playwright):
    browser = playwright.chromium.launch(headless=False)  # Set to True for production
    page = browser.new_page()

    try:
        # Navigate to the form page
        page.goto('https://example.com/login')

        # Wait for form to load
        page.wait_for_selector('form')

        # Fill form fields
        page.fill('input[name="username"]', 'your_username')
        page.fill('input[name="password"]', 'your_password')

        # Submit the form
        page.click('button[type="submit"]')

        # Wait for navigation after form submission
        page.wait_for_url('**/dashboard**')  # Wait for redirect to dashboard

        print("Form submitted successfully!")

    except Exception as e:
        print(f"Error: {e}")
    finally:
        browser.close()

with sync_playwright() as p:
    submit_form(p)

JavaScript Example

const { chromium } = require('playwright');

async function submitForm() {
    const browser = await chromium.launch({ headless: false });
    const page = await browser.newPage();

    try {
        // Navigate to the form page
        await page.goto('https://example.com/login');

        // Wait for form to load
        await page.waitForSelector('form');

        // Fill form fields
        await page.fill('input[name="username"]', 'your_username');
        await page.fill('input[name="password"]', 'your_password');

        // Submit the form
        await page.click('button[type="submit"]');

        // Wait for navigation after form submission
        await page.waitForURL('**/dashboard**');

        console.log('Form submitted successfully!');

    } catch (error) {
        console.error('Error:', error);
    } finally {
        await browser.close();
    }
}

submitForm();

Advanced Form Interactions

Handling Different Input Types

# Text inputs
page.fill('input[name="email"]', 'user@example.com')

# Checkboxes
page.check('input[name="terms"]')  # Check
page.uncheck('input[name="newsletter"]')  # Uncheck

# Radio buttons
page.check('input[value="option1"]')

# Select dropdowns
page.select_option('select[name="country"]', 'US')

# File uploads
page.set_input_files('input[type="file"]', 'path/to/file.pdf')

# Textareas
page.fill('textarea[name="message"]', 'Your message here')

Multiple Submission Methods

# Method 1: Click submit button
page.click('button[type="submit"]')

# Method 2: Press Enter on form field
page.press('input[name="username"]', 'Enter')

# Method 3: Call form.submit() with JavaScript
page.evaluate('document.querySelector("form").submit()')

# Method 4: Use page.submit_form() if form has action attribute
page.locator('form').submit()

Error Handling and Validation

Robust Form Submission

from playwright.sync_api import sync_playwright, TimeoutError

def robust_form_submit(playwright):
    browser = playwright.chromium.launch()
    page = browser.new_page()

    try:
        page.goto('https://example.com/contact', timeout=30000)

        # Check if form exists
        if not page.locator('form').is_visible():
            raise Exception("Form not found on page")

        # Fill required fields with validation
        required_fields = {
            'input[name="name"]': 'John Doe',
            'input[name="email"]': 'john@example.com',
            'textarea[name="message"]': 'Hello world'
        }

        for selector, value in required_fields.items():
            if page.locator(selector).is_visible():
                page.fill(selector, value)
            else:
                print(f"Warning: Field {selector} not found")

        # Submit with confirmation
        with page.expect_navigation():
            page.click('button[type="submit"]')

        # Check for success message or error
        if page.locator('.success-message').is_visible():
            print("Form submitted successfully!")
        elif page.locator('.error-message').is_visible():
            error_text = page.locator('.error-message').text_content()
            print(f"Submission failed: {error_text}")

    except TimeoutError:
        print("Page load timeout")
    except Exception as e:
        print(f"Error: {e}")
    finally:
        browser.close()

with sync_playwright() as p:
    robust_form_submit(p)

Waiting Strategies

# Wait for element to be visible
page.wait_for_selector('form', state='visible')

# Wait for form submission to complete
page.wait_for_load_state('networkidle')

# Wait for specific response
with page.expect_response('**/api/submit**') as response_info:
    page.click('button[type="submit"]')
response = response_info.value
print(f"Status: {response.status}")

# Wait for URL change
page.wait_for_url('**/success**')

Best Practices

  1. Always use proper selectors: Prefer data-testid attributes over fragile CSS selectors
  2. Handle timeouts: Set appropriate timeout values for slow-loading forms
  3. Validate before submission: Check if required fields are filled
  4. Wait for responses: Ensure form submission completes before proceeding
  5. Handle errors gracefully: Implement proper error handling and logging
  6. Respect rate limits: Add delays between multiple form submissions
  7. Use headless mode in production: Set headless=True for automated environments

Common Troubleshooting

  • Element not found: Use page.wait_for_selector() before interacting
  • Form not submitting: Check if JavaScript validation is preventing submission
  • Slow responses: Increase timeout values or wait for network idle state
  • CAPTCHA protection: Some forms may require human verification
  • CSRF tokens: Modern forms may need token handling for security

Responsible Usage

When automating form submissions: - Respect website terms of service - Implement reasonable delays between requests - Handle failures gracefully without overwhelming servers - Consider using official APIs when available - Test thoroughly before production deployment

Remember that automated form submission should be used responsibly and in compliance with website policies and applicable laws.

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon