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
17 changes: 14 additions & 3 deletions .github/workflows/e2e-manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ on:
required: true
default: false
type: boolean
exclude_timing_sensitive:
description: Exclude timing-sensitive optional scenarios (ON_NEXT_RESUME/ON_NEXT_SUSPEND)
required: false
default: true
type: boolean

jobs:
e2e-ios:
Expand Down Expand Up @@ -85,11 +90,17 @@ jobs:
env:
E2E_RETRY_COUNT: "3"
E2E_RETRY_DELAY_SEC: "30"
E2E_EXCLUDE_TIMING_SENSITIVE: ${{ inputs.exclude_timing_sensitive }}
run: |
TIMING_SENSITIVE_ARG=""
if [ "$E2E_EXCLUDE_TIMING_SENSITIVE" = "true" ]; then
TIMING_SENSITIVE_ARG="--exclude-timing-sensitive"
fi

if [ "${{ inputs.expo }}" = "true" ]; then
npm run e2e -- --app "${{ inputs.app }}" --platform ios --simulator "${{ steps.boot-simulator.outputs.simulator }}" --framework expo --retry-count "$E2E_RETRY_COUNT" --retry-delay-sec "$E2E_RETRY_DELAY_SEC"
npm run e2e -- --app "${{ inputs.app }}" --platform ios --simulator "${{ steps.boot-simulator.outputs.simulator }}" --framework expo --retry-count "$E2E_RETRY_COUNT" --retry-delay-sec "$E2E_RETRY_DELAY_SEC" $TIMING_SENSITIVE_ARG
else
npm run e2e -- --app "${{ inputs.app }}" --platform ios --simulator "${{ steps.boot-simulator.outputs.simulator }}" --retry-count "$E2E_RETRY_COUNT" --retry-delay-sec "$E2E_RETRY_DELAY_SEC"
npm run e2e -- --app "${{ inputs.app }}" --platform ios --simulator "${{ steps.boot-simulator.outputs.simulator }}" --retry-count "$E2E_RETRY_COUNT" --retry-delay-sec "$E2E_RETRY_DELAY_SEC" $TIMING_SENSITIVE_ARG
fi

e2e-android:
Expand Down Expand Up @@ -150,4 +161,4 @@ jobs:
arch: x86_64
profile: pixel_7
emulator-boot-timeout: 900
script: if [ "${{ inputs.expo }}" = "true" ]; then npm run e2e -- --app "${{ inputs.app }}" --platform android --framework expo --retry-count "$E2E_RETRY_COUNT" --retry-delay-sec "$E2E_RETRY_DELAY_SEC"; else npm run e2e -- --app "${{ inputs.app }}" --platform android --retry-count "$E2E_RETRY_COUNT" --retry-delay-sec "$E2E_RETRY_DELAY_SEC"; fi
script: TIMING_SENSITIVE_ARG=$([ "${{ inputs.exclude_timing_sensitive }}" = "true" ] && echo "--exclude-timing-sensitive" || echo ""); if [ "${{ inputs.expo }}" = "true" ]; then npm run e2e -- --app "${{ inputs.app }}" --platform android --framework expo --retry-count "$E2E_RETRY_COUNT" --retry-delay-sec "$E2E_RETRY_DELAY_SEC" $TIMING_SENSITIVE_ARG; else npm run e2e -- --app "${{ inputs.app }}" --platform android --retry-count "$E2E_RETRY_COUNT" --retry-delay-sec "$E2E_RETRY_DELAY_SEC" $TIMING_SENSITIVE_ARG; fi
14 changes: 7 additions & 7 deletions .github/workflows/e2e-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ on:
required: false
default: true
type: boolean
include_timing_sensitive:
description: Include timing-sensitive optional scenarios (ON_NEXT_RESUME/ON_NEXT_SUSPEND)
exclude_timing_sensitive:
description: Exclude timing-sensitive optional scenarios (ON_NEXT_RESUME/ON_NEXT_SUSPEND)
required: false
default: false
default: true
type: boolean

