Skip to content

Unable to select value from picker #798

@matthewrfindley

Description

@matthewrfindley

Description

Using detox to select a value from a picker appears to be broken on IOS. Using a testID on a Picker or using UIPickerView have different results as seen below. This could be a result of any number of things going wrong in the dependency chain, but I figured the detox community may know the answer. I've added a spec to the e2e tests to isolate the issue. You can find the branch here.

Steps to Reproduce

Detox, Node, Device, Xcode and macOS Versions

  • Detox: 7.4.3
  • React Native: 0.51 (in detox repo)
  • Node: 8.11.1
  • Device: iPhone 8 Plus - 11.4
  • Xcode: 9.4.1
  • macOS: 10.13.5

Device and verbose Detox logs

✗ :ios: Picker picker should trigger change handler correctly using testID
 ● :ios: Picker › picker should trigger change handler correctly using testID

    Error: Cannot find UI element.
    Exception with Action: {
      "Action Name" : "Set picker column 0 to value 'Bar'",
      "Element Matcher" : "(((respondsToSelector(accessibilityIdentifier) && accessibilityID('FooPicker')) && !(kindOfClass('RCTScrollView'))) || (kindOfClass('UIScrollView') && ((kindOfClass('UIView') || respondsToSelector(accessibilityContainer)) && ancestorThatMatches(((respondsToSelector(accessibilityIdentifier) && accessibilityID('FooPicker')) && kindOfClass('RCTScrollView'))))))",
      "Recovery Suggestion" : "Check if the element exists in the UI hierarchy printed below. If it exists, adjust the matcher so that it accurately matches element."
    }

    Error Trace: [
      {
        "Description" : "Interaction cannot continue because the desired element was not found.",
        "Error Domain" : "com.google.earlgrey.ElementInteractionErrorDomain",
        "Error Code" : "0",
        "File Name" : "GREYElementInteraction.m",
        "Function Name" : "-[GREYElementInteraction matchedElementsWithTimeout:error:]",
        "Line" : "124"
      }
    ]

      71 |     // when this test run fails, we want a stack trace from up here where the
      72 |     // $callee is still available, and not inside the catch block where it isn't
    > 73 |     const potentialError = new Error()
      74 |
      75 |     try {
      76 |       await this.sendAction(new actions.Invoke(invocation));

      at Client.execute (../../src/client/Client.js:73:28)
      at InvocationManager.execute (../../src/invoke.js:11:33)
      at ActionInteraction.execute (../../src/ios/expect.js:178:29)
      at Element.setColumnToValue (../../src/ios/expect.js:306:86)
      at Object.it (20.picker.test.js:10:39)
send: {"type":"invoke","params":{"target":{"type":"Invocation","value":{"target":{"type":"EarlGrey","value":"instance"},"method":"detox_selectElementWithMatcher:","args":[{"type":"Invocation","value":{"target":{"type":"Class","value":"GREYMatchers"},"method":"matcherForAccessibilityID:","args":[{"type":"NSString","value":"FooPicker"}]}}]}},"method":"performAction:","args":[{"type":"Invocation","value":{"target":{"type":"Class","value":"GREYActions"},"method":"actionForSetPickerColumn:toValue:","args":[{"type":"NSInteger","value":0},{"type":"NSString","value":"Bar"}]}}]},"messageId":3}
 onMessage: {"type":"testFailed","messageId":3,"params":{"details":"Cannot find UI element.\nException with Action: {\n  \"Action Name\" : \"Set picker column 0 to value 'Bar'\",\n  \"Element Matcher\" : \"(((respondsToSelector(accessibilityIdentifier) && accessibilityID('FooPicker')) && !(kindOfClass('RCTScrollView'))) || (kindOfClass('UIScrollView') && ((kindOfClass('UIView') || respondsToSelector(accessibilityContainer)) && ancestorThatMatches(((respondsToSelector(accessibilityIdentifier) && accessibilityID('FooPicker')) && kindOfClass('RCTScrollView'))))))\",\n  \"Recovery Suggestion\" : \"Check if the element exists in the UI hierarchy printed below. If it exists, adjust the matcher so that it accurately matches element.\"\n}\n\nError Trace: [\n  {\n    \"Description\" : \"Interaction cannot continue because the desired element was not found.\",\n    \"Error Domain\" : \"com.google.earlgrey.ElementInteractionErrorDomain\",\n    \"Error Code\" : \"0\",\n    \"File Name\" : \"GREYElementInteraction.m\",\n    \"Function Name\" : \"-[GREYElementInteraction matchedElementsWithTimeout:error:]\",\n    \"Line\" : \"124\"\n  }\n]"}}
✗ :ios: Picker picker should trigger change handler correctly using type
 ● :ios: Picker › picker should trigger change handler correctly using type

    Error: An action failed. Please refer to the error trace below.
    Exception with Action: {
      "Action Name" : "Set picker column 0 to value 'Bar'",
      "Element Matcher" : "((kindOfClass('UIPickerView') && !(kindOfClass('RCTScrollView'))) || (kindOfClass('UIScrollView') && ((kindOfClass('UIView') || respondsToSelector(accessibilityContainer)) && ancestorThatMatches((kindOfClass('UIPickerView') && kindOfClass('RCTScrollView'))))))"
    }

    Error Trace: [
      {
        "Description" : "UIPickerView does not contain desired value!",
        "Error Domain" : "com.google.earlgrey.ElementInteractionErrorDomain",
        "Error Code" : "2",
        "File Name" : "GREYPickerAction.m",
        "Function Name" : "-[GREYPickerAction perform:error:]",
        "Line" : "120"
      }
    ]

      71 |     // when this test run fails, we want a stack trace from up here where the
      72 |     // $callee is still available, and not inside the catch block where it isn't
    > 73 |     const potentialError = new Error()
      74 |
      75 |     try {
      76 |       await this.sendAction(new actions.Invoke(invocation));

      at Client.execute (../../src/client/Client.js:73:28)
      at InvocationManager.execute (../../src/invoke.js:11:33)
      at ActionInteraction.execute (../../src/ios/expect.js:178:29)
      at Element.setColumnToValue (../../src/ios/expect.js:306:86)
      at Object.it (20.picker.test.js:18:44)
send: {"type":"invoke","params":{"target":{"type":"Invocation","value":{"target":{"type":"EarlGrey","value":"instance"},"method":"detox_selectElementWithMatcher:","args":[{"type":"Invocation","value":{"target":{"type":"Class","value":"GREYMatchers"},"method":"detoxMatcherForClass:","args":[{"type":"NSString","value":"UIPickerView"}]}}]}},"method":"performAction:","args":[{"type":"Invocation","value":{"target":{"type":"Class","value":"GREYActions"},"method":"actionForSetPickerColumn:toValue:","args":[{"type":"NSInteger","value":0},{"type":"NSString","value":"Bar"}]}}]},"messageId":6}
 onMessage: {"type":"testFailed","messageId":6,"params":{"details":"An action failed. Please refer to the error trace below.\nException with Action: {\n  \"Action Name\" : \"Set picker column 0 to value 'Bar'\",\n  \"Element Matcher\" : \"((kindOfClass('UIPickerView') && !(kindOfClass('RCTScrollView'))) || (kindOfClass('UIScrollView') && ((kindOfClass('UIView') || respondsToSelector(accessibilityContainer)) && ancestorThatMatches((kindOfClass('UIPickerView') && kindOfClass('RCTScrollView'))))))\"\n}\n\nError Trace: [\n  {\n    \"Description\" : \"UIPickerView does not contain desired value!\",\n    \"Error Domain\" : \"com.google.earlgrey.ElementInteractionErrorDomain\",\n    \"Error Code\" : \"2\",\n    \"File Name\" : \"GREYPickerAction.m\",\n    \"Function Name\" : \"-[GREYPickerAction perform:error:]\",\n    \"Line\" : \"120\"\n  }\n]"}}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions