// // OnboardingTests.swift // Tests iOS // // Onboarding flow completion and non-repetition tests. // import XCTest final class OnboardingTests: BaseUITestCase { override var seedFixture: String? { "empty" } override var skipOnboarding: Bool { false } /// TC-120: Complete the full onboarding flow. func testOnboarding_CompleteFlow() { // Welcome screen should appear let welcomeText = app.staticTexts.matching( NSPredicate(format: "label CONTAINS[cd] %@", "Welcome to Feels") ).firstMatch XCTAssertTrue( welcomeText.waitForExistence(timeout: 10), "Welcome screen should appear on first launch" ) captureScreenshot(name: "onboarding_welcome") // Swipe to Time screen app.swipeLeft() captureScreenshot(name: "onboarding_time") // Swipe to Day screen app.swipeLeft() // Select "Today" if the button exists let todayButton = app.descendants(matching: .any) .matching(identifier: "onboarding_day_today") .firstMatch if todayButton.waitForExistence(timeout: 3) { todayButton.tap() } captureScreenshot(name: "onboarding_day") // Swipe to Style screen app.swipeLeft() captureScreenshot(name: "onboarding_style") // Swipe to Subscription screen app.swipeLeft() captureScreenshot(name: "onboarding_subscription") // Tap "Maybe Later" to complete onboarding let skipButton = app.descendants(matching: .any) .matching(identifier: "onboarding_skip_button") .firstMatch XCTAssertTrue( skipButton.waitForExistence(timeout: 5), "Skip/Maybe Later button should exist on subscription screen" ) skipButton.tap() // After onboarding, the tab bar should appear let tabBar = app.tabBars.firstMatch XCTAssertTrue( tabBar.waitForExistence(timeout: 10), "Tab bar should be visible after completing onboarding" ) captureScreenshot(name: "onboarding_complete") } /// TC-121: After completing onboarding, relaunch should go directly to Day view. func testOnboarding_DoesNotRepeatAfterCompletion() { // First, complete onboarding let welcomeText = app.staticTexts.matching( NSPredicate(format: "label CONTAINS[cd] %@", "Welcome to Feels") ).firstMatch if welcomeText.waitForExistence(timeout: 5) { // Swipe through all screens app.swipeLeft() // -> Time app.swipeLeft() // -> Day app.swipeLeft() // -> Style app.swipeLeft() // -> Subscription let skipButton = app.descendants(matching: .any) .matching(identifier: "onboarding_skip_button") .firstMatch if skipButton.waitForExistence(timeout: 5) { skipButton.tap() } } // Wait for main app to load let tabBar = app.tabBars.firstMatch XCTAssertTrue( tabBar.waitForExistence(timeout: 10), "Tab bar should appear after onboarding" ) // Terminate and relaunch (keeping --reset-state OUT to preserve onboarding completion) app.terminate() // Relaunch WITHOUT reset-state so onboarding completion is preserved let freshApp = XCUIApplication() freshApp.launchArguments = ["--ui-testing", "--disable-animations", "--bypass-subscription", "--skip-onboarding"] freshApp.launch() // Tab bar should appear immediately (no onboarding) let freshTabBar = freshApp.tabBars.firstMatch XCTAssertTrue( freshTabBar.waitForExistence(timeout: 10), "Tab bar should appear immediately on relaunch (no onboarding)" ) // Welcome screen should NOT appear let welcomeAgain = freshApp.staticTexts.matching( NSPredicate(format: "label CONTAINS[cd] %@", "Welcome to Feels") ).firstMatch XCTAssertFalse( welcomeAgain.waitForExistence(timeout: 2), "Onboarding should not appear on second launch" ) captureScreenshot(name: "no_onboarding_on_relaunch") } }