@@ -28,21 +28,22 @@ const getElementMethods = () => ({
2828 } } , 'getSize' ) as unknown as WebdriverIO . Element [ 'getSize' ] ,
2929} satisfies Partial < WebdriverIO . Element > )
3030
31- const elementFactory = ( _selector : string , index ?: number ) : WebdriverIO . Element => {
31+ export const elementFactory = ( _selector : string , index ?: number , parent : WebdriverIO . Browser | WebdriverIO . Element = browser ) : WebdriverIO . Element => {
3232 const partialElement = {
3333 selector : _selector ,
3434 ...getElementMethods ( ) ,
3535 index,
3636 $,
37- $$
37+ $$,
38+ parent
3839 } satisfies Partial < WebdriverIO . Element >
3940
4041 const element = partialElement as unknown as WebdriverIO . Element
4142 element . getElement = vi . fn ( ) . mockResolvedValue ( element )
4243 return element
4344}
4445
45- function $ ( _selector : string ) {
46+ const $ = vi . fn ( ( _selector : string ) => {
4647 const element = elementFactory ( _selector )
4748
4849 // Wdio framework does return a Promise-wrapped element, so we need to mimic this behavior
@@ -59,25 +60,46 @@ function $(_selector: string) {
5960 }
6061 } )
6162 return runtimeChainableElement
62- }
63+ } )
6364
64- function $$ ( selector : string ) {
65+ const $$ = vi . fn ( ( selector : string ) => {
6566 const length = ( this as any ) ?. _length || 2
67+ return chainableElementArrayFactory ( selector , length )
68+ } )
69+
70+ export function elementArrayFactory ( selector : string , length ?: number ) : WebdriverIO . ElementArray {
6671 const elements : WebdriverIO . Element [ ] = Array ( length ) . fill ( null ) . map ( ( _ , index ) => elementFactory ( selector , index ) )
6772
6873 const elementArray = elements as unknown as WebdriverIO . ElementArray
6974
7075 elementArray . foundWith = '$$'
7176 elementArray . props = [ ]
7277 elementArray . selector = selector
73- elementArray . getElements = async ( ) => elementArray
78+ elementArray . getElements = vi . fn ( ) . mockResolvedValue ( elementArray )
7479 elementArray . filter = async < T > ( fn : ( element : WebdriverIO . Element , index : number , array : T [ ] ) => boolean | Promise < boolean > ) => {
7580 const results = await Promise . all ( elements . map ( ( el , i ) => fn ( el , i , elements as unknown as T [ ] ) ) )
7681 return Array . prototype . filter . call ( elements , ( _ , i ) => results [ i ] )
7782 }
78-
7983 elementArray . parent = browser
8084
85+ // TODO Verify if we need to implement other array methods
86+ // [Symbol.iterator]: array[Symbol.iterator].bind(array)
87+ // filter: vi.fn().mockReturnThis(),
88+ // map: vi.fn().mockReturnThis(),
89+ // find: vi.fn().mockReturnThis(),
90+ // forEach: vi.fn(),
91+ // some: vi.fn(),
92+ // every: vi.fn(),
93+ // slice: vi.fn().mockReturnThis(),
94+ // toArray: vi.fn().mockReturnThis(),
95+ // getElements: vi.fn().mockResolvedValue(array)
96+
97+ return elementArray
98+ }
99+
100+ export function chainableElementArrayFactory ( selector : string , length : number ) {
101+ const elementArray = elementArrayFactory ( selector , length )
102+
81103 // Wdio framework does return a Promise-wrapped element, so we need to mimic this behavior
82104 const chainablePromiseArray = Promise . resolve ( elementArray ) as unknown as ChainablePromiseArray
83105
0 commit comments