diff --git a/detox/ios/Detox/Invocation/Element.swift b/detox/ios/Detox/Invocation/Element.swift index 81f108318b..a7179f0e50 100644 --- a/detox/ios/Detox/Invocation/Element.swift +++ b/detox/ios/Detox/Invocation/Element.swift @@ -313,14 +313,19 @@ class Element : NSObject { @objc var attributes: [String : Any] { let views = self.views - - if views.count == 1 { + + if let index = index { + guard index < views.count else { + dtx_fatalError("Index \(index) beyond bounds \(views.count > 0 ? "[0 .. \(views.count - 1)] " : " ")for "\(self.description)"", viewDescription: failDebugAttributes) + } + return views[index].dtx_attributes + } else if views.count == 1 { return views.first!.dtx_attributes } else { let elements = views.map { return $0.dtx_attributes } - + return ["elements": elements] } } diff --git a/detox/test/e2e/33.attributes.test.js b/detox/test/e2e/33.attributes.test.js index f3a7b055fe..9d4fbecf67 100644 --- a/detox/test/e2e/33.attributes.test.js +++ b/detox/test/e2e/33.attributes.test.js @@ -220,6 +220,28 @@ describe('Attributes', () => { }); }); + describe('of multiple views with atIndex', () => { + it(':ios: @legacy should return attributes of a single element when using atIndex', async () => { + const result = await element(by.type('RCTView').withAncestor(by.id('attrScrollView'))).atIndex(0).getAttributes(); + + expect(result).not.toHaveProperty('elements'); + expect(result).toMatchObject({ + enabled: true, + visible: true, + }); + }); + + it(':ios: @new-arch should return attributes of a single element when using atIndex', async () => { + const result = await element(by.type('RCTViewComponentView')).atIndex(0).getAttributes(); + + expect(result).not.toHaveProperty('elements'); + expect(result).toMatchObject({ + enabled: true, + visible: true, + }); + }); + }); + describe('of multiple views', () => { it(':ios: @legacy should return an object with .elements array', async () => { await useMatcher(by.type('RCTView').withAncestor(by.id('attrScrollView')));