Prevent keymaster bindings from causing failed tests (#976)

no issue
- keymaster bindings could be kept around between tests with references to objects that should have been deleted. This was manifesting itself with a Tags acceptance test failing because one of the key binding tests triggered two actions, one on the route under test and another on a route that was kept around from a previous Error Handling acceptance test (previous test intentionally had an aborted transition so the action in the current test was complaining about the first transition not being complete)
- add guard to ensure that shortcuts can't be registered multiple times on an object
- remove all `default` scope keymaster bindings when destroying a test app instance
This commit is contained in:
Kevin Ansfield 2018-03-19 18:39:17 +00:00 committed by GitHub
parent 2a55c5767f
commit 069bccdd94
2 changed files with 32 additions and 15 deletions

View File

@ -44,27 +44,34 @@ key.setScope('default');
* Find out more at the keymaster docs
*/
export default Mixin.create({
_hasRegisteredShortcuts: false,
registerShortcuts() {
let shortcuts = this.get('shortcuts');
if (!this._hasRegisteredShortcuts) {
let shortcuts = this.get('shortcuts');
Object.keys(shortcuts).forEach((shortcut) => {
let scope = shortcuts[shortcut].scope || 'default';
let action = shortcuts[shortcut];
let options;
Object.keys(shortcuts).forEach((shortcut) => {
let scope = shortcuts[shortcut].scope || 'default';
let action = shortcuts[shortcut];
let options;
if (typeOf(action) !== 'string') {
options = action.options;
action = action.action;
}
if (typeOf(action) !== 'string') {
options = action.options;
action = action.action;
}
key(shortcut, scope, (event) => {
// stop things like ctrl+s from actually opening a save dialogue
event.preventDefault();
run(this, function () {
this.send(action, options);
key(shortcut, scope, (event) => {
// stop things like ctrl+s from actually opening a save dialogue
event.preventDefault();
run(this, function () {
this.send(action, options);
});
});
});
});
this._hasRegisteredShortcuts = true;
}
},
removeShortcuts() {
@ -74,5 +81,10 @@ export default Mixin.create({
let scope = shortcuts[shortcut].scope || 'default';
key.unbind(shortcut, scope);
});
},
willDestroy() {
this._super(...arguments);
this.removeShortcuts();
}
});

View File

@ -1,3 +1,4 @@
/* global key */
import {run} from '@ember/runloop';
export default function destroyApp(application) {
@ -6,5 +7,9 @@ export default function destroyApp(application) {
server.shutdown();
}
// extra check to ensure we don't have references hanging around via key
// bindings on supposedly destroyed objects
key.deleteScope('default');
run(application, 'destroy');
}