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
76 changes: 38 additions & 38 deletions .github/workflows/nightly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +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
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
20 changes: 20 additions & 0 deletions .github/workflows/pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,24 @@ jobs:
ios: ${{ matrix.ios }}
xcode: ${{ matrix.xcode }}
is_pr: true
secrets: inherit

ui-tests-pr:
needs: [test-orchestrator]
uses: ./.github/workflows/reusable-ui-test-workflow.yaml
with:
is_pr: true
# First test in each AuthFlowTesterUITests suite (same order as ui-test-nightly matrix)
pr_tests: |
[
"AuthFlowTesterUITests/AdvancedAuthBeaconLoginTests/testBeaconAdvancedOpaque_DefaultScopes",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Running one test of each suite with every PR - but maybe that's too many?

"AuthFlowTesterUITests/BeaconLoginTests/testBeaconAdvancedOpaque_DefaultScopes",
"AuthFlowTesterUITests/DefaultScopesLegacyLoginTests/testCAAdvancedOpaque_DefaultScopes_WebServerFlow",
"AuthFlowTesterUITests/DynamicConfigLoginTests/testCAAdvancedJwt_DefaultScopes_DynamicConfiguration_WithRestart",
"AuthFlowTesterUITests/ECALoginTests/testECAAdvancedOpaque_DefaultScopes",
"AuthFlowTesterUITests/LegacyLoginTests/testCAAdvancedOpaque_SubsetScopes_WebServerFlow",
"AuthFlowTesterUITests/MigrationTests/testMigrateCA_AddMoreScopes",
"AuthFlowTesterUITests/MultiUserLoginTests/testBothStatic_SameApp_SameScopes",
"AuthFlowTesterUITests/WelcomeLoginTests/testWelcomeDiscoveryWithRegularAuthLoginHost"
]
secrets: inherit
170 changes: 170 additions & 0 deletions .github/workflows/reusable-ui-test-workflow.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
on:
workflow_call:
inputs:
is_pr:
type: boolean
default: false
ios:
default: "^26"
required: false
type: string
xcode:
default: "^26"
required: false
type: string
macos:
default: macos-latest
required: false
type: string
test-retry-iterations:
description: "Max retries per test on failure (1 = no retry)."
default: 2
required: false
type: number
test_suite:
description: "Test class to run only (e.g. ECALoginTests). Empty = run all. Ignored when is_pr (PR uses pr_tests instead)."
default: ""
required: false
type: string
pr_tests:
description: "JSON array of test identifiers to run (e.g. ['AuthFlowTesterUITests/ECALoginTests/testECA...']). Used when is_pr is true; empty = use default PR smoke test."
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: ""
required: false
type: string
parallel-testing-worker-count:
description: "xcodebuild -parallel-testing-worker-count (0 = do not set; parallel testing uses xcodebuild default)."
default: 0
required: false
type: number

