@web-auto/camo 0.1.18 → 0.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -19
- package/bin/browser-service.mjs +11 -0
- package/package.json +7 -2
- package/scripts/install.mjs +3 -3
- package/src/cli.mjs +8 -5
- package/src/commands/attach.mjs +141 -0
- package/src/commands/browser.mjs +5 -16
- package/src/commands/mouse.mjs +2 -12
- package/src/container/runtime-core/operations/index.mjs +6 -15
- package/src/container/subscription-registry.mjs +6 -6
- package/src/core/actions.mjs +0 -12
- package/src/core/index.mjs +0 -1
- package/src/lifecycle/lock.mjs +7 -3
- package/src/services/browser-service/index.js +651 -0
- package/src/services/browser-service/index.js.map +1 -0
- package/src/services/browser-service/internal/BrowserSession.input.test.js +322 -0
- package/src/services/browser-service/internal/BrowserSession.input.test.js.map +1 -0
- package/src/services/browser-service/internal/BrowserSession.js +304 -0
- package/src/services/browser-service/internal/BrowserSession.js.map +1 -0
- package/src/services/browser-service/internal/ElementRegistry.js +61 -0
- package/src/services/browser-service/internal/ElementRegistry.js.map +1 -0
- package/src/services/browser-service/internal/ProfileLock.js +85 -0
- package/src/services/browser-service/internal/ProfileLock.js.map +1 -0
- package/src/services/browser-service/internal/SessionManager.js +184 -0
- package/src/services/browser-service/internal/SessionManager.js.map +1 -0
- package/src/services/browser-service/internal/SessionManager.test.js +40 -0
- package/src/services/browser-service/internal/SessionManager.test.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/cookies.js +145 -0
- package/src/services/browser-service/internal/browser-session/cookies.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/input-ops.js +127 -0
- package/src/services/browser-service/internal/browser-session/input-ops.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/input-pipeline.js +133 -0
- package/src/services/browser-service/internal/browser-session/input-pipeline.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/logging.js +46 -0
- package/src/services/browser-service/internal/browser-session/navigation.js +39 -0
- package/src/services/browser-service/internal/browser-session/navigation.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/page-hooks.js +443 -0
- package/src/services/browser-service/internal/browser-session/page-hooks.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/page-management.js +212 -0
- package/src/services/browser-service/internal/browser-session/page-management.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/recording.js +199 -0
- package/src/services/browser-service/internal/browser-session/recording.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/runtime-events.js +62 -0
- package/src/services/browser-service/internal/browser-session/runtime-events.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/session-core.js +85 -0
- package/src/services/browser-service/internal/browser-session/session-core.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/session-state.js +39 -0
- package/src/services/browser-service/internal/browser-session/session-state.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/types.js +15 -0
- package/src/services/browser-service/internal/browser-session/types.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/utils.js +69 -0
- package/src/services/browser-service/internal/browser-session/utils.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/viewport-manager.js +47 -0
- package/src/services/browser-service/internal/browser-session/viewport-manager.js.map +1 -0
- package/src/services/browser-service/internal/browser-session/viewport.js +216 -0
- package/src/services/browser-service/internal/browser-session/viewport.js.map +1 -0
- package/src/services/browser-service/internal/container-matcher.js +852 -0
- package/src/services/browser-service/internal/container-matcher.js.map +1 -0
- package/src/services/browser-service/internal/container-registry.js +182 -0
- package/src/services/browser-service/internal/engine-manager.js +259 -0
- package/src/services/browser-service/internal/engine-manager.js.map +1 -0
- package/src/services/browser-service/internal/fingerprint.js +203 -0
- package/src/services/browser-service/internal/fingerprint.js.map +1 -0
- package/src/services/browser-service/internal/heartbeat.js +137 -0
- package/src/services/browser-service/internal/logging.js +46 -0
- package/src/services/browser-service/internal/page-runtime/runtime.js +1317 -0
- package/src/services/browser-service/internal/pageRuntime.js +29 -0
- package/src/services/browser-service/internal/pageRuntime.js.map +1 -0
- package/src/services/browser-service/internal/runtimeInjector.js +31 -0
- package/src/services/browser-service/internal/runtimeInjector.js.map +1 -0
- package/src/services/browser-service/internal/service-process-logger.js +140 -0
- package/src/services/browser-service/internal/state-bus.js +46 -0
- package/src/services/browser-service/internal/state-bus.js.map +1 -0
- package/src/services/browser-service/internal/storage-paths.js +42 -0
- package/src/services/browser-service/internal/storage-paths.js.map +1 -0
- package/src/services/browser-service/internal/ws-server.js +1194 -0
- package/src/services/browser-service/internal/ws-server.js.map +1 -0
- package/src/services/browser-service/internal/ws-server.test.js +59 -0
- package/src/services/browser-service/internal/ws-server.test.js.map +1 -0
- package/src/services/browser-service/server.mjs +6 -0
- package/src/services/controller/cli-bridge.js +93 -0
- package/src/services/controller/container-index.js +50 -0
- package/src/services/controller/container-storage.js +36 -0
- package/src/services/controller/controller-actions.js +207 -0
- package/src/services/controller/controller.js +1138 -0
- package/src/services/controller/selectors.js +54 -0
- package/src/services/controller/transport.js +118 -0
- package/src/utils/browser-service.mjs +100 -125
- package/src/utils/config.mjs +22 -21
- package/src/utils/help.mjs +11 -9
- package/src/utils/ws-client.mjs +30 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionManager.js","sourceRoot":"","sources":["../../../../../modules/camo-backend/src/internal/SessionManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { SessionManager } from './SessionManager.js';
|
|
4
|
+
test('createSession closes session when start fails', async () => {
|
|
5
|
+
let closeCalled = 0;
|
|
6
|
+
const fakeSession = {
|
|
7
|
+
id: 'start-fail-profile',
|
|
8
|
+
modeName: 'dev',
|
|
9
|
+
onExit: undefined,
|
|
10
|
+
async start() {
|
|
11
|
+
throw new Error('start_failed');
|
|
12
|
+
},
|
|
13
|
+
async close() {
|
|
14
|
+
closeCalled += 1;
|
|
15
|
+
},
|
|
16
|
+
getCurrentUrl() {
|
|
17
|
+
return null;
|
|
18
|
+
},
|
|
19
|
+
getRecordingStatus() {
|
|
20
|
+
return {
|
|
21
|
+
active: false,
|
|
22
|
+
enabled: false,
|
|
23
|
+
name: null,
|
|
24
|
+
outputPath: null,
|
|
25
|
+
overlay: false,
|
|
26
|
+
startedAt: null,
|
|
27
|
+
endedAt: null,
|
|
28
|
+
eventCount: 0,
|
|
29
|
+
lastEventAt: null,
|
|
30
|
+
lastError: null,
|
|
31
|
+
};
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
const manager = new SessionManager({ ownerWatchdogMs: 60_000 }, () => fakeSession);
|
|
35
|
+
await assert.rejects(async () => manager.createSession({ profileId: 'start-fail-profile' }), /start_failed/);
|
|
36
|
+
assert.equal(closeCalled, 1);
|
|
37
|
+
assert.equal(manager.getSession('start-fail-profile'), undefined);
|
|
38
|
+
await manager.shutdown();
|
|
39
|
+
});
|
|
40
|
+
//# sourceMappingURL=SessionManager.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionManager.test.js","sourceRoot":"","sources":["../../../../../modules/camo-backend/src/internal/SessionManager.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,IAAI,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;IAC/D,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,MAAM,WAAW,GAAQ;QACvB,EAAE,EAAE,oBAAoB;QACxB,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,SAAS;QACjB,KAAK,CAAC,KAAK;YACT,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;QAClC,CAAC;QACD,KAAK,CAAC,KAAK;YACT,WAAW,IAAI,CAAC,CAAC;QACnB,CAAC;QACD,aAAa;YACX,OAAO,IAAI,CAAC;QACd,CAAC;QACD,kBAAkB;YAChB,OAAO;gBACL,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE,KAAK;gBACd,IAAI,EAAE,IAAqB;gBAC3B,UAAU,EAAE,IAAqB;gBACjC,OAAO,EAAE,KAAK;gBACd,SAAS,EAAE,IAAqB;gBAChC,OAAO,EAAE,IAAqB;gBAC9B,UAAU,EAAE,CAAC;gBACb,WAAW,EAAE,IAAqB;gBAClC,SAAS,EAAE,IAAqB;aACjC,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,EAAE,eAAe,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC;IAEnF,MAAM,MAAM,CAAC,OAAO,CAClB,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,oBAAoB,EAAE,CAAC,EACtE,cAAc,CACf,CAAC;IACF,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAC7B,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,oBAAoB,CAAC,EAAE,SAAS,CAAC,CAAC;IAElE,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;AAC3B,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import crypto from 'node:crypto';
|
|
4
|
+
import { resolveCookiesRoot } from '../storage-paths.js';
|
|
5
|
+
export class BrowserSessionCookies {
|
|
6
|
+
profileId;
|
|
7
|
+
getContext;
|
|
8
|
+
getActivePage;
|
|
9
|
+
lastCookieSignature = null;
|
|
10
|
+
lastCookieSaveTs = 0;
|
|
11
|
+
constructor(profileId, getContext, getActivePage) {
|
|
12
|
+
this.profileId = profileId;
|
|
13
|
+
this.getContext = getContext;
|
|
14
|
+
this.getActivePage = getActivePage;
|
|
15
|
+
}
|
|
16
|
+
async getCookies() {
|
|
17
|
+
const context = this.getContext();
|
|
18
|
+
if (!context)
|
|
19
|
+
return [];
|
|
20
|
+
return context.cookies();
|
|
21
|
+
}
|
|
22
|
+
async saveCookiesForActivePage() {
|
|
23
|
+
const context = this.getContext();
|
|
24
|
+
if (!context)
|
|
25
|
+
return [];
|
|
26
|
+
const page = this.getActivePage();
|
|
27
|
+
if (!page)
|
|
28
|
+
return [];
|
|
29
|
+
const cookies = await context.cookies();
|
|
30
|
+
if (!cookies.length)
|
|
31
|
+
return [];
|
|
32
|
+
const digest = this.hashCookies(cookies);
|
|
33
|
+
const now = Date.now();
|
|
34
|
+
if (digest === this.lastCookieSignature && now - this.lastCookieSaveTs < 2000) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
const targets = this.resolveCookieTargets(page.url());
|
|
38
|
+
if (!targets.length)
|
|
39
|
+
return [];
|
|
40
|
+
const payload = JSON.stringify({
|
|
41
|
+
timestamp: now,
|
|
42
|
+
profileId: this.profileId,
|
|
43
|
+
url: page.url(),
|
|
44
|
+
cookies,
|
|
45
|
+
}, null, 2);
|
|
46
|
+
const results = [];
|
|
47
|
+
for (const target of targets) {
|
|
48
|
+
await fs.promises.mkdir(path.dirname(target), { recursive: true });
|
|
49
|
+
await fs.promises.writeFile(target, payload, 'utf-8');
|
|
50
|
+
results.push({ path: target, count: cookies.length });
|
|
51
|
+
}
|
|
52
|
+
this.lastCookieSignature = digest;
|
|
53
|
+
this.lastCookieSaveTs = now;
|
|
54
|
+
return results;
|
|
55
|
+
}
|
|
56
|
+
async saveCookiesToFile(filePath) {
|
|
57
|
+
const cookies = await this.getCookies();
|
|
58
|
+
await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
59
|
+
await fs.promises.writeFile(filePath, JSON.stringify({ timestamp: Date.now(), cookies }, null, 2), 'utf-8');
|
|
60
|
+
return { path: filePath, count: cookies.length };
|
|
61
|
+
}
|
|
62
|
+
async saveCookiesIfStable(filePath, opts = {}) {
|
|
63
|
+
const minDelayMs = Math.max(1000, Number(opts.minDelayMs) || 2000);
|
|
64
|
+
const page = this.getActivePage();
|
|
65
|
+
if (!page)
|
|
66
|
+
return null;
|
|
67
|
+
const html = await page.content();
|
|
68
|
+
const isLoggedIn = html.includes('Frame_wrap_') && !html.includes('LoginCard') && !html.includes('passport');
|
|
69
|
+
if (!isLoggedIn)
|
|
70
|
+
return null;
|
|
71
|
+
const cookies = await this.getCookies();
|
|
72
|
+
if (!cookies.length)
|
|
73
|
+
return null;
|
|
74
|
+
const digest = this.hashCookies(cookies);
|
|
75
|
+
const now = Date.now();
|
|
76
|
+
if (digest === this.lastCookieSignature && now - this.lastCookieSaveTs < minDelayMs) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
80
|
+
await fs.promises.writeFile(filePath, JSON.stringify({ timestamp: now, cookies }, null, 2), 'utf-8');
|
|
81
|
+
this.lastCookieSignature = digest;
|
|
82
|
+
this.lastCookieSaveTs = now;
|
|
83
|
+
return { path: filePath, count: cookies.length };
|
|
84
|
+
}
|
|
85
|
+
async injectCookiesFromFile(filePath) {
|
|
86
|
+
const context = this.getContext();
|
|
87
|
+
if (!context)
|
|
88
|
+
throw new Error('context not ready');
|
|
89
|
+
const raw = JSON.parse(await fs.promises.readFile(filePath, 'utf-8'));
|
|
90
|
+
const cookies = Array.isArray(raw) ? raw : Array.isArray(raw?.cookies) ? raw.cookies : [];
|
|
91
|
+
if (!cookies.length)
|
|
92
|
+
return { count: 0 };
|
|
93
|
+
await context.addCookies(cookies);
|
|
94
|
+
return { count: cookies.length };
|
|
95
|
+
}
|
|
96
|
+
resolveCookieTargets(currentUrl) {
|
|
97
|
+
const cookieDir = resolveCookiesRoot();
|
|
98
|
+
const targets = new Set([path.join(cookieDir, `${this.profileId}.json`)]);
|
|
99
|
+
if (currentUrl) {
|
|
100
|
+
try {
|
|
101
|
+
const { hostname } = new URL(currentUrl);
|
|
102
|
+
const hostSegment = this.sanitizeHost(hostname);
|
|
103
|
+
if (hostSegment) {
|
|
104
|
+
targets.add(path.join(cookieDir, `${hostSegment}-latest.json`));
|
|
105
|
+
}
|
|
106
|
+
if (hostname && hostname.includes('weibo')) {
|
|
107
|
+
targets.add(path.join(cookieDir, 'weibo.com-latest.json'));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
targets.add(path.join(cookieDir, 'default-latest.json'));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return Array.from(targets);
|
|
115
|
+
}
|
|
116
|
+
sanitizeHost(host) {
|
|
117
|
+
if (!host)
|
|
118
|
+
return 'default';
|
|
119
|
+
return host.replace(/[^a-z0-9.-]/gi, '_');
|
|
120
|
+
}
|
|
121
|
+
hashCookies(cookies) {
|
|
122
|
+
const normalized = cookies
|
|
123
|
+
.map((c) => ({
|
|
124
|
+
name: c.name,
|
|
125
|
+
value: c.value,
|
|
126
|
+
domain: c.domain,
|
|
127
|
+
path: c.path,
|
|
128
|
+
expires: c.expires,
|
|
129
|
+
httpOnly: !!c.httpOnly,
|
|
130
|
+
secure: !!c.secure,
|
|
131
|
+
}))
|
|
132
|
+
.sort((a, b) => {
|
|
133
|
+
if (a.domain === b.domain) {
|
|
134
|
+
if (a.name === b.name)
|
|
135
|
+
return (a.path || '').localeCompare(b.path || '');
|
|
136
|
+
return a.name.localeCompare(b.name);
|
|
137
|
+
}
|
|
138
|
+
return (a.domain || '').localeCompare(b.domain || '');
|
|
139
|
+
});
|
|
140
|
+
const hash = crypto.createHash('sha1');
|
|
141
|
+
hash.update(JSON.stringify(normalized));
|
|
142
|
+
return hash.digest('hex');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=cookies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cookies.js","sourceRoot":"","sources":["../../../../../../modules/camo-backend/src/internal/browser-session/cookies.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { isTimeoutLikeError } from './utils.js';
|
|
2
|
+
export class BrowserSessionInputOps {
|
|
3
|
+
ensurePrimaryPage;
|
|
4
|
+
ensureInputReady;
|
|
5
|
+
runInputAction;
|
|
6
|
+
withInputActionLock;
|
|
7
|
+
wheelMode = 'wheel';
|
|
8
|
+
inputActionTail = Promise.resolve();
|
|
9
|
+
constructor(ensurePrimaryPage, ensureInputReady, runInputAction, withInputActionLock) {
|
|
10
|
+
this.ensurePrimaryPage = ensurePrimaryPage;
|
|
11
|
+
this.ensureInputReady = ensureInputReady;
|
|
12
|
+
this.runInputAction = runInputAction;
|
|
13
|
+
this.withInputActionLock = withInputActionLock;
|
|
14
|
+
const envMode = String(process.env.CAMO_SCROLL_INPUT_MODE || '').trim().toLowerCase();
|
|
15
|
+
this.wheelMode = envMode === 'keyboard' ? 'keyboard' : 'wheel';
|
|
16
|
+
}
|
|
17
|
+
async mouseClick(opts) {
|
|
18
|
+
const page = await this.ensurePrimaryPage();
|
|
19
|
+
await this.withInputActionLock(async () => {
|
|
20
|
+
await this.runInputAction(page, 'input:ready', (activePage) => this.ensureInputReady(activePage));
|
|
21
|
+
const { x, y, button = 'left', clicks = 1, delay = 50, nudgeBefore = false } = opts;
|
|
22
|
+
const moveToTarget = async (clickPage) => {
|
|
23
|
+
try {
|
|
24
|
+
await clickPage.mouse.move(x, y, { steps: 1 });
|
|
25
|
+
}
|
|
26
|
+
catch { }
|
|
27
|
+
};
|
|
28
|
+
const nudgePointer = async (clickPage) => {
|
|
29
|
+
const viewport = clickPage.viewportSize();
|
|
30
|
+
const maxX = Math.max(2, Number(viewport?.width || 1280) - 2);
|
|
31
|
+
const maxY = Math.max(2, Number(viewport?.height || 720) - 2);
|
|
32
|
+
const nudgeX = Math.max(2, Math.min(maxX, Math.round(Math.max(24, x * 0.2))));
|
|
33
|
+
const nudgeY = Math.max(2, Math.min(maxY, Math.round(Math.max(24, y * 0.2))));
|
|
34
|
+
await clickPage.mouse.move(nudgeX, nudgeY, { steps: 3 }).catch(() => { });
|
|
35
|
+
await clickPage.waitForTimeout(40).catch(() => { });
|
|
36
|
+
};
|
|
37
|
+
for (let i = 0; i < clicks; i++) {
|
|
38
|
+
if (i > 0)
|
|
39
|
+
await new Promise(r => setTimeout(r, 100 + Math.random() * 100));
|
|
40
|
+
try {
|
|
41
|
+
await this.runInputAction(page, 'mouse:click(direct)', async (clickPage) => {
|
|
42
|
+
if (nudgeBefore)
|
|
43
|
+
await nudgePointer(clickPage);
|
|
44
|
+
await moveToTarget(clickPage);
|
|
45
|
+
await clickPage.mouse.click(x, y, { button, clickCount: 1, delay: Math.max(0, Number(delay) || 0) });
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
if (!isTimeoutLikeError(error))
|
|
50
|
+
throw error;
|
|
51
|
+
await this.runInputAction(page, 'mouse:click(retry)', async (clickPage) => {
|
|
52
|
+
await nudgePointer(clickPage);
|
|
53
|
+
await moveToTarget(clickPage);
|
|
54
|
+
await clickPage.mouse.click(x, y, { button, clickCount: 1, delay: Math.max(0, Number(delay) || 0) });
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async mouseMove(opts) {
|
|
61
|
+
const x = Number(opts?.x);
|
|
62
|
+
const y = Number(opts?.y);
|
|
63
|
+
throw new Error(`mouse:move disabled (x=${Number.isFinite(x) ? x : 'NaN'}, y=${Number.isFinite(y) ? y : 'NaN'})`);
|
|
64
|
+
}
|
|
65
|
+
async mouseWheel(opts) {
|
|
66
|
+
const page = await this.ensurePrimaryPage();
|
|
67
|
+
await this.withInputActionLock(async () => {
|
|
68
|
+
await this.runInputAction(page, 'input:ready', (activePage) => this.ensureInputReady(activePage));
|
|
69
|
+
const { deltaX = 0, deltaY } = opts;
|
|
70
|
+
const normalizedDeltaX = Number(deltaX) || 0;
|
|
71
|
+
const normalizedDeltaY = Number(deltaY) || 0;
|
|
72
|
+
if (normalizedDeltaY === 0 && normalizedDeltaX === 0)
|
|
73
|
+
return;
|
|
74
|
+
const keyboardKey = normalizedDeltaY > 0 ? 'PageDown' : 'PageUp';
|
|
75
|
+
const keyboardTimes = Math.max(1, Math.min(4, Math.round(Math.abs(normalizedDeltaY) / 420) || 1));
|
|
76
|
+
const runKeyboardWheel = async () => {
|
|
77
|
+
for (let i = 0; i < keyboardTimes; i += 1) {
|
|
78
|
+
await this.runInputAction(page, `mouse:wheel:keyboard:${keyboardKey}`, (p) => p.keyboard.press(keyboardKey));
|
|
79
|
+
if (i + 1 < keyboardTimes) {
|
|
80
|
+
await this.runInputAction(page, 'mouse:wheel:keyboard:wait', (p) => p.waitForTimeout(80));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
if (this.wheelMode === 'keyboard') {
|
|
85
|
+
await runKeyboardWheel();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
await this.runInputAction(page, 'mouse:wheel', async (activePage) => {
|
|
90
|
+
const viewport = activePage.viewportSize();
|
|
91
|
+
const moveX = Math.max(1, Math.floor(((viewport?.width || 1280) * 0.5)));
|
|
92
|
+
const moveY = Math.max(1, Math.floor(((viewport?.height || 720) * 0.5)));
|
|
93
|
+
await activePage.mouse.move(moveX, moveY, { steps: 1 }).catch(() => { });
|
|
94
|
+
await activePage.mouse.wheel(normalizedDeltaX, normalizedDeltaY);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (!isTimeoutLikeError(error) || normalizedDeltaX !== 0 || normalizedDeltaY === 0)
|
|
99
|
+
throw error;
|
|
100
|
+
this.wheelMode = 'keyboard';
|
|
101
|
+
await runKeyboardWheel();
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
async keyboardType(opts) {
|
|
106
|
+
const page = await this.ensurePrimaryPage();
|
|
107
|
+
await this.withInputActionLock(async () => {
|
|
108
|
+
await this.runInputAction(page, 'input:ready', (activePage) => this.ensureInputReady(activePage));
|
|
109
|
+
const { text, delay = 80, submit } = opts;
|
|
110
|
+
if (text && text.length > 0) {
|
|
111
|
+
await this.runInputAction(page, 'keyboard:type', (activePage) => activePage.keyboard.type(text, { delay }));
|
|
112
|
+
}
|
|
113
|
+
if (submit) {
|
|
114
|
+
await this.runInputAction(page, 'keyboard:press', (activePage) => activePage.keyboard.press('Enter'));
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
async keyboardPress(opts) {
|
|
119
|
+
const page = await this.ensurePrimaryPage();
|
|
120
|
+
await this.withInputActionLock(async () => {
|
|
121
|
+
await this.runInputAction(page, 'input:ready', (activePage) => this.ensureInputReady(activePage));
|
|
122
|
+
const { key, delay } = opts;
|
|
123
|
+
await this.runInputAction(page, 'keyboard:press', (activePage) => activePage.keyboard.press(key, typeof delay === 'number' ? { delay } : undefined));
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=input-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-ops.js","sourceRoot":"","sources":["../../../../../../modules/camo-backend/src/internal/browser-session/input-ops.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { resolveInputActionMaxAttempts, resolveInputActionTimeoutMs, resolveInputRecoveryBringToFrontTimeoutMs, resolveInputRecoveryDelayMs, resolveInputReadySettleMs } from './utils.js';
|
|
2
|
+
import { ensurePageRuntime } from '../pageRuntime.js';
|
|
3
|
+
export class BrowserInputPipeline {
|
|
4
|
+
ensurePrimaryPage;
|
|
5
|
+
isHeadless;
|
|
6
|
+
constructor(ensurePrimaryPage, isHeadless) {
|
|
7
|
+
this.ensurePrimaryPage = ensurePrimaryPage;
|
|
8
|
+
this.isHeadless = isHeadless;
|
|
9
|
+
}
|
|
10
|
+
inputActionTail = Promise.resolve();
|
|
11
|
+
async ensureInputReady(page) {
|
|
12
|
+
if (this.isHeadless())
|
|
13
|
+
return;
|
|
14
|
+
const bringToFrontTimeoutMs = resolveInputRecoveryBringToFrontTimeoutMs();
|
|
15
|
+
let bringToFrontTimer = null;
|
|
16
|
+
try {
|
|
17
|
+
await Promise.race([
|
|
18
|
+
page.bringToFront(),
|
|
19
|
+
new Promise((_resolve, reject) => {
|
|
20
|
+
bringToFrontTimer = setTimeout(() => {
|
|
21
|
+
reject(new Error(`input ready bringToFront timed out after ${bringToFrontTimeoutMs}ms`));
|
|
22
|
+
}, bringToFrontTimeoutMs);
|
|
23
|
+
}),
|
|
24
|
+
]);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Best-effort only
|
|
28
|
+
}
|
|
29
|
+
finally {
|
|
30
|
+
if (bringToFrontTimer)
|
|
31
|
+
clearTimeout(bringToFrontTimer);
|
|
32
|
+
}
|
|
33
|
+
const settleMs = resolveInputReadySettleMs();
|
|
34
|
+
if (settleMs > 0) {
|
|
35
|
+
await page.waitForTimeout(settleMs).catch(() => { });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async resolveInputPage(preferredPage) {
|
|
39
|
+
try {
|
|
40
|
+
const page = await this.ensurePrimaryPage();
|
|
41
|
+
if (page && !page.isClosed())
|
|
42
|
+
return page;
|
|
43
|
+
}
|
|
44
|
+
catch { }
|
|
45
|
+
if (preferredPage && !preferredPage.isClosed())
|
|
46
|
+
return preferredPage;
|
|
47
|
+
return this.ensurePrimaryPage();
|
|
48
|
+
}
|
|
49
|
+
async withInputActionTimeout(label, run, timeoutOverrideMs) {
|
|
50
|
+
const resolvedOverride = Number(timeoutOverrideMs);
|
|
51
|
+
const timeoutMs = Number.isFinite(resolvedOverride) && resolvedOverride > 0
|
|
52
|
+
? Math.floor(resolvedOverride)
|
|
53
|
+
: resolveInputActionTimeoutMs();
|
|
54
|
+
let timer = null;
|
|
55
|
+
try {
|
|
56
|
+
return await Promise.race([
|
|
57
|
+
run(),
|
|
58
|
+
new Promise((_resolve, reject) => {
|
|
59
|
+
timer = setTimeout(() => reject(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
60
|
+
}),
|
|
61
|
+
]);
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
if (timer)
|
|
65
|
+
clearTimeout(timer);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async recoverInputPipeline(page) {
|
|
69
|
+
const activePage = await this.resolveInputPage(page).catch(() => page);
|
|
70
|
+
const bringToFrontTimeoutMs = resolveInputRecoveryBringToFrontTimeoutMs();
|
|
71
|
+
let bringToFrontTimer = null;
|
|
72
|
+
try {
|
|
73
|
+
await Promise.race([
|
|
74
|
+
activePage.bringToFront(),
|
|
75
|
+
new Promise((_resolve, reject) => {
|
|
76
|
+
bringToFrontTimer = setTimeout(() => {
|
|
77
|
+
reject(new Error(`input recovery bringToFront timed out after ${bringToFrontTimeoutMs}ms`));
|
|
78
|
+
}, bringToFrontTimeoutMs);
|
|
79
|
+
}),
|
|
80
|
+
]);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// Best-effort recovery only.
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
if (bringToFrontTimer)
|
|
87
|
+
clearTimeout(bringToFrontTimer);
|
|
88
|
+
}
|
|
89
|
+
const delayMs = resolveInputRecoveryDelayMs();
|
|
90
|
+
if (delayMs > 0) {
|
|
91
|
+
try {
|
|
92
|
+
await activePage.waitForTimeout(delayMs);
|
|
93
|
+
}
|
|
94
|
+
catch { }
|
|
95
|
+
}
|
|
96
|
+
await ensurePageRuntime(activePage, true).catch(() => { });
|
|
97
|
+
return this.resolveInputPage(activePage).catch(() => activePage);
|
|
98
|
+
}
|
|
99
|
+
async runInputAction(page, label, run) {
|
|
100
|
+
const maxAttempts = resolveInputActionMaxAttempts();
|
|
101
|
+
let lastError = null;
|
|
102
|
+
let activePage = page;
|
|
103
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
104
|
+
activePage = await this.resolveInputPage(activePage).catch(() => activePage);
|
|
105
|
+
try {
|
|
106
|
+
return await this.withInputActionTimeout(`${label} (attempt ${attempt}/${maxAttempts})`, () => run(activePage));
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
lastError = error;
|
|
110
|
+
if (attempt >= maxAttempts)
|
|
111
|
+
break;
|
|
112
|
+
activePage = await this.recoverInputPipeline(activePage);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (lastError instanceof Error)
|
|
116
|
+
throw lastError;
|
|
117
|
+
throw new Error(`${label} failed`);
|
|
118
|
+
}
|
|
119
|
+
async withInputActionLock(run) {
|
|
120
|
+
const previous = this.inputActionTail;
|
|
121
|
+
let release = null;
|
|
122
|
+
this.inputActionTail = new Promise((resolve) => { release = resolve; });
|
|
123
|
+
await previous.catch(() => { });
|
|
124
|
+
try {
|
|
125
|
+
return await run();
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
if (release)
|
|
129
|
+
release();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=input-pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-pipeline.js","sourceRoot":"","sources":["../../../../../../modules/camo-backend/src/internal/browser-session/input-pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { CONFIG_DIR, ensureDir } from '../../../utils/config.mjs';
|
|
4
|
+
|
|
5
|
+
const LOG_DIR = String(process.env.CAMO_LOG_DIR || '').trim() || path.join(CONFIG_DIR, 'logs');
|
|
6
|
+
const DEBUG_LOG_FILE = path.join(LOG_DIR, 'debug.jsonl');
|
|
7
|
+
let debugReady = false;
|
|
8
|
+
|
|
9
|
+
function isDebugEnabled() {
|
|
10
|
+
return (
|
|
11
|
+
process.env.DEBUG === '1'
|
|
12
|
+
|| process.env.debug === '1'
|
|
13
|
+
|| process.env.CAMO_DEBUG === '1'
|
|
14
|
+
|| process.env.CAMO_DEBUG === '1'
|
|
15
|
+
|| process.env.CAMO_DEBUG === '1'
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function ensureDebugLogDir() {
|
|
20
|
+
if (debugReady) return;
|
|
21
|
+
try {
|
|
22
|
+
ensureDir(LOG_DIR);
|
|
23
|
+
debugReady = true;
|
|
24
|
+
} catch {
|
|
25
|
+
// ignore
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function logDebug(module, event, data = {}) {
|
|
30
|
+
if (!isDebugEnabled()) return;
|
|
31
|
+
ensureDebugLogDir();
|
|
32
|
+
const entry = {
|
|
33
|
+
ts: Date.now(),
|
|
34
|
+
level: 'debug',
|
|
35
|
+
module,
|
|
36
|
+
event,
|
|
37
|
+
data,
|
|
38
|
+
};
|
|
39
|
+
try {
|
|
40
|
+
fs.appendFileSync(DEBUG_LOG_FILE, `${JSON.stringify(entry)}\n`, 'utf8');
|
|
41
|
+
} catch {
|
|
42
|
+
// ignore
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { DEBUG_LOG_FILE };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ensurePageRuntime } from '../pageRuntime.js';
|
|
2
|
+
import { normalizeUrl, resolveNavigationWaitUntil } from './utils.js';
|
|
3
|
+
export class BrowserSessionNavigation {
|
|
4
|
+
deps;
|
|
5
|
+
constructor(deps) {
|
|
6
|
+
this.deps = deps;
|
|
7
|
+
}
|
|
8
|
+
async goto(url) {
|
|
9
|
+
const page = await this.deps.ensurePrimaryPage();
|
|
10
|
+
await page.goto(url, { waitUntil: resolveNavigationWaitUntil() });
|
|
11
|
+
await ensurePageRuntime(page);
|
|
12
|
+
this.deps.recordLastKnownUrl(url);
|
|
13
|
+
}
|
|
14
|
+
async goBack() {
|
|
15
|
+
const page = await this.deps.ensurePrimaryPage();
|
|
16
|
+
const waitUntil = resolveNavigationWaitUntil();
|
|
17
|
+
try {
|
|
18
|
+
const res = await page.goBack({ waitUntil }).catch(() => null);
|
|
19
|
+
await ensurePageRuntime(page, true).catch(() => { });
|
|
20
|
+
this.deps.recordLastKnownUrl(page.url());
|
|
21
|
+
return { ok: Boolean(res), url: page.url() };
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
await ensurePageRuntime(page, true).catch(() => { });
|
|
25
|
+
this.deps.recordLastKnownUrl(page.url());
|
|
26
|
+
return { ok: false, url: page.url() };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
getCurrentUrl() {
|
|
30
|
+
const page = this.deps.getActivePage();
|
|
31
|
+
if (page)
|
|
32
|
+
return page.url() || this.deps.getLastKnownUrl();
|
|
33
|
+
return this.deps.getLastKnownUrl();
|
|
34
|
+
}
|
|
35
|
+
normalizeUrl(raw) {
|
|
36
|
+
return normalizeUrl(raw);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../../../../../modules/camo-backend/src/internal/browser-session/navigation.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAStE,MAAM,OAAO,wBAAwB;IACf;IAApB,YAAoB,IAAoB;QAApB,SAAI,GAAJ,IAAI,CAAgB;IAAG,CAAC;IAE5C,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACjD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,0BAA0B,EAAE,EAAE,CAAC,CAAC;QAClE,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACjD,MAAM,SAAS,GAAG,0BAA0B,EAAE,CAAC;QAC/C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,GAAS,EAAE,CAAC,IAAI,CAAC,CAAC;YACrE,MAAM,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACpD,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACzC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACpD,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACzC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACxC,CAAC;IACH,CAAC;IAED,aAAa;QACX,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;QAC3D,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;IACrC,CAAC;IAED,YAAY,CAAC,GAAW;QACtB,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF"}
|