1- /* eslint-disable babel/ no-invalid-this, no-eval */
1+ /* eslint-disable no-eval, @babel/new-cap */
22
33import path from 'path'
44import fs from 'fs'
5- import { queries as baseQueries } from '@testing-library/dom'
5+ import {
6+ Matcher ,
7+ MatcherOptions ,
8+ queries as baseQueries ,
9+ waitForOptions as WaitForOptions ,
10+ } from '@testing-library/dom'
611import 'simmerjs'
712
13+ import { BrowserBase , ElementBase } from './wdio-types'
814import {
9- BrowserBase ,
15+ QueryArg ,
1016 Config ,
11- ElementBase ,
1217 QueryName ,
1318 WebdriverIOQueries ,
19+ ObjectQueryArg ,
20+ SerializedObject ,
21+ SerializedArg ,
1422} from './types'
1523
1624declare global {
@@ -45,9 +53,9 @@ async function injectDOMTestingLibrary(container: ElementBase) {
4553 } )
4654
4755 if ( shouldInject . domTestingLibrary ) {
48- await container . execute ( function ( library ) {
56+ await container . execute ( function ( library : string ) {
4957 // add DOM Testing Library to page as a script tag to support Firefox
50- if ( navigator . userAgent . indexOf ( 'Firefox' ) !== - 1 ) {
58+ if ( navigator . userAgent . includes ( 'Firefox' ) ) {
5159 const script = document . createElement ( 'script' )
5260 script . innerHTML = library
5361 return document . head . append ( script )
@@ -62,74 +70,83 @@ async function injectDOMTestingLibrary(container: ElementBase) {
6270 await container . execute ( SIMMERJS )
6371 }
6472
65- if ( _config ) {
66- await container . execute ( function ( config : Config ) {
67- window . TestingLibraryDom . configure ( config )
68- } , _config )
69- }
73+ await container . execute ( function ( config : Config ) {
74+ window . TestingLibraryDom . configure ( config )
75+ } , _config )
7076}
7177
72- function serializeObject ( object : Object ) : Object {
78+ function serializeObject ( object : ObjectQueryArg ) : SerializedObject {
7379 return Object . entries ( object )
74- . map ( ( [ key , value ] ) => [ key , serializeArg ( value ) ] )
75- . reduce ( ( acc , [ key , value ] ) => ( { ...acc , [ key ] : value } ) , { } )
80+ . map < [ string , SerializedArg ] > ( ( [ key , value ] : [ string , QueryArg ] ) => [
81+ key ,
82+ serializeArg ( value ) ,
83+ ] )
84+ . reduce ( ( acc , [ key , value ] ) => ( { ...acc , [ key ] : value } ) , {
85+ serialized : 'object' ,
86+ } )
7687}
7788
78- function serializeArg ( arg : any ) {
89+ function serializeArg ( arg : QueryArg ) : SerializedArg {
7990 if ( arg instanceof RegExp ) {
80- return { RegExp : arg . toString ( ) }
91+ return { serialized : 'RegExp' , RegExp : arg . toString ( ) }
8192 }
8293 if ( typeof arg === 'undefined' ) {
83- return { Undefined : true }
94+ return { serialized : 'Undefined' , Undefined : true }
8495 }
8596 if ( arg && typeof arg === 'object' ) {
8697 return serializeObject ( arg )
8798 }
8899 return arg
89100}
90101
102+ type SerializedQueryResult =
103+ | { selector : string | false ; element : HTMLElement } [ ]
104+ | string
105+ | { selector : string | false ; element : HTMLElement }
106+ | null
107+
91108function executeQuery (
92109 query : QueryName ,
93110 container : HTMLElement ,
94- ...args : any [ ]
111+ ...args : SerializedArg [ ]
95112) {
96- const done = args . pop ( ) as ( result : any ) => void
113+ const done = args . pop ( ) as unknown as ( result : SerializedQueryResult ) => void
97114
98- function deserializeObject ( object : object ) : object {
115+ function deserializeObject ( object : SerializedObject ) {
99116 return Object . entries ( object )
100- . map ( ( [ key , value ] ) => [ key , deserializeArg ( value ) ] )
117+ . map < [ string , QueryArg ] > ( ( [ key , value ] ) => [ key , deserializeArg ( value ) ] )
101118 . reduce ( ( acc , [ key , value ] ) => ( { ...acc , [ key ] : value } ) , { } )
102119 }
103120
104- function deserializeArg ( arg : any ) {
105- if ( arg && arg . RegExp ) {
121+ function deserializeArg ( arg : SerializedArg ) : QueryArg {
122+ if ( typeof arg === 'object' && arg . serialized === ' RegExp' ) {
106123 return eval ( arg . RegExp )
107124 }
108- if ( arg && arg . Undefined ) {
125+ if ( typeof arg === 'object' && arg . serialized === ' Undefined' ) {
109126 return undefined
110127 }
111- if ( arg && typeof arg === 'object' ) {
128+ if ( typeof arg === 'object' ) {
112129 return deserializeObject ( arg )
113130 }
114131 return arg
115132 }
116133
117134 const [ matcher , options , waitForOptions ] = args . map ( deserializeArg )
118135
119- ; ( async ( ) => {
120- let result : undefined | null | HTMLElement | HTMLElement [ ]
136+ void ( async ( ) => {
137+ let result : ReturnType < typeof window . TestingLibraryDom [ typeof query ] > = null
121138 try {
122139 // Override RegExp to fix 'matcher instanceof RegExp' check on Firefox
123140 window . RegExp = RegExp
124141
125142 result = await window . TestingLibraryDom [ query ] (
126143 container ,
127- matcher ,
128- options ,
129- waitForOptions ,
144+ matcher as Matcher ,
145+ options as MatcherOptions ,
146+ waitForOptions as WaitForOptions ,
130147 )
131- } catch ( e ) {
132- done ( e . message )
148+ } catch ( e : unknown ) {
149+ return done ( ( e as Error ) . message )
133150 }
134151
135152 if ( ! result ) {
@@ -160,10 +177,10 @@ Element. There are valid WebElement JSONs that exclude the key but can be turned
160177into Elements, such as { ELEMENT: elementId }; this can happen in setups that
161178aren't generated by @wdio/cli.
162179*/
163- function createElement (
180+ async function createElement (
164181 container : ElementBase ,
165- result : { selector : string | false ; element : any } ,
166- ) {
182+ result : { selector : string | false ; element : object } ,
183+ ) : Promise < WebdriverIO . Element > {
167184 // use selector if possible so that element can be refetched
168185 if ( result . selector ) {
169186 return container . $ ( result . selector )
@@ -176,11 +193,12 @@ function createElement(
176193 } )
177194}
178195
179- function createQuery ( container : ElementBase , queryName : string ) {
180- return async ( ...args : any [ ] ) => {
196+ function createQuery ( container : ElementBase , queryName : QueryName ) {
197+ return async ( ...args : QueryArg [ ] ) => {
181198 await injectDOMTestingLibrary ( container )
182199
183- const result = await container . executeAsync (
200+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
201+ const result : SerializedQueryResult = await container . executeAsync (
184202 executeQuery ,
185203 queryName ,
186204 container ,
@@ -204,7 +222,7 @@ function createQuery(container: ElementBase, queryName: string) {
204222}
205223
206224function within ( element : ElementBase ) {
207- return Object . keys ( baseQueries ) . reduce (
225+ return ( Object . keys ( baseQueries ) as QueryName [ ] ) . reduce (
208226 ( queries , queryName ) => ( {
209227 ...queries ,
210228 [ queryName ] : createQuery ( element , queryName ) ,
@@ -213,22 +231,29 @@ function within(element: ElementBase) {
213231 ) as WebdriverIOQueries
214232}
215233
216- function setupBrowser ( browser : BrowserBase ) {
217- const queries : { [ key : string ] : any } = { }
234+ /*
235+ eslint-disable
236+ @typescript -eslint/no-explicit-any,
237+ @typescript -eslint/no-unsafe-argument
238+ */
239+ function setupBrowser ( browser : BrowserBase ) : WebdriverIOQueries {
240+ const queries : { [ key : string ] : WebdriverIOQueries [ QueryName ] } = { }
218241
219242 Object . keys ( baseQueries ) . forEach ( ( key ) => {
220- const queryName = key as keyof typeof baseQueries
243+ const queryName = key as QueryName
221244
222- const query = async ( ...args : any [ ] ) => {
245+ const query = async (
246+ ...args : Parameters < WebdriverIOQueries [ QueryName ] >
247+ ) => {
223248 const body = await browser . $ ( 'body' )
224- return within ( body ) [ queryName ] ( ...args )
249+ return within ( body ) [ queryName ] ( ...( args as any [ ] ) )
225250 }
226251
227252 // add query to response queries
228- queries [ queryName ] = query
253+ queries [ queryName ] = query as WebdriverIOQueries [ QueryName ]
229254
230255 // add query to BrowserObject
231- browser . addCommand ( queryName , query )
256+ browser . addCommand ( queryName , query as WebdriverIOQueries [ QueryName ] )
232257
233258 // add query to Elements
234259 browser . addCommand (
@@ -242,6 +267,11 @@ function setupBrowser(browser: BrowserBase) {
242267
243268 return queries as WebdriverIOQueries
244269}
270+ /*
271+ eslint-enable
272+ @typescript -eslint/no-explicit-any,
273+ @typescript -eslint/no-unsafe-argument
274+ */
245275
246276function configure ( config : Partial < Config > ) {
247277 _config = config
0 commit comments