@intuned/runtime-dev 1.3.14-ts-runtime-helpers-1 → 1.3.15-ts-helpers
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/dist/commands/intuned-cli/helpers/intunedJson.d.ts +1 -1
- package/dist/common/constants.d.ts +0 -2
- package/dist/common/constants.js +2 -4
- package/dist/common/extension/extensionsHelpers.js +2 -17
- package/dist/common/extension/intunedExtensionServer.d.ts +3 -1
- package/dist/common/extension/intunedExtensionServer.js +36 -19
- package/dist/common/extension/types.d.ts +206 -15
- package/dist/common/extension/types.js +47 -1
- package/dist/common/intunedJson.d.ts +6 -6
- package/dist/common/runApi/index.js +0 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -0
- package/dist/runtime/captcha.d.ts +4 -7
- package/dist/runtime/captcha.js +14 -27
- package/dist/runtime/captcha.test.js +662 -55
- package/dist/runtime/getAiGatewayConfig.d.ts +10 -0
- package/dist/runtime/getAiGatewayConfig.js +16 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +7 -0
- package/package.json +3 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _vitest = require("vitest");
|
|
4
|
+
var _intunedExtensionServer = require("../common/extension/intunedExtensionServer");
|
|
4
5
|
var _captcha = require("./captcha");
|
|
5
6
|
_vitest.vi.mock("fastify", () => {
|
|
6
7
|
const fastify = () => ({
|
|
@@ -13,48 +14,93 @@ _vitest.vi.mock("fastify", () => {
|
|
|
13
14
|
default: fastify
|
|
14
15
|
};
|
|
15
16
|
});
|
|
16
|
-
class FakeExtensionServer {
|
|
17
|
-
captchas = new Map();
|
|
18
|
-
subscribers = new Set();
|
|
19
|
-
subscribeCalls = 0;
|
|
20
|
-
unsubscribeCalls = 0;
|
|
21
|
-
seed(captchas) {
|
|
22
|
-
this.captchas.clear();
|
|
23
|
-
for (const c of captchas) this.captchas.set(c.id, c);
|
|
24
|
-
}
|
|
25
|
-
async upsertCaptcha(captcha) {
|
|
26
|
-
this.captchas.set(captcha.id, captcha);
|
|
27
|
-
for (const h of this.subscribers) {
|
|
28
|
-
await h(captcha);
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
async getCaptchas(_page, status) {
|
|
32
|
-
const list = [...this.captchas.values()];
|
|
33
|
-
return status ? list.filter(c => c.status === status) : list;
|
|
34
|
-
}
|
|
35
|
-
async subscribe(_page, handler) {
|
|
36
|
-
this.subscribeCalls += 1;
|
|
37
|
-
this.subscribers.add(handler);
|
|
38
|
-
}
|
|
39
|
-
async unsubscribe(_page, handler) {
|
|
40
|
-
this.unsubscribeCalls += 1;
|
|
41
|
-
this.subscribers.delete(handler);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
17
|
let server;
|
|
45
|
-
_vitest.vi.mock("../common/extension/intunedExtensionServer",
|
|
18
|
+
_vitest.vi.mock("../common/extension/intunedExtensionServer", async importOriginal => {
|
|
19
|
+
const actual = await importOriginal();
|
|
46
20
|
return {
|
|
47
|
-
|
|
21
|
+
...actual,
|
|
22
|
+
getIntunedExtensionServer: () => server,
|
|
23
|
+
getTabId: _vitest.vi.fn(async () => 0)
|
|
48
24
|
};
|
|
49
25
|
});
|
|
50
26
|
function makeMockPage() {
|
|
51
27
|
return {
|
|
52
|
-
waitForLoadState: _vitest.vi.fn().mockResolvedValue(undefined)
|
|
28
|
+
waitForLoadState: _vitest.vi.fn().mockResolvedValue(undefined),
|
|
29
|
+
waitForFunction: _vitest.vi.fn().mockResolvedValue(undefined),
|
|
30
|
+
evaluate: _vitest.vi.fn().mockResolvedValue(0)
|
|
53
31
|
};
|
|
54
32
|
}
|
|
33
|
+
async function runCaptchaTestScenario({
|
|
34
|
+
page,
|
|
35
|
+
mockStates,
|
|
36
|
+
timeoutMs = 10000,
|
|
37
|
+
settleDurationMs = 100,
|
|
38
|
+
expectErrorCode,
|
|
39
|
+
expectTimeout = false
|
|
40
|
+
}) {
|
|
41
|
+
for (const state of mockStates) {
|
|
42
|
+
await server.handleUpsertCaptcha(state.initial);
|
|
43
|
+
}
|
|
44
|
+
const allTransitions = [];
|
|
45
|
+
for (const state of mockStates) {
|
|
46
|
+
for (const transition of state.transitions) {
|
|
47
|
+
allTransitions.push({
|
|
48
|
+
timeMs: transition.timeMs,
|
|
49
|
+
captchaId: state.initial.id,
|
|
50
|
+
type: state.initial.type,
|
|
51
|
+
status: transition.status,
|
|
52
|
+
errorCode: transition.errorCode
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
allTransitions.sort((a, b) => a.timeMs - b.timeMs);
|
|
57
|
+
const p = (0, _captcha.waitForCaptchaSolve)(page, {
|
|
58
|
+
timeoutInMs: timeoutMs,
|
|
59
|
+
settleDurationMs
|
|
60
|
+
});
|
|
61
|
+
let assertion;
|
|
62
|
+
if (expectErrorCode) {
|
|
63
|
+
assertion = (0, _vitest.expect)(p).rejects.toThrow(`CAPTCHA Solve Error: ${expectErrorCode}`);
|
|
64
|
+
} else if (expectTimeout) {
|
|
65
|
+
assertion = (0, _vitest.expect)(p).rejects.toThrow("CAPTCHA Solve timed out with pending captchas.");
|
|
66
|
+
}
|
|
67
|
+
await _vitest.vi.advanceTimersByTimeAsync(0);
|
|
68
|
+
let currentTimeMs = 0;
|
|
69
|
+
for (const transition of allTransitions) {
|
|
70
|
+
const deltaMs = transition.timeMs - currentTimeMs;
|
|
71
|
+
if (deltaMs > 0) {
|
|
72
|
+
await _vitest.vi.advanceTimersByTimeAsync(deltaMs);
|
|
73
|
+
currentTimeMs = transition.timeMs;
|
|
74
|
+
}
|
|
75
|
+
const captcha = transition.status === "error" && transition.errorCode ? {
|
|
76
|
+
id: transition.captchaId,
|
|
77
|
+
tabId: 0,
|
|
78
|
+
type: transition.type,
|
|
79
|
+
status: "error",
|
|
80
|
+
error: {
|
|
81
|
+
code: transition.errorCode
|
|
82
|
+
}
|
|
83
|
+
} : {
|
|
84
|
+
id: transition.captchaId,
|
|
85
|
+
tabId: 0,
|
|
86
|
+
type: transition.type,
|
|
87
|
+
status: transition.status
|
|
88
|
+
};
|
|
89
|
+
await server.handleUpsertCaptcha(captcha);
|
|
90
|
+
}
|
|
91
|
+
await _vitest.vi.advanceTimersByTimeAsync(settleDurationMs + 10);
|
|
92
|
+
if (expectTimeout || expectErrorCode) {
|
|
93
|
+
await _vitest.vi.advanceTimersByTimeAsync(timeoutMs + settleDurationMs);
|
|
94
|
+
}
|
|
95
|
+
if (assertion) {
|
|
96
|
+
await assertion;
|
|
97
|
+
} else {
|
|
98
|
+
await (0, _vitest.expect)(p).resolves.toBeUndefined();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
55
101
|
(0, _vitest.beforeEach)(() => {
|
|
56
102
|
_vitest.vi.useFakeTimers();
|
|
57
|
-
server = new
|
|
103
|
+
server = new _intunedExtensionServer.ExtensionServer();
|
|
58
104
|
});
|
|
59
105
|
(0, _vitest.afterEach)(() => {
|
|
60
106
|
_vitest.vi.useRealTimers();
|
|
@@ -65,13 +111,11 @@ function makeMockPage() {
|
|
|
65
111
|
const page = makeMockPage();
|
|
66
112
|
const p = (0, _captcha.waitForCaptchaSolve)(page, {
|
|
67
113
|
timeoutInMs: 1000,
|
|
68
|
-
|
|
114
|
+
settleDurationMs: 10
|
|
69
115
|
});
|
|
70
116
|
await _vitest.vi.advanceTimersByTimeAsync(10);
|
|
71
117
|
await p;
|
|
72
118
|
(0, _vitest.expect)(page.waitForLoadState).not.toHaveBeenCalled();
|
|
73
|
-
(0, _vitest.expect)(server.subscribeCalls).toBe(1);
|
|
74
|
-
(0, _vitest.expect)(server.unsubscribeCalls).toBe(1);
|
|
75
119
|
});
|
|
76
120
|
(0, _vitest.it)("withWaitForCaptchaSolve: preserves return value and waits for networkidle by default", async () => {
|
|
77
121
|
const page = makeMockPage();
|
|
@@ -98,19 +142,19 @@ function makeMockPage() {
|
|
|
98
142
|
});
|
|
99
143
|
(0, _vitest.it)("waitForCaptchaSolve: completes when a solving captcha becomes solved", async () => {
|
|
100
144
|
const page = makeMockPage();
|
|
101
|
-
server.
|
|
145
|
+
await server.handleUpsertCaptcha({
|
|
102
146
|
id: "c1",
|
|
103
147
|
tabId: 0,
|
|
104
148
|
type: "recaptcha",
|
|
105
149
|
status: "solving",
|
|
106
150
|
retryCount: 0
|
|
107
|
-
}
|
|
151
|
+
});
|
|
108
152
|
const p = (0, _captcha.waitForCaptchaSolve)(page, {
|
|
109
153
|
timeoutInMs: 1000,
|
|
110
|
-
|
|
154
|
+
settleDurationMs: 10
|
|
111
155
|
});
|
|
112
156
|
await Promise.resolve();
|
|
113
|
-
await server.
|
|
157
|
+
await server.handleUpsertCaptcha({
|
|
114
158
|
id: "c1",
|
|
115
159
|
tabId: 0,
|
|
116
160
|
type: "recaptcha",
|
|
@@ -122,20 +166,20 @@ function makeMockPage() {
|
|
|
122
166
|
});
|
|
123
167
|
(0, _vitest.it)("waitForCaptchaSolve: throws on captcha error", async () => {
|
|
124
168
|
const page = makeMockPage();
|
|
125
|
-
server.
|
|
169
|
+
await server.handleUpsertCaptcha({
|
|
126
170
|
id: "c1",
|
|
127
171
|
tabId: 0,
|
|
128
172
|
type: "recaptcha",
|
|
129
173
|
status: "solving",
|
|
130
174
|
retryCount: 0
|
|
131
|
-
}
|
|
175
|
+
});
|
|
132
176
|
const p = (0, _captcha.waitForCaptchaSolve)(page, {
|
|
133
177
|
timeoutInMs: 1000,
|
|
134
|
-
|
|
178
|
+
settleDurationMs: 10
|
|
135
179
|
});
|
|
136
180
|
const assertion = (0, _vitest.expect)(p).rejects.toThrow("CAPTCHA Solve Error: UNEXPECTED_ERROR");
|
|
137
|
-
await
|
|
138
|
-
await server.
|
|
181
|
+
await _vitest.vi.advanceTimersByTimeAsync(0);
|
|
182
|
+
await server.handleUpsertCaptcha({
|
|
139
183
|
id: "c1",
|
|
140
184
|
tabId: 0,
|
|
141
185
|
type: "recaptcha",
|
|
@@ -147,49 +191,48 @@ function makeMockPage() {
|
|
|
147
191
|
});
|
|
148
192
|
await _vitest.vi.advanceTimersByTimeAsync(10);
|
|
149
193
|
await assertion;
|
|
150
|
-
(0, _vitest.expect)(server.unsubscribeCalls).toBe(1);
|
|
151
194
|
});
|
|
152
195
|
(0, _vitest.it)("waitForCaptchaSolve: times out if captchas are still pending", async () => {
|
|
153
196
|
const page = makeMockPage();
|
|
154
|
-
server.
|
|
197
|
+
await server.handleUpsertCaptcha({
|
|
155
198
|
id: "c1",
|
|
156
199
|
tabId: 0,
|
|
157
200
|
type: "recaptcha",
|
|
158
201
|
status: "solving",
|
|
159
202
|
retryCount: 0
|
|
160
|
-
}
|
|
203
|
+
});
|
|
161
204
|
const p = (0, _captcha.waitForCaptchaSolve)(page, {
|
|
162
205
|
timeoutInMs: 5,
|
|
163
|
-
|
|
206
|
+
settleDurationMs: 1
|
|
164
207
|
});
|
|
165
208
|
const assertion = (0, _vitest.expect)(p).rejects.toThrow("CAPTCHA Solve timed out with pending captchas.");
|
|
166
209
|
await Promise.resolve();
|
|
167
210
|
await _vitest.vi.advanceTimersByTimeAsync(6);
|
|
168
211
|
await _vitest.vi.advanceTimersByTimeAsync(1);
|
|
169
212
|
await assertion;
|
|
170
|
-
(0, _vitest.expect)(server.unsubscribeCalls).toBe(1);
|
|
171
213
|
});
|
|
172
214
|
(0, _vitest.it)("waitForCaptchaSolve: waits for all captchas to resolve", async () => {
|
|
173
215
|
const page = makeMockPage();
|
|
174
|
-
server.
|
|
216
|
+
await server.handleUpsertCaptcha({
|
|
175
217
|
id: "c1",
|
|
176
218
|
tabId: 0,
|
|
177
219
|
type: "recaptcha",
|
|
178
220
|
status: "solving",
|
|
179
221
|
retryCount: 0
|
|
180
|
-
}
|
|
222
|
+
});
|
|
223
|
+
await server.handleUpsertCaptcha({
|
|
181
224
|
id: "c2",
|
|
182
225
|
tabId: 0,
|
|
183
226
|
type: "hcaptcha",
|
|
184
227
|
status: "solving",
|
|
185
228
|
retryCount: 0
|
|
186
|
-
}
|
|
229
|
+
});
|
|
187
230
|
const p = (0, _captcha.waitForCaptchaSolve)(page, {
|
|
188
231
|
timeoutInMs: 1000,
|
|
189
|
-
|
|
232
|
+
settleDurationMs: 10
|
|
190
233
|
});
|
|
191
234
|
await Promise.resolve();
|
|
192
|
-
await server.
|
|
235
|
+
await server.handleUpsertCaptcha({
|
|
193
236
|
id: "c1",
|
|
194
237
|
tabId: 0,
|
|
195
238
|
type: "recaptcha",
|
|
@@ -201,7 +244,7 @@ function makeMockPage() {
|
|
|
201
244
|
p.then(() => settled = true).catch(() => settled = true);
|
|
202
245
|
await Promise.resolve();
|
|
203
246
|
(0, _vitest.expect)(settled).toBe(false);
|
|
204
|
-
await server.
|
|
247
|
+
await server.handleUpsertCaptcha({
|
|
205
248
|
id: "c2",
|
|
206
249
|
tabId: 0,
|
|
207
250
|
type: "hcaptcha",
|
|
@@ -211,4 +254,568 @@ function makeMockPage() {
|
|
|
211
254
|
await _vitest.vi.advanceTimersByTimeAsync(10);
|
|
212
255
|
await (0, _vitest.expect)(p).resolves.toBeUndefined();
|
|
213
256
|
});
|
|
257
|
+
(0, _vitest.describe)("captchaStateTransitions", () => {
|
|
258
|
+
(0, _vitest.it)("captcha detached completes successfully", async () => {
|
|
259
|
+
const page = makeMockPage();
|
|
260
|
+
await runCaptchaTestScenario({
|
|
261
|
+
page,
|
|
262
|
+
mockStates: [{
|
|
263
|
+
initial: {
|
|
264
|
+
id: "test1",
|
|
265
|
+
tabId: 0,
|
|
266
|
+
type: "recaptcha",
|
|
267
|
+
status: "solving"
|
|
268
|
+
},
|
|
269
|
+
transitions: [{
|
|
270
|
+
timeMs: 100,
|
|
271
|
+
status: "detached"
|
|
272
|
+
}]
|
|
273
|
+
}],
|
|
274
|
+
settleDurationMs: 100
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
(0, _vitest.it)("attached to solving to solved", async () => {
|
|
278
|
+
const page = makeMockPage();
|
|
279
|
+
await runCaptchaTestScenario({
|
|
280
|
+
page,
|
|
281
|
+
mockStates: [{
|
|
282
|
+
initial: {
|
|
283
|
+
id: "captcha1",
|
|
284
|
+
tabId: 0,
|
|
285
|
+
type: "recaptcha",
|
|
286
|
+
status: "attached"
|
|
287
|
+
},
|
|
288
|
+
transitions: [{
|
|
289
|
+
timeMs: 50,
|
|
290
|
+
status: "solving"
|
|
291
|
+
}, {
|
|
292
|
+
timeMs: 350,
|
|
293
|
+
status: "solved"
|
|
294
|
+
}]
|
|
295
|
+
}],
|
|
296
|
+
settleDurationMs: 100
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
(0, _vitest.it)("attached to detached", async () => {
|
|
300
|
+
const page = makeMockPage();
|
|
301
|
+
await runCaptchaTestScenario({
|
|
302
|
+
page,
|
|
303
|
+
mockStates: [{
|
|
304
|
+
initial: {
|
|
305
|
+
id: "captcha1",
|
|
306
|
+
tabId: 0,
|
|
307
|
+
type: "recaptcha",
|
|
308
|
+
status: "attached"
|
|
309
|
+
},
|
|
310
|
+
transitions: [{
|
|
311
|
+
timeMs: 100,
|
|
312
|
+
status: "detached"
|
|
313
|
+
}]
|
|
314
|
+
}],
|
|
315
|
+
settleDurationMs: 100
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
(0, _vitest.it)("attached to solving to error", async () => {
|
|
319
|
+
const page = makeMockPage();
|
|
320
|
+
await runCaptchaTestScenario({
|
|
321
|
+
page,
|
|
322
|
+
mockStates: [{
|
|
323
|
+
initial: {
|
|
324
|
+
id: "captcha1",
|
|
325
|
+
tabId: 0,
|
|
326
|
+
type: "recaptcha",
|
|
327
|
+
status: "attached"
|
|
328
|
+
},
|
|
329
|
+
transitions: [{
|
|
330
|
+
timeMs: 50,
|
|
331
|
+
status: "solving"
|
|
332
|
+
}, {
|
|
333
|
+
timeMs: 550,
|
|
334
|
+
status: "error",
|
|
335
|
+
errorCode: "UNEXPECTED_ERROR"
|
|
336
|
+
}]
|
|
337
|
+
}],
|
|
338
|
+
settleDurationMs: 100,
|
|
339
|
+
expectErrorCode: "UNEXPECTED_ERROR"
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
(0, _vitest.it)("attached to solving to detached", async () => {
|
|
343
|
+
const page = makeMockPage();
|
|
344
|
+
await runCaptchaTestScenario({
|
|
345
|
+
page,
|
|
346
|
+
mockStates: [{
|
|
347
|
+
initial: {
|
|
348
|
+
id: "captcha1",
|
|
349
|
+
tabId: 0,
|
|
350
|
+
type: "recaptcha",
|
|
351
|
+
status: "attached"
|
|
352
|
+
},
|
|
353
|
+
transitions: [{
|
|
354
|
+
timeMs: 50,
|
|
355
|
+
status: "solving"
|
|
356
|
+
}, {
|
|
357
|
+
timeMs: 200,
|
|
358
|
+
status: "detached"
|
|
359
|
+
}]
|
|
360
|
+
}],
|
|
361
|
+
settleDurationMs: 100
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
(0, _vitest.it)("visibility toggle then solved", async () => {
|
|
365
|
+
const page = makeMockPage();
|
|
366
|
+
await runCaptchaTestScenario({
|
|
367
|
+
page,
|
|
368
|
+
mockStates: [{
|
|
369
|
+
initial: {
|
|
370
|
+
id: "captcha1",
|
|
371
|
+
tabId: 0,
|
|
372
|
+
type: "recaptcha",
|
|
373
|
+
status: "attached"
|
|
374
|
+
},
|
|
375
|
+
transitions: [{
|
|
376
|
+
timeMs: 50,
|
|
377
|
+
status: "solving"
|
|
378
|
+
}, {
|
|
379
|
+
timeMs: 100,
|
|
380
|
+
status: "attached"
|
|
381
|
+
}, {
|
|
382
|
+
timeMs: 120,
|
|
383
|
+
status: "solving"
|
|
384
|
+
}, {
|
|
385
|
+
timeMs: 420,
|
|
386
|
+
status: "solved"
|
|
387
|
+
}]
|
|
388
|
+
}],
|
|
389
|
+
settleDurationMs: 100
|
|
390
|
+
});
|
|
391
|
+
});
|
|
392
|
+
(0, _vitest.it)("visibility toggle then error", async () => {
|
|
393
|
+
const page = makeMockPage();
|
|
394
|
+
await runCaptchaTestScenario({
|
|
395
|
+
page,
|
|
396
|
+
mockStates: [{
|
|
397
|
+
initial: {
|
|
398
|
+
id: "captcha1",
|
|
399
|
+
tabId: 0,
|
|
400
|
+
type: "recaptcha",
|
|
401
|
+
status: "attached"
|
|
402
|
+
},
|
|
403
|
+
transitions: [{
|
|
404
|
+
timeMs: 50,
|
|
405
|
+
status: "solving"
|
|
406
|
+
}, {
|
|
407
|
+
timeMs: 100,
|
|
408
|
+
status: "attached"
|
|
409
|
+
}, {
|
|
410
|
+
timeMs: 120,
|
|
411
|
+
status: "solving"
|
|
412
|
+
}, {
|
|
413
|
+
timeMs: 620,
|
|
414
|
+
status: "error",
|
|
415
|
+
errorCode: "MAX_RETRIES"
|
|
416
|
+
}]
|
|
417
|
+
}],
|
|
418
|
+
settleDurationMs: 100,
|
|
419
|
+
expectErrorCode: "MAX_RETRIES"
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
(0, _vitest.it)("visibility toggle then detached", async () => {
|
|
423
|
+
const page = makeMockPage();
|
|
424
|
+
await runCaptchaTestScenario({
|
|
425
|
+
page,
|
|
426
|
+
mockStates: [{
|
|
427
|
+
initial: {
|
|
428
|
+
id: "captcha1",
|
|
429
|
+
tabId: 0,
|
|
430
|
+
type: "recaptcha",
|
|
431
|
+
status: "attached"
|
|
432
|
+
},
|
|
433
|
+
transitions: [{
|
|
434
|
+
timeMs: 50,
|
|
435
|
+
status: "solving"
|
|
436
|
+
}, {
|
|
437
|
+
timeMs: 100,
|
|
438
|
+
status: "attached"
|
|
439
|
+
}, {
|
|
440
|
+
timeMs: 110,
|
|
441
|
+
status: "detached"
|
|
442
|
+
}]
|
|
443
|
+
}],
|
|
444
|
+
settleDurationMs: 100
|
|
445
|
+
});
|
|
446
|
+
});
|
|
447
|
+
(0, _vitest.it)("visibility toggle solving then detached", async () => {
|
|
448
|
+
const page = makeMockPage();
|
|
449
|
+
await runCaptchaTestScenario({
|
|
450
|
+
page,
|
|
451
|
+
mockStates: [{
|
|
452
|
+
initial: {
|
|
453
|
+
id: "captcha1",
|
|
454
|
+
tabId: 0,
|
|
455
|
+
type: "recaptcha",
|
|
456
|
+
status: "attached"
|
|
457
|
+
},
|
|
458
|
+
transitions: [{
|
|
459
|
+
timeMs: 50,
|
|
460
|
+
status: "solving"
|
|
461
|
+
}, {
|
|
462
|
+
timeMs: 100,
|
|
463
|
+
status: "attached"
|
|
464
|
+
}, {
|
|
465
|
+
timeMs: 120,
|
|
466
|
+
status: "solving"
|
|
467
|
+
}, {
|
|
468
|
+
timeMs: 270,
|
|
469
|
+
status: "detached"
|
|
470
|
+
}]
|
|
471
|
+
}],
|
|
472
|
+
settleDurationMs: 100
|
|
473
|
+
});
|
|
474
|
+
});
|
|
475
|
+
(0, _vitest.it)("rapid visibility toggle then solved", async () => {
|
|
476
|
+
const page = makeMockPage();
|
|
477
|
+
await runCaptchaTestScenario({
|
|
478
|
+
page,
|
|
479
|
+
mockStates: [{
|
|
480
|
+
initial: {
|
|
481
|
+
id: "captcha1",
|
|
482
|
+
tabId: 0,
|
|
483
|
+
type: "recaptcha",
|
|
484
|
+
status: "attached"
|
|
485
|
+
},
|
|
486
|
+
transitions: [{
|
|
487
|
+
timeMs: 50,
|
|
488
|
+
status: "solving"
|
|
489
|
+
}, {
|
|
490
|
+
timeMs: 60,
|
|
491
|
+
status: "attached"
|
|
492
|
+
}, {
|
|
493
|
+
timeMs: 65,
|
|
494
|
+
status: "solving"
|
|
495
|
+
}, {
|
|
496
|
+
timeMs: 75,
|
|
497
|
+
status: "attached"
|
|
498
|
+
}, {
|
|
499
|
+
timeMs: 80,
|
|
500
|
+
status: "solving"
|
|
501
|
+
}, {
|
|
502
|
+
timeMs: 380,
|
|
503
|
+
status: "solved"
|
|
504
|
+
}]
|
|
505
|
+
}],
|
|
506
|
+
settleDurationMs: 100
|
|
507
|
+
});
|
|
508
|
+
});
|
|
509
|
+
(0, _vitest.it)("rapid visibility toggle then detached", async () => {
|
|
510
|
+
const page = makeMockPage();
|
|
511
|
+
await runCaptchaTestScenario({
|
|
512
|
+
page,
|
|
513
|
+
mockStates: [{
|
|
514
|
+
initial: {
|
|
515
|
+
id: "captcha1",
|
|
516
|
+
tabId: 0,
|
|
517
|
+
type: "recaptcha",
|
|
518
|
+
status: "attached"
|
|
519
|
+
},
|
|
520
|
+
transitions: [{
|
|
521
|
+
timeMs: 50,
|
|
522
|
+
status: "solving"
|
|
523
|
+
}, {
|
|
524
|
+
timeMs: 60,
|
|
525
|
+
status: "attached"
|
|
526
|
+
}, {
|
|
527
|
+
timeMs: 65,
|
|
528
|
+
status: "solving"
|
|
529
|
+
}, {
|
|
530
|
+
timeMs: 75,
|
|
531
|
+
status: "attached"
|
|
532
|
+
}, {
|
|
533
|
+
timeMs: 80,
|
|
534
|
+
status: "detached"
|
|
535
|
+
}]
|
|
536
|
+
}],
|
|
537
|
+
settleDurationMs: 100
|
|
538
|
+
});
|
|
539
|
+
});
|
|
540
|
+
(0, _vitest.it)("instant toggles then solved", async () => {
|
|
541
|
+
const page = makeMockPage();
|
|
542
|
+
await runCaptchaTestScenario({
|
|
543
|
+
page,
|
|
544
|
+
mockStates: [{
|
|
545
|
+
initial: {
|
|
546
|
+
id: "captcha1",
|
|
547
|
+
tabId: 0,
|
|
548
|
+
type: "recaptcha",
|
|
549
|
+
status: "attached"
|
|
550
|
+
},
|
|
551
|
+
transitions: [{
|
|
552
|
+
timeMs: 1,
|
|
553
|
+
status: "solving"
|
|
554
|
+
}, {
|
|
555
|
+
timeMs: 2,
|
|
556
|
+
status: "attached"
|
|
557
|
+
}, {
|
|
558
|
+
timeMs: 3,
|
|
559
|
+
status: "solving"
|
|
560
|
+
}, {
|
|
561
|
+
timeMs: 300,
|
|
562
|
+
status: "solved"
|
|
563
|
+
}]
|
|
564
|
+
}],
|
|
565
|
+
settleDurationMs: 100
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
(0, _vitest.it)("long solving timeout", async () => {
|
|
569
|
+
const page = makeMockPage();
|
|
570
|
+
await runCaptchaTestScenario({
|
|
571
|
+
page,
|
|
572
|
+
mockStates: [{
|
|
573
|
+
initial: {
|
|
574
|
+
id: "captcha1",
|
|
575
|
+
tabId: 0,
|
|
576
|
+
type: "recaptcha",
|
|
577
|
+
status: "attached"
|
|
578
|
+
},
|
|
579
|
+
transitions: [{
|
|
580
|
+
timeMs: 10,
|
|
581
|
+
status: "solving"
|
|
582
|
+
}, {
|
|
583
|
+
timeMs: 30000,
|
|
584
|
+
status: "error",
|
|
585
|
+
errorCode: "UNEXPECTED_ERROR"
|
|
586
|
+
}]
|
|
587
|
+
}],
|
|
588
|
+
timeoutMs: 10000,
|
|
589
|
+
settleDurationMs: 3000,
|
|
590
|
+
expectTimeout: true
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
(0, _vitest.it)("multiple captchas both solve", async () => {
|
|
594
|
+
const page = makeMockPage();
|
|
595
|
+
await runCaptchaTestScenario({
|
|
596
|
+
page,
|
|
597
|
+
mockStates: [{
|
|
598
|
+
initial: {
|
|
599
|
+
id: "captcha1",
|
|
600
|
+
tabId: 0,
|
|
601
|
+
type: "recaptcha",
|
|
602
|
+
status: "solving"
|
|
603
|
+
},
|
|
604
|
+
transitions: [{
|
|
605
|
+
timeMs: 100,
|
|
606
|
+
status: "solved"
|
|
607
|
+
}]
|
|
608
|
+
}, {
|
|
609
|
+
initial: {
|
|
610
|
+
id: "captcha2",
|
|
611
|
+
tabId: 0,
|
|
612
|
+
type: "hcaptcha",
|
|
613
|
+
status: "solving"
|
|
614
|
+
},
|
|
615
|
+
transitions: [{
|
|
616
|
+
timeMs: 200,
|
|
617
|
+
status: "solved"
|
|
618
|
+
}]
|
|
619
|
+
}],
|
|
620
|
+
settleDurationMs: 100
|
|
621
|
+
});
|
|
622
|
+
});
|
|
623
|
+
(0, _vitest.it)("multiple captchas one errors", async () => {
|
|
624
|
+
const page = makeMockPage();
|
|
625
|
+
await runCaptchaTestScenario({
|
|
626
|
+
page,
|
|
627
|
+
mockStates: [{
|
|
628
|
+
initial: {
|
|
629
|
+
id: "captcha1",
|
|
630
|
+
tabId: 0,
|
|
631
|
+
type: "recaptcha",
|
|
632
|
+
status: "solving"
|
|
633
|
+
},
|
|
634
|
+
transitions: []
|
|
635
|
+
}, {
|
|
636
|
+
initial: {
|
|
637
|
+
id: "captcha2",
|
|
638
|
+
tabId: 0,
|
|
639
|
+
type: "hcaptcha",
|
|
640
|
+
status: "solving"
|
|
641
|
+
},
|
|
642
|
+
transitions: [{
|
|
643
|
+
timeMs: 100,
|
|
644
|
+
status: "error",
|
|
645
|
+
errorCode: "HIT_LIMIT"
|
|
646
|
+
}]
|
|
647
|
+
}],
|
|
648
|
+
settleDurationMs: 100,
|
|
649
|
+
expectErrorCode: "HIT_LIMIT"
|
|
650
|
+
});
|
|
651
|
+
});
|
|
652
|
+
(0, _vitest.it)("staggered captcha resolution", async () => {
|
|
653
|
+
const page = makeMockPage();
|
|
654
|
+
await runCaptchaTestScenario({
|
|
655
|
+
page,
|
|
656
|
+
mockStates: [{
|
|
657
|
+
initial: {
|
|
658
|
+
id: "captcha1",
|
|
659
|
+
tabId: 0,
|
|
660
|
+
type: "recaptcha",
|
|
661
|
+
status: "solving"
|
|
662
|
+
},
|
|
663
|
+
transitions: [{
|
|
664
|
+
timeMs: 100,
|
|
665
|
+
status: "solved"
|
|
666
|
+
}]
|
|
667
|
+
}, {
|
|
668
|
+
initial: {
|
|
669
|
+
id: "captcha2",
|
|
670
|
+
tabId: 0,
|
|
671
|
+
type: "hcaptcha",
|
|
672
|
+
status: "solving"
|
|
673
|
+
},
|
|
674
|
+
transitions: [{
|
|
675
|
+
timeMs: 200,
|
|
676
|
+
status: "detached"
|
|
677
|
+
}]
|
|
678
|
+
}, {
|
|
679
|
+
initial: {
|
|
680
|
+
id: "captcha3",
|
|
681
|
+
tabId: 0,
|
|
682
|
+
type: "funcaptcha",
|
|
683
|
+
status: "solving"
|
|
684
|
+
},
|
|
685
|
+
transitions: [{
|
|
686
|
+
timeMs: 300,
|
|
687
|
+
status: "solved"
|
|
688
|
+
}]
|
|
689
|
+
}],
|
|
690
|
+
settleDurationMs: 100
|
|
691
|
+
});
|
|
692
|
+
});
|
|
693
|
+
});
|
|
694
|
+
(0, _vitest.describe)("onCaptchaEvent", () => {
|
|
695
|
+
(0, _vitest.it)("calls callback for matching status", async () => {
|
|
696
|
+
const page = makeMockPage();
|
|
697
|
+
const receivedCaptchas = [];
|
|
698
|
+
await (0, _captcha.onCaptchaEvent)(page, "solved", async captcha => {
|
|
699
|
+
receivedCaptchas.push(captcha);
|
|
700
|
+
});
|
|
701
|
+
await server.handleUpsertCaptcha({
|
|
702
|
+
id: "c1",
|
|
703
|
+
tabId: 0,
|
|
704
|
+
type: "recaptcha",
|
|
705
|
+
status: "solved"
|
|
706
|
+
});
|
|
707
|
+
(0, _vitest.expect)(receivedCaptchas).toHaveLength(1);
|
|
708
|
+
(0, _vitest.expect)(receivedCaptchas[0].id).toBe("c1");
|
|
709
|
+
(0, _vitest.expect)(receivedCaptchas[0].status).toBe("solved");
|
|
710
|
+
});
|
|
711
|
+
(0, _vitest.it)("ignores non-matching status", async () => {
|
|
712
|
+
const page = makeMockPage();
|
|
713
|
+
const receivedCaptchas = [];
|
|
714
|
+
await (0, _captcha.onCaptchaEvent)(page, "solved", async captcha => {
|
|
715
|
+
receivedCaptchas.push(captcha);
|
|
716
|
+
});
|
|
717
|
+
await server.handleUpsertCaptcha({
|
|
718
|
+
id: "c1",
|
|
719
|
+
tabId: 0,
|
|
720
|
+
type: "recaptcha",
|
|
721
|
+
status: "solving"
|
|
722
|
+
});
|
|
723
|
+
(0, _vitest.expect)(receivedCaptchas).toHaveLength(0);
|
|
724
|
+
});
|
|
725
|
+
(0, _vitest.it)("calls callback multiple times for multiple matching events", async () => {
|
|
726
|
+
const page = makeMockPage();
|
|
727
|
+
const receivedCaptchas = [];
|
|
728
|
+
await (0, _captcha.onCaptchaEvent)(page, "solved", async captcha => {
|
|
729
|
+
receivedCaptchas.push(captcha);
|
|
730
|
+
});
|
|
731
|
+
await server.handleUpsertCaptcha({
|
|
732
|
+
id: "c1",
|
|
733
|
+
tabId: 0,
|
|
734
|
+
type: "recaptcha",
|
|
735
|
+
status: "solved"
|
|
736
|
+
});
|
|
737
|
+
await server.handleUpsertCaptcha({
|
|
738
|
+
id: "c2",
|
|
739
|
+
tabId: 0,
|
|
740
|
+
type: "hcaptcha",
|
|
741
|
+
status: "solved"
|
|
742
|
+
});
|
|
743
|
+
(0, _vitest.expect)(receivedCaptchas).toHaveLength(2);
|
|
744
|
+
(0, _vitest.expect)(receivedCaptchas[0].id).toBe("c1");
|
|
745
|
+
(0, _vitest.expect)(receivedCaptchas[1].id).toBe("c2");
|
|
746
|
+
});
|
|
747
|
+
});
|
|
748
|
+
(0, _vitest.describe)("onceCaptchaEvent", () => {
|
|
749
|
+
(0, _vitest.it)("calls callback only once for first matching event", async () => {
|
|
750
|
+
const page = makeMockPage();
|
|
751
|
+
const receivedCaptchas = [];
|
|
752
|
+
await (0, _captcha.onceCaptchaEvent)(page, "solved", async captcha => {
|
|
753
|
+
receivedCaptchas.push(captcha);
|
|
754
|
+
});
|
|
755
|
+
await server.handleUpsertCaptcha({
|
|
756
|
+
id: "c1",
|
|
757
|
+
tabId: 0,
|
|
758
|
+
type: "recaptcha",
|
|
759
|
+
status: "solved"
|
|
760
|
+
});
|
|
761
|
+
await server.handleUpsertCaptcha({
|
|
762
|
+
id: "c2",
|
|
763
|
+
tabId: 0,
|
|
764
|
+
type: "hcaptcha",
|
|
765
|
+
status: "solved"
|
|
766
|
+
});
|
|
767
|
+
(0, _vitest.expect)(receivedCaptchas).toHaveLength(1);
|
|
768
|
+
(0, _vitest.expect)(receivedCaptchas[0].id).toBe("c1");
|
|
769
|
+
});
|
|
770
|
+
(0, _vitest.it)("receives all events until first match, then unsubscribes", async () => {
|
|
771
|
+
const page = makeMockPage();
|
|
772
|
+
const receivedCaptchas = [];
|
|
773
|
+
await (0, _captcha.onceCaptchaEvent)(page, "solved", async captcha => {
|
|
774
|
+
receivedCaptchas.push(captcha);
|
|
775
|
+
});
|
|
776
|
+
await server.handleUpsertCaptcha({
|
|
777
|
+
id: "c1",
|
|
778
|
+
tabId: 0,
|
|
779
|
+
type: "recaptcha",
|
|
780
|
+
status: "solving"
|
|
781
|
+
});
|
|
782
|
+
(0, _vitest.expect)(receivedCaptchas).toHaveLength(0);
|
|
783
|
+
await server.handleUpsertCaptcha({
|
|
784
|
+
id: "c2",
|
|
785
|
+
tabId: 0,
|
|
786
|
+
type: "recaptcha",
|
|
787
|
+
status: "solved"
|
|
788
|
+
});
|
|
789
|
+
(0, _vitest.expect)(receivedCaptchas).toHaveLength(1);
|
|
790
|
+
(0, _vitest.expect)(receivedCaptchas[0].id).toBe("c2");
|
|
791
|
+
await server.handleUpsertCaptcha({
|
|
792
|
+
id: "c3",
|
|
793
|
+
tabId: 0,
|
|
794
|
+
type: "recaptcha",
|
|
795
|
+
status: "solved"
|
|
796
|
+
});
|
|
797
|
+
(0, _vitest.expect)(receivedCaptchas).toHaveLength(1);
|
|
798
|
+
});
|
|
799
|
+
(0, _vitest.it)("unsubscribes after first matching event", async () => {
|
|
800
|
+
const page = makeMockPage();
|
|
801
|
+
let callCount = 0;
|
|
802
|
+
await (0, _captcha.onceCaptchaEvent)(page, "solved", async () => {
|
|
803
|
+
callCount++;
|
|
804
|
+
});
|
|
805
|
+
await server.handleUpsertCaptcha({
|
|
806
|
+
id: "c1",
|
|
807
|
+
tabId: 0,
|
|
808
|
+
type: "recaptcha",
|
|
809
|
+
status: "solved"
|
|
810
|
+
});
|
|
811
|
+
(0, _vitest.expect)(callCount).toBe(1);
|
|
812
|
+
await server.handleUpsertCaptcha({
|
|
813
|
+
id: "c2",
|
|
814
|
+
tabId: 0,
|
|
815
|
+
type: "recaptcha",
|
|
816
|
+
status: "solved"
|
|
817
|
+
});
|
|
818
|
+
(0, _vitest.expect)(callCount).toBe(1);
|
|
819
|
+
});
|
|
820
|
+
});
|
|
214
821
|
});
|