import XCTest /// UI tests for the dashboard: widgets, alerts, threat score, navigation. final class DashboardUITests: UITestBase { override class var scenario: UITestScenario { .populatedDashboard } // MARK: - Dashboard Loads with Widgets /// Verify the dashboard loads with all widget sections func testDashboardLoadsWithWidgets() { // Navigate to Dashboard tab (should be default) navigateToTab(.dashboard) // Verify key dashboard elements exist XCTAssertTrue(app.navigationBars["Dashboard"].waitForExistence(timeout: 5), "Dashboard navigation bar should exist") // Threat score section let threatScoreLabel = text("Threat Score") XCTAssertTrue(threatScoreLabel.waitForExistence(timeout: 3), "Threat Score label should be visible") XCTAssertTrue(text("Alerts").exists, "Alerts stat badge should be visible") XCTAssertTrue(text("Exposures").exists, "Exposures stat badge should be visible") XCTAssertTrue(text("Watched").exists, "Watched stat badge should be visible") // Recent Alerts section XCTAssertTrue(text("Recent Alerts").waitForExistence(timeout: 3), "Recent Alerts section should be visible") // Services section XCTAssertTrue(text("Services").exists, "Services section should be visible") // Quick Actions section XCTAssertTrue(text("Quick Actions").exists, "Quick Actions section should be visible") captureScreen(name: "DashboardWithWidgets") } // MARK: - Alert Tap Opens Detail View /// Verify tapping an alert navigates to the detail view func testTapAlertOpensDetailView() { navigateToTab(.dashboard) // Wait for alerts to load let alertTitle = text("Data Exposure Detected") guard alertTitle.waitForExistence(timeout: 5) else { XCTFail("Expected alert 'Data Exposure Detected' not found") return } // Tap the alert (it's inside a NavigationLink) alertTitle.tap() // Should navigate to alert detail (the navigation bar title changes) let detailExists = app.navigationBars.element(boundBy: 0).waitForExistence(timeout: 3) XCTAssertTrue(detailExists, "Alert detail view should open") captureScreen(name: "AlertDetail") } // MARK: - Threat Score Display /// Verify threat score displays and updates correctly func testThreatScoreUpdatesCorrectly() { navigateToTab(.dashboard) // With populatedDashboard scenario, we have mock alerts and exposures // The threat score should be visible let scoreExists = app.staticTexts.matching(NSPredicate(format: "label MATCHES '\\\\d+'")).element.exists XCTAssertTrue(scoreExists || app.staticTexts["0"].exists || app.staticTexts["100"].exists, "Threat score number should be visible") } // MARK: - Services Section on Dashboard /// Verify the services grid is visible on dashboard func testDashboardShowsServiceSummaries() { navigateToTab(.dashboard) // The services grid should show all 5 service names let serviceNames = ["DarkWatch", "VoicePrint", "SpamShield", "HomeTitle", "RemoveBrokers"] for name in serviceNames { XCTAssertTrue(text(name).exists, "Service '\(name)' should be visible on dashboard") } } // MARK: - Quick Actions /// Verify quick action buttons are present func testQuickActionsAreVisible() { navigateToTab(.dashboard) // Scroll down to make sure Quick Actions are visible scrollDown() let quickActions = ["Scan", "Alerts", "Profile", "Settings"] for action in quickActions { XCTAssertTrue(text(action).exists, "Quick action '\(action)' should be visible") } } // MARK: - Dashboard Tab Navigation /// Verify tab bar navigation works from dashboard func testTabNavigationFromDashboard() { navigateToTab(.dashboard) // Navigate to Services tab navigateToTab(.services) XCTAssertTrue(app.navigationBars["Services"].waitForExistence(timeout: 3), "Services screen should appear") // Navigate back to Dashboard navigateToTab(.dashboard) XCTAssertTrue(app.navigationBars["Dashboard"].waitForExistence(timeout: 3), "Dashboard should appear after switching back") // Navigate to Alerts tab navigateToTab(.alerts) XCTAssertTrue(app.navigationBars["Alerts"].waitForExistence(timeout: 3), "Alerts screen should appear") // Navigate to Settings tab navigateToTab(.settings) XCTAssertTrue(app.navigationBars["Settings"].waitForExistence(timeout: 3), "Settings screen should appear") } }