I'm using Network framework for communication between devices. The first time I instantiate an NWBrowser, it will prompt the user with a popup that says:
Allow <app name> to find devices on local networks?
The problem is, once I upgraded from Xcode 15.4 to Xcode 16.4, the popup doesn't appear; it says in the debug window:
nw_browser_fail_on_dns_error_locked [B1] nw_browser_dns_service_browse_callback failed: PolicyDenied(18,446,744,073,709,486,046)
I do have the info.plist keys Privacy-Local Network Usage Description (NSLocalNetworkUsageDescription) and Bonjour Services (NSBonjourServices) so it's not that.
Also, It still works on a real device.
I think something changed with Xcode 16 that tightened the security on a simulator, or maybe disabled Network framework entirely. It's not the firewall on my computer because that is turned off. I'm using an M1 MacBook Pro.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
To me this is a clear bug (and I submitted it as one: FB11813464), unless there's something I'm missing?
When the confirmationDialog is showing on an iPad, and you click outside it, the confirmationDialog disappears, as it should. This is the same behavior as the popover in UIKit; the outside-click acts in lieu of a Cancel button when you're on an iPad. HOWEVER, the outside-click also triggers behaviors elsewhere on the screen, for ex if the place you click has a Button, or an onTapGesture listener. As demonstrated in this picture, when the confirmationDialog is showing, and you click on this button, the confirmationDialog disappears, which is correct, but the print action also runs, which shouldn't.
I’m running Xcode 14.1, targeting iOS 16.1, and running on an iPad 10th gen simulator.
This example is pretty contrived, but it illustrates the behavior. I know you can use .accessibilityIdentifier to uniquely identify a control, but I'm just trying to better understand the interplay between XCUIElement and XCUIElementQuery.
Let's say you have an app like this:
import SwiftUI
struct ContentView: View {
@State var showRedButton = true
var body: some View {
VStack {
if showRedButton {
Button("Click me") {
showRedButton = false
}
.background(.red)
}
else {
HStack {
Button("Click me") {
showRedButton = true
}
.background(.blue)
Spacer()
}
}
}
}
}
And you are UI testing like this:
import XCTest
final class MyAppUITests: XCTestCase {
func testExample() throws {
let app = XCUIApplication()
app.launch()
print(app.debugDescription)
// At this point, the Element subtree shows
// a single Button:
// Button, 0x14e40d290,
// {{162.3, 418.3}, {65.3, 20.3}}, label: 'Click me'
let btn = app.buttons["Click me"]
// This tap makes the red button disappear
// and shows the blue button
btn.tap()
print(app.debugDescription)
// Now, the Element subtree shows a single Button
// that has a different ID
// and different x-y coordinates:
// Button, 0x15dc12e50,
// {{0.0, 418.3}, {65.3, 20.3}}, label: 'Click me'
// This tap now works on the blue button??
// Without requerying?
btn.tap()
print(app.debugDescription)
// The red button reappears,
// but with a different ID (which makes sense).
}
}
Why does the second tap work, even though it's a different control? This must mean that SwiftUI is automatically re-running the XCUIElementQuery to find the button that matches "Click me". Apparently the variable btn isn't linked to the control with the ID 0x14e40d290. Does this mean XCUIElement actually represents an XCUIElementQuery?
I expected it to require me to explicitly re-run the query like this,
btn = app.buttons["Click me"]
prior to running the 2nd tap, or the tap would've said that btn was no longer available.
The final print of the Element subtree shows that the red button has a
different ID now. This makes sense, because when SwiftUI redraws the
red button, it's not the same instance as the last time. This is
explained well in the WWDC videos. Nevertheless, at the moment I
connected the variable "btn" to the control, I thought there was a
tighter affiliation. Maybe UI testing has to behave this way because
SwiftUI redraws controls so frequently?