ember-cli-yadda-opinionated
Version:
A radical take on Cucumber to solve your test maintenance woes.
141 lines (110 loc) • 5.29 kB
JavaScript
import { blur, click, doubleClick, fillIn, focus, settled, triggerEvent, visit, triggerKeyEvent } from '@ember/test-helpers';
import { assert } from '@ember/debug';
import { findEditable, findInputForLabelWithText } from 'ember-cli-yadda-opinionated/test-support/-private/dom-helpers';
const steps = {
async "When I (?:visit|am at|proceed to) URL $opinionatedString"(url) {
try {
await visit(url);
} catch (e) {
// See https://github.com/emberjs/ember-test-helpers/issues/332
if (e.message !== 'TransitionAborted') {
throw e;
}
}
return settled();
},
"When the app settles"() {
return settled();
},
"When I click (?:on )?$opinionatedElement"([collection/* , label, selector */]) {
assert(`Expected a single element, but ${collection.length} found`, collection.length === 1);
return click(collection[0]);
},
"When I double click (?:on )?$opinionatedElement"([collection/* , label, selector */]) {
assert(`Expected a single element, but ${collection.length} found`, collection.length === 1);
return doubleClick(collection[0]);
},
"When I fill \"(.*)\" into $opinionatedElement"(text, [collection/* , label, selector */]) {
assert(`Expected a single element, but ${collection.length} found`, collection.length === 1);
const element = collection[0];
const target = findEditable(element);
return fillIn(target, text);
},
"When I move the mouse pointer into $opinionatedElement"([collection/* , label, selector */]) {
assert(`Expected a single element, but ${collection.length} found`, collection.length === 1);
return triggerEvent(collection[0], 'mouseenter');
},
"When I move the mouse pointer out of $opinionatedElement"([collection/* , label, selector */]) {
assert(`Expected a single element, but ${collection.length} found`, collection.length === 1);
return triggerEvent(collection[0], 'mouseeleave');
},
"When I focus into $opinionatedElement"([collection/* , label, selector */]) {
assert(`Expected a single element, but ${collection.length} found`, collection.length === 1);
return focus(collection[0]);
},
"When I focus out of $opinionatedElement"([collection/* , label, selector */]) {
assert(`Expected a single element, but ${collection.length} found`, collection.length === 1);
return blur(collection[0]);
},
"When I (de)?select (?:the )?(?:radio button|checkbox) $opinionatedElement"(de, [collection/* , label, selector */]) {
assert(`Expected a single element, but ${collection.length} found.`, collection.length === 1);
const [element] = collection;
let input;
if (element.type === 'checkbox' || element.type === 'radio') {
input = element;
} else {
const inputs = element.querySelectorAll('input[type="text"], input[type="checkbox"]');
assert(`Expected one checkbox/radio, but ${inputs.length} found`, inputs.length === 1);
[input] = inputs;
}
assert('A radio button cannot be deselected', !(de && (input.type === 'radio')));
assert(`Expected input ${de ? 'not ' : ''}to be selected`, de ? input.checked : !input.checked);
return click(input);
},
"When I (de)?select (?:the )?(?:radio button|checkbox) $opinionatedString in $opinionatedElement"(de, text, [collection/* , label, selector */]) {
assert(`Expected a single element, but ${collection.length} found.`, collection.length === 1);
const [element] = collection;
const input = findInputForLabelWithText(text, element);
assert('Expected input to exist', input)
assert('Expected input to be a checkbox or radio button', input.type === 'checkbox' || input.type === 'radio');
assert('A radio button cannot be deselected', !(de && (input.type === 'radio')));
assert(`Expected input ${de ? '' : 'not '}to be selected`, de ? input.checked : !input.checked);
return click(input);
},
"When I (press|press down|release) the $opinionatedString key in $opinionatedElement"(eventRaw, key, [collection/* , label, selector */]) {
assert(`Expected a single element, but ${collection.length} found`, collection.length === 1);
const events = {
press: 'keypress',
'press down': 'keydown',
release: 'keyup',
};
const event = events[eventRaw];
const keys = key.split('+');
const {modifiers, remainingKeys} = keys.reduce(({modifiers, remainingKeys}, key) => {
if (key.toLowerCase() === 'ctrl') {
modifiers.ctrlKey = true;
}
else if (key.toLowerCase() === 'alt') {
modifiers.ctrlKey = true;
}
else if (key.toLowerCase() === 'shift') {
modifiers.shiftKey = true;
}
else if (key.toLowerCase() === 'meta') {
modifiers.ctrlKey = true;
}
else {
remainingKeys.push(key);
}
return {modifiers, remainingKeys};
}, {modifiers: {}, remainingKeys: []});
if (remainingKeys.length > 1) {
throw new Error(`Can press only one non-modifier key at once, but tried to press ${remainingKeys.join('+')}`);
}
if (remainingKeys.length === 0) {
throw new Error('A non-modifier key is required to press.');
}
triggerKeyEvent(collection[0], event, remainingKeys[0], modifiers);
},
};
export default steps;