Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help needed: BackItem broken for UITests #35

Open
luke-riu opened this issue Feb 18, 2021 · 6 comments
Open

Help needed: BackItem broken for UITests #35

luke-riu opened this issue Feb 18, 2021 · 6 comments

Comments

@luke-riu
Copy link

Since bringing this (fantastic) library in, my UI test has failed when trying to press the back button in the navigation bar. Do you know if there is a trick to getting it tappable at all?
I used to have app.navigationBars.buttons.element(boundBy: 0).tap(), but that is now failing with

Failed to synthesize event: Failed to scroll to visible (by AX action) Button, label: 'Back', error: Error kAXErrorCannotComplete performing AXAction 2003 on element AX element pid: 15737, elementOrHash.elementID: 105553178871296.256. (Underlying Error: Error kAXErrorCannotComplete performing AXAction 2003 on element AX element pid: 15737, elementOrHash.elementID: 105553178871296.256)

Any help appreciated.
Thanks a lot
Luke

@Pircate
Copy link
Owner

Pircate commented Mar 4, 2021

Which version are you using?

@luke-riu
Copy link
Author

luke-riu commented Mar 4, 2021

My podlock file shows 1.15.0

@Pircate
Copy link
Owner

Pircate commented Mar 4, 2021

Can I have a look at your code?

@luke-riu
Copy link
Author

luke-riu commented Mar 4, 2021

Sure.
Ignore the custom Colour., Fonts. and Image.. These are SwiftGen structs for UIColor, UIFont and UIImage

In my UINavigationController subclass, I have

private func setupNavigationBar() {
    self.navigation.configuration.isEnabled = true
    self.navigation.configuration.titleTextAttributes = [
      .foregroundColor: Colour.text
    ]
    self.navigation.configuration.barTintColor = Colour.layer1
    self.navigation.configuration.isTranslucent = false
    self.navigation.configuration.isHidden = true
    self.navigation.configuration.backItem = UINavigationController
      .Configuration
      .BackItem(style: .image(Image.back),
                tintColor: Colour.text)
    
  }

The homepage has

private fund setupNavigationBar() {
    self.navigation.bar.isHidden = false
    
    self.navigation.bar.prefersLargeTitles = false
    self.navigation.item.largeTitleDisplayMode = .never
    self.navigation.bar.additionalHeight = 20
    
    // acts as a bit of a skirt to keep the label off the bottom of the nav bar
    let navFooter = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 18))
    navFooter.backgroundColor = Colour.layer1
    self.navigation.bar.additionalView = navFooter
    
     // title
    let label = UILabel(frame: .zero)
    label.text = "Explore"
    label.font = Fonts.h2
    self.navigation.item.leftBarButtonItem = UIBarButtonItem(customView: label)

     // search button
    let imageview = UIImageView()
    imageview.image = Image.search.withRenderingMode(.alwaysTemplate)
    imageview.tintColor = Colour.text
    
    let searchButton = UIButton(type: .custom)
    searchButton.addTarget(buttonTarget, action: buttonSelector, for: .touchUpInside)
    searchButton.addSubview(imageview)
    searchButton.accessibilityIdentifier = "nav_button"
    
   // snapkit constraints
    imageview.snp.makeConstraints { (make) in
      make.width.height.equalTo(24)
      make.left.right.equalToSuperview()
      make.top.bottom.equalToSuperview().inset(10)
    }
    
    self.navigation.item.rightBarButtonItem = UIBarButtonItem(customView: searchButton)
}

Before the next view controller is pushed, I call

trendingViewController.navigationItem.title = "Trending"

then in viewDidLoad(animated:) on that view controller, I call

    self.navigation.bar.prefersLargeTitles = true
    self.navigation.item.largeTitleDisplayMode = .always

Then, my UI tests goes something like this

    let app = XCUIApplication()
    // tap cell to get into view controller
    // test element exists
    app.navigationBars.buttons.element(boundBy: 0).tap() // <-- fails

Thanks

@Pircate
Copy link
Owner

Pircate commented Mar 4, 2021

navigation.bar.backBarButtonItem = .init(style: .image(image))

Try using it in trendingViewController

@luke-riu
Copy link
Author

luke-riu commented Mar 4, 2021

Sadly not made any difference. Putting a breakpoint in my test, when I type into the console

po app.navigationBars.buttons

I get the following output

Find: Target Application 'com.my.app'
  Output: {
    Application, pid: 18209, label: 'App'
  }
  ↪︎Find: Descendants matching type NavigationBar
    Output: {
      NavigationBar, {{0.0, 47.0}, {428.0, 96.0}}, identifier: 'Trending'
      NavigationBar, {{0.0, 47.0}, {428.0, 96.0}}, identifier: 'Trending'
    }
    ↪︎Find: Descendants matching type Button
      Output: {
        Button, {{0.0, 47.0}, {55.7, 44.0}}, label: 'Back'
        Button, {{12.0, 47.0}, {36.0, 44.0}}
      }

I'm sure you'll know better than me, but I think it a bit weird there are two buttons, one which says "Back". Either way, when doing either po app.navigationBars.buttons.element(boundBy: 0).isHittable is false for both 0 and 1.
I'm not sure if that's helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants