Introduction

Bombadil is property-based testing for web UIs, autonomously exploring and validating correctness properties, finding harder bugs earlier. It runs in your local developer environment, in CI, and inside Antithesis.

Why Bombadil?

Or rather, why property-based testing? Because example-based testing, especially in the area of browser testing, is costly and limited:

This is where property-based testing, or fuzzing if you will, comes into play. By randomly and systematically searching the state space, Bombadil behaves in ways you didn’t think about testing for. Unexpected sequences of actions, weird timings, strange inputs that you forgot could be entered.

How it works

Instead of describing “what good looks like” in terms of fixed test cases, you express general properties of your system, how it should behave in all cases. Bombadil checks each property as it explores your system in its chaotic ways, reporting back any violations.

To test a web application using Bombadil, you write a specification in TypeScript that exports properties and action generators. These can be domain-specific — to exercise and validate your system’s logic in custom ways — or be imported from the defaults provided by Bombadil. It doesn’t matter how the application is built — if it’s a single-page app, server-side rendered, or even static HTML — Bombadil tests anything that uses the DOM.

Conceptually, it runs in a loop doing the following:

  1. Extracts the current state from the browser
  2. Checks all properties against the current state, recording violations1
  3. Selects the next action based on the current state, and performs it
  4. Waits for the next event (page navigation, DOM mutation, or timeout)
  5. Goes to step 1

Bombadil itself decides what is an interesting event and when to capture state. The specification author provides the properties and actions, Bombadil does the rest.


  1. You can also configure Bombadil to exit on the first found violation.↩︎