|
| 1 | +// E2E (Playwright) conventions for the example demos. Each demo carries a sibling `e2e/` |
| 2 | +// Playwright project that drives the full passkey ceremony through Chrome's CDP virtual WebAuthn |
| 3 | +// authenticator (see examples/<demo>/e2e/). This wires that suite into `check` as an OPT-IN task: |
| 4 | +// it runs only when PK_RUN_E2E=1 (or -PrunE2e) is set, so the default local `check` and the |
| 5 | +// existing CI `build` job stay fast and Chrome-free. The dedicated CI e2e jobs |
| 6 | +// (.github/workflows/ci.yml) set the flag; the task itself provisions the Chrome channel via |
| 7 | +// `npx playwright install` (adding --with-deps when PW_INSTALL_DEPS is set, as CI does). |
| 8 | +plugins { |
| 9 | + java |
| 10 | +} |
| 11 | + |
| 12 | +// Every demo's webServer binds the same port (:8080), so two e2eTest tasks must never run at once. |
| 13 | +// With org.gradle.parallel=true a root-level `PK_RUN_E2E=1 ./gradlew check` would otherwise run the |
| 14 | +// sibling demos' suites concurrently and collide on the port. A shared build service with |
| 15 | +// maxParallelUsages=1 serializes them across the whole build (registerIfAbsent dedupes by name, so |
| 16 | +// all three demos share one lock). In CI each demo runs on its own isolated runner, so this lock is |
| 17 | +// a no-op there — it only matters for single-machine multi-demo runs. |
| 18 | +abstract class E2eServerLock : BuildService<BuildServiceParameters.None> |
| 19 | + |
| 20 | +val e2eServerLock = gradle.sharedServices.registerIfAbsent( |
| 21 | + "pkauthE2eServerLock", |
| 22 | + E2eServerLock::class, |
| 23 | +) { |
| 24 | + maxParallelUsages.set(1) |
| 25 | +} |
| 26 | + |
| 27 | +// Opt-in switch: PK_RUN_E2E=1 in the environment, or -PrunE2e on the command line. An explicitly |
| 28 | +// set PK_RUN_E2E (even to a non-"1" value) wins over the property, so `PK_RUN_E2E=0` forces off. |
| 29 | +// Resolved to a plain Boolean at configuration time (the env var / property become configuration |
| 30 | +// cache inputs) so the wiring below captures no script reference — an `onlyIf { provider.get() }` |
| 31 | +// closure would not be configuration-cache-serializable. |
| 32 | +val runE2e: Boolean = providers.environmentVariable("PK_RUN_E2E").orNull |
| 33 | + ?.let { it == "1" } |
| 34 | + ?: providers.gradleProperty("runE2e").isPresent |
| 35 | + |
| 36 | +val e2eDir = layout.projectDirectory.dir("e2e") |
| 37 | + |
| 38 | +val e2eTest = tasks.register<Exec>("e2eTest") { |
| 39 | + group = "verification" |
| 40 | + description = "Runs the Playwright end-to-end suite for this demo (opt-in: set PK_RUN_E2E=1)." |
| 41 | + usesService(e2eServerLock) // serialize across demos — they share port :8080 |
| 42 | + workingDir = e2eDir.asFile |
| 43 | + // `npm ci` pins deps to the committed lockfile. `playwright install` provisions the Chrome |
| 44 | + // channel the config pins (CDP virtual WebAuthn needs Google Chrome); --with-deps is added in |
| 45 | + // CI (PW_INSTALL_DEPS) to also install the OS libraries. The webServer in playwright.config.ts |
| 46 | + // boots this demo via the Gradle `run` task, so no separately-started server is needed. |
| 47 | + commandLine( |
| 48 | + "sh", "-c", |
| 49 | + "npm ci --no-audit --no-fund && " + |
| 50 | + "npx playwright install ${'$'}{PW_INSTALL_DEPS:+--with-deps} chrome && " + |
| 51 | + "npx playwright test", |
| 52 | + ) |
| 53 | +} |
| 54 | + |
| 55 | +// Wire into `check` only when opted in, so a default `check` (local or the CI `build` job) neither |
| 56 | +// depends on nor runs the suite. `./gradlew :examples:<demo>:e2eTest` still runs it on demand. |
| 57 | +if (runE2e) { |
| 58 | + tasks.named("check") { |
| 59 | + dependsOn(e2eTest) |
| 60 | + } |
| 61 | +} |
0 commit comments