LiveLoad.Scenario.Context (LiveLoad v0.0.1-rc.18)

Copy Markdown View Source

A context struct that is given to every LiveLoad.Scenario.run/3 callback while running a LiveLoad.Scenario. It wraps the LiveLoad.Browser.Context details for the runner and provides a simple API for interacting with the browser.

This module's API is based on Plug.Conn, using the following patterns:

  • A scenario that is :halted? at any point in the scenario will short-circuit and not run any other functions.
  • A scenario that has an :error at any point in the scenario will short-circuit and not run any other functions.
  • Values can be extracted from the page through the available functions and assigned onto the context for future use in the pipeline.

Halting and Errors

Halting and errors are mutually exclusive:

  • A scenario can be halted by calling the halt/1 function in order to mark the scenario as halted.
  • A scenario will be marked with an error whenever any error, exception, or exit occurs while an operation is running.

The reason for this mutual exclusivity is to preserve the reason for a scenario not completing. Errors are unexpected occurences that may happen for any number of reasons and are marked as such to ensure that any consumers of LiveLoad are able to understand what errors are happening in their application while load testing their sites. However, halting is manually marked and is a decision by the writer of the scenario. Halting can be used to simply short-circuit a scenario should the writer decide that it can be short-circuited at any point during the scenario's run.

As such, when calling halt/1, a scenario will only be marked has halted if no error has occured in the pipeline in order to preserve the reason for the scenario not completing.

Two helper functions, halted?/1 and failed?/1 are provided in order to determine if a scenario failed or was halted manually.

Assigns

All functions exposed on the API accept both a raw value and a 1-arity function so that you can get values from the context and its assigns.

For example, if you simple need to click on a button with a specific hard-coded ID, you might write something like this:

click(context, "#submit")

However, if the button may have a dynamic ID, you can pass in a 1-arity function and build the ID based on the assigns:

click(context, &"##{&1.assigns.button_id}")

Summary

Types

A key passed in to the :as option when using functions that extract values from the context.

A resolvable variable given to operations on the LiveLoad.Scenario.Context.

t()

Functions

Assigns a value to a key in the context.

Clears a specific assign on the context.

Detects whether or not the current page is a LiveView.

Checks to see if the LiveLoad.Scenario.Context failed to complete.

Halts a LiveLoad.Scenario by preventing any further operations to take place on the context.

Checks to see if the LiveLoad.Scenario.Context was halted.

Extracts the innerHTML value of an element matching the given selector and assigns it to the :as option on the context's assigns.

Navigates to the given URL.

Extracts the current page's content and assigns it to the :as option on the context's assigns.

Updates a value under a specified key in the context.

Waits for a LiveView to be fully connected.

Waits for an element that matches the given selector to appear on the current page.

Types

assigned_as()

@type assigned_as() ::
  atom() | (term() -> atom()) | (term() -> %{required(atom()) => term()})

A key passed in to the :as option when using functions that extract values from the context.

Values that are extracted can be specified to be assigned to the context's assigns via the :as option, which can receive an atom/0, or a 1-arity function which may return either an atom/0 or a map/0 of atom/0 keys to values which will be merged onto the context's assigns.

resolvable(value)

@type resolvable(value) :: value | (t() -> value)

A resolvable variable given to operations on the LiveLoad.Scenario.Context.

Can either be a value, or a 1-arity function that receives a LiveLoad.Scenario.Context and returns a value.

t()

@type t() :: %LiveLoad.Scenario.Context{
  assigns: %{optional(atom()) => term()},
  browser_context: LiveLoad.Browser.Context.t(),
  error: LiveLoad.Scenario.Error.t() | nil,
  halted?: boolean(),
  step: non_neg_integer()
}

Functions

assign(context, key, value)

@spec assign(context :: t(), key :: atom(), value :: term()) :: t()

Assigns a value to a key in the context.

The assigns storage is meant to be used to store values in the connection so that other operations in your scenario's pipeline can access them. The assigns storage is a map.

clear_assign(context, key)

@spec clear_assign(context :: t(), key :: atom()) :: t()

Clears a specific assign on the context.

After clearing this key will no longer be available and assertive access will cause an exception.

See assign/3 for information about the assigns storage.

ensure_liveview(ctx)

@spec ensure_liveview(context :: t()) :: t()

Detects whether or not the current page is a LiveView.

failed?(context)

@spec failed?(context :: t()) :: boolean()

Checks to see if the LiveLoad.Scenario.Context failed to complete.

Failure occurs when an error occurs while the LiveLoad.Scenario is running.

halt(ctx)

@spec halt(context :: t()) :: t()

Halts a LiveLoad.Scenario by preventing any further operations to take place on the context.

If the scenario has already had an error, this results in a No-Op and the context will not be marked as halted in order to preserve the error.

halted?(context)

@spec halted?(context :: t()) :: boolean()

Checks to see if the LiveLoad.Scenario.Context was halted.

Halting occurs when the halt/1 function is called on the context directly.

inner_html(ctx, selector, opts \\ [])

@spec inner_html(
  context :: t(),
  selector :: String.t(),
  opts :: [{:as, assigned_as()}]
) :: t()

Extracts the innerHTML value of an element matching the given selector and assigns it to the :as option on the context's assigns.

Options

  • :as - an atom key to place the page content under on the context's assigns. Alternatively, you can pass a 1-arity function which will be run with the returned value. The function must return either an atom, which will be used as the key, or a map of new assigns values that will be merged into the current assigns on the context.

page_content(ctx, opts \\ [])

@spec page_content(context :: t(), opts :: [{:as, assigned_as()}]) :: t()

Extracts the current page's content and assigns it to the :as option on the context's assigns.

Options

  • :as - an atom key to place the page content under on the context's assigns. Alternatively, you can pass a 1-arity function which will be run with the returned value. The function must return either an atom, which will be used as the key, or a map of new assigns values that will be merged into the current assigns on the context.

update_assign!(context, key, update_fn)

@spec update_assign!(context :: t(), key :: atom(), (term() -> term())) :: t()

Updates a value under a specified key in the context.

Raises a KeyError exception if the specified key does not exist on the assigns.

See assign/3 for information about the assigns storage.

wait_for_liveview(ctx)

@spec wait_for_liveview(context :: t()) :: t()

Waits for a LiveView to be fully connected.

wait_for_selector(ctx, selector)

@spec wait_for_selector(context :: t(), selector :: resolvable(String.t())) :: t()

Waits for an element that matches the given selector to appear on the current page.