docs: document rendering contribution workflow
This commit is contained in:
@@ -29,8 +29,24 @@ A few notes to keep the project maintainable:
|
||||
|
||||
## Building
|
||||
|
||||
Obscura supports four release configurations. Keep all four building when you
|
||||
change feature gates or shared code:
|
||||
|
||||
| Configuration | Command |
|
||||
| --- | --- |
|
||||
| Rendering | `cargo build --release -p obscura-cli --bins --features render` |
|
||||
| Rendering and stealth | `cargo build --release -p obscura-cli --bins --features render,stealth` |
|
||||
| No rendering | `cargo build --release -p obscura-cli --bins --no-default-features` |
|
||||
| No rendering, with stealth | `cargo build --release -p obscura-cli --bins --no-default-features --features stealth` |
|
||||
|
||||
The standard release archives and Docker image include rendering. The
|
||||
`-no-render` release variants keep the smaller DOM, JavaScript, networking,
|
||||
CDP, and automation runtime but intentionally omit screenshots, screencast,
|
||||
and PDF output.
|
||||
|
||||
```bash
|
||||
cargo build --release --features render # binary at ./target/release/obscura
|
||||
cargo build --release -p obscura-cli --bins --features render
|
||||
# binary at ./target/release/obscura
|
||||
```
|
||||
|
||||
- The first build compiles V8 from source: roughly 5 minutes and a few GB of
|
||||
@@ -52,6 +68,11 @@ cargo nextest run --release --features render -p <crate>
|
||||
cargo nextest run --release --features render --no-fail-fast
|
||||
```
|
||||
|
||||
If you changed shared DOM, JavaScript, CDP, CLI, or feature-gated code, also
|
||||
run the affected tests without rendering and build the no-render variant. A
|
||||
render-only request made through a no-render binary must return a clear
|
||||
unsupported error rather than panic or silently produce an invalid result.
|
||||
|
||||
`cargo test` runs the whole test binary in one process, but the engine holds a
|
||||
single V8 isolate per process, so the runtime tests fail under it. `nextest`
|
||||
runs each test in its own process, which is the only supported way.
|
||||
@@ -66,13 +87,56 @@ OBSCURA_BIN=./target/release/obscura python3 obstacle-course/run.py --runs 1 --w
|
||||
|
||||
It serves local fixtures, so it is deterministic and offline.
|
||||
|
||||
## Rendering changes
|
||||
|
||||
The native renderer is shared by every capture surface:
|
||||
|
||||
- CLI `fetch --screenshot` (`-s`), including viewport and full-page captures.
|
||||
- CDP `Page.captureScreenshot`, `Page.startScreencast`,
|
||||
`Page.stopScreencast`, and `Page.printToPDF`.
|
||||
- Puppeteer and Playwright screenshot and PDF calls made through CDP.
|
||||
- MCP `browser_screenshot` and `browser_pdf`.
|
||||
|
||||
It currently covers block, inline, flex, grid, table, float, positioned,
|
||||
overflow, and transformed layout, plus text, images, SVG, canvas, backgrounds,
|
||||
borders, animation, fixed and sticky elements, and screen and print output.
|
||||
This is an independent engine, not Chromium, so long-tail CSS, media,
|
||||
compositor behavior, and platform font rasterization can still differ. Fix the
|
||||
underlying layout or paint rule instead of adding site-specific behavior.
|
||||
|
||||
For layout, style, paint, image, animation, viewport, scrolling, or pagination
|
||||
changes:
|
||||
|
||||
1. Add or update a small deterministic fixture in `render-repros/` that
|
||||
isolates the behavior.
|
||||
2. Build the render binary, then run `render-repros/run.sh`. This captures each
|
||||
fixture in Obscura and Chromium and runs the structural checks.
|
||||
3. Run `render-repros/representative-suite/run.sh <new-output-dir>` at the top
|
||||
of the configured pages, then run it again with `bottom` as the second
|
||||
argument. The output directory must not already exist.
|
||||
4. Exercise the affected public surface, not just the renderer internally. In
|
||||
particular, cover clipped and full-page screenshots, viewport size and
|
||||
device-pixel ratio, and a scrolled page when geometry is involved.
|
||||
5. If lifecycle or animation scheduling changed, verify screencast frame
|
||||
delivery and acknowledgment. If print layout changed, verify PDF page size,
|
||||
margins, backgrounds, page ranges, and stream output where relevant.
|
||||
6. Compare old and new revisions with identical release builds, fixtures,
|
||||
viewport, device-pixel ratio, fonts, network state, settle time, scroll
|
||||
position, and capture options. Confirm resources loaded successfully before
|
||||
interpreting image differences.
|
||||
|
||||
Pixel deltas are useful tripwires, but they are not a fidelity score by
|
||||
themselves. Include the focused repro, before and after images, structural
|
||||
metrics, and any remaining expected difference in the PR. Rendering work must
|
||||
also preserve non-render automation behavior and the no-render build.
|
||||
|
||||
## Before you open a PR
|
||||
|
||||
For any code change:
|
||||
|
||||
1. `cargo nextest run --release --features render` passes for the crates you touched.
|
||||
2. The full render-feature nextest command above passes.
|
||||
3. `CARGO_INCREMENTAL=0 CARGO_BUILD_JOBS=2 cargo build --release --features render` compiles clean.
|
||||
3. `CARGO_INCREMENTAL=0 CARGO_BUILD_JOBS=2 cargo build --release -p obscura-cli --bins --features render` compiles clean.
|
||||
4. The obstacle course still reports **33/33**.
|
||||
5. **Performance is a hard constraint.** Obscura is roughly 12x faster and uses
|
||||
about 6x less memory than headless Chrome on framework pages. Keep native
|
||||
@@ -81,11 +145,8 @@ For any code change:
|
||||
with identical release builds, fixtures, networks, viewport, settle policy,
|
||||
and capture path. Report a distribution and memory use; the noise floor is
|
||||
about plus or minus 10%.
|
||||
6. For rendering changes, run the deterministic `render-repros` fixtures and
|
||||
the representative real-site suite at both the top and bottom of pages.
|
||||
Confirm resource and navigation success before interpreting image diffs;
|
||||
pixel error is a tripwire, not a verdict. Never add hostname-specific layout
|
||||
or style behavior.
|
||||
6. For rendering changes, complete the rendering checks above. For shared or
|
||||
feature-gated changes, also build and test without the `render` feature.
|
||||
7. For stealth changes, re-test with `--stealth`. A non-stealth binary does not
|
||||
exercise the `wreq` path.
|
||||
|
||||
@@ -130,11 +191,15 @@ Fixes #316.
|
||||
Open an issue with enough detail to reproduce:
|
||||
|
||||
- The obscura version or commit, plus OS and architecture.
|
||||
- The build configuration: render, render and stealth, no-render, or no-render
|
||||
and stealth.
|
||||
- A repro: a URL, an `--eval` snippet, or a short CDP sequence.
|
||||
- What you expected and what actually happened.
|
||||
- If it is a rendering or compatibility issue, whether headless Chrome behaves
|
||||
the same. Anti-bot, CAPTCHA, and login walls block headless Chrome too from a
|
||||
datacenter IP, so those are not engine bugs.
|
||||
the same. Include the viewport, device-pixel ratio, scroll position, capture
|
||||
mode, screenshot clip or full-page setting, and PDF options where applicable.
|
||||
Anti-bot, CAPTCHA, and login walls block headless Chrome too from a datacenter
|
||||
IP, so those are not engine bugs.
|
||||
|
||||
Multi-statement `--eval` that starts with `const` returns `null` (V8 gives
|
||||
`const` an empty completion value). Wrap repro snippets in an IIFE:
|
||||
|
||||
Reference in New Issue
Block a user