skip to content

What can a component test not prove when its host is a simulated document rather than a real browser engine?

level: seniorimportance: should knowfreq 50%

answer

  1. the tree is modelled, the rendering is not
  2. no layout engine, no paint
  3. geometry answers with stubs, not errors
  4. measurement branches never run there

basics

~20 s

Anything downstream of layout and paint. A simulated document models the tree and its APIs but lays nothing out, so measured sizes and positions, overflow, styling-driven visibility, scrolling, hit-testing and real navigation are stubbed or absent — and stubs answer, rather than fail.

solid answer

~50 s

A simulated host is an in-process implementation of the document APIs: it models the tree, attributes, events and the accessibility-relevant structure, which is why it supports the vast majority of component tests. What it does not include is a layout engine, a paint pipeline or a navigation stack. So geometry queries answer with stubbed values, styling that depends on the cascade and on box sizes is not resolved, nothing overflows or scrolls, pointer behaviour is not hit-tested, and a navigation is recorded rather than performed. The dangerous part is that these answer instead of failing: a width of zero satisfies a naive assertion, so the code path that depends on a real measurement is never exercised. Coverage for those belongs in a small real-engine suite, which is slower and more fragile and should stay small.

go deeper

for a junior

Know that the host in most component tests models the tree but never lays anything out, so numbers about size and position there are placeholders rather than observations.

for a middle

List the gap precisely — layout, style resolution, overflow and scrolling, paint, hit-testing, real navigation — and explain why stubbed geometry produces false green rather than a failure.

for a senior

Recount a bug this hid: a measurement-dependent branch that passed against zeros and broke in the product. Say where you moved that case and why you did not stub the numbers.

for a principal

Own the division of labour between a large fast suite and a small real-engine one. Define what qualifies for the slow tier, since an unbounded real-engine suite decays into the flakiest, least-trusted part of the pipeline.

## What a simulated host actually is A simulated document is an implementation of the document APIs written to run inside the test process. It holds a tree of nodes, supports creating and moving them, dispatches events with realistic propagation, tracks attributes and properties, and models enough of the accessibility-relevant structure that role- and name-based queries work. It boots in milliseconds and has no window on screen. That covers what most component tests are about: given these inputs, does the tree contain the right things, and does interacting with it produce the right changes. The gap is narrower than people fear — and sharper than they expect. ## Where the gap is | Capability | Simulated document | Real engine | | --- | --- | --- | | Tree structure, attributes, text | modelled | real | | Event dispatch and propagation | modelled | real | | Box sizes and positions | stubbed, typically zero | measured after layout | | Style resolution over the cascade | partial at best | full | | Overflow, clipping, scrolling | absent | real | | Paint, compositing, animation frames | absent | real | | Pointer hit-testing | absent — dispatch goes where you aim it | decided by geometry | | Navigation | recorded, not performed | performed | The consequence is not that visual bugs are missed in some vague sense. It is specific: **every behaviour a component derives from a measurement is untested there.** A component that collapses a toolbar when it is narrower than its contents, a list that decides how many rows fit, a popover that flips side when it would leave the viewport, a control that scrolls the selected option into view — all of them run their measurement branch against zeros. ## Why stubs are worse than errors If a geometry query threw, the test would fail and the author would notice. Instead it answers with zero, and zero is a value: - a guard like *only flip if the box would extend past the edge* never fires, so the default branch is the only branch the test ever sees; - an assertion that a measurement is not negative passes for the wrong reason; - an element with no size is not treated as hidden by most queries, so the test finds things a user could not see. That is the honest formulation of the limitation: the test does not go red, it goes green about something it never checked. A passing suite in a simulated host supports claims about structure, text, state transitions and interaction wiring — and supports no claim at all about layout. ## Where the missing coverage goes A real engine closes the gap because it is the real thing: it lays out, paints, hit-tests and navigates. It is also slower to start, needs a display or a headless mode, adds a process boundary between the test and the tree, and is more sensitive to timing and to environment differences between machines. Those are not reasons to avoid it; they are reasons to keep the number of cases small and chosen. A reasonable division: 1. **Simulated host, high volume** — rendered structure and text, state transitions, interaction wiring, conditional branches that do not depend on measurement. 2. **Real engine, low volume** — geometry-dependent behaviour, scrolling and overflow, focus and pointer interaction that depends on hit-testing, real navigation, and anything about what is actually visible. 3. **Neither** — claims about appearance in a specific browser, which need image comparison rather than assertions, and belong to a different kind of suite entirely. The thing to avoid is the middle failure mode: writing a measurement-dependent assertion in a simulated host, watching it pass, and believing the branch is covered. ## Recognising it in a failure Two signatures come up repeatedly. - A test passes but the feature is visibly broken, and the code near the failure reads a size, a position or a scroll offset. The test exercised the zero path. - A test fails with an inexplicable value — a height of zero where markup clearly implies content. Nothing was laid out; the number is a stub, not a defect in the component. In both cases the fix is not to make the simulated host lie more convincingly by stubbing measurements with plausible numbers. Hand-fed geometry proves only that the component does what you told it to do with the numbers you invented. Either move the case to a real engine, or restructure the component so the interesting decision is a pure function of a measurement it receives, and test that function directly with values you choose deliberately. ## The summary a reviewer wants A simulated host is the right default because it is fast and covers most of what component tests assert. Be explicit about its edge, treat a measurement in that host as an invented number rather than an observation, and keep a small, deliberate real-engine suite for the behaviour that only geometry can decide.

  • Why is a zero-valued measurement in a simulated host particularly dangerous?
    Because it is a value, not an error. Geometry queries answer with zeros, so guards that compare against a size never fire and naive assertions pass. The branch that depends on a real measurement is never exercised, and the suite reports success about something it never checked.
  • How do you decide what to move into a real-engine suite?
    Move what the simulated host cannot answer and the product would visibly break on: geometry-dependent behaviour, scrolling and overflow, pointer interaction that depends on hit-testing, and real navigation. Keep the set small and named, because each case is slower and more sensitive to environment than the component test it replaces.
  • Why is feeding plausible fake measurements into the simulated host a poor fix?
    It proves only that the component behaves as instructed with numbers you invented, while suggesting the measurement path is covered. It is more honest to extract the decision as a pure function of the measurement and test it over chosen values, and to verify the measurement itself in a real engine.

saying these in an interview costs you the question

  • Assumes measured widths and positions are real in a simulated host
  • Treats a zero measurement as a passing assertion rather than a stub
  • Believes the full style cascade is resolved in a simulated document
  • Claims a green component suite proves the layout is correct
  • Concludes a real browser engine carries no cost worth weighing