English · 日本語
The showcase suite (Bajutsu's single cross-platform fixture)¶
Bajutsu's test fixture lives under
demos/showcase/. The same screen contract is built five times — SwiftUI and UIKit on iOS, Jetpack Compose and Views on Android, and one Flutter codebase that targets both platforms — mostly in an accessibility-on / -off pair per toolkit (Flutter's iOS build ships accessibility-on only, for now). Together, the five codebases register a dozentargets.<name>entries indemos/showcase/showcase.config.yaml. It packs the interaction surface a real app has (five tabs with push navigation, four modal styles shared by every codebase plus a fifth, iOS-only native alert, text entry, gestures, async loading, live + mockable networking, an OS-alert screen) into the smallest coherent app that still tells that whole story.BE-0079 made it the single iOS fixture, retiring the older
demo/sample/sample2apps; BE-0007 and BE-0008 then grew that iOS fixture into today's cross-platform one, adding the Android and Flutter twins. The authoritative, screen-by-screen contract — every identifier, every scenario mapping — isdemos/showcase/SPEC.md; this page summarizes how to reach it.
Related: scenarios · configuration · codegen · cli
Why two toolkits × two accessibility variants¶
The showcase makes visible the two axes on which Bajutsu's design rests:
- Toolkit axis (UIKit vs SwiftUI) — the two accessibility-on products (
showcase-swiftui/showcase-uikit) expose an identical identifier contract, so the shareddemos/showcase/scenarios/runs unchanged against either. What differs is the element tree the backend sees, which is exactly what a cross-toolkit driver must absorb. - Accessibility axis (no suffix ↔
-noax) — the-noaxbuilds carry no identifiers (idNamespaces: []). They are the controlled experiment for selector stability (DESIGN §5): the same goal recorded against both shows the value of accessibility work as a concrete diff, and they are therecord/doctor"missing accessibility" subjects.
Build and run¶
The four core iOS targets keep the original bundle ids
(com.bajutsu.showcase.ios.{swiftui,uikit}[.noax]) and deeplink schemes
(showcase{swiftui,uikit}[noax]). They build with XcodeGen + xcodebuild (project.yml is the
source of truth; .xcodeproj / build/ are gitignored). A fifth iOS target,
showcase-swiftui-bundled, runs the same SwiftUI app with no xcuitest: sub-config. A Simulator
run for it resolves to the wheel-bundled runner (BE-0292) instead of the locally built one, and
bajutsu doctor --target showcase-swiftui-bundled reports which one that is. The remaining seven
targets are the Android twins (android/, Jetpack Compose and Views,
BE-0007) and the Flutter twins on both platforms (flutter/,
BE-0008). They build with Gradle and the Flutter SDK respectively.
make -C demos/showcase swiftui-build # compile the SwiftUI a11y product for the Simulator
make -C demos/showcase run-swiftui # build → install → bajutsu run (XCUITest) against a booted Simulator
make -C demos/showcase doctor # the accessibility A/B: a11y grades Ready, -noax Blocked
make -C demos/showcase ui-test # the codegen path: scenario → XCUITest → xcodebuild test
make -C demos/showcase run-flutter # the Flutter twin on iOS: build → install → bajutsu run (XCUITest)
make -C demos/showcase run-flutter-android # the Flutter twin on Android: build → install → bajutsu run (adb)
make -C demos/showcase/android e2e-codegen # the Android twin: scenario → UI Automator → connectedAndroidTest (needs a booted emulator, BE-0294)
bajutsu run / serve also build the app on demand via each target's build command, so a manual
build is rarely needed.
Launch-environment hooks¶
Driven via launchEnv and passed as SIMCTL_CHILD_<NAME> (drivers).
BE-0079 removed the launch-env shortcuts to a data state and to a pushed screen: the catalog is
fixed (no seed knob), and a deeplink no longer jumps onto a detail — a detail is reached only by
tapping its row. BE-0107 finished the job by retiring SHOWCASE_TAB, the last launch-env shortcut to
a screen: the app always launches on the Stable tab, and every other tab is reached by tapping the
native tab bar. The XCUITest backend taps the native tab bar's individual tabs, so the tab-crossing
scenarios run on --backend ios. Every screen beyond the launch tab is
reached by driving the UI, and a scenario observes the app's own data rather than relying on an injected data state.
| Variable | Effect |
|---|---|
SHOWCASE_UITEST=1 |
disable animations (keeps condition waits tight) |
SHOWCASE_API_URL / SHOWCASE_HTTP_BASE |
base URLs for the catalog GET and the echo POST/DELETE endpoints |
The full identifier catalog, the deeplink grammar, and the primitive-to-scenario mapping are in
demos/showcase/SPEC.md.