Files
Michał Pierzchała cd9a7ce41b test(android): add comprehensive emulator E2E coverage (#1482)
* test(android): add catalog emulator smoke coverage

* test(android): use stable snapshot diff mutation

* test(android): assert actual back destination

* test(android): separate keyboard and fill IMEs

* fix(ci): keep Android timing report in one shell

* refactor(test): simplify simulator e2e coverage

* test(android): assert stable diff landmarks

* fix(android): release snapshot helper gracefully

* fix(android): fully release snapshot helper runtime

* test(android): report coverage classifications

* fix(android): stabilize accessibility root capture

* fix(android): bound UiAutomation connection

* ci: upload worktree daemon diagnostics

* fix(android): cancel stalled wait captures

* fix(android): bound helper fallback lifecycle

* fix(android): harden emulator e2e lifecycle

* fix: align e2e changes with kernel package

* test(android): prove alert helper reuse directly

* fix(android): cancel stalled settle captures

* fix(android): separate helper retirement budgets
2026-07-30 15:10:21 +02:00

64 lines
2.1 KiB
TypeScript

import assert from 'node:assert/strict';
import fs from 'node:fs';
import path from 'node:path';
import type { LiveDeviceContext } from './runtime.ts';
export function computeMissingCoverage<BehaviorId extends string>(
context: LiveDeviceContext<BehaviorId>,
scenarios: readonly { id: string }[],
commandsForScenario: (scenarioId: string) => readonly string[],
behaviorsForScenario: (scenarioId: string) => readonly BehaviorId[],
) {
return {
missingBehaviors: scenarios
.flatMap((scenario) => behaviorsForScenario(scenario.id))
.filter((behavior) => (context.behaviorEvidence[behavior]?.length ?? 0) === 0),
missingCommands: scenarios
.flatMap((scenario) => commandsForScenario(scenario.id))
.filter((command) => (context.commandEvidence[command]?.length ?? 0) === 0),
missingScenarios: scenarios
.map((scenario) => scenario.id)
.filter((id) => !context.completedScenarios.includes(id)),
};
}
export function assertCoverageComplete<BehaviorId extends string>(
context: LiveDeviceContext<BehaviorId>,
scenarios: readonly { id: string }[],
commandsForScenario: (scenarioId: string) => readonly string[],
behaviorsForScenario: (scenarioId: string) => readonly BehaviorId[],
message: string,
): void {
assert.deepEqual(
computeMissingCoverage(context, scenarios, commandsForScenario, behaviorsForScenario),
{ missingBehaviors: [], missingCommands: [], missingScenarios: [] },
message,
);
}
export function writeCoverageReport<BehaviorId extends string>(
context: LiveDeviceContext<BehaviorId>,
extra: Record<string, unknown> = {},
): string {
const reportPath = path.join(context.artifactDir, 'coverage-report.json');
fs.writeFileSync(
reportPath,
JSON.stringify(
{
behaviorEvidence: context.behaviorEvidence,
commandEvidence: context.commandEvidence,
completedScenarios: context.completedScenarios,
...extra,
timings: {
runDurationMs: Date.now() - context.startedAtMs,
scenarios: context.timings,
},
},
null,
2,
),
);
return reportPath;
}