From 780114a4ea55759606cd03cf3c39a163d5caefea Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Wed, 4 Mar 2026 14:12:34 -0800 Subject: [PATCH 01/14] Fix for publication step --- .github/workflows/reusable-ui-test-workflow.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/reusable-ui-test-workflow.yaml b/.github/workflows/reusable-ui-test-workflow.yaml index 19c621d7ea..49fe109761 100644 --- a/.github/workflows/reusable-ui-test-workflow.yaml +++ b/.github/workflows/reusable-ui-test-workflow.yaml @@ -86,6 +86,7 @@ jobs: if [ -n "${{ inputs.pr_test }}" ]; then ONLY_TESTING_ARGS+=(-only-testing "${{ inputs.pr_test }}") fi + set -o pipefail xcodebuild test \ -workspace SalesforceMobileSDK.xcworkspace \ -scheme AuthFlowTester \ @@ -97,6 +98,15 @@ jobs: | xcbeautify env: CODE_COVERAGE: YES + - name: Verify xcresult bundle exists + if: success() || failure() + run: | + if [ ! -d "test.xcresult" ]; then + echo "::error::test.xcresult bundle was not created" + exit 1 + fi + echo "xcresult bundle exists and contains:" + ls -lh test.xcresult/ - name: Publish test results uses: kishikawakatsumi/xcresulttool@v1 if: success() || failure() From 5316a43a7ab49651d5e95210830565a500eb8514 Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Wed, 4 Mar 2026 15:13:54 -0800 Subject: [PATCH 02/14] Temporary change for testing --- .github/workflows/nightly.yaml | 83 ++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index f66e2e0292..8a3fa958cf 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -7,42 +7,49 @@ on: workflow_dispatch: jobs: - ios-nightly: - strategy: - fail-fast: false - matrix: - lib: [SalesforceSDKCommon, SalesforceAnalytics, SalesforceSDKCore, SmartStore, MobileSync] - ios: [^26, ^18, ^17] - include: - - ios: ^26 - xcode: ^26 - - ios: ^18 - xcode: ^16 - - ios: ^17 - xcode: ^16 - uses: ./.github/workflows/reusable-test-workflow.yaml - with: - lib: ${{ matrix.lib }} - ios: ${{ matrix.ios }} - xcode: ${{ matrix.xcode }} - secrets: inherit +# ios-nightly: +# strategy: +# fail-fast: false +# matrix: +# lib: [SalesforceSDKCommon, SalesforceAnalytics, SalesforceSDKCore, SmartStore, MobileSync] +# ios: [^26, ^18, ^17] +# include: +# - ios: ^26 +# xcode: ^26 +# - ios: ^18 +# xcode: ^16 +# - ios: ^17 +# xcode: ^16 +# uses: ./.github/workflows/reusable-test-workflow.yaml +# with: +# lib: ${{ matrix.lib }} +# ios: ${{ matrix.ios }} +# xcode: ${{ matrix.xcode }} +# secrets: inherit +# +# native-samples-nightly: +# strategy: +# fail-fast: false +# matrix: +# app: [RestAPIExplorer, MobileSyncExplorer, AuthFlowTester] +# ios: [^26, ^18, ^17] +# include: +# - ios: ^26 +# xcode: ^26 +# - ios: ^18 +# xcode: ^16 +# - ios: ^17 +# xcode: ^16 +# uses: ./.github/workflows/reusable-build-workflow.yaml +# with: +# app: ${{ matrix.app }} +# ios: ${{ matrix.ios }} +# xcode: ${{ matrix.xcode }} +# secrets: inherit - native-samples-nightly: - strategy: - fail-fast: false - matrix: - app: [RestAPIExplorer, MobileSyncExplorer, AuthFlowTester] - ios: [^26, ^18, ^17] - include: - - ios: ^26 - xcode: ^26 - - ios: ^18 - xcode: ^16 - - ios: ^17 - xcode: ^16 - uses: ./.github/workflows/reusable-build-workflow.yaml - with: - app: ${{ matrix.app }} - ios: ${{ matrix.ios }} - xcode: ${{ matrix.xcode }} - secrets: inherit \ No newline at end of file + ios-ui-test-nightly: + uses: ./.github/workflows/reusable-ui-test-workflow.yaml + with: + ios: "^26" + xcode: "^26" + secrets: inherit From 50cbbca641c9aa10117816ee8bda363ba2131408 Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Thu, 5 Mar 2026 10:54:34 -0800 Subject: [PATCH 03/14] Attempting to fix publish step --- .github/workflows/reusable-ui-test-workflow.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/reusable-ui-test-workflow.yaml b/.github/workflows/reusable-ui-test-workflow.yaml index 49fe109761..c42f7819a6 100644 --- a/.github/workflows/reusable-ui-test-workflow.yaml +++ b/.github/workflows/reusable-ui-test-workflow.yaml @@ -82,10 +82,8 @@ jobs: id: xcodebuild run: | DESTINATION="${{ steps.resolve_destination.outputs.destination }}" - ONLY_TESTING_ARGS=() - if [ -n "${{ inputs.pr_test }}" ]; then - ONLY_TESTING_ARGS+=(-only-testing "${{ inputs.pr_test }}") - fi + # Hardcoded for faster CI run - revert to inputs.pr_test when done + ONLY_TESTING_ARGS=(-only-testing "AuthFlowTesterUITests/WelcomeLoginTests/testWelcomeDiscovery_RegularAuthLoginHost") set -o pipefail xcodebuild test \ -workspace SalesforceMobileSDK.xcworkspace \ @@ -111,7 +109,7 @@ jobs: uses: kishikawakatsumi/xcresulttool@v1 if: success() || failure() with: - path: test.xcresult + path: ${{ github.workspace }}/test.xcresult show-passed-tests: true title: AuthFlowTester UI Test Results - uses: codecov/codecov-action@v4 From f5e3625cda2f5cdea6b6ac4a4331b04b150f49fc Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Thu, 5 Mar 2026 11:08:21 -0800 Subject: [PATCH 04/14] Adding debug statements --- .../workflows/reusable-ui-test-workflow.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/reusable-ui-test-workflow.yaml b/.github/workflows/reusable-ui-test-workflow.yaml index c42f7819a6..9c36dc0c78 100644 --- a/.github/workflows/reusable-ui-test-workflow.yaml +++ b/.github/workflows/reusable-ui-test-workflow.yaml @@ -105,6 +105,24 @@ jobs: fi echo "xcresult bundle exists and contains:" ls -lh test.xcresult/ + - name: Debug xcresult bundle for xcresulttool + if: success() || failure() + run: | + XCRESULT_PATH="${{ github.workspace }}/test.xcresult" + echo "::group::xcresult path and existence" + echo "Path: $XCRESULT_PATH" + echo "Exists: $([ -d "$XCRESULT_PATH" ] && echo yes || echo no)" + echo "::endgroup::" + echo "::group::xcresult bundle contents" + ls -laR "$XCRESULT_PATH" 2>&1 || true + echo "::endgroup::" + echo "::group::xcrun xcresulttool get (raw output)" + xcrun xcresulttool get --path "$XCRESULT_PATH" 2>&1; echo "xcrun exit code: $?" + echo "::endgroup::" + echo "::group::xcrun version and SDK" + xcrun --version + xcrun --sdk iphonesimulator --show-sdk-path + echo "::endgroup::" - name: Publish test results uses: kishikawakatsumi/xcresulttool@v1 if: success() || failure() From 5d08441d065505a7c29fae3b19fab4fb7ac8f59e Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Thu, 5 Mar 2026 13:12:06 -0800 Subject: [PATCH 05/14] Trying to fix test results publishing --- .../workflows/reusable-ui-test-workflow.yaml | 27 ++++--------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/.github/workflows/reusable-ui-test-workflow.yaml b/.github/workflows/reusable-ui-test-workflow.yaml index 9c36dc0c78..f7738e7c16 100644 --- a/.github/workflows/reusable-ui-test-workflow.yaml +++ b/.github/workflows/reusable-ui-test-workflow.yaml @@ -105,31 +105,14 @@ jobs: fi echo "xcresult bundle exists and contains:" ls -lh test.xcresult/ - - name: Debug xcresult bundle for xcresulttool + - name: Publish test results if: success() || failure() run: | XCRESULT_PATH="${{ github.workspace }}/test.xcresult" - echo "::group::xcresult path and existence" - echo "Path: $XCRESULT_PATH" - echo "Exists: $([ -d "$XCRESULT_PATH" ] && echo yes || echo no)" - echo "::endgroup::" - echo "::group::xcresult bundle contents" - ls -laR "$XCRESULT_PATH" 2>&1 || true - echo "::endgroup::" - echo "::group::xcrun xcresulttool get (raw output)" - xcrun xcresulttool get --path "$XCRESULT_PATH" 2>&1; echo "xcrun exit code: $?" - echo "::endgroup::" - echo "::group::xcrun version and SDK" - xcrun --version - xcrun --sdk iphonesimulator --show-sdk-path - echo "::endgroup::" - - name: Publish test results - uses: kishikawakatsumi/xcresulttool@v1 - if: success() || failure() - with: - path: ${{ github.workspace }}/test.xcresult - show-passed-tests: true - title: AuthFlowTester UI Test Results + echo "## AuthFlowTester UI Test Results" >> "$GITHUB_STEP_SUMMARY" + echo '```' >> "$GITHUB_STEP_SUMMARY" + xcrun xcresulttool get object --legacy --path "$XCRESULT_PATH" >> "$GITHUB_STEP_SUMMARY" 2>&1 || true + echo '```' >> "$GITHUB_STEP_SUMMARY" - uses: codecov/codecov-action@v4 if: success() || failure() with: From 0b6953d2cecc50fdd698766fe3975138df956cfc Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Thu, 5 Mar 2026 13:36:36 -0800 Subject: [PATCH 06/14] Bringing back test results parsing --- .../workflows/reusable-ui-test-workflow.yaml | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/workflows/reusable-ui-test-workflow.yaml b/.github/workflows/reusable-ui-test-workflow.yaml index f7738e7c16..5b335a8c5c 100644 --- a/.github/workflows/reusable-ui-test-workflow.yaml +++ b/.github/workflows/reusable-ui-test-workflow.yaml @@ -105,14 +105,24 @@ jobs: fi echo "xcresult bundle exists and contains:" ls -lh test.xcresult/ - - name: Publish test results + - name: Parse test results if: success() || failure() run: | - XCRESULT_PATH="${{ github.workspace }}/test.xcresult" - echo "## AuthFlowTester UI Test Results" >> "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" - xcrun xcresulttool get object --legacy --path "$XCRESULT_PATH" >> "$GITHUB_STEP_SUMMARY" 2>&1 || true - echo '```' >> "$GITHUB_STEP_SUMMARY" + brew install xcresultparser + xcresultparser -o junit test.xcresult > test-results-authflowtester-ui-ios${{ inputs.ios }}.xml + - name: Test Report + uses: mikepenz/action-junit-report@v5 + if: success() || failure() + with: + check_name: AuthFlowTester UI Test Results + job_name: AuthFlowTester UI Test Results + require_tests: true + include_empty_in_summary: false + simplified_summary: true + detailed_summary: true + comment: true + job_summary: true + report_paths: 'test-results-authflowtester-ui-ios${{ inputs.ios }}.xml' - uses: codecov/codecov-action@v4 if: success() || failure() with: From b4837eba7a979823765633c9b0e7256d466a2f1e Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Thu, 5 Mar 2026 14:02:52 -0800 Subject: [PATCH 07/14] Back to running all UI tests in nightly runs --- .github/workflows/reusable-ui-test-workflow.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-ui-test-workflow.yaml b/.github/workflows/reusable-ui-test-workflow.yaml index 5b335a8c5c..8bd3b97f7b 100644 --- a/.github/workflows/reusable-ui-test-workflow.yaml +++ b/.github/workflows/reusable-ui-test-workflow.yaml @@ -82,8 +82,10 @@ jobs: id: xcodebuild run: | DESTINATION="${{ steps.resolve_destination.outputs.destination }}" - # Hardcoded for faster CI run - revert to inputs.pr_test when done - ONLY_TESTING_ARGS=(-only-testing "AuthFlowTesterUITests/WelcomeLoginTests/testWelcomeDiscovery_RegularAuthLoginHost") + ONLY_TESTING_ARGS=() + if [ -n "${{ inputs.pr_test }}" ]; then + ONLY_TESTING_ARGS+=(-only-testing "${{ inputs.pr_test }}") + fi set -o pipefail xcodebuild test \ -workspace SalesforceMobileSDK.xcworkspace \ From 62b53f0fca16659e81c7bf94d042734d6d0e1776 Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Fri, 6 Mar 2026 10:40:08 -0800 Subject: [PATCH 08/14] Centralizing UI timeouts in a new helper class UITestTimeouts Timeouts can be passed through environment CI is running with longer timeout Also making sure to run on a iOS simulator matching the requested value in the workflow --- .github/workflows/nightly.yaml | 2 + .github/workflows/pr.yaml | 2 + .../workflows/reusable-ui-test-workflow.yaml | 25 ++++++++- .github/workflows/ui-test-nightly.yaml | 2 + .../AuthFlowTesterMainPageObject.swift | 27 +++++---- .../PageObjects/LoginOptionsPageObject.swift | 9 ++- .../PageObjects/LoginPageObject.swift | 17 +++--- .../Util/UITestTimeouts.swift | 56 +++++++++++++++++++ 8 files changed, 109 insertions(+), 31 deletions(-) create mode 100644 native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/Util/UITestTimeouts.swift diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 8a3fa958cf..0735b6ac6a 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -52,4 +52,6 @@ jobs: with: ios: "^26" xcode: "^26" + short_timeout: "5" + long_timeout: "15" secrets: inherit diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 932a046cd7..a9140d5ef9 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -142,4 +142,6 @@ jobs: with: is_pr: true pr_test: "AuthFlowTesterUITests/LegacyLoginTests/testCAOpaque_DefaultScopes_WebServerFlow" + short_timeout: "5" + long_timeout: "15" secrets: inherit \ No newline at end of file diff --git a/.github/workflows/reusable-ui-test-workflow.yaml b/.github/workflows/reusable-ui-test-workflow.yaml index 8bd3b97f7b..7a2dda2a80 100644 --- a/.github/workflows/reusable-ui-test-workflow.yaml +++ b/.github/workflows/reusable-ui-test-workflow.yaml @@ -26,6 +26,16 @@ on: default: "" required: false type: string + short_timeout: + description: "UI test short timeout in seconds (env UI_TEST_SHORT_TIMEOUT). Empty = use code default (1)." + default: "" + required: false + type: string + long_timeout: + description: "UI test long timeout in seconds (env UI_TEST_LONG_TIMEOUT). Empty = use code default (3)." + default: "" + required: false + type: string jobs: test-ui: @@ -62,18 +72,25 @@ jobs: if [ -n "${{ inputs.destination }}" ]; then echo "destination=${{ inputs.destination }}" >> "$GITHUB_OUTPUT" else + # Extract major iOS version from input (e.g. ^26 -> 26, 26.0 -> 26) + IOS_VERSION="${{ inputs.ios }}" + IOS_MAJOR=$(echo "$IOS_VERSION" | sed 's/^\^//' | cut -d. -f1) SIM_UDID=$(xcrun simctl list devices available -j | python3 -c ' import sys, json + major = sys.argv[1] d = json.load(sys.stdin) - for devices in d.get("devices", {}).values(): + runtime_prefix = "iOS-" + major + "-" + for runtime_key, devices in d.get("devices", {}).items(): + if runtime_prefix not in runtime_key: + continue for dev in devices: if dev.get("isAvailable", True) and "iPhone" in dev.get("name", ""): print(dev["udid"]) sys.exit(0) sys.exit(1) - ') + ' "$IOS_MAJOR") if [ -z "$SIM_UDID" ]; then - echo "::error::No available iPhone simulator found" + echo "::error::No available iPhone simulator found for iOS $IOS_MAJOR" exit 1 fi echo "destination=platform=iOS Simulator,id=$SIM_UDID" >> "$GITHUB_OUTPUT" @@ -98,6 +115,8 @@ jobs: | xcbeautify env: CODE_COVERAGE: YES + UI_TEST_SHORT_TIMEOUT: ${{ inputs.short_timeout }} + UI_TEST_LONG_TIMEOUT: ${{ inputs.long_timeout }} - name: Verify xcresult bundle exists if: success() || failure() run: | diff --git a/.github/workflows/ui-test-nightly.yaml b/.github/workflows/ui-test-nightly.yaml index 81904cedfe..fbc03cb43d 100644 --- a/.github/workflows/ui-test-nightly.yaml +++ b/.github/workflows/ui-test-nightly.yaml @@ -11,4 +11,6 @@ jobs: with: ios: "^26" xcode: "^26" + short_timeout: "5" + long_timeout: "15" secrets: inherit diff --git a/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/AuthFlowTesterMainPageObject.swift b/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/AuthFlowTesterMainPageObject.swift index 2e69b1d332..bf0c33dce7 100644 --- a/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/AuthFlowTesterMainPageObject.swift +++ b/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/AuthFlowTesterMainPageObject.swift @@ -213,14 +213,13 @@ struct JwtDetailsData { /// and extract data (user credentials, OAuth configuration, JWT details) from the UI. class AuthFlowTesterMainPageObject { let app: XCUIApplication - let timeout: double_t = 3 - + init(testApp: XCUIApplication) { app = testApp } func isShowing() -> Bool { - return navigationTitle().waitForExistence(timeout: 1) + return navigationTitle().waitForExistence(timeout: UITestTimeouts.short) } func performLogout() { @@ -231,7 +230,7 @@ class AuthFlowTesterMainPageObject { func makeRestRequest() -> Bool { tap(makeRestRequestButton()) let alert = app.alerts["Request Successful"] - if (alert.waitForExistence(timeout: timeout)) { + if (alert.waitForExistence(timeout: UITestTimeouts.long)) { alert.buttons["OK"].tap() return true } @@ -241,7 +240,7 @@ class AuthFlowTesterMainPageObject { func revokeAccessToken() -> Bool { tap(revokeButton()) let alert = app.alerts["Access Token Revoked"] - if (alert.waitForExistence(timeout: timeout)) { + if (alert.waitForExistence(timeout: UITestTimeouts.long)) { alert.buttons["OK"].tap() return true } @@ -282,7 +281,7 @@ class AuthFlowTesterMainPageObject { tapIfPresent(allowButton()) let alert = app.alerts["Migration Error"] - if (alert.waitForExistence(timeout: timeout)) { + if (alert.waitForExistence(timeout: UITestTimeouts.long)) { alert.buttons["OK"].tap() return false } @@ -309,7 +308,7 @@ class AuthFlowTesterMainPageObject { // Wait for alert to appear let alert = importConfigAlert() - _ = alert.waitForExistence(timeout: timeout) + _ = alert.waitForExistence(timeout: UITestTimeouts.long) // Type into the alert's text field let textField = importConfigTextField() @@ -438,25 +437,25 @@ class AuthFlowTesterMainPageObject { // MARK: - Actions private func tap(_ element: XCUIElement) { - _ = element.waitForExistence(timeout: timeout) + _ = element.waitForExistence(timeout: UITestTimeouts.long) element.tap() } private func tapIfPresent(_ element: XCUIElement) { - if (element.waitForExistence(timeout: timeout)) { + if (element.waitForExistence(timeout: UITestTimeouts.long)) { element.tap() } } private func setTextField(_ textField: XCUIElement, value: String) { - _ = textField.waitForExistence(timeout: timeout) + _ = textField.waitForExistence(timeout: UITestTimeouts.long) textField.tap() // Clear any existing text if let currentValue = textField.value as? String, !currentValue.isEmpty { textField.tap() let selectAll = app.menuItems["Select All"] - if selectAll.waitForExistence(timeout: 1) { + if selectAll.waitForExistence(timeout: UITestTimeouts.short) { selectAll.tap() textField.typeText(XCUIKeyboardKey.delete.rawValue) } @@ -535,7 +534,7 @@ class AuthFlowTesterMainPageObject { func getJwtDetails() -> JwtDetailsData? { // Check if JWT export button exists (indicates JWT token is available) - guard exportJwtTokenButton().waitForExistence(timeout: 1) else { + guard exportJwtTokenButton().waitForExistence(timeout: UITestTimeouts.short) else { return nil } @@ -571,7 +570,7 @@ class AuthFlowTesterMainPageObject { // Wait for and get the alert let alert = app.alerts[alertTitle] - guard alert.waitForExistence(timeout: timeout) else { + guard alert.waitForExistence(timeout: UITestTimeouts.long) else { return [:] } @@ -594,7 +593,7 @@ class AuthFlowTesterMainPageObject { private func hasStaticText(_ text: String) -> Bool { let staticText = app.staticTexts.containing(NSPredicate(format: "label CONTAINS '\(text)'")) - return staticText.firstMatch.waitForExistence(timeout: timeout) + return staticText.firstMatch.waitForExistence(timeout: UITestTimeouts.long) } } diff --git a/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/LoginOptionsPageObject.swift b/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/LoginOptionsPageObject.swift index ea5cd466e4..735b1b29ee 100644 --- a/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/LoginOptionsPageObject.swift +++ b/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/LoginOptionsPageObject.swift @@ -33,7 +33,6 @@ import SalesforceSDKCore /// Use after navigating to Login Options from the login screen (e.g. via Settings → Login Options). class LoginOptionsPageObject { let app: XCUIApplication - let timeout: double_t = 2 init(testApp: XCUIApplication) { app = testApp @@ -101,7 +100,7 @@ class LoginOptionsPageObject { // Wait for alert and enter JSON (text field is automatically focused) let alert = app.alerts["Import Configuration"] - _ = alert.waitForExistence(timeout: timeout) + _ = alert.waitForExistence(timeout: UITestTimeouts.long) let textField = alert.textFields.firstMatch textField.typeText(jsonString) @@ -116,7 +115,7 @@ class LoginOptionsPageObject { // Wait for alert and enter JSON (text field is automatically focused) let alert = app.alerts["Import Discovery Result"] - _ = alert.waitForExistence(timeout: timeout) + _ = alert.waitForExistence(timeout: UITestTimeouts.long) let textField = alert.textFields.firstMatch textField.typeText(jsonString) @@ -153,12 +152,12 @@ class LoginOptionsPageObject { // MARK: - Actions private func tap(_ element: XCUIElement) { - _ = element.waitForExistence(timeout: timeout) + _ = element.waitForExistence(timeout: UITestTimeouts.long) element.tap() } private func setSwitchField(_ switchField: XCUIElement, value: Bool) { - _ = switchField.waitForExistence(timeout: timeout) + _ = switchField.waitForExistence(timeout: UITestTimeouts.long) // Switch values are "0" (off) or "1" (on) in XCTest let currentValue = (switchField.value as? String) == "1" diff --git a/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/LoginPageObject.swift b/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/LoginPageObject.swift index 24a8142816..1f5838bc28 100644 --- a/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/LoginPageObject.swift +++ b/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/LoginPageObject.swift @@ -33,22 +33,21 @@ import SalesforceSDKCore /// Provides methods to configure login servers, login options and perform user authentication. class LoginPageObject { let app: XCUIApplication - let timeout: double_t = 3 - + init(testApp: XCUIApplication) { app = testApp } func isShowing() -> Bool { - return loginNavigationBar().waitForExistence(timeout: timeout) + return loginNavigationBar().waitForExistence(timeout: UITestTimeouts.long) } func hasFilledUsernameField(username: String) -> Bool { - return app.staticTexts[username].waitForExistence(timeout: timeout) + return app.staticTexts[username].waitForExistence(timeout: UITestTimeouts.long) } func isShowingAdvancedAuth() -> Bool { - return advancedAuthCloseButton().waitForExistence(timeout: 1) + return advancedAuthCloseButton().waitForExistence(timeout: UITestTimeouts.short) } func closeAdvancedAuth() -> Void { @@ -200,12 +199,12 @@ class LoginPageObject { // MARK: - Actions private func tap(_ element: XCUIElement) { - _ = element.waitForExistence(timeout: timeout) + _ = element.waitForExistence(timeout: UITestTimeouts.long) element.tap() } private func tapIfPresent(_ element: XCUIElement) { - if (element.waitForExistence(timeout: timeout)) { + if (element.waitForExistence(timeout: UITestTimeouts.long)) { element.tap() } } @@ -222,7 +221,7 @@ class LoginPageObject { if let currentValue = textField.value as? String, !currentValue.isEmpty { tap(textField) // second tap should bring up menu let selectAll = app.menuItems["Select All"] - if selectAll.waitForExistence(timeout: 1) { + if selectAll.waitForExistence(timeout: UITestTimeouts.short) { selectAll.tap() textField.typeText(XCUIKeyboardKey.delete.rawValue) } @@ -235,7 +234,7 @@ class LoginPageObject { private func hasHost(host: String) -> Bool { let row = hostRow(host: host) - return row.waitForExistence(timeout: timeout) + return row.waitForExistence(timeout: UITestTimeouts.long) } } diff --git a/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/Util/UITestTimeouts.swift b/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/Util/UITestTimeouts.swift new file mode 100644 index 0000000000..9afe2d5866 --- /dev/null +++ b/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/Util/UITestTimeouts.swift @@ -0,0 +1,56 @@ +/* + UITestTimeouts.swift + AuthFlowTesterUITests + + Copyright (c) 2026-present, salesforce.com, inc. All rights reserved. + + Redistribution and use of this software in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of + conditions and the following disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of salesforce.com, inc. nor the names of its contributors may be used to + endorse or promote products derived from this software without specific prior written + permission of salesforce.com, inc. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +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. +enum UITestTimeouts { + /// Default short timeout in seconds (e.g. for quick UI state checks). + private static let defaultShort: TimeInterval = 1 + /// Default long timeout in seconds (e.g. for page load or alert appearance). + private static let defaultLong: TimeInterval = 3 + + private static func parseEnv(_ key: String) -> TimeInterval? { + guard let raw = ProcessInfo.processInfo.environment[key], + !raw.isEmpty, + let value = TimeInterval(raw), + value > 0 else { return nil } + return value + } + + /// Short timeout (seconds). Use for fast UI checks (e.g. menu items, close buttons). + static var short: TimeInterval { + parseEnv("UI_TEST_SHORT_TIMEOUT") ?? defaultShort + } + + /// Long timeout (seconds). Use for page visibility, alerts, and general element waits. + static var long: TimeInterval { + parseEnv("UI_TEST_LONG_TIMEOUT") ?? defaultLong + } +} From 1217cdf2dbb7b2cccbf388420de91cb57f4de5e3 Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Fri, 6 Mar 2026 15:12:25 -0800 Subject: [PATCH 09/14] From Xcode 15.3 on, only environment variables whose names start with TEST_RUNNER_ are passed from the host into the test runner. --- .github/workflows/reusable-ui-test-workflow.yaml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reusable-ui-test-workflow.yaml b/.github/workflows/reusable-ui-test-workflow.yaml index 7a2dda2a80..e490175d91 100644 --- a/.github/workflows/reusable-ui-test-workflow.yaml +++ b/.github/workflows/reusable-ui-test-workflow.yaml @@ -115,8 +115,9 @@ jobs: | xcbeautify env: CODE_COVERAGE: YES - UI_TEST_SHORT_TIMEOUT: ${{ inputs.short_timeout }} - UI_TEST_LONG_TIMEOUT: ${{ inputs.long_timeout }} + # Xcode 15.3+ only forwards env vars prefixed with TEST_RUNNER_ to the test runner (prefix is stripped). + TEST_RUNNER_UI_TEST_SHORT_TIMEOUT: ${{ inputs.short_timeout }} + TEST_RUNNER_UI_TEST_LONG_TIMEOUT: ${{ inputs.long_timeout }} - name: Verify xcresult bundle exists if: success() || failure() run: | From e8be4fad6d2c266a855dde1e5d74d449b1922273 Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Fri, 6 Mar 2026 20:51:26 -0800 Subject: [PATCH 10/14] Tests on CI were not dismissing keyboards when expected --- .github/workflows/nightly.yaml | 4 ++-- .github/workflows/pr.yaml | 4 ++-- .github/workflows/ui-test-nightly.yaml | 4 ++-- .../PageObjects/LoginPageObject.swift | 20 +++++++++++++++---- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 0735b6ac6a..bbea5950fa 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -52,6 +52,6 @@ jobs: with: ios: "^26" xcode: "^26" - short_timeout: "5" - long_timeout: "15" + short_timeout: "2" + long_timeout: "5" secrets: inherit diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index a9140d5ef9..c8721153df 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -142,6 +142,6 @@ jobs: with: is_pr: true pr_test: "AuthFlowTesterUITests/LegacyLoginTests/testCAOpaque_DefaultScopes_WebServerFlow" - short_timeout: "5" - long_timeout: "15" + short_timeout: "2" + long_timeout: "5" secrets: inherit \ No newline at end of file diff --git a/.github/workflows/ui-test-nightly.yaml b/.github/workflows/ui-test-nightly.yaml index fbc03cb43d..4f2b424782 100644 --- a/.github/workflows/ui-test-nightly.yaml +++ b/.github/workflows/ui-test-nightly.yaml @@ -11,6 +11,6 @@ jobs: with: ios: "^26" xcode: "^26" - short_timeout: "5" - long_timeout: "15" + short_timeout: "2" + long_timeout: "5" secrets: inherit diff --git a/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/LoginPageObject.swift b/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/LoginPageObject.swift index 1f5838bc28..1d219a95d2 100644 --- a/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/LoginPageObject.swift +++ b/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/LoginPageObject.swift @@ -72,9 +72,9 @@ class LoginPageObject { func performLogin(username: String, password: String) { setTextField(usernameField(), value: username) - tap(toolbarDoneButton()) + dismissKeyboardAfterTyping() setTextField(passwordField(), value: password) - tap(toolbarDoneButton()) + dismissKeyboardAfterTyping() tap(loginButton()) tapIfPresent(allowButton()) } @@ -162,6 +162,15 @@ class LoginPageObject { return app.staticTexts[host].firstMatch } + /// Dismisses the keyboard after typing in a field. Tries the toolbar "Done" button first; + /// if not found (e.g. on some simulators it is exposed as a Key, not Button), taps the + /// password label to dismiss. + private func dismissKeyboardAfterTyping() { + if !tapIfPresent(toolbarDoneButton()) { + tap(passwordFieldLabel()) + } + } + private func toolbarDoneButton() -> XCUIElement { return app.toolbars["Toolbar"].buttons["Done"] } @@ -203,10 +212,13 @@ class LoginPageObject { element.tap() } - private func tapIfPresent(_ element: XCUIElement) { - if (element.waitForExistence(timeout: UITestTimeouts.long)) { + @discardableResult + private func tapIfPresent(_ element: XCUIElement) -> Bool { + if element.waitForExistence(timeout: UITestTimeouts.long) { element.tap() + return true } + return false } private func setTextField(_ textField: XCUIElement, value: String) { From 6bae74aa7563a3644d4a1699943ec6cfd8e29d46 Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Sat, 7 Mar 2026 00:06:25 -0800 Subject: [PATCH 11/14] Adjusting time outs --- .github/workflows/nightly.yaml | 2 +- .github/workflows/pr.yaml | 2 +- .github/workflows/ui-test-nightly.yaml | 2 +- .../PageObjects/AuthFlowTesterMainPageObject.swift | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index bbea5950fa..4462624ec1 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -53,5 +53,5 @@ jobs: ios: "^26" xcode: "^26" short_timeout: "2" - long_timeout: "5" + long_timeout: "6" secrets: inherit diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index c8721153df..1a9cbf387b 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -143,5 +143,5 @@ jobs: is_pr: true pr_test: "AuthFlowTesterUITests/LegacyLoginTests/testCAOpaque_DefaultScopes_WebServerFlow" short_timeout: "2" - long_timeout: "5" + long_timeout: "6" secrets: inherit \ No newline at end of file diff --git a/.github/workflows/ui-test-nightly.yaml b/.github/workflows/ui-test-nightly.yaml index 4f2b424782..d939fda481 100644 --- a/.github/workflows/ui-test-nightly.yaml +++ b/.github/workflows/ui-test-nightly.yaml @@ -12,5 +12,5 @@ jobs: ios: "^26" xcode: "^26" short_timeout: "2" - long_timeout: "5" + long_timeout: "6" secrets: inherit diff --git a/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/AuthFlowTesterMainPageObject.swift b/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/AuthFlowTesterMainPageObject.swift index bf0c33dce7..fcdcbdcea8 100644 --- a/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/AuthFlowTesterMainPageObject.swift +++ b/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/PageObjects/AuthFlowTesterMainPageObject.swift @@ -219,7 +219,7 @@ class AuthFlowTesterMainPageObject { } func isShowing() -> Bool { - return navigationTitle().waitForExistence(timeout: UITestTimeouts.short) + return navigationTitle().waitForExistence(timeout: UITestTimeouts.long) } func performLogout() { From a78d72626add1f17ed1b929459a57a6e25594937 Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Sat, 7 Mar 2026 09:43:47 -0800 Subject: [PATCH 12/14] Longer timeout Back to the test matrix (otherwise run take more than 3h) --- .github/workflows/nightly.yaml | 16 +++++++++++- .github/workflows/pr.yaml | 2 +- .../workflows/reusable-ui-test-workflow.yaml | 25 +++++++++++++++---- .github/workflows/ui-test-nightly.yaml | 16 +++++++++++- 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 4462624ec1..90e3d28854 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -48,10 +48,24 @@ jobs: # secrets: inherit ios-ui-test-nightly: + strategy: + fail-fast: false + matrix: + test_suite: + - AuthFlowTesterUITests/AdvancedAuthBeaconLoginTests + - AuthFlowTesterUITests/BeaconLoginTests + - AuthFlowTesterUITests/ECALoginTests + - AuthFlowTesterUITests/LegacyLoginTests + - AuthFlowTesterUITests/LoginWithRestartTests + - AuthFlowTesterUITests/MultiUserLoginTests + - AuthFlowTesterUITests/RefreshTokenMigrationTests + - AuthFlowTesterUITests/RefreshTokenMigrationWithRestartTests + - AuthFlowTesterUITests/WelcomeLoginTests uses: ./.github/workflows/reusable-ui-test-workflow.yaml with: ios: "^26" xcode: "^26" short_timeout: "2" - long_timeout: "6" + long_timeout: "7" + test_suite: ${{ matrix.test_suite }} secrets: inherit diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 1a9cbf387b..8fa2020dc9 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -143,5 +143,5 @@ jobs: is_pr: true pr_test: "AuthFlowTesterUITests/LegacyLoginTests/testCAOpaque_DefaultScopes_WebServerFlow" short_timeout: "2" - long_timeout: "6" + long_timeout: "7" secrets: inherit \ No newline at end of file diff --git a/.github/workflows/reusable-ui-test-workflow.yaml b/.github/workflows/reusable-ui-test-workflow.yaml index e490175d91..f29ff868b2 100644 --- a/.github/workflows/reusable-ui-test-workflow.yaml +++ b/.github/workflows/reusable-ui-test-workflow.yaml @@ -21,6 +21,11 @@ on: default: "" required: false type: string + test_suite: + description: "Test suite to run (e.g. 'AuthFlowTesterUITests/BeaconLoginTests'). Empty = run all tests. Used with matrix for parallel nightly runs." + default: "" + required: false + type: string destination: description: "xcodebuild -destination (e.g. 'platform=iOS Simulator,name=iPhone 17,OS=26.0'). Empty = use default for iOS 26." default: "" @@ -41,6 +46,14 @@ jobs: test-ui: runs-on: ${{ inputs.macos }} steps: + - name: Set result suffix for matrix runs + id: result_suffix + run: | + if [ -n "${{ inputs.test_suite }}" ]; then + echo "suffix=$(echo '${{ inputs.test_suite }}' | tr '/' '-')" >> "$GITHUB_OUTPUT" + else + echo "suffix=all" >> "$GITHUB_OUTPUT" + fi - uses: actions/checkout@v4 if: ${{ inputs.is_pr }} with: @@ -102,6 +115,8 @@ jobs: ONLY_TESTING_ARGS=() if [ -n "${{ inputs.pr_test }}" ]; then ONLY_TESTING_ARGS+=(-only-testing "${{ inputs.pr_test }}") + elif [ -n "${{ inputs.test_suite }}" ]; then + ONLY_TESTING_ARGS+=(-only-testing "${{ inputs.test_suite }}") fi set -o pipefail xcodebuild test \ @@ -131,20 +146,20 @@ jobs: if: success() || failure() run: | brew install xcresultparser - xcresultparser -o junit test.xcresult > test-results-authflowtester-ui-ios${{ inputs.ios }}.xml + xcresultparser -o junit test.xcresult > test-results-authflowtester-ui-ios${{ inputs.ios }}-${{ steps.result_suffix.outputs.suffix }}.xml - name: Test Report uses: mikepenz/action-junit-report@v5 if: success() || failure() with: - check_name: AuthFlowTester UI Test Results - job_name: AuthFlowTester UI Test Results + check_name: AuthFlowTester UI Test Results ${{ steps.result_suffix.outputs.suffix }} + job_name: AuthFlowTester UI Test Results ${{ steps.result_suffix.outputs.suffix }} require_tests: true include_empty_in_summary: false simplified_summary: true detailed_summary: true comment: true job_summary: true - report_paths: 'test-results-authflowtester-ui-ios${{ inputs.ios }}.xml' + report_paths: 'test-results-authflowtester-ui-ios${{ inputs.ios }}-${{ steps.result_suffix.outputs.suffix }}.xml' - uses: codecov/codecov-action@v4 if: success() || failure() with: @@ -155,6 +170,6 @@ jobs: if: success() || failure() uses: actions/upload-artifact@v4 with: - name: xcresult-authflowtester-ui-ios${{ inputs.ios }} + name: xcresult-authflowtester-ui-ios${{ inputs.ios }}-${{ steps.result_suffix.outputs.suffix }} path: test.xcresult/ retention-days: 30 diff --git a/.github/workflows/ui-test-nightly.yaml b/.github/workflows/ui-test-nightly.yaml index d939fda481..8d51872210 100644 --- a/.github/workflows/ui-test-nightly.yaml +++ b/.github/workflows/ui-test-nightly.yaml @@ -7,10 +7,24 @@ on: jobs: ios-ui-test-nightly: + strategy: + fail-fast: false + matrix: + test_suite: + - AuthFlowTesterUITests/AdvancedAuthBeaconLoginTests + - AuthFlowTesterUITests/BeaconLoginTests + - AuthFlowTesterUITests/ECALoginTests + - AuthFlowTesterUITests/LegacyLoginTests + - AuthFlowTesterUITests/LoginWithRestartTests + - AuthFlowTesterUITests/MultiUserLoginTests + - AuthFlowTesterUITests/RefreshTokenMigrationTests + - AuthFlowTesterUITests/RefreshTokenMigrationWithRestartTests + - AuthFlowTesterUITests/WelcomeLoginTests uses: ./.github/workflows/reusable-ui-test-workflow.yaml with: ios: "^26" xcode: "^26" short_timeout: "2" - long_timeout: "6" + long_timeout: "7" + test_suite: ${{ matrix.test_suite }} secrets: inherit From 47b1d4770ce5fc7445e56e0e17ae50758f6d9150 Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Sat, 7 Mar 2026 13:57:27 -0800 Subject: [PATCH 13/14] Going back to single runner - multi-runners running for more than 4 hours --- .github/workflows/nightly.yaml | 14 -------------- .github/workflows/ui-test-nightly.yaml | 14 -------------- 2 files changed, 28 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 90e3d28854..4642b7efa3 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -48,24 +48,10 @@ jobs: # secrets: inherit ios-ui-test-nightly: - strategy: - fail-fast: false - matrix: - test_suite: - - AuthFlowTesterUITests/AdvancedAuthBeaconLoginTests - - AuthFlowTesterUITests/BeaconLoginTests - - AuthFlowTesterUITests/ECALoginTests - - AuthFlowTesterUITests/LegacyLoginTests - - AuthFlowTesterUITests/LoginWithRestartTests - - AuthFlowTesterUITests/MultiUserLoginTests - - AuthFlowTesterUITests/RefreshTokenMigrationTests - - AuthFlowTesterUITests/RefreshTokenMigrationWithRestartTests - - AuthFlowTesterUITests/WelcomeLoginTests uses: ./.github/workflows/reusable-ui-test-workflow.yaml with: ios: "^26" xcode: "^26" short_timeout: "2" long_timeout: "7" - test_suite: ${{ matrix.test_suite }} secrets: inherit diff --git a/.github/workflows/ui-test-nightly.yaml b/.github/workflows/ui-test-nightly.yaml index 8d51872210..c06b3f2a6a 100644 --- a/.github/workflows/ui-test-nightly.yaml +++ b/.github/workflows/ui-test-nightly.yaml @@ -7,24 +7,10 @@ on: jobs: ios-ui-test-nightly: - strategy: - fail-fast: false - matrix: - test_suite: - - AuthFlowTesterUITests/AdvancedAuthBeaconLoginTests - - AuthFlowTesterUITests/BeaconLoginTests - - AuthFlowTesterUITests/ECALoginTests - - AuthFlowTesterUITests/LegacyLoginTests - - AuthFlowTesterUITests/LoginWithRestartTests - - AuthFlowTesterUITests/MultiUserLoginTests - - AuthFlowTesterUITests/RefreshTokenMigrationTests - - AuthFlowTesterUITests/RefreshTokenMigrationWithRestartTests - - AuthFlowTesterUITests/WelcomeLoginTests uses: ./.github/workflows/reusable-ui-test-workflow.yaml with: ios: "^26" xcode: "^26" short_timeout: "2" long_timeout: "7" - test_suite: ${{ matrix.test_suite }} secrets: inherit From 3b43b4d5f9723facf625bc56257ed0c81b54c5ef Mon Sep 17 00:00:00 2001 From: Wolfgang Mathurin Date: Mon, 9 Mar 2026 13:11:37 -0700 Subject: [PATCH 14/14] Scheduled for Monday and Wednesday evening --- .github/workflows/nightly.yaml | 81 ++++++++++++-------------- .github/workflows/ui-test-nightly.yaml | 2 +- 2 files changed, 37 insertions(+), 46 deletions(-) diff --git a/.github/workflows/nightly.yaml b/.github/workflows/nightly.yaml index 4642b7efa3..11ac989057 100644 --- a/.github/workflows/nightly.yaml +++ b/.github/workflows/nightly.yaml @@ -7,51 +7,42 @@ on: workflow_dispatch: jobs: -# ios-nightly: -# strategy: -# fail-fast: false -# matrix: -# lib: [SalesforceSDKCommon, SalesforceAnalytics, SalesforceSDKCore, SmartStore, MobileSync] -# ios: [^26, ^18, ^17] -# include: -# - ios: ^26 -# xcode: ^26 -# - ios: ^18 -# xcode: ^16 -# - ios: ^17 -# xcode: ^16 -# uses: ./.github/workflows/reusable-test-workflow.yaml -# with: -# lib: ${{ matrix.lib }} -# ios: ${{ matrix.ios }} -# xcode: ${{ matrix.xcode }} -# secrets: inherit -# -# native-samples-nightly: -# strategy: -# fail-fast: false -# matrix: -# app: [RestAPIExplorer, MobileSyncExplorer, AuthFlowTester] -# ios: [^26, ^18, ^17] -# include: -# - ios: ^26 -# xcode: ^26 -# - ios: ^18 -# xcode: ^16 -# - ios: ^17 -# xcode: ^16 -# uses: ./.github/workflows/reusable-build-workflow.yaml -# with: -# app: ${{ matrix.app }} -# ios: ${{ matrix.ios }} -# xcode: ${{ matrix.xcode }} -# secrets: inherit + ios-nightly: + strategy: + fail-fast: false + matrix: + lib: [SalesforceSDKCommon, SalesforceAnalytics, SalesforceSDKCore, SmartStore, MobileSync] + ios: [^26, ^18, ^17] + include: + - ios: ^26 + xcode: ^26 + - ios: ^18 + xcode: ^16 + - ios: ^17 + xcode: ^16 + uses: ./.github/workflows/reusable-test-workflow.yaml + with: + lib: ${{ matrix.lib }} + ios: ${{ matrix.ios }} + xcode: ${{ matrix.xcode }} + secrets: inherit - ios-ui-test-nightly: - uses: ./.github/workflows/reusable-ui-test-workflow.yaml + native-samples-nightly: + strategy: + fail-fast: false + matrix: + app: [RestAPIExplorer, MobileSyncExplorer, AuthFlowTester] + ios: [^26, ^18, ^17] + include: + - ios: ^26 + xcode: ^26 + - ios: ^18 + xcode: ^16 + - ios: ^17 + xcode: ^16 + uses: ./.github/workflows/reusable-build-workflow.yaml with: - ios: "^26" - xcode: "^26" - short_timeout: "2" - long_timeout: "7" + app: ${{ matrix.app }} + ios: ${{ matrix.ios }} + xcode: ${{ matrix.xcode }} secrets: inherit diff --git a/.github/workflows/ui-test-nightly.yaml b/.github/workflows/ui-test-nightly.yaml index c06b3f2a6a..21e23da32a 100644 --- a/.github/workflows/ui-test-nightly.yaml +++ b/.github/workflows/ui-test-nightly.yaml @@ -2,7 +2,7 @@ name: UI Nightly Tests on: schedule: - - cron: "0 5 * * 3,5" # cron is UTC, this translates to 10 PM PST Tues and Thur. + - cron: "0 5 * * 2,4" # cron is UTC, this translates to 10 PM PST Mon and Wed. workflow_dispatch: jobs: