65 lines
2.1 KiB
Markdown
65 lines
2.1 KiB
Markdown
---
|
|
name: node-playwright-web-automation
|
|
description: Use Node.js Playwright for web automation on this system — the browser tool fails due to sandbox issues.
|
|
---
|
|
# Node.js Playwright Web Automation
|
|
|
|
On this server, `browser_navigate` and other browser tools fail with "No usable sandbox" errors.
|
|
Use Node.js + Playwright directly instead.
|
|
|
|
## Environment
|
|
- Playwright: `/home/ubuntu/.hermes/hermes-agent/node_modules/playwright`
|
|
- Chromium: `/home/ubuntu/.cache/ms-playwright/chromium-1217/chrome-linux64/chrome`
|
|
- Node.js: available in PATH
|
|
|
|
## Usage Pattern
|
|
|
|
1. Write JS script to `/tmp/task.js`
|
|
2. Run: `cd /home/ubuntu && node /tmp/task.js`
|
|
|
|
## Script Template
|
|
|
|
```javascript
|
|
const { chromium } = require("/home/ubuntu/.hermes/hermes-agent/node_modules/playwright");
|
|
|
|
(async () => {
|
|
const browser = await chromium.launch({
|
|
headless: true,
|
|
args: ["--no-sandbox", "--disable-setuid-sandbox", "--disable-dev-shm-usage"]
|
|
});
|
|
const context = await browser.newContext({ ignoreHTTPSErrors: true });
|
|
const page = await context.newPage();
|
|
|
|
try {
|
|
await page.goto("https://example.com", { waitUntil: "domcontentloaded", timeout: 30000 });
|
|
await page.waitForTimeout(3000);
|
|
|
|
// Fill inputs
|
|
await page.fill('input[type="text"]', "value");
|
|
await page.fill('input[type="password"]', "password");
|
|
|
|
// Click login button
|
|
await page.click(".btn-primary");
|
|
|
|
await page.waitForTimeout(5000);
|
|
|
|
console.log("URL: " + page.url());
|
|
console.log("Title: " + await page.title());
|
|
const txt = await page.evaluate(() => document.body.innerText);
|
|
console.log("Body: " + txt.substring(0, 1000));
|
|
|
|
} catch (e) {
|
|
console.error("ERROR: " + e.message);
|
|
}
|
|
|
|
await browser.close();
|
|
})();
|
|
```
|
|
|
|
## Pitfalls
|
|
- Use `ignoreHTTPSErrors: true` — atomlisting.com and other sites may have cert issues
|
|
- Use `waitUntil: "domcontentloaded"` — `networkidle` often times out on SPA sites
|
|
- `page.fill()` is more reliable than `input.click()` + `input.type()`
|
|
- Login buttons may have spaces in text: "登 录" not "登录"
|
|
- Write scripts to files and run them — inline `node -e` breaks on quotes
|
|
- Always close browser at the end to prevent zombie processes |