diff --git a/Feedbridge.xcodeproj/project.pbxproj b/Feedbridge.xcodeproj/project.pbxproj index 2762692..3ae0704 100644 --- a/Feedbridge.xcodeproj/project.pbxproj +++ b/Feedbridge.xcodeproj/project.pbxproj @@ -45,6 +45,7 @@ 2FE5DCB129EE6107004B9AB4 /* AccountOnboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FE5DCAC29EE6107004B9AB4 /* AccountOnboarding.swift */; }; 2FF53D8D2A8729D600042B76 /* FeedbridgeStandard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FF53D8C2A8729D600042B76 /* FeedbridgeStandard.swift */; }; 35B62D5D2D80C20C0096904E /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35B62D5C2D80C20C0096904E /* SettingsView.swift */; }; + 35B62F7A2D8257EC0096904E /* AddBabyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35B62F792D8257E80096904E /* AddBabyTests.swift */; }; 53F30C282D7FBB670077FD21 /* AddDataViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53F30C272D7FBB670077FD21 /* AddDataViewTests.swift */; }; 5680DD3E2AB8CD84004E6D4A /* ContributionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5680DD3D2AB8CD84004E6D4A /* ContributionsTest.swift */; }; 56E708352BB06B7100B08F0A /* SpeziLicense in Frameworks */ = {isa = PBXBuildFile; productRef = 56E708342BB06B7100B08F0A /* SpeziLicense */; }; @@ -113,6 +114,7 @@ 2FF53D8C2A8729D600042B76 /* FeedbridgeStandard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedbridgeStandard.swift; sourceTree = ""; }; 358F60B12D73FEE000721B85 /* DashboardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardView.swift; sourceTree = ""; }; 35B62D5C2D80C20C0096904E /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; + 35B62F792D8257E80096904E /* AddBabyTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddBabyTests.swift; sourceTree = ""; }; 35E52D2B2D794472005A6BB7 /* WeightCharts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeightCharts.swift; sourceTree = ""; }; 35E52D302D79475E005A6BB7 /* StoolCharts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoolCharts.swift; sourceTree = ""; }; 35E52D332D7947D3005A6BB7 /* StoolsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoolsView.swift; sourceTree = ""; }; @@ -338,6 +340,7 @@ 653A256A28338800005D4D48 /* FeedbridgeUITests */ = { isa = PBXGroup; children = ( + 35B62F792D8257E80096904E /* AddBabyTests.swift */, 53F30C272D7FBB670077FD21 /* AddDataViewTests.swift */, 2F4E237D2989A2FE0013F3D9 /* OnboardingTests.swift */, 653A256B28338800005D4D48 /* SchedulerTests.swift */, @@ -612,6 +615,7 @@ 53F30C282D7FBB670077FD21 /* AddDataViewTests.swift in Sources */, 2F4E237E2989A2FE0013F3D9 /* OnboardingTests.swift in Sources */, 653A256C28338800005D4D48 /* SchedulerTests.swift in Sources */, + 35B62F7A2D8257EC0096904E /* AddBabyTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/FeedbridgeUITests/AddBabyTests.swift b/FeedbridgeUITests/AddBabyTests.swift new file mode 100644 index 0000000..4f444ee --- /dev/null +++ b/FeedbridgeUITests/AddBabyTests.swift @@ -0,0 +1,90 @@ +// +// AddBabyTests.swift +// Feedbridge +// +// Created by Shreya D'Souza on 3/11/25. +// +// SPDX-FileCopyrightText: 2025 Stanford University +// +// SPDX-License-Identifier: MIT +// + +import XCTest +import XCTestExtensions + +@MainActor +class AddBabyTests: XCTestCase { + /// Sets up the test environment before each test case. + /// Ensures that there are no existing babies and launches the app with test configurations. + override func setUp() async throws { + continueAfterFailure = false + + let app = XCUIApplication() + app.launchArguments = ["--setupTestAccount", "--skipOnboarding"] + app.deleteAndLaunch(withSpringboardAppName: "Feedbridge") + + // Clear existing babies before each test + deleteAllBabies(app) + } + + /// Deletes all babies using the UI delete button, ensuring a clean state before each test. + /// - Parameter app: The XCUIApplication instance. + private func deleteAllBabies(_ app: XCUIApplication) { + app.buttons["Settings"].tap() + + let deleteButton = app.buttons["Delete Baby, Delete Baby"] + + // If the delete button exists, repeatedly tap it to remove all babies + while deleteButton.waitForExistence(timeout: 2) { + deleteButton.tap() + app.buttons["Delete"].tap() + } + } + + /// Tests the process of adding a new baby and verifying that the baby is correctly displayed in the UI. + func testAddBaby() { + let app = XCUIApplication() + app.buttons["Settings"].tap() + + // Verify initial state: No baby should be selected + XCTAssertTrue(app.staticTexts["Select Baby"].exists, "Select baby dropdown should be visible") + XCTAssertTrue(app.staticTexts["No baby selected"].exists, "No babies should exist") + + // Open the dropdown menu and select "Add New Baby" + let dropdown = app.buttons["Baby icon, Select Baby, Menu dropdown"] + dropdown.tap() + let addNew = app.buttons["Add New Baby"] + XCTAssertTrue(addNew.exists, "Should be an option to add a baby") + addNew.tap() + + // Ensure that the Save button is initially disabled + let saveButton = app.buttons["Save"] + XCTAssertFalse(saveButton.isEnabled, "Save button should be disabled initially") + + // Enter baby's name + let nameField = app.textFields["Baby's Name"] + nameField.tap() + nameField.typeText("Benjamin") + + // Verify that a duplicate name warning is not displayed + XCTAssertFalse(app.staticTexts["This name is already taken"].exists, "Duplicate name warning should not appear") + + // Date Picker: Select March 2025 (valid past date) + let datePickersQuery = app.datePickers.firstMatch + datePickersQuery.tap() + app.staticTexts["1"].tap() + app.buttons["PopoverDismissRegion"].tap() // Close the date picker + + // Ensure the Save button is enabled now that valid data is entered + XCTAssertTrue(saveButton.isEnabled, "Save button should be enabled when valid data is entered") + + // Save the baby data + saveButton.tap() + + // Verify that the new baby is correctly added and displayed in the UI + XCTAssertTrue(app.staticTexts["Benjamin"].exists, "Baby's name should be displayed") + XCTAssertTrue(app.buttons["Baby icon, Benjamin, Menu dropdown"].exists, "Baby dropdown should show new baby") + XCTAssertTrue(app.buttons["Delete Baby, Delete Baby"].exists, "Delete button should be displayed for the new baby") + XCTAssertTrue(app.staticTexts["Use Kilograms"].exists, "The 'Use Kilograms' text should be displayed") + } +}