ember-semantic-test-helpers
v1.0.0
Published
Semantic test helpers for testing accessible ember apps
Downloads
142
Maintainers
Readme
ember-semantic-test-helpers
Exposes semantic helpers based on https://github.com/emberjs/rfcs/pull/327 RFC
The goal of this addon is to promote a path way to aria compatibility for ember applications and addons. while improving developer ergonomics.
An element must be perceivable to assistive technologies in order to have a democratized internet. If an element is not perceivable then it is should not be perceivable to tests either.
Instead of searching for elements using css selectors you will use what is present on your ui, the happy path is that your ui is aria compliant and this addon would just work. Since their are many applications that are not compliant, if we don't explode but we use configurable strategies to find and fill in elements.
Compatibility
- Ember.js v2.18 or above
- Ember CLI v2.13 or above
Installation
ember install ember-semantic-test-helpers
Basic Usage
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { visit } from '@ember/test-helpers';
import { click, fillIn, select, toggle } from 'ember-semantic-test-helpers/test-support';
module('Login', function(hooks) {
setupApplicationTest(hooks);
test('Logging in', async function(assert) {
await visit('/login');
await fillIn('Email', '[email protected]');
await fillIn('Password', 'topsecret');
await select('Some label targeting a select', 123)
await toggle('keep me logged in')
await click('Log in');
});
});
Interacting with elements
Elements are differentiated by their modes of interaction. here is a list of interactions and corresponding helpers:
- dropdowns -
select
- input boxes -
fillIn
- toggles -
toggle
- clickable elements -
click
The definition of what elements are select/text.. can be found here. These definitions will improve and grow over time, let us know if something is missing, or incorrectly defined.
How elements are found.
An element is perceived using the Text alternative spec, which is implemented here
If your element does not follow this spec we currently comes support 2 fallback finding strategies.
perceivedByName, uses
[name=""]
invalidFor, Not all elements are equal if your labels
[for=""]
targets an element that is not an HTML semantic form control, it is not aria compliant.
if an element is found using a fallback strategy it is considered an error, the severity of that error can be configured. by default all rules are set to 1
import config from 'ember-semantic-test-helpers/test-support/config';
config.setErrorLevels({
invalidFor: 0 //Throw error
perceivedByName: 2 //silence
myCustomRule: 1 //log to console
})
Trimming
Change the way we trim the inner text of dom. by default we normalize it all line breaks and mutli-spaces to 1space.
import config from 'ember-semantic-test-helpers/test-support/config';
config.trim = function(text){ return text }
//if you don't want it to be trim
If you need to build more fallback strategies
Finders are passed a selector: string
which encapsulates the various types as defined before. they then use various strategies to compute a label for the elements selected. This label is matched the passed text
Every finder should have a unique key that will be used for error level configuration.
Finally finders should implement and error text if they have matched, ideally, every finder will match find-by-aria, as this is the aria compliancy finder. if they do not it is considered an error, but we still want elements found so that developers can use the helpers. While providing a path to aria compliancy.
Finder Object Defintion
{
key: string
run: function(selector: string, text: string): HTMLElement
errorText: function(type, labelText)
}
Actors
Elements are interacted with using actors. toggle
,select
, click
, fillin
helpers are all actors. The problem arises that there is a diverse set of customised form controls, that either this addon does not support the aria spec completely yet, or that are just not compliant at all. In order to resolve this, you can define your own actors.
Actors are by the base helpers, toggle
,select
, click
, fillin
Actor object definition
{
type: Enum('select', 'toggle', 'text', 'click')
run:function(control: HTMLElement, value)
}
The type of value is different for each kind of actor
- select
value: string
- toggle
value: null
- text
value: string
- click
value: null
An example of a select actor can be found here
API
function click(label: string): Promise<void>
function select(label: string, value): Promise<void>
function toggle(label: string): Promise<void>
function fillIn(label: string, value): Promise<void>
function findButton(label: string, value): HTMLElement
function findControl(label: string, value): HTMLElement
Contributing
See the Contributing guide for details.
License
This project is licensed under the MIT License.