// // BlackjackUITests.swift // BlackjackUITests // // Created by Matt Bruce on 12/17/25. // import XCTest final class BlackjackUITests: XCTestCase { var app: XCUIApplication! override func setUpWithError() throws { // Put setup code here. This method is called before the invocation of each test method in the class. // In UI tests it is usually best to stop immediately when a failure occurs. continueAfterFailure = false app = XCUIApplication() app.launchArguments = ["UI-TESTING"] // In UI tests it's important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. } override func tearDownWithError() throws { // Put teardown code here. This method is called after the invocation of each test method in the class. app = nil } @MainActor func testExample() throws { // UI tests must launch the application that they test. app.launch() // Use XCTAssert and related functions to verify your tests produce the correct results. } // MARK: - UI Navigation Tests @MainActor func testAppLaunches() throws { app.launch() XCTAssertTrue(app.exists, "App should launch successfully") } @MainActor func testTopBarElements() throws { app.launch() // Wait for the app to load let balanceText = app.staticTexts.matching(identifier: "balance").firstMatch XCTAssertTrue(balanceText.waitForExistence(timeout: 2), "Balance should be visible") // Check settings button exists let settingsButton = app.buttons.matching(identifier: "settings").firstMatch XCTAssertTrue(settingsButton.exists, "Settings button should exist") // Check help button exists let helpButton = app.buttons.matching(identifier: "help").firstMatch XCTAssertTrue(helpButton.exists, "Help button should exist") // Check stats button exists let statsButton = app.buttons.matching(identifier: "stats").firstMatch XCTAssertTrue(statsButton.exists, "Stats button should exist") } @MainActor func testSettingsSheet() throws { app.launch() // Find and tap settings button let settingsButton = app.buttons.matching(identifier: "settings").firstMatch XCTAssertTrue(settingsButton.waitForExistence(timeout: 2), "Settings button should exist") settingsButton.tap() // Wait for settings sheet to appear let settingsSheet = app.scrollViews.firstMatch XCTAssertTrue(settingsSheet.waitForExistence(timeout: 2), "Settings sheet should appear") // Check for some expected elements in settings XCTAssertTrue(app.staticTexts["Table Limits"].waitForExistence(timeout: 1) || app.staticTexts["Game Settings"].waitForExistence(timeout: 1), "Settings content should be visible") // Close settings (tap outside or dismiss button) if app.buttons["Done"].exists { app.buttons["Done"].tap() } else { // Tap outside to dismiss app.coordinate(withNormalizedOffset: CGVector(dx: 0.1, dy: 0.1)).tap() } } @MainActor func testHelpSheet() throws { app.launch() // Find and tap help button let helpButton = app.buttons.matching(identifier: "help").firstMatch XCTAssertTrue(helpButton.waitForExistence(timeout: 2), "Help button should exist") helpButton.tap() // Wait for help sheet to appear let helpSheet = app.scrollViews.firstMatch XCTAssertTrue(helpSheet.waitForExistence(timeout: 2), "Help sheet should appear") // Check for rules content XCTAssertTrue(app.staticTexts["Rules"].exists || app.staticTexts["How to Play"].exists, "Rules content should be visible") } // MARK: - Betting Tests @MainActor func testChipSelector() throws { app.launch() // Wait for chip selector to appear let chipSelector = app.otherElements["chip-selector"] XCTAssertTrue(chipSelector.waitForExistence(timeout: 2) || app.buttons.matching(NSPredicate(format: "label CONTAINS '$'")).count > 0, "Chip selector should be visible") // Find a chip button (they should have $ in the label) let chipButtons = app.buttons.matching(NSPredicate(format: "label CONTAINS '$'")) XCTAssertGreaterThan(chipButtons.count, 0, "Should have chip buttons") } @MainActor func testPlaceBet() throws { app.launch() // Wait for betting area sleep(1) // Find deal button (should be disabled initially) let dealButton = app.buttons["Deal"] XCTAssertTrue(dealButton.waitForExistence(timeout: 2), "Deal button should exist") // Initially deal button should be disabled XCTAssertFalse(dealButton.isEnabled, "Deal button should be disabled before bet") // Tap on betting zone let bettingZone = app.otherElements["betting-zone"] if bettingZone.exists { bettingZone.tap() // Deal button should now be enabled (or still disabled if bet is below minimum) // We can't reliably test this without knowing the bet amount vs minimum } } @MainActor func testClearButton() throws { app.launch() // Wait and place a bet by tapping betting zone sleep(1) let bettingZone = app.otherElements["betting-zone"] if bettingZone.exists { bettingZone.tap() } // Find clear button let clearButton = app.buttons["Clear"] if clearButton.exists { clearButton.tap() // After clearing, deal button should be disabled again let dealButton = app.buttons["Deal"] XCTAssertFalse(dealButton.isEnabled, "Deal button should be disabled after clear") } } // MARK: - Gameplay Tests @MainActor func testDealCards() throws { app.launch() sleep(1) // Place a bet by tapping betting zone multiple times to ensure we meet minimum let bettingZone = app.otherElements["betting-zone"] if bettingZone.exists { for _ in 1...5 { bettingZone.tap() } } // Find and tap deal button let dealButton = app.buttons["Deal"] if dealButton.waitForExistence(timeout: 2) && dealButton.isEnabled { dealButton.tap() // Wait for cards to be dealt sleep(2) // After dealing, we should see hit/stand buttons or a result let hitButton = app.buttons["Hit"] let standButton = app.buttons["Stand"] let newRoundButton = app.buttons["New Round"] XCTAssertTrue(hitButton.exists || standButton.exists || newRoundButton.exists, "Should see action buttons after dealing") } } @MainActor func testLaunchPerformance() throws { // This measures how long it takes to launch your application. measure(metrics: [XCTApplicationLaunchMetric()]) { XCUIApplication().launch() } } }