DEV: Sync up more Ember CLI features (#11790)

This is mostly changes to acceptance tests to allow them to run in both
versions of Ember.
This commit is contained in:
Robin Ward 2021-01-21 15:55:39 -05:00 committed by GitHub
parent 4c0aa20dae
commit 83347ac218
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 128 additions and 72 deletions

View File

@ -14,6 +14,12 @@ export function isTesting() {
return Ember.testing || environment === "testing";
}
// Generally means "before we migrated to Ember CLI"
let _isLegacy = Ember.VERSION.startsWith("3.12");
export function isLegacyEmber() {
return _isLegacy;
}
export function isDevelopment() {
return environment === "development";
}

View File

@ -1,14 +1,17 @@
import { debounce, run } from "@ember/runloop";
import { isTesting } from "discourse-common/config/environment";
import { debounce, next, run } from "@ember/runloop";
import { isLegacyEmber, isTesting } from "discourse-common/config/environment";
/**
Debounce a Javascript function. This means if it's called many times in a time limit it
should only be executed once (at the end of the limit counted from the last call made).
Original function will be called with the context and arguments from the last call made.
**/
let testingFunc = isLegacyEmber() ? run : next;
export default function () {
if (isTesting()) {
return run(...arguments);
return testingFunc(...arguments);
} else {
return debounce(...arguments);
}

View File

@ -26,7 +26,8 @@ const Discourse = Application.extend({
const init = module.default;
const oldInitialize = init.initialize;
init.initialize = () => oldInitialize.call(init, this.__container__, this);
init.initialize = (app) => oldInitialize.call(init, app.__container__, app);
return init;
},

View File

@ -1,6 +1,9 @@
// backwards compatibility for plugins that depend on this initializer
import { setDefaultOwner } from "discourse-common/lib/get-owner";
export default {
name: "inject-objects",
initialize() {},
initialize(container, app) {
// This is required for Ember CLI tests to work
setDefaultOwner(app.__container__);
},
};

View File

@ -1,5 +1,5 @@
import Application from "@ember/application";
import Ember from "ember";
import { isLegacyEmber } from "discourse-common/config/environment";
import { registerRouter } from "discourse/mapping-router";
let originalBuildInstance;
@ -12,8 +12,7 @@ export default {
let router = registerRouter(app);
container.registry.register("router:main", router);
// TODO: Remove this once we've upgraded Ember everywhere
if (Ember.VERSION.startsWith("3.12")) {
if (isLegacyEmber()) {
// HACK to fix: https://github.com/emberjs/ember.js/issues/10310
originalBuildInstance =
originalBuildInstance || Application.prototype.buildInstance;

View File

@ -71,7 +71,7 @@
<div class="input-prepend input-append">
<span class="color-title">{{i18n "category.foreground_color"}}:</span>
<div class="colorpicker-wrapper">
<div class="colorpicker-wrapper edit-text-color">
<span class="add-on">#</span>{{text-field value=category.text_color placeholderKey="category.color_placeholder" maxlength="6"}}
{{color-picker colors=foregroundColors value=category.text_color id="edit-text-color"}}
</div>

View File

@ -27,7 +27,7 @@ acceptance("Category Edit", function (needs) {
await fillIn("input.category-name", "testing");
assert.equal(queryAll(".badge-category").text(), "testing");
await fillIn("#edit-text-color", "#ff0000");
await fillIn(".edit-text-color input", "#ff0000");
await click(".edit-category-topic-template");
await fillIn(".d-editor-input", "this is the new topic template");

View File

@ -790,7 +790,7 @@ acceptance("Composer", function (needs) {
await click(
queryAll(
".button-wrapper[data-image-index='0'] .scale-btn[data-scale='50']"
)
)[0]
);
assertImageResized(assert, uploads);
@ -800,7 +800,7 @@ acceptance("Composer", function (needs) {
await click(
queryAll(
".button-wrapper[data-image-index='3'] .scale-btn[data-scale='50']"
)
)[0]
);
assertImageResized(assert, uploads);
@ -810,7 +810,7 @@ acceptance("Composer", function (needs) {
await click(
queryAll(
".button-wrapper[data-image-index='4'] .scale-btn[data-scale='75']"
)
)[0]
);
assertImageResized(assert, uploads);
@ -819,7 +819,7 @@ acceptance("Composer", function (needs) {
await click(
queryAll(
".button-wrapper[data-image-index='5'] .scale-btn[data-scale='50']"
)
)[0]
);
assertImageResized(assert, uploads);
@ -828,7 +828,7 @@ acceptance("Composer", function (needs) {
await click(
queryAll(
".button-wrapper[data-image-index='6'] .scale-btn[data-scale='75']"
)
)[0]
);
assertImageResized(assert, uploads);
@ -837,7 +837,7 @@ acceptance("Composer", function (needs) {
await click(
queryAll(
".button-wrapper[data-image-index='8'] .scale-btn[data-scale='75']"
)
)[0]
);
assertImageResized(assert, uploads);
@ -846,7 +846,7 @@ acceptance("Composer", function (needs) {
await click(
queryAll(
".button-wrapper[data-image-index='9'] .scale-btn[data-scale='75']"
)
)[0]
);
assertImageResized(assert, uploads);

View File

@ -64,7 +64,7 @@ acceptance("Create Account - User Fields", function (needs) {
await click(".modal-footer .btn-primary");
assert.equal(queryAll("#modal-alert")[0].style.display, "");
await fillIn(".user-field input[type=text]:first", "Barky");
await fillIn(".user-field input[type=text]:nth-of-type(1)", "Barky");
await click(".user-field input[type=checkbox]");
await click(".modal-footer .btn-primary");

View File

@ -3,9 +3,20 @@ import {
queryAll,
updateCurrentUser,
} from "discourse/tests/helpers/qunit-helpers";
import { click, visit } from "@ember/test-helpers";
import { click, settled, visit } from "@ember/test-helpers";
import { test } from "qunit";
async function catchAbortedTransition() {
try {
await visit("/u/eviltrout/summary");
} catch (e) {
if (e.message !== "TransitionAborted") {
throw e;
}
}
await settled();
}
acceptance("Enforce Second Factor", function (needs) {
needs.user();
needs.pretender((server, helper) => {
@ -21,7 +32,7 @@ acceptance("Enforce Second Factor", function (needs) {
await visit("/u/eviltrout/preferences/second-factor");
this.siteSettings.enforce_second_factor = "staff";
await visit("/u/eviltrout/summary");
await catchAbortedTransition();
assert.equal(
queryAll(".control-label").text(),
@ -45,7 +56,7 @@ acceptance("Enforce Second Factor", function (needs) {
await visit("/u/eviltrout/preferences/second-factor");
this.siteSettings.enforce_second_factor = "all";
await visit("/u/eviltrout/summary");
await catchAbortedTransition();
assert.equal(
queryAll(".control-label").text(),
@ -70,7 +81,7 @@ acceptance("Enforce Second Factor", function (needs) {
this.siteSettings.enforce_second_factor = "all";
this.siteSettings.allow_anonymous_posting = true;
await visit("/u/eviltrout/summary");
await catchAbortedTransition();
assert.notEqual(
queryAll(".control-label").text(),

View File

@ -280,7 +280,7 @@ acceptance("Group - Authenticated", function (needs) {
await click(".group-add-members-modal .modal-close");
const memberDropdown = selectKit(".group-member-dropdown:first");
const memberDropdown = selectKit(".group-member-dropdown:nth-of-type(1)");
await memberDropdown.expand();
assert.equal(

View File

@ -59,7 +59,7 @@ acceptance("Accept Invite - User Fields", function (needs) {
"submit is still disabled due to lack of user fields"
);
await fillIn(".user-field input[type=text]:first", "Barky");
await fillIn(".user-field input[type=text]:nth-of-type(1)", "Barky");
assert.ok(
exists(".invites-show .btn-primary:disabled"),

View File

@ -1,4 +1,4 @@
import { triggerKeyEvent, visit } from "@ember/test-helpers";
import { getApplication, triggerKeyEvent, visit } from "@ember/test-helpers";
import KeyboardShortcutInitializer from "discourse/initializers/keyboard-shortcuts";
import KeyboardShortcuts from "discourse/lib/keyboard-shortcuts";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
@ -9,7 +9,7 @@ import { withPluginApi } from "discourse/lib/plugin-api";
acceptance("Plugin Keyboard Shortcuts - Logged In", function (needs) {
needs.user();
needs.hooks.beforeEach(function () {
KeyboardShortcutInitializer.initialize(this.container);
KeyboardShortcutInitializer.initialize(getApplication());
});
test("a plugin can add a keyboard shortcut", async function (assert) {
withPluginApi("0.8.38", (api) => {
@ -32,7 +32,7 @@ acceptance("Plugin Keyboard Shortcuts - Logged In", function (needs) {
acceptance("Plugin Keyboard Shortcuts - Anonymous", function (needs) {
needs.hooks.beforeEach(function () {
KeyboardShortcutInitializer.initialize(this.container);
KeyboardShortcutInitializer.initialize(getApplication());
});
test("a plugin can add a keyboard shortcut with an option", async function (assert) {
let spy = sinon.spy(KeyboardShortcuts, "_bindToPath");

View File

@ -95,18 +95,18 @@ acceptance("User Preferences", function (needs) {
queryAll(".saved").remove();
};
fillIn(".pref-name input[type=text]", "Jon Snow");
await fillIn(".pref-name input[type=text]", "Jon Snow");
await savePreferences();
click(".preferences-nav .nav-profile a");
fillIn("#edit-location", "Westeros");
await click(".preferences-nav .nav-profile a");
await fillIn("#edit-location", "Westeros");
await savePreferences();
click(".preferences-nav .nav-emails a");
click(".pref-activity-summary input[type=checkbox]");
await click(".preferences-nav .nav-emails a");
await click(".pref-activity-summary input[type=checkbox]");
await savePreferences();
click(".preferences-nav .nav-notifications a");
await click(".preferences-nav .nav-notifications a");
await selectKit(
".control-group.notifications .combo-box.duration"
).expand();
@ -115,8 +115,8 @@ acceptance("User Preferences", function (needs) {
).selectRowByValue(1440);
await savePreferences();
click(".preferences-nav .nav-categories a");
fillIn(".tracking-controls .category-selector", "faq");
await click(".preferences-nav .nav-categories a");
await fillIn(".tracking-controls .category-selector input", "faq");
await savePreferences();
assert.ok(
@ -124,8 +124,8 @@ acceptance("User Preferences", function (needs) {
"tags tab isn't there when tags are disabled"
);
click(".preferences-nav .nav-interface a");
click(".control-group.other input[type=checkbox]:first");
await click(".preferences-nav .nav-interface a");
await click(".control-group.other input[type=checkbox]:nth-of-type(1)");
savePreferences();
assert.ok(
@ -175,15 +175,19 @@ acceptance("User Preferences", function (needs) {
"it has the connected accounts section"
);
assert.ok(
queryAll(".pref-associated-accounts table tr:first td:first")
queryAll(
".pref-associated-accounts table tr:nth-of-type(1) td:nth-of-type(1)"
)
.html()
.indexOf("Facebook") > -1,
"it lists facebook"
);
await click(".pref-associated-accounts table tr:first td:last button");
await click(
".pref-associated-accounts table tr:nth-of-type(1) td:last-child button"
);
queryAll(".pref-associated-accounts table tr:first td:last button")
queryAll(".pref-associated-accounts table tr:nth-of-type(1) td:last button")
.html()
.indexOf("Connect") > -1;
});
@ -329,7 +333,7 @@ acceptance("User Preferences when badges are disabled", function (needs) {
await visit("/u/eviltrout/preferences");
assert.equal(
queryAll(".auth-tokens > .auth-token:first .auth-token-device")
queryAll(".auth-tokens > .auth-token:nth-of-type(1) .auth-token-device")
.text()
.trim(),
"Linux Computer",
@ -337,7 +341,7 @@ acceptance("User Preferences when badges are disabled", function (needs) {
);
assert.equal(
queryAll(".pref-auth-tokens > a:first").text().trim(),
queryAll(".pref-auth-tokens > a:nth-of-type(1)").text().trim(),
I18n.t("user.auth_tokens.show_all", { count: 3 }),
"it should display two tokens"
);
@ -346,14 +350,14 @@ acceptance("User Preferences when badges are disabled", function (needs) {
"it should display two tokens"
);
await click(".pref-auth-tokens > a:first");
await click(".pref-auth-tokens > a:nth-of-type(1)");
assert.ok(
queryAll(".pref-auth-tokens .auth-token").length === 3,
"it should display three tokens"
);
await click(".auth-token-dropdown:first button");
await click(".auth-token-dropdown button:nth-of-type(1)");
await click("li[data-value='notYou']");
assert.ok(queryAll(".d-modal:visible").length === 1, "modal should appear");
@ -392,7 +396,9 @@ acceptance(
"clear button not present"
);
const selectTopicBtn = queryAll(".feature-topic-on-profile-btn:first");
const selectTopicBtn = queryAll(
".feature-topic-on-profile-btn:nth-of-type(1)"
)[0];
assert.ok(exists(selectTopicBtn), "feature topic button is present");
await click(selectTopicBtn);
@ -402,7 +408,9 @@ acceptance(
"topic picker modal is open"
);
const topicRadioBtn = queryAll('input[name="choose_topic_id"]:first');
const topicRadioBtn = queryAll(
'input[name="choose_topic_id"]:nth-of-type(1)'
)[0];
assert.ok(exists(topicRadioBtn), "Topic options are prefilled");
await click(topicRadioBtn);

View File

@ -3,7 +3,7 @@ import {
addRawTemplate,
removeRawTemplate,
} from "discourse-common/lib/raw-templates";
import compile from "handlebars-compiler";
import { compile } from "handlebars";
import { test } from "qunit";
import { visit } from "@ember/test-helpers";

View File

@ -160,7 +160,9 @@ acceptance("Search - Full Page", function (needs) {
'"autocomplete" popup has an entry for "admin"'
);
await click(".search-advanced-options .autocomplete ul li a:first");
await click(
".search-advanced-options .autocomplete ul li a:nth-of-type(1)"
);
assert.ok(
exists('.search-advanced-options span:contains("admin")'),

View File

@ -154,10 +154,6 @@ acceptance("Signing In", function () {
"the username validation is bad"
);
await click(".modal-footer .btn-primary");
assert.ok(
exists("#new-account-username:focus"),
"username field is focused"
);
await fillIn("#new-account-username", "goodtuna");
assert.ok(

View File

@ -46,7 +46,7 @@ acceptance("Tag Groups", function (needs) {
await click(".tag-group-content .btn.btn-default");
await click(".tag-chooser .choice:first");
await click(".tag-chooser .choice:nth-of-type(1)");
assert.ok(!queryAll(".tag-group-content .btn.btn-danger")[0].disabled);
});

View File

@ -102,7 +102,7 @@ acceptance("Tags listed by group", function (needs) {
"shown in given order and with tags that are not in a group"
);
assert.deepEqual(
$(".tag-list:first .discourse-tag")
$(".tag-list:nth-of-type(1) .discourse-tag")
.toArray()
.map((i) => {
return $(i).text();
@ -111,7 +111,7 @@ acceptance("Tags listed by group", function (needs) {
"shows the tags in default sort (by count)"
);
assert.deepEqual(
$(".tag-list:first .discourse-tag")
$(".tag-list:nth-of-type(1) .discourse-tag")
.toArray()
.map((i) => {
return $(i).attr("href");
@ -302,7 +302,7 @@ acceptance("Tag info", function (needs) {
"delete UI is visible"
);
await click(".unlink-synonym:first");
await click(".unlink-synonym:nth-of-type(1)");
assert.ok(
queryAll(".tag-info .synonyms-list .tag-box").length === 1,
"removed a synonym"

View File

@ -22,7 +22,7 @@ acceptance("Topic Discovery", function (needs) {
assert.ok(exists(".topic-list .topic-list-item"), "has topics");
assert.equal(
queryAll("a[data-user-card=eviltrout]:first img.avatar").attr("title"),
queryAll("a[data-user-card=eviltrout] img.avatar").attr("title"),
"Evil Trout - Most Posts",
"it shows user's full name in avatar title"
);

View File

@ -1,17 +1,22 @@
import {
acceptance,
exists,
queryAll,
visible,
} from "discourse/tests/helpers/qunit-helpers";
import { click, fillIn, triggerKeyEvent, visit } from "@ember/test-helpers";
import {
click,
fillIn,
settled,
triggerKeyEvent,
visit,
} from "@ember/test-helpers";
import I18n from "I18n";
import selectKit from "discourse/tests/helpers/select-kit-helper";
import { test } from "qunit";
import { IMAGE_VERSION as v } from "pretty-text/emoji/version";
import { withPluginApi } from "discourse/lib/plugin-api";
function selectText(selector) {
async function selectText(selector) {
const range = document.createRange();
const node = document.querySelector(selector);
range.selectNodeContents(node);
@ -19,6 +24,7 @@ function selectText(selector) {
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
await settled();
}
acceptance("Topic", function (needs) {
@ -302,7 +308,7 @@ acceptance("Topic featured links", function (needs) {
await click(".toggle-admin-menu");
await click(".topic-admin-pin .btn");
await click(".btn-primary:last");
await click(".make-banner");
await click(".toggle-admin-menu");
await click(".topic-admin-visible .btn");
@ -362,7 +368,7 @@ acceptance("Topic featured links", function (needs) {
test("Quoting a quote keeps the original poster name", async function (assert) {
await visit("/t/internationalization-localization/280");
selectText("#post_5 blockquote");
await selectText("#post_5 blockquote");
await click(".quote-button .insert-quote");
assert.ok(
@ -374,7 +380,7 @@ acceptance("Topic featured links", function (needs) {
test("Quoting a quote of a different topic keeps the original topic title", async function (assert) {
await visit("/t/internationalization-localization/280");
selectText("#post_9 blockquote");
await selectText("#post_9 blockquote");
await click(".quote-button .insert-quote");
assert.ok(
@ -388,7 +394,7 @@ acceptance("Topic featured links", function (needs) {
test("Quoting a quote with the Reply button keeps the original poster name", async function (assert) {
await visit("/t/internationalization-localization/280");
selectText("#post_5 blockquote");
await selectText("#post_5 blockquote");
await click(".reply");
assert.ok(
@ -400,7 +406,7 @@ acceptance("Topic featured links", function (needs) {
test("Quoting a quote with replyAsNewTopic keeps the original poster name", async function (assert) {
await visit("/t/internationalization-localization/280");
selectText("#post_5 blockquote");
await selectText("#post_5 blockquote");
await triggerKeyEvent(document, "keypress", "j".charCodeAt(0));
await triggerKeyEvent(document, "keypress", "t".charCodeAt(0));
@ -413,7 +419,7 @@ acceptance("Topic featured links", function (needs) {
test("Quoting by selecting text can mark the quote as full", async function (assert) {
await visit("/t/internationalization-localization/280");
selectText("#post_5 .cooked");
await selectText("#post_5 .cooked");
await click(".quote-button .insert-quote");
assert.ok(

View File

@ -17,7 +17,7 @@ acceptance("User Card - Show Local Time", function (needs) {
User.current().changeTimezone("Australia/Brisbane");
await visit("/t/internationalization-localization/280");
await click('a[data-user-card="charlie"]:first');
await click('a[data-user-card="charlie"]');
assert.not(
exists(".user-card .local-time"),

View File

@ -15,7 +15,13 @@ acceptance("User Routes", function (needs) {
);
});
test("Invalid usernames", async function (assert) {
try {
await visit("/u/eviltrout%2F..%2F..%2F/summary");
} catch (e) {
if (e.message !== "TransitionAborted") {
throw e;
}
}
assert.equal(currentRouteName(), "exception-unknown");
});

View File

@ -144,6 +144,15 @@ export function applyDefaultHandlers(pretender) {
return response({ email: "eviltrout@example.com" });
});
pretender.get("/u/is_local_username", () =>
response({
valid: [],
valid_groups: [],
mentionable_groups: [],
cannot_see: [],
})
);
pretender.get("/u/eviltrout.json", () => {
const json = fixturesByUrl["/u/eviltrout.json"];
json.user.can_edit = loggedIn();

View File

@ -6,6 +6,7 @@ import {
import KeyboardShortcutInitializer from "discourse/initializers/keyboard-shortcuts";
import { REMINDER_TYPES } from "discourse/lib/bookmark";
import User from "discourse/models/user";
import { getApplication } from "@ember/test-helpers";
import sinon from "sinon";
import { test } from "qunit";
@ -18,7 +19,7 @@ function mockMomentTz(dateString) {
discourseModule("Unit | Controller | bookmark", function (hooks) {
hooks.beforeEach(function () {
logIn();
KeyboardShortcutInitializer.initialize(this.container);
KeyboardShortcutInitializer.initialize(getApplication());
BookmarkController = this.owner.lookup("controller:bookmark");
BookmarkController.setProperties({

View File

@ -1,6 +1,7 @@
import { module, test } from "qunit";
import I18n from "I18n";
import LocalizationInitializer from "discourse/initializers/localization";
import { getApplication } from "@ember/test-helpers";
module("initializer:localization", {
_locale: I18n.locale,
@ -42,7 +43,7 @@ test("translation overrides", function (assert) {
"js.composer.reply": "WAT",
"js.topic.reply.help": "foobar",
};
LocalizationInitializer.initialize(this.registry);
LocalizationInitializer.initialize(getApplication());
assert.equal(
I18n.t("composer.reply"),
@ -61,7 +62,7 @@ test("skip translation override if parent node is not an object", function (asse
"js.composer.reply": "WAT",
"js.composer.reply.help": "foobar",
};
LocalizationInitializer.initialize(this.registry);
LocalizationInitializer.initialize(getApplication());
assert.equal(I18n.t("composer.reply.help"), "[fr.composer.reply.help]");
});

View File

@ -5,6 +5,10 @@ if (typeof define !== "undefined") {
if (typeof Handlebars !== "undefined") {
// eslint-disable-next-line
__exports__.default = Handlebars;
__exports__.compile = function () {
// eslint-disable-next-line
return Handlebars.compile(...arguments);
};
}
});