browser_tester 1.5.0

Deterministic lightweight browser runtime for Rust tests
Documentation
# browser-tester

A deterministic browser-like testing crate implemented entirely in Rust.

- Japanese README: [translations/ja/README.md]translations/ja/README.md
- Architecture: [doc/architecture.md]doc/architecture.md
- Capability matrix: [doc/capability-matrix.md]doc/capability-matrix.md
- Mock guide: [doc/mock-guide.md]doc/mock-guide.md
- HTML spec conformance roadmap: [doc/html-spec-conformance-roadmap.md]doc/html-spec-conformance-roadmap.md
- Developed by [Finite Field, K.K.]https://finitefield.org

## Purpose

- Run DOM and script tests deterministically in a single process.
- Test browser-like interactions without an external browser, WebDriver, or Node.js.
- Keep time, randomness, and test-only browser APIs under Rust-side control.

## Quick Start

```rust
use browser_tester::Harness;

fn main() -> browser_tester::Result<()> {
    let html = r#"
      <input id='name' />
      <button id='submit'>Submit</button>
      <p id='result'></p>
      <script>
        document.getElementById('submit').addEventListener('click', () => {
          const name = document.getElementById('name').value;
          document.getElementById('result').textContent = `Hello, ${name}`;
        });
      </script>
    "#;

    let mut harness = Harness::from_html(html)?;
    harness.type_text("#name", "Alice")?;
    harness.click("#submit")?;
    harness.assert_text("#result", "Hello, Alice")?;
    Ok(())
}
```

## Core API

Constructors:

- `Harness::from_html(html)`
- `Harness::from_html_with_url(url, html)`
- `Harness::from_html_with_local_storage(html, &[("key", "value"), ...])`
- `Harness::from_html_with_url_and_local_storage(url, html, &[("key", "value"), ...])`

Actions:

- `type_text`
- `set_select_value`
- `set_input_files`
- `set_checked`
- `click`
- `press_enter`
- `copy`
- `paste`
- `cut`
- `focus`
- `blur`
- `submit`
- `dispatch`
- `dispatch_keyboard`

Assertions:

- `assert_text`
- `assert_value`
- `assert_checked`
- `assert_exists`
- `dump_dom`

Time and scheduling:

- `now_ms`
- `advance_time`
- `advance_time_to`
- `run_due_timers`
- `run_next_timer`
- `run_next_due_timer`
- `flush`
- `pending_timers`
- `clear_timer`
- `clear_all_timers`

Trace and diagnostics:

- `enable_trace`
- `take_trace_logs`
- `set_trace_stderr`
- `set_trace_events`
- `set_trace_timers`
- `set_trace_log_limit`

## Test Mocks

Main mock families:

- `fetch`
- `confirm` / `prompt` / `alert`
- `window.print()`
- `location` and history-backed mock pages
- `navigator.clipboard`
- `localStorage` seed state
- download capture
- `input[type="file"]`
- `matchMedia`

Full API details and examples are in [doc/mock-guide.md](doc/mock-guide.md).

Minimal fetch mock example:

```rust
use browser_tester::Harness;

fn main() -> browser_tester::Result<()> {
    let html = r#"
      <button id='run'>run</button>
      <p id='out'></p>
      <script>
        document.getElementById('run').addEventListener('click', () => {
          fetch('https://app.local/api/message')
            .then((res) => res.text())
            .then((text) => {
              document.getElementById('out').textContent = text;
            });
        });
      </script>
    "#;

    let mut h = Harness::from_html(html)?;
    h.set_fetch_mock("https://app.local/api/message", "hello");
    h.click("#run")?;
    h.assert_text("#out", "hello")?;
    assert_eq!(
        h.take_fetch_calls(),
        vec!["https://app.local/api/message".to_string()]
    );
    Ok(())
}
```

## Runtime Constraints

- `eval` is intentionally not implemented.
- `Date.now()` and `performance.now()` are backed by a fake clock.
- `Math.random()` is deterministic and can be reseeded with `set_random_seed`.
- Real network I/O is not the target. `fetch` should be used with mocks.
- Rendering, layout, style application, and the accessibility tree are intentionally partial.
- This crate provides a deterministic browser-like subset, not full browser compatibility.

Form submission policy:

- `Harness::submit(selector)` follows a user-like submission path.
- Script-side `form.requestSubmit([submitter])` also follows the user-like path.
- Script-side `form.submit()` bypasses validation and does not dispatch `submit`.

## Running Tests

Run the main test suite:

```bash
cargo test
```

Run by test layer:

```bash
scripts/run-test-layer.sh contract
scripts/run-test-layer.sh subsystem dom_navigation_dialog
scripts/run-test-layer.sh integration issue_174_175
scripts/run-test-layer.sh fuzz
```

Run repository maintenance guardrails:

```bash
scripts/check-file-size-guard.sh
```

Regular integration tests are grouped under a single `integration_suite` target to reduce
Cargo's per-file test crate and link overhead:

```bash
cargo test --test integration_suite issue_174_175
```

Minimal public contract coverage for stable `Harness` APIs:

```bash
cargo test --test contract_harness_core
```

If you only want to confirm the contract target still builds:

```bash
scripts/run-test-layer.sh contract-build
```

Property and fuzz tests for parser and runtime:

```bash
# default: parser=256 cases, runtime=128 cases
cargo test --test parser_property_fuzz_test --test runtime_property_fuzz_test -- --nocapture

# quick profile
BROWSER_TESTER_PROPTEST_CASES=64 \
BROWSER_TESTER_RUNTIME_PROPTEST_CASES=64 \
cargo test --test parser_property_fuzz_test --test runtime_property_fuzz_test

# deep profile
BROWSER_TESTER_PROPTEST_CASES=1024 \
BROWSER_TESTER_RUNTIME_PROPTEST_CASES=512 \
cargo test --test parser_property_fuzz_test --test runtime_property_fuzz_test
```

- `BROWSER_TESTER_PROPTEST_CASES`: default parser-oriented case count
- `BROWSER_TESTER_RUNTIME_PROPTEST_CASES`: runtime action case count
- shrunk failing seeds are stored in:
  - `tests/proptest-regressions/parser_property_fuzz_test.txt`
  - `tests/proptest-regressions/runtime_property_fuzz_test.txt`

## Documentation

- Architecture and subsystem overview: [doc/architecture.md]doc/architecture.md
- Capability classification: [doc/capability-matrix.md]doc/capability-matrix.md
- File-size guard and allowlist policy: [doc/file-size-guard.md]doc/file-size-guard.md
- Public API checklist: [doc/public-api-checklist.md]doc/public-api-checklist.md
- Subsystem ownership map: [doc/subsystem-map.md]doc/subsystem-map.md
- Test taxonomy and placement rules: [doc/test-taxonomy.md]doc/test-taxonomy.md
- Mock APIs and examples: [doc/mock-guide.md]doc/mock-guide.md
- HTML conformance roadmap: [doc/html-spec-conformance-roadmap.md]doc/html-spec-conformance-roadmap.md
- WPT audit inventory: [doc/p3-wpt-audit-inventory.md]doc/p3-wpt-audit-inventory.md