Each adapter should adhere to some core functionality to promote ease of use of different adapters for different situations. Some adapters also provide additional functionality best suited for their intended use case.
Adapters provide the details of how test views are combined, how elements are selected and how actions interact with elements. It is useful to consider adapters as adhering to the same interface but parameterizing it on two types.
You can use more than one adapter in a test, but test views from different adapters cannot be combined together safely.
Adapters specify the type of the elements they interact with. For the most part this is going to be related to the underlying DOM types, but some adapters might wrap it in a more convenient structure.
Adapters specify the type of the selectors they use to make queries. These can be varied and rich.
The core functionality provided is a way to create test views that have a selector and some actions. Default test views are also provided.
Adapters have a default export that is a function to create test views.
testView(selector: SelectorType, actions: ?ActionMap, aggregateActions: ?AggregateMap): TestView
-
selector
Describes how to find the element this test view will operate on. It's specific structure will vary depending on the adapter. For example, the CSS adapter uses plain strings while the Enzyme adapter uses functions.
-
actions (optional)
Describes the actions that are available on this test view once it is materialized. It takes the form of a map from action names to functions. Each function must take as its first argument the element being operated on. This is not supplied when the action is invoked. The functions may take other arguments that will be supplied when the action is invoked.
-
aggregate actions (optional)
Describes the aggregate actions that are available on this test view once it is materialized. It takes the form of a map from action names to functions. Each function must take as its first argument an array of each element that was selected. This is not supplied when the action is invoked. The functions may take other arguments that will be supplied when the action is invoked.
A test view.
The function used to create a test view has default test views attached to it. Access these from the defaultViews
property. For example:
testView.defaultViews.button
Selects inputs with the checkbox type.
Toggles the state of the checkbox, from checked to unchecked or unchecked to checked.
toggle: () => void
Returns a boolean whose value depends on the checked state of the checkbox.
isChecked: () => boolean
Returns the value of the checkbox.
getValue: () => string
Selects inputs with the radio type.
Selects the targeted radio button.
select: () => void
Gets the selected value for the radio button group. The radio button group is defined as all the radio buttons that share the same name that are at the same level in the DOM.
getSelectedValue: () => string | null
Selects inputs with a type of text or text areas.
Enters the given text into the text view.
enterText: (text: string) => void
Returns the text in the text view.
getText: () => string
Selects select inputs that cannot have multiple values selected.
Select the given value.
select: (value: string) => void
Return the selected value.
getSelection: () => string
TODO: This should be string | null
Selects select inputs that can have multiple values selected.
Ensures the given values are selected. This will deselect any values that are not provided.
select: (values: string[]) => void
Returns the selected values.
getSelection: () => string[]
Selects forms.
Submits the form
submit: () => void
Selects buttons. This includes button elements and inputs with type button or with type submit.
Clicks the button.
click: () => void
Test views are callable as functions and this combines two test views. This is
used as a way to build up more complicated test views from smaller pieces. An
example is selecting all the text inputs in a form:
defaultViews.form(defaultViews.textInput)
. Only the actions from the last
test view are available when the test view is materialized. The exact mechanism
of combining selectors is left up to the individual adapters, however it should
be associative.
(): (testView: TestView) => TestView
Test views are used by materializing them. When materializing a test view an element (the exact structure of which is determined by the adapter) must be supplied. All selectors will be run against this element as the root.
materialize: (element: ElementType): MaterializedTestView;
Actions are used to query or manipulate the state of the elements under test.
Actions are specified when creating a test view. When specifying actions they should be specified such that their first argument is an element that will be provided by the adapter. Other arguments may also be specified, for example to set the state of an input.
Actions should be invoked after the test view has been materialized. Only then will the first argument be provided automatically. Actions are invoked like functions, and any other arguments that were specified should be provided at invocation time.
All actions provide a few different invocation strategies that are useful in different situations.
By default an action will be called against every element that was selected by the test view. The results of each call are aggregated and returned in an array.
action: (...) => ReturnType[]
An action may be run against a single matched element. If there are zero or multiple elements an error will be thrown.
action.one: (...) => ReturnType
An action may be run against a specific matched element. To do so you provide an index and the action will be called against the element at that index. Because HTML tends to index elements starting at 1, this invocation method also indexes starting at 1. The index is provided as the first argument to the invoked action. If there is no element at the specified index an error will be thrown.
action.at: (index: number, ...) => ReturnType
Every test view has some default actions that are automatically provided.
Returns the element that was selected.
get: () => ElementType
Returns a string representation of the elements selected by the test view. For debugging. The method of stringifying is determined by the adapter.
printSelected: () => string[]
Every test view has some default aggregate methods that are automatically provided.
Returns a string representation of the selector computed by the test view. This includes composed test views as well as any parameterization. Useful for debugging purposes. The method of stringifying is determined by the adapter.
printSelector: () => string
Returns a string representation of the root element used to materialize the test view. Useful for debugging purposes. The method of stringifying is determined by the adapter.
printRoot: () => string
Errors are thrown when a prerequisite for an action invocation strategy is not met. They will have a few extra properties to aid in debugging.
This error is thrown when invoking an action on a single element and multiple elements are selected.
class MultipleSelectedElementsError extends Error {
selector: SelectorType;
root: ElementType;
}
This error is thrown when invoking an action on a single element and no elements are selected.
class ZeroSelectedElementsError extends Error {
selector: SelectorType;
root: ElementType;
}
This error is thrown when invoking an action on an indexed element and the element does not exist.
class IndexOutOfBoundsError extends Error {
selector: SelectorType;
root: ElementType;
index: number;
}