Add cross-border-ecommerce/node-playwright-web-automation
This commit is contained in:
@@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
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
|
||||||
Reference in New Issue
Block a user