Can't access elements in browser which is opened from an app on iOS v26.0
Is there an existing issue for this?
- [x] I have searched the existing issues and didn't find mine.
Steps to reproduce
- Install iOS 26
- Launch a Simulator which iOS 26 e.g iPhone 17
- Build & install your App
- Run a Maestro flow
Actual results
In case the app opens a browser during the flow for example to enter login credentials to have a secure sign-in process with oauth, Maestro isn't able to detect any elements in the browser which was opened by the app.
Expected results
As in previous versions of iOS Maestro should be able to access the elements in the browser which was opened by the app.
About app
It is a native app built with expo and react native. Here are the versions:
- Expo: 52.0.39
- React Native: 0.77.2
The app isn't open source and therefore i cannot share a build or a reproducible sample. However i assume that the behaviour will be the same in other apps
About environment
- Java: OpenJDK 17
- MacBook M3 with MacOS 26
- Architecture: Arm Apple Silicon
Logs
Logs
Assertion is false: "Customer login" is visible
Assertion '"Customer login" is visible' failed. Check the UI hierarchy in debug artifacts to verify the element state and properties.
Possible causes:
- Element selector may be incorrect - check if there are similar elements with slightly different names/properties.
- Element may be temporarily unavailable due to loading state
- This could be a real regression that needs to be addressed
Maestro version
2.0.3
How did you install Maestro?
install script (https://get.maestro.mobile.dev)
Anything else?
No response
MAE-294 Can't access elements in browser which is opened from an app on iOS v26.0 Silly bot.
You don't have access to this workspace. Please contact a workspace admin for access. 😩
@dnsmob That's our internal tracker, so that we can view it alongside Cloud and Studio work. The comment is a necessary biproduct. You don't need access to that.
When you say
opens a browser
Do we mean a browser? Or is this a webview?
A way to reproduce this somewhere would be most helpful
We are experiencing the same issue with iOS 26. Our app’s login flow presents an in-app webview for authentication. For example, in Maestro Studio, the contents of the webview used to be “visible” to Maestro, allowing it to find individual elements when running on the iOS 18.4 simulator.
I have created a sample project where this issue can be reproduced: https://github.com/dornelas-atx/sample-app-with-webview
Here’s a screenshot of Maestro Studio with the app running on iOS 18.4:
Individual elements within the webview content are visible and tappable.
Here’s a screenshot of Maestro Studio with the app running on iOS 26:
The entire webview appears as a single visible element with a very strange identifier.
We are also facing the same facing issue for the SF safari web view controller on ios 26.0. For the time being as a workaround I am using
- inputText: "whatevertext"
- pressKey: Enter it is flaky, because there is no way to wait for the web view to load.
When you say
opens a browser
Do we mean a browser? Or is this a webview?
A way to reproduce this somewhere would be most helpful
I mean a webview yes. The description from @dornelas-atx is exactly the problem i have
We are also experiencing this issue with ios26, and are sticking to testing on ios18 meanwhile.
I've done some further investigation, as this issue continues to block our migration to Xcode 26 / iOS 26.
In my example app, I added some standard Xcode UI tests. While recording events, I noticed that tapping the SafariViewController causes a new XCUIApplication to be created with the bundle identifier "com.apple.SafariViewService". This led me to believe that, in iOS 26, webviews might now appear in a different application container.
To dig deeper, I reviewed your Maestro XC UI test runner and started debugging the foregroundApplication in ViewHierarchyHandler.swift to check for webview elements. I observed that the webview count was empty, and the AXElements returned from the server’s /viewHierarchy request did not include anything related to the webview.
To test my theory, I modified the foregroundApp to hardcode the use of XCUIApplication(bundleIdentifier: "com.apple.SafariViewService") while the webview was presented in my example app. With this change, I was finally able to see the webview elements in the response.
Based on this, I made the following changes in ViewHierarchyHandler.swift (line 69):
// Check for Safari web views in iOS 16+ (moved to separate service)
let safariWebViewHierarchy = getSafariWebViewHierarchy()
let keyboard = app.keyboards.firstMatch
if (excludeKeyboardElements && keyboard.exists) {
let filteredChildren = appHierarchy.filterAllChildrenNotInKeyboardBounds(keyboard.frame)
return AXElement(children: [
springboardHierarchy,
AXElement(children: filteredChildren),
safariWebViewHierarchy,
].compactMap { $0 })
}
return AXElement(children: [
springboardHierarchy,
appHierarchy,
safariWebViewHierarchy,
].compactMap { $0 })
And added the following helper function:
private func getSafariWebViewHierarchy() -> AXElement? {
// Check for Safari web views in iOS 26+ (moved to separate SafariViewService)
// Use runtime version check
let systemVersion = ProcessInfo.processInfo.operatingSystemVersion
let isIOS26OrLater = systemVersion.majorVersion >= 26
guard isIOS26OrLater else {
return nil
}
let safariWebService = XCUIApplication(bundleIdentifier: "com.apple.SafariViewService")
guard safariWebService.webViews.count > 0 else {
return nil
}
do {
let safariHierarchy = try elementHierarchy(xcuiElement: safariWebService)
logger.info("Successfully retrieved Safari web view hierarchy with \(safariWebService.webViews.count) web views")
return safariHierarchy
} catch {
logger.error("Failed to fetch Safari web view hierarchy: \(error)")
return nil
}
}
After recompiling the Maestro tooling locally and running Maestro Studio, I was finally able to find and inspect elements in the presented webview again.
I can try to provide a PR for this, but wanted to check with you first to see if you think this is the right approach. It works for us so far, though I still need to test it in our CI environment with our other dozen tests. I’ll report back if I encounter any issues or caveats with this solution.
Let me know your thoughts!
@dornelas-atx really nice work on this! Approach sounds solid - if you open a PR we will review it!
The fix worked well in all my local testing on my M4 Pro machine. However, after updating our CI to use Xcode 26 and my forked version of Maestro with these fixes, I was disappointed to see the test failing due to a Maestro server disconnection after the webview is presented Error: Failed to connect to / [0:0:0:0:0:0:0:1]:7001 I've noticed this server disconnects usually happens when the Maestro iOS test runner crashes.
Our CI runs on M1 hardware, so I wonder if this is a performance issue related to the complex hierarchy of the Safari web service. Before I contribute some fix to the Maestro tooling, I want to validate that it works in a more constrained environment.
same issue here.
Would be great to see PR/fix merged.
Thanks!
@Leland-Takamine A huge percentage of apps do this type of login flow. I don't mean to sound rude, but it's kind of crazy that a mobile.dev employee hasn't submitted a PR to fix this when iOS 26 has been out for months.
I don't mean to sound rude
A swing and a miss then 😂 We're a tiny team, with fewer engineers than I'm sure your org has. One of the things I love about open source is how I can contribute with my time and skill rather than my cash if I like a project and want it to succeed.
@Fishbowler @Leland-Takamine Is there any update on this issue since a PR has been opened?
It's literally number 1 on our queue of PRs to be reviewed. It'll be in the next Maestro release, which should be happening within the next week.
Great to hear! Been evaluating Maestro to see if we can migrate Plex over to your stack but this was a blocker. Looking forward to seeing this release go out.
@dornelas-atx Mind if I add your app to Maestro's e2e tests, so that when it's merged, it stays fixed?