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
|
product: VNCCore
|
||||||
- package: VNCUI
|
- package: VNCUI
|
||||||
product: 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