// // BaseUITestCase.swift // PlantGuideUITests // // Base class for all PlantGuide UI tests. // Provides deterministic launch, fixture control, and shared helpers. // import XCTest /// Base class every UI test class should inherit from. /// /// Provides: /// - Deterministic `app` instance with clean lifecycle /// - Convenience launchers for clean state, mock data, offline /// - Tab navigation via `navigateToTab(_:)` /// - Implicit `waitForLaunch()` after every launch helper class BaseUITestCase: XCTestCase { // MARK: - Properties /// The application under test. Reset for each test method. var app: XCUIApplication! // MARK: - Lifecycle override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false app = XCUIApplication() } override func tearDownWithError() throws { app = nil try super.tearDownWithError() } // MARK: - Launch Helpers /// Launches with a fresh database and no prior state. func launchClean() { app.launchArguments += [ LaunchConfigKey.uiTesting, LaunchConfigKey.cleanState, LaunchConfigKey.skipOnboarding ] app.launchEnvironment[LaunchConfigKey.isUITesting] = "YES" app.launch() XCTAssertTrue(app.waitForLaunch(timeout: 15), "App did not launch (clean)") } /// Launches with mock plants and care data pre-populated. func launchWithMockData(plantCount: Int = 5) { app.launchArguments += [ LaunchConfigKey.uiTesting, LaunchConfigKey.mockData, LaunchConfigKey.skipOnboarding ] app.launchEnvironment[LaunchConfigKey.isUITesting] = "YES" app.launchEnvironment[LaunchConfigKey.useMockData] = "YES" app.launchEnvironment["MOCK_PLANT_COUNT"] = String(plantCount) app.launch() XCTAssertTrue(app.waitForLaunch(timeout: 15), "App did not launch (mock data)") } /// Launches simulating no network. func launchOffline() { app.launchArguments += [ LaunchConfigKey.uiTesting, LaunchConfigKey.offlineMode, LaunchConfigKey.skipOnboarding ] app.launchEnvironment[LaunchConfigKey.isUITesting] = "YES" app.launchEnvironment[LaunchConfigKey.isOfflineMode] = "YES" app.launch() XCTAssertTrue(app.waitForLaunch(timeout: 15), "App did not launch (offline)") } // MARK: - Tab Navigation /// Taps a tab by its label (use `UITestID.TabBar.*`). func navigateToTab(_ tabLabel: String) { let tab = app.tabBars.buttons[tabLabel] XCTAssertTrue(tab.waitForExistence(timeout: 10), "Tab '\(tabLabel)' not found") tab.tap() } }