@@ -152,22 +152,43 @@ describe('GenericProvider', () => {
152152 describe ( 'getRegionsByElements' , ( ) => {
153153 let getRegionObjectSpy ;
154154 let mockElement ;
155+ let mockDriver ;
155156
156157 beforeEach ( ( ) => {
157158 getRegionObjectSpy = spyOn ( provider , 'getRegionObject' ) . and . resolveTo ( { } ) ;
158- mockElement = {
159- getAttribute : jasmine . createSpy ( ) . and . returnValue ( 'some-class ')
159+ mockDriver = {
160+ getCapabilities : jasmine . createSpy ( 'getCapabilities ')
160161 } ;
161162 } ) ;
162163
163164 it ( 'should get regions for each element' , async ( ) => {
165+ // Set up mock driver with platform capability
166+ mockDriver . getCapabilities . and . resolveTo ( { platformName : 'android' } ) ;
167+
164168 const elementsArray = [ ] ;
169+ mockElement = {
170+ getAttribute : jasmine . createSpy ( 'getAttribute' )
171+ . and . callFake ( attr => {
172+ if ( attr === 'resource-id' ) return 'test_id' ;
173+ if ( attr === 'class' ) return 'android.widget.Button' ;
174+ return null ;
175+ } )
176+ } ;
165177 const elements = [ mockElement , mockElement , mockElement ] ;
166178
167- await provider . getRegionsByElements . call ( { driver, getRegionObject : getRegionObjectSpy } , elementsArray , elements ) ;
179+ await provider . getRegionsByElements . call (
180+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
181+ elementsArray ,
182+ elements
183+ ) ;
168184
169185 expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 3 ) ;
170186 expect ( elementsArray ) . toEqual ( [ { } , { } , { } ] ) ;
187+
188+ // Verify each call had correct selector
189+ for ( let i = 0 ; i < 3 ; i ++ ) {
190+ expect ( getRegionObjectSpy . calls . argsFor ( i ) [ 0 ] ) . toBe ( `element: ${ i } test_id` ) ;
191+ }
171192 } ) ;
172193
173194 it ( 'should ignore when error' , async ( ) => {
@@ -180,6 +201,163 @@ describe('GenericProvider', () => {
180201 // expect(getRegionObjectSpy).not.toHaveBeenCalled();
181202 expect ( elementsArray ) . toEqual ( [ ] ) ;
182203 } ) ;
204+
205+ describe ( 'Platform specific tests' , ( ) => {
206+ it ( 'should handle unknown platform' , async ( ) => {
207+ mockDriver . getCapabilities . and . resolveTo ( { platformName : 'unknown' } ) ;
208+ const elementsArray = [ ] ;
209+ mockElement = {
210+ getAttribute : jasmine . createSpy ( 'getAttribute' )
211+ . and . returnValue ( 'some-value' )
212+ } ;
213+
214+ await provider . getRegionsByElements . call (
215+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
216+ elementsArray ,
217+ [ mockElement ]
218+ ) ;
219+
220+ expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 1 ) ;
221+ expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0' ) ;
222+ expect ( elementsArray ) . toEqual ( [ { } ] ) ;
223+ } ) ;
224+
225+ describe ( 'Android' , ( ) => {
226+ beforeEach ( ( ) => {
227+ mockDriver . getCapabilities . and . resolveTo ( { platformName : 'android' } ) ;
228+ } ) ;
229+
230+ it ( 'should use resource-id as primary identifier' , async ( ) => {
231+ const elementsArray = [ ] ;
232+ mockElement = {
233+ getAttribute : jasmine . createSpy ( 'getAttribute' )
234+ . and . callFake ( attr => {
235+ if ( attr === 'resource-id' ) return 'test_resource_id' ;
236+ if ( attr === 'class' ) return 'android.widget.Button' ;
237+ return null ;
238+ } )
239+ } ;
240+
241+ await provider . getRegionsByElements . call (
242+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
243+ elementsArray ,
244+ [ mockElement ]
245+ ) ;
246+
247+ expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 1 ) ;
248+ expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0 test_resource_id' ) ;
249+ expect ( elementsArray ) . toEqual ( [ { } ] ) ;
250+ } ) ;
251+
252+ it ( 'should fallback to class when resource-id is not available' , async ( ) => {
253+ const elementsArray = [ ] ;
254+ mockElement = {
255+ getAttribute : jasmine . createSpy ( 'getAttribute' )
256+ . and . callFake ( attr => {
257+ if ( attr === 'resource-id' ) return null ;
258+ if ( attr === 'class' ) return 'android.widget.Button' ;
259+ return null ;
260+ } )
261+ } ;
262+
263+ await provider . getRegionsByElements . call (
264+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
265+ elementsArray ,
266+ [ mockElement ]
267+ ) ;
268+
269+ expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 1 ) ;
270+ expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0 android.widget.Button' ) ;
271+ expect ( elementsArray ) . toEqual ( [ { } ] ) ;
272+ } ) ;
273+ } ) ;
274+
275+ describe ( 'iOS' , ( ) => {
276+ beforeEach ( ( ) => {
277+ mockDriver . getCapabilities . and . resolveTo ( { platformName : 'ios' } ) ;
278+ } ) ;
279+
280+ it ( 'should use name as primary identifier' , async ( ) => {
281+ const elementsArray = [ ] ;
282+ mockElement = {
283+ getAttribute : jasmine . createSpy ( 'getAttribute' )
284+ . and . callFake ( attr => {
285+ if ( attr === 'name' ) return 'TestButton' ;
286+ if ( attr === 'type' ) return 'XCUIElementTypeButton' ;
287+ return null ;
288+ } )
289+ } ;
290+
291+ await provider . getRegionsByElements . call (
292+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
293+ elementsArray ,
294+ [ mockElement ]
295+ ) ;
296+
297+ expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 1 ) ;
298+ expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0 TestButton' ) ;
299+ expect ( elementsArray ) . toEqual ( [ { } ] ) ;
300+ } ) ;
301+
302+ it ( 'should fallback to type when name is not available' , async ( ) => {
303+ const elementsArray = [ ] ;
304+ mockElement = {
305+ getAttribute : jasmine . createSpy ( 'getAttribute' )
306+ . and . callFake ( attr => {
307+ if ( attr === 'name' ) return null ;
308+ if ( attr === 'type' ) return 'XCUIElementTypeButton' ;
309+ return null ;
310+ } )
311+ } ;
312+
313+ await provider . getRegionsByElements . call (
314+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
315+ elementsArray ,
316+ [ mockElement ]
317+ ) ;
318+
319+ expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 1 ) ;
320+ expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0 XCUIElementTypeButton' ) ;
321+ expect ( elementsArray ) . toEqual ( [ { } ] ) ;
322+ } ) ;
323+ } ) ;
324+ } ) ;
325+
326+ describe ( 'Error handling' , ( ) => {
327+ it ( 'should handle elements with no identifiers' , async ( ) => {
328+ mockDriver . getCapabilities . and . resolveTo ( { platformName : 'android' } ) ;
329+ const elementsArray = [ ] ;
330+ mockElement = {
331+ getAttribute : jasmine . createSpy ( 'getAttribute' ) . and . returnValue ( null )
332+ } ;
333+
334+ await provider . getRegionsByElements . call (
335+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
336+ elementsArray ,
337+ [ mockElement ]
338+ ) ;
339+
340+ expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 1 ) ;
341+ expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0' ) ;
342+ expect ( elementsArray ) . toEqual ( [ { } ] ) ;
343+ } ) ;
344+
345+ it ( 'should handle capability errors' , async ( ) => {
346+ mockDriver . getCapabilities . and . rejectWith ( new Error ( 'Capabilities not found' ) ) ;
347+ const elementsArray = [ ] ;
348+ mockElement = {
349+ getAttribute : jasmine . createSpy ( 'getAttribute' )
350+ } ;
351+
352+ await provider . getRegionsByElements . call (
353+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
354+ elementsArray ,
355+ [ mockElement ]
356+ ) ;
357+
358+ expect ( elementsArray ) . toEqual ( [ ] ) ;
359+ } ) ;
360+ } ) ;
183361 } ) ;
184362
185363 describe ( 'getRegionsByLocation function' , ( ) => {
0 commit comments