Skip to content

Migrate from Wraith

Wraith is the BBC's Ruby screenshot-comparison tool — capture URLs across widths, diff the pixels with ImageMagick, publish a gallery.

Wraith is archived

The Wraith repository has been archived / read-only since January 2026, and its last release (v4.2.4) was June 2019. Its default capture engines — PhantomJS, CasperJS, SlimerJS — are themselves abandoned, which makes a clean install increasingly fragile. It needs replacing, not patching.

Why Dungbeetle

WraithDungbeetle
MaintainedNo — archived Jan 2026Yes
EnginePhantomJS / SlimerJS / Selenium (Ruby + ImageMagick)Playwright/Chromium (Node)
DiffPixel (ImageMagick)Structured tree (+ tolerant pixel fallback)
Baselinesshots/ PNGs; wraith historydungbeetle.snapshots/, versioned in cloud
Review UINo — static gallery.htmlYesself-host or managed
RuntimeRuby + ImageMagick + PhantomJSNode 22+

Two capture models — pick the baseline one

Wraith has two modes; map them deliberately:

  • History mode (wraith historywraith latest) is the baseline model and maps cleanly onto Dungbeetle: wraith historydungbeetle update, wraith latestdungbeetle test.
  • Two-domain compare (capturing english vs live every run, no stored baseline) is an environment diff, not regression-vs-baseline. In Dungbeetle you'd capture one environment as the committed baseline and compare the other against it with dungbeetle test — or run two targets and compare reports. Most teams actually want the baseline model; this is a good moment to switch to it.

Translate your config

Wraith uses YAML under configs/. Paths × widths become Dungbeetle web targets:

yaml
# configs/capture.yaml
browser: "phantomjs"
domains:
  live: "https://example.com"
paths:
  home: /
  news: /news
screen_widths:
  - 320
  - 1280
threshold: 5
directory: 'shots'
json
// dungbeetle.config.json
{
  "version": 1,
  "project": { "name": "example" },
  "lifecycle": {
    "capture": [
      { "kind": "web", "name": "home-320",  "driver": "playwright", "url": "https://example.com/",     "screenshot": true, "viewport": { "width": 320,  "height": 720 } },
      { "kind": "web", "name": "home-1280", "driver": "playwright", "url": "https://example.com/",     "screenshot": true, "viewport": { "width": 1280, "height": 720 } },
      { "kind": "web", "name": "news-320",  "driver": "playwright", "url": "https://example.com/news", "screenshot": true, "viewport": { "width": 320,  "height": 720 } },
      { "kind": "web", "name": "news-1280", "driver": "playwright", "url": "https://example.com/news", "screenshot": true, "viewport": { "width": 1280, "height": 720 } }
    ]
  },
  "comparison": { "pixelTolerance": { "maxChangedRatio": 0.05 } }
}

Field mapping:

WraithDungbeetle
domains + pathsone web target per URL
screen_widthscapture[].viewport.width (one target per width)
browserdriver: "playwright" + browser.channel
threshold (% changed)comparison.pixelTolerance.maxChangedRatio (ratio, so 5%0.05)
fuzz (anti-alias tolerance)covered by pixelTolerance; or drop pixels and rely on the structured DOM diff
directory / history_dirdungbeetle.snapshots/ (the baselines dir)

Consider dropping pixels entirely

Wraith is pixel-only. If your pages render server-side HTML, Dungbeetle's default structured DOM capture (no screenshot, no browser) is far less flaky than ImageMagick pixel diffs — try a target without driver/screenshot first and only add screenshots where you truly need pixels.

Re-baseline, then CI

sh
dungbeetle update        # ≈ wraith history  → dungbeetle.snapshots/
dungbeetle test          # ≈ wraith latest
dungbeetle ci --json report.json --html report.html   # in CI

Commit dungbeetle.snapshots/. The old shots/ PNGs don't carry over.

Wraith's output is a static gallery you publish as an artifact. Push to a Dungbeetle cloud server instead for hosted baselines, a review/approve/promote UI, history, and flakiness analytics:

sh
dungbeetle push --report report.json \
  --server "$DUNGBEETLE_SERVER_URL" \
  --client-id "$DUNGBEETLE_CLIENT_ID" --client-secret "$DUNGBEETLE_CLIENT_SECRET"

Next

Source-available: CLI under FSL-1.1-ALv2, cloud server under BUSL-1.1. See Licensing.