I want to be able to tap on one of the buttons in the bottom nav bar to navigate to each tab of my app in order to take screenshots. I set it all up according to https://docs.fastlane.tools/getting-started/ios/screenshots/ and the screenshotting works successfully. The issue is I cannot figure out how to address the button. I assumed I would be able to just do something like this:
print(app.navigationBars)
But this returns the inscrutable:
<XCUIElementQuery: 0x600003b46b20>
I then thought to look at the hierarchical view of the app in XCode (as per How do I inspect the view hierarchy in iOS?), but for Flutter apps it just shows up with a bunch of black boxes with unhelpful names.
In general, how do I figure out how to address buttons as part of these UI tests for taking screenshots? Some are intuitive, like app.buttons["Search"]
, but others don’t work quite so easily, e.g. app.navigationBars["Revision"]
.
Other resources I’ve read include the following, but they weren’t super useful:
Thanks!
2
Answers
Pavlo's answer is what I ended up going with. I wanted to respond to this with a more complete guide explaining what to do.
First, add these
dev_dependencies
topubspec.yaml
:Then make a file called
test_driver/integration_driver.dart
like this:Then make a file called something like
integration_test/screenshot_test.dart
:You can then invoke it like this:
Make sure to first make the appropriate directories, like this:
There is currently an issue with Flutter / its testing deps that as of 2.10.4 means you have to alter the testing package: https://github.com/flutter/flutter/issues/91668. In short, make the following change to
packages/integration_test/ios/Classes/IntegrationTestPlugin.m
:You might need to run
flutter clean
after this.Now you're at the point where you can take screenshots!
As a bonus, this Python script will spin up a bunch of simulators / emulators for iOS and Android and drive the above integration test to take screenshots for all of them:
Note, if you try to take multiple screenshots on Android with this approach, you'll have a bad time. Check out https://github.com/flutter/flutter/issues/92381. The fix is still en route.
What you want is impossible. At least for now. Flutter UI is rendered as a game would render which is much deeper than regular iOs UI. Moreover, flutter has its own gestures framework – thus you won’t be able to correctly translate iOs gestures to flutter gestures(well you will be able but it will take too much effort). Also, native iOs UI testing framework(Xcode UI tests) is not supporting flutter and, I think, it will never will.
What you can do is look into flutter integration testing here and here. Because they are flutter native – you will be able to address UI via various different ways(by Keys, class name, widget properties, etc.). You will be able to interact with that UI also.
Regarding screenshots – officially they are not supported yet but there are other ways basically what you need to do is:
The code is not mine, it is from the link above, when I was trying to implement it some time ago way before that article – it was not working – maybe now it is – you have to try.
You can also look into golden testing for flutter here or here or just google it). There is even a library for that here.
Regarding taking screenshots via Fastlane – maybe it is possible while combining the approaches above with Fastlane scrips – I am not sure because it is quite unusual procedure, but you can try.