web-form-automation
使用 Playwright 自动执行 Web 表单交互,包括登录、文件上传、文本输入和表单提交。当用户需要自动化网站交互、将文件上传到 Web 表单、使用文本输入填写表单、单击按钮或向 Web 应用程序提交数据时使用。支持通过 cookie 进行会话管理、压缩图像上传 (webp) 以及适当的事件触发以实现可靠的表单提交。
安装 / 下载方式
TotalClaw CLI推荐
totalclaw skills install shop:totalclaw:totalclaw~flyingzl-web-form-automationcURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Atotalclaw~flyingzl-web-form-automation/file -o flyingzl-web-form-automation.md## 概述(中文)
使用 Playwright 自动执行 Web 表单交互,包括登录、文件上传、文本输入和表单提交。当用户需要自动化网站交互、将文件上传到 Web 表单、使用文本输入填写表单、单击按钮或向 Web 应用程序提交数据时使用。支持通过 cookie 进行会话管理、压缩图像上传 (webp) 以及适当的事件触发以实现可靠的表单提交。
## 原文
# 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