新增完整 UI Test 回归套件,并完善启动隔离逻辑。

按模块拆分 XCUITest 用例与 Support 基础设施,UI Test 运行时跳过推送与排队 WebSocket,并将 Podfile 最低版本对齐 iOS 16。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-26 10:45:00 +08:00
parent 703078352c
commit 0c01ee26c3
39 changed files with 1533 additions and 231 deletions

View File

@ -0,0 +1,25 @@
//
// AuthFlowUITests.swift
// suixinkanUITests
//
import XCTest
final class AuthFlowUITests: AuthenticatedUITestCase {
/// Tab
func testLoginReachesMainTabs() {
XCTAssertTrue(app.isOnMainTabs)
}
/// 访 Tab
func testLoggedInUserCanSwitchPrimaryTabs() {
TabBarNavigator.select(.home, app: app)
XCTAssertTrue(
app.application.staticTexts["常用应用"].waitForExistence(timeout: 8)
|| app.application.staticTexts["请选择景区"].exists
)
TabBarNavigator.select(.profile, app: app)
NavigationAssertions.waitForNavigationTitle("个人信息", in: app)
}
}

View File

@ -0,0 +1,60 @@
//
// LoginSmokeUITests.swift
// suixinkanUITests
//
import XCTest
final class LoginSmokeUITests: XCTestCase {
override func setUp() {
super.setUp()
continueAfterFailure = false
}
///
func testFreshLaunchShowsLoginScreen() {
let app = SuixinkanApp(resetState: true).launch(waitForLoading: false)
XCTAssertTrue(app.application.staticTexts["login.title"].waitForExistence(timeout: 8))
XCTAssertTrue(app.application.textFields["login.username"].exists)
XCTAssertTrue(
app.application.secureTextFields["login.password"].exists
|| app.application.textFields["login.password"].exists
)
XCTAssertTrue(app.application.buttons["login.submit"].exists)
XCTAssertTrue(app.application.buttons["login.userAgreement"].exists)
XCTAssertTrue(app.application.buttons["login.privacyPolicy"].exists)
}
///
func testLoginRequiresPrivacyAgreement() throws {
let app = SuixinkanApp(resetState: true).launch(waitForLoading: false)
guard UITestLaunchConfiguration.credentials != nil else {
throw XCTSkip("缺少 UI Test 账号。")
}
let usernameField = app.application.textFields["login.username"]
XCTAssertTrue(usernameField.waitForExistence(timeout: 8))
XCTAssertFalse(app.application.buttons["login.submit"].isEnabled)
}
///
func testEmptyPasswordDoesNotLeaveLoginScreen() throws {
let app = SuixinkanApp(resetState: true).launch(waitForLoading: false)
let credentials = try UITestLaunchConfiguration.requireCredentials()
let usernameField = app.application.textFields["login.username"]
XCTAssertTrue(usernameField.waitForExistence(timeout: 8))
usernameField.tap()
usernameField.typeText(credentials.phone)
let privacyToggle = app.application.buttons["login.privacy"]
if privacyToggle.exists {
privacyToggle.tap()
}
app.application.buttons["login.submit"].tap()
app.waitForGlobalLoadingToDisappear(timeout: 5)
XCTAssertTrue(app.isOnLoginScreen)
}
}