import { ElementHandle } from './ElementHandle' ; import { Page , Frame } from 'playwright' ; import { TargetLocator as ITargetLocator , ElementHandle as IElementHandle } from './types' ; import { getFrames } from '../utils/frames' ; internal export class TargetLocator implements ITargetLocator { constructor ( private currentPage , private currentFrame , private applyFrame , private applyPage ) { } public async activeElement ( ) { const jsHandle = await this . currentPage . evaluateHandle ( ( ) => document . activeElement || document . body ) ; if ( ! jsHandle ) return null ; const element = jsHandle . asElement ( ) ; if ( ! element ) return null ; return new ElementHandle ( element , this . currentPage , this . currentFrame ) . initErrorString ( ) ; } private async findFrameFromWindow ( id ) { const frames = getFrames ( this . currentPage . frames ( ) ) ; const frameElementName = await this . currentPage . evaluate ( ( id ) => { const frame = Array . from ( window . frames ) . find ( ( frame ) => frame ?. frameElement ?. id === id ) ; if ( ! frame ) throw Error ( `No frame found with id=${ id }` ) ; return frame . name ; } , id ) ; return frames . find ( ( frame ) => frame . name ( ) === frameElementName ) ; } /**
     * Navigates to the topmost frame
     */ public async defaultContent ( ) { this . applyFrame ( null ) ; } param id public async frame ( id ) { if ( id === null ) { this . defaultContent ( ) ; return ; } let nextFrame ; const frames = getFrames ( this . currentPage . frames ( ) ) ; if ( typeof id === 'number' ) { const frameElementName = await this . currentPage . evaluate ( ( index ) => { const frame = ( window as any ) . frames [ Number ( index ) ] ; if ( ! frame ) throw Error ( `No frame found at index: ${ index }` ) ; return frame . name || frame . id ; } , id ) ; nextFrame = frames . find ( ( frame ) => frame . name ( ) === frameElementName ) ; if ( ! nextFrame ) throw new Error ( `Could not match frame by name or id: '${ frameElementName }'` ) ; this . applyFrame ( nextFrame ) ; } else if ( typeof id === 'string' ) { nextFrame = frames . find ( ( frame ) => frame . name ( ) === id ) ; if ( ! nextFrame ) { nextFrame = await this . findFrameFromWindow ( id ) ; } if ( ! nextFrame ) throw new Error ( `Could not match frame by name or id: '${ id }'` ) ; this . applyFrame ( nextFrame ) ; } else if ( id instanceof ElementHandle ) { const tagName = await id . tagName ( ) ; if ( ! tagName || ! [ 'FRAME' , 'WINDOW' , 'IFRAME' ] . includes ( tagName ) ) throw new Error ( `ElementHandle supplied to frame() must be a reference to a <frame>, window, or <iframe> element, got <${ ( tagName && tagName . toLowerCase ( ) ) || null }>` ) ; let name = await id . getProperty ( 'name' ) ; if ( ! name ) name = await id . getProperty ( 'id' ) ; nextFrame = frames . find ( ( frame ) => frame . name ( ) === name ) ; if ( ! nextFrame ) { nextFrame = await this . findFrameFromWindow ( name ) ; } if ( ! nextFrame ) throw new Error ( `Could not match frame by name or id: '${ name }'` ) ; this . applyFrame ( nextFrame ) ; } } param page public async page ( page ) { await this . applyPage ( page ) ; } }