# `testing.FakeSession`

> Contract 2.0.0 · package sha256 `a857eca95b35921109faf997094bb4192f12527d9d0fcd4be7e97f06425bad6e` · generated from `testing.d.ts` by `services/onsite-scripter/scripts/build-contract-docs.mjs`; edit the source, not this file.

Interface · `import type { FakeSession } from '@holostep-configurators/runtime-client/testing';` · stable · since 2.0.0 · section 24. /testing

A [`Session`](Session.md) that runs in Node with fake timers, plus controls for tests. How the fake runs:
- Time moves only on [`tick`](testing.FakeSession.tick.md): loads, decodes, timeouts, tweens, clips and `autoRotate` run on
  fake-clock ms. A commit to show, an event to dispatch, a camera move or a clip arms a frame
  16 fake ms ahead, which [`tick`](testing.FakeSession.tick.md) draws once it passes it; `frame()` draws one at once.
- Only a drawn frame presents commits and dispatches events (spec section 6.11), except
  'problem', which dispatches when it is recorded. Clips and camera moves step by the fake time
  since the previous drawn frame (the camera capped at 1/15 s), so `frame()` with no [`tick`](testing.FakeSession.tick.md)
  between steps nothing. A test pumps `tick(16)` and awaits between ticks, so promise
  continuations run: a write's Promise settles at its commit point, its events a frame later.
- Overlays: `hotspots.set`, `anchors.set` and `dimensions` apply at the next drawn frame, and
  'anchors:moved' fires at drawn frames, the anchors projected through the fake's camera and
  `viewport`, as on the runtime. [`hotspot`](testing.FakeSession.hotspot.md) clicks, hovers and leaves a badge ('hotspot:click',
  'hotspot:hover'), and [`rulers`](testing.FakeSession.rulers.md) reads the rulers shown; no read returns the badges or anchors.
- The camera: a [`pointer`](testing.FakeSession.pointer.md) press no drag claims is the shopper's camera gesture
  ('camera:control-start' and '-end'), and one pointer's path turns the camera as the
  runtime's orbit controls do, so 'camera:changed' and 'camera:rest' fire. [`resize`](testing.FakeSession.resize.md) resizes
  the element ('resize'). The in-page AR events ('xr:start', 'xr:end', 'xr:cta') never fire:
  the fake opens no AR session; try-on answers from `profile.tryOn`.
- [`capture()`](Session.capture.md) resolves `image` as a 1-byte placeholder `Blob` of the asked type ('image/png'
  unless `format` says 'jpeg'), not a picture; `snapshot` holds what it drew. [`export()`](Session.export.md)
  resolves a 1-byte `blob` likewise, once `profile.permits` lists 'export'.
- A member or setting the runtime doesn't build yet throws 'not built yet' at the call, as on
  the runtime, and [`supports()`](Session.supports.md) answers false for its id.

## Members

| Member | Kind | Summary |
| --- | --- | --- |
| <a id="tick"></a>[`tick`](testing.FakeSession.tick.md) | method | Advances fake time by `dtMs`, running every timer due on the way in due order, synchronously, the armed frame included (see above). |
| <a id="now"></a>[`now`](testing.FakeSession.now.md) | method | The fake's timeline, ms: the [`Frame.timeMs`](Frame.timeMs.md) a frame drawn at this moment reads, that is `performance.now()` when the session was made plus the fake time ticked since. |
| <a id="frame"></a>[`frame`](testing.FakeSession.frame.md) | method | Draws `count` frames now: presents, dispatches events, runs frame hooks. |
| <a id="pointer"></a>[`pointer`](testing.FakeSession.pointer.md) | method | Simulates canvas input on the fake clock: a press at `at`, then the path, then the release. |
| <a id="hotspot"></a>[`hotspot?`](testing.FakeSession.hotspot.md) | method · labs | The shopper's pointer on a hotspot badge, by its [`HotspotBadge.id`](HotspotBadge.id.md). |
| <a id="rulers"></a>[`rulers?`](testing.FakeSession.rulers.md) | method · labs | The rulers [`overlays.dimensions`](Overlays.dimensions.md) shows now, as the shopper reads them, so a planner's test asserts its labels, its per-module split and that they follow its writes: one entry per ruler, in set order (one set for … |
| <a id="resize"></a>[`resize?`](testing.FakeSession.resize.md) | method · labs | Resizes the element to `width` × `height` CSS px, as the page's layout would: the viewport `createFakeSession` took changes at once ([`camera.state.aspect`](CameraState.aspect.md), [`camera.project`](Camera.project.md), picks, [`info()`](Session.info.md)), 'resize' fires at the next… |
| <a id="script"></a>[`script`](testing.FakeSession.script.md) | method | Forces a member's next outcome, e.g. a load failure. |
| <a id="setarmodes"></a>[`setArModes`](testing.FakeSession.setArModes.md) | method | The AR probe's answer: sets `info().ar.modes` and turns `info().ar.pending` false at once; 'ar:modes' dispatches at the next drawn frame (`frame()` or `tick(16)`), as the fake's other events do, so call one of them… |
| <a id="detach"></a>[`detach`](testing.FakeSession.detach.md) | method | Simulates `el` leaving the document after [`boot`](boot.md), as spec section 6.5's disconnect row says. |
| <a id="record"></a>[`record`](testing.FakeSession.record.md) | method | Records `problem` as the runtime would, with `at` and `docs` filled: in `problems()` and [`info().problems`](InfoReport.problems.md), and to 'problem' handlers at once, as the runtime dispatches a recorded Problem (spec section 6.11, step 10). |
| <a id="trace"></a>[`trace`](testing.FakeSession.trace.md) | method | Every state change so far, in order: each operation's states (spec section 6.2), each drawn frame that presents commits (member 'frame') and each commit's dispatch (member 'events'). |
| <a id="problems"></a>[`problems`](testing.FakeSession.problems.md) | method | Every Problem recorded so far. |

