appium-remote-debugger 15.3.3 → 15.3.5
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/CHANGELOG.md +12 -0
- package/build/lib/atoms.d.ts.map +1 -1
- package/build/lib/atoms.js +2 -2
- package/build/lib/atoms.js.map +1 -1
- package/build/lib/index.d.ts +2 -1
- package/build/lib/index.d.ts.map +1 -1
- package/build/lib/index.js +0 -1
- package/build/lib/index.js.map +1 -1
- package/build/lib/logger.js.map +1 -1
- package/build/lib/mixins/connect.d.ts.map +1 -1
- package/build/lib/mixins/connect.js +11 -8
- package/build/lib/mixins/connect.js.map +1 -1
- package/build/lib/mixins/cookies.d.ts.map +1 -1
- package/build/lib/mixins/cookies.js.map +1 -1
- package/build/lib/mixins/events.d.ts.map +1 -1
- package/build/lib/mixins/events.js +1 -1
- package/build/lib/mixins/events.js.map +1 -1
- package/build/lib/mixins/execute.d.ts.map +1 -1
- package/build/lib/mixins/execute.js +2 -2
- package/build/lib/mixins/execute.js.map +1 -1
- package/build/lib/mixins/message-handlers.d.ts.map +1 -1
- package/build/lib/mixins/message-handlers.js.map +1 -1
- package/build/lib/mixins/misc.d.ts.map +1 -1
- package/build/lib/mixins/misc.js +1 -1
- package/build/lib/mixins/misc.js.map +1 -1
- package/build/lib/mixins/navigate.d.ts.map +1 -1
- package/build/lib/mixins/navigate.js +2 -3
- package/build/lib/mixins/navigate.js.map +1 -1
- package/build/lib/mixins/property-accessors.d.ts +20 -20
- package/build/lib/mixins/property-accessors.d.ts.map +1 -1
- package/build/lib/mixins/property-accessors.js.map +1 -1
- package/build/lib/mixins/screenshot.d.ts.map +1 -1
- package/build/lib/mixins/screenshot.js +5 -1
- package/build/lib/mixins/screenshot.js.map +1 -1
- package/build/lib/protocol/index.d.ts.map +1 -1
- package/build/lib/protocol/index.js +2 -3
- package/build/lib/protocol/index.js.map +1 -1
- package/build/lib/remote-debugger-real-device.d.ts.map +1 -1
- package/build/lib/remote-debugger-real-device.js.map +1 -1
- package/build/lib/remote-debugger.d.ts.map +1 -1
- package/build/lib/remote-debugger.js +3 -1
- package/build/lib/remote-debugger.js.map +1 -1
- package/build/lib/rpc/index.d.ts.map +1 -1
- package/build/lib/rpc/index.js.map +1 -1
- package/build/lib/rpc/remote-messages.d.ts.map +1 -1
- package/build/lib/rpc/remote-messages.js +16 -15
- package/build/lib/rpc/remote-messages.js.map +1 -1
- package/build/lib/rpc/rpc-client-real-device.d.ts.map +1 -1
- package/build/lib/rpc/rpc-client-real-device.js.map +1 -1
- package/build/lib/rpc/rpc-client-simulator.d.ts.map +1 -1
- package/build/lib/rpc/rpc-client-simulator.js +3 -4
- package/build/lib/rpc/rpc-client-simulator.js.map +1 -1
- package/build/lib/rpc/rpc-client.d.ts.map +1 -1
- package/build/lib/rpc/rpc-client.js +6 -6
- package/build/lib/rpc/rpc-client.js.map +1 -1
- package/build/lib/rpc/rpc-message-handler.d.ts.map +1 -1
- package/build/lib/rpc/rpc-message-handler.js +3 -4
- package/build/lib/rpc/rpc-message-handler.js.map +1 -1
- package/build/lib/types.d.ts.map +1 -1
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +6 -5
- package/build/lib/utils.js.map +1 -1
- package/lib/atoms.ts +8 -6
- package/lib/index.ts +18 -11
- package/lib/logger.ts +1 -1
- package/lib/mixins/connect.ts +63 -47
- package/lib/mixins/cookies.ts +5 -11
- package/lib/mixins/events.ts +8 -19
- package/lib/mixins/execute.ts +43 -35
- package/lib/mixins/message-handlers.ts +21 -20
- package/lib/mixins/misc.ts +12 -15
- package/lib/mixins/navigate.ts +68 -61
- package/lib/mixins/property-accessors.ts +48 -23
- package/lib/mixins/screenshot.ts +10 -11
- package/lib/protocol/index.ts +11 -9
- package/lib/remote-debugger-real-device.ts +5 -5
- package/lib/remote-debugger.ts +22 -28
- package/lib/rpc/index.ts +2 -2
- package/lib/rpc/remote-messages.ts +48 -48
- package/lib/rpc/rpc-client-real-device.ts +4 -4
- package/lib/rpc/rpc-client-simulator.ts +23 -20
- package/lib/rpc/rpc-client.ts +161 -108
- package/lib/rpc/rpc-message-handler.ts +34 -24
- package/lib/types.ts +3 -3
- package/lib/utils.ts +24 -17
- package/package.json +3 -1
package/lib/rpc/rpc-client.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import {RemoteMessages} from './remote-messages';
|
|
2
|
+
import {waitForCondition} from 'asyncbox';
|
|
3
|
+
import {log} from '../logger';
|
|
4
4
|
import _ from 'lodash';
|
|
5
5
|
import B from 'bluebird';
|
|
6
6
|
import RpcMessageHandler from './rpc-message-handler';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import {util, timing} from '@appium/support';
|
|
8
|
+
import {EventEmitter} from 'node:events';
|
|
9
9
|
import AsyncLock from 'async-lock';
|
|
10
|
-
import {
|
|
11
|
-
import type {
|
|
10
|
+
import {convertJavascriptEvaluationResult} from '../utils';
|
|
11
|
+
import type {StringRecord} from '@appium/types';
|
|
12
12
|
import type {
|
|
13
13
|
AppIdKey,
|
|
14
14
|
PageIdKey,
|
|
@@ -152,7 +152,10 @@ export class RpcClient {
|
|
|
152
152
|
this.messageHandler.on('Target.targetCreated', this.addTarget.bind(this));
|
|
153
153
|
this.messageHandler.on('Target.didCommitProvisionalTarget', this.updateTarget.bind(this));
|
|
154
154
|
this.messageHandler.on('Target.targetDestroyed', this.removeTarget.bind(this));
|
|
155
|
-
this.messageHandler.on(
|
|
155
|
+
this.messageHandler.on(
|
|
156
|
+
'Runtime.executionContextCreated',
|
|
157
|
+
this.onExecutionContextCreated.bind(this),
|
|
158
|
+
);
|
|
156
159
|
this.messageHandler.on('Heap.garbageCollected', this.onGarbageCollected.bind(this));
|
|
157
160
|
}
|
|
158
161
|
|
|
@@ -301,7 +304,7 @@ export class RpcClient {
|
|
|
301
304
|
let target = this.getTarget(appIdKey, pageIdKey);
|
|
302
305
|
if (target) {
|
|
303
306
|
log.debug(
|
|
304
|
-
`The target '${target}' for app '${appIdKey}' and page '${pageIdKey}' already exists, no need to wait
|
|
307
|
+
`The target '${target}' for app '${appIdKey}' and page '${pageIdKey}' already exists, no need to wait`,
|
|
305
308
|
);
|
|
306
309
|
return target;
|
|
307
310
|
}
|
|
@@ -310,23 +313,26 @@ export class RpcClient {
|
|
|
310
313
|
const waitMs = Math.max(MIN_WAIT_FOR_TARGET_TIMEOUT_MS, this.pageLoadTimeoutMs || 0);
|
|
311
314
|
log.debug(
|
|
312
315
|
`Waiting up to ${waitMs}ms for a target to be created for ` +
|
|
313
|
-
|
|
316
|
+
`app '${appIdKey}' and page '${pageIdKey}'`,
|
|
314
317
|
);
|
|
315
318
|
try {
|
|
316
|
-
await waitForCondition(
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
319
|
+
await waitForCondition(
|
|
320
|
+
() => {
|
|
321
|
+
target = this.getTarget(appIdKey, pageIdKey);
|
|
322
|
+
return !_.isEmpty(target);
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
waitMs,
|
|
326
|
+
intervalMs: WAIT_FOR_TARGET_INTERVAL_MS,
|
|
327
|
+
},
|
|
328
|
+
);
|
|
323
329
|
return target;
|
|
324
330
|
} catch (err: any) {
|
|
325
331
|
if (!err.message.includes('Condition unmet')) {
|
|
326
332
|
throw err;
|
|
327
333
|
}
|
|
328
334
|
throw new Error(
|
|
329
|
-
`No targets could be matched for the app '${appIdKey}' and page '${pageIdKey}' after ${waitMs}ms
|
|
335
|
+
`No targets could be matched for the app '${appIdKey}' and page '${pageIdKey}' after ${waitMs}ms`,
|
|
330
336
|
);
|
|
331
337
|
}
|
|
332
338
|
}
|
|
@@ -341,19 +347,23 @@ export class RpcClient {
|
|
|
341
347
|
* @param waitForResponse - Whether to wait for a response. Defaults to true.
|
|
342
348
|
* @returns A promise that resolves to the command result or options.
|
|
343
349
|
*/
|
|
344
|
-
async send(
|
|
350
|
+
async send(
|
|
351
|
+
command: string,
|
|
352
|
+
opts: RemoteCommandOpts,
|
|
353
|
+
waitForResponse: boolean = true,
|
|
354
|
+
): Promise<any> {
|
|
345
355
|
const timer = new timing.Timer().start();
|
|
346
356
|
try {
|
|
347
357
|
return await this.sendToDevice(command, opts, waitForResponse);
|
|
348
358
|
} catch (err: any) {
|
|
349
|
-
const {
|
|
350
|
-
appIdKey,
|
|
351
|
-
pageIdKey
|
|
352
|
-
} = opts;
|
|
359
|
+
const {appIdKey, pageIdKey} = opts;
|
|
353
360
|
const messageLc = (err.message || '').toLowerCase();
|
|
354
361
|
if (messageLc.includes(NO_TARGET_SUPPORTED_ERROR)) {
|
|
355
362
|
return await this.sendToDevice(command, opts, waitForResponse);
|
|
356
|
-
} else if (
|
|
363
|
+
} else if (
|
|
364
|
+
appIdKey &&
|
|
365
|
+
NO_TARGET_PRESENT_YET_ERRORS.some((error) => messageLc.includes(error))
|
|
366
|
+
) {
|
|
357
367
|
await this.waitForTarget(appIdKey, pageIdKey as PageIdKey);
|
|
358
368
|
return await this.sendToDevice(command, opts, waitForResponse);
|
|
359
369
|
}
|
|
@@ -378,7 +388,7 @@ export class RpcClient {
|
|
|
378
388
|
async sendToDevice<TWaitForResponse extends boolean = true>(
|
|
379
389
|
command: string,
|
|
380
390
|
opts: RemoteCommandOpts,
|
|
381
|
-
waitForResponse: TWaitForResponse = true as TWaitForResponse
|
|
391
|
+
waitForResponse: TWaitForResponse = true as TWaitForResponse,
|
|
382
392
|
): Promise<TWaitForResponse extends true ? any : RemoteCommandOpts> {
|
|
383
393
|
return await new B<any>(async (resolve, reject) => {
|
|
384
394
|
// promise to be resolved whenever remote debugger
|
|
@@ -400,12 +410,15 @@ export class RpcClient {
|
|
|
400
410
|
const targetId = opts.targetId ?? this.getTarget(appIdKey, pageIdKey);
|
|
401
411
|
|
|
402
412
|
// retrieve the correct command to send
|
|
403
|
-
const fullOpts: RemoteCommandOpts & RemoteCommandId = _.defaults(
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
413
|
+
const fullOpts: RemoteCommandOpts & RemoteCommandId = _.defaults(
|
|
414
|
+
{
|
|
415
|
+
connId: this.connId,
|
|
416
|
+
senderId: this.senderId,
|
|
417
|
+
targetId,
|
|
418
|
+
id: msgId.toString(),
|
|
419
|
+
},
|
|
420
|
+
opts,
|
|
421
|
+
);
|
|
409
422
|
let cmd: RawRemoteCommand;
|
|
410
423
|
try {
|
|
411
424
|
cmd = this.remoteMessages.getRemoteCommand(command, fullOpts);
|
|
@@ -441,7 +454,7 @@ export class RpcClient {
|
|
|
441
454
|
// a protocol change. Log and check during testing
|
|
442
455
|
log.error(
|
|
443
456
|
`Received error from send that is not being waited for (id: ${msgId}): ` +
|
|
444
|
-
|
|
457
|
+
_.truncate(JSON.stringify(err), DATA_LOG_LENGTH),
|
|
445
458
|
);
|
|
446
459
|
// reject, though it is very rare that this will be triggered, since
|
|
447
460
|
// the promise is resolved directly after send. On the off chance,
|
|
@@ -450,19 +463,28 @@ export class RpcClient {
|
|
|
450
463
|
}
|
|
451
464
|
});
|
|
452
465
|
} else if (this.messageHandler.listenerCount(cmd.__selector)) {
|
|
453
|
-
this.messageHandler.prependOnceListener(
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
466
|
+
this.messageHandler.prependOnceListener(
|
|
467
|
+
cmd.__selector,
|
|
468
|
+
(err: Error | null, ...args: any[]) => {
|
|
469
|
+
if (err) {
|
|
470
|
+
return reject(err);
|
|
471
|
+
}
|
|
472
|
+
log.debug(
|
|
473
|
+
`Received response from send (id: ${msgId}): '${_.truncate(JSON.stringify(args), DATA_LOG_LENGTH)}'`,
|
|
474
|
+
);
|
|
475
|
+
resolve(args);
|
|
476
|
+
},
|
|
477
|
+
);
|
|
460
478
|
} else if (hasSocketData) {
|
|
461
479
|
this.messageHandler.once(msgId.toString(), (err: Error | null, value: any) => {
|
|
462
480
|
if (err) {
|
|
463
|
-
return reject(
|
|
481
|
+
return reject(
|
|
482
|
+
new Error(`Remote debugger error with code '${(err as any).code}': ${err.message}`),
|
|
483
|
+
);
|
|
464
484
|
}
|
|
465
|
-
log.debug(
|
|
485
|
+
log.debug(
|
|
486
|
+
`Received data response from send (id: ${msgId}): '${_.truncate(JSON.stringify(value), DATA_LOG_LENGTH)}'`,
|
|
487
|
+
);
|
|
466
488
|
resolve(value);
|
|
467
489
|
});
|
|
468
490
|
} else {
|
|
@@ -470,7 +492,8 @@ export class RpcClient {
|
|
|
470
492
|
messageHandled = false;
|
|
471
493
|
}
|
|
472
494
|
|
|
473
|
-
const msg =
|
|
495
|
+
const msg =
|
|
496
|
+
`Sending '${cmd.__selector}' message` +
|
|
474
497
|
(appIdKey ? ` to app '${appIdKey}'` : '') +
|
|
475
498
|
(pageIdKey ? `, page '${pageIdKey}'` : '') +
|
|
476
499
|
(targetId ? `, target '${targetId}'` : '') +
|
|
@@ -545,11 +568,7 @@ export class RpcClient {
|
|
|
545
568
|
if (!pendingPageTargetDetails) {
|
|
546
569
|
return;
|
|
547
570
|
}
|
|
548
|
-
const {
|
|
549
|
-
appIdKey,
|
|
550
|
-
pageIdKey,
|
|
551
|
-
pageReadinessDetector,
|
|
552
|
-
} = pendingPageTargetDetails;
|
|
571
|
+
const {appIdKey, pageIdKey, pageReadinessDetector} = pendingPageTargetDetails;
|
|
553
572
|
|
|
554
573
|
if (!_.isPlainObject(this.targets[appIdKey])) {
|
|
555
574
|
this.targets[appIdKey] = {
|
|
@@ -565,9 +584,7 @@ export class RpcClient {
|
|
|
565
584
|
|
|
566
585
|
const elapsedMs = timer.getDuration().asMilliSeconds;
|
|
567
586
|
if (elapsedMs >= pageReadinessDetector.timeoutMs) {
|
|
568
|
-
log.warn(
|
|
569
|
-
`Page '${pageIdKey}' took too long to initialize, skipping readiness check`
|
|
570
|
-
);
|
|
587
|
+
log.warn(`Page '${pageIdKey}' took too long to initialize, skipping readiness check`);
|
|
571
588
|
return;
|
|
572
589
|
}
|
|
573
590
|
return {
|
|
@@ -578,7 +595,7 @@ export class RpcClient {
|
|
|
578
595
|
|
|
579
596
|
if (targetInfo.isProvisional) {
|
|
580
597
|
log.debug(
|
|
581
|
-
`Provisional target created for app '${appIdKey}' and page '${pageIdKey}': '${JSON.stringify(targetInfo)}'
|
|
598
|
+
`Provisional target created for app '${appIdKey}' and page '${pageIdKey}': '${JSON.stringify(targetInfo)}'`,
|
|
582
599
|
);
|
|
583
600
|
|
|
584
601
|
this._provisionedPages.add(pageIdKey);
|
|
@@ -592,31 +609,36 @@ export class RpcClient {
|
|
|
592
609
|
await this._resumeTarget(appIdKey, pageIdKey, targetInfo.targetId);
|
|
593
610
|
} else {
|
|
594
611
|
log.debug(
|
|
595
|
-
`Provisional target ${targetInfo.targetId}@${appIdKey} is not paused, so not resuming
|
|
612
|
+
`Provisional target ${targetInfo.targetId}@${appIdKey} is not paused, so not resuming`,
|
|
596
613
|
);
|
|
597
614
|
}
|
|
598
615
|
}
|
|
599
616
|
if (wasInitialized) {
|
|
600
617
|
await this._waitForPageReadiness(
|
|
601
|
-
appIdKey,
|
|
618
|
+
appIdKey,
|
|
619
|
+
pageIdKey,
|
|
620
|
+
targetInfo.targetId,
|
|
621
|
+
adjustPageReadinessDetector(),
|
|
602
622
|
);
|
|
603
623
|
}
|
|
604
624
|
});
|
|
605
625
|
} catch (e: any) {
|
|
606
626
|
log.warn(
|
|
607
627
|
`Cannot complete the initialization of the provisional target '${targetInfo.targetId}' ` +
|
|
608
|
-
|
|
628
|
+
`after ${timer.getDuration().asMilliSeconds}ms: ${e.message}`,
|
|
609
629
|
);
|
|
610
630
|
}
|
|
611
631
|
return;
|
|
612
632
|
}
|
|
613
633
|
|
|
614
|
-
log.debug(
|
|
634
|
+
log.debug(
|
|
635
|
+
`Target created for app '${appIdKey}' and page '${pageIdKey}': ${JSON.stringify(targetInfo)}`,
|
|
636
|
+
);
|
|
615
637
|
if (_.has(this.targets[appIdKey], pageIdKey)) {
|
|
616
638
|
const existingTarget = this.targets[appIdKey][pageIdKey] as TargetId;
|
|
617
639
|
log.debug(
|
|
618
640
|
`There is already a target for this app and page ('${existingTarget}'). ` +
|
|
619
|
-
|
|
641
|
+
`This might cause problems`,
|
|
620
642
|
);
|
|
621
643
|
}
|
|
622
644
|
this.targets[appIdKey][pageIdKey] = targetInfo.targetId;
|
|
@@ -629,7 +651,7 @@ export class RpcClient {
|
|
|
629
651
|
});
|
|
630
652
|
} catch (e: any) {
|
|
631
653
|
log.debug(
|
|
632
|
-
`Cannot setup pause on start for app '${appIdKey}' and page '${pageIdKey}': ${e.message}
|
|
654
|
+
`Cannot setup pause on start for app '${appIdKey}' and page '${pageIdKey}': ${e.message}`,
|
|
633
655
|
);
|
|
634
656
|
}
|
|
635
657
|
|
|
@@ -650,7 +672,10 @@ export class RpcClient {
|
|
|
650
672
|
}
|
|
651
673
|
if (wasInitialized) {
|
|
652
674
|
await this._waitForPageReadiness(
|
|
653
|
-
appIdKey,
|
|
675
|
+
appIdKey,
|
|
676
|
+
pageIdKey,
|
|
677
|
+
targetInfo.targetId,
|
|
678
|
+
adjustPageReadinessDetector(),
|
|
654
679
|
);
|
|
655
680
|
}
|
|
656
681
|
});
|
|
@@ -671,12 +696,15 @@ export class RpcClient {
|
|
|
671
696
|
* @param app - The application identifier key.
|
|
672
697
|
* @param targetInfo - Information about the provisional target update.
|
|
673
698
|
*/
|
|
674
|
-
async updateTarget(
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
699
|
+
async updateTarget(
|
|
700
|
+
err: Error | undefined,
|
|
701
|
+
app: AppIdKey,
|
|
702
|
+
targetInfo: ProvisionalTargetInfo,
|
|
703
|
+
): Promise<void> {
|
|
704
|
+
const {oldTargetId, newTargetId} = targetInfo;
|
|
705
|
+
log.debug(
|
|
706
|
+
`Target updated for app '${app}'. Old target: '${oldTargetId}', new target: '${newTargetId}'`,
|
|
707
|
+
);
|
|
680
708
|
|
|
681
709
|
const appTargetsMap = this.targets[app];
|
|
682
710
|
if (!appTargetsMap) {
|
|
@@ -717,17 +745,17 @@ export class RpcClient {
|
|
|
717
745
|
if (targetId === oldTargetId) {
|
|
718
746
|
log.debug(
|
|
719
747
|
`Found provisional target for app '${app}'. ` +
|
|
720
|
-
|
|
748
|
+
`Old target: '${oldTargetId}', new target: '${newTargetId}'. Updating`,
|
|
721
749
|
);
|
|
722
750
|
appTargetsMap[page] = newTargetId;
|
|
723
751
|
return;
|
|
724
752
|
}
|
|
725
753
|
}
|
|
726
754
|
log.warn(
|
|
727
|
-
`Provisional target for app '${app}' found, but no suitable existing target found. This may cause problems
|
|
755
|
+
`Provisional target for app '${app}' found, but no suitable existing target found. This may cause problems`,
|
|
728
756
|
);
|
|
729
757
|
log.warn(
|
|
730
|
-
`Old target: '${oldTargetId}', new target: '${newTargetId}'. Existing targets: ${JSON.stringify(appTargetsMap)}
|
|
758
|
+
`Old target: '${oldTargetId}', new target: '${newTargetId}'. Existing targets: ${JSON.stringify(appTargetsMap)}`,
|
|
731
759
|
);
|
|
732
760
|
}
|
|
733
761
|
|
|
@@ -739,7 +767,9 @@ export class RpcClient {
|
|
|
739
767
|
return;
|
|
740
768
|
}
|
|
741
769
|
}
|
|
742
|
-
log.debug(
|
|
770
|
+
log.debug(
|
|
771
|
+
`Target '${targetInfo.targetId}' deleted for app '${app}', but no such target exists`,
|
|
772
|
+
);
|
|
743
773
|
}
|
|
744
774
|
|
|
745
775
|
/**
|
|
@@ -769,7 +799,7 @@ export class RpcClient {
|
|
|
769
799
|
async selectPage(
|
|
770
800
|
appIdKey: AppIdKey,
|
|
771
801
|
pageIdKey: PageIdKey,
|
|
772
|
-
pageReadinessDetector?: PageReadinessDetector
|
|
802
|
+
pageReadinessDetector?: PageReadinessDetector,
|
|
773
803
|
): Promise<void> {
|
|
774
804
|
await this._pageSelectionLock.acquire(toPageSelectionKey(appIdKey, pageIdKey), async () => {
|
|
775
805
|
this._pendingTargetNotification = {appIdKey, pageIdKey, pageReadinessDetector};
|
|
@@ -794,29 +824,35 @@ export class RpcClient {
|
|
|
794
824
|
const setupWebview = async () => {
|
|
795
825
|
// highlight and then un-highlight the webview
|
|
796
826
|
for (const enabled of [true, false]) {
|
|
797
|
-
await this.send(
|
|
798
|
-
|
|
799
|
-
|
|
827
|
+
await this.send(
|
|
828
|
+
'indicateWebView',
|
|
829
|
+
Object.assign(
|
|
830
|
+
{
|
|
831
|
+
enabled,
|
|
832
|
+
},
|
|
833
|
+
sendOpts,
|
|
834
|
+
),
|
|
835
|
+
false,
|
|
836
|
+
);
|
|
800
837
|
}
|
|
801
838
|
await this.send('setSenderKey', sendOpts);
|
|
802
839
|
};
|
|
803
|
-
await B.resolve(setupWebview())
|
|
804
|
-
|
|
840
|
+
await B.resolve(setupWebview()).timeout(
|
|
841
|
+
timeoutMs,
|
|
842
|
+
`Cannot set up page '${pageIdKey}' for app '${appIdKey}' within ${timeoutMs}ms`,
|
|
843
|
+
);
|
|
805
844
|
|
|
806
845
|
const msLeft = Math.max(timeoutMs - Math.trunc(timer.getDuration().asMilliSeconds), 1000);
|
|
807
846
|
log.debug(
|
|
808
|
-
`Waiting up to ${msLeft}ms for page '${pageIdKey}' of app '${appIdKey}' to be selected
|
|
847
|
+
`Waiting up to ${msLeft}ms for page '${pageIdKey}' of app '${appIdKey}' to be selected`,
|
|
809
848
|
);
|
|
810
849
|
await new Promise<void>((resolve) => {
|
|
811
|
-
const onPageInitialized = (
|
|
812
|
-
notifiedAppIdKey: AppIdKey,
|
|
813
|
-
notifiedPageIdKey: PageIdKey
|
|
814
|
-
) => {
|
|
850
|
+
const onPageInitialized = (notifiedAppIdKey: AppIdKey, notifiedPageIdKey: PageIdKey) => {
|
|
815
851
|
const timeoutHandler = setTimeout(() => {
|
|
816
852
|
this._pageSelectionMonitor.off(ON_PAGE_INITIALIZED_EVENT, onPageInitialized);
|
|
817
853
|
log.warn(
|
|
818
854
|
`Page '${pageIdKey}' for app '${appIdKey}' has not been selected ` +
|
|
819
|
-
|
|
855
|
+
`within ${timer.getDuration().asMilliSeconds}ms. Continuing anyway`,
|
|
820
856
|
);
|
|
821
857
|
resolve();
|
|
822
858
|
}, msLeft);
|
|
@@ -825,13 +861,13 @@ export class RpcClient {
|
|
|
825
861
|
clearTimeout(timeoutHandler);
|
|
826
862
|
this._pageSelectionMonitor.off(ON_PAGE_INITIALIZED_EVENT, onPageInitialized);
|
|
827
863
|
log.debug(
|
|
828
|
-
`Selected the page ${pageIdKey}@${appIdKey} after ${timer.getDuration().asMilliSeconds}ms
|
|
864
|
+
`Selected the page ${pageIdKey}@${appIdKey} after ${timer.getDuration().asMilliSeconds}ms`,
|
|
829
865
|
);
|
|
830
866
|
resolve();
|
|
831
867
|
} else {
|
|
832
868
|
log.debug(
|
|
833
869
|
`Got notified that page ${notifiedPageIdKey}@${notifiedAppIdKey} is initialized, ` +
|
|
834
|
-
|
|
870
|
+
`but we are waiting for ${pageIdKey}@${appIdKey}. Continuing to wait`,
|
|
835
871
|
);
|
|
836
872
|
}
|
|
837
873
|
};
|
|
@@ -855,7 +891,7 @@ export class RpcClient {
|
|
|
855
891
|
private async _initializePage(
|
|
856
892
|
appIdKey: AppIdKey,
|
|
857
893
|
pageIdKey: PageIdKey,
|
|
858
|
-
targetId?: TargetId
|
|
894
|
+
targetId?: TargetId,
|
|
859
895
|
): Promise<boolean> {
|
|
860
896
|
const sendOpts: RemoteCommandOpts = {
|
|
861
897
|
appIdKey,
|
|
@@ -890,7 +926,7 @@ export class RpcClient {
|
|
|
890
926
|
}
|
|
891
927
|
log.debug(
|
|
892
928
|
`Simple initialization of page '${pageIdKey}' for app '${appIdKey}' completed ` +
|
|
893
|
-
|
|
929
|
+
`in ${timer.getDuration().asMilliSeconds}ms`,
|
|
894
930
|
);
|
|
895
931
|
return true;
|
|
896
932
|
}
|
|
@@ -958,12 +994,18 @@ export class RpcClient {
|
|
|
958
994
|
try {
|
|
959
995
|
const res = await this.send(domain, opts);
|
|
960
996
|
if (domain === 'Console.getLoggingChannels') {
|
|
961
|
-
for (const source of (res?.channels || []).map((entry: {
|
|
997
|
+
for (const source of (res?.channels || []).map((entry: {source: any}) => entry.source)) {
|
|
962
998
|
try {
|
|
963
|
-
await this.send(
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
999
|
+
await this.send(
|
|
1000
|
+
'Console.setLoggingChannelLevel',
|
|
1001
|
+
Object.assign(
|
|
1002
|
+
{
|
|
1003
|
+
source,
|
|
1004
|
+
level: 'verbose',
|
|
1005
|
+
},
|
|
1006
|
+
sendOpts,
|
|
1007
|
+
),
|
|
1008
|
+
);
|
|
967
1009
|
} catch (err: any) {
|
|
968
1010
|
log.info(`Cannot set logging channel level for '${source}': ${err.message}`);
|
|
969
1011
|
if (MISSING_TARGET_ERROR_PATTERN.test(err.message)) {
|
|
@@ -981,7 +1023,7 @@ export class RpcClient {
|
|
|
981
1023
|
}
|
|
982
1024
|
log.debug(
|
|
983
1025
|
`Full initialization of page '${pageIdKey}' for app '${appIdKey}' completed ` +
|
|
984
|
-
|
|
1026
|
+
`in ${timer.getDuration().asMilliSeconds}ms`,
|
|
985
1027
|
);
|
|
986
1028
|
return true;
|
|
987
1029
|
}
|
|
@@ -1011,8 +1053,10 @@ export class RpcClient {
|
|
|
1011
1053
|
// if this is a report of a proxy redirect from the remote debugger
|
|
1012
1054
|
// we want to update our dictionary and get a new app id
|
|
1013
1055
|
if (oldAppIdKey && correctAppIdKey !== oldAppIdKey) {
|
|
1014
|
-
log.debug(
|
|
1015
|
-
|
|
1056
|
+
log.debug(
|
|
1057
|
+
`We were notified we might have connected to the wrong app. ` +
|
|
1058
|
+
`Using id ${correctAppIdKey} instead of ${oldAppIdKey}`,
|
|
1059
|
+
);
|
|
1016
1060
|
}
|
|
1017
1061
|
|
|
1018
1062
|
reject(new Error(NEW_APP_CONNECTED_ERROR));
|
|
@@ -1046,7 +1090,7 @@ export class RpcClient {
|
|
|
1046
1090
|
* @param err - Error if one occurred, undefined otherwise.
|
|
1047
1091
|
* @param context - The execution context information.
|
|
1048
1092
|
*/
|
|
1049
|
-
onExecutionContextCreated(err: Error | undefined, context: {
|
|
1093
|
+
onExecutionContextCreated(err: Error | undefined, context: {id: number}): void {
|
|
1050
1094
|
// { id: 2, isPageContext: true, name: '', frameId: '0.1' }
|
|
1051
1095
|
// right now we have no way to map contexts to apps/pages
|
|
1052
1096
|
// so just store
|
|
@@ -1080,7 +1124,11 @@ export class RpcClient {
|
|
|
1080
1124
|
* @param pageIdKey - The page identifier key.
|
|
1081
1125
|
* @param targetId - The target ID to resume.
|
|
1082
1126
|
*/
|
|
1083
|
-
private async _resumeTarget(
|
|
1127
|
+
private async _resumeTarget(
|
|
1128
|
+
appIdKey: AppIdKey,
|
|
1129
|
+
pageIdKey: PageIdKey,
|
|
1130
|
+
targetId: TargetId,
|
|
1131
|
+
): Promise<void> {
|
|
1084
1132
|
try {
|
|
1085
1133
|
await this.send('Target.resume', {
|
|
1086
1134
|
appIdKey,
|
|
@@ -1106,7 +1154,7 @@ export class RpcClient {
|
|
|
1106
1154
|
appIdKey: AppIdKey,
|
|
1107
1155
|
pageIdKey: PageIdKey,
|
|
1108
1156
|
targetId: TargetId,
|
|
1109
|
-
pageReadinessDetector?: PageReadinessDetector
|
|
1157
|
+
pageReadinessDetector?: PageReadinessDetector,
|
|
1110
1158
|
): Promise<void> {
|
|
1111
1159
|
if (!pageReadinessDetector) {
|
|
1112
1160
|
return;
|
|
@@ -1119,15 +1167,17 @@ export class RpcClient {
|
|
|
1119
1167
|
try {
|
|
1120
1168
|
const commandTimeoutMs = Math.max(
|
|
1121
1169
|
100,
|
|
1122
|
-
Math.trunc((pageReadinessDetector.timeoutMs - timer.getDuration().asMilliSeconds) * 0.8)
|
|
1170
|
+
Math.trunc((pageReadinessDetector.timeoutMs - timer.getDuration().asMilliSeconds) * 0.8),
|
|
1123
1171
|
);
|
|
1124
|
-
const rawResult = await B.resolve(
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1172
|
+
const rawResult = await B.resolve(
|
|
1173
|
+
this.send('Runtime.evaluate', {
|
|
1174
|
+
expression: 'document.readyState;',
|
|
1175
|
+
returnByValue: true,
|
|
1176
|
+
appIdKey,
|
|
1177
|
+
pageIdKey,
|
|
1178
|
+
targetId,
|
|
1179
|
+
}),
|
|
1180
|
+
).timeout(commandTimeoutMs);
|
|
1131
1181
|
readyState = convertJavascriptEvaluationResult(rawResult);
|
|
1132
1182
|
} catch (e: any) {
|
|
1133
1183
|
log.debug(`Cannot determine page readiness: ${e.message}`);
|
|
@@ -1136,7 +1186,7 @@ export class RpcClient {
|
|
|
1136
1186
|
if (pageReadinessDetector.readinessDetector(readyState)) {
|
|
1137
1187
|
log.info(
|
|
1138
1188
|
`Page '${pageIdKey}' for app '${appIdKey}' is ready after ` +
|
|
1139
|
-
|
|
1189
|
+
`${timer.getDuration().asMilliSeconds}ms`,
|
|
1140
1190
|
);
|
|
1141
1191
|
return;
|
|
1142
1192
|
}
|
|
@@ -1144,7 +1194,7 @@ export class RpcClient {
|
|
|
1144
1194
|
}
|
|
1145
1195
|
log.warn(
|
|
1146
1196
|
`Page '${pageIdKey}' for app '${appIdKey}' is not ready after ` +
|
|
1147
|
-
|
|
1197
|
+
`${timer.getDuration().asMilliSeconds}ms. Continuing anyway`,
|
|
1148
1198
|
);
|
|
1149
1199
|
}
|
|
1150
1200
|
|
|
@@ -1165,7 +1215,10 @@ export class RpcClient {
|
|
|
1165
1215
|
const timer = new timing.Timer().start();
|
|
1166
1216
|
await Promise.all([
|
|
1167
1217
|
lock.acquire(pageIdKey, async () => await B.delay(0)),
|
|
1168
|
-
this._pageSelectionLock.acquire(
|
|
1218
|
+
this._pageSelectionLock.acquire(
|
|
1219
|
+
toPageSelectionKey(appIdKey, pageIdKey),
|
|
1220
|
+
async () => await B.delay(0),
|
|
1221
|
+
),
|
|
1169
1222
|
]);
|
|
1170
1223
|
const durationMs = timer.getDuration().asMilliSeconds;
|
|
1171
1224
|
if (durationMs > 10) {
|
|
@@ -1183,11 +1236,11 @@ export class RpcClient {
|
|
|
1183
1236
|
*/
|
|
1184
1237
|
private _getPendingPageTargetDetails(
|
|
1185
1238
|
appId: AppIdKey,
|
|
1186
|
-
targetInfo: TargetInfo
|
|
1239
|
+
targetInfo: TargetInfo,
|
|
1187
1240
|
): PendingPageTargetDetails | undefined {
|
|
1188
1241
|
const logInfo = (message: string): undefined =>
|
|
1189
1242
|
void log.info(
|
|
1190
|
-
`Skipping 'Target.targetCreated' event ${message} for app '${appId}': ${JSON.stringify(targetInfo)}
|
|
1243
|
+
`Skipping 'Target.targetCreated' event ${message} for app '${appId}': ${JSON.stringify(targetInfo)}`,
|
|
1191
1244
|
);
|
|
1192
1245
|
if (!this._pendingTargetNotification) {
|
|
1193
1246
|
return logInfo('with no pending request');
|