jobs:
Expand Down Expand Up @@ -146,11 +146,11 @@ jobs:
MAESTRO_DRIVER_STARTUP_TIMEOUT: "300000"
E2E_RETRY_COUNT: "3"
E2E_RETRY_DELAY_SEC: "30"
E2E_INCLUDE_TIMING_SENSITIVE: ${{ inputs.include_timing_sensitive }}
E2E_EXCLUDE_TIMING_SENSITIVE: ${{ inputs.exclude_timing_sensitive }}
run: |
TIMING_SENSITIVE_ARG=""
if [ "$E2E_INCLUDE_TIMING_SENSITIVE" = "true" ]; then
TIMING_SENSITIVE_ARG="--include-timing-sensitive"
if [ "$E2E_EXCLUDE_TIMING_SENSITIVE" = "true" ]; then
TIMING_SENSITIVE_ARG="--exclude-timing-sensitive"
fi

if [ "${{ startsWith(matrix.app, 'Expo') }}" = "true" ]; then
Expand Down Expand Up @@ -233,4 +233,4 @@ jobs:
arch: x86_64
profile: pixel_7
emulator-boot-timeout: 900
script: TIMING_SENSITIVE_ARG=$([ "${{ inputs.include_timing_sensitive }}" = "true" ] && echo "--include-timing-sensitive" || echo ""); if [ "${{ startsWith(matrix.app, 'Expo') }}" = "true" ]; then npm run e2e -- --app "${{ matrix.app }}" --platform android --framework expo --retry-count "$E2E_RETRY_COUNT" --retry-delay-sec "$E2E_RETRY_DELAY_SEC" $TIMING_SENSITIVE_ARG; else npm run e2e -- --app "${{ matrix.app }}" --platform android --retry-count "$E2E_RETRY_COUNT" --retry-delay-sec "$E2E_RETRY_DELAY_SEC" $TIMING_SENSITIVE_ARG; fi
script: TIMING_SENSITIVE_ARG=$([ "${{ inputs.exclude_timing_sensitive }}" = "true" ] && echo "--exclude-timing-sensitive" || echo ""); if [ "${{ startsWith(matrix.app, 'Expo') }}" = "true" ]; then npm run e2e -- --app "${{ matrix.app }}" --platform android --framework expo --retry-count "$E2E_RETRY_COUNT" --retry-delay-sec "$E2E_RETRY_DELAY_SEC" $TIMING_SENSITIVE_ARG; else npm run e2e -- --app "${{ matrix.app }}" --platform android --retry-count "$E2E_RETRY_COUNT" --retry-delay-sec "$E2E_RETRY_DELAY_SEC" $TIMING_SENSITIVE_ARG; fi
6 changes: 3 additions & 3 deletions e2e/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ npm run e2e -- --app Expo55Beta --framework expo --platform ios --maestro-only
| `--framework <type>` | 아니오 | Expo 예제 앱인 경우 `expo` 지정 |
| `--simulator <name>` | 아니오 | iOS 시뮬레이터 이름 (부팅된 시뮬레이터 자동 감지, 기본값 "iPhone 16") |
| `--maestro-only` | 아니오 | 빌드 단계 생략, 테스트 플로우만 실행 |
| `--include-timing-sensitive` | 아니오 | 타이밍 민감 optional 시나리오(`03`, `04`) 추가 실행. 기본값: 비활성 |
| `--exclude-timing-sensitive` | 아니오 | 타이밍 민감 optional 시나리오(`03`, `04`)를 제외합니다. 기본값: 비활성, 즉 로컬 실행에는 기본 포함 |

## 실행 과정

Expand Down Expand Up @@ -75,8 +75,8 @@ npm run e2e -- --app Expo55Beta --framework expo --platform ios --maestro-only
13. **optional 업데이트 플로우 실행** — 아래 조건에서 업데이트가 적용되는지 확인합니다.
- `01-optional-update-on-relaunch` — 앱을 종료 후 재실행할 때
- `02-optional-update-on-restart-button` — 앱 내 "Restart app" 버튼을 누를 때
- `03-optional-update-on-resume-after-20s` — 앱이 백그라운드에 20초 이상 머문 뒤 포그라운드로 돌아올 때 `ON_NEXT_RESUME`으로 업데이트가 적용되는지 확인합니다. `--include-timing-sensitive` 옵션 사용 시에만 실행
- `04-optional-update-on-suspend-after-20s` — 앱이 백그라운드에 20초 이상 머무는 동안 `ON_NEXT_SUSPEND`로 업데이트가 적용되고, 다음 포그라운드 진입 시 반영된 번들이 보이는지 확인합니다. `--include-timing-sensitive` 옵션 사용 시에만 실행
- `03-optional-update-on-resume-after-20s` — 앱이 백그라운드에 20초 이상 머문 뒤 포그라운드로 돌아올 때 `ON_NEXT_RESUME`으로 업데이트가 적용되는지 확인합니다. `--exclude-timing-sensitive`를 주지 않으면 실행됩니다.
- `04-optional-update-on-suspend-after-20s` — 앱이 백그라운드에 20초 이상 머무는 동안 `ON_NEXT_SUSPEND`로 업데이트가 적용되고, 다음 포그라운드 진입 시 반영된 번들이 보이는지 확인합니다. `--exclude-timing-sensitive`를 주지 않으면 실행됩니다.

