The crash occurs because ViewInspector's precondition is not safeguarded against external manipulation during testing. Once the static window is initialized and set as the keyWindow, it becomes accessible to other tests, leading to potential crashes.
The following example demonstrates how to reproduce the crash (tested in Xcode 15.4, Simulator iOS 17.5):
import SwiftUI
import ViewInspector
import XCTest
final class ViewInspectorCrash: XCTestCase {
func testViewInspectorCrash() {
let view = Text("Crash")
// This triggers the one-time creation of ViewHosting.window
ViewHosting.host(view: view)
// The created window is now the keyWindow and can be accessed and manipulated by any other test
UIApplication.shared.keyWindow?.rootViewController = nil
// Manipulation from another test will lead to a crash:
ViewHosting.host(view: view)
}
}
Each test execution should be isolated and safe from external interference (ensuring the static window/window.rootViewController is reset or properly cleaned or implementing checks to verify the integrity of the keyWindow before it is used).
Description of the Issue
The crash occurs because ViewInspector's precondition is not safeguarded against external manipulation during testing. Once the
static window
is initialized and set as thekeyWindow
, it becomes accessible to other tests, leading to potential crashes.https://github.com/nalexn/ViewInspector/blob/21a2ff9e75e66eb97e5f1a35a181e20cd55b1fe2/Sources/ViewInspector/ViewHosting.swift#L136-L145
The crash itself will be triggered here: https://github.com/nalexn/ViewInspector/blob/21a2ff9e75e66eb97e5f1a35a181e20cd55b1fe2/Sources/ViewInspector/ViewHosting.swift#L161-L163
Steps to Reproduce
The following example demonstrates how to reproduce the crash (tested in Xcode 15.4, Simulator iOS 17.5):
Each test execution should be isolated and safe from external interference (ensuring the
static window
/window.rootViewController
is reset or properly cleaned or implementing checks to verify the integrity of thekeyWindow
before it is used).