@@ -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 ( ) => {
@@ -181,33 +202,179 @@ describe('GenericProvider', () => {
181202 expect ( elementsArray ) . toEqual ( [ ] ) ;
182203 } ) ;
183204
184- it ( 'should add regions for valid elements' , async ( ) => {
185- const elementsArray = [ ] ;
186- const mockElements = [
187- {
188- getRect : jasmine . createSpy ( ) . and . resolveTo ( { x : 10 , y : 20 , width : 100 , height : 50 } )
189- } ,
190- {
191- getRect : jasmine . createSpy ( ) . and . resolveTo ( { x : 30 , y : 40 , width : 200 , height : 60 } )
192- }
193- ] ;
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+ } ) ;
194224
195- await provider . getRegionsByElements . call ( { driver, getRegionObject : getRegionObjectSpy } , elementsArray , mockElements ) ;
225+ it ( 'should handle missing platformName in capabilities' , async ( ) => {
226+ mockDriver . getCapabilities . and . resolveTo ( { } ) ;
227+ const elementsArray = [ ] ;
228+ mockElement = {
229+ getAttribute : jasmine . createSpy ( 'getAttribute' )
230+ . and . returnValue ( 'some-value' )
231+ } ;
232+
233+ await provider . getRegionsByElements . call (
234+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
235+ elementsArray ,
236+ [ mockElement ]
237+ ) ;
238+
239+ expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 1 ) ;
240+ expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0' ) ;
241+ expect ( elementsArray ) . toEqual ( [ { } ] ) ;
242+ } ) ;
243+ describe ( 'Android' , ( ) => {
244+ beforeEach ( ( ) => {
245+ mockDriver . getCapabilities . and . resolveTo ( { platformName : 'android' } ) ;
246+ } ) ;
247+
248+ it ( 'should use resource-id as primary identifier' , async ( ) => {
249+ const elementsArray = [ ] ;
250+ mockElement = {
251+ getAttribute : jasmine . createSpy ( 'getAttribute' )
252+ . and . callFake ( attr => {
253+ if ( attr === 'resource-id' ) return 'test_resource_id' ;
254+ if ( attr === 'class' ) return 'android.widget.Button' ;
255+ return null ;
256+ } )
257+ } ;
258+
259+ await provider . getRegionsByElements . call (
260+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
261+ elementsArray ,
262+ [ mockElement ]
263+ ) ;
264+
265+ expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 1 ) ;
266+ expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0 test_resource_id' ) ;
267+ expect ( elementsArray ) . toEqual ( [ { } ] ) ;
268+ } ) ;
269+
270+ it ( 'should fallback to class when resource-id is not available' , async ( ) => {
271+ const elementsArray = [ ] ;
272+ mockElement = {
273+ getAttribute : jasmine . createSpy ( 'getAttribute' )
274+ . and . callFake ( attr => {
275+ if ( attr === 'resource-id' ) return null ;
276+ if ( attr === 'class' ) return 'android.widget.Button' ;
277+ return null ;
278+ } )
279+ } ;
280+
281+ await provider . getRegionsByElements . call (
282+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
283+ elementsArray ,
284+ [ mockElement ]
285+ ) ;
286+
287+ expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 1 ) ;
288+ expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0 android.widget.Button' ) ;
289+ expect ( elementsArray ) . toEqual ( [ { } ] ) ;
290+ } ) ;
291+ } ) ;
196292
197- expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 2 ) ;
198- expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0' ) ;
199- expect ( getRegionObjectSpy . calls . argsFor ( 1 ) [ 0 ] ) . toBe ( 'element: 1' ) ;
200- expect ( elementsArray ) . toEqual ( [ { } , { } ] ) ;
293+ describe ( 'iOS' , ( ) => {
294+ beforeEach ( ( ) => {
295+ mockDriver . getCapabilities . and . resolveTo ( { platformName : 'ios' } ) ;
296+ } ) ;
297+
298+ it ( 'should use name as primary identifier' , async ( ) => {
299+ const elementsArray = [ ] ;
300+ mockElement = {
301+ getAttribute : jasmine . createSpy ( 'getAttribute' )
302+ . and . callFake ( attr => {
303+ if ( attr === 'name' ) return 'TestButton' ;
304+ if ( attr === 'type' ) return 'XCUIElementTypeButton' ;
305+ return null ;
306+ } )
307+ } ;
308+
309+ await provider . getRegionsByElements . call (
310+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
311+ elementsArray ,
312+ [ mockElement ]
313+ ) ;
314+
315+ expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 1 ) ;
316+ expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0 TestButton' ) ;
317+ expect ( elementsArray ) . toEqual ( [ { } ] ) ;
318+ } ) ;
319+
320+ it ( 'should fallback to type when name is not available' , async ( ) => {
321+ const elementsArray = [ ] ;
322+ mockElement = {
323+ getAttribute : jasmine . createSpy ( 'getAttribute' )
324+ . and . callFake ( attr => {
325+ if ( attr === 'name' ) return null ;
326+ if ( attr === 'type' ) return 'XCUIElementTypeButton' ;
327+ return null ;
328+ } )
329+ } ;
330+
331+ await provider . getRegionsByElements . call (
332+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
333+ elementsArray ,
334+ [ mockElement ]
335+ ) ;
336+
337+ expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 1 ) ;
338+ expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0 XCUIElementTypeButton' ) ;
339+ expect ( elementsArray ) . toEqual ( [ { } ] ) ;
340+ } ) ;
341+ } ) ;
201342 } ) ;
202343
203- it ( 'should handle empty elements array' , async ( ) => {
204- const elementsArray = [ ] ;
205- const mockElements = [ ] ;
206-
207- await provider . getRegionsByElements . call ( { driver, getRegionObject : getRegionObjectSpy } , elementsArray , mockElements ) ;
208-
209- expect ( getRegionObjectSpy ) . not . toHaveBeenCalled ( ) ;
210- expect ( elementsArray ) . toEqual ( [ ] ) ;
344+ describe ( 'Error handling' , ( ) => {
345+ it ( 'should handle elements with no identifiers' , async ( ) => {
346+ mockDriver . getCapabilities . and . resolveTo ( { platformName : 'android' } ) ;
347+ const elementsArray = [ ] ;
348+ mockElement = {
349+ getAttribute : jasmine . createSpy ( 'getAttribute' ) . and . returnValue ( null )
350+ } ;
351+
352+ await provider . getRegionsByElements . call (
353+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
354+ elementsArray ,
355+ [ mockElement ]
356+ ) ;
357+
358+ expect ( getRegionObjectSpy ) . toHaveBeenCalledTimes ( 1 ) ;
359+ expect ( getRegionObjectSpy . calls . argsFor ( 0 ) [ 0 ] ) . toBe ( 'element: 0' ) ;
360+ expect ( elementsArray ) . toEqual ( [ { } ] ) ;
361+ } ) ;
362+
363+ it ( 'should handle capability errors' , async ( ) => {
364+ mockDriver . getCapabilities . and . rejectWith ( new Error ( 'Capabilities not found' ) ) ;
365+ const elementsArray = [ ] ;
366+ mockElement = {
367+ getAttribute : jasmine . createSpy ( 'getAttribute' )
368+ } ;
369+
370+ await provider . getRegionsByElements . call (
371+ { driver : mockDriver , getRegionObject : getRegionObjectSpy } ,
372+ elementsArray ,
373+ [ mockElement ]
374+ ) ;
375+
376+ expect ( elementsArray ) . toEqual ( [ ] ) ;
377+ } ) ;
211378 } ) ;
212379 } ) ;
213380
0 commit comments