Stateful scenarios

Stateful, keyless browser scenarios with portable checkpoint evidence.

class layoutlens.scenarios.Scenario(source, *, base_url=None, steps=())[source]

A sequence whose chained methods return new scenarios.

Parameters:
tab(*, backwards=False)[source]

Press Tab or Shift+Tab and record the actual focus transition.

Parameters:

backwards (bool)

Return type:

Scenario

press(key)[source]

Press a Playwright keyboard key or chord, such as Escape or Shift+Tab.

Parameters:

key (str)

Return type:

Scenario

type(text)[source]

Type into the focused editable element, emitting keyboard and input events.

Parameters:

text (str)

Return type:

Scenario

fill(target, text)[source]

Fill a named or explicitly selected editable element.

Parameters:
Return type:

Scenario

click(target)[source]

Click an actionable target; obscured or missing targets interrupt the run.

Parameters:

target (str)

Return type:

Scenario

hover(target)[source]

Move the pointer over a target to reveal hover-dependent content.

Parameters:

target (str)

Return type:

Scenario

drag(source, target)[source]

Drag between actionable elements using Playwright’s pointer sequence.

Parameters:
Return type:

Scenario

navigate(url)[source]

Navigate in the existing browser context, retaining cookies and storage.

Parameters:

url (str)

Return type:

Scenario

resize(width, height)[source]

Resize the current page to test responsive state transitions.

Parameters:
Return type:

Scenario

pointer_move(x, y)[source]

Move the pointer to viewport CSS coordinates.

Parameters:
Return type:

Scenario

pointer_down(button='left')[source]

Press a pointer button without releasing it.

Parameters:

button (str)

Return type:

Scenario

pointer_up(button='left')[source]

Release a pointer button.

Parameters:

button (str)

Return type:

Scenario

checkpoint(name)[source]

Capture the current rendered state without resetting focus or media settings.

Parameters:

name (str)

Return type:

Scenario

expect_focus(target)[source]

Require the named element to receive focus, including inside open shadow DOM.

Parameters:

target (str)

Return type:

Scenario

expect_visible(target)[source]

Require a target to become visible within the action timeout.

Parameters:

target (str)

Return type:

Scenario

expect_hidden(target)[source]

Require a target to become hidden or detached, for example after dismissal.

Parameters:

target (str)

Return type:

Scenario

expect_url(url)[source]

Require an exact URL, or a route path with its optional query string.

Parameters:

url (str)

Return type:

Scenario

expect_text(target, text)[source]

Require the target’s rendered text to match an explicit content contract.

Parameters:
Return type:

Scenario

expect_count(target, count)[source]

Require a locator count, for example one modal instead of stacked dialogs.

Parameters:
Return type:

Scenario

expect_style(target, property_name, value)[source]

Require a computed CSS property, such as the expected focus-ring outline.

Parameters:
  • target (str)

  • property_name (str)

  • value (str)

Return type:

Scenario

expect_clickable(target)[source]

Require Playwright’s click actionability checks to pass without clicking.

Parameters:

target (str)

Return type:

Scenario

expect_tab_reaches(target, *, max_tabs=20)[source]

Require a target to be reachable within a bounded forward keyboard sequence.

Parameters:
Return type:

Scenario

to_dict()[source]

Export the executable definition; values supplied to type and fill are included.

Return type:

dict[str, Any]

classmethod from_dict(data, *, base_url=None)[source]

Load a declarative scenario; arbitrary script execution is unsupported.

Parameters:
Return type:

Scenario

classmethod load(path, *, base_url=None)[source]

Read a JSON scenario definition.

Parameters:
Return type:

Scenario

async run(*, browser='chromium', viewport='desktop', color_scheme='light', reduced_motion='reduce', locale='en-US', timezone_id='UTC', device_scale_factor=None, timeout=30000, policy='qualified')[source]

Run locally without an API key and return ordered receipts and checkpoints.

