• Stars
    star
    186
  • Rank 207,316 (Top 5 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 8 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Test helpers for your integration tests that fire native events

Build Status

IMPORTANT: You probably don't need this addon.

In Ember, since ember-(cli-)qunit 3.X (around late 2017) there is a new testing API that already provides almost identical test helpers from the ones in this addon.

This addon was used as an experiment that helped bikeshed the API of the helpers that are now part of default testing API, like click, tap, fillIn and others.

The only two helpers in this addon that are not part of the default set of helpers that ship with Ember's test harness are scrollTo(selectorOrHTMLElement, x, y) and selectFiles(selectorOrHTMLElement, files = []).

Unless you want to use those, you are better served using the helpers provided by @ember/test-helpers.

ember-native-dom-helpers

Test helpers for integration tests that mimic the behaviour of the acceptance test helpers provided by Ember.

Use this addon as a way to start the gradual migration towards the future "testing unification" RFC, which proposes only native DOM.

See the Grand Testing Unification RFC

Status: (Pre) 1.0, although we have a good idea about what the needs are for test helpers, we are working through a few points on what changes are needed when using only standard DOM APIs (i.e. without jQuery).

Usage

Integration tests

import { click, fillIn, find, findAll, keyEvent, triggerEvent } from 'ember-native-dom-helpers';

moduleForComponent('my-component', 'Integration | Component | my-component', {
  integration: true
});


test('I can interact with my component', async function(assert) {
  this.render(hbs```
    {{my-component}}
  ```);

  await fillIn('.some-input', 'some text');
  await click('.main-button');
  await keyEvent('.other-input', 'keyup', 40); // down arrow
  await triggerEvent('.some-drop-area', 'mouseenter');

  assert.ok(find('.result-of-event-happened'));
  assert.equal(findAll('.result-list-item').length, 3);
})

Acceptance tests

You can use the exact same helpers for your acceptance tests. All interaction helpers like click, fillIn, et al., return a promise that fullfils when "the world has settled" (that is, there are no pending requests or promises, and the runloop has been drained), which is what the andThen acceptance helper used to do. However, this helper can now be replaced by the async/await syntax in ES2017, yielding easier-to-read tests:

import { visit, click, find, fillIn } from 'ember-native-dom-helpers';

moduleForAcceptance('Acceptance | Sign up');

test('Usage awaiting the world to settle', async function(assert) {
  await visit('/sign-up');

  await fillIn('.first-name', 'Chuck');
  await fillIn('.last-name', 'Berry');
  await click('.submit-btn');

  assert.ok(find('.welcome-msg'), 'There is a welcome banner');
  assert.equal(find('.welcome-msg-name'), 'Chuck');
});

Advantages compared with this.$(selector).click()

The main advantages are:

  • Fires native events: In Ember, when adding events with the onclick={{action "foo"}} syntax, dispatching jQuery events leads to the action being called twice. Additionally, there are subtle differences between jQuery and Native events that can bite you. Firing native events fixes that problem, but they are very verbose and there are browser incompatibilities. This addon makes firing native events a no-brainer.

  • Runloop aware: These helpers automatically spawn a runloop, so you don't need to wrap every interaction with Ember.run(() => /* interact with element */ );.

  • wait by default: All the helpers return the wait() promise, making it possible to wait for asynchronous side-effects with async/await. (Note that for using async/await in browsers without native support you must install ember-maybe-import-regenerator).

    test('some test', async function(assert) {
      this.render(hbs```{{my-component}}```);
    
      await click('.my-button');
    
      assert.ok('something happened');
    });
  • More realistic behaviour: When a user clicks on an element, click is not the only event fired. In a real click, the sequence of events is mousedown, focus, mouseup, click. When a user fills in an input the sequence of events is focus, <mutate-value>, input, and change. The helpers provided by this addon fire those events in the right order, simulating more closely how a real user would interact with the page.

Standard DOM elements returned using a find/findAll helpers

  • The find helper uses document.querySelector and will return a single HTMLElement or null.
  • The findAll helper uses document.querySelectorAll and returns an Array with zero or more elements.
  • Both find and findAll helpers query the DOM within #ember-testing.
  • To use a different value from your config/environment.js settings, add to tests/test-helper.js…
import { settings } from 'ember-native-dom-helpers';
import config from '../config/environment';
const { APP: { rootElement } } = config;

settings.rootElement = rootElement || settings.rootElement;

What if I prefer jQuery collections over native DOM?

Fear not. If you prefer to use jQuery, just wrap the result and do your thing:

assert.equal($(find('.my-class')).attr('aria-owns'), '#id123')

Testing an unsettled world

There is one new helper in this addon that enables some testing patterns that weren't previously easy to perform using traditional methods.

Since the andThen helper waits for the app to settle (no pending requests or promises), and every integration test interaction is wrapped in Ember.run, there is no easy way to test transient state, like loading substates or the state of a component, while some promise is pending, without an awkward setup of timeouts.

Now, however, thanks to explicit usage of promises and the waitUntil helper, you can perform assertions on unsettled states:

import { visit, click, find, fillIn, waitUntil, currentURL } from 'ember-native-dom-helpers';

moduleForAcceptance('Acceptance | Sign up');

test('Usage awaiting the world to settle', async function(assert) {
  await visit('/login');

  await fillIn('.email', '[email protected]');
  await fillIn('.password', 'goldeneye');
  let promise = click('.submit-btn');

  // We wait until the loading substate, that takes 200ms to appear, is displayed
  await waitUntil(() => find('.substate-spinner'));
  assert.equal(find('.loading-substate-header').textContent.trim(), 'Loading mission. Please wait, Mr. Bond');

  await promise; // now we wait until the dashboard is fully loaded
  assert.equal(currentURL(), '/dashboard');
  assert.equal(find('.section-header').textContent, 'Main dashboard');
});

I WANT IT NOW, IS THERE A SHORTCUT?

Yes, there is a codemod that will help you transform your test suite to this new style "automatically". Check https://github.com/simonihmig/ember-native-dom-helpers-codemod.

The codemod can't make a perfect conversion, but it will do most of the work for you.

Helpers

  • click(selectorOrHTMLElement, contextHTMLElement, eventOptions)
  • tap(selectorOrHTMLElement, eventOptions)
  • fillIn(selectorOrHTMLElement, text)
  • find(selector, contextHTMLElement) (query for an element in test DOM, #ember-testing)
  • findAll(selector, contextHTMLElement) (query for elements in test DOM, #ember-testing)
  • findWithAssert(selector, contextHTMLElement) (same as find, but raises an Error if no result)
  • keyEvent(selectorOrHTMLElement, type, keyCode, modifiers) (type being keydown, keyup or keypress, modifiers being object with { ctrlKey: false, altKey: false, shiftKey: false, metaKey: false })
  • triggerEvent(selectorOrHTMLElement, type, options)
  • focus(selectorOrHTMLElement)
  • blur(selectorOrHTMLElement)
  • scrollTo(selectorOrHTMLElement, x, y)
  • selectFiles(selectorOrHTMLElement, files = []) (selects the file(s)/Blob(s) to the given input[type=file]. Example
  • visit(url) (only available in acceptance. Raises an error in integration.)
  • waitUntil(function, options) (Polls the page until the given callback returns a truthy value, or timesout after 1s)
  • waitFor(selector, options) (Convenience for the most common use-case of waitUntil. It polls the page until the element with the given selector is on the page, or timesout after 1s. It accepts a count: 3 option to await a specific number of matches.)
  • currentURL() Identical to the one provided by Ember.
  • currentPath() Identical to the one provided by Ember.
  • currentRouteName() Identical to the one provided by Ember.

Notes of tap

In order for tap to work, your browser has to support touch events. Desktop Chrome and Firefox have touch events disabled unless the device emulation mode is on. To enable touch events in your CI, you need to configure testem like the testem.js file on this repo.

More Repositories

1

ember-power-select

The extensible select component built for ember.
JavaScript
540
star
2

ember-cpm

ComputedProperty Macros for Ember
JavaScript
275
star
3

svelte-intl-precompile

I18n library for Svelte.js that analyzes your keys at build time for max performance and minimal footprint
JavaScript
258
star
4

ember-power-calendar

Powerful and customizable calendar component for Ember
JavaScript
207
star
5

ember-basic-dropdown

The basic dropdown you ember app needs
JavaScript
148
star
6

svelte-media

Svelte.js util to easily observe media queries as a reactive store
TypeScript
58
star
7

ember-cli-yuidoc

EmberCLI addon for generate documentation from YUIDoc coments
JavaScript
55
star
8

ember-power-datepicker

An extensible datepicker for Ember
JavaScript
50
star
9

ember-power-select-with-create

Ember-power-select addon with an `Add ${term}` option in the first position
JavaScript
50
star
10

ember-ast-helpers

Utility belt to level-up your Ember AST transforms
TypeScript
40
star
11

ember-text-measurer

Simple Ember Service to measure the width of a string in a performant way
JavaScript
38
star
12

ember-power-select-typeahead

Typeahead component built on top of ember-power-select
JavaScript
36
star
13

storyteller

Storyteller application built with Exilir and Dynamo. Is a concurrent storyteller.
Elixir
34
star
14

rubytapas_downloader

Simple ruby script that downloads the latest rubytapas episodes.
Ruby
26
star
15

mobile-patterns

Showcase of mobile UI patterns implemented in Ember.js
JavaScript
21
star
16

ember-hash-helper-polyfill

Polyfill for the new Ember hash helper
JavaScript
15
star
17

precompile-intl-runtime

Runtime helpers to be used in translations precompiled by babel-plugin-precompile-intl
TypeScript
10
star
18

ember-power-select-with-fallback

Ember Power Select that fallbacks to a native select when certain criteria are met
JavaScript
10
star
19

rollup-plugin-precompile-intl

Rollup plugin to precompile translations in the ICU message syntax
JavaScript
9
star
20

ember-power-calendar-moment

Internal utils of Ember Power Calendar built on top of Moment.js
JavaScript
9
star
21

ember-power-select-blockless

Blockless version of ember-power-select
JavaScript
8
star
22

git-repo-version

Calculates the version of a repo based on the package.json and the current SHA
JavaScript
8
star
23

ember-disable-proxy-controllers

Disables ObjectController/ArrayController for autogenerated controllers
JavaScript
7
star
24

babel-plugin-precompile-intl

Compile translations in ICU message format to invocable functions at build time
TypeScript
7
star
25

ember-power-select-places

Ember Power Select ❀️Google Places
JavaScript
6
star
26

ember-power-select-sortable

Ember-power-select <3 Ember-sortable
JavaScript
6
star
27

DahuaDoorbell2MQTT

Node.js script that connects to a Dahua Video Doorbell and broadcasts to MQTT events fired by it.
JavaScript
6
star
28

ember-power-select-collection

Ember-power-select component that {{vertical-collection}} for performance
JavaScript
5
star
29

ember-basic-dropdown-hover

Variation of ember-basic-dropdown that opens on hover
JavaScript
5
star
30

ember-k-codemod

Removes all usages of Ember.K
JavaScript
5
star
31

ember-assign-helper

Simple {{assign}} helper for Ember
JavaScript
5
star
32

ember-code-example-component

Small component to show code snippets (hbs + js + css + evaluated-result)
JavaScript
5
star
33

homeassistant-poolstation

HomeAssistant custom component for integrating the Poolstation platform.
Python
4
star
34

ember-power-calendar-luxon

Internal utils of Ember Power Calendar built on top of Luxon
JavaScript
3
star
35

marvel-api-ember-sample-app

Sample Ember.js app using marvel API
JavaScript
3
star
36

vite-plugin-svelte-inline-components

Allows you to define your components inline in tests using tagged templates
JavaScript
3
star
37

ember-simple-i18n

Simple i18n library for ember.js apps
JavaScript
3
star
38

cibernox.github.io

JavaScript
3
star
39

space-crops

JavaScript
2
star
40

home-assistant-addons

Repository with unofficial addons for home assistant
Shell
2
star
41

spanish_ccc_validator

Simple validator for spanish bank account numbers
Ruby
2
star
42

sample-app-svelte-intl-precompile

Sample app that uses svelte-intl-precompile, to use as a doc
Svelte
2
star
43

web_experiments

Web experiments using pure HTML5 and CSS3 and Javascript
JavaScript
2
star
44

sparkles-ember-basic-dropdown

Just testing sparkles-component
JavaScript
2
star
45

svelte-intl-precompile-docs

Documentation page for Svelte-intl-precompile
JavaScript
2
star
46

ember-proxy-controllers

Ember.ObjectController and Ember.ArrayController extracted as an standalone addon
JavaScript
2
star
47

ember-cli-google-libphonenumber-shim

Ember-cli addon that imports google-libphonenumber and provides shims for it
JavaScript
2
star
48

ember-i18n-errors

Extension to ember-i18n for translating error messages within the route hierarchy
JavaScript
2
star
49

sveltekit-bug-with-plugin

Repro
Svelte
1
star
50

PyPoolstation

Python library to interact the the Poolstation platform
Python
1
star
51

pinkmine

A redmine-inspired project management web app
Ruby
1
star
52

angular-football-experiment

Sample app for learn angular.
CoffeeScript
1
star
53

bencher

Simplest benchmarking library for ruby
Ruby
1
star
54

my-mu-app

Sample ember app with module unification layour
JavaScript
1
star
55

my-mu-addon

First addon ever created with the addon MU blueprint
JavaScript
1
star