## 아키텍처

Expand Down
6 changes: 3 additions & 3 deletions e2e/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ npm run e2e -- --app Expo55Beta --framework expo --platform ios --maestro-only
| `--framework <type>` | No | Use `expo` for Expo example apps |
| `--simulator <name>` | No | iOS simulator name (auto-detects booted simulator, defaults to "iPhone 16") |
| `--maestro-only` | No | Skip build step, only run test flows |
| `--include-timing-sensitive` | No | Also run timing-sensitive optional scenarios (`03`, `04`). Default: off |
| `--exclude-timing-sensitive` | No | Skip timing-sensitive optional scenarios (`03`, `04`). Default: off, so local runs include them |

## What It Does

Expand Down Expand Up @@ -75,8 +75,8 @@ The test runner (`e2e/run.ts`) executes these phases in order:
13. **Run optional update flows** — Verifies optional updates are applied when:
- `01-optional-update-on-relaunch` — The app is killed and relaunched.
- `02-optional-update-on-restart-button` — The in-app "Restart app" button is pressed.
- `03-optional-update-on-resume-after-20s` — Verifies `ON_NEXT_RESUME` applies the update when the app returns to foreground after staying in background for at least 20 seconds. Runs only with `--include-timing-sensitive`.
- `04-optional-update-on-suspend-after-20s` — Verifies `ON_NEXT_SUSPEND` applies the update while the app stays in background for at least 20 seconds, so the updated bundle is visible on the next foreground. Runs only with `--include-timing-sensitive`.
- `03-optional-update-on-resume-after-20s` — Verifies `ON_NEXT_RESUME` applies the update when the app returns to foreground after staying in background for at least 20 seconds. Runs unless `--exclude-timing-sensitive` is passed.
- `04-optional-update-on-suspend-after-20s` — Verifies `ON_NEXT_SUSPEND` applies the update while the app stays in background for at least 20 seconds, so the updated bundle is visible on the next foreground. Runs unless `--exclude-timing-sensitive` is passed.

## Architecture

Expand Down
14 changes: 8 additions & 6 deletions e2e/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface CliOptions {
framework?: "expo";
simulator?: string;
maestroOnly?: boolean;
includeTimingSensitive?: boolean;
excludeTimingSensitive?: boolean;
retryCount: number;
retryDelaySec: number;
}
Expand Down Expand Up @@ -50,8 +50,8 @@ const program = new Command()
.option("--simulator <name>", "iOS simulator name (default: booted)")
.option("--maestro-only", "Skip build, only run test flows", false)
.option(
"--include-timing-sensitive",
"Include timing-sensitive optional install mode scenarios (ON_NEXT_RESUME/ON_NEXT_SUSPEND)",
"--exclude-timing-sensitive",
"Exclude timing-sensitive optional install mode scenarios (ON_NEXT_RESUME/ON_NEXT_SUSPEND)",
false,
)
.option(
Expand Down Expand Up @@ -227,7 +227,7 @@ async function main() {
},
];

if (options.includeTimingSensitive) {
if (!options.excludeTimingSensitive) {
optionalUpdateScenarios.push(
{
name: "apply on resume after 20 seconds",
Expand All @@ -240,8 +240,10 @@ async function main() {
flowPath: path.resolve(__dirname, "flows-optional/04-optional-update-on-suspend-after-20s.yaml"),
},
);
} else {
console.log("\n=== [phase 4] skipping timing-sensitive scenarios (pass --include-timing-sensitive to enable) ===");
}

if (options.excludeTimingSensitive) {
console.log("\n=== [phase 4] skipping timing-sensitive scenarios (omit --exclude-timing-sensitive to include them) ===");
}

for (const scenario of optionalUpdateScenarios) {
Expand Down
Loading