Name: test-extras
Owner: Dojo
Description: :rocket: Dojo 2 - set of modules to help with testing Dojo.
Created: 2017-03-13 10:06:27.0
Updated: 2018-05-02 14:03:42.0
Pushed: 2018-05-02 14:03:40.0
Homepage: http://dojo.io
Size: 713
Language: TypeScript
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
Provides a simple API for testing and asserting Dojo 2 widget's expected virtual DOM and behavior.
harness
harness.expect
harness.expectPartial
harness.trigger
harness()
is the primary API when working with @dojo/test-extras
, essentially setting up each test and providing a context to perform virtual DOM assertions and interactions. Designed to mirror the core behavior for widgets when updating properties
or children
and widget invalidation, with no special or custom logic required.
ess(renderFunction: () => WNode, customComparators?: CustomComparator[]): Harness;
renderFunction
: A function that returns a WNode for the widget under testcustomComparators
: Array of custom comparator descriptors. Each provides a comparator function to be used during the comparison for properties
located using a selector
and property
nameThe harness returns a Harness
object that provides a small API for interacting with the widget under test:
Harness
expect
: Performs an assertion against the full render output from the widget under test.expectPartial
: Performs an assertion against a section of the render output from the widget under test.trigger
: Used to trigger a function from a node on the widget under test's APIgetRender
: Returns a render from the harness based on the index providedSetting up a widget for testing is simple and familiar using the w()
function from @dojo/widget-core
:
s MyWidget extends WidgetBase<{ foo: string; }> {
protected render() {
const { foo } = this.properties;
return v('div', { foo }, this.children);
}
t h = harness(() => w(MyWidget, { foo: 'bar' }, [ 'child' ]));
The harness also supports tsx
usage as show below. For the rest of the README the examples will be using the programmatic w()
API, there are more examples of tsx
in the unit tests.
t h = harness(() => <MyWidget foo='bar'>child</MyWidget>);
The renderFunction
is lazily executed so it can include additional logic to manipulate the widget's properties
and children
between assertions.
foo = 'bar';
t h = harness(() => {
return w(MyWidget, { foo }, [ 'child' ]));
pect(/** assertion that includes bar **/);
pdate the property that is passed to the widget
= 'foo';
pect(/** assertion that includes foo **/)
There are circumstances where the exact value of a property is unknown during testing, so will require the use of a custom compare descriptor.
The descriptors have a selector
to locate the virtual nodes to check, a property name for the custom compare and a comparator function that receives the actual value and returns a boolean result for the assertion.
t compareId = {
selector: '*', // all nodes
property: 'id',
comparator: (value: any) => typeof value === 'string' // checks the property value is a string
t h = harness(() => w(MyWidget, {}), [ compareId ]);
For all assertions, using the returned harness
API will now only test identified id
properties using the comparator
instead of the standard equality.
The harness
APIs commonly support a concept of CSS style selectors to target nodes within the virtual DOM for assertions and operations. Review the full list of supported selectors for more information.
In addition to the standard API:
@
symbol is supported as shorthand for targeting a node's key
propertyclasses
property is used instead of class
when using the standard shorthand .
for targeting classesharness.expect
The most common requirement for testing is to assert the structural output from a widget's render
function. expect
accepts a render function that returns the expected render output from the widget under test.
API
ct(expectedRenderFunction: () => DNode | DNode[], actualRenderFunction?: () => DNode | DNode[]);
expectedRenderFunction
: A function that returns the expected DNode
structure of the queried nodeactualRenderFunction
: An optional function that returns the actual DNode
structure to be assertedpect(() => v('div', { key: 'foo'}, [
w(Widget, { key: 'child-widget' }),
'text node',
v('span', { classes: [ 'class' ] })
Optionally expect
can accepts a second parameter of function that returns a render result to assert against.
pect(() => v('div', { key: 'foo'}), () => v('div', { key: 'foo' }));
If the actual render output and expected render output are different, an exception is thrown with a structured visualization indicating all differences with (A)
(the actual value) and (E)
(the expected value).
Example assertion failure output:
iv", {
"classes": [
"root",
"other"
"another"
],
"onclick": "function"
v("span", {
"classes": "span",
"id": "random-id",
"key": "label",
"onclick": "function",
"style": "width: 100px"
}, [
"hello 0"
])
w(ChildWidget, {
"id": "random-id",
"key": "widget"
})
w("registry-item", {
"id": true,
"key": "registry"
})
harness.expectPartial
expectPartial
asserts against a section of the widget's render output based on a selector
.
API
ctPartial(selector: string, expectedRenderFunction: () => DNode | DNode[]);
selector
: The selector query to find the node to targetexpectedRenderFunction
: A function that returns the expected DNode
structure of the queried nodeactualRenderFunction
: An optional function that returns the actual DNode
structure to be assertedExample usage:
pectPartial('@child-widget', () => w(Widget, { key: 'child-widget' }));
harness.trigger
harness.trigger()
calls a function with the name
on the node targeted by the selector
.
rface FunctionalSelector {
(node: VNode | WNode): undefined | Function;
ger(selector: string, functionSelector: string | FunctionalSelector, ...args: any[]): any;
selector
: The selector query to find the node to targetfunctionSelector
: Either the name of the function to call from found node's properties or a functional selector that returns a function from a nodes properties.args
: The arguments to call the located function withReturns the result of the function triggered if one is returned.
Example Usage(s):
alls the `onclick` function on the first node with a key of `foo`
igger('@foo', 'onclick');
s
alls the `customFunction` function on the first node with a key of `bar` with an argument of `100`
nd receives the result of the triggered function
t result = h.trigger('@bar', 'customFunction', 100);
harness.getRender
harness.getRender()
returns the render with the index provided, when no index is provided it returns the last render.
ender(index?: number);
index
: The index of the render result to returnExample Usage(s):
eturns the result of the last render
t render = h.getRender();
s
eturns the result of the render for the index provided
tRender(1);
We appreciate your interest! Please see the Dojo Meta Repository for the Contributing Guidelines.
This repository uses prettier
for code styling rules and formatting. A pre-commit hook is installed automatically and configured to run prettier
against all staged files as per the configuration in the projects package.json
.
An additional npm script to run prettier
(with write set to true
) against all src
and test
project files is available by running:
run prettier
To start working with this package, clone the repository and run npm install
.
In order to build the project, run grunt dev
or grunt dist
.
Test cases MUST be written using Intern using the Object test interface and Assert assertion interface.
90% branch coverage MUST be provided for all code submitted to this repository, as reported by istanbul?s combined coverage results for all supported platforms.
To test locally in node run:
grunt test
To test against browsers with a local selenium server run:
grunt test:local
To test against BrowserStack or Sauce Labs run:
grunt test:browserstack
or
grunt test:saucelabs
© 2018 JS Foundation. New BSD license.