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
96 changes: 96 additions & 0 deletions implementations/android-sdk/scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Android reference app scripts

Developer helper scripts for the Android reference implementation. They wrap the Gradle + `adb` +
emulator workflow so you can go from a clean checkout to a running app or a green E2E run with a
single command.

> [!NOTE]
>
> These scripts forward the mock server into the emulator with `adb reverse tcp:8000 tcp:8000` so
> the app can reach `http://localhost:8000`.

## Scripts

| Script | Purpose |
| ---------------- | -------------------------------------------------------------------- |
| `bootstrap.sh` | Build, install, and launch the app on an emulator for local dev |
| `run-e2e.sh` | Build, install, and run the UI Automator 2 instrumented E2E suite |
| `prepare-env.sh` | Validate the local environment without starting anything (fast fail) |

## Prerequisites

- Android SDK installed with `ANDROID_HOME` set, and `adb` on `PATH`.
- pnpm dependencies installed at the monorepo root (`pnpm install`).
- The JS bridge built: `pnpm --filter @contentful/optimization-js-bridge build` (`bootstrap.sh` and
`run-e2e.sh` build it for you unless `SKIP_BUILD=true`).

If no device or emulator is connected, `bootstrap.sh` starts an existing AVD (or creates a Pixel 7
API 35 AVD as a last resort), and `run-e2e.sh` auto-launches a visible emulator pinned to the
CI-aligned AVD `pixel_7_api35_e2e`.

## `bootstrap.sh`

Ensures a device is available, starts the mock server, sets up `adb reverse`, builds and installs
the app, and launches it. The mock server keeps running in the foreground (press `Ctrl+C` to stop it
and exit).

```sh
cd implementations/android-sdk
./scripts/bootstrap.sh
```

## `run-e2e.sh`

Ensures a visible emulator, starts the mock server, sets up `adb reverse`, builds and installs the
app and test APKs, then runs the UI Automator 2 instrumented suite. Logs are written to
`implementations/android-sdk/logs/` (`mock-server.log`, `test-results.log`).

```sh
cd implementations/android-sdk
./scripts/run-e2e.sh
```

Run a single test class or method:

```sh
./scripts/run-e2e.sh --test-class AnalyticsTests
./scripts/run-e2e.sh --test-class AnalyticsTests --test-method testTracksComponentImpressionEventsForVisibleEntries
```

Skip the build and reuse the installed APKs:

```sh
./scripts/run-e2e.sh --skip-build
```

Run `./scripts/run-e2e.sh --help` for the full option list.

## `prepare-env.sh`

Read-only validation: checks that the mock server is reachable, the bridge bundle is built, a device
is connected, and sets up `adb reverse`. It starts nothing, so it fails fast with a clear message.
It is wired in as a "Before launch" step for the **App** and **All UI Tests** run configurations in
Android Studio.

```sh
cd implementations/android-sdk
./scripts/prepare-env.sh
```

## Environment variables

| Variable | Default | `bootstrap.sh` | `run-e2e.sh` | `prepare-env.sh` | Notes |
| ----------------------------- | ------------------- | :------------: | :----------: | :--------------: | -------------------------------------------------------- |
| `MOCK_SERVER_PORT` | `8000` | ✅ | ✅ | ✅ | Port for the mock API server. |
| `SKIP_BUILD` | `false` | ✅ | ✅ | — | Reuse the existing build instead of rebuilding. |
| `EMULATOR_AVD` | `pixel_7_api35_e2e` | — | ✅ | — | AVD to require/auto-launch; pinned to match CI. |
| `DISABLE_EMULATOR_ANIMATIONS` | `true` | — | ✅ | — | Set `false` to keep emulator animation scales unchanged. |
| `FAIL_FAST` | `true` | — | ✅ | — | Set `false` to run the whole suite even after a failure. |
| `STREAM_BACKGROUND_LOGS` | `false` | — | ✅ | — | Set `true` to stream mock server logs to stdout. |
| `CI` | `false` | — | ✅ | — | Set `true` for CI mode. |

## Related