Parameters:
  • browser (str)

  • viewport (ViewportType | tuple[int, int])

  • color_scheme (str)

  • reduced_motion (str)

  • locale (str)

  • timezone_id (str)

  • device_scale_factor (float | None)

  • timeout (int)

  • policy (GatePolicy)

Return type:

ScenarioReport

Portable interaction receipts and checkpoint artifacts.

class layoutlens.scenarios.models.Step(*, action, target=None, value=None)[source]

One declarative browser action or explicit expectation.

Parameters:
  • action (Literal['tab', 'press', 'type', 'fill', 'click', 'hover', 'drag', 'navigate', 'resize', 'pointer_move', 'pointer_down', 'pointer_up', 'checkpoint', 'expect_focus', 'expect_visible', 'expect_hidden', 'expect_url', 'expect_text', 'expect_count', 'expect_style', 'expect_clickable', 'expect_tab_reaches'])

  • target (str | None)

  • value (Any)

validate_arguments()[source]

Reject malformed declarative steps before any browser action runs.

Return type:

Step

model_config = {'allow_inf_nan': False, 'extra': 'forbid', 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class layoutlens.scenarios.models.Event(*, sequence, step, time_ms, kind, url, detail=<factory>)[source]

An observed event, with run-relative time and the active step index.

Parameters:
model_config = {'allow_inf_nan': False, 'extra': 'forbid', 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class layoutlens.scenarios.models.StepResult(*, index, action, target=None, status='pass', before=<factory>, after=<factory>, evidence=<factory>, error=None)[source]

Action outcome, focus transition, and measured expectation evidence.

Parameters:
model_config = {'allow_inf_nan': False, 'extra': 'forbid', 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class layoutlens.scenarios.models.InteractionFinding(*, step, defect_class, element, evidence, exceptions=<factory>, level='candidate')[source]

A reproducible observation matching a reviewable interaction predicate.

Parameters:
model_config = {'allow_inf_nan': False, 'extra': 'forbid', 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class layoutlens.scenarios.models.ScenarioReport(*, schema_version=1, source, policy='qualified', definition_fingerprint, planned_steps, steps=<factory>, events=<factory>, findings=<factory>, checkpoints=<factory>, incomplete_reasons=<factory>)[source]

A complete or interrupted run, retaining its ordered evidence.

Parameters:
property gate_status: Literal['pass', 'fail', 'incomplete']

Keep execution gaps distinct from failed, explicitly requested contracts.

to_json()[source]

Serialize receipts and checkpoint metadata, excluding screenshot bytes.

Return type:

str

save(directory)[source]

Write a new run directory with individually verified checkpoint artifacts.

Parameters:

directory (str | Path)

Return type:

Path

classmethod load(path)[source]

Load saved receipts and reject corrupt or escaping checkpoint references.

Parameters:

path (str | Path)

Return type:

ScenarioReport

diff(after, **options)[source]

Compare corresponding named checkpoints across two scenario runs.

Parameters:
Return type:

ScenarioDiff

model_config = {'allow_inf_nan': False, 'extra': 'forbid', 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class layoutlens.scenarios.models.ScenarioDiff(*, checkpoints, transitions=<factory>, failed_expectations=<factory>, incomplete_reasons=<factory>)[source]

Checkpoint regressions and changed observed focus transitions.

Parameters:
property gate_status: Literal['pass', 'fail', 'incomplete']

Require comparable complete checkpoints before reporting a passing gate.

model_config = {'allow_inf_nan': False, 'extra': 'forbid', 'validate_default': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class layoutlens.browser.BrowserConfig(browser='chromium', color_scheme='light', reduced_motion='reduce', locale='en-US', timezone_id='UTC', device_scale_factor=None)[source]

Browser and emulation settings shared by captures and scenarios.

Parameters:
  • browser (str)

  • color_scheme (str)

  • reduced_motion (str)

  • locale (str)

  • timezone_id (str)

  • device_scale_factor (float | None)