If you do a lot of iOS testing using Appium, and have requirements especially for user flows that involve rotating the device to a different screen orientation, you might have noticed that screenshots retrieved by Appium in these cases might be incorrectly rotated. That is, the screenshot might not match the visible orientation of the device. This can be especially troublesome if you are using image-based testing, because Appium uses the coordinates from the screenshot to enable you to interact with found image regions!
Unfortunately, some of the time the screenshot comes back rotated incorrectly, Appium is not at fault; in these cases, XCUITest is just doing its thing, and Appium doesn't know whether the image is correct or not (it's not peeking at the "contents" of the screenshot to check that it's correct). But if you find yourself in this situation as a test author, you know what the screenshot is supposed to look like, you know which orientation your device is in, and you can tell Appium which orientation you want it to use for screenshots!
The screenshotOrientation setting
To accomplish this we make use of Appium's Settings API, and specifically a setting (released in Appium 1.17) called screenshotOrientation. There are 5 possible values this setting can take:
- auto: don't enforce any screenshot orientation. Just pass along the screenshot given by XCUITest.
- portrait: enforce portrait orientation for the screenshot.
- portraitUpsideDown: enforce the "upside-down" orientation for the screenshot.
- landscapeRight: enforce a landscape (turned to the right) orientation.
- landscapeLeft: enforce a landscape (turned to the left) orientation.
The way we tell Appium to use a particular value is (in Java) with the driver.setSetting command:
Calling this will set the screenshot orientation value for the duration of the Appium session (or until I choose to call setSetting again with a different value).
I was able to see this setting in action by writing a test that first turns a device to landscape mode, and then attempts to take a screenshot. If, before I start the test, I rotated the device manually, but in the opposite direction to the one Appium would normally rotate it (i.e., if I rotate it left), then I noticed that Appium's screenshots came back upside down!
Anyway, in this case, including the setting of the screenshotOrientation value enabled me to guarantee the screenshot would always come back in the correct orientation. Check out the full example below (and as always, the code is up on GitHub too: