gleewright/step

A Step is an asynchronous action in a test, such as a click or an assertion, that either succeeds with a value or fails with an Error.

Chain steps with use and try. The test body returns the last step:

gleewright.it("signs in", fn(page) {
  use _ <- step.try(page.goto(page, "/login"))
  use title <- step.try(page.title(page))
  use _ <- step.try(expect.equal(title, "Sign in"))
  page.get_by_role(page, role.Button) |> locator.click
})

As soon as one step fails, the rest of the chain is skipped and the test fails with that step’s error.

Reusable setup, such as signing in, is an ordinary function that takes the rest of the test as a callback:

fn signed_in(page: Page, next: fn() -> Step(a)) -> Step(a) {
  use _ <- step.try(page.goto(page, "/login"))
  use _ <- step.try(page.get_by_label(page, "Email") |> locator.fill("me@example.com"))
  use _ <- step.try(page.get_by_role_named(page, role.Button, "Sign in") |> locator.click)
  next()
}

gleewright.it("shows the dashboard", fn(page) {
  use <- signed_in(page)
  expect.page(page) |> expect.to_have_url("/dashboard")
})

Types

An asynchronous action that succeeds with a value of type a, or fails with an Error.

pub opaque type Step(a)

Values

pub fn await(promise: promise.Promise(a)) -> Step(a)

Wrap a promise that cannot fail as a step.

pub fn context(step: Step(a), description: String) -> Step(a)

Add context to the error of a failing step, e.g. "logging in".

pub fn done() -> Step(Nil)

A step that succeeds with Nil. Useful to end a chain of steps.

pub fn each(
  items: List(a),
  with run: fn(a) -> Step(b),
) -> Step(Nil)

Run a step for every item in a list, one after another, stopping at the first failure.

pub fn fail(message: String) -> Step(a)

A step that immediately fails the test with the given message.

pub fn from_promise(
  promise: promise.Promise(Result(a, error.Error)),
) -> Step(a)

Wrap a promise of a result as a step.

pub fn from_result(result: Result(a, error.Error)) -> Step(a)

Lift a Result into a step.

pub fn map(step: Step(a), with transform: fn(a) -> b) -> Step(b)

Transform the value produced by a step.

pub fn map_each(
  items: List(a),
  with run: fn(a) -> Step(b),
) -> Step(List(b))

Run a step for every item in a list, one after another, collecting the results.

pub fn sleep(milliseconds: Int) -> Step(Nil)

Pause the test for the given number of milliseconds. Prefer expect assertions, which wait automatically, over fixed sleeps.

pub fn succeed(value: a) -> Step(a)

A step that immediately succeeds with the given value.

pub fn to_promise(
  step: Step(a),
) -> promise.Promise(Result(a, error.Error))

Get the underlying promise of a step.

pub fn try(step: Step(a), next: fn(a) -> Step(b)) -> Step(b)

Run a step, and if it succeeds pass its value on to the next one.

✨ Search Document