- 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):
blurfocusout
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):
mousedownmouseupclick
For focusable (e.g. form control) elements the following events are triggered (in order):
mousedownfocusfocusinmouseupclick
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_optionsMouseEventInit 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):
mousedownmouseupclickmousedownmouseupclickdblclick
For focusable (e.g. form control) elements the following events are triggered (in order):
mousedownfocusfocusinmouseupclickmousedownmouseupclickdblclick
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_optionsMouseEventInit 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 intotextstring 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):
focusfocusin
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 onxNumber x-coordinateyNumber y-coordinate
Scroll DOM element to specific coordinates
scrollTo('#my-long-div', 0, 0); // scroll to top
scrollTo('#my-long-div', 0, 100); // scroll downReturns 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 selectkeepPreviouslySelectedboolean 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.
-
optionsObject? 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):
touchstarttouchendmousedownmouseupclick
For focusable (e.g. form control) elements the following events are triggered (in order):
touchstarttouchendmousedownfocusfocusinmouseupclick
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 onoptionsObject 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 oneventTypestring the type of event to triggeroptionsObject additional properties to be set on the eventforceboolean if true, will bypass availability checks (false by default) (optional, defaultfalse)
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 -
modifiersObject? the state of various modifier keys (optional, defaultDEFAULT_MODIFIERS)modifiers.ctrlKeyboolean if true the generated event will indicate the control key was pressed during the key event (optional, defaultfalse)modifiers.altKeyboolean if true the generated event will indicate the alt key was pressed during the key event (optional, defaultfalse)modifiers.shiftKeyboolean if true the generated event will indicate the shift key was pressed during the key event (optional, defaultfalse)modifiers.metaKeyboolean 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 intotextstring the test to fill the element withoptionsObject {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.
selectorstring 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.
selectorstring 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 renderoptionsRenderOptions 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 -
optionsObject? 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
Used to wait for a particular selector to receive focus. Useful for verifying keyboard navigation handling and default focus behaviour, without having to think about timing issues.
-
target(string | IDOMElementDescriptor) the selector or DOM element descriptor to wait receiving focus -
optionsObject? the options to be used (optional, default{})
Waiting until a selector receive focus:
await waitForFocus('.my-selector', { timeout: 2000 })Returns Promise<Element> resolves when the element received focus
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).
-
callbackFunction the callback to use for testing when waiting should stop -
optionsObject? 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 betrueotherwise 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/ajaxCompleteevents 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.
debugHelperDebugInfoHelper 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.
resolverEmber.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.getPropertiesto the provided context - setting up AJAX listeners
- setting up
pauseTest(also available asthis.pauseTest()) andresumeTesthelpers
-
baseObject the context to setup -
optionsObject? options used to override defaults (optional, default{})options.resolverResolver? 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.
contextObject 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
-
contextObject the context to setup -
optionsObject? options used to override defaults (optional, default{})options.waitForSettledboolean 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
renderhelper. - Ensuring the event dispatcher is properly setup.
- Setting
this.elementto the root element of the testing container (things rendered viarenderwill go into this element).
contextTestContext 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
setupApplicationContextmethod. - Used by
setupContextandsetupRenderingContextwhen present.
applicationEmber.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.
contextObject 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...
callbackFunction 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.
onErrorFunction 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.
contextBaseContext 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.
helperNamestring 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.labelstring 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.hookFunction 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.
helperNamestring 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.labelstring 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.argsArray<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
callbackFunction? 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
callbackFunction? 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