From 9b30fbdbbdf6c0af4811c606f5b1634e17fe833a Mon Sep 17 00:00:00 2001 From: Rafael dos Santos Silva Date: Fri, 3 Sep 2021 15:17:11 -0300 Subject: [PATCH] DEV: Run tests in Firefox ESR (#14094) --- .github/workflows/ember.yml | 2 +- app/assets/javascripts/discourse/testem.js | 4 +- .../tests/acceptance/mobile-pan-test.js | 42 ++--- .../acceptance/topic-quote-button-test.js | 154 ++++++++++-------- .../discourse/tests/acceptance/topic-test.js | 27 +-- .../discourse/tests/helpers/qunit-helpers.js | 18 +- .../integration/components/d-editor-test.js | 1 + 7 files changed, 149 insertions(+), 99 deletions(-) diff --git a/.github/workflows/ember.yml b/.github/workflows/ember.yml index 538b16b316e..7a237cdfe6e 100644 --- a/.github/workflows/ember.yml +++ b/.github/workflows/ember.yml @@ -43,5 +43,5 @@ jobs: - name: Core QUnit working-directory: ./app/assets/javascripts/discourse - run: yarn ember test + run: sudo -E -u discourse -H yarn ember test timeout-minutes: 30 diff --git a/app/assets/javascripts/discourse/testem.js b/app/assets/javascripts/discourse/testem.js index b6be26b3592..1bc59b31df8 100644 --- a/app/assets/javascripts/discourse/testem.js +++ b/app/assets/javascripts/discourse/testem.js @@ -1,8 +1,9 @@ module.exports = { test_page: "tests/index.html?hidepassed", disable_watching: true, - launch_in_ci: ["Chrome"], + launch_in_ci: ["Chrome", "Firefox"], launch_in_dev: ["Chrome"], + parallel: -1, // run Firefox and Chrome in parallel browser_args: { Chrome: [ // --no-sandbox is needed when running Chrome inside a container @@ -14,5 +15,6 @@ module.exports = { "--remote-debugging-port=4201", "--window-size=1440,900", ].filter(Boolean), + Firefox: ["-headless", "--width=1440", "--height=900"], }, }; diff --git a/app/assets/javascripts/discourse/tests/acceptance/mobile-pan-test.js b/app/assets/javascripts/discourse/tests/acceptance/mobile-pan-test.js index ff78f547796..0aa70c8abe3 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/mobile-pan-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/mobile-pan-test.js @@ -1,10 +1,10 @@ import { acceptance, + chromeTest, count, exists, } from "discourse/tests/helpers/qunit-helpers"; import { click, triggerEvent, visit } from "@ember/test-helpers"; -import { test } from "qunit"; async function triggerSwipeStart(touchTarget) { // some tests are shown in a zoom viewport. @@ -73,11 +73,12 @@ async function triggerSwipeEnd({ x, y, touchTarget }) { }); } +// new Touch() isn't availiable in Firefox, so this is skipped there acceptance("Mobile - menu swipes", function (needs) { needs.mobileView(); needs.user(); - test("swipe to close hamburger", async function (assert) { + chromeTest("swipe to close hamburger", async function (assert) { await visit("/"); await click(".hamburger-dropdown"); @@ -93,26 +94,29 @@ acceptance("Mobile - menu swipes", function (needs) { ); }); - test("swipe back and flick to re-open hamburger", async function (assert) { - await visit("/"); - await click(".hamburger-dropdown"); + chromeTest( + "swipe back and flick to re-open hamburger", + async function (assert) { + await visit("/"); + await click(".hamburger-dropdown"); - const touchTarget = document.querySelector(".panel-body"); - let swipe = await triggerSwipeStart(touchTarget); - swipe.x -= 100; - await triggerSwipeMove(swipe); - swipe.x += 20; - await triggerSwipeMove(swipe); - await triggerSwipeEnd(swipe); + const touchTarget = document.querySelector(".panel-body"); + let swipe = await triggerSwipeStart(touchTarget); + swipe.x -= 100; + await triggerSwipeMove(swipe); + swipe.x += 20; + await triggerSwipeMove(swipe); + await triggerSwipeEnd(swipe); - assert.equal( - count(".panel-body"), - 1, - "it should re-open hamburger on a right swipe" - ); - }); + assert.equal( + count(".panel-body"), + 1, + "it should re-open hamburger on a right swipe" + ); + } + ); - test("swipe to user menu", async function (assert) { + chromeTest("swipe to user menu", async function (assert) { await visit("/"); await click("#current-user"); diff --git a/app/assets/javascripts/discourse/tests/acceptance/topic-quote-button-test.js b/app/assets/javascripts/discourse/tests/acceptance/topic-quote-button-test.js index 66d78a2ea08..7ddeca57d4b 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/topic-quote-button-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/topic-quote-button-test.js @@ -1,10 +1,10 @@ import { acceptance, + chromeTest, exists, queryAll, } from "discourse/tests/helpers/qunit-helpers"; import I18n from "I18n"; -import { test } from "qunit"; import { settled, visit } from "@ember/test-helpers"; async function selectText(selector) { @@ -18,6 +18,7 @@ async function selectText(selector) { await settled(); } +// This tests are flaky on Firefox. Fails with `calling set on destroyed object` acceptance("Topic - Quote button - logged in", function (needs) { needs.user(); needs.settings({ @@ -25,41 +26,50 @@ acceptance("Topic - Quote button - logged in", function (needs) { share_quote_buttons: "twitter|email", }); - test("Does not show the quote share buttons by default", async function (assert) { - await visit("/t/internationalization-localization/280"); - await selectText("#post_5 blockquote"); - assert.ok(exists(".insert-quote"), "it shows the quote button"); - assert.ok(!exists(".quote-sharing"), "it does not show quote sharing"); - }); + chromeTest( + "Does not show the quote share buttons by default", + async function (assert) { + await visit("/t/internationalization-localization/280"); + await selectText("#post_5 blockquote"); + assert.ok(exists(".insert-quote"), "it shows the quote button"); + assert.ok(!exists(".quote-sharing"), "it does not show quote sharing"); + } + ); - test("Shows quote share buttons with the right site settings", async function (assert) { - this.siteSettings.share_quote_visibility = "all"; + chromeTest( + "Shows quote share buttons with the right site settings", + async function (assert) { + this.siteSettings.share_quote_visibility = "all"; - await visit("/t/internationalization-localization/280"); - await selectText("#post_5 blockquote"); + await visit("/t/internationalization-localization/280"); + await selectText("#post_5 blockquote"); - assert.ok(exists(".quote-sharing"), "it shows the quote sharing options"); - assert.ok( - exists(`.quote-sharing .btn[title='${I18n.t("share.twitter")}']`), - "it includes the twitter share button" - ); - assert.ok( - exists(`.quote-sharing .btn[title='${I18n.t("share.email")}']`), - "it includes the email share button" - ); - }); + assert.ok(exists(".quote-sharing"), "it shows the quote sharing options"); + assert.ok( + exists(`.quote-sharing .btn[title='${I18n.t("share.twitter")}']`), + "it includes the twitter share button" + ); + assert.ok( + exists(`.quote-sharing .btn[title='${I18n.t("share.email")}']`), + "it includes the email share button" + ); + } + ); - test("Quoting a Onebox should not copy the formatting of the rendered Onebox", async function (assert) { - await visit("/t/topic-for-group-moderators/2480"); - await selectText("#post_3 aside.onebox p"); - await click(".insert-quote"); + chromeTest( + "Quoting a Onebox should not copy the formatting of the rendered Onebox", + async function (assert) { + await visit("/t/topic-for-group-moderators/2480"); + await selectText("#post_3 aside.onebox p"); + await click(".insert-quote"); - assert.equal( - queryAll(".d-editor-input").val().trim(), - '[quote="group_moderator, post:3, topic:2480"]\nhttps://example.com/57350945\n[/quote]', - "quote only contains a link" - ); - }); + assert.equal( + queryAll(".d-editor-input").val().trim(), + '[quote="group_moderator, post:3, topic:2480"]\nhttps://example.com/57350945\n[/quote]', + "quote only contains a link" + ); + } + ); }); acceptance("Topic - Quote button - anonymous", function (needs) { @@ -68,46 +78,58 @@ acceptance("Topic - Quote button - anonymous", function (needs) { share_quote_buttons: "twitter|email", }); - test("Shows quote share buttons with the right site settings", async function (assert) { - await visit("/t/internationalization-localization/280"); - await selectText("#post_5 blockquote"); + chromeTest( + "Shows quote share buttons with the right site settings", + async function (assert) { + await visit("/t/internationalization-localization/280"); + await selectText("#post_5 blockquote"); - assert.ok(queryAll(".quote-sharing"), "it shows the quote sharing options"); - assert.ok( - exists(`.quote-sharing .btn[title='${I18n.t("share.twitter")}']`), - "it includes the twitter share button" - ); - assert.ok( - exists(`.quote-sharing .btn[title='${I18n.t("share.email")}']`), - "it includes the email share button" - ); - assert.ok(!exists(".insert-quote"), "it does not show the quote button"); - }); + assert.ok( + queryAll(".quote-sharing"), + "it shows the quote sharing options" + ); + assert.ok( + exists(`.quote-sharing .btn[title='${I18n.t("share.twitter")}']`), + "it includes the twitter share button" + ); + assert.ok( + exists(`.quote-sharing .btn[title='${I18n.t("share.email")}']`), + "it includes the email share button" + ); + assert.ok(!exists(".insert-quote"), "it does not show the quote button"); + } + ); - test("Shows single share button when site setting only has one item", async function (assert) { - this.siteSettings.share_quote_buttons = "twitter"; + chromeTest( + "Shows single share button when site setting only has one item", + async function (assert) { + this.siteSettings.share_quote_buttons = "twitter"; - await visit("/t/internationalization-localization/280"); - await selectText("#post_5 blockquote"); + await visit("/t/internationalization-localization/280"); + await selectText("#post_5 blockquote"); - assert.ok(exists(".quote-sharing"), "it shows the quote sharing options"); - assert.ok( - exists(`.quote-sharing .btn[title='${I18n.t("share.twitter")}']`), - "it includes the twitter share button" - ); - assert.ok( - !exists(".quote-share-label"), - "it does not show the Share label" - ); - }); + assert.ok(exists(".quote-sharing"), "it shows the quote sharing options"); + assert.ok( + exists(`.quote-sharing .btn[title='${I18n.t("share.twitter")}']`), + "it includes the twitter share button" + ); + assert.ok( + !exists(".quote-share-label"), + "it does not show the Share label" + ); + } + ); - test("Shows nothing when visibility is disabled", async function (assert) { - this.siteSettings.share_quote_visibility = "none"; + chromeTest( + "Shows nothing when visibility is disabled", + async function (assert) { + this.siteSettings.share_quote_visibility = "none"; - await visit("/t/internationalization-localization/280"); - await selectText("#post_5 blockquote"); + await visit("/t/internationalization-localization/280"); + await selectText("#post_5 blockquote"); - assert.ok(!exists(".quote-sharing"), "it does not show quote sharing"); - assert.ok(!exists(".insert-quote"), "it does not show the quote button"); - }); + assert.ok(!exists(".quote-sharing"), "it does not show quote sharing"); + assert.ok(!exists(".insert-quote"), "it does not show the quote button"); + } + ); }); diff --git a/app/assets/javascripts/discourse/tests/acceptance/topic-test.js b/app/assets/javascripts/discourse/tests/acceptance/topic-test.js index c380d9ba9d9..584989f3a94 100644 --- a/app/assets/javascripts/discourse/tests/acceptance/topic-test.js +++ b/app/assets/javascripts/discourse/tests/acceptance/topic-test.js @@ -1,5 +1,6 @@ import { acceptance, + chromeTest, count, exists, query, @@ -400,18 +401,22 @@ 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"); - await selectText("#post_5 blockquote"); - await triggerKeyEvent(document, "keypress", "j".charCodeAt(0)); - await triggerKeyEvent(document, "keypress", "t".charCodeAt(0)); + // Using J/K on Firefox clean the text selection, so this won't work there + chromeTest( + "Quoting a quote with replyAsNewTopic keeps the original poster name", + async function (assert) { + await visit("/t/internationalization-localization/280"); + await selectText("#post_5 blockquote"); + await triggerKeyEvent(document, "keypress", "j".charCodeAt(0)); + await triggerKeyEvent(document, "keypress", "t".charCodeAt(0)); - assert.ok( - queryAll(".d-editor-input") - .val() - .indexOf('quote="codinghorror said, post:3, topic:280"') !== -1 - ); - }); + assert.ok( + queryAll(".d-editor-input") + .val() + .indexOf('quote="codinghorror said, post:3, topic:280"') !== -1 + ); + } + ); test("Quoting by selecting text can mark the quote as full", async function (assert) { await visit("/t/internationalization-localization/280"); diff --git a/app/assets/javascripts/discourse/tests/helpers/qunit-helpers.js b/app/assets/javascripts/discourse/tests/helpers/qunit-helpers.js index f0cf9099e43..98bb531a091 100644 --- a/app/assets/javascripts/discourse/tests/helpers/qunit-helpers.js +++ b/app/assets/javascripts/discourse/tests/helpers/qunit-helpers.js @@ -1,4 +1,4 @@ -import QUnit, { module } from "qunit"; +import QUnit, { module, skip, test } from "qunit"; import MessageBus from "message-bus-client"; import { clearCache as clearOutletCache, @@ -468,3 +468,19 @@ export function publishToMessageBus(channelPath, ...args) { .filterBy("channel", channelPath) .map((c) => c.func(...args)); } + +export function conditionalTest(name, condition, testCase) { + if (condition) { + test(name, testCase); + } else { + skip(name, testCase); + } +} + +export function chromeTest(name, testCase) { + conditionalTest(name, navigator.userAgent.includes("Chrome"), testCase); +} + +export function firefoxTest(name, testCase) { + conditionalTest(name, navigator.userAgent.includes("Firefox"), testCase); +} diff --git a/app/assets/javascripts/discourse/tests/integration/components/d-editor-test.js b/app/assets/javascripts/discourse/tests/integration/components/d-editor-test.js index 047ce443a09..372689b5e6c 100644 --- a/app/assets/javascripts/discourse/tests/integration/components/d-editor-test.js +++ b/app/assets/javascripts/discourse/tests/integration/components/d-editor-test.js @@ -85,6 +85,7 @@ discourseModule("Integration | Component | d-editor", function (hooks) { const textarea = jumpEnd(query("textarea.d-editor-input")); testFunc.call(this, assert, textarea); }, + skip: !navigator.userAgent.includes("Chrome"), }); }