- DOM Interaction Helpers
- DOM Query Helpers
- Routing Helpers
- Rendering Helpers
- Wait Helpers
- Pause Helpers
- Debug Helpers
- Test Framework APIs
- rerender
- registerHook
- runHooks
- getDeprecations
- getDeprecationsDuringCallback
- getWarnings
- getWarningsDuringCallback
Unfocus the specified target.
Sends a number of events intending to simulate a "real" user unfocusing an element.
The following events are triggered (in order):
blur
focusout
The exact listing of events that are triggered may change over time as needed to continue to emulate how actual browsers handle unfocusing a given element.
target
(string | Element | IDOMElementDescriptor) the element, selector, or descriptor to unfocus (optional, defaultdocument.activeElement
)
Emulating blurring an input using blur
blur('input');
Returns Promise<void> resolves when settled
Clicks on the specified target.
Sends a number of events intending to simulate a "real" user clicking on an element.
For non-focusable elements the following events are triggered (in order):
mousedown
mouseup
click
For focusable (e.g. form control) elements the following events are triggered (in order):
mousedown
focus
focusin
mouseup
click
The exact listing of events that are triggered may change over time as needed to continue to emulate how actual browsers handle clicking a given element.
Use the options
hash to change the parameters of the MouseEvents.
You can use this to specify modifier keys as well.
target
(string | Element | IDOMElementDescriptor) the element, selector, or descriptor to click on_options
MouseEventInit the options to be merged into the mouse events. (optional, default{}
)
Emulating clicking a button using click
click('button');
Emulating clicking a button and pressing the shift
key simultaneously using click
with options
.
click('button', { shiftKey: true });
Returns Promise<void> resolves when settled
Double-clicks on the specified target.
Sends a number of events intending to simulate a "real" user clicking on an element.
For non-focusable elements the following events are triggered (in order):
mousedown
mouseup
click
mousedown
mouseup
click
dblclick
For focusable (e.g. form control) elements the following events are triggered (in order):
mousedown
focus
focusin
mouseup
click
mousedown
mouseup
click
dblclick
The exact listing of events that are triggered may change over time as needed to continue to emulate how actual browsers handle clicking a given element.
Use the options
hash to change the parameters of the MouseEvents.
target
(string | Element | IDOMElementDescriptor) the element, selector, or descriptor to double-click on_options
MouseEventInit the options to be merged into the mouse events (optional, default{}
)
Emulating double clicking a button using doubleClick
doubleClick('button');
Emulating double clicking a button and pressing the shift
key simultaneously using click
with options
.
doubleClick('button', { shiftKey: true });
Returns Promise<void> resolves when settled
Fill the provided text into the value
property (or set .innerHTML
when
the target is a content editable element) then trigger change
and input
events on the specified target.
target
(string | Element | IDOMElementDescriptor) the element, selector, or descriptor to enter text intotext
string the text to fill into the target element
Emulating filling an input with text using fillIn
fillIn('input', 'hello world');
Returns Promise<void> resolves when the application is settled
Focus the specified target.
Sends a number of events intending to simulate a "real" user focusing an element.
The following events are triggered (in order):
focus
focusin
The exact listing of events that are triggered may change over time as needed to continue to emulate how actual browsers handle focusing a given element.
Emulating focusing an input using focus
focus('input');
Returns Promise<void> resolves when the application is settled
Scrolls DOM element, selector, or descriptor to the given coordinates.
target
(string | HTMLElement | IDOMElementDescriptor) the element, selector, or descriptor to trigger scroll onx
Number x-coordinatey
Number y-coordinate
Scroll DOM element to specific coordinates
scrollTo('#my-long-div', 0, 0); // scroll to top
scrollTo('#my-long-div', 0, 100); // scroll down
Returns Promise<void> resolves when settled
Set the selected
property true for the provided option the target is a
select element (or set the select property true for multiple options if the
multiple attribute is set true on the HTMLSelectElement) then trigger
change
and input
events on the specified target.
target
(string | Element | IDOMElementDescriptor) the element, selector, or descriptor for the select elementoptions
(string | Array<string>) the value/values of the items to selectkeepPreviouslySelected
boolean a flag keep any existing selections (optional, defaultfalse
)
Emulating selecting an option or multiple options using select
select('select', 'apple');
select('select', ['apple', 'orange']);
select('select', ['apple', 'orange'], true);
Returns Promise<void> resolves when the application is settled
Emulates the user pressing the tab button.
Sends a number of events intending to simulate a "real" user pressing tab on their keyboard.
-
options
Object? optional tab behaviors (optional, default{}
)
Emulating pressing the TAB
key
tab();
Emulating pressing the SHIFT
+TAB
key combination
tab({ backwards: true });
Returns Promise<void> resolves when settled
Taps on the specified target.
Sends a number of events intending to simulate a "real" user tapping on an element.
For non-focusable elements the following events are triggered (in order):
touchstart
touchend
mousedown
mouseup
click
For focusable (e.g. form control) elements the following events are triggered (in order):
touchstart
touchend
mousedown
focus
focusin
mouseup
click
The exact listing of events that are triggered may change over time as needed to continue to emulate how actual browsers handle tapping on a given element.
Use the options
hash to change the parameters of the tap events.
target
(string | Element | IDOMElementDescriptor) the element, selector, or descriptor to tap onoptions
Object the options to be merged into the touch events (optional, default{}
)
Emulating tapping a button using tap
tap('button');
Returns Promise<void> resolves when settled
Triggers an event on the specified target.
target
(string | Element | IDOMElementDescriptor) the element, selector, or descriptor to trigger the event oneventType
string the type of event to triggeroptions
Object additional properties to be set on the event
Using triggerEvent
to upload a file
When using triggerEvent
to upload a file the eventType
must be change
and you must pass the
options
param as an object with a key files
containing an array of
Blob.
triggerEvent(
'input.fileUpload',
'change',
{ files: [new Blob(['Ember Rules!'])] }
);
Using triggerEvent
to upload a dropped file
When using triggerEvent
to handle a dropped (via drag-and-drop) file, the eventType
must be drop
. Assuming your drop
event handler uses the DataTransfer API,
you must pass the options
param as an object with a key of dataTransfer
. The options.dataTransfer
object should have a files
key, containing an array of File.
triggerEvent(
'[data-test-drop-zone]',
'drop',
{
dataTransfer: {
files: [new File(['Ember Rules!'], 'ember-rules.txt')]
}
}
)
Returns Promise<void> resolves when the application is settled
Triggers a keyboard event of given type in the target element.
It also requires the developer to provide either a string with the key
or the numeric keyCode
of the pressed key.
Optionally the user can also provide a POJO with extra modifiers for the event.
-
target
(string | Element | IDOMElementDescriptor) the element, selector, or descriptor to trigger the event on -
eventType
("keydown"
|"keyup"
|"keypress"
) the type of event to trigger -
key
(number | string) thekeyCode
(number) orkey
(string) of the event being triggered -
modifiers
Object? the state of various modifier keys (optional, defaultDEFAULT_MODIFIERS
)modifiers.ctrlKey
boolean if true the generated event will indicate the control key was pressed during the key event (optional, defaultfalse
)modifiers.altKey
boolean if true the generated event will indicate the alt key was pressed during the key event (optional, defaultfalse
)modifiers.shiftKey
boolean if true the generated event will indicate the shift key was pressed during the key event (optional, defaultfalse
)modifiers.metaKey
boolean if true the generated event will indicate the meta key was pressed during the key event (optional, defaultfalse
)
Emulating pressing the ENTER
key on a button using triggerKeyEvent
triggerKeyEvent('button', 'keydown', 'Enter');
Returns Promise<void> resolves when the application is settled unless awaitSettled is false
Mimics character by character entry into the target input
or textarea
element.
Allows for simulation of slow entry by passing an optional millisecond delay between key events.
The major difference between typeIn
and fillIn
is that typeIn
triggers
keyboard events as well as input
and change
.
Typically this looks like focus
-> focusin
-> keydown
-> keypress
-> keyup
-> input
-> change
per character of the passed text (this may vary on some browsers).
target
(string | Element | IDOMElementDescriptor) the element, selector, or descriptor to enter text intotext
string the test to fill the element withoptions
Object {delay: x} (default 50) number of milliseconds to wait per keypress (optional, default{}
)
Emulating typing in an input using typeIn
typeIn('input', 'hello world');
Returns Promise<void> resolves when the application is settled
Find the first element matched by the given selector. Equivalent to calling
querySelector()
on the test root element.
selector
string the selector to search for
Finding the first element with id 'foo'
find('#foo');
Returns (Element | null) matched element or null
Find all elements matched by the given selector. Similar to calling
querySelectorAll()
on the test root element, but returns an array instead
of a NodeList
.
selector
string the selector to search for
Find all of the elements matching '.my-selector'.
findAll('.my-selector');
Returns Array array of matched elements
Get the root element of the application under test (usually #ember-testing
)
Getting the root element of the application and checking that it is equal to the element with id 'ember-testing'.
assert.equal(getRootElement(), document.querySelector('#ember-testing'));
Returns Element the root element
Navigate the application to the provided URL.
Visiting the route for post 1.
await visit('/posts/1');
Visiting the route for post 1 while also providing the rootElement
app boot option.
await visit('/', { rootElement: '#container' });
Returns Promise<void> resolves when settled
Returns string the currently active route name
Returns string the applications current url
Renders the provided template and appends it to the DOM.
templateFactoryOrComponent
(Template | Component) the component (or template) to renderoptions
RenderOptions options hash containing engine owner ({ owner: engineOwner })
Render a div element with the class 'container'.
await render(hbs`<div class="container"></div>`);
Returns Promise<void> resolves when settled
Clears any templates previously rendered. This is commonly used for
confirming behavior that is triggered by teardown (e.g.
willDestroyElement
).
Returns Promise<void> resolves when settled
Used to wait for a particular selector to appear in the DOM. Due to the fact that it does not wait for general settledness, this is quite useful for testing interim DOM states (e.g. loading states, pending promises, etc).
-
target
(string | IDOMElementDescriptor) the selector or DOM element descriptor to wait for -
options
Object? the options to be used (optional, default{}
)
Waiting until a selector is rendered:
await waitFor('.my-selector', { timeout: 2000 })
Returns Promise<(Element | Array<Element>)> resolves when the element(s) appear on the page
Wait for the provided callback to return a truthy value.
This does not leverage settled()
, and as such can be used to manage async
while not settled (e.g. "loading" or "pending" states).
-
callback
Function the callback to use for testing when waiting should stop -
options
Object? options used to override defaults (optional, default{}
)
Waiting until a selected element displays text:
await waitUntil(function() {
return find('.my-selector').textContent.includes('something')
}, { timeout: 2000 })
Returns Promise resolves with the callback value when it returns a truthy value
Returns a promise that resolves when in a settled state (see isSettled
for
a definition of "settled state").
Returns Promise<void> resolves when settled
Checks various settledness metrics (via getSettledState()
) to determine if things are settled or not.
Settled generally means that there are no pending timers, no pending waiters, no pending AJAX requests, and no current run loop. However, new settledness metrics may be added and used as they become available.
Returns boolean true
if settled, false
otherwise
Check various settledness metrics, and return an object with the following properties:
hasRunLoop
- Checks if a run-loop has been started. If it has, this will betrue
otherwise it will befalse
.hasPendingTimers
- Checks if there are scheduled timers in the run-loop. These pending timers are primarily registered byEmber.run.schedule
. If there are pending timers, this will betrue
, otherwisefalse
.hasPendingWaiters
- Checks if any registered test waiters are still pending (e.g. the waiter returnstrue
). If there are pending waiters, this will betrue
, otherwisefalse
.hasPendingRequests
- Checks if there are pending AJAX requests (based onajaxSend
/ajaxComplete
events triggered byjQuery.ajax
). If there are pending requests, this will betrue
, otherwisefalse
.hasPendingTransitions
- Checks if there are pending route transitions. If the router has not been instantiated / setup for the test yet this will returnnull
, if there are pending transitions, this will betrue
, otherwisefalse
.pendingRequestCount
- The count of pending AJAX requests.debugInfo
- Debug information that's combined with info return from backburner's getDebugInfo method.isRenderPending
- Checks if there are any pending render operations. This will be true as long as there are tracked values in the template that have not been rerendered yet.
Returns Object object with properties for each of the metrics used to determine settledness
Returns a promise to be used to pauses the current test (due to being returned from the test itself). This is useful for debugging while testing or for test-driving. It allows you to inspect the state of your application at any point.
The test framework wrapper (e.g. ember-qunit
or ember-mocha
) should
ensure that when pauseTest()
is used, any framework specific test timeouts
are disabled.
Usage via ember-qunit
import { setupRenderingTest } from 'ember-qunit';
import { render, click, pauseTest } from '@ember/test-helpers';
module('awesome-sauce', function(hooks) {
setupRenderingTest(hooks);
test('does something awesome', async function(assert) {
await render(hbs`{{awesome-sauce}}`);
// added here to visualize / interact with the DOM prior
// to the interaction below
await pauseTest();
click('.some-selector');
assert.equal(this.element.textContent, 'this sauce is awesome!');
});
});
Returns Promise<void> resolves only when resumeTest()
is invoked
Resumes a test previously paused by await pauseTest()
.
Retrieves debug information from backburner's current deferred actions queue (runloop instance).
If the getDebugInfo
method isn't available, it returns null
.
Returns (MaybeDebugInfo | null) Backburner debugInfo or, if the getDebugInfo method is not present, null
Registers a custom debug info helper to augment the output for test isolation validation.
debugHelper
DebugInfoHelper a custom debug info helper
import { registerDebugInfoHelper } from '@ember/test-helpers';
registerDebugInfoHelper({
name: 'Date override detection',
log() {
if (dateIsOverridden()) {
console.log(this.name);
console.log('The date object has been overridden');
}
}
})
Stores the provided resolver instance so that tests being ran can resolve objects in the same way as a normal application.
Used by setupContext
and setupRenderingContext
as a fallback when setApplication
was not used.
resolver
Ember.Resolver the resolver to be used for testing
Retrieve the resolver instance stored by setResolver
.
Returns Ember.Resolver the previously stored resolver
Used by test framework addons to setup the provided context for testing.
Responsible for:
- sets the "global testing context" to the provided context (
setContext
) - create an owner object and set it on the provided context (e.g.
this.owner
) - setup
this.set
,this.setProperties
,this.get
, andthis.getProperties
to the provided context - setting up AJAX listeners
- setting up
pauseTest
(also available asthis.pauseTest()
) andresumeTest
helpers
-
base
Object the context to setup -
options
Object? options used to override defaults (optional, default{}
)options.resolver
Resolver? a resolver to use for customizing normal resolution
Returns Promise<Object> resolves with the context that was setup
Retrieve the "global testing context" as stored by setContext
.
Returns Object the previously stored testing context
Stores the provided context as the "global testing context".
Generally setup automatically by setupContext
.
context
Object the context to use
Clear the "global testing context".
Generally invoked from teardownContext
.
Used by test framework addons to tear down the provided context after testing is completed.
Responsible for:
- un-setting the "global testing context" (
unsetContext
) - destroy the contexts owner object
- remove AJAX listeners
-
context
Object the context to setup -
options
Object? options used to override defaults (optional, default{}
)options.waitForSettled
boolean should the teardown wait forsettled()
ness (optional, defaulttrue
)
Returns Promise<void> resolves when settled
Used by test framework addons to setup the provided context for rendering.
setupContext
must have been ran on the provided context
prior to calling setupRenderingContext
.
Responsible for:
- Setup the basic framework used for rendering by the
render
helper. - Ensuring the event dispatcher is properly setup.
- Setting
this.element
to the root element of the testing container (things rendered viarender
will go into this element).
context
TestContext the context to setup for rendering
Rendering out a paragraph element containing the content 'hello', and then clearing that content via clearRender.
await render(hbs`<p>Hello!</p>`);
assert.equal(this.element.textContent, 'Hello!', 'has rendered content');
await clearRender();
assert.equal(this.element.textContent, '', 'has rendered content');
Returns Promise<RenderingTestContext> resolves with the context that was setup
Retrieve the application instance stored by setApplication
.
Returns Ember.Application the previously stored application instance under test
Stores the provided application instance so that tests being ran will be aware of the application under test.
- Required by
setupApplicationContext
method. - Used by
setupContext
andsetupRenderingContext
when present.
application
Ember.Application the application that will be tested
Used by test framework addons to setup the provided context for working with an application (e.g. routing).
setupContext
must have been run on the provided context prior to calling
setupApplicationContext
.
Sets up the basic framework used by application tests.
context
Object the context to setup
Returns Promise<void> resolves when the context is set up
Validate the provided error handler to confirm that it properly re-throws
errors when Ember.testing
is true.
This is intended to be used by test framework hosts (or other libraries) to
ensure that Ember.onerror
is properly configured. Without a check like
this, Ember.onerror
could easily swallow all errors and make it seem
like everything is just fine (and have green tests) when in reality
everything is on fire...
callback
Function the callback to validate (optional, defaultEmber.onerror
)
Example implementation for ember-qunit
import { validateErrorHandler } from '@ember/test-helpers';
test('Ember.onerror is functioning properly', function(assert) {
let result = validateErrorHandler();
assert.ok(result.isValid, result.message);
});
Returns Object object with isValid
and message
Sets the Ember.onerror
function for tests. This value is intended to be reset after
each test to ensure correct test isolation. To reset, you should simply call setupOnerror
without an onError
argument.
onError
Function the onError function to be set on Ember.onerror
Example implementation for ember-qunit
or ember-mocha
import { setupOnerror } from '@ember/test-helpers';
test('Ember.onerror is stubbed properly', function(assert) {
setupOnerror(function(err) {
assert.ok(err);
});
});
Resets Ember.onerror
to the value it originally was at the start of the test run.
If there is no context or cached value this is a no-op.
import { resetOnerror } from '@ember/test-helpers';
QUnit.testDone(function() {
resetOnerror();
})
Gets the test metadata associated with the provided test context. Will create a new test metadata object if one does not exist.
context
BaseContext the context to use
Returns TestMetadata the test metadata for the provided context
Returns a promise which will resolve when rendering has completed. In this context, rendering is completed when all auto-tracked state that is consumed in the template (including any tracked state in models, services, etc. that are then used in a template) has been updated in the DOM.
For example, in a test you might want to update some tracked state and
then run some assertions after rendering has completed. You could use
await settled()
in that location, but in some contexts you don't want to
wait for full settledness (which includes test waiters, pending AJAX/fetch,
run loops, etc) but instead only want to know when that updated value has
been rendered in the DOM. THAT is what await rerender()
is perfect
for.
Returns Promise<void> a promise which fulfills when rendering has completed
Registers a function to be run during the invocation of a test helper.
helperName
string The name of the test helper in which to run the hook. Test helper names includeblur
,click
,doubleClick
,fillIn
,fireEvent
,focus
,render
,scrollTo
,select
,tab
,tap
,triggerEvent
,triggerKeyEvent
,typeIn
, andvisit
.label
string A label to help identify the hook. Built-in labels includestart
,end
, andtargetFound
, the former designating either the start or end of the helper invocation.hook
Function The hook function to run when the test helper is invoked.
Registering a hook for the end
point of the click
test helper invocation
const hook = registerHook('click', 'end', () => {
console.log('Running `click:end` test helper hook');
});
// Unregister the hook at some later point in time
hook.unregister();
Returns HookUnregister An object containing an unregister
function that unregisters
the specific hook initially registered to the helper.
Runs all hooks registered for a specific test helper.
helperName
string The name of the test helper in which to run the hook. Test helper names includeblur
,click
,doubleClick
,fillIn
,fireEvent
,focus
,render
,scrollTo
,select
,tab
,tap
,triggerEvent
,triggerKeyEvent
,typeIn
, andvisit
.label
string A label to help identify the hook. Built-in labels includestart
,end
, andtargetFound
, the former designating either the start or end of the helper invocation.args
Array<unknown> Any arguments originally passed to the test helper.
Returns Promise<void> A promise representing the serial invocation of the hooks.
Returns deprecations which have occurred so far for a the current test context
Usage via ember-qunit
import { getDeprecations } from '@ember/test-helpers';
module('awesome-sauce', function(hooks) {
setupRenderingTest(hooks);
test('does something awesome', function(assert) {
const deprecations = getDeprecations() // => returns deprecations which have occurred so far in this test
});
});
Returns Array<DeprecationFailure> An array of deprecation messages
Returns deprecations which have occurred so far for a the current test context
callback
Function? The callback that when executed will have its DeprecationFailure recorded
Usage via ember-qunit
import { getDeprecationsDuringCallback } from '@ember/test-helpers';
module('awesome-sauce', function(hooks) {
setupRenderingTest(hooks);
test('does something awesome', function(assert) {
const deprecations = getDeprecationsDuringCallback(() => {
// code that might emit some deprecations
}); // => returns deprecations which occurred while the callback was invoked
});
test('does something awesome', async function(assert) {
const deprecations = await getDeprecationsDuringCallback(async () => {
// awaited code that might emit some deprecations
}); // => returns deprecations which occurred while the callback was invoked
});
});
Returns (Array<DeprecationFailure> | Promise<Array<DeprecationFailure>>) An array of deprecation messages
Returns warnings which have occurred so far for a the current test context
Usage via ember-qunit
import { getWarnings } from '@ember/test-helpers';
module('awesome-sauce', function(hooks) {
setupRenderingTest(hooks);
test('does something awesome', function(assert) {
const warnings = getWarnings() // => returns warnings which have occurred so far in this test
});
});
Returns Array<Warning> An array of warnings
Returns warnings which have occurred so far for a the current test context
callback
Function? The callback that when executed will have its warnings recorded
Usage via ember-qunit
import { getWarningsDuringCallback } from '@ember/test-helpers';
import { warn } from '@ember/debug';
module('awesome-sauce', function(hooks) {
setupRenderingTest(hooks);
test('does something awesome', function(assert) {
const warnings = getWarningsDuringCallback(() => {
warn('some warning');
}); // => returns warnings which occurred while the callback was invoked
});
test('does something awesome', async function(assert) {
warn('some warning');
const warnings = await getWarningsDuringCallback(async () => {
warn('some other warning');
}); // => returns warnings which occurred while the callback was invoked
});
});
Returns (Array<Warning> | Promise<Array<Warning>>) An array of warnings information