@@ -25,8 +25,6 @@ import { Page } from './page';
2525import * as platform from './platform' ;
2626import { Selectors } from './selectors' ;
2727
28- export type WaitForInteractableOptions = types . TimeoutOptions & { waitForInteractable ?: boolean } ;
29-
3028export class FrameExecutionContext extends js . ExecutionContext {
3129 readonly frame : frames . Frame ;
3230
@@ -232,15 +230,10 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
232230 return point ;
233231 }
234232
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 > {
239234 const relativePoint = options ? options . relativePoint : undefined ;
240235 await this . _scrollRectIntoViewIfNeeded ( relativePoint ? { x : relativePoint . x , y : relativePoint . y , width : 0 , height : 0 } : undefined ) ;
241236 const point = relativePoint ? await this . _relativePoint ( relativePoint ) : await this . _clickablePoint ( ) ;
242- if ( waitForInteractable )
243- await this . _waitForHitTargetAt ( point , options ) ;
244237 let restoreModifiers : input . Modifier [ ] | undefined ;
245238 if ( options && options . modifiers )
246239 restoreModifiers = await this . _page . keyboard . _ensureModifiers ( options . modifiers ) ;
@@ -249,19 +242,19 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
249242 await this . _page . keyboard . _ensureModifiers ( restoreModifiers ) ;
250243 }
251244
252- hover ( options ?: input . PointerActionOptions & WaitForInteractableOptions ) : Promise < void > {
245+ hover ( options ?: input . PointerActionOptions ) : Promise < void > {
253246 return this . _performPointerAction ( point => this . _page . mouse . move ( point . x , point . y ) , options ) ;
254247 }
255248
256- click ( options ?: input . ClickOptions & WaitForInteractableOptions ) : Promise < void > {
249+ click ( options ?: input . ClickOptions ) : Promise < void > {
257250 return this . _performPointerAction ( point => this . _page . mouse . click ( point . x , point . y , options ) , options ) ;
258251 }
259252
260- dblclick ( options ?: input . MultiClickOptions & WaitForInteractableOptions ) : Promise < void > {
253+ dblclick ( options ?: input . MultiClickOptions ) : Promise < void > {
261254 return this . _performPointerAction ( point => this . _page . mouse . dblclick ( point . x , point . y , options ) , options ) ;
262255 }
263256
264- tripleclick ( options ?: input . MultiClickOptions & WaitForInteractableOptions ) : Promise < void > {
257+ tripleclick ( options ?: input . MultiClickOptions ) : Promise < void > {
265258 return this . _performPointerAction ( point => this . _page . mouse . tripleclick ( point . x , point . y , options ) , options ) ;
266259 }
267260
@@ -409,20 +402,19 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
409402 await this . _page . keyboard . type ( text , options ) ;
410403 }
411404
412- async press ( key : string , options ? : { delay ?: number , text ?: string } ) {
405+ async press ( key : string , options : { delay ?: number ; text ?: string ; } | undefined ) {
413406 await this . focus ( ) ;
414407 await this . _page . keyboard . press ( key , options ) ;
415408 }
416-
417- async check ( options ?: WaitForInteractableOptions ) {
418- await this . _setChecked ( true , options ) ;
409+ async check ( ) {
410+ await this . _setChecked ( true ) ;
419411 }
420412
421- async uncheck ( options ?: WaitForInteractableOptions ) {
422- await this . _setChecked ( false , options ) ;
413+ async uncheck ( ) {
414+ await this . _setChecked ( false ) ;
423415 }
424416
425- private async _setChecked ( state : boolean , options : WaitForInteractableOptions = { } ) {
417+ private async _setChecked ( state : boolean ) {
426418 const isCheckboxChecked = async ( ) : Promise < boolean > => {
427419 return this . _evaluateInUtility ( ( node : Node ) => {
428420 if ( node . nodeType !== Node . ELEMENT_NODE )
@@ -450,7 +442,7 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
450442
451443 if ( await isCheckboxChecked ( ) === state )
452444 return ;
453- await this . click ( options ) ;
445+ await this . click ( ) ;
454446 if ( await isCheckboxChecked ( ) !== state )
455447 throw new Error ( 'Unable to click checkbox' ) ;
456448 }
@@ -505,52 +497,6 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
505497 return visibleRatio ;
506498 } ) ;
507499 }
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- }
554500}
555501
556502function normalizeSelector ( selector : string ) : string {
@@ -568,44 +514,51 @@ function normalizeSelector(selector: string): string {
568514
569515export type Task = ( context : FrameExecutionContext ) => Promise < js . JSHandle > ;
570516
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 ;
572519 if ( helper . isString ( polling ) )
573520 assert ( polling === 'raf' || polling === 'mutation' , 'Unknown polling option: ' + polling ) ;
574521 else if ( helper . isNumber ( polling ) )
575522 assert ( polling > 0 , 'Cannot poll with non-positive interval: ' + polling ) ;
576523 else
577524 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 ) ;
583525 const predicateBody = helper . isString ( pageFunction ) ? 'return (' + pageFunction + ')' : 'return (' + pageFunction + ')(...args)' ;
584526 if ( selector !== undefined )
585527 selector = normalizeSelector ( selector ) ;
586528
587529 return async ( context : FrameExecutionContext ) => context . evaluateHandle ( ( injected : Injected , selector : string | undefined , predicateBody : string , polling : types . Polling , timeout : number , ...args ) => {
588530 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 {
590538 if ( selector === undefined )
591539 return innerPredicate ( ...args ) ;
592540 return innerPredicate ( element , ...args ) ;
593- } ) ;
541+ }
594542 } , await context . _injected ( ) , selector , predicateBody , polling , options . timeout || 0 , ...args ) ;
595543}
596544
597545export 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+ } ;
609562}
610563
611564export const setFileInputFunction = async ( element : HTMLInputElement , payloads : types . FilePayload [ ] ) => {
0 commit comments