Inherited from [`Session`](Session.md): [`revision`](Session.revision.md), [`seq`](Session.seq.md), [`history`](Session.history.md), [`input`](Session.input.md), [`overlays`](Session.overlays.md), [`document`](Session.document.md), [`transaction`](Session.transaction.md), [`beforeCommit`](Session.beforeCommit.md), [`undo`](Session.undo.md), [`redo`](Session.redo.md), [`on`](Session.on.md), [`onFrame`](Session.onFrame.md), [`idle`](Session.idle.md), [`capture`](Session.capture.md), [`export`](Session.export.md), [`activateAR`](Session.activateAR.md), [`canTryOn`](Session.canTryOn.md), [`tryOn`](Session.tryOn.md), [`endAR`](Session.endAR.md), [`describe`](Session.describe.md), [`supports`](Session.supports.md), [`permits`](Session.permits.md), [`applyDocument`](Session.applyDocument.md), [`info`](Session.info.md), [`destroy`](Session.destroy.md).

Inherited from [`Writer`](Writer.md): [`node`](Writer.node.md), [`find`](Writer.find.md), [`collection`](Writer.collection.md), [`apply`](Writer.apply.md), [`applyPatch`](Writer.applyPatch.md), [`setSceneModel`](Writer.setSceneModel.md), [`select`](Writer.select.md), [`stage`](Writer.stage.md), [`materials`](Writer.materials.md), [`assembly`](Writer.assembly.md), [`camera`](Writer.camera.md), [`animations`](Writer.animations.md), [`labs`](Writer.labs.md), [`state`](Writer.state.md), [`getSceneModel`](Writer.getSceneModel.md).

## Declaration

```ts
export interface FakeSession extends Session {
  tick(dtMs: number): void;
  now(): number;
  frame(count?: number): void;
  pointer(input: {
    kind: 'click' | 'drag' | 'longPress' | 'move';
    at: {
      x: number;
      y: number;
    };
    to?: {
      x: number;
      y: number;
    };
    pointerType?: 'mouse' | 'pen' | 'touch';
    durationMs?: number;
    pointerId?: number;
  }): void;
  hotspot?(id: string, action?: 'click' | 'hover' | 'leave'): boolean;
  rulers?(): ReadonlyArray<{
    readonly axis: 'width' | 'height' | 'depth';
    readonly metres: number;
    readonly label: string;
    readonly part: Part | null;
  }>;
  resize?(width: number, height: number): void;
  script(member: string, result: {
    fail?: boolean;
    delayMs?: number;
    problem?: ProblemCode;
    collection?: string;
    cancel?: boolean;
  }): void;
  setArModes(modes: InfoReport['ar']['modes']): void;
  detach(): void;
  record(problem: Omit<Problem, 'at' | 'docs'>): void;
  trace(): readonly TraceEntry[];
  problems(): readonly Problem[];
}
```

## Generic-API test (spec 3.1)

| Rule | Result |
| --- | --- |
| 1. Neutral name | pass: `FakeSession` names no product |
| 2. A precedent | not recorded: no ledger row (coverage.json) names this member or its owner |
| 3. Two apps, or labs | not recorded: no ledger row names this member or its owner |
| 4. The cheaper fix first | not recorded per member (Appendix B decides it per need) |
