adds a dsl to simplify testing of the select-box

This commit is contained in:
Joffrey JAFFEUX 2017-09-14 19:50:32 +02:00 committed by GitHub
parent 16fe7aa307
commit 562e48dfb7
12 changed files with 244 additions and 173 deletions

View File

@ -43,6 +43,10 @@
"asyncRender":true,
"selectDropdown":true,
"selectBox":true,
"expandSelectBox":true,
"collapseSelectBox":true,
"selectBoxSelectRow":true,
"selectBoxFillInFilter":true,
"asyncTestDiscourse":true,
"fixture":true,
"find":true,

View File

@ -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}`);
};
},

View File

@ -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")) {

View File

@ -39,6 +39,7 @@
shouldHighlightRow=shouldHighlightRow
shouldSelectRow=shouldSelectRow
titleForRow=titleForRow
idForRow=idForRow
onSelectRow=(action "onSelectRow")
onHoverRow=(action "onHoverRow")
onClearSelection=(action "onClearSelection")

View File

@ -9,6 +9,7 @@
{{component selectBoxRowComponent
content=content
templateForRow=templateForRow
idForRow=idForRow
titleForRow=titleForRow
shouldHighlightRow=shouldHighlightRow
shouldSelectRow=shouldSelectRow

View File

@ -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(() => {

View File

@ -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"
);
});

View File

@ -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");
});
}
});

View File

@ -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 doesnt have an icon if not specified");
assert.equal(selectBox().header.icon().length, 0, "it doesnt 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('doesnt 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(), "<b>robin</b>");
});
andThen(() => assert.equal(selectBox().row(1).el().html(), "<b>robin</b>") );
}
});
@ -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 doesnt change header text");
assert.equal(selectBox().header.text(), "Choose...", "it doesnt 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");
});
}
});

View File

@ -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 ||

View File

@ -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'))
};
}

View File

@ -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();