← Back to index

SpotsUITests

SpotsUITests
CodeWhat It DoesHow It Does It
▶ IMPORTS
import XCTestFramework importsImports XCTest.
final class SpotsUITests: XCTestCase { var app: XCUIApplication! override func setUpWithError() throws { continueAfterFailure = false app = XCUIApplication() // Only launch once — reuse the running instance for subsequent tests if app.state != .runningForeground { app.launch() } // Dismiss any sheet left open by the previous test let cancel = app.navigationBars.buttons["Cancel"] if cancel.exists { cancel.tap() } } override func tearDownWithError() throws { // Don't terminate — keep the app alive for the next test app = nil } // MARK: - Tab Bar func testTabBarHasFiveTabs() throws { let tabBar = app.tabBars.firstMatch XCTAssertTrue(tabBar.exists, "Tab bar should exist") XCTAssertEqual(tabBar.buttons.count, 5, "Tab bar should have exactly 5 tabs") } func testAllExpectedTabsExist() throws { let tabBar = app.tabBars.firstMatch XCTAssertTrue(tabBar.buttons["Map"].exists, "Map tab should exist") XCTAssertTrue(tabBar.buttons["Shops"].exists, "Shops tab should exist") XCTAssertTrue(tabBar.buttons["Sites"].exists, "Sites tab should exist") XCTAssertTrue(tabBar.buttons["Shows"].exists, "Shows tab should exist") XCTAssertTrue(tabBar.buttons["Food"].exists, "Food tab should exist") } func testNoMoreButtonInTabBar() throws { XCTAssertFalse(app.tabBars.firstMatch.buttons["More"].exists, "Tab bar should not have a 'More' button") } func testTabSwitching() throws { let tabBar = app.tabBars.firstMatch tabBar.buttons["Food"].tap() XCTAssertTrue(app.navigationBars["Food"].exists || app.staticTexts["Food"].exists, "Food tab content should be visible") tabBar.buttons["Shows"].tap() XCTAssertTrue(app.navigationBars["Shows"].exists || app.staticTexts["Shows"].exists, "Shows tab content should be visible") tabBar.buttons["Shops"].tap() XCTAssertTrue(app.navigationBars["Shops"].exists || app.staticTexts["Shops"].exists, "Shops tab content should be visible") tabBar.buttons["Sites"].tap() XCTAssertTrue(app.navigationBars["Sites"].exists || app.staticTexts["Sites"].exists, "Sites tab content should be visible") } // MARK: - Search func testSearchBarExistsOnFoodTab() throws { app.tabBars.firstMatch.buttons["Food"].tap() // The app uses a TextField (not a system SearchBar) for filtering let searchField = app.textFields.firstMatch XCTAssertTrue(searchField.exists, "Search field should exist on Food tab") } func testSearchBarExistsOnShowsTab() throws { app.tabBars.firstMatch.buttons["Shows"].tap() let searchField = app.textFields.firstMatch XCTAssertTrue(searchField.exists, "Search field should exist on Shows tab") } func testSearchBarExistsOnShopsTab() throws { app.tabBars.firstMatch.buttons["Shops"].tap() let searchField = app.textFields.firstMatch XCTAssertTrue(searchField.exists, "Search field should exist on Shops tab") } func testTypingInSearchFilters() throws { app.tabBars.firstMatch.buttons["Food"].tap() let searchField = app.textFields.firstMatch guard searchField.exists else { return } searchField.tap() searchField.typeText("pizza") XCTAssertEqual(searchField.value as? String, "pizza", "Search field should contain typed text") } // MARK: - Add Entry Form func testAddEntryButtonExistsOnFoodTab() throws { app.tabBars.firstMatch.buttons["Food"].tap() let addButton = app.navigationBars.buttons.matching( NSPredicate(format: "label CONTAINS 'Add' OR label == '+'") ).firstMatch XCTAssertTrue(addButton.exists, "Add entry button should exist on Food tab") } func testAddFoodEntryFormOpens() throws { app.tabBars.firstMatch.buttons["Food"].tap() let addButton = app.navigationBars.buttons.matching( NSPredicate(format: "label CONTAINS 'Add' OR label == '+'") ).firstMatch guard addButton.exists else { return } addButton.tap() XCTAssertTrue( app.navigationBars["Add"].exists || app.staticTexts["Add"].exists, "Add entry form should open" ) } func testAddFoodEntryFormHasNameField() throws { app.tabBars.firstMatch.buttons["Food"].tap() let addButton = app.navigationBars.buttons.matching( NSPredicate(format: "label CONTAINS 'Add' OR label == '+'") ).firstMatch guard addButton.exists else { return } addButton.tap() XCTAssertTrue(app.textFields["Name"].exists, "Name field should exist in Add form") } func testAddFoodEntryRequiresName() throws { app.tabBars.firstMatch.buttons["Food"].tap() let addButton = app.navigationBars.buttons.matching( NSPredicate(format: "label CONTAINS 'Add' OR label == '+'") ).firstMatch guard addButton.exists else { return } addButton.tap() let saveButton = app.navigationBars.buttons["Save"] if saveButton.exists { XCTAssertFalse(saveButton.isEnabled, "Save button should be disabled when name is empty") } } func testAddFoodEntryCanBeSaved() throws { app.tabBars.firstMatch.buttons["Food"].tap() let addButton = app.navigationBars.buttons.matching( NSPredicate(format: "label CONTAINS 'Add' OR label == '+'") ).firstMatch guard addButton.exists else { return } addButton.tap() let nameField = app.textFields["Name"] guard nameField.exists else { XCTFail("Name field not found"); return } nameField.tap() nameField.typeText("Test Restaurant") let saveButton = app.navigationBars.buttons["Save"] XCTAssertTrue(saveButton.isEnabled, "Save button should be enabled when name is filled") saveButton.tap() XCTAssertFalse(app.navigationBars["Add"].exists, "Add form should dismiss after saving") } func testCancelAddEntryForm() throws { app.tabBars.firstMatch.buttons["Food"].tap() let addButton = app.navigationBars.buttons.matching( NSPredicate(format: "label CONTAINS 'Add' OR label == '+'") ).firstMatch guard addButton.exists else { return } addButton.tap() XCTAssertTrue(app.navigationBars["Add"].exists, "Add form should be open") let cancelButton = app.navigationBars.buttons["Cancel"] XCTAssertTrue(cancelButton.exists, "Cancel button should exist") cancelButton.tap() XCTAssertFalse(app.navigationBars["Add"].exists, "Add form should dismiss after cancel") } func testAddShowEntryFormOpens() throws { app.tabBars.firstMatch.buttons["Shows"].tap() let addButton = app.navigationBars.buttons.matching( NSPredicate(format: "label CONTAINS 'Add' OR label == '+'") ).firstMatch guard addButton.exists else { return } addButton.tap() XCTAssertTrue( app.navigationBars["Add"].exists || app.staticTexts["Add"].exists, "Add form should open from Shows tab" ) XCTAssertTrue( app.staticTexts["Show Information"].exists || app.staticTexts["SHOW INFORMATION"].exists, "Add form from Shows tab should show Show Information section" ) } // MARK: - Map Tab func testMapTabOpens() throws { app.tabBars.firstMatch.buttons["Map"].tap() XCTAssertTrue(app.tabBars.firstMatch.buttons["Map"].isSelected, "Map tab should be selected after tapping") } // MARK: - Empty State func testFoodTabOpens() throws { app.tabBars.firstMatch.buttons["Food"].tap() XCTAssertTrue(app.tabBars.firstMatch.buttons["Food"].isSelected, "Food tab should be selected") } func testShowsTabOpens() throws { app.tabBars.firstMatch.buttons["Shows"].tap() XCTAssertTrue(app.tabBars.firstMatch.buttons["Shows"].isSelected, "Shows tab should be selected") } func testSitesTabOpens() throws { app.tabBars.firstMatch.buttons["Sites"].tap() XCTAssertTrue(app.tabBars.firstMatch.buttons["Sites"].isSelected, "Sites tab should be selected") } func testShopsTabOpens() throws { app.tabBars.firstMatch.buttons["Shops"].tap() XCTAssertTrue(app.tabBars.firstMatch.buttons["Shops"].isSelected, "Shops tab should be selected") } }`SpotsUITests` classDefines the `SpotsUITests` class. Conforms to XCTestCase.