1
1
import { readFileSync } from 'fs'
2
2
import * as path from 'path'
3
- import { ElementHandle , EvaluateFn , JSHandle , Page } from 'puppeteer'
3
+ import { ElementHandle , Frame , JSHandle , Page } from 'puppeteer'
4
4
import waitForExpect from 'wait-for-expect'
5
5
6
6
import { IConfigureOptions , IQueryUtils , IScopedQueryUtils } from './typedefs'
@@ -43,6 +43,17 @@ function convertRegExpToProxy(o: any, depth: number): any {
43
43
return { __regex : o . source , __flags : o . flags }
44
44
}
45
45
46
+ function getExecutionContextFromHandle (
47
+ elementHandle : ElementHandle ,
48
+ ) : Pick < Frame , 'evaluate' | 'evaluateHandle' > {
49
+ if ( ! elementHandle . frame ) {
50
+ // @ts -ignore - Support versions of puppeteer before v17.
51
+ return elementHandle . executionContext ( )
52
+ }
53
+
54
+ return elementHandle . frame
55
+ }
56
+
46
57
const delegateFnBodyToExecuteInPageInitial = `
47
58
${ domLibraryAsString } ;
48
59
${ convertProxyToRegExp . toString ( ) } ;
@@ -56,16 +67,16 @@ const delegateFnBodyToExecuteInPageInitial = `
56
67
57
68
let delegateFnBodyToExecuteInPage = delegateFnBodyToExecuteInPageInitial
58
69
59
- type DOMReturnType = ElementHandle | ElementHandle [ ] | null
70
+ type DOMReturnType = ElementHandle < Node > | Array < ElementHandle < Node > > | null
60
71
61
72
type ContextFn = ( ...args : any [ ] ) => ElementHandle
62
73
63
- async function createElementHandleArray ( handle : JSHandle ) : Promise < ElementHandle [ ] > {
74
+ async function createElementHandleArray ( handle : JSHandle ) : Promise < Array < ElementHandle < Node > > > {
64
75
const lengthHandle = await handle . getProperty ( 'length' )
65
76
if ( ! lengthHandle ) throw new Error ( `Failed to assess length property` )
66
77
const length = ( await lengthHandle . jsonValue ( ) ) as number
67
78
68
- const elements : ElementHandle [ ] = [ ]
79
+ const elements : Array < ElementHandle < Node > > = [ ]
69
80
for ( let i = 0 ; i < length ; i ++ ) {
70
81
const jsElement = await handle . getProperty ( i . toString ( ) )
71
82
if ( ! jsElement ) throw new Error ( `Failed to assess ${ i . toString ( ) } property` )
@@ -76,7 +87,7 @@ async function createElementHandleArray(handle: JSHandle): Promise<ElementHandle
76
87
return elements
77
88
}
78
89
79
- async function createElementHandle ( handle : JSHandle ) : Promise < ElementHandle | null > {
90
+ async function createElementHandle ( handle : JSHandle ) : Promise < ElementHandle < Node > | null > {
80
91
const element = handle . asElement ( )
81
92
if ( element ) return element
82
93
await handle . dispose ( )
@@ -88,31 +99,37 @@ async function covertToElementHandle(handle: JSHandle, asArray: boolean): Promis
88
99
}
89
100
90
101
function processNodeText ( handles : IHandleSet ) : Promise < string > {
91
- return handles . containerHandle
92
- . executionContext ( )
93
- . evaluate ( handles . evaluateFn , handles . containerHandle , 'getNodeText' )
102
+ return getExecutionContextFromHandle ( handles . containerHandle ) . evaluate (
103
+ handles . evaluateFn ,
104
+ handles . containerHandle ,
105
+ 'getNodeText' ,
106
+ )
94
107
}
95
108
96
109
async function processQuery ( handles : IHandleSet ) : Promise < DOMReturnType > {
97
110
const { containerHandle, evaluateFn, fnName, argsToForward} = handles
98
111
99
112
try {
100
- const handle = await containerHandle
101
- . executionContext ( )
102
- . evaluateHandle ( evaluateFn , containerHandle , fnName , ...argsToForward )
113
+ const handle = await getExecutionContextFromHandle ( containerHandle ) . evaluateHandle (
114
+ evaluateFn ,
115
+ containerHandle ,
116
+ fnName ,
117
+ ...argsToForward ,
118
+ )
103
119
return await covertToElementHandle ( handle , fnName . includes ( 'All' ) )
104
120
} catch ( err ) {
121
+ if ( typeof err !== 'object' || ! err || ! ( err instanceof Error ) ) throw err
105
122
err . message = err . message . replace ( '[fnName]' , `[${ fnName } ]` )
106
- err . stack = err . stack . replace ( '[fnName]' , `[${ fnName } ]` )
123
+ err . stack = ( err . stack || '' ) . replace ( '[fnName]' , `[${ fnName } ]` )
107
124
throw err
108
125
}
109
126
}
110
127
111
128
interface IHandleSet {
112
129
containerHandle : ElementHandle
113
- evaluateFn : EvaluateFn
114
130
fnName : string
115
131
argsToForward : any [ ]
132
+ evaluateFn ( ...params : any [ ] ) : any
116
133
}
117
134
118
135
function createDelegateFor < T = DOMReturnType > (
@@ -145,13 +162,13 @@ function createDelegateFor<T = DOMReturnType>(
145
162
}
146
163
}
147
164
148
- export async function getDocument ( _page ?: Page ) : Promise < ElementHandle > {
165
+ export async function getDocument ( _page ?: Page ) : Promise < ElementHandle < Element > > {
149
166
// @ts -ignore
150
167
const page : Page = _page || this
151
168
const documentHandle = await page . mainFrame ( ) . evaluateHandle ( 'document' )
152
169
const document = documentHandle . asElement ( )
153
170
if ( ! document ) throw new Error ( 'Could not find document' )
154
- return document
171
+ return document as ElementHandle < Element >
155
172
}
156
173
157
174
export function wait (
0 commit comments