jobs:
test-ui:
runs-on: ${{ inputs.macos }}
steps:
- uses: actions/checkout@v4
if: ${{ inputs.is_pr }}
with:
fetch-depth: 100
ref: ${{ github.event.pull_request.head.sha }}
- uses: actions/checkout@v4
if: ${{ !inputs.is_pr }}
with:
ref: ${{ github.head_ref }}
- name: Install Dependencies
env:
UI_TEST_CONFIG: ${{ secrets.UI_TEST_CONFIG }}
run: |
./install.sh
echo "$UI_TEST_CONFIG" > ./shared/test/ui_test_config.json
- name: Install iOS 17 runtime if needed
if: ${{ inputs.ios == '^17' }}
run: xcodes runtimes install "iOS 17.5"
# Select Xcode only (mxcl action does not support -retry-tests-on-failure)
- uses: mxcl/xcodebuild@v3
with:
xcode: ${{ inputs.xcode }}
platform: iOS
platform-version: ${{ inputs.ios }}
action: none
- name: Resolve simulator destination
id: resolve_destination
run: |
if [ -n "${{ inputs.destination }}" ]; then
echo "destination=${{ inputs.destination }}" >> "$GITHUB_OUTPUT"
else
SIM_UDID=$(xcrun simctl list devices available -j | python3 -c '
import sys, json
d = json.load(sys.stdin)
for devices in d.get("devices", {}).values():
for dev in devices:
if dev.get("isAvailable", True) and "iPhone" in dev.get("name", ""):
print(dev["udid"])
sys.exit(0)
sys.exit(1)
')
if [ -z "$SIM_UDID" ]; then
echo "::error::No available iPhone simulator found"
exit 1
fi
echo "destination=platform=iOS Simulator,id=$SIM_UDID" >> "$GITHUB_OUTPUT"
fi
- name: Run UI tests
id: xcodebuild
run: |
DESTINATION="${{ steps.resolve_destination.outputs.destination }}"
RETRY_ARGS=()
if [ "${{ inputs.test-retry-iterations }}" -gt 1 ]; then
RETRY_ARGS=(-retry-tests-on-failure -test-iterations "${{ inputs.test-retry-iterations }}")
fi
ONLY_TESTING_ARGS=()
if [ "$IS_PR" = "true" ]; then
PR_TESTS='${{ inputs.pr_tests }}'
if [ -n "$PR_TESTS" ] && [ "$PR_TESTS" != "[]" ]; then
while IFS= read -r t; do
ONLY_TESTING_ARGS+=(-only-testing "$t")
done < <(echo "$PR_TESTS" | python3 -c "import sys, json; [print(t) for t in json.load(sys.stdin)]")
else
ONLY_TESTING_ARGS=(-only-testing 'AuthFlowTesterUITests/ECALoginTests/testECAAdvancedJwt_DefaultScopes')
fi
elif [ -n "${{ inputs.test_suite }}" ]; then
ONLY_TESTING_ARGS=(-only-testing "AuthFlowTesterUITests/${{ inputs.test_suite }}")
fi
PARALLEL_ARGS=()
if [ "${{ inputs.parallel-testing-worker-count }}" -gt 0 ]; then
PARALLEL_ARGS=(-parallel-testing-enabled YES -parallel-testing-worker-count "${{ inputs.parallel-testing-worker-count }}")
fi
xcodebuild test \
-workspace SalesforceMobileSDK.xcworkspace \
-scheme AuthFlowTester \
-destination "$DESTINATION" \
"${PARALLEL_ARGS[@]}" \
"${ONLY_TESTING_ARGS[@]}" \
"${RETRY_ARGS[@]}" \
-resultBundlePath test \
-enableCodeCoverage YES \
| xcbeautify
env:
CODE_COVERAGE: YES
IS_PR: ${{ inputs.is_pr }}
- name: Parse test results
if: success() || failure()
run: |
brew install xcresultparser
mkdir -p firebase_results
SUITE="${{ inputs.test_suite }}"
[ -z "$SUITE" ] && SUITE=all
[ "$IS_PR" = "true" ] && SUITE=pr
xcresultparser -o junit test.xcresult > firebase_results/authflowtester-ui-${SUITE}-test_result.xml
- name: Test Report
uses: mikepenz/action-junit-report@v5
if: success() || failure()
with:
check_name: AuthFlowTester UI Test Results ${{ inputs.test_suite && format('({0})', inputs.test_suite) || '' }}
job_name: AuthFlowTester UI Test Results ${{ inputs.test_suite && format('({0})', inputs.test_suite) || '' }}
require_tests: true
check_retries: true
flaky_summary: true
fail_on_failure: true
group_reports: false
include_passed: true
include_empty_in_summary: false
simplified_summary: true
job_summary: ${{ steps.xcodebuild.outcome == 'failure' }}
report_paths: 'firebase_results/**.xml'
- uses: codecov/codecov-action@v4
if: success() || failure()
with:
flags: AuthFlowTesterUI
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Upload test results artifact
if: success() || failure()
uses: actions/upload-artifact@v4
with:
name: test-results-authflowtester-ui-${{ inputs.test_suite || 'all' }}-ios${{ inputs.ios }}
path: firebase_results/
28 changes: 28 additions & 0 deletions .github/workflows/ui-test-nightly.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: UI Nightly Tests
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NB: separate workflow for UI nightly tests.
Should we have a separate workflow for UI tests for PR also??


on:
schedule:
- cron: "0 5 * * 3,5" # cron is UTC, this translates to 10 PM PST Tues and Thur.
workflow_dispatch:

jobs:
ios-ui-test-nightly:
strategy:
fail-fast: false
matrix:
test_suite:
- AdvancedAuthBeaconLoginTests
- BeaconLoginTests
- DefaultScopesLegacyLoginTests
- DynamicConfigLoginTests
- ECALoginTests
- LegacyLoginTests
- MigrationTests
- MultiUserLoginTests
- WelcomeLoginTests
uses: ./.github/workflows/reusable-ui-test-workflow.yaml
with:
ios: "^26"
xcode: "^26"
test_suite: ${{ matrix.test_suite }}
secrets: inherit
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ project.xcworkspace
artifacts
node_modules
shared/test/test_credentials.json
shared/test/ui_test_config.json
bootconfig.plist
/SalesforceMobileSDK.xcworkspace/xcshareddata/SalesforceMobileSDK.xccheckout
/SalesforceMobileSDK.xcworkspace/xcshareddata/SalesforceMobileSDK.xcscmblueprint
Expand All @@ -21,7 +22,6 @@ bootconfig.plist
/libs/MobileSync/build/
/libs/SalesforceSDKCommon/build/
/native/SampleApps/RestAPIExplorer/build/
/native/SampleApps/AuthFlowTester/AuthFlowTesterUITests/ui_test_config.json
node_modules/
.idea/
package-lock.json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
AUTH042 /* OAuthConfigurationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AUTH043 /* OAuthConfigurationView.swift */; };
AUTH049 /* JwtTokenView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AUTH050 /* JwtTokenView.swift */; };
AUTH051 /* InfoRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AUTH052 /* InfoRowView.swift */; };
AUTH054 /* ui_test_config.json in Resources */ = {isa = PBXBuildFile; fileRef = AUTH053 /* ui_test_config.json */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -77,13 +78,14 @@
AUTH043 /* OAuthConfigurationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OAuthConfigurationView.swift; sourceTree = "<group>"; };
AUTH050 /* JwtTokenView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JwtTokenView.swift; sourceTree = "<group>"; };
AUTH052 /* InfoRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoRowView.swift; sourceTree = "<group>"; };
AUTH053 /* ui_test_config.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = ui_test_config.json; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
4F5946272ED670C7003C5BDE /* Exceptions for "AuthFlowTesterUITests" folder in "AuthFlowTesterUITests" target */ = {
4F1B50CF2F3D35BB0025A685 /* Exceptions for "AuthFlowTesterUITests" folder in "AuthFlowTesterUITests" target */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
ui_test_config.json.sample,
overview.md,
);
target = 4F8E4AF02ED13CE800DA7B7A /* AuthFlowTesterUITests */;
};
Expand All @@ -93,7 +95,7 @@
4F8E4AF22ED13CE800DA7B7A /* AuthFlowTesterUITests */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
4F5946272ED670C7003C5BDE /* Exceptions for "AuthFlowTesterUITests" folder in "AuthFlowTesterUITests" target */,
4F1B50CF2F3D35BB0025A685 /* Exceptions for "AuthFlowTesterUITests" folder in "AuthFlowTesterUITests" target */,
);
path = AuthFlowTesterUITests;
sourceTree = "<group>";
Expand Down Expand Up @@ -144,11 +146,21 @@
children = (
AUTH020 /* AuthFlowTester */,
4F8E4AF22ED13CE800DA7B7A /* AuthFlowTesterUITests */,
AUTH055 /* Shared Test */,
4F95A8952EA801DC00C98D18 /* Frameworks */,
AUTH021 /* Products */,
);
sourceTree = "<group>";
};
AUTH055 /* Shared Test */ = {
isa = PBXGroup;
children = (
AUTH053 /* ui_test_config.json */,
);
path = ../../../shared/test;
sourceTree = "<group>";
name = "Shared Test";
};
AUTH020 /* AuthFlowTester */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -292,6 +304,7 @@
4F8E4AEF2ED13CE800DA7B7A /* Resources */ = {
isa = PBXResourcesBuildPhase;
files = (
AUTH054 /* ui_test_config.json in Resources */,
);
};
AUTH026 /* Resources */ = {
Expand Down
Loading