diff --git a/.eslintrc b/.eslintrc
index 7b8ffc00311..19d38e35c77 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -43,6 +43,10 @@
"asyncRender":true,
"selectDropdown":true,
"selectBox":true,
+ "expandSelectBox":true,
+ "collapseSelectBox":true,
+ "selectBoxSelectRow":true,
+ "selectBoxFillInFilter":true,
"asyncTestDiscourse":true,
"fixture":true,
"find":true,
diff --git a/app/assets/javascripts/discourse/components/select-box.js.es6 b/app/assets/javascripts/discourse/components/select-box.js.es6
index d2e0c25b990..1a05f398078 100644
--- a/app/assets/javascripts/discourse/components/select-box.js.es6
+++ b/app/assets/javascripts/discourse/components/select-box.js.es6
@@ -62,10 +62,17 @@ export default Ember.Component.extend({
};
},
- @computed
- titleForRow: function() {
+ @computed("textKey")
+ titleForRow(textKey) {
return (rowComponent) => {
- return rowComponent.get(`content.${this.get("textKey")}`);
+ return rowComponent.get(`content.${textKey}`);
+ };
+ },
+
+ @computed("idKey")
+ idForRow(idKey) {
+ return (rowComponent) => {
+ return rowComponent.get(`content.${idKey}`);
};
},
diff --git a/app/assets/javascripts/discourse/components/select-box/select-box-row.js.es6 b/app/assets/javascripts/discourse/components/select-box/select-box-row.js.es6
index f0e359dafb4..247b95f5735 100644
--- a/app/assets/javascripts/discourse/components/select-box/select-box-row.js.es6
+++ b/app/assets/javascripts/discourse/components/select-box/select-box-row.js.es6
@@ -8,29 +8,24 @@ export default Ember.Component.extend({
tagName: "li",
- attributeBindings: ["title"],
+ attributeBindings: ["title", "id:data-id"],
classNameBindings: ["isHighlighted:is-highlighted", "isSelected:is-selected"],
@computed("titleForRow")
- title(titleForRow) {
- return titleForRow(this);
- },
+ title(titleForRow) { return titleForRow(this); },
+
+ @computed("idForRow")
+ id(idForRow) { return idForRow(this); },
@computed("templateForRow")
- template(templateForRow) {
- return templateForRow(this);
- },
+ template(templateForRow) { return templateForRow(this); },
@computed("shouldHighlightRow", "highlightedValue")
- isHighlighted(shouldHighlightRow) {
- return shouldHighlightRow(this);
- },
+ isHighlighted(shouldHighlightRow) { return shouldHighlightRow(this); },
@computed("shouldSelectRow", "value")
- isSelected(shouldSelectRow) {
- return shouldSelectRow(this);
- },
+ isSelected(shouldSelectRow) { return shouldSelectRow(this); },
icon() {
if (this.get("content.icon")) {
diff --git a/app/assets/javascripts/discourse/templates/components/select-box.hbs b/app/assets/javascripts/discourse/templates/components/select-box.hbs
index c20f76e2e37..129be626394 100644
--- a/app/assets/javascripts/discourse/templates/components/select-box.hbs
+++ b/app/assets/javascripts/discourse/templates/components/select-box.hbs
@@ -39,6 +39,7 @@
shouldHighlightRow=shouldHighlightRow
shouldSelectRow=shouldSelectRow
titleForRow=titleForRow
+ idForRow=idForRow
onSelectRow=(action "onSelectRow")
onHoverRow=(action "onHoverRow")
onClearSelection=(action "onClearSelection")
diff --git a/app/assets/javascripts/discourse/templates/components/select-box/select-box-collection.hbs b/app/assets/javascripts/discourse/templates/components/select-box/select-box-collection.hbs
index 3d77b5050e5..f6adcdf1acc 100644
--- a/app/assets/javascripts/discourse/templates/components/select-box/select-box-collection.hbs
+++ b/app/assets/javascripts/discourse/templates/components/select-box/select-box-collection.hbs
@@ -9,6 +9,7 @@
{{component selectBoxRowComponent
content=content
templateForRow=templateForRow
+ idForRow=idForRow
titleForRow=titleForRow
shouldHighlightRow=shouldHighlightRow
shouldSelectRow=shouldSelectRow
diff --git a/test/javascripts/acceptance/category-edit-test.js.es6 b/test/javascripts/acceptance/category-edit-test.js.es6
index fe7568a4982..24c2ada061b 100644
--- a/test/javascripts/acceptance/category-edit-test.js.es6
+++ b/test/javascripts/acceptance/category-edit-test.js.es6
@@ -75,7 +75,9 @@ QUnit.test("Subcategory list settings", assert => {
click('.edit-category-general');
- selectBox('.edit-category-tab-general .category-select-box', 'feature');
+ expandSelectBox('.edit-category-tab-general .category-select-box');
+
+ selectBoxSelectRow(3, {selector: '.edit-category-tab-general .category-select-box'});
click('.edit-category-settings');
andThen(() => {
diff --git a/test/javascripts/acceptance/topic-test.js.es6 b/test/javascripts/acceptance/topic-test.js.es6
index 2c85636b9a4..a6510a2f473 100644
--- a/test/javascripts/acceptance/topic-test.js.es6
+++ b/test/javascripts/acceptance/topic-test.js.es6
@@ -48,11 +48,14 @@ QUnit.test("Showing and hiding the edit controls", assert => {
QUnit.test("Updating the topic title and category", assert => {
visit("/t/internationalization-localization/280");
+
click('#topic-title .d-icon-pencil');
fillIn('#edit-title', 'this is the new title');
- selectBox('.title-wrapper .category-select-box', 'faq');
+ expandSelectBox('.title-wrapper .category-select-box');
+
+ selectBoxSelectRow(4, {selector: '.title-wrapper .category-select-box'});
click('#topic-title .submit-edit');
@@ -100,7 +103,7 @@ QUnit.test("Reply as new topic", assert => {
"it fills composer with the ring string"
);
assert.equal(
- find('.category-select-box .select-box-header .current-selection').html().trim(), "feature",
+ selectBox('.category-select-box').header.text(), "feature",
"it fills category selector with the right category"
);
});
diff --git a/test/javascripts/components/pinned-button-test.js.es6 b/test/javascripts/components/pinned-button-test.js.es6
index f58681fd511..0e41d4056d4 100644
--- a/test/javascripts/components/pinned-button-test.js.es6
+++ b/test/javascripts/components/pinned-button-test.js.es6
@@ -21,24 +21,20 @@ componentTest('updating the content refreshes the list', {
},
test(assert) {
- andThen(() => {
- assert.equal(find(".pinned-button").hasClass("is-hidden"), false);
- });
+ andThen(() => assert.notOk(selectBox().isHidden) );
- click(".select-box-header");
+ expandSelectBox();
- andThen(() => {
- assert.equal(find(".select-box-row.is-selected .title").html().trim(), "Pinned");
- });
+ andThen(() => assert.equal(selectBox().selectedRow.el().find(".title").text(), "Pinned") );
andThen(() => {
this.set("topic.pinned", false);
- assert.equal(find(".select-box-row.is-selected .title").html().trim(), "Unpinned");
+ assert.equal(selectBox().selectedRow.el().find(".title").text(), "Unpinned");
});
andThen(() => {
this.set("topic.deleted", true);
- assert.equal(find(".pinned-button").hasClass("is-hidden"), true);
+ assert.ok(find(".pinned-button").hasClass("is-hidden"), "it hides the button when topic is deleted");
});
}
});
diff --git a/test/javascripts/components/select-box-test.js.es6 b/test/javascripts/components/select-box-test.js.es6
index ebc9fcfb2e4..e4775bbd120 100644
--- a/test/javascripts/components/select-box-test.js.es6
+++ b/test/javascripts/components/select-box-test.js.es6
@@ -10,12 +10,12 @@ componentTest('updating the content refreshes the list', {
},
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
andThen(() => {
- assert.equal(find(".select-box-row .text").html().trim(), "robin");
+ assert.equal(selectBox().row(1).text(), "robin");
this.set("content", [{ id: 1, text: "regis" }]);
- assert.equal(find(".select-box-row .text").html().trim(), "regis");
+ assert.equal(selectBox().row(1).text(), "regis");
});
}
});
@@ -29,16 +29,16 @@ componentTest('accepts a value by reference', {
},
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
andThen(() => {
assert.equal(
- find(".select-box-row.is-selected .text").html().trim(), "robin",
+ selectBox().selectedRow.text(), "robin",
"it highlights the row corresponding to the value"
);
});
- click(".select-box-row[title='robin']");
+ selectBoxSelectRow(1);
andThen(() => {
assert.equal(this.get("value"), 1, "it mutates the value");
@@ -54,21 +54,19 @@ componentTest('select-box can be filtered', {
},
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
andThen(() => assert.equal(find(".filter-query").length, 1, "it has a search input"));
- fillIn(".filter-query", "regis");
- triggerEvent('.filter-query', 'keyup');
+ selectBoxFillInFilter("regis");
- andThen(() => assert.equal(find(".select-box-row").length, 1, "it filters results"));
+ andThen(() => assert.equal(selectBox().rows.length, 1, "it filters results"));
- fillIn(".filter-query", "");
- triggerEvent('.filter-query', 'keyup');
+ selectBoxFillInFilter("");
andThen(() => {
assert.equal(
- find(".select-box-row").length, 2,
+ selectBox().rows.length, 2,
"it returns to original content when filter is empty"
);
});
@@ -79,7 +77,7 @@ componentTest('no default icon', {
template: '{{select-box}}',
test(assert) {
- assert.equal(find(".select-box-header .icon").length, 0, "it doesn’t have an icon if not specified");
+ assert.equal(selectBox().header.icon().length, 0, "it doesn’t have an icon if not specified");
}
});
@@ -87,7 +85,7 @@ componentTest('customisable icon', {
template: '{{select-box icon="shower"}}',
test(assert) {
- assert.equal(find(".select-box-header .icon").hasClass("d-icon-shower"), true, "it has a the correct icon");
+ assert.ok(selectBox().header.icon().hasClass("d-icon-shower"), "it has a the correct icon");
}
});
@@ -95,22 +93,22 @@ componentTest('default search icon', {
template: '{{select-box filterable=true}}',
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
andThen(() => {
- assert.equal(find(".select-box-filter .d-icon-search").length, 1, "it has a the correct icon");
+ assert.ok(selectBox().filter.icon().hasClass("d-icon-search"), "it has a the correct icon");
});
}
});
componentTest('with no search icon', {
- template: '{{select-box filterable=true searchIcon=null}}',
+ template: '{{select-box filterable=true filterIcon=null}}',
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
andThen(() => {
- assert.equal(find(".search-icon").length, 0, "it has no icon");
+ assert.equal(selectBox().filter.icon().length, 0, "it has no icon");
});
}
});
@@ -119,10 +117,10 @@ componentTest('custom search icon', {
template: '{{select-box filterable=true filterIcon="shower"}}',
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
andThen(() => {
- assert.equal(find(".select-box-filter .d-icon-shower").length, 1, "it has a the correct icon");
+ assert.ok(selectBox().filter.icon().hasClass("d-icon-shower"), "it has a the correct icon");
});
}
});
@@ -130,29 +128,22 @@ componentTest('custom search icon', {
componentTest('not filterable by default', {
template: '{{select-box}}',
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
- andThen(() => {
- assert.equal(find(".select-box-filter").length, 0);
- });
+ andThen(() => assert.notOk(selectBox().filter.exists()) );
}
});
-
componentTest('select-box is expandable', {
template: '{{select-box}}',
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
- andThen(() => {
- assert.equal(find(".select-box").hasClass("is-expanded"), true);
- });
+ andThen(() => assert.ok(selectBox().isExpanded) );
- click(".select-box-header");
+ collapseSelectBox();
- andThen(() => {
- assert.equal(find(".select-box").hasClass("is-expanded"), false);
- });
+ andThen(() => assert.notOk(selectBox().isExpanded) );
}
});
@@ -165,10 +156,10 @@ componentTest('accepts custom id/text keys', {
},
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
andThen(() => {
- assert.equal(find(".select-box-row.is-selected .text").html().trim(), "robin");
+ assert.equal(selectBox().selectedRow.text(), "robin");
});
}
});
@@ -181,12 +172,12 @@ componentTest('doesn’t render collection content before first expand', {
},
test(assert) {
- assert.equal(find(".select-box-body .collection").length, 0);
+ assert.notOk(exists(find(".collection")));
- click(".select-box-header");
+ expandSelectBox();
andThen(() => {
- assert.equal(find(".select-box-body .collection").length, 1);
+ assert.ok(exists(find(".collection")));
});
}
});
@@ -199,25 +190,19 @@ componentTest('persists filter state when expandind/collapsing', {
},
test(assert) {
- click(".select-box-header");
- fillIn('.filter-query', 'rob');
- triggerEvent('.filter-query', 'keyup');
+ expandSelectBox();
- andThen(() => {
- assert.equal(find(".select-box-row").length, 1);
- });
+ selectBoxFillInFilter("rob");
- click(".select-box-header");
+ andThen(() => assert.equal(selectBox().rows.length, 1) );
- andThen(() => {
- assert.equal(find(".select-box").hasClass("is-expanded"), false);
- });
+ collapseSelectBox();
- click(".select-box-header");
+ andThen(() => assert.notOk(selectBox().isExpanded) );
- andThen(() => {
- assert.equal(find(".select-box-row").length, 1);
- });
+ expandSelectBox();
+
+ andThen(() => assert.equal(selectBox().rows.length, 1) );
}
});
@@ -229,10 +214,11 @@ componentTest('supports options to limit size', {
},
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
andThen(() => {
- assert.equal(parseInt(find(".select-box-body").height()), 20, "it limits the height");
+ const body = find(".select-box-body");
+ assert.equal(parseInt(body.height()), 20, "it limits the height");
});
}
});
@@ -248,11 +234,9 @@ componentTest('supports custom row template', {
},
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
- andThen(() => {
- assert.equal(find(".select-box-row").html().trim(), "robin");
- });
+ andThen(() => assert.equal(selectBox().row(1).el().html(), "robin") );
}
});
@@ -265,11 +249,9 @@ componentTest('supports converting select value to integer', {
},
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
- andThen(() => {
- assert.equal(find(".select-box-row.is-selected .text").text(), "régis");
- });
+ andThen(() => assert.equal(selectBox().selectedRow.text(), "régis") );
andThen(() => {
this.set("value", 3);
@@ -277,7 +259,7 @@ componentTest('supports converting select value to integer', {
});
andThen(() => {
- assert.equal(find(".select-box-row.is-selected .text").text(), "jeff", "it works with dynamic content");
+ assert.equal(selectBox().selectedRow.text(), "jeff", "it works with dynamic content");
});
}
});
@@ -290,14 +272,14 @@ componentTest('dynamic headerText', {
},
test(assert) {
- click(".select-box-header");
- andThen(() => {
- assert.equal(find(".select-box-header .current-selection").html().trim(), "robin");
- });
+ expandSelectBox();
+
+ andThen(() => assert.equal(selectBox().header.text(), "robin") );
+
+ selectBoxSelectRow(2);
- click(".select-box-row[title='regis']");
andThen(() => {
- assert.equal(find(".select-box-header .current-selection").html().trim(), "regis", "it changes header text");
+ assert.equal(selectBox().header.text(), "regis", "it changes header text");
});
}
});
@@ -311,14 +293,16 @@ componentTest('static headerText', {
},
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
+
andThen(() => {
- assert.equal(find(".select-box-header .current-selection").html().trim(), "Choose...");
+ assert.equal(selectBox().header.text(), "Choose...");
});
- click(".select-box-row[title='regis']");
+ selectBoxSelectRow(2);
+
andThen(() => {
- assert.equal(find(".select-box-header .current-selection").html().trim(), "Choose...", "it doesn’t change header text");
+ assert.equal(selectBox().header.text(), "Choose...", "it doesn’t change header text");
});
}
});
@@ -332,11 +316,9 @@ componentTest('supports custom row title', {
},
test(assert) {
- click(".select-box-header");
+ expandSelectBox();
- andThen(() => {
- assert.equal(find(".select-box-row:first").attr("title"), "sam");
- });
+ andThen(() => assert.equal(selectBox().row(1).title(), "sam") );
}
});
@@ -348,96 +330,60 @@ componentTest('supports keyboard events', {
},
test(assert) {
- const arrowDownEvent = () => {
- const event = jQuery.Event("keydown");
- event.keyCode = 40;
- find(".select-box").trigger(event);
- };
+ expandSelectBox();
- const arrowUpEvent = () => {
- const event = jQuery.Event("keydown");
- event.keyCode = 38;
- find(".select-box").trigger(event);
- };
-
- const escapeEvent = () => {
- const event = jQuery.Event("keydown");
- event.keyCode = 27;
- find(".select-box").trigger(event);
- };
-
- const enterEvent = () => {
- const event = jQuery.Event("keydown");
- event.keyCode = 13;
- find(".select-box").trigger(event);
- };
-
- const tabEvent = () => {
- const event = jQuery.Event("keydown");
- event.keyCode = 9;
- find(".select-box").trigger(event);
- };
-
- click(".select-box-header");
-
- andThen(() => arrowDownEvent() );
+ selectBox().keyboard.down();
andThen(() => {
- assert.equal(find(".select-box-row.is-highlighted").attr("title"), "robin", "it highlights the first row");
+ assert.equal(selectBox().highlightedRow.title(), "robin", "it highlights the first row");
});
- andThen(() => arrowDownEvent() );
+ selectBox().keyboard.down();
andThen(() => {
- assert.equal(find(".select-box-row.is-highlighted").attr("title"), "regis", "it highlights the next row");
+ assert.equal(selectBox().highlightedRow.title(), "regis", "it highlights the next row");
});
- andThen(() => arrowDownEvent() );
+ selectBox().keyboard.down();
andThen(() => {
- assert.equal(find(".select-box-row.is-highlighted").attr("title"), "regis", "it keeps highlighting the last row when reaching the end");
+ assert.equal(selectBox().highlightedRow.title(), "regis", "it keeps highlighting the last row when reaching the end");
});
- andThen(() => arrowUpEvent() );
+ selectBox().keyboard.up();
andThen(() => {
- assert.equal(find(".select-box-row.is-highlighted").attr("title"), "robin", "it highlights the previous row");
+ assert.equal(selectBox().highlightedRow.title(), "robin", "it highlights the previous row");
});
- andThen(() => enterEvent() );
+ selectBox().keyboard.enter();
andThen(() => {
- assert.equal(find(".select-box-row.is-selected").attr("title"), "robin", "it selects the row when pressing enter");
- assert.equal(find(".select-box").hasClass("is-expanded"), false, "it collapses the select box when selecting a row");
+ assert.equal(selectBox().selectedRow.title(), "robin", "it selects the row when pressing enter");
+ assert.notOk(selectBox().isExpanded, "it collapses the select box when selecting a row");
});
- click(".select-box-header");
+ expandSelectBox();
+
+ selectBox().keyboard.escape();
+
andThen(() => {
- assert.equal(find(".select-box").hasClass("is-expanded"), true);
+ assert.notOk(selectBox().isExpanded, "it collapses the select box");
});
- andThen(() => escapeEvent() );
+ expandSelectBox();
+
+ selectBoxFillInFilter("regis");
andThen(() => {
- assert.equal(find(".select-box").hasClass("is-expanded"), false, "it collapses the select box");
+ assert.equal(selectBox().highlightedRow.title(), "regis", "it highlights the first result");
});
- click(".select-box-header");
- andThen(() => {
- assert.equal(find(".select-box").hasClass("is-expanded"), true);
- });
-
- fillIn(".filter-query", "regis");
- triggerEvent('.filter-query', 'keyup');
- andThen(() => {
- assert.equal(find(".select-box-row.is-highlighted").attr("title"), "regis", "it highlights the first result");
- });
-
- andThen(() => tabEvent() );
+ selectBox().keyboard.tab();
andThen(() => {
- assert.equal(find(".select-box-row.is-selected").attr("title"), "regis", "it selects the row when pressing tab");
- assert.equal(find(".select-box").hasClass("is-expanded"), false, "it collapses the select box when selecting a row");
+ assert.equal(selectBox().selectedRow.title(), "regis", "it selects the row when pressing tab");
+ assert.notOk(selectBox().isExpanded, "it collapses the select box when selecting a row");
});
}
});
diff --git a/test/javascripts/helpers/assertions.js b/test/javascripts/helpers/assertions.js
index d254f144c44..4e6b53b5d16 100644
--- a/test/javascripts/helpers/assertions.js
+++ b/test/javascripts/helpers/assertions.js
@@ -18,11 +18,6 @@ Ember.Test.registerAsyncHelper('selectDropdown', function(app, selector, itemId)
$select2.trigger("change");
});
-Ember.Test.registerAsyncHelper('selectBox', function(app, selector, title) {
- click(selector + ' .select-box-header');
- click(selector + ' .select-box-row[title="' + title + '"]');
-});
-
function invisible(selector) {
var $items = find(selector + ":visible");
return $items.length === 0 ||
diff --git a/test/javascripts/helpers/select-box-helper.js b/test/javascripts/helpers/select-box-helper.js
new file mode 100644
index 00000000000..e6fc96fd7dd
--- /dev/null
+++ b/test/javascripts/helpers/select-box-helper.js
@@ -0,0 +1,121 @@
+function checkSelectBoxIsNotExpanded(selectBoxSelector) {
+ if (find(selectBoxSelector).hasClass('is-expanded')) {
+ throw 'You expected select-box to be collapsed but it is expanded.';
+ }
+}
+
+function checkSelectBoxIsNotCollapsed(selectBoxSelector) {
+ if (!find(selectBoxSelector).hasClass('is-expanded')) {
+ throw 'You expected select-box to be expanded but it is collapsed.';
+ }
+}
+
+Ember.Test.registerAsyncHelper('expandSelectBox', function(app, selectBoxSelector) {
+ selectBoxSelector = selectBoxSelector || '.select-box';
+
+ checkSelectBoxIsNotExpanded(selectBoxSelector);
+
+ click(selectBoxSelector + ' .select-box-header');
+});
+
+Ember.Test.registerAsyncHelper('collapseSelectBox', function(app, selectBoxSelector) {
+ selectBoxSelector = selectBoxSelector || '.select-box';
+
+ checkSelectBoxIsNotCollapsed(selectBoxSelector);
+
+ click(selectBoxSelector + ' .select-box-header');
+});
+
+Ember.Test.registerAsyncHelper('selectBoxSelectRow', function(app, rowId, options) {
+ options = options || {};
+ options.selector = options.selector || '.select-box';
+
+ checkSelectBoxIsNotCollapsed(options.selector);
+
+ click(options.selector + " .select-box-row[data-id='" + rowId + "']");
+});
+
+Ember.Test.registerAsyncHelper('selectBoxFillInFilter', function(app, filter, options) {
+ options = options || {};
+ options.selector = options.selector || '.select-box';
+
+ checkSelectBoxIsNotCollapsed(options.selector);
+
+ var filterQuerySelector = options.selector + ' .filter-query';
+ fillIn(filterQuerySelector, filter);
+ triggerEvent(filterQuerySelector, 'keyup');
+});
+
+function selectBox(selector) { // eslint-disable-line no-unused-vars
+ selector = selector || '.select-box';
+
+ function rowHelper(row) {
+ return {
+ text: function() { return row.find('.text').text().trim(); },
+ icon: function() { return row.find('.d-icon'); },
+ title: function() { return row.attr('title'); },
+ el: function() { return row; }
+ };
+ }
+
+ function headerHelper(header) {
+ return {
+ text: function() { return header.find('.current-selection').text().trim(); },
+ icon: function() { return header.find('.icon'); },
+ title: function() { return header.attr('title'); },
+ el: header
+ };
+ }
+
+ function filterHelper(filter) {
+ return {
+ icon: function() { return filter.find('.d-icon'); },
+ exists: function() { return exists(filter); },
+ el: filter
+ };
+ }
+
+ function keyboardHelper() {
+ function createEvent(target, keyCode) {
+ if (typeof target !== 'undefined') {
+ selector = find(selector).find(target);
+ }
+
+ andThen(function() {
+ var event = jQuery.Event('keydown');
+ event.keyCode = keyCode;
+ find(selector).trigger(event);
+ });
+ }
+
+ return {
+ down: function(target) { createEvent(target, 40); },
+ up: function(target) { createEvent(target, 38); },
+ escape: function(target) { createEvent(target, 27); },
+ enter: function(target) { createEvent(target, 13); },
+ tab: function(target) { createEvent(target, 9); }
+ };
+ }
+
+ return {
+ keyboard: keyboardHelper(),
+
+ isExpanded: find(selector).hasClass('is-expanded'),
+
+ isHidden: find(selector).hasClass('is-hidden'),
+
+ header: headerHelper(find(selector).find('.select-box-header')),
+
+ filter: filterHelper(find(selector).find('.select-box-filter')),
+
+ rows: find(selector).find('.select-box-row'),
+
+ row: function(id) {
+ return rowHelper(find(selector).find('.select-box-row[data-id="' + id + '"]'));
+ },
+
+ selectedRow: rowHelper(find(selector).find('.select-box-row.is-selected')),
+
+ highlightedRow: rowHelper(find(selector).find('.select-box-row.is-highlighted'))
+ };
+}
diff --git a/test/javascripts/test_helper.js b/test/javascripts/test_helper.js
index 0f24b2d367a..edc11911698 100644
--- a/test/javascripts/test_helper.js
+++ b/test/javascripts/test_helper.js
@@ -32,6 +32,7 @@
//= require sinon-qunit-1.0.0
//= require helpers/assertions
+//= require helpers/select-box-helper
//= require helpers/qunit-helpers
//= require_tree ./fixtures
@@ -168,4 +169,3 @@ Object.keys(requirejs.entries).forEach(function(entry) {
});
resetSite();
-