145 lines
4.4 KiB
Markdown
145 lines
4.4 KiB
Markdown
# Login and Browser Harness
|
|
|
|
Use this reference only when live E10 access is required.
|
|
|
|
## Safety requirements
|
|
|
|
- Use an isolated Chrome instance, never the user's daily browser profile.
|
|
- Do not store credentials in files, memory, shell history notes, examples, or final documentation.
|
|
- Keep all E10 activity read-only.
|
|
- Clean up the isolated browser process when finished.
|
|
|
|
## Cross-platform placeholders
|
|
|
|
| Placeholder | Linux | macOS | Windows |
|
|
|---|---|---|---|
|
|
| `<CHROME>` | `google-chrome` | `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome` | `"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"` |
|
|
| `<TEMP_DIR>` | `/tmp/bh-e10` | `/tmp/bh-e10` | `%TEMP%\\bh-e10` |
|
|
| `<SCREENSHOT_DIR>` | `/tmp` | `/tmp` | `%TEMP%` |
|
|
|
|
## Start isolated Chrome
|
|
|
|
Clean stale browser-harness daemons first. Then start Chrome with a dedicated remote debugging port and profile directory.
|
|
|
|
Linux/macOS pattern:
|
|
|
|
```bash
|
|
pkill -f browser_harness.daemon 2>/dev/null; rm -f /tmp/bu-*.sock /tmp/bu-*.pid 2>/dev/null
|
|
<CHROME> --headless=new --remote-debugging-port=9223 --user-data-dir=<TEMP_DIR> --no-first-run --no-default-browser-check --window-size=1920,1080
|
|
sleep 3 && curl -s http://127.0.0.1:9223/json/version | grep webSocketDebuggerUrl
|
|
```
|
|
|
|
Every browser-harness command must set `BU_CDP_URL` in the same shell command:
|
|
|
|
```bash
|
|
export BU_CDP_URL=http://127.0.0.1:9223 && browser-harness <<'PY'
|
|
# commands
|
|
PY
|
|
```
|
|
|
|
Do not run `export BU_CDP_URL=...` on a separate line and then invoke `browser-harness`; the daemon may not inherit the later shell environment.
|
|
|
|
Windows pattern:
|
|
|
|
```bat
|
|
set BU_CDP_URL=http://127.0.0.1:9223 && browser-harness
|
|
```
|
|
|
|
## Navigate and detect session state
|
|
|
|
```python
|
|
new_tab("https://<E10_BASE>/login")
|
|
wait_for_load()
|
|
wait(3)
|
|
capture_screenshot("<SCREENSHOT_DIR>/e10_login.png")
|
|
print("URL:", js("window.location.href"))
|
|
```
|
|
|
|
If the URL is not `/login`, an existing session may already be authenticated in the isolated profile. Continue only if the current page confirms a valid E10 session.
|
|
|
|
## Captcha handling
|
|
|
|
E10 captcha is expected to be a four-digit number. If visual recognition returns fewer than four digits, refresh the captcha image and capture again.
|
|
|
|
```python
|
|
capture_screenshot("<SCREENSHOT_DIR>/e10_captcha.png")
|
|
```
|
|
|
|
Use available visual inspection capability to read the four digits. If incomplete, click the captcha image center and retry.
|
|
|
|
## Fill login form reliably
|
|
|
|
E10 input fields may not respond to direct `element.value = ...`. Use the native input setter and dispatch events.
|
|
|
|
```python
|
|
import json
|
|
|
|
info = json.loads(js('''
|
|
var inputs = document.querySelectorAll("input");
|
|
var result = [];
|
|
for (var i = 0; i < inputs.length; i++) {
|
|
var r = inputs[i].getBoundingClientRect();
|
|
result.push({
|
|
dataId: inputs[i].getAttribute("data-id"),
|
|
x: Math.round(r.left + r.width/2),
|
|
y: Math.round(r.top + r.height/2)
|
|
});
|
|
}
|
|
var btn = document.querySelector("button");
|
|
var br = btn ? btn.getBoundingClientRect() : null;
|
|
return JSON.stringify({inputs: result, btn: br ? {x: Math.round(br.left+br.width/2), y: Math.round(br.top+br.height/2)} : null});
|
|
'''))
|
|
|
|
js('''
|
|
var ns = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set;
|
|
window.__fi = function(dataId, value) {
|
|
var el = document.querySelector("[data-id='" + dataId + "']");
|
|
el.focus();
|
|
el.value = "";
|
|
ns.call(el, value);
|
|
el.dispatchEvent(new Event("input", { bubbles: true }));
|
|
el.dispatchEvent(new Event("change", { bubbles: true }));
|
|
el.dispatchEvent(new Event("blur", { bubbles: true }));
|
|
};
|
|
''')
|
|
|
|
u = info["inputs"][0]
|
|
p = info["inputs"][1]
|
|
c = info["inputs"][2]
|
|
b = info["btn"]
|
|
|
|
click_at_xy(u["x"], u["y"]); wait(0.2)
|
|
js('window.__fi("' + u["dataId"] + '", "<USERNAME>")')
|
|
click_at_xy(p["x"], p["y"]); wait(0.2)
|
|
js('window.__fi("' + p["dataId"] + '", "<PASSWORD>")')
|
|
click_at_xy(c["x"], c["y"]); wait(0.2)
|
|
js('window.__fi("' + c["dataId"] + '", "<CAPTCHA>")')
|
|
|
|
print(js('''
|
|
var vals = [];
|
|
document.querySelectorAll("input").forEach(function(el){ vals.push(el.value ? "set" : "empty"); });
|
|
JSON.stringify(vals);
|
|
'''))
|
|
|
|
click_at_xy(b["x"], b["y"])
|
|
wait(5)
|
|
wait_for_load()
|
|
print("After login:", js("window.location.href"))
|
|
```
|
|
|
|
If still on `/login`, assume captcha or credentials failed. Refresh captcha and retry rather than proceeding.
|
|
|
|
## Cleanup
|
|
|
|
Linux/macOS:
|
|
|
|
```bash
|
|
pkill -f "chrome.*9223" 2>/dev/null
|
|
```
|
|
|
|
Windows:
|
|
|
|
```bat
|
|
taskkill /F /IM chrome.exe 2>nul
|
|
```
|