Add UI test covering layout + core flows
Verifies: - Title lives in the top 25% of the screen (guards against letterboxing regressions) - Plus button opens Add Connection sheet; Cancel dismisses - Settings gear opens Settings sheet; Done dismisses - Search field accepts input and keeps the top chrome visible - Empty-state CTA routes to Add Connection Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
14
Project.yml
14
Project.yml
@@ -43,3 +43,17 @@ targets:
|
||||
product: VNCCore
|
||||
- package: VNCUI
|
||||
product: VNCUI
|
||||
|
||||
ScreensUITests:
|
||||
type: bundle.ui-testing
|
||||
platform: iOS
|
||||
deploymentTarget: "18.0"
|
||||
sources:
|
||||
- path: ScreensUITests
|
||||
settings:
|
||||
base:
|
||||
PRODUCT_BUNDLE_IDENTIFIER: com.tt.screens.uitests
|
||||
TEST_TARGET_NAME: Screens
|
||||
GENERATE_INFOPLIST_FILE: YES
|
||||
dependencies:
|
||||
- target: Screens
|
||||
|
||||
63
ScreensUITests/ScreensUITests.swift
Normal file
63
ScreensUITests/ScreensUITests.swift
Normal file
@@ -0,0 +1,63 @@
|
||||
import XCTest
|
||||
|
||||
final class ScreensUITests: XCTestCase {
|
||||
override func setUp() {
|
||||
continueAfterFailure = false
|
||||
}
|
||||
|
||||
@MainActor
|
||||
func testLayoutFillsScreenAndCoreFlows() {
|
||||
let app = XCUIApplication()
|
||||
app.launch()
|
||||
|
||||
// ---- Top chrome is present and flush with the safe area top.
|
||||
let title = app.staticTexts["Screens"]
|
||||
XCTAssertTrue(title.waitForExistence(timeout: 5), "Title should appear")
|
||||
|
||||
let screenFrame = app.windows.firstMatch.frame
|
||||
let titleY = title.frame.midY
|
||||
XCTAssertLessThan(titleY, screenFrame.height * 0.25,
|
||||
"Title should sit in the top 25% of the screen; actual Y \(titleY) in screen \(screenFrame.height)")
|
||||
|
||||
// ---- Tap + to open Add Connection sheet.
|
||||
let addButton = app.buttons["Add connection"]
|
||||
XCTAssertTrue(addButton.exists, "Add button should exist")
|
||||
addButton.tap()
|
||||
|
||||
let displayNameField = app.textFields["Display name"]
|
||||
XCTAssertTrue(displayNameField.waitForExistence(timeout: 2),
|
||||
"Add Connection sheet should present and show Display name field")
|
||||
|
||||
app.buttons["Cancel"].tap()
|
||||
XCTAssertFalse(displayNameField.waitForExistence(timeout: 1),
|
||||
"Add sheet should dismiss on Cancel")
|
||||
|
||||
// ---- Settings gear opens Settings sheet.
|
||||
app.buttons["Settings"].tap()
|
||||
let settingsTitle = app.navigationBars.staticTexts["Settings"]
|
||||
XCTAssertTrue(settingsTitle.waitForExistence(timeout: 2),
|
||||
"Settings sheet should present")
|
||||
app.buttons["Done"].tap()
|
||||
|
||||
// ---- Search field accepts input and clears.
|
||||
let search = app.textFields.matching(NSPredicate(format: "placeholderValue == %@", "Search connections")).firstMatch
|
||||
XCTAssertTrue(search.waitForExistence(timeout: 2), "Search field should exist")
|
||||
search.tap()
|
||||
search.typeText("mini")
|
||||
XCTAssertEqual(search.value as? String, "mini",
|
||||
"Search text should round-trip")
|
||||
// Title should still be visible (top chrome does not scroll off)
|
||||
XCTAssertTrue(title.isHittable, "Title should remain on screen during search")
|
||||
|
||||
// ---- Empty-state CTA routes to Add Connection.
|
||||
let emptyCTA = app.buttons["Add a computer"]
|
||||
if emptyCTA.waitForExistence(timeout: 1) {
|
||||
// clear search first
|
||||
app.buttons["Clear search"].tap()
|
||||
emptyCTA.tap()
|
||||
XCTAssertTrue(displayNameField.waitForExistence(timeout: 2),
|
||||
"Empty-state CTA should present Add Connection sheet")
|
||||
app.buttons["Cancel"].tap()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user