From 6c49f321913ae79aa2b6214f1613670c7724b77a Mon Sep 17 00:00:00 2001 From: admin9webs Date: Fri, 10 Jul 2026 16:12:06 +0800 Subject: [PATCH] Add cross-border-ecommerce/node-playwright-web-automation --- .../node-playwright-web-automation/SKILL.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 skills/cross-border-ecommerce/node-playwright-web-automation/SKILL.md diff --git a/skills/cross-border-ecommerce/node-playwright-web-automation/SKILL.md b/skills/cross-border-ecommerce/node-playwright-web-automation/SKILL.md new file mode 100644 index 0000000..51dbc7e --- /dev/null +++ b/skills/cross-border-ecommerce/node-playwright-web-automation/SKILL.md @@ -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 \ No newline at end of file