✓ Verified 💻 Development ✓ Enhanced Data

Web Form Automation

Automate web form interactions including login, file upload, text input, and form submission using P

Rating
5 (26 reviews)
Downloads
5,775 downloads
Version
1.0.0

Overview

Automate web form interactions including login, file upload, text input, and form submission using Playwright.

Complete Documentation

View Source →

Web Form Automation

Automate web form interactions reliably using Playwright with best practices for session management, file uploads, and form submission.

Quick Start

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

// Basic form automation
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://example.com/form');

// Upload compressed images
await page.locator('input[type="file"]').setInputFiles('/path/to/image.webp');

// Type text (triggers events properly)
await page.locator('textarea').pressSequentially('Your text', { delay: 30 });

// Submit form
await page.locator('button[type="submit"]').click({ force: true });

Session Management

Using Browser Session Data

When user provides a JSON file with session data:

javascript
const sessionData = JSON.parse(fs.readFileSync('session.json', 'utf8'));

// Set cookies before navigating
for (const cookie of sessionData.cookies || []) {
  await context.addCookies([cookie]);
}

// Set localStorage/sessionStorage
await page.evaluate((data) => {
  for (const [k, v] of Object.entries(data.localStorage || {})) {
    localStorage.setItem(k, v);
  }
}, sessionData);

File Upload Best Practices

Image Compression

Always compress images before upload for reliability:

bash
# Convert to webp for best compression
convert input.png output.webp

# Or resize if needed
convert input.png -resize 1024x1024 output.webp

Size comparison:

  • Original PNG: ~4MB
  • Compressed PNG: ~1MB
  • WebP: ~30-50KB (99% smaller)

Upload Sequence

javascript
// 1. Find file inputs
const fileInputs = await page.locator('input[type="file"]').all();

// 2. Upload with waiting time
await fileInputs[0].setInputFiles('/path/to/start.webp');
await page.waitForTimeout(3000); // Wait for upload to process

await fileInputs[1].setInputFiles('/path/to/end.webp');
await page.waitForTimeout(3000);

Text Input Best Practices

Use pressSequentially, not fill()

Don't use fill() - doesn't trigger input events:

javascript
await textInput.fill('text'); // May not activate submit button

Use pressSequentially() - simulates real typing:

javascript
await textInput.pressSequentially('text', { delay: 30 });

Trigger Events Manually (if needed)

javascript
await page.evaluate(() => {
  const el = document.querySelector('textarea');
  el.dispatchEvent(new Event('input', { bubbles: true }));
  el.dispatchEvent(new Event('change', { bubbles: true }));
});

Button Clicking

Force Click When Disabled

If button appears disabled but should be clickable:

javascript
await button.click({ force: true });

Check Button State

javascript
const isEnabled = await button.isEnabled();
const isVisible = await button.isVisible();

Complete Example: Video Generation Form

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

async function submitVideoForm(sessionFile, startImage, endImage, prompt) {
  const browser = await chromium.launch({ 
    headless: true, 
    args: ['--no-sandbox'] 
  });
  const context = await browser.newContext();
  const page = await context.newPage();
  
  // Load session if provided
  if (fs.existsSync(sessionFile)) {
    const session = JSON.parse(fs.readFileSync(sessionFile, 'utf8'));
    // Set cookies, localStorage...
  }
  
  // Navigate
  await page.goto('https://example.com/video', { 
    waitUntil: 'domcontentloaded' 
  });
  await page.waitForTimeout(3000);
  
  // Upload images (webp compressed)
  const inputs = await page.locator('input[type="file"]').all();
  await inputs[0].setInputFiles(startImage);
  await page.waitForTimeout(3000);
  await inputs[1].setInputFiles(endImage);
  await page.waitForTimeout(3000);
  
  // Select options
  await page.click('text=Seedance 2.0 Fast');
  await page.click('text=15s');
  
  // Type prompt
  const textarea = page.locator('textarea').first();
  await textarea.pressSequentially(prompt, { delay: 30 });
  await page.waitForTimeout(2000);
  
  // Submit
  await page.locator('button[class*="submit"]').click({ force: true });
  
  // Wait and screenshot
  await page.waitForTimeout(5000);
  await page.screenshot({ path: 'result.png' });
  
  await browser.close();
}

Scripts

The scripts/ directory contains reusable automation scripts:

  • webp-compress.sh - Convert images to webp format
  • form-submit.js - Generic form submission template

Troubleshooting

Button stays gray/disabled

  • Wait longer after file upload (3+ seconds)
  • Ensure text input triggers events (use pressSequentially)
  • Check if images are still uploading

Upload times out

  • Compress images to webp format first
  • Reduce image dimensions if very large

Form doesn't submit

  • Use force: true for click
  • Check button selector is correct
  • Verify all required fields are filled

Installation

Terminal bash

openclaw install web-form-automation
    
Copied!

💻Code Examples

await page.locator('button[type="submit"]').click({ force: true });

await-pagelocatorbuttontypesubmitclick-force-true-.txt
## Session Management

### Using Browser Session Data

When user provides a JSON file with session data:

}, sessionData);

-sessiondata.txt
## File Upload Best Practices

### Image Compression

Always compress images before upload for reliability:

convert input.png -resize 1024x1024 output.webp

convert-inputpng--resize-1024x1024-outputwebp.txt
**Size comparison:**
- Original PNG: ~4MB
- Compressed PNG: ~1MB  
- WebP: ~30-50KB (99% smaller)

### Upload Sequence

await page.waitForTimeout(3000);

await-pagewaitfortimeout3000.txt
## Text Input Best Practices

### Use pressSequentially, not fill()

❌ **Don't use fill()** - doesn't trigger input events:

});

.txt
## Button Clicking

### Force Click When Disabled

If button appears disabled but should be clickable:
example.js
const { chromium } = require('playwright');

// Basic form automation
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://example.com/form');

// Upload compressed images
await page.locator('input[type="file"]').setInputFiles('/path/to/image.webp');

// Type text (triggers events properly)
await page.locator('textarea').pressSequentially('Your text', { delay: 30 });

// Submit form
await page.locator('button[type="submit"]').click({ force: true });
example.js
const sessionData = JSON.parse(fs.readFileSync('session.json', 'utf8'));

// Set cookies before navigating
for (const cookie of sessionData.cookies || []) {
  await context.addCookies([cookie]);
}

// Set localStorage/sessionStorage
await page.evaluate((data) => {
  for (const [k, v] of Object.entries(data.localStorage || {})) {
    localStorage.setItem(k, v);
  }
}, sessionData);
example.sh
# Convert to webp for best compression
convert input.png output.webp

# Or resize if needed
convert input.png -resize 1024x1024 output.webp
example.js
// 1. Find file inputs
const fileInputs = await page.locator('input[type="file"]').all();

// 2. Upload with waiting time
await fileInputs[0].setInputFiles('/path/to/start.webp');
await page.waitForTimeout(3000); // Wait for upload to process

await fileInputs[1].setInputFiles('/path/to/end.webp');
await page.waitForTimeout(3000);
example.js
await page.evaluate(() => {
  const el = document.querySelector('textarea');
  el.dispatchEvent(new Event('input', { bubbles: true }));
  el.dispatchEvent(new Event('change', { bubbles: true }));
});

Tags

#web_and-frontend-development #automation #web

Quick Info

Category Development
Model Claude 3.5
Complexity Multi-Agent
Author flyingzl
Last Updated 3/10/2026
🚀
Optimized for
Claude 3.5
🧠

Ready to Install?

Get started with this skill in seconds

openclaw install web-form-automation