- [Android reference app README](../README.md)
- [iOS reference app scripts](../../ios-sdk/scripts/README.md)
- [Mock server](../../../lib/mocks/README.md)
26 changes: 26 additions & 0 deletions implementations/ios-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,32 @@ From the monorepo root, start the mock API server before running UI tests:
pnpm serve:mocks
```

## Running locally

The bootstrap script runs preflight checks, then configures, builds, and launches the app on an iOS
Simulator with the mock server running. When it finishes it leaves a simulator booted with the
reference app and the mock server running in the foreground:

```sh
cd implementations/ios-sdk
./scripts/bootstrap.sh
```

The preflight checks verify that you are on macOS with Xcode (full IDE, not just the Command Line
Tools), an iOS Simulator runtime, Node.js, and pnpm. If a check fails, the script prints the exact
remediation steps and stops before building anything. XcodeGen is installed automatically via
Homebrew if it is missing.

Useful environment variables:

- `APP_SHELL` — `swiftui` (default) or `uikit`.
- `IOS_SIM_NAME` — simulator device name (default `iPhone 16`); falls back to the first available
iPhone if the named device is absent.
- `SKIP_BUILD` — set to `true` to reuse the last build.

Unlike the Android app, no port forwarding is required: the iOS Simulator shares the host network,
so the app reaches the mock server at `localhost:8000` directly.

## Running E2E tests

Run the full suite against both app shells from `implementations/ios-sdk/`:
Expand Down
86 changes: 86 additions & 0 deletions implementations/ios-sdk/scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# iOS reference app scripts

Developer helper scripts for the iOS reference implementation. They wrap the XcodeGen +
`xcodebuild` + `simctl` workflow so you can go from a clean checkout to a running app or a green E2E
run with a single command.

> [!NOTE]
>
> These scripts only run on macOS with Xcode. They reach the mock server at `http://localhost:8000`;
> unlike the Android scripts, no port forwarding is needed because the iOS Simulator shares the host
> network.

## Scripts

| Script | Purpose |
| -------------- | ----------------------------------------------------------------- |
| `bootstrap.sh` | Configure, build, and launch the app on a simulator for local dev |
| `run-e2e.sh` | Run the XCUITest E2E suite against one or both app shells |

Both scripts run the same preflight checks first and stop with explicit remediation steps if
anything is missing, before building or running anything.

## Preflight checks

Both scripts verify, in order:

1. The host is macOS.
2. The Xcode Command Line Tools are installed (`xcode-select -p`).
3. A full Xcode install is selected and its license is accepted (`xcodebuild -version`).
4. An iOS Simulator runtime with at least one iPhone is available.
5. Node.js and pnpm are on `PATH`.
6. XcodeGen is installed — auto-installed via Homebrew if missing.

If a check fails, the script prints the exact command to fix it (for example
`xcode-select --install`, or installing Xcode from the App Store and running
`sudo xcode-select -s /Applications/Xcode.app/Contents/Developer`) and exits without building.

## `bootstrap.sh`

Runs preflight, then configures, builds, and launches the app. When it finishes it leaves a
simulator booted with the reference app and the mock server running in the foreground (press
`Ctrl+C` to stop the mock server and exit).

```sh
cd implementations/ios-sdk
./scripts/bootstrap.sh
```

## `run-e2e.sh`

Runs preflight, starts the mock server, resolves a simulator, and runs the XCUITest suite via
`xcodebuild test`. Result bundles are written to `implementations/ios-sdk/logs/<scheme>.xcresult`.

```sh
cd implementations/ios-sdk
./scripts/run-e2e.sh
```

Run a single test class against the SwiftUI shell:

```sh
ONLY_TESTING=OptimizationAppUITestsSwiftUI/PreviewPanelOverridesTests \
./scripts/run-e2e.sh
```

Run the full suite against both shells:

```sh
APP_SHELL=both ./scripts/run-e2e.sh
```

## Environment variables

| Variable | Default | `bootstrap.sh` | `run-e2e.sh` | Notes |
| ------------------ | ----------- | :------------: | :----------: | ---------------------------------------------------------------------------------------- |
| `APP_SHELL` | `swiftui` | ✅ | ✅ | `swiftui` or `uikit`. `run-e2e.sh` also accepts `both`. |
| `IOS_SIM_NAME` | `iPhone 16` | ✅ | ✅ | Simulator device name; falls back to the first available iPhone if absent. |
| `MOCK_SERVER_PORT` | `8000` | ✅ | ✅ | The app is hardcoded to `localhost:8000`; override only if you also edit `Config.swift`. |
| `SKIP_BUILD` | `false` | ✅ | ✅ | `bootstrap.sh` reuses the last build; `run-e2e.sh` runs `test-without-building`. |
| `ONLY_TESTING` | _(unset)_ | — | ✅ | Restrict the run to a target/class/method, e.g. `OptimizationAppUITestsSwiftUI/...`. |

## Related

- [iOS reference app README](../README.md)
- [Android reference app scripts](../../android-sdk/scripts/README.md)
- [Mock server](../../../lib/mocks/README.md)
Loading
Loading