DEV: Use hasAttribute/hasAria/hasStyle in tests (#29568)

This commit is contained in:
Jarek Radosz
2024-11-04 11:30:38 +01:00
committed by GitHub
parent 9694d2477a
commit 380974ce00
31 changed files with 462 additions and 551 deletions

View File

@ -12,7 +12,6 @@ import {
acceptance,
count,
exists,
query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
@ -55,8 +54,10 @@ acceptance("Admin - Site Settings", function (needs) {
test("links to staff action log", async function (assert) {
await visit("/admin/site_settings");
assert.strictEqual(
query(".row.setting .setting-label h3 a").getAttribute("href"),
assert
.dom(".row.setting .setting-label h3 a")
.hasAttribute(
"href",
"/admin/logs/staff_action_logs?filters=%7B%22subject%22%3A%22title%22%2C%22action_name%22%3A%22change_site_setting%22%7D&force_refresh=true",
"it links to the staff action log"
);

View File

@ -68,10 +68,9 @@ acceptance("Composer Actions", function (needs) {
assert
.dom(".action-title .topic-link")
.hasText("Internationalization / localization");
assert.strictEqual(
query(".action-title .topic-link").getAttribute("href"),
"/t/internationalization-localization/280"
);
assert
.dom(".action-title .topic-link")
.hasAttribute("href", "/t/internationalization-localization/280");
assert.strictEqual(
query(".d-editor-input").value,
"test replying to topic when initially replied to post"

View File

@ -935,8 +935,10 @@ acceptance("Composer", function (needs) {
await click("#post_1 .d-icon-pencil");
await fillIn(".d-editor-input", "");
assert.strictEqual(
query(".d-editor-container textarea").getAttribute("placeholder"),
assert
.dom(".d-editor-container textarea")
.hasAttribute(
"placeholder",
I18n.t("composer.reply_placeholder"),
"it should not block because of missing category"
);

View File

@ -125,13 +125,9 @@ acceptance("EmojiPicker", function (needs) {
"it has multiple recent emojis"
);
assert.strictEqual(
/grinning/.test(
query(".section.recent .section-group img.emoji").getAttribute("src")
),
true,
"it puts the last used emoji in first"
);
assert
.dom(".section.recent .section-group img.emoji")
.hasAttribute("src", /grinning/, "puts the last used emoji in first");
});
test("updates the recent list when selecting from it (after you close re-open it or select other emoji)", async function (assert) {

View File

@ -4,7 +4,6 @@ import {
acceptance,
count,
exists,
query,
queryAll,
updateCurrentUser,
} from "discourse/tests/helpers/qunit-helpers";
@ -26,8 +25,10 @@ acceptance("Group Members - Anonymous", function () {
.dom(".group-member-dropdown")
.doesNotExist("it does not allow anon user to manage group members");
assert.strictEqual(
query(".group-username-filter").getAttribute("placeholder"),
assert
.dom(".group-username-filter")
.hasAttribute(
"placeholder",
I18n.t("groups.members.filter_placeholder"),
"it should display the right filter placeholder"
);
@ -63,8 +64,10 @@ acceptance("Group Members", function (needs) {
.dom(".group-member-dropdown")
.exists("it allows admin user to manage group members");
assert.strictEqual(
query(".group-username-filter").getAttribute("placeholder"),
assert
.dom(".group-username-filter")
.hasAttribute(
"placeholder",
I18n.t("groups.members.filter_placeholder_admin"),
"it should display the right filter placeholder"
);

View File

@ -4,11 +4,8 @@ import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Meta Tag Updater", function (needs) {
needs.pretender((server, helper) => {
server.get("/about", () => {
return helper.response({});
server.get("/about", () => helper.response({}));
});
});
needs.site({});
test("updates OG title and URL", async function (assert) {
await visit("/");
@ -17,40 +14,20 @@ acceptance("Meta Tag Updater", function (needs) {
);
await click("a[href='/about']");
assert.strictEqual(
document
.querySelector("meta[property='og:title']")
.getAttribute("content"),
document.title,
"it should update OG title"
);
assert.ok(
document
.querySelector("meta[property='og:url']")
.getAttribute("content")
.endsWith("/about"),
"it should update OG URL"
);
assert.strictEqual(
document
.querySelector("meta[name='twitter:title']")
.getAttribute("content"),
document.title,
"it should update Twitter title"
);
assert.ok(
document
.querySelector("meta[name='twitter:url']")
.getAttribute("content")
.endsWith("/about"),
"it should update Twitter URL"
);
assert.ok(
document
.querySelector("link[rel='canonical']")
.getAttribute("href")
.endsWith("/about"),
"it should update the canonical URL"
);
assert
.dom("meta[property='og:title']", document)
.hasAttribute("content", document.title, "updates OG title");
assert
.dom("meta[property='og:url']", document)
.hasAttribute("content", /\/about$/, "updates OG URL");
assert
.dom("meta[name='twitter:title']", document)
.hasAttribute("content", document.title, "updates Twitter title");
assert
.dom("meta[name='twitter:url']", document)
.hasAttribute("content", /\/about$/, "updates Twitter URL");
assert
.dom("link[rel='canonical']", document)
.hasAttribute("href", /\/about$/, "updates the canonical URL");
});
});

View File

@ -1,10 +1,6 @@
import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import {
acceptance,
exists,
query,
} from "discourse/tests/helpers/qunit-helpers";
import { acceptance, exists } from "discourse/tests/helpers/qunit-helpers";
acceptance("Topic Discovery - Mobile", function (needs) {
needs.mobileView();
@ -13,10 +9,10 @@ acceptance("Topic Discovery - Mobile", function (needs) {
assert.ok(exists(".topic-list"), "The list of topics was rendered");
assert.ok(exists(".topic-list .topic-list-item"), "has topics");
assert.strictEqual(
query("a[data-user-card=codinghorror] img.avatar").getAttribute(
"loading"
),
assert
.dom("a[data-user-card=codinghorror] img.avatar")
.hasAttribute(
"loading",
"lazy",
"it adds loading=`lazy` to topic list avatars"
);

View File

@ -1,113 +1,93 @@
import { click, visit } from "@ember/test-helpers";
import { test } from "qunit";
import {
acceptance,
query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
import I18n from "discourse-i18n";
acceptance("Post controls", function () {
test("accessibility of the likes list below the post", async function (assert) {
await visit("/t/internationalization-localization/280");
const showLikesButton = query("#post_2 button.like-count");
assert.equal(
showLikesButton.getAttribute("aria-pressed"),
"false",
"show likes button isn't pressed"
);
assert.equal(
showLikesButton.getAttribute("aria-label"),
assert
.dom("#post_2 button.like-count")
.hasAria("pressed", "false", "show likes button isn't pressed");
assert
.dom("#post_2 button.like-count")
.hasAria(
"label",
I18n.t("post.sr_post_like_count_button", { count: 4 }),
"show likes button has aria-label"
);
await click(showLikesButton);
assert.equal(
showLikesButton.getAttribute("aria-pressed"),
"true",
"show likes button is now pressed"
);
await click("#post_2 button.like-count");
assert
.dom("#post_2 button.like-count")
.hasAria("pressed", "true", "show likes button is now pressed");
const likesContainer = query("#post_2 .small-user-list.who-liked");
assert.equal(
likesContainer.getAttribute("role"),
"list",
"likes container has list role"
);
assert.equal(
likesContainer.getAttribute("aria-label"),
assert
.dom("#post_2 .small-user-list.who-liked")
.hasAttribute("role", "list", "likes container has list role");
assert
.dom("#post_2 .small-user-list.who-liked")
.hasAria(
"label",
I18n.t("post.actions.people.sr_post_likers_list_description"),
"likes container has aria-label"
);
assert.equal(
likesContainer
.querySelector(".list-description")
.getAttribute("aria-hidden"),
"true",
"list description is aria-hidden"
);
assert
.dom("#post_2 .small-user-list.who-liked .list-description")
.hasAria("hidden", "true", "list description is aria-hidden");
const likesAvatars = likesContainer.querySelectorAll("a.trigger-user-card");
assert.ok(likesAvatars.length > 0, "avatars are rendered");
likesAvatars.forEach((avatar) => {
assert.equal(
avatar.getAttribute("aria-hidden"),
"false",
"avatars are not aria-hidden"
);
assert.equal(
avatar.getAttribute("role"),
"listitem",
"avatars have listitem role"
);
});
assert
.dom("#post_2 .small-user-list.who-liked a.trigger-user-card")
.exists("avatars are rendered");
assert
.dom("#post_2 .small-user-list.who-liked a.trigger-user-card")
.hasAria("hidden", "false", "avatars are not aria-hidden");
assert
.dom("#post_2 .small-user-list.who-liked a.trigger-user-card")
.hasAttribute("role", "listitem", "avatars have listitem role");
});
test("accessibility of the embedded replies below the post", async function (assert) {
await visit("/t/internationalization-localization/280");
const showRepliesButton = query("#post_1 button.show-replies");
assert.equal(
showRepliesButton.getAttribute("aria-pressed"),
"false",
"show replies button isn't pressed"
);
assert.equal(
showRepliesButton.getAttribute("aria-label"),
assert
.dom("#post_1 button.show-replies")
.hasAria("pressed", "false", "show replies button isn't pressed");
assert
.dom("#post_1 button.show-replies")
.hasAria(
"label",
I18n.t("post.sr_expand_replies", { count: 1 }),
"show replies button has aria-label"
);
await click(showRepliesButton);
assert.equal(
showRepliesButton.getAttribute("aria-pressed"),
"true",
"show replies button is now pressed"
);
await click("#post_1 button.show-replies");
assert
.dom("#post_1 button.show-replies")
.hasAria("pressed", "true", "show replies button is now pressed");
const replies = Array.from(queryAll("#post_1 .embedded-posts .reply"));
assert.equal(replies.length, 1, "replies are rendered");
replies.forEach((reply) => {
assert.equal(
reply.getAttribute("role"),
"region",
"replies have region role"
);
assert.equal(
reply.getAttribute("aria-label"),
// const replies = Array.from(queryAll("#post_1 .embedded-posts .reply"));
assert
.dom("#post_1 .embedded-posts .reply")
.exists({ count: 1 }, "replies are rendered");
assert
.dom("#post_1 .embedded-posts .reply")
.hasAttribute("role", "region", "replies have region role");
assert.dom("#post_1 .embedded-posts .reply").hasAria(
"label",
I18n.t("post.sr_embedded_reply_description", {
post_number: 1,
username: "somebody",
}),
"replies have aria-label"
);
});
assert.equal(
query("#post_1 .embedded-posts .btn.collapse-up").getAttribute(
"aria-label"
),
assert
.dom("#post_1 .embedded-posts .btn.collapse-up")
.hasAria(
"label",
I18n.t("post.sr_collapse_replies"),
"collapse button has aria-label"
);

View File

@ -536,18 +536,14 @@ acceptance("Search - Authenticated", function (needs) {
await fillIn("#search-term", "Development");
await triggerKeyEvent(document.activeElement, "keyup", "Enter");
const firstSearchResult =
".search-menu .results li:nth-of-type(1) a.search-link";
const firstTopicResultUrl = "/t/development-mode-super-slow/2179";
assert.strictEqual(
query(firstSearchResult).getAttribute("href"),
firstTopicResultUrl
);
assert
.dom(".search-menu .results li a.search-link")
.hasAttribute("href", "/t/development-mode-super-slow/2179");
await click(firstSearchResult);
await click(".search-menu .results li a.search-link");
assert.strictEqual(
currentURL(),
firstTopicResultUrl,
"/t/development-mode-super-slow/2179",
"redirects to clicked search result url"
);
});
@ -579,26 +575,24 @@ acceptance("Search - Authenticated", function (needs) {
.exists("has topic results");
await triggerKeyEvent("#search-term", "keyup", "ArrowDown");
assert.strictEqual(
document.activeElement.getAttribute("href"),
query(`${container} li:first-child a`).getAttribute("href"),
"arrow down selects first element"
);
assert
.dom(`${container} li:first-child a`)
.isFocused("arrow down selects first element");
await triggerKeyEvent(document.activeElement, "keydown", "ArrowDown");
assert.strictEqual(
document.activeElement.getAttribute("href"),
query(`${container} li:nth-child(2) a`).getAttribute("href"),
"arrow down selects next element"
);
assert
.dom(`${container} li:nth-child(2) a`)
.isFocused("arrow down selects next element");
// navigate to the `more link`
await triggerKeyEvent(document.activeElement, "keydown", "ArrowDown");
await triggerKeyEvent(document.activeElement, "keydown", "ArrowDown");
await triggerKeyEvent(document.activeElement, "keydown", "ArrowDown");
await triggerKeyEvent(document.activeElement, "keydown", "ArrowDown");
assert.strictEqual(
document.activeElement.getAttribute("href"),
assert
.dom(document.activeElement)
.hasAttribute(
"href",
"/search?q=dev",
"arrow down sets focus to more results link"
);
@ -673,17 +667,18 @@ acceptance("Search - Authenticated", function (needs) {
await triggerKeyEvent(document.activeElement, "keyup", "Enter");
await triggerKeyEvent(document.activeElement, "keyup", "ArrowDown");
const firstTopicResultUrl = "/t/development-mode-super-slow/2179";
assert.strictEqual(
document.activeElement.getAttribute("href"),
firstTopicResultUrl,
assert
.dom(document.activeElement)
.hasAttribute(
"href",
"/t/development-mode-super-slow/2179",
"first search result is highlighted"
);
await triggerKeyEvent(document.activeElement, "keydown", "Enter");
assert.strictEqual(
currentURL(),
firstTopicResultUrl,
"/t/development-mode-super-slow/2179",
"redirects to selected search result url"
);
});

View File

@ -212,15 +212,22 @@ acceptance("Tags listed by group", function (needs) {
["focus", "Escort"],
"shows the tags in default sort (by count)"
);
assert.deepEqual(
[...queryAll(".tag-list:nth-of-type(1) .discourse-tag")].map((el) =>
el.getAttribute("href")
),
["/tag/focus", "/tag/escort"],
"always uses lowercase URLs for mixed case tags"
assert
.dom(".tag-list .tag-box:nth-of-type(1) .discourse-tag")
.hasAttribute("href", "/tag/focus");
assert
.dom(".tag-list .tag-box:nth-of-type(2) .discourse-tag")
.hasAttribute(
"href",
"/tag/escort",
"uses a lowercase URL for a mixed case tag"
);
assert.strictEqual(
query(`a[data-tag-name="private"]`).getAttribute("href"),
assert
.dom(`a[data-tag-name="private"]`)
.hasAttribute(
"href",
"/u/eviltrout/messages/tags/private",
"links to private messages"
);

View File

@ -33,14 +33,18 @@ acceptance("Topic Discovery", function (needs) {
assert.ok(exists(".topic-list"), "The list of topics was rendered");
assert.ok(exists(".topic-list .topic-list-item"), "has topics");
assert.strictEqual(
query("a[data-user-card=eviltrout] img.avatar").getAttribute("title"),
assert
.dom("a[data-user-card=eviltrout] img.avatar")
.hasAttribute(
"title",
"eviltrout - Most Posts",
"it shows user's full name in avatar title"
);
assert.strictEqual(
query("a[data-user-card=eviltrout] img.avatar").getAttribute("loading"),
assert
.dom("a[data-user-card=eviltrout] img.avatar")
.hasAttribute(
"loading",
"lazy",
"it adds loading=`lazy` to topic list avatars"
);

View File

@ -2,7 +2,7 @@ import { visit } from "@ember/test-helpers";
import { test } from "qunit";
import { withPluginApi } from "discourse/lib/plugin-api";
import { clearCustomLastUnreadUrlCallbacks } from "discourse/models/topic";
import { acceptance, query } from "discourse/tests/helpers/qunit-helpers";
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
acceptance("Topic list plugin API", function () {
function customLastUnreadUrl(context) {
@ -16,10 +16,10 @@ acceptance("Topic list plugin API", function () {
});
await visit("/");
assert.strictEqual(
query(
".topic-list .topic-list-item:first-child a.raw-topic-link"
).getAttribute("href"),
assert
.dom(".topic-list .topic-list-item:first-child a.raw-topic-link")
.hasAttribute(
"href",
"/t/error-after-upgrade-to-0-9-7-9/11557/1?overridden"
);
} finally {

View File

@ -282,7 +282,9 @@ acceptance("Topic featured links", function (needs) {
const link = query(".title-wrapper .topic-featured-link");
assert.strictEqual(link.innerText, "example.com");
assert.strictEqual(link.getAttribute("rel"), "ugc");
assert
.dom(".title-wrapper .topic-featured-link")
.hasAttribute("rel", "ugc");
});
test("remove featured link", async function (assert) {

View File

@ -62,36 +62,35 @@ acceptance("User menu", function (needs) {
test("notifications panel has a11y attributes", async function (assert) {
await visit("/");
await click(".d-header-icons .current-user button");
const panel = query("#quick-access-all-notifications");
assert.strictEqual(panel.getAttribute("tabindex"), "-1");
assert.strictEqual(
panel.querySelector("ul").getAttribute("aria-labelledby"),
"user-menu-button-all-notifications"
);
assert
.dom("#quick-access-all-notifications")
.hasAttribute("tabindex", "-1");
assert
.dom("#quick-access-all-notifications ul")
.hasAria("labelledby", "user-menu-button-all-notifications");
});
test("replies notifications panel has a11y attributes", async function (assert) {
await visit("/");
await click(".d-header-icons .current-user button");
await click("#user-menu-button-replies");
const panel = query("#quick-access-replies");
assert.strictEqual(panel.getAttribute("tabindex"), "-1");
assert.strictEqual(
panel.querySelector("ul").getAttribute("aria-labelledby"),
"user-menu-button-replies"
);
assert.dom("#quick-access-replies").hasAttribute("tabindex", "-1");
assert
.dom("#quick-access-replies ul")
.hasAria("labelledby", "user-menu-button-replies");
});
test("profile panel has a11y attributes", async function (assert) {
await visit("/");
await click(".d-header-icons .current-user button");
await click("#user-menu-button-profile");
const panel = query("#quick-access-profile");
assert.strictEqual(panel.getAttribute("tabindex"), "-1");
assert.strictEqual(
panel.querySelector("ul").getAttribute("aria-labelledby"),
"user-menu-button-profile"
);
assert.dom("#quick-access-profile").hasAttribute("tabindex", "-1");
assert
.dom("#quick-access-profile ul")
.hasAria("labelledby", "user-menu-button-profile");
});
test("clicking on an unread notification", async function (assert) {

View File

@ -3,7 +3,7 @@ import { click, render, triggerKeyEvent } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import { exists } from "discourse/tests/helpers/qunit-helpers";
import { withSilencedDeprecationsAsync } from "discourse-common/lib/deprecated";
import I18n from "discourse-i18n";
@ -15,11 +15,7 @@ module("Integration | Component | d-button", function (hooks) {
assert.ok(exists("button.btn.btn-icon.no-text"), "it has all the classes");
assert.ok(exists("button .d-icon.d-icon-plus"), "it has the icon");
assert.strictEqual(
query("button").getAttribute("tabindex"),
"3",
"it has the tabindex"
);
assert.dom("button").hasAttribute("tabindex", "3", "it has the tabindex");
});
test("icon and text button", async function (assert) {
@ -117,17 +113,14 @@ module("Integration | Component | d-button", function (hooks) {
this.set("ariaLabel", "test.fooAriaLabel");
assert.strictEqual(
query("button").getAttribute("aria-label"),
I18n.t("test.fooAriaLabel")
);
assert.dom("button").hasAria("label", I18n.t("test.fooAriaLabel"));
this.setProperties({
ariaLabel: null,
translatedAriaLabel: "bar",
});
assert.dom("button").hasAttribute("aria-label", "bar");
assert.dom("button").hasAria("label", "bar");
});
test("title", async function (assert) {
@ -138,10 +131,7 @@ module("Integration | Component | d-button", function (hooks) {
);
this.set("title", "test.fooTitle");
assert.strictEqual(
query("button").getAttribute("title"),
I18n.t("test.fooTitle")
);
assert.dom("button").hasAttribute("title", I18n.t("test.fooTitle"));
this.setProperties({
title: null,
@ -192,10 +182,7 @@ module("Integration | Component | d-button", function (hooks) {
await render(hbs`<DButton @ariaControls={{this.ariaControls}} />`);
this.set("ariaControls", "foo-bar");
assert.strictEqual(
query("button").getAttribute("aria-controls"),
"foo-bar"
);
assert.dom("button").hasAria("controls", "foo-bar");
});
test("onKeyDown callback", async function (assert) {

View File

@ -621,29 +621,17 @@ third line`
assert.strictEqual(textarea.selectionEnd, 18);
});
test("clicking the toggle-direction changes dir from ltr to rtl", async function (assert) {
test("clicking the toggle-direction changes dir from ltr to rtl and back", async function (assert) {
this.siteSettings.support_mixed_text_direction = true;
this.siteSettings.default_locale = "en";
await render(hbs`<DEditor @value={{this.value}} />`);
await click("button.toggle-direction");
assert.strictEqual(
query("textarea.d-editor-input").getAttribute("dir"),
"rtl"
);
});
assert.dom("textarea.d-editor-input").hasAttribute("dir", "rtl");
test("clicking the toggle-direction changes dir from ltr to rtl", async function (assert) {
this.siteSettings.support_mixed_text_direction = true;
this.siteSettings.default_locale = "en";
await render(hbs`<DEditor @value={{this.value}} />`);
const textarea = query("textarea.d-editor-input");
textarea.setAttribute("dir", "ltr");
await click("button.toggle-direction");
assert.strictEqual(textarea.getAttribute("dir"), "rtl");
assert.dom("textarea.d-editor-input").hasAttribute("dir", "ltr");
});
test("toolbar event supports replaceText", async function (assert) {
@ -757,12 +745,10 @@ third line`
await render(hbs`<DEditor />`);
const buttons = queryAll(".d-editor-button-bar .btn");
assert.strictEqual(
buttons[0].getAttribute("tabindex"),
"0",
"it makes the first button focusable"
);
assert.strictEqual(buttons[1].getAttribute("tabindex"), "-1");
assert
.dom(buttons[0])
.hasAttribute("tabindex", "0", "it makes the first button focusable");
assert.dom(buttons[1]).hasAttribute("tabindex", "-1");
});
testCase("replace-text event by default", async function (assert) {

View File

@ -5,7 +5,6 @@ import { setupLightboxes } from "discourse/lib/lightbox";
import { SELECTORS } from "discourse/lib/lightbox/constants";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { generateLightboxMarkup } from "discourse/tests/helpers/lightbox-helpers";
import { query } from "discourse/tests/helpers/qunit-helpers";
import domFromString from "discourse-common/lib/dom-from-string";
module("Integration | Component | d-lightbox", function (hooks) {
@ -56,10 +55,11 @@ module("Integration | Component | d-lightbox", function (hooks) {
// the content has an aria-labelledby attribute
assert.dom(SELECTORS.LIGHTBOX_CONTENT).hasAttribute("aria-labelledby");
assert.true(
query(SELECTORS.LIGHTBOX_CONTENT)
.getAttribute("style")
.match(/--d-lightbox/g).length > 0,
assert
.dom(SELECTORS.LIGHTBOX_CONTENT)
.hasAttribute(
"style",
/--d-lightbox/,
"the content has the correct css variables added"
);

View File

@ -2,7 +2,7 @@ import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import { exists } from "discourse/tests/helpers/qunit-helpers";
import I18n from "discourse-i18n";
module("Integration | Component | d-toggle-switch", function (hooks) {
@ -14,10 +14,7 @@ module("Integration | Component | d-toggle-switch", function (hooks) {
await render(hbs`<DToggleSwitch @state={{this.state}}/>`);
assert.ok(exists(".d-toggle-switch"), "it renders a toggle switch");
assert.strictEqual(
query(".d-toggle-switch__checkbox").getAttribute("aria-checked"),
"false"
);
assert.dom(".d-toggle-switch__checkbox").hasAria("checked", "false");
});
test("it renders a toggle button in a enabled state", async function (assert) {
@ -26,10 +23,7 @@ module("Integration | Component | d-toggle-switch", function (hooks) {
await render(hbs`<DToggleSwitch @state={{this.state}}/>`);
assert.ok(exists(".d-toggle-switch"), "it renders a toggle switch");
assert.strictEqual(
query(".d-toggle-switch__checkbox").getAttribute("aria-checked"),
"true"
);
assert.dom(".d-toggle-switch__checkbox").hasAria("checked", "true");
});
test("it renders a checkmark icon when enabled", async function (assert) {

View File

@ -2,7 +2,6 @@ import { click, render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { query } from "discourse/tests/helpers/qunit-helpers";
module("Integration | Component | emoji-picker", function (hooks) {
setupRenderingTest(hooks);
@ -18,10 +17,9 @@ module("Integration | Component | emoji-picker", function (hooks) {
`);
await click(".emoji-picker-anchor");
assert.strictEqual(
query(".emoji-picker.opened").getAttribute("data-popper-placement"),
"bottom"
);
assert
.dom(".emoji-picker.opened")
.hasAttribute("data-popper-placement", "bottom");
});
test("when placement == right, places the picker on the right", async function (assert) {
@ -35,9 +33,8 @@ module("Integration | Component | emoji-picker", function (hooks) {
`);
await click(".emoji-picker-anchor");
assert.strictEqual(
query(".emoji-picker.opened").getAttribute("data-popper-placement"),
"right"
);
assert
.dom(".emoji-picker.opened")
.hasAttribute("data-popper-placement", "right");
});
});

View File

@ -1,7 +1,6 @@
import { getOwner } from "@ember/owner";
import {
click,
find,
render,
triggerEvent,
triggerKeyEvent,
@ -220,17 +219,15 @@ module("Integration | Component | FloatKit | d-menu", function (hooks) {
);
await open();
assert.ok(
find(".fk-d-menu").getAttribute("style").includes("max-width: 20px;")
);
assert.dom(".fk-d-menu").hasStyle({ maxWidth: "20px" });
});
test("applies position", async function (assert) {
await render(hbs`<DMenu @inline={{true}} @label="label" />`);
await open();
assert.dom(".fk-d-menu").hasAttribute("style", /left: /);
assert.ok(find(".fk-d-menu").getAttribute("style").includes("top: "));
assert.dom(".fk-d-menu").hasAttribute("style", /top: [\d.]+?px/);
assert.dom(".fk-d-menu").hasAttribute("style", /left: [\d.]+?px/);
});
test("content close argument", async function (assert) {

View File

@ -78,8 +78,10 @@ module(
.dom(".selected-name", this.subject.header().el())
.doesNotExist("hides the text of the selected item");
assert.strictEqual(
this.subject.header().el().getAttribute("title"),
assert
.dom(this.subject.header().el())
.hasAttribute(
"title",
"[en.test_none]",
"it adds a title attribute to the button"
);

View File

@ -425,16 +425,15 @@ module("Integration | Component | select-kit/single-select", function (hooks) {
hbs`<SingleSelect @value={{this.value}} @content={{this.content}} />`
);
assert.strictEqual(
this.subject.header().el().getAttribute("name"),
I18n.t("select_kit.select_to_filter")
);
assert
.dom(this.subject.header().el())
.hasAttribute("name", I18n.t("select_kit.select_to_filter"));
await this.subject.expand();
await this.subject.selectRowByValue(1);
assert.strictEqual(
this.subject.header().el().getAttribute("name"),
assert.dom(this.subject.header().el()).hasAttribute(
"name",
I18n.t("select_kit.filter_by", {
name: this.content.firstObject.name,
})

View File

@ -3,7 +3,7 @@ import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit";
import { resetFlair } from "discourse/lib/avatar-flair";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import { exists } from "discourse/tests/helpers/qunit-helpers";
function setupSiteGroups(that) {
that.site.groups = [
@ -62,11 +62,10 @@ module("Integration | Component | user-avatar-flair", function (hooks) {
assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-bars"), "it has the svg icon");
assert.strictEqual(
query(".avatar-flair").getAttribute("style"),
"background-color: #CC000A; color: #FFFFFA; ",
"it has styles"
);
assert.dom(".avatar-flair").hasStyle({
backgroundColor: "rgb(204, 0, 10)",
color: "rgb(255, 255, 250)",
});
});
test("avatar flair for moderator user with fallback to staff", async function (assert) {
@ -82,11 +81,10 @@ module("Integration | Component | user-avatar-flair", function (hooks) {
assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-bars"), "it has the svg icon");
assert.strictEqual(
query(".avatar-flair").getAttribute("style"),
"background-color: #CC0005; color: #FFFFF5; ",
"it has styles"
);
assert.dom(".avatar-flair").hasStyle({
backgroundColor: "rgb(204, 0, 5)",
color: "rgb(255, 255, 245)",
});
});
test("avatar flair for trust level", async function (assert) {
@ -102,11 +100,10 @@ module("Integration | Component | user-avatar-flair", function (hooks) {
assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-dice-two"), "it has the svg icon");
assert.strictEqual(
query(".avatar-flair").getAttribute("style"),
"background-color: #CC0002; color: #FFFFF2; ",
"it has styles"
);
assert.dom(".avatar-flair").hasStyle({
backgroundColor: "rgb(204, 0, 2)",
color: "rgb(255, 255, 242)",
});
});
test("avatar flair for trust level when set to none", async function (assert) {
@ -136,11 +133,10 @@ module("Integration | Component | user-avatar-flair", function (hooks) {
assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-dice-two"), "it has the svg icon");
assert.strictEqual(
query(".avatar-flair").getAttribute("style"),
"background-color: #CC0002; color: #FFFFF2; ",
"it has styles"
);
assert.dom(".avatar-flair").hasStyle({
backgroundColor: "rgb(204, 0, 2)",
color: "rgb(255, 255, 242)",
});
});
test("avatar flair for login-required site, before login", async function (assert) {
@ -176,11 +172,10 @@ module("Integration | Component | user-avatar-flair", function (hooks) {
assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-xmark"), "it has the svg icon");
assert.strictEqual(
query(".avatar-flair").getAttribute("style"),
"background-color: #123456; color: #B0B0B0; ",
"it has styles"
);
assert.dom(".avatar-flair").hasStyle({
backgroundColor: "rgb(18, 52, 86)",
color: "rgb(176, 176, 176)",
});
});
test("user-avatar-flair for user with no flairs", async function (assert) {

View File

@ -23,16 +23,18 @@ module("Integration | Component | user-menu", function (hooks) {
test("active tab has a11y attributes that indicate it's active", async function (assert) {
await render(template);
const activeTab = query(".top-tabs.tabs-list .btn.active");
assert.strictEqual(activeTab.getAttribute("tabindex"), "0");
assert.strictEqual(activeTab.getAttribute("aria-selected"), "true");
assert.dom(".top-tabs.tabs-list .btn.active").hasAttribute("tabindex", "0");
assert.dom(".top-tabs.tabs-list .btn.active").hasAria("selected", "true");
});
test("inactive tab has a11y attributes that indicate it's inactive", async function (assert) {
await render(template);
const inactiveTab = query(".top-tabs.tabs-list .btn:not(.active)");
assert.strictEqual(inactiveTab.getAttribute("tabindex"), "-1");
assert.strictEqual(inactiveTab.getAttribute("aria-selected"), "false");
assert
.dom(".top-tabs.tabs-list .btn:not(.active)")
.hasAttribute("tabindex", "-1");
assert
.dom(".top-tabs.tabs-list .btn:not(.active)")
.hasAria("selected", "false");
});
test("the menu has a group of tabs at the top", async function (assert) {
@ -44,10 +46,7 @@ module("Integration | Component | user-menu", function (hooks) {
(tab, index) => {
assert.strictEqual(tabs[index].id, `user-menu-button-${tab}`);
assert.strictEqual(tabs[index].dataset.tabNumber, index.toString());
assert.strictEqual(
tabs[index].getAttribute("aria-controls"),
`quick-access-${tab}`
);
assert.dom(tabs[index]).hasAria("controls", `quick-access-${tab}`);
}
);
});
@ -60,7 +59,7 @@ module("Integration | Component | user-menu", function (hooks) {
const profileTab = tabs[0];
assert.strictEqual(profileTab.id, "user-menu-button-profile");
assert.strictEqual(profileTab.dataset.tabNumber, "6");
assert.strictEqual(profileTab.getAttribute("tabindex"), "-1");
assert.dom(profileTab).hasAttribute("tabindex", "-1");
});
test("likes tab is hidden if current user's like notifications frequency is 'never'", async function (assert) {

View File

@ -88,8 +88,10 @@ module(
I18n.t("user.dismiss"),
"dismiss button has a label"
);
assert.strictEqual(
dismissButton.getAttribute("title"),
assert
.dom(".panel-body-bottom .btn.notifications-dismiss")
.hasAttribute(
"title",
I18n.t("user.dismiss_notifications_tooltip"),
"dismiss button has title attribute"
);

View File

@ -2,7 +2,7 @@ import { render } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import { exists, query } from "discourse/tests/helpers/qunit-helpers";
import { exists } from "discourse/tests/helpers/qunit-helpers";
module("Integration | Component | Widget | avatar-flair", function (hooks) {
setupRenderingTest(hooks);
@ -20,11 +20,10 @@ module("Integration | Component | Widget | avatar-flair", function (hooks) {
assert.ok(exists(".avatar-flair"), "it has the tag");
assert.ok(exists("svg.d-icon-bars"), "it has the svg icon");
assert.strictEqual(
query(".avatar-flair").getAttribute("style"),
"background-color: #CC0000; color: #FFFFFF; ",
"it has styles"
);
assert.dom(".avatar-flair").hasStyle({
backgroundColor: "rgb(204, 0, 0)",
color: "rgb(255, 255, 255)",
});
});
test("avatar flair with an image", async function (assert) {

View File

@ -4,12 +4,7 @@ import { click, render, triggerEvent } from "@ember/test-helpers";
import { hbs } from "ember-cli-htmlbars";
import { module, test } from "qunit";
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
import {
count,
exists,
query,
queryAll,
} from "discourse/tests/helpers/qunit-helpers";
import { count, exists, query } from "discourse/tests/helpers/qunit-helpers";
import I18n from "discourse-i18n";
module("Integration | Component | Widget | post", function (hooks) {
@ -44,14 +39,8 @@ module("Integration | Component | Widget | post", function (hooks) {
hbs`<MountWidget @widget="post-contents" @args={{this.args}} />`
);
assert.strictEqual(
queryAll("a[data-clicks='1']")[0].getAttribute("data-clicks"),
"1"
);
assert.strictEqual(
queryAll("a[data-clicks='2']")[0].getAttribute("data-clicks"),
"2"
);
assert.dom("a[data-clicks='1']").hasAttribute("data-clicks", "1");
assert.dom("a[data-clicks='2']").hasAttribute("data-clicks", "2");
});
test("post - onebox links", async function (assert) {
@ -78,13 +67,17 @@ module("Integration | Component | Widget | post", function (hooks) {
hbs`<MountWidget @widget="post-contents" @args={{this.args}} />`
);
assert.strictEqual(
queryAll("a[data-clicks='1']")[0].getAttribute("data-clicks"),
assert
.dom("a[data-clicks='1']")
.hasAttribute(
"data-clicks",
"1",
"First link has correct data attribute and content"
);
assert.strictEqual(
queryAll("a[data-clicks='2']")[0].getAttribute("data-clicks"),
assert
.dom("a[data-clicks='2']")
.hasAttribute(
"data-clicks",
"2",
"Second link has correct data attribute and content"
);
@ -279,10 +272,12 @@ module("Integration | Component | Widget | post", function (hooks) {
assert.dom(".actions button.like").exists();
assert.dom(".actions button.like-count").doesNotExist();
assert.strictEqual(
query("button.like").getAttribute("title"),
assert
.dom("button.like")
.hasAttribute(
"title",
I18n.t("post.controls.like"),
`shows the right button title for anonymous users`
"shows the right button title for anonymous users"
);
await click(".actions button.like");
@ -354,10 +349,12 @@ module("Integration | Component | Widget | post", function (hooks) {
assert.strictEqual(count("button.create-flag"), 1, `button is displayed`);
assert.strictEqual(count("button.delete"), 1, `button is displayed`);
assert.strictEqual(
query("button.delete").getAttribute("title"),
assert
.dom("button.delete")
.hasAttribute(
"title",
I18n.t("post.controls.delete_topic_disallowed"),
`shows the right button title for users without permissions`
"shows the right button title for users without permissions"
);
});
@ -1002,10 +999,9 @@ module("Integration | Component | Widget | post", function (hooks) {
const link = query(".group-request a");
assert.strictEqual(link.innerText.trim(), I18n.t("groups.requests.handle"));
assert.strictEqual(
link.getAttribute("href"),
"/g/testGroup/requests?filter=foo"
);
assert
.dom(".group-request a")
.hasAttribute("href", "/g/testGroup/requests?filter=foo");
});
test("shows user status if enabled in site settings", async function (assert) {

View File

@ -27,10 +27,6 @@ function quoteHtml() {
`;
}
function assertDirection(assert, elem, expected, message) {
assert.strictEqual(elem.getAttribute("dir"), expected, message);
}
module("Unit | Utility | text-direction", function (hooks) {
setupTest(hooks);
@ -62,15 +58,17 @@ module("Unit | Utility | text-direction", function (hooks) {
const [englishTitle, arabicTitle] = Array.from(
cooked.querySelectorAll(".title")
);
assertDirection(
assert,
englishTitle,
assert
.dom(englishTitle)
.hasAttribute(
"dir",
"ltr",
"quote title always matches site direction regardless of its content"
);
assertDirection(
assert,
arabicTitle,
assert
.dom(arabicTitle)
.hasAttribute(
"dir",
"ltr",
"quote title always matches site direction regardless of its content"
);
@ -84,39 +82,37 @@ module("Unit | Utility | text-direction", function (hooks) {
notQuotedRtl,
] = Array.from(cooked.querySelectorAll("p"));
assertDirection(
assert,
quotedRtl,
"auto",
"RTL paragraphs inside quote have auto dir"
);
assertDirection(
assert,
quotedLtr,
"auto",
"LTR paragraphs inside quote have auto dir"
);
assertDirection(
assert,
quotedLtrNested,
assert
.dom(quotedRtl)
.hasAttribute("dir", "auto", "RTL paragraphs inside quote have auto dir");
assert
.dom(quotedLtr)
.hasAttribute("dir", "auto", "LTR paragraphs inside quote have auto dir");
assert
.dom(quotedLtrNested)
.hasAttribute(
"dir",
"auto",
"LTR paragraphs inside nested quote have auto dir"
);
assertDirection(
assert,
quotedRtlNested,
assert
.dom(quotedRtlNested)
.hasAttribute(
"dir",
"auto",
"RTL paragraphs inside nested quote have auto dir"
);
assertDirection(
assert,
notQuotedLtr,
assert
.dom(notQuotedLtr)
.hasAttribute(
"dir",
"auto",
"LTR paragraphs outside quotes have auto dir"
);
assertDirection(
assert,
notQuotedRtl,
assert
.dom(notQuotedRtl)
.hasAttribute(
"dir",
"auto",
"RTL paragraphs outside quotes have auto dir"
);

View File

@ -155,17 +155,15 @@ module("Unit | Utility | pretty-text/upload-short-url", function (hooks) {
let video = fixture().querySelector("video");
let link = fixture().querySelector("a");
assert.strictEqual(image1.getAttribute("src"), "/images/avatar.png?a");
assert.strictEqual(image2.getAttribute("src"), "/images/avatar.png?b");
assert.strictEqual(link.getAttribute("href"), "/uploads/short-url/c.pdf");
assert.strictEqual(
video.querySelector("source").getAttribute("src"),
"/uploads/default/original/3X/c/b/4.mp4"
);
assert.strictEqual(
audio.querySelector("source").getAttribute("src"),
"/uploads/default/original/3X/c/b/5.mp3"
);
assert.dom(image1).hasAttribute("src", "/images/avatar.png?a");
assert.dom(image2).hasAttribute("src", "/images/avatar.png?b");
assert.dom(link).hasAttribute("href", "/uploads/short-url/c.pdf");
assert
.dom("source", video)
.hasAttribute("src", "/uploads/default/original/3X/c/b/4.mp4");
assert
.dom("source", audio)
.hasAttribute("src", "/uploads/default/original/3X/c/b/5.mp3");
});
test("resolveAllShortUrls - url with full origin replaced correctly", async function (assert) {
@ -174,8 +172,10 @@ module("Unit | Utility | pretty-text/upload-short-url", function (hooks) {
await settled();
let video = fixture().querySelectorAll("video")[1];
assert.strictEqual(
video.querySelector("source").getAttribute("src"),
assert
.dom("source", video)
.hasAttribute(
"src",
"http://localhost:3000/uploads/default/original/3X/c/b/6.mp4"
);
});
@ -196,10 +196,9 @@ module("Unit | Utility | pretty-text/upload-short-url", function (hooks) {
await settled();
let link = fixture().querySelector("a");
assert.strictEqual(
link.getAttribute("href"),
"/secure-uploads/default/original/3X/c/b/3.pdf"
);
assert
.dom(link)
.hasAttribute("href", "/secure-uploads/default/original/3X/c/b/3.pdf");
});
test("resolveAllShortUrls - scoped", async function (assert) {

View File

@ -99,10 +99,11 @@ module("Discourse Chat | Component | chat-upload", function (hooks) {
await render(hbs`<ChatUpload @upload={{this.upload}} />`);
assert.true(exists("video.chat-video-upload"), "displays as an video");
const video = query("video.chat-video-upload");
assert.true(video.hasAttribute("controls"), "has video controls");
assert.strictEqual(
video.getAttribute("preload"),
assert.dom("video.chat-video-upload").hasAttribute("controls");
assert
.dom("video.chat-video-upload")
.hasAttribute(
"preload",
"metadata",
"video has correct preload settings"
);
@ -114,10 +115,11 @@ module("Discourse Chat | Component | chat-upload", function (hooks) {
await render(hbs`<ChatUpload @upload={{this.upload}} />`);
assert.true(exists("audio.chat-audio-upload"), "displays as an audio");
const audio = query("audio.chat-audio-upload");
assert.true(audio.hasAttribute("controls"), "has audio controls");
assert.strictEqual(
audio.getAttribute("preload"),
assert.dom("audio.chat-audio-upload").hasAttribute("controls");
assert
.dom("audio.chat-audio-upload")
.hasAttribute(
"preload",
"metadata",
"audio has correct preload settings"
);

View File

@ -15,12 +15,6 @@ acceptance("Local Dates - composer", function (needs) {
});
test("composer bbcode", async function (assert) {
const getAttr = (attr) => {
return query(
".d-editor-preview .discourse-local-date.cooked-date"
).getAttribute(`data-${attr}`);
};
await visit("/");
await click("#create-topic");
const categoryChooser = selectKit(".category-chooser");
@ -32,32 +26,38 @@ acceptance("Local Dates - composer", function (needs) {
'[date=2017-10-23 time=01:30:00 displayedTimezone="America/Chicago" format="LLLL" calendar="off" recurring="1.weeks" timezone=" Asia/Calcutta" timezones="Europe/Paris|America/Los_Angeles"]'
);
assert.strictEqual(
getAttr("date"),
"2017-10-23",
"it has the correct date"
);
assert.strictEqual(getAttr("time"), "01:30:00", "it has the correct time");
assert.strictEqual(
getAttr("displayed-timezone"),
assert
.dom(".d-editor-preview .discourse-local-date.cooked-date")
.hasAttribute("data-date", "2017-10-23", "has the correct date");
assert
.dom(".d-editor-preview .discourse-local-date.cooked-date")
.hasAttribute("data-time", "01:30:00", "has the correct time");
assert
.dom(".d-editor-preview .discourse-local-date.cooked-date")
.hasAttribute(
"data-displayed-timezone",
"America/Chicago",
"it has the correct displayed timezone"
"has the correct displayed timezone"
);
assert.strictEqual(getAttr("format"), "LLLL", "it has the correct format");
assert.strictEqual(
getAttr("timezones"),
assert
.dom(".d-editor-preview .discourse-local-date.cooked-date")
.hasAttribute("data-format", "LLLL", "has the correct format");
assert
.dom(".d-editor-preview .discourse-local-date.cooked-date")
.hasAttribute(
"data-timezones",
"Europe/Paris|America/Los_Angeles",
"it has the correct timezones"
"has the correct timezones"
);
assert.strictEqual(
getAttr("recurring"),
"1.weeks",
"it has the correct recurring"
);
assert.strictEqual(
getAttr("timezone"),
assert
.dom(".d-editor-preview .discourse-local-date.cooked-date")
.hasAttribute("data-recurring", "1.weeks", "has the correct recurring");
assert
.dom(".d-editor-preview .discourse-local-date.cooked-date")
.hasAttribute(
"data-timezone",
"Asia/Calcutta",
"it has the correct timezone"
"has the correct timezone"
);
await fillIn(
@ -65,12 +65,12 @@ acceptance("Local Dates - composer", function (needs) {
'[date=2017-10-24 format="LL" timezone="Asia/Calcutta" timezones="Europe/Paris|America/Los_Angeles"]'
);
assert.strictEqual(
getAttr("date"),
"2017-10-24",
"it has the correct date"
);
assert.notOk(getAttr("time"), "it doesn’t have time");
assert
.dom(".d-editor-preview .discourse-local-date.cooked-date")
.hasAttribute("data-date", "2017-10-24", "has the correct date");
assert
.dom(".d-editor-preview .discourse-local-date.cooked-date")
.doesNotHaveAttribute("data-time", "doesn’t have time");
});
test("date modal", async function (assert) {