DEV: Run tests in Firefox ESR (#14094)

DEV: Run tests in Firefox ESR (#14094)

diff --git a/.github/workflows/ember.yml b/.github/workflows/ember.yml
index 538b16b..7a237cd 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 b6be26b..1bc59b3 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 ff78f54..0aa70c8 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 66d78a2..7ddeca5 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");
-  });
-
-  test("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");
-
-    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");
-
-    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"
-    );
-  });
+  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");
+    }
+  );
+
+  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");
+
+      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"
+      );
+    }
+  );
+
+  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"
+      );
+    }
+  );
 });
 
 acceptance("Topic - Quote button - anonymous", function (needs) {
@@ -68,46 +78,58 @@ acceptance("Topic - Quote button - anonymous", function (needs) {
     share_quote_buttons: "twitter|email",
   });
 

[... diff too long, it was truncated ...]

GitHub sha: 9b30fbdbbdf6c0af4811c606f5b1634e17fe833a

This commit appears in #14094 which was approved by jjaffeux. It was merged by Falco.