@@ -25,8 +25,6 @@ import { Page } from './page';
25
25
import * as platform from './platform' ;
26
26
import { Selectors } from './selectors' ;
27
27
28
- export type WaitForInteractableOptions = types . TimeoutOptions & { waitForInteractable ?: boolean } ;
29
-
30
28
export class FrameExecutionContext extends js . ExecutionContext {
31
29
readonly frame : frames . Frame ;
32
30
@@ -232,15 +230,10 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
232
230
return point ;
233
231
}
234
232
235
- async _performPointerAction ( action : ( point : types . Point ) => Promise < void > , options ?: input . PointerActionOptions & WaitForInteractableOptions ) : Promise < void > {
236
- const { waitForInteractable = true } = ( options || { } ) ;
237
- if ( waitForInteractable )
238
- await this . _waitForStablePosition ( options ) ;
233
+ async _performPointerAction ( action : ( point : types . Point ) => Promise < void > , options ?: input . PointerActionOptions ) : Promise < void > {
239
234
const relativePoint = options ? options . relativePoint : undefined ;
240
235
await this . _scrollRectIntoViewIfNeeded ( relativePoint ? { x : relativePoint . x , y : relativePoint . y , width : 0 , height : 0 } : undefined ) ;
241
236
const point = relativePoint ? await this . _relativePoint ( relativePoint ) : await this . _clickablePoint ( ) ;
242
- if ( waitForInteractable )
243
- await this . _waitForHitTargetAt ( point , options ) ;
244
237
let restoreModifiers : input . Modifier [ ] | undefined ;
245
238
if ( options && options . modifiers )
246
239
restoreModifiers = await this . _page . keyboard . _ensureModifiers ( options . modifiers ) ;
@@ -249,19 +242,19 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
249
242
await this . _page . keyboard . _ensureModifiers ( restoreModifiers ) ;
250
243
}
251
244
252
- hover ( options ?: input . PointerActionOptions & WaitForInteractableOptions ) : Promise < void > {
245
+ hover ( options ?: input . PointerActionOptions ) : Promise < void > {
253
246
return this . _performPointerAction ( point => this . _page . mouse . move ( point . x , point . y ) , options ) ;
254
247
}
255
248
256
- click ( options ?: input . ClickOptions & WaitForInteractableOptions ) : Promise < void > {
249
+ click ( options ?: input . ClickOptions ) : Promise < void > {
257
250
return this . _performPointerAction ( point => this . _page . mouse . click ( point . x , point . y , options ) , options ) ;
258
251
}
259
252
260
- dblclick ( options ?: input . MultiClickOptions & WaitForInteractableOptions ) : Promise < void > {
253
+ dblclick ( options ?: input . MultiClickOptions ) : Promise < void > {
261
254
return this . _performPointerAction ( point => this . _page . mouse . dblclick ( point . x , point . y , options ) , options ) ;
262
255
}
263
256
264
- tripleclick ( options ?: input . MultiClickOptions & WaitForInteractableOptions ) : Promise < void > {
257
+ tripleclick ( options ?: input . MultiClickOptions ) : Promise < void > {
265
258
return this . _performPointerAction ( point => this . _page . mouse . tripleclick ( point . x , point . y , options ) , options ) ;
266
259
}
267
260
@@ -409,20 +402,19 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
409
402
await this . _page . keyboard . type ( text , options ) ;
410
403
}
411
404
412
- async press ( key : string , options ? : { delay ?: number , text ?: string } ) {
405
+ async press ( key : string , options : { delay ?: number ; text ?: string ; } | undefined ) {
413
406
await this . focus ( ) ;
414
407
await this . _page . keyboard . press ( key , options ) ;
415
408
}
416
-
417
- async check ( options ?: WaitForInteractableOptions ) {
418
- await this . _setChecked ( true , options ) ;
409
+ async check ( ) {
410
+ await this . _setChecked ( true ) ;
419
411
}
420
412
421
- async uncheck ( options ?: WaitForInteractableOptions ) {
422
- await this . _setChecked ( false , options ) ;
413
+ async uncheck ( ) {
414
+ await this . _setChecked ( false ) ;
423
415
}
424
416
425
- private async _setChecked ( state : boolean , options : WaitForInteractableOptions = { } ) {
417
+ private async _setChecked ( state : boolean ) {
426
418
const isCheckboxChecked = async ( ) : Promise < boolean > => {
427
419
return this . _evaluateInUtility ( ( node : Node ) => {
428
420
if ( node . nodeType !== Node . ELEMENT_NODE )
@@ -450,7 +442,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
450
442
451
443
if ( await isCheckboxChecked ( ) === state )
452
444
return ;
453
- await this . click ( options ) ;
445
+ await this . click ( ) ;
454
446
if ( await isCheckboxChecked ( ) !== state )
455
447
throw new Error ( 'Unable to click checkbox' ) ;
456
448
}
@@ -505,52 +497,6 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
505
497
return visibleRatio ;
506
498
} ) ;
507
499
}
508
-
509
- async _waitForStablePosition ( options : types . TimeoutOptions = { } ) : Promise < void > {
510
- const context = await this . _context . frame . _utilityContext ( ) ;
511
- const stablePromise = context . evaluate ( ( injected : Injected , node : Node , timeout : number ) => {
512
- if ( ! node . isConnected )
513
- throw new Error ( 'Element is not attached to the DOM' ) ;
514
- const element = node . nodeType === Node . ELEMENT_NODE ? ( node as Element ) : node . parentElement ;
515
- if ( ! element )
516
- throw new Error ( 'Element is not attached to the DOM' ) ;
517
-
518
- let lastRect : types . Rect | undefined ;
519
- return injected . poll ( 'raf' , undefined , timeout , ( ) => {
520
- const clientRect = element . getBoundingClientRect ( ) ;
521
- const rect = { x : clientRect . top , y : clientRect . left , width : clientRect . width , height : clientRect . height } ;
522
- const isStable = lastRect && rect . x === lastRect . x && rect . y === lastRect . y && rect . width === lastRect . width && rect . height === lastRect . height ;
523
- lastRect = rect ;
524
- return isStable ;
525
- } ) ;
526
- } , await context . _injected ( ) , this , options . timeout || 0 ) ;
527
- await helper . waitWithTimeout ( stablePromise , 'element to stop moving' , options . timeout || 0 ) ;
528
- }
529
-
530
- async _waitForHitTargetAt ( point : types . Point , options : types . TimeoutOptions = { } ) : Promise < void > {
531
- const frame = await this . ownerFrame ( ) ;
532
- if ( frame && frame . parentFrame ( ) ) {
533
- const element = await frame . frameElement ( ) ;
534
- const box = await element . boundingBox ( ) ;
535
- if ( ! box )
536
- throw new Error ( 'Element is not attached to the DOM' ) ;
537
- // Translate from viewport coordinates to frame coordinates.
538
- point = { x : point . x - box . x , y : point . y - box . y } ;
539
- }
540
- const context = await this . _context . frame . _utilityContext ( ) ;
541
- const hitTargetPromise = context . evaluate ( ( injected : Injected , node : Node , timeout : number , point : types . Point ) => {
542
- const element = node . nodeType === Node . ELEMENT_NODE ? ( node as Element ) : node . parentElement ;
543
- if ( ! element )
544
- throw new Error ( 'Element is not attached to the DOM' ) ;
545
- return injected . poll ( 'raf' , undefined , timeout , ( ) => {
546
- let hitElement = injected . utils . deepElementFromPoint ( document , point . x , point . y ) ;
547
- while ( hitElement && hitElement !== element )
548
- hitElement = injected . utils . parentElementOrShadowHost ( hitElement ) ;
549
- return hitElement === element ;
550
- } ) ;
551
- } , await context . _injected ( ) , this , options . timeout || 0 , point ) ;
552
- await helper . waitWithTimeout ( hitTargetPromise , 'element to receive mouse events' , options . timeout || 0 ) ;
553
- }
554
500
}
555
501
556
502
function normalizeSelector ( selector : string ) : string {
@@ -568,44 +514,51 @@ function normalizeSelector(selector: string): string {
568
514
569
515
export type Task = ( context : FrameExecutionContext ) => Promise < js . JSHandle > ;
570
516
571
- function assertPolling ( polling : types . Polling ) {
517
+ export function waitForFunctionTask ( selector : string | undefined , pageFunction : Function | string , options : types . WaitForFunctionOptions , ...args : any [ ] ) {
518
+ const { polling = 'raf' } = options ;
572
519
if ( helper . isString ( polling ) )
573
520
assert ( polling === 'raf' || polling === 'mutation' , 'Unknown polling option: ' + polling ) ;
574
521
else if ( helper . isNumber ( polling ) )
575
522
assert ( polling > 0 , 'Cannot poll with non-positive interval: ' + polling ) ;
576
523
else
577
524
throw new Error ( 'Unknown polling options: ' + polling ) ;
578
- }
579
-
580
- export function waitForFunctionTask ( selector : string | undefined , pageFunction : Function | string , options : types . WaitForFunctionOptions , ...args : any [ ] ) : Task {
581
- const { polling = 'raf' } = options ;
582
- assertPolling ( polling ) ;
583
525
const predicateBody = helper . isString ( pageFunction ) ? 'return (' + pageFunction + ')' : 'return (' + pageFunction + ')(...args)' ;
584
526
if ( selector !== undefined )
585
527
selector = normalizeSelector ( selector ) ;
586
528
587
529
return async ( context : FrameExecutionContext ) => context . evaluateHandle ( ( injected : Injected , selector : string | undefined , predicateBody : string , polling : types . Polling , timeout : number , ...args ) => {
588
530
const innerPredicate = new Function ( '...args' , predicateBody ) ;
589
- return injected . poll ( polling , selector , timeout , ( element : Element | undefined ) : any => {
531
+ if ( polling === 'raf' )
532
+ return injected . pollRaf ( selector , predicate , timeout ) ;
533
+ if ( polling === 'mutation' )
534
+ return injected . pollMutation ( selector , predicate , timeout ) ;
535
+ return injected . pollInterval ( selector , polling , predicate , timeout ) ;
536
+
537
+ function predicate ( element : Element | undefined ) : any {
590
538
if ( selector === undefined )
591
539
return innerPredicate ( ...args ) ;
592
540
return innerPredicate ( element , ...args ) ;
593
- } ) ;
541
+ }
594
542
} , await context . _injected ( ) , selector , predicateBody , polling , options . timeout || 0 , ...args ) ;
595
543
}
596
544
597
545
export function waitForSelectorTask ( selector : string , visibility : types . Visibility , timeout : number ) : Task {
598
- selector = normalizeSelector ( selector ) ;
599
- return async ( context : FrameExecutionContext ) => context . evaluateHandle ( ( injected : Injected , selector : string , visibility : types . Visibility , timeout : number ) => {
600
- const polling = visibility === 'any' ? 'mutation' : 'raf' ;
601
- return injected . poll ( polling , selector , timeout , ( element : Element | undefined ) : Element | boolean => {
602
- if ( ! element )
603
- return visibility === 'hidden' ;
604
- if ( visibility === 'any' )
605
- return element ;
606
- return injected . isVisible ( element ) === ( visibility === 'visible' ) ? element : false ;
607
- } ) ;
608
- } , await context . _injected ( ) , selector , visibility , timeout ) ;
546
+ return async ( context : FrameExecutionContext ) => {
547
+ selector = normalizeSelector ( selector ) ;
548
+ return context . evaluateHandle ( ( injected : Injected , selector : string , visibility : types . Visibility , timeout : number ) => {
549
+ if ( visibility !== 'any' )
550
+ return injected . pollRaf ( selector , predicate , timeout ) ;
551
+ return injected . pollMutation ( selector , predicate , timeout ) ;
552
+
553
+ function predicate ( element : Element | undefined ) : Element | boolean {
554
+ if ( ! element )
555
+ return visibility === 'hidden' ;
556
+ if ( visibility === 'any' )
557
+ return element ;
558
+ return injected . isVisible ( element ) === ( visibility === 'visible' ) ? element : false ;
559
+ }
560
+ } , await context . _injected ( ) , selector , visibility , timeout ) ;
561
+ } ;
609
562
}
610
563
611
564
export const setFileInputFunction = async ( element : HTMLInputElement , payloads : types . FilePayload [ ] ) => {
0 commit comments