Skip to content

Browser plugin: add a step that saves the page DOM to a file in the artifacts directory #96

Closed
bddkit/bddkit-browser
#3

Description

@sergeym

Problem

There is no way to get the page's DOM out of a scenario. I execute the script returns a string into <<script_result>>, but nothing writes a variable to a file, so the only option is printing it to the log, where it is truncated. Writing a selector for an unfamiliar page means a full run per guess.

Proposal

Add two steps, kind action, same shape as I dump the browser console:

  • I dump the DOM – writes the serialized current document as HTML into the artifacts directory.
  • I dump the DOM of "<selector>" – same for one element's outerHTML (CSS, xpath= or text=, like the other selectors).

Behaviour:

  • Never waits (like steps 26–28); use an eventual assertion to arm it.
  • The file name does not collide with a previous dump in the same scenario (dom-<n>.html).
  • on_failure gains a dom value (off by default); the failure diagnostic carries the file path.

Implementation notes

  • Add GET /session/{id}/source to webdriver.rs; the element form uses execute with arguments[0].outerHTML.
  • The source endpoint does not include shadow roots or iframe contents. Document this; walking them can be a follow-up.

Open questions

  • Masking: hidden fields, tokens and input values end up in the file. Dumps should go through the same masking as other output.
  • Screenshots have the same overwrite problem today (screenshot.png).

Note

The steps belong to the browser plugin (bddkit/bddkit-browser, src/steps.rs); filed here for tracking.


Generated by Claude Code

Activity

  1. sergeym commented on Oct 9, 2026

    @sergeym
    CollaboratorAuthor

    Implemented in bddkit/bddkit-browser#3. Decisions taken:

    • File names: dom-<n>.html and, as the issue noted, screenshot-<n>.png too. n counts from 1 per kind, per scenario, and starts over at the next scenario. The host already gives every step its own artifacts_dir, so nothing was being overwritten; the number records the order within a scenario, it does not prevent a collision. Both DOM steps share one counter.
    • I dump the DOM of: looks once and fails at once on a missing element (fatal; an action cannot answer not_yet). Arm it with an eventual assertion about the element, like steps 26–28.
    • on_failure: dom: off by default; the failure dump gets a DOM (html) entry with the file path, not the HTML itself.
    • Masking: not done. The plugin has no masking anywhere, and neither does the host. Console and network dumps are already raw. The DOM file contains hidden fields, tokens and attribute values as they are; the README says so, and it is why dom is opt-in. Masking would need a host-level mechanism first. Left open.
    • Shadow roots and iframe contents are not in either dump (page-source endpoint and outerHTML); documented, walking them is a follow-up.
    • CI: the e2e suite now fails instead of skipping when CI is set and the browser or bddkit is missing, so the examples cannot pass unrun.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions