Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ jobs:
ios: ${{ matrix.ios }}
xcode: ${{ matrix.xcode }}
pr_test: "AuthFlowTesterUITests/LegacyLoginTests/testCAOpaque_DefaultScopes_WebServerFlow"
short_timeout: "2"
long_timeout: "7"
short_timeout: "3"
long_timeout: "15"
secrets:
UI_TEST_CONFIG: ${{ secrets.UI_TEST_CONFIG }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
4 changes: 2 additions & 2 deletions .github/workflows/ui-test-nightly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ jobs:
with:
ios: ${{ matrix.ios }}
xcode: ${{ matrix.xcode }}
short_timeout: "2"
long_timeout: "7"
short_timeout: "3"
long_timeout: "15"
secrets:
UI_TEST_CONFIG: ${{ secrets.UI_TEST_CONFIG }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ class AuthFlowTesterMainPageObject {
}

func isShowing() -> Bool {
return navigationTitle().waitForExistence(timeout: UITestTimeouts.long)
return navigationTitle().waitForExistence(timeout: UITestTimeouts.network)
}

func performLogout() {
Expand Down Expand Up @@ -461,13 +461,14 @@ class AuthFlowTesterMainPageObject {

// MARK: - Actions

private func tap(_ element: XCUIElement) {
_ = element.waitForExistence(timeout: UITestTimeouts.long)
private func tap(_ element: XCUIElement, timeout: TimeInterval = UITestTimeouts.long, file: StaticString = #file, line: UInt = #line) {
let exists = element.waitForExistence(timeout: timeout)
XCTAssertTrue(exists, "Element \(element.debugDescription) did not appear within \(timeout)s", file: file, line: line)
element.tap()
}
private func tapIfPresent(_ element: XCUIElement) {
if (element.waitForExistence(timeout: UITestTimeouts.long)) {

private func tapIfPresent(_ element: XCUIElement, timeout: TimeInterval = UITestTimeouts.long) {
if element.waitForExistence(timeout: timeout) {
element.tap()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ class AuthFlowTypesPageObject {

// MARK: - Actions

private func tap(_ element: XCUIElement) {
_ = element.waitForExistence(timeout: UITestTimeouts.long)
private func tap(_ element: XCUIElement, timeout: TimeInterval = UITestTimeouts.long, file: StaticString = #file, line: UInt = #line) {
let exists = element.waitForExistence(timeout: timeout)
XCTAssertTrue(exists, "Element \(element.debugDescription) did not appear within \(timeout)s", file: file, line: line)
element.tap()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,9 @@ class LoginOptionsPageObject {

// MARK: - Actions

private func tap(_ element: XCUIElement) {
_ = element.waitForExistence(timeout: UITestTimeouts.long)
private func tap(_ element: XCUIElement, timeout: TimeInterval = UITestTimeouts.long, file: StaticString = #file, line: UInt = #line) {
let exists = element.waitForExistence(timeout: timeout)
XCTAssertTrue(exists, "Element \(element.debugDescription) did not appear within \(timeout)s", file: file, line: line)
element.tap()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class LoginPageObject {
}

func isShowing() -> Bool {
return loginNavigationBar().waitForExistence(timeout: UITestTimeouts.long)
return loginNavigationBar().waitForExistence(timeout: UITestTimeouts.network)
}

func hasFilledUsernameField(username: String) -> Bool {
Expand Down Expand Up @@ -84,16 +84,16 @@ class LoginPageObject {
usernameField().typeText(XCUIKeyboardKey.return.rawValue)
} else {
dismissKeyboardAfterTyping()
tap(loginButton())
tap(loginButton(), timeout: UITestTimeouts.network)
}
setTextField(passwordField(), value: password)
if advancedAuth {
passwordField().typeText(XCUIKeyboardKey.return.rawValue)
} else {
dismissKeyboardAfterTyping()
tap(loginButton())
tap(loginButton(), timeout: UITestTimeouts.network)
}
tapIfPresent(allowButton())
tapIfPresent(allowButton(), timeout: UITestTimeouts.network)
}

/// Performs login via the "Login for Admin" flow.
Expand All @@ -111,15 +111,15 @@ class LoginPageObject {
}

func performWelcomeLogin(password: String, advancedAuth: Bool = false) {
tap(loginButton())
tap(loginButton(), timeout: UITestTimeouts.network)
setTextField(passwordField(), value: password)
if advancedAuth {
passwordField().typeText(XCUIKeyboardKey.return.rawValue)
} else {
dismissKeyboardAfterTyping()
tap(loginButton())
tap(loginButton(), timeout: UITestTimeouts.network)
}
tapIfPresent(allowButton())
tapIfPresent(allowButton(), timeout: UITestTimeouts.network)
}

func configureLoginOptions(
Expand Down Expand Up @@ -257,14 +257,15 @@ class LoginPageObject {

// MARK: - Actions

private func tap(_ element: XCUIElement) {
_ = element.waitForExistence(timeout: UITestTimeouts.long)
private func tap(_ element: XCUIElement, timeout: TimeInterval = UITestTimeouts.long, file: StaticString = #file, line: UInt = #line) {
let exists = element.waitForExistence(timeout: timeout)
XCTAssertTrue(exists, "Element \(element.debugDescription) did not appear within \(timeout)s", file: file, line: line)
element.tap()
}

@discardableResult
private func tapIfPresent(_ element: XCUIElement) -> Bool {
if element.waitForExistence(timeout: UITestTimeouts.long) {
private func tapIfPresent(_ element: XCUIElement, timeout: TimeInterval = UITestTimeouts.long) -> Bool {
if element.waitForExistence(timeout: timeout) {
element.tap()
return true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@
import Foundation

/// Provides timeout values for UI test element waits.
/// Values come from the environment (`UI_TEST_SHORT_TIMEOUT`, `UI_TEST_LONG_TIMEOUT`) when set,
/// otherwise from defaults. CI workflows can pass larger timeouts via these env vars.
/// Values come from the environment (`UI_TEST_SHORT_TIMEOUT`, `UI_TEST_LONG_TIMEOUT`,
/// `UI_TEST_NETWORK_TIMEOUT`) when set, otherwise from defaults.
/// CI workflows can pass larger timeouts via these env vars.
enum UITestTimeouts {
/// Default short timeout in seconds (e.g. for quick UI state checks).
private static let defaultShort: TimeInterval = 1
private static let defaultShort: TimeInterval = 2
/// Default long timeout in seconds (e.g. for page load or alert appearance).
private static let defaultLong: TimeInterval = 3
private static let defaultLong: TimeInterval = 10
/// Default network timeout in seconds (e.g. for operations that hit real OAuth servers).
private static let defaultNetwork: TimeInterval = 30

private static func parseEnv(_ key: String) -> TimeInterval? {
guard let raw = ProcessInfo.processInfo.environment[key],
Expand All @@ -53,4 +56,10 @@ enum UITestTimeouts {
static var long: TimeInterval {
parseEnv("UI_TEST_LONG_TIMEOUT") ?? defaultLong
}

/// Network timeout (seconds). Use for operations involving real server round-trips
/// (e.g. OAuth login, WKWebView page loads hitting Salesforce endpoints).
static var network: TimeInterval {
parseEnv("UI_TEST_NETWORK_TIMEOUT") ?? defaultNetwork
}
}
Loading