Extractors #
In order to describe a condition about the web page you’re
testing, you first need to extract state. This is done with the
extract function, which runs inside the browser on
every state that Bombadil decides to capture.
extract(state => ...)You give it a function that takes the current browser state
as an argument, and returns JSON-serializable data. The state
object contains a bunch of things, but the most important are
document and window — the same ones
you have access to in JavaScript running in a browser.
To extract the title, you’d define this at the top level of your specification:
const title = extract(state => state.document.title || "");The title value is not a string
though — it’s a Cell<string>, a stateful
value that changes over time. For every new state captured by
Bombadil, the extractor function gets run, and the cell is
updated with its return value.
Using the title cell, you can define the
property:
export const hasTitle = always(() =>
title.current !== ""
);Two things to note about this example:
- The expression passed to
alwaysis a function that takes no arguments — a thunk. This is because it needs to be evaluated in every state. It needs to always be true, not just once, and that’s why you need to supply the thunk rather than aboolean. - To get the
stringvalue out of the cell, you use.current.
This is a custom property using the temporal
operator called always. There are other temporal
operators, described in Formulas below.