Package-level declarations

@TapTest, @TapDevice, @TapDevices, Devices, tapTest and the configuration it reads.

Types

Link copied to clipboard

When the JUnit extension captures device artifacts (tap.capture).

Link copied to clipboard
class DeviceBarrier(val parties: Int, val oneShot: Boolean = false)

Coroutine coordination for simultaneous multi-device phases. All waiting is suspension (await), never thread blocking, and cancellation is safe: a waiter cancelled before the barrier trips leaves the barrier intact for the rest.

Link copied to clipboard

How long the JUnit extension keeps a test's devices attached (TapTest.deviceLifetime).

Link copied to clipboard

The devices opened for one test, by role.

Link copied to clipboard
data class TapConfig(val serials: List<String>, val artifactsDir: Path, val acquireTimeout: Duration, val pinnedRoles: Map<String, String>, val manageDaemon: Boolean = false, val capture: CaptureMode = CaptureMode.ON_FAILURE)

Resolved once per JVM from system properties, falling back to environment variables named by envName (tap.artifactsDir → TAP_ARTIFACTS_DIR, tap.device.sender → TAP_DEVICE_SENDER).

Link copied to clipboard
annotation class TapDevice(val role: String = DEFAULT_ROLE)

Injects the Device bound to role; the default role is "device".

Link copied to clipboard
annotation class TapDevices(val roles: String)

Declares the named roles a test (or every test in a class) needs; inject them as Devices.

Link copied to clipboard
class TapExtension : BeforeEachCallback, AfterEachCallback, AfterAllCallback, ParameterResolver, InvocationInterceptor

Per-test device sessions for JUnit 5, over the coroutine client. Before each test it maps every declared role to a serial (rotating the starting device from test to test; a single-role test also moves on to the next device when one is busy), creates the per-test root Job, and opens one driver session per role — in sorted serial order, waiting up to tap.acquireTimeoutSeconds for a device another session holds, so two multi-device tests can never deadlock — all as children of the root job. The test body runs only inside tapTest, which binds this state and installs the SDK TapContext; Device calls outside it fail with a usage error, so plain metadata-only tests stay possible but cannot touch live devices.

Link copied to clipboard
class TapLauncherSessionListener : LauncherSessionListener

Registered through META-INF/services; closes SharedConnection once all tests have run.

Link copied to clipboard
@Target(allowedTargets = [AnnotationTarget.CLASS])
@ExtendWith(value = [TapExtension::class])
annotation class TapTest(val deviceLifetime: DeviceLifetime = DeviceLifetime.PER_TEST)

Enables Tap for a test class: one driver session per declared role is opened before each test and closed (with failure artifacts captured first) after it.

Properties

Link copied to clipboard
const val DEFAULT_ROLE: String

Functions

Link copied to clipboard
fun tapTest(block: suspend CoroutineScope.() -> Unit)

The mandatory entry point for suspending framework calls in JUnit tests: @Test fun x(device: Device) = tapTest { ... } (a block body works too). tapTest returns Unit, so the test method compiles to a void JUnit can discover whatever the block's last expression is. JUnit test methods are not suspend, so this is the real-time runBlocking-style bridge onto the extension-owned per-test context (root job + TapContext); it never uses virtual time because ADB, devices and command deadlines are external real-time systems.