mirror of
https://github.com/callstack/agent-device.git
synced 2026-09-14 20:06:34 +08:00
bd42b2602f
* fix(ios): serve regular --depth from every snapshot backend A regular depth-capped request was refused on every runner backend but the recursive tree: the query sweep past depth 1 and private AX at any depth returned no capture, so a plan pinned or deferred to private AX (custom actions, a private AX verdict on the session, the XCTest channel penalty) fell through to the synthetic sparse root, which the daemon then rejected as "regular iOS snapshot presentation requires a valid viewport". Presentation already applies the presented-depth cut to whatever hierarchy a backend acquired, and a depth-capped regular capture is a subset of the unscoped one from the same backend, so the refusal protected nothing the unscoped answer did not already disclose through truncated/effectiveDepth. Delete the gate, declare private AX as regular-depth=presentation-cut, and record the rule in ADR 0004. Closes #2403 * test(ios): prove a private-AX-pinned plan serves regular --depth through acquisition The presentation-package test passes with the old backend depth gate restored, because it calls presentation directly. This runner-bundle test pins private AX, asks for regular depth 1 against the launched host app, and requires the plan to reach acquisition and presentation: a private-ax verdict that is not sparse, more than one node, a real root rect, and a payload no larger than the unscoped capture from the same backend. With the gate restored the plan logs SNAPSHOT_BACKEND_DEPTH_UNSUPPORTED and returns the zero-rect sparse root, and the test fails.
323 lines
21 KiB
YAML
323 lines
21 KiB
YAML
name: iOS
|
|
|
|
on:
|
|
pull_request:
|
|
paths-ignore:
|
|
- 'docs/**'
|
|
- 'website/**'
|
|
- 'README.md'
|
|
- 'AGENTS.md'
|
|
- 'CHANGELOG.md'
|
|
- 'CONTEXT.md'
|
|
- 'CONTRIBUTING.md'
|
|
- 'LICENSE'
|
|
- 'SECURITY.md'
|
|
- '.github/actions/build-docs/action.yml'
|
|
- '.github/workflows/deploy.yml'
|
|
- '.github/workflows/pr-preview.yml'
|
|
- '.github/workflows/pr-preview-cleanup.yml'
|
|
# Routing (#1781 A9-2). Everything below is derived from the affected selector's
|
|
# device-lane ownership (scripts/check-affected/device-lanes.ts): unit tests no device
|
|
# lane runs, and trees another platform family owns. `pnpm check:gate-manifest` asserts
|
|
# this list against the selector over every tracked path, both ways — a path the selector
|
|
# routes to the iOS lane (or fails open on: tooling, workflows, package manifests) must not
|
|
# appear here, and a path it classifies as another family's or as a unit test must. The
|
|
# `push` trigger has no filter: main runs every lane unconditionally.
|
|
- '**/*.md'
|
|
- 'src/**/*.test.ts'
|
|
- 'src/**/__tests__/**/*.ts'
|
|
- 'packages/*/src/**/*.test.ts'
|
|
- 'packages/*/src/**/__tests__/**/*.ts'
|
|
- 'packages/platform-android/src/**'
|
|
- 'packages/capture-kit/src/snapshot/snapshot-presentation/android/**'
|
|
- 'packages/platform-harmonyos/src/**'
|
|
- 'packages/platform-linux/src/**'
|
|
- 'packages/platform-vega/src/**'
|
|
- 'packages/platform-web/src/**'
|
|
- 'android/**'
|
|
- 'linux/**'
|
|
- 'test/integration/replays/android/**'
|
|
- 'test/integration/replays/linux/**'
|
|
- 'test/integration/replays/macos/**'
|
|
- 'test/integration/android-**'
|
|
- 'test/integration/smoke-android-**'
|
|
- 'test/integration/smoke-linux-**'
|
|
- 'test/integration/linux-e2e/**'
|
|
- 'test/integration/smoke-macos-**'
|
|
- 'test/integration/smoke-web-**'
|
|
- 'test/integration/macos-e2e/**'
|
|
- 'test/integration/web-e2e/**'
|
|
push:
|
|
branches:
|
|
- main
|
|
|
|
permissions:
|
|
contents: read
|
|
actions: read
|
|
|
|
concurrency:
|
|
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
smoke-ios:
|
|
name: Smoke Tests
|
|
runs-on: macos-26
|
|
timeout-minutes: 80
|
|
env:
|
|
IOS_RUNTIME_VERSION: '26.2'
|
|
AGENT_DEVICE_STATE_DIR: ${{ github.workspace }}/.tmp/agent-device-state
|
|
AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH: ${{ github.workspace }}/.tmp/ios-runner-derived
|
|
AGENT_DEVICE_IOS_PREPARE_TIMEOUT_MS: '420000'
|
|
AGENT_DEVICE_XCUITEST_INCLUDE_UNIT_TESTS: '1'
|
|
# A generic simulator destination leaves the active arch undefined and Xcode 26.6
|
|
# defaults it to x86_64, which runs the whole runner under Rosetta on arm64 hosts.
|
|
# Pin the native slice: measured ~30% faster commits on identical CI hardware
|
|
# (#1874 diagnosis, PR #1941).
|
|
AGENT_DEVICE_XCUITEST_ARCHS: 'arm64'
|
|
AGENT_DEVICE_IOS_APP_EVENT_URL_TEMPLATE: agent-device-test-app:///automation?event={event}&payload={payload}
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
|
|
- name: Set fixture producer wait policy
|
|
id: fixture-producer
|
|
run: |
|
|
set -euo pipefail
|
|
WAIT_SECONDS=1800
|
|
if [ "${{ github.event_name }}" = "pull_request" ] && [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]; then
|
|
echo "Fork pull request cannot publish the shared fixture artifact; a cache miss will build inline."
|
|
WAIT_SECONDS=0
|
|
fi
|
|
echo "wait-seconds=$WAIT_SECONDS" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Setup toolchain
|
|
uses: ./.github/actions/setup-node-pnpm
|
|
with:
|
|
cache-dependency-path: |
|
|
pnpm-lock.yaml
|
|
examples/test-app/pnpm-lock.yaml
|
|
|
|
- name: Establish host focus canary
|
|
id: host-focus-canary
|
|
run: |
|
|
set -euo pipefail
|
|
osascript -e 'tell application "Finder" to activate'
|
|
sleep 1
|
|
FRONTMOST="$(osascript -e 'tell application "System Events" to get bundle identifier of first application process whose frontmost is true')"
|
|
test "$FRONTMOST" = "com.apple.finder"
|
|
mkdir -p .tmp
|
|
echo "$FRONTMOST" > .tmp/ios-host-focus-before
|
|
|
|
- name: Restore and build iOS XCTest runner
|
|
uses: ./.github/actions/setup-apple-runner-build
|
|
with:
|
|
derived-path: ${{ env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH }}
|
|
cache-key-prefix: ios-runner-prebuilt
|
|
cache-key-suffix: -ios-${{ env.IOS_RUNTIME_VERSION }}-arm64
|
|
gate: swift-runner-ios
|
|
xcuitest-platform: ios
|
|
xcuitest-destination: generic/platform=iOS Simulator
|
|
|
|
- name: Boot iOS test simulator
|
|
id: ios-simulator
|
|
uses: ./.github/actions/boot-ios-test-simulator
|
|
with:
|
|
runtime-version: ${{ env.IOS_RUNTIME_VERSION }}
|
|
preferred-device-name: iPhone 17 Pro
|
|
|
|
- name: Verify clean-installed Simulator snapshot bridge preparation
|
|
if: github.event_name == 'pull_request'
|
|
env:
|
|
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
|
run: |
|
|
git fetch origin "$BASE_SHA" --depth=1
|
|
if git diff --quiet "$BASE_SHA"...HEAD -- \
|
|
apple/snapshot-bridge \
|
|
packages/platform-apple/src/snapshot-source \
|
|
scripts/check-package.ts \
|
|
scripts/size-report-install.mjs \
|
|
scripts/size-report-package.mjs; then
|
|
echo "Snapshot bridge packaging is unchanged; skipping preparation proof."
|
|
exit 0
|
|
fi
|
|
pnpm build
|
|
pnpm exec vitest run packages/platform-apple/src/snapshot-source/native-runtime.test.ts
|
|
pnpm check:package -- --verify-snapshot-bridge-preparation
|
|
|
|
- name: Run targeted iOS runner XCTest regressions
|
|
run: |
|
|
set -o pipefail
|
|
XCTESTRUN_PATH="$(find "$AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH/Build/Products" -maxdepth 1 -name '*.xctestrun' -print -quit)"
|
|
test -n "$XCTESTRUN_PATH"
|
|
xcodebuild test-without-building \
|
|
-xctestrun "$XCTESTRUN_PATH" \
|
|
-destination "platform=iOS Simulator,id=${{ steps.ios-simulator.outputs.simulator-udid }}" \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSinglePointerFlingFallsBackToXCTestCoordinateDragWhenPrivateSynthesisFails \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testAlertDispatchResolvesItsOwnModalWithoutCoordinateTapRoutingProbe \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testAlertResolutionCannotBypassRequestedDeadline \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testTypeWithoutResolvedInputReturnsTypedFailureBeforeDispatchingText \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testBareTypeUsesTappedInputWhenSoftwareKeyboardIsHidden \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testHardwareKeyboardResponderConfirmsItsOwnKeyboardFocus \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPenalizedCoordinateTapOnNonTextControlDoesNotAuthorizeBareType \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testBareDelayedTypeFailsWhenTappedInputDisappearsMidCommand \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSynthesizedTextCommitProgressWalksExpectedPrefixOnly \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testEmptyReplacementWithoutResolvableTargetFailsClosed \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testTextEntryTapWitnessIsBoundToTargetIdentity \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testCoordinateTapTextInputProbeSkipsPenalizedXCTestChannel \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testFreshCoordinateTapContainsUnavailableTextInputProbe \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testTextInputProbeIssueScopeIsThreadBound \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testTextInputProbePreservesEnclosingRunnerWait \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSuppressedAxIssueMakesTextInputProbeUnavailable \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testHealthyCoordinateTapPreservesBareTypingWitness \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testTextInputProbeContainmentExcludesRequiredReadsAndLaterIssues \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testCoordinateTextInputCandidateMustBeEnabledAndContainTheTouchPoint \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testQuerySelectorPrefersHittableMatchOverNonHittableDuplicate \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testActivateTargetSkipsForegroundAndActivatesNonForegroundApplication \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testMissingBundleCommandInvalidatesCompleteCachedTargetState \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testCachedTargetInvalidationClearsProcessBoundState \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testAlertResolutionCannotBypassRequestedDeadline \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testAlertAcceptTreatsOpenAsAffirmative \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testAlertAcceptDoesNotActivateAReplacementWithASharedButton \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testAlertDismissDoesNotActivateAReplacementWithTheSameTitle \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testAlertCannotProveAnIdenticalReplacementAndDoesNotActivateIt \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testAlertDeadlineBeforeActivationLeavesTheOriginalUntouched \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSystemModalProbeSliceSharesAndClampsToPlanDeadline \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testDispatchRecoverySkipsBookkeepingWhileXCTestChannelOccupied \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testBoundedSystemModalProbeTimeoutRecoversThenReleasesOnDrain \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testBoundedSystemModalProbeTimeoutRecoversThenReleasesOnDrainForSnapshotRaw \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSnapshotTraversalIdentityPreservesSameOriginNodesWithDifferentBounds \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSnapshotPresentationPreservesCurrentWireShape \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRegularPresentationKeepsNestedClipGeometryCumulative \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRegularPresentationKeepsFramelessSemanticCarriersNonActionableAndNonClipping \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRawPresentationKeepsReportedOffscreenAndFramelessFacts \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testFixedSeedRegularPresentationMaintainsCumulativeClipInvariant \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPresentationFailureKeepsItsNamedSnapshotQualityReason \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRegularPresentationPublishesEffectiveRectWhileRawKeepsReportedFrame \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSnapshotPresentationOwnsBackendNeutralEligibility \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSnapshotPresentationOwnsScopeAndRelativeDepth \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPresentationRefusesAnAcquisitionCapturedForTheOtherProjection \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testCaptureHintIsTheOnlyAcquisitionViewOfARequest \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRegularDepthFrontierSurvivesStructuralWrapperCollapse \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRegularDepthFrontierKeepsVisibleIndependentChildPastClippedParent \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRegularFoldClipsScrollOverflowReparentsAndBooksHints \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRegularFoldKeepsWindowCarriersButNeverHittableOutsideClip \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRegularFoldDropsSubPixelContentlessDecorationOnEveryBackend \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPlainViewportPolicyFoldsWithoutAncestorCursor \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPlainViewportPolicyDoesNotClipToScrollAncestor \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testEffectiveGeometryIntersectsViewportAndAncestorClip \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testEffectiveGeometryKeepsReportedOriginWhenFullyClipped \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRegularPresentationRoutesThroughVisibilityFold \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRegularPresentationPublishesGeometricActionabilityWithoutOcclusionOrTypeGate \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSnapshotAcquisitionDoesNotReintroduceRunnerOcclusionScan \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSnapshotScopePolicyMatchesGoldenParityTable \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testScrollContainerTypeNamesMatchElementTypeSet \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPrivateAXDepthLimitedRequiresEveryFrontierResolved \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testDeepExtensionCountsMissedFrontiers \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPreferredPrivateAXBackendPlansAsPenalized \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPreferredTreeBackendPinsRegularPlanAndLeavesStructuredEvidence \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRawDiagnosticPlanCarriesOnlyBackendsThatCanServeRaw \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSnapshotBackendDeclarationsMatchCapabilityFixture \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testProjectionMismatchFailureIsStructuredAndNotAnAxFailure \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPrivateAXRegularPresentationProjectsToViewportAndKeepsScrollHint \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPrivateAXRawProjectionKeepsEveryAcquiredNode \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPrivateAXRawProjectionAppliesRequestedTraversalDepth \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPrivateAXPresentationKeepsOffscreenSubtreeExcludedWhenChildFramesAreClamped \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPrivateAXGeometrylessSemanticsAreNeverActionableOrScrollContexts \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPrivateAXAcquisitionDoesNotInterpretScope \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPrivateAXInteractiveFiltersLoginLikeHiddenDrawer \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testDecodedPreferredBackendReachesOptionsAndApplicablePlan \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testSparsePayloadReasonMatrix \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testStampedPayloadTruncationTracksCompletenessNotRecoveryProvenance \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRunnerScreenshotStabilitySettledNeedsEnoughSamples \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRunnerScreenshotStabilitySettledTrueWhenWindowMatches \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRunnerScreenshotStabilitySettledFalseOnMidWindowMismatch \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRunnerScreenshotStabilitySettledFalseOnFailedCapture \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRunnerScreenshotStabilitySettledOnlyLooksAtTheTrailingWindow \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRunnerScreenshotStabilitySettledRejectsDegenerateRequirement \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testCustomActionsRequestPinsPrivateAXBackend \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPrivateAXNodesCarryAnnotatedCustomActions \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testRequestPinnedBackendReportsItsOwnReason \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testCustomActionCoverageParsesOnlyCompletePairs \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPartialCustomActionPassIsDisclosedAndCompleteOneIsNot \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testActionNamesAreCappedPerElementAndReported \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testHungCustomActionReadIsContainedAndRecovers \
|
|
-only-testing:AgentDeviceRunnerUITests/RunnerTests/testPrivateAXPinnedRegularDepthReachesAcquisitionAndPresentation 2>&1 | tee /tmp/agent-device-runner-regressions.log
|
|
node --input-type=module -e '
|
|
import { readFileSync } from "node:fs";
|
|
const log = readFileSync("/tmp/agent-device-runner-regressions.log", "utf8");
|
|
if (!/\] AGENT_DEVICE_RUNNER_OPTIONAL_PROBE_WAIT_COMPLETED$/m.test(log)) {
|
|
throw new Error("Optional observation ended the runner test before its wait completed");
|
|
}
|
|
'
|
|
|
|
- name: Preflight iOS runner through public CLI
|
|
run: |
|
|
pnpm clean:daemon
|
|
node --experimental-strip-types src/bin.ts prepare ios-runner --platform ios --udid "${{ steps.ios-simulator.outputs.simulator-udid }}" --timeout "$AGENT_DEVICE_IOS_PREPARE_TIMEOUT_MS" --json
|
|
pnpm clean:daemon
|
|
|
|
- name: Run iOS Settings replay smoke test
|
|
run: |
|
|
node --experimental-strip-types src/bin.ts test test/integration/replays/ios/simulator/01-settings.ad --udid "${{ steps.ios-simulator.outputs.simulator-udid }}" --retries 2 --artifacts-dir test/artifacts/replays-ios-simulator-smoke --report-junit test/artifacts/replays-ios-simulator-smoke.junit.xml
|
|
|
|
- name: Fetch current fixture app
|
|
id: fixture-app
|
|
uses: ./.github/actions/setup-fixture-app
|
|
with:
|
|
install: 'false'
|
|
wait-for-artifact-seconds: ${{ steps.fixture-producer.outputs.wait-seconds }}
|
|
|
|
- name: Report fixture cache source
|
|
run: |
|
|
echo "Fixture app source: ${{ steps.fixture-app.outputs.source }}" >> "$GITHUB_STEP_SUMMARY"
|
|
|
|
- name: Run fixture-backed iOS simulator E2E smoke
|
|
env:
|
|
AGENT_DEVICE_FIXTURE_APP_ID: ${{ steps.fixture-app.outputs.app-id }}
|
|
AGENT_DEVICE_FIXTURE_APP_PATH: ${{ steps.fixture-app.outputs.app-path }}
|
|
AGENT_DEVICE_IOS_E2E: '1'
|
|
AGENT_DEVICE_IOS_E2E_TIER: smoke
|
|
AGENT_DEVICE_IOS_UDID: ${{ steps.ios-simulator.outputs.simulator-udid }}
|
|
run: |
|
|
pnpm gate build
|
|
node --experimental-strip-types scripts/node-test-tmpdir.ts --test test/integration/smoke-ios-simulator-coverage.test.ts test/integration/smoke-ios-simulator.test.ts
|
|
|
|
# #1584: isolated, cheap automatic guard for the #1562 class of regression (iOS silently
|
|
# ignoring a `gesture pan` duration). Split out of gesture-lab.ad, which stays full-tier
|
|
# (dispatch-only via replays-manual.yml) because its multi-touch commands are a separate,
|
|
# heavier concern. This is the only automatic lane this assertion runs in today.
|
|
# --timeout raises the per-attempt budget past the script's own 60s: it absorbs an
|
|
# in-replay runner rebuild (measured 48-61s build + ~40s launch) on a runner cache miss;
|
|
# the normal path finishes in 21-34s.
|
|
- name: Run gesture pan-duration smoke replay
|
|
run: |
|
|
xcrun simctl install "${{ steps.ios-simulator.outputs.simulator-udid }}" "${{ steps.fixture-app.outputs.app-path }}"
|
|
pnpm clean:daemon
|
|
node --experimental-strip-types src/bin.ts test examples/test-app/replays/gesture-pan-duration.ad --udid "${{ steps.ios-simulator.outputs.simulator-udid }}" --timeout 180000 --retries 2 --artifacts-dir test/artifacts/replays-ios-gesture-pan-duration --report-junit test/artifacts/replays-ios-gesture-pan-duration.junit.xml
|
|
pnpm clean:daemon
|
|
|
|
- name: Assert simulator automation preserved host focus
|
|
if: ${{ always() }}
|
|
run: |
|
|
set -euo pipefail
|
|
test "$(cat .tmp/ios-host-focus-before)" = "com.apple.finder"
|
|
FRONTMOST="$(osascript -e 'tell application "System Events" to get bundle identifier of first application process whose frontmost is true')"
|
|
test "$FRONTMOST" = "com.apple.finder"
|
|
|
|
- name: Run iOS physical device smoke replay
|
|
if: env.IOS_UDID != ''
|
|
env:
|
|
IOS_UDID: ${{ vars.IOS_UDID }}
|
|
run: |
|
|
pnpm clean:daemon
|
|
node --experimental-strip-types src/bin.ts test test/integration/replays/ios/device/01-physical-lifecycle.ad --udid "$IOS_UDID" --retries 2 --artifacts-dir test/artifacts/replays-ios-device-smoke --report-junit test/artifacts/replays-ios-device-smoke.junit.xml
|
|
|
|
- name: Upload iOS artifacts
|
|
if: always()
|
|
uses: ./.github/actions/upload-agent-device-artifacts
|
|
with:
|
|
artifact-name: ios-artifacts
|
|
agent-state-dir: ${{ env.AGENT_DEVICE_STATE_DIR }}
|
|
runner-derived-path: ${{ env.AGENT_DEVICE_IOS_RUNNER_DERIVED_PATH }}
|