diff --git a/frontend/test/metabase/scenarios/question/question-reproductions.cy.spec.js b/frontend/test/metabase/scenarios/question/question-reproductions.cy.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..caec455e0827bc64d05d16ed31db778d50fe4a2e
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/question-reproductions.cy.spec.js
@@ -0,0 +1,39 @@
+import { issue4482 } from "./reproductions/4482-temporal-min-max";
+import { issue6239 } from "./reproductions/6239-sort-using-cust-exp";
+import { issue9027 } from "./reproductions/9027-new-questions-not-in-saved-questions-immediately";
+import { issue13097 } from "./reproductions/13097-mongo-apply-distinct-count-multiple-columns";
+import { issue13263 } from "./reproductions/13263-postgres-show-row-details-on-pk-click";
+import { issue14957 } from "./reproductions/14957-unable-to-save-question-before-query-executed";
+import { issue15714 } from "./reproductions/15714-cc-postgres-percentile-accepts-two-params";
+import { issue15876 } from "./reproductions/15876-postgres-cast-time";
+import { issue16621 } from "./reproductions/16621-create-multiple-filters-with-same-value";
+import { issue17512 } from "./reproductions/17512";
+import { issue17514 } from "./reproductions/17514-ui-overlay";
+import { issue17963 } from "./reproductions/17963-mongo-filter-expression-compare-two-fields";
+import { issue18207 } from "./reproductions/18207-string-min-max";
+import { issue18978 } from "./reproductions/18978-18977-nested-question-nodata-user";
+import { issue19341 } from "./reproductions/19341-disabled-nested-queries";
+import { issue19742 } from "./reproductions/19742-data-picker-closes-after-hiding-table";
+import { issue20551 } from "./reproductions/20551-filter-starts-with";
+import { issue20627 } from "./reproductions/20627-nested-long-names-wrong-aliases";
+import { issue20683 } from "./reproductions/20683-postgres-current-quarter";
+
+issue4482();
+issue6239();
+issue9027();
+issue13097();
+issue13263();
+issue14957();
+issue15714();
+issue15876();
+issue16621();
+issue17512();
+issue17514();
+issue17963();
+issue18207();
+issue18978();
+issue19341();
+issue19742();
+issue20551();
+issue20627();
+issue20683();
diff --git a/frontend/test/metabase/scenarios/question/reproductions/13097-mongo-apply-distinct-count-multiple-columns.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/13097-mongo-apply-distinct-count-multiple-columns.cy.spec.js
deleted file mode 100644
index 416197fcad816dda40a959886fc3ea8e2c64bcf6..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/13097-mongo-apply-distinct-count-multiple-columns.cy.spec.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import {
-  restore,
-  visualize,
-  withDatabase,
-  adhocQuestionHash,
-  summarize,
-} from "__support__/e2e/cypress";
-
-const MONGO_DB_ID = 2;
-
-describe("issue 13097", () => {
-  beforeEach(() => {
-    restore("mongo-4");
-    cy.signInAsAdmin();
-
-    withDatabase(MONGO_DB_ID, ({ PEOPLE_ID }) => {
-      const questionDetails = {
-        dataset_query: {
-          type: "query",
-          query: { "source-table": PEOPLE_ID, limit: 5 },
-          database: MONGO_DB_ID,
-        },
-      };
-
-      const hash = adhocQuestionHash(questionDetails);
-
-      cy.visit(`/question/notebook#${hash}`);
-    });
-  });
-
-  it("should correctly apply distinct count on multiple columns (metabase#13097)", () => {
-    summarize({ mode: "notebook" });
-
-    cy.findByText("Number of distinct values of ...").click();
-    cy.findByText("City").click();
-
-    cy.findAllByTestId("notebook-cell-item")
-      .find(".Icon-add")
-      .click();
-
-    cy.findByText("Number of distinct values of ...").click();
-    cy.findByText("State").click();
-
-    visualize();
-
-    // cy.log("Reported failing on stats ~v0.36.3");
-    cy.get(".cellData")
-      .should("have.length", 4)
-      .and("contain", "Distinct values of City")
-      .and("contain", "1,966")
-      .and("contain", "Distinct values of State")
-      .and("contain", "49");
-  });
-});
diff --git a/frontend/test/metabase/scenarios/question/reproductions/13097-mongo-apply-distinct-count-multiple-columns.js b/frontend/test/metabase/scenarios/question/reproductions/13097-mongo-apply-distinct-count-multiple-columns.js
new file mode 100644
index 0000000000000000000000000000000000000000..fad2051ddfcc8640c807300fdbc609f118f49ebb
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/13097-mongo-apply-distinct-count-multiple-columns.js
@@ -0,0 +1,56 @@
+import {
+  restore,
+  visualize,
+  withDatabase,
+  adhocQuestionHash,
+  summarize,
+} from "__support__/e2e/cypress";
+
+const MONGO_DB_ID = 2;
+
+export function issue13097() {
+  describe("issue 13097", () => {
+    beforeEach(() => {
+      restore("mongo-4");
+      cy.signInAsAdmin();
+
+      withDatabase(MONGO_DB_ID, ({ PEOPLE_ID }) => {
+        const questionDetails = {
+          dataset_query: {
+            type: "query",
+            query: { "source-table": PEOPLE_ID, limit: 5 },
+            database: MONGO_DB_ID,
+          },
+        };
+
+        const hash = adhocQuestionHash(questionDetails);
+
+        cy.visit(`/question/notebook#${hash}`);
+      });
+    });
+
+    it("should correctly apply distinct count on multiple columns (metabase#13097)", () => {
+      summarize({ mode: "notebook" });
+
+      cy.findByText("Number of distinct values of ...").click();
+      cy.findByText("City").click();
+
+      cy.findAllByTestId("notebook-cell-item")
+        .find(".Icon-add")
+        .click();
+
+      cy.findByText("Number of distinct values of ...").click();
+      cy.findByText("State").click();
+
+      visualize();
+
+      // cy.log("Reported failing on stats ~v0.36.3");
+      cy.get(".cellData")
+        .should("have.length", 4)
+        .and("contain", "Distinct values of City")
+        .and("contain", "1,966")
+        .and("contain", "Distinct values of State")
+        .and("contain", "49");
+    });
+  });
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/13263-postgres-show-row-details-on-pk-click.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/13263-postgres-show-row-details-on-pk-click.cy.spec.js
deleted file mode 100644
index a22a3ae3060a10e5150e5734bb7212a53e8d9344..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/13263-postgres-show-row-details-on-pk-click.cy.spec.js
+++ /dev/null
@@ -1,35 +0,0 @@
-import { restore } from "__support__/e2e/cypress";
-
-const PG_DB_NAME = "QA Postgres12";
-
-describe("postgres > user > query", () => {
-  beforeEach(() => {
-    restore("postgres-12");
-    cy.signInAsAdmin();
-
-    cy.visit("/question/new");
-    cy.findByText("Simple question").click();
-    cy.findByText(PG_DB_NAME)
-      .should("be.visible")
-      .click();
-    cy.findByTextEnsureVisible("Orders").click();
-  });
-
-  it("should show row details when clicked on its entity key (metabase#13263)", () => {
-    // We're clicking on ID: 1 (the first order) => do not change!
-    // It is tightly coupled to the assertion ("37.65"), which is "Subtotal" value for that order.
-    cy.get(".Table-ID")
-      .eq(0)
-      .click();
-
-    // Wait until "doing science" spinner disappears (DOM is ready for assertions)
-    // TODO: if this proves to be reliable, extract it as a helper function for waiting on DOM to render
-    cy.findByTestId("loading-spinner").should("not.exist");
-
-    // Assertions
-    cy.log("Fails in v0.36.6");
-    // This could be omitted because real test is searching for "37.65" on the page
-    cy.findByText("There was a problem with your question").should("not.exist");
-    cy.contains("37.65");
-  });
-});
diff --git a/frontend/test/metabase/scenarios/question/reproductions/13263-postgres-show-row-details-on-pk-click.js b/frontend/test/metabase/scenarios/question/reproductions/13263-postgres-show-row-details-on-pk-click.js
new file mode 100644
index 0000000000000000000000000000000000000000..216964b5a56f71e9c6de2f06752de72524ad6fa7
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/13263-postgres-show-row-details-on-pk-click.js
@@ -0,0 +1,39 @@
+import { restore } from "__support__/e2e/cypress";
+
+const PG_DB_NAME = "QA Postgres12";
+
+export function issue13263() {
+  describe("postgres > user > query", () => {
+    beforeEach(() => {
+      restore("postgres-12");
+      cy.signInAsAdmin();
+
+      cy.visit("/question/new");
+      cy.findByText("Simple question").click();
+      cy.findByText(PG_DB_NAME)
+        .should("be.visible")
+        .click();
+      cy.findByTextEnsureVisible("Orders").click();
+    });
+
+    it("should show row details when clicked on its entity key (metabase#13263)", () => {
+      // We're clicking on ID: 1 (the first order) => do not change!
+      // It is tightly coupled to the assertion ("37.65"), which is "Subtotal" value for that order.
+      cy.get(".Table-ID")
+        .eq(0)
+        .click();
+
+      // Wait until "doing science" spinner disappears (DOM is ready for assertions)
+      // TODO: if this proves to be reliable, extract it as a helper function for waiting on DOM to render
+      cy.findByTestId("loading-spinner").should("not.exist");
+
+      // Assertions
+      cy.log("Fails in v0.36.6");
+      // This could be omitted because real test is searching for "37.65" on the page
+      cy.findByText("There was a problem with your question").should(
+        "not.exist",
+      );
+      cy.contains("37.65");
+    });
+  });
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/14957-unable-to-save-question-before-query-executed.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/14957-unable-to-save-question-before-query-executed.cy.spec.js
deleted file mode 100644
index caa4985d03825152f426ee7e7cce660a62e92969..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/14957-unable-to-save-question-before-query-executed.cy.spec.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import { restore, modal } from "__support__/e2e/cypress";
-
-const PG_DB_NAME = "QA Postgres12";
-
-describe.skip("issue 14957", () => {
-  beforeEach(() => {
-    restore("postgres-12");
-    cy.signInAsAdmin();
-
-    cy.visit("/question/new");
-    cy.findByText("Native query").click();
-    cy.findByText(PG_DB_NAME)
-      .should("be.visible")
-      .click();
-  });
-
-  it("should save a question before query has been executed (metabase#14957)", () => {
-    cy.get(".ace_content").type("select pg_sleep(60)");
-
-    cy.findByText("Save").click();
-
-    cy.findByLabelText("Name").type("14957");
-    cy.button("Save").click();
-
-    modal().should("not.exist");
-  });
-});
diff --git a/frontend/test/metabase/scenarios/question/reproductions/14957-unable-to-save-question-before-query-executed.js b/frontend/test/metabase/scenarios/question/reproductions/14957-unable-to-save-question-before-query-executed.js
new file mode 100644
index 0000000000000000000000000000000000000000..e80cebb96bbe00d7441805cb0c4bc88a23d5e2eb
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/14957-unable-to-save-question-before-query-executed.js
@@ -0,0 +1,29 @@
+import { restore, modal } from "__support__/e2e/cypress";
+
+const PG_DB_NAME = "QA Postgres12";
+
+export function issue14957() {
+  describe.skip("issue 14957", () => {
+    beforeEach(() => {
+      restore("postgres-12");
+      cy.signInAsAdmin();
+
+      cy.visit("/question/new");
+      cy.findByText("Native query").click();
+      cy.findByText(PG_DB_NAME)
+        .should("be.visible")
+        .click();
+    });
+
+    it("should save a question before query has been executed (metabase#14957)", () => {
+      cy.get(".ace_content").type("select pg_sleep(60)");
+
+      cy.findByText("Save").click();
+
+      cy.findByLabelText("Name").type("14957");
+      cy.button("Save").click();
+
+      modal().should("not.exist");
+    });
+  });
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/15714-cc-postgres-percentile-accepts-two-params.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/15714-cc-postgres-percentile-accepts-two-params.cy.spec.js
deleted file mode 100644
index 13c85520aa3995c81be4cd385078bdc2b1b98093..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/15714-cc-postgres-percentile-accepts-two-params.cy.spec.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import { enterCustomColumnDetails, restore } from "__support__/e2e/cypress";
-
-const PG_DB_NAME = "QA Postgres12";
-
-describe("postgres > question > custom columns", () => {
-  beforeEach(() => {
-    restore("postgres-12");
-    cy.signInAsAdmin();
-
-    cy.visit("/question/new");
-    cy.findByText("Custom question").click();
-    cy.findByText(PG_DB_NAME)
-      .should("be.visible")
-      .click();
-    cy.findByTextEnsureVisible("Orders").click();
-  });
-
-  it("`Percentile` custom expression function should accept two parameters (metabase#15714)", () => {
-    cy.findByText("Pick the metric you want to see").click();
-    cy.findByText("Custom Expression").click();
-    enterCustomColumnDetails({ formula: "Percentile([Subtotal], 0.1)" });
-    cy.findByPlaceholderText("Name (required)")
-      .as("description")
-      .click();
-
-    cy.findByText("Function Percentile expects 1 argument").should("not.exist");
-    cy.get("@description").type("A");
-    cy.button("Done")
-      .should("not.be.disabled")
-      .click();
-    // Todo: Add positive assertions once this is fixed
-  });
-});
diff --git a/frontend/test/metabase/scenarios/question/reproductions/15714-cc-postgres-percentile-accepts-two-params.js b/frontend/test/metabase/scenarios/question/reproductions/15714-cc-postgres-percentile-accepts-two-params.js
new file mode 100644
index 0000000000000000000000000000000000000000..06217c2ba29ebac955056585463c8730766e395b
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/15714-cc-postgres-percentile-accepts-two-params.js
@@ -0,0 +1,37 @@
+import { enterCustomColumnDetails, restore } from "__support__/e2e/cypress";
+
+const PG_DB_NAME = "QA Postgres12";
+
+export function issue15714() {
+  describe("postgres > question > custom columns", () => {
+    beforeEach(() => {
+      restore("postgres-12");
+      cy.signInAsAdmin();
+
+      cy.visit("/question/new");
+      cy.findByText("Custom question").click();
+      cy.findByText(PG_DB_NAME)
+        .should("be.visible")
+        .click();
+      cy.findByTextEnsureVisible("Orders").click();
+    });
+
+    it("`Percentile` custom expression function should accept two parameters (metabase#15714)", () => {
+      cy.findByText("Pick the metric you want to see").click();
+      cy.findByText("Custom Expression").click();
+      enterCustomColumnDetails({ formula: "Percentile([Subtotal], 0.1)" });
+      cy.findByPlaceholderText("Name (required)")
+        .as("description")
+        .click();
+
+      cy.findByText("Function Percentile expects 1 argument").should(
+        "not.exist",
+      );
+      cy.get("@description").type("A");
+      cy.button("Done")
+        .should("not.be.disabled")
+        .click();
+      // Todo: Add positive assertions once this is fixed
+    });
+  });
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/15876-postgres-cast-time.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/15876-postgres-cast-time.js
similarity index 73%
rename from frontend/test/metabase/scenarios/question/reproductions/15876-postgres-cast-time.cy.spec.js
rename to frontend/test/metabase/scenarios/question/reproductions/15876-postgres-cast-time.js
index 77df532a3ff9cfb33ab910696be3a00f1f87b916..8ee07785924355406fb9bc3b10bd012a79e216af 100644
--- a/frontend/test/metabase/scenarios/question/reproductions/15876-postgres-cast-time.cy.spec.js
+++ b/frontend/test/metabase/scenarios/question/reproductions/15876-postgres-cast-time.js
@@ -41,21 +41,23 @@ const correctValues = [
   },
 ];
 
-describe("issue 15876", () => {
-  beforeEach(() => {
-    restore("postgres-12");
-    cy.signInAsAdmin();
-  });
+export function issue15876() {
+  describe("issue 15876", () => {
+    beforeEach(() => {
+      restore("postgres-12");
+      cy.signInAsAdmin();
+    });
 
-  it("should correctly cast to `TIME` (metabase#15876)", () => {
-    cy.createNativeQuestion(questionDetails, { visitQuestion: true });
+    it("should correctly cast to `TIME` (metabase#15876)", () => {
+      cy.createNativeQuestion(questionDetails, { visitQuestion: true });
 
-    cy.get(".Visualization").within(() => {
-      correctValues.forEach(({ value, rows }) => {
-        const count = rows * castColumns;
+      cy.get(".Visualization").within(() => {
+        correctValues.forEach(({ value, rows }) => {
+          const count = rows * castColumns;
 
-        cy.findAllByText(value).should("have.length", count);
+          cy.findAllByText(value).should("have.length", count);
+        });
       });
     });
   });
-});
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/16621-create-multiple-filters-with-same-value.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/16621-create-multiple-filters-with-same-value.cy.spec.js
deleted file mode 100644
index a4060086b6bf3a632e4d8030ee70af5bdba3e1bf..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/16621-create-multiple-filters-with-same-value.cy.spec.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import { restore, openProductsTable } from "__support__/e2e/cypress";
-
-describe("issue 16661", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-    openProductsTable({ limit: 3 });
-  });
-
-  it("should be possible to create multiple filter that start with the same value (metabase#16621)", () => {
-    cy.findByText("Category").click();
-    cy.findByText("Filter by this column").click();
-    cy.findByPlaceholderText("Search the list").type("Doo{enter}");
-    cy.findByTestId("Doo-filter-value").click();
-    cy.button("Update filter").click();
-    cy.findByText("Category is Doo").click();
-    cy.findByTestId("Doohickey-filter-value").click();
-    cy.button("Update filter").click();
-    cy.findByText("Category is 2 selections");
-  });
-});
diff --git a/frontend/test/metabase/scenarios/question/reproductions/16621-create-multiple-filters-with-same-value.js b/frontend/test/metabase/scenarios/question/reproductions/16621-create-multiple-filters-with-same-value.js
new file mode 100644
index 0000000000000000000000000000000000000000..95e2e5664086625d1c503294f972c0604ea714f1
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/16621-create-multiple-filters-with-same-value.js
@@ -0,0 +1,23 @@
+import { restore, openProductsTable } from "__support__/e2e/cypress";
+
+export function issue16621() {
+  describe("issue 16661", () => {
+    beforeEach(() => {
+      restore();
+      cy.signInAsAdmin();
+      openProductsTable({ limit: 3 });
+    });
+
+    it("should be possible to create multiple filter that start with the same value (metabase#16621)", () => {
+      cy.findByText("Category").click();
+      cy.findByText("Filter by this column").click();
+      cy.findByPlaceholderText("Search the list").type("Doo{enter}");
+      cy.findByTestId("Doo-filter-value").click();
+      cy.button("Update filter").click();
+      cy.findByText("Category is Doo").click();
+      cy.findByTestId("Doohickey-filter-value").click();
+      cy.button("Update filter").click();
+      cy.findByText("Category is 2 selections");
+    });
+  });
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/17512.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/17512.cy.spec.js
deleted file mode 100644
index 6728eba85061c637e0a58c5d78386181a460679d..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/17512.cy.spec.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import {
-  restore,
-  openOrdersTable,
-  popover,
-  visualize,
-  summarize,
-} from "__support__/e2e/cypress";
-
-describe("issue 17512", () => {
-  beforeEach(() => {
-    cy.intercept("POST", "/api/dataset").as("dataset");
-
-    restore();
-    cy.signInAsAdmin();
-  });
-
-  it("custom expression should work with `case` in nested queries (metabase#17512)", () => {
-    openOrdersTable({ mode: "notebook" });
-
-    addSummarizeCustomExpression(
-      "Distinct(case([Discount] > 0, [Subtotal], [Total]))",
-      "CE",
-    );
-
-    cy.findByText("Pick a column to group by").click();
-    cy.findByText("Created At").click();
-
-    addCustomColumn("1 + 1", "CC");
-
-    visualize(({ body }) => {
-      expect(body.error).to.not.exist;
-    });
-
-    cy.findByText("CE");
-    cy.findByText("CC");
-  });
-});
-
-function addSummarizeCustomExpression(formula, name) {
-  summarize({ mode: "notebook" });
-  popover()
-    .contains("Custom Expression")
-    .click();
-
-  popover().within(() => {
-    cy.get(".ace_text-input")
-      .type(formula)
-      .blur();
-    cy.findByPlaceholderText("Name (required)").type(name);
-    cy.button("Done").click();
-  });
-}
-
-function addCustomColumn(formula, name) {
-  cy.findByText("Custom column").click();
-  popover().within(() => {
-    cy.get(".ace_text-input")
-      .type(formula)
-      .blur();
-    cy.findByPlaceholderText("Something nice and descriptive").type(name);
-    cy.button("Done").click();
-  });
-}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/17512.js b/frontend/test/metabase/scenarios/question/reproductions/17512.js
new file mode 100644
index 0000000000000000000000000000000000000000..a77aa859ae250c03f96dee2e0ffc7d160a1dc461
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/17512.js
@@ -0,0 +1,65 @@
+import {
+  restore,
+  openOrdersTable,
+  popover,
+  visualize,
+  summarize,
+} from "__support__/e2e/cypress";
+
+export function issue17512() {
+  describe("issue 17512", () => {
+    beforeEach(() => {
+      cy.intercept("POST", "/api/dataset").as("dataset");
+
+      restore();
+      cy.signInAsAdmin();
+    });
+
+    it("custom expression should work with `case` in nested queries (metabase#17512)", () => {
+      openOrdersTable({ mode: "notebook" });
+
+      addSummarizeCustomExpression(
+        "Distinct(case([Discount] > 0, [Subtotal], [Total]))",
+        "CE",
+      );
+
+      cy.findByText("Pick a column to group by").click();
+      cy.findByText("Created At").click();
+
+      addCustomColumn("1 + 1", "CC");
+
+      visualize(({ body }) => {
+        expect(body.error).to.not.exist;
+      });
+
+      cy.findByText("CE");
+      cy.findByText("CC");
+    });
+  });
+
+  function addSummarizeCustomExpression(formula, name) {
+    summarize({ mode: "notebook" });
+    popover()
+      .contains("Custom Expression")
+      .click();
+
+    popover().within(() => {
+      cy.get(".ace_text-input")
+        .type(formula)
+        .blur();
+      cy.findByPlaceholderText("Name (required)").type(name);
+      cy.button("Done").click();
+    });
+  }
+
+  function addCustomColumn(formula, name) {
+    cy.findByText("Custom column").click();
+    popover().within(() => {
+      cy.get(".ace_text-input")
+        .type(formula)
+        .blur();
+      cy.findByPlaceholderText("Something nice and descriptive").type(name);
+      cy.button("Done").click();
+    });
+  }
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/17514-ui-overlay.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/17514-ui-overlay.cy.spec.js
deleted file mode 100644
index 7d7625d560f7a85210e7041a1ff9aa83071c3e8e..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/17514-ui-overlay.cy.spec.js
+++ /dev/null
@@ -1,193 +0,0 @@
-import {
-  restore,
-  showDashboardCardActions,
-  filterWidget,
-  saveDashboard,
-  editDashboard,
-  visualize,
-  visitDashboard,
-} from "__support__/e2e/cypress";
-
-import { setAdHocFilter } from "../../native-filters/helpers/e2e-date-filter-helpers";
-
-import { SAMPLE_DATABASE } from "__support__/e2e/cypress_sample_database";
-
-const { ORDERS, ORDERS_ID, PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE;
-
-const questionDetails = {
-  name: "17514",
-  query: {
-    "source-table": ORDERS_ID,
-    joins: [
-      {
-        fields: "all",
-        "source-table": PRODUCTS_ID,
-        condition: [
-          "=",
-          ["field", ORDERS.PRODUCT_ID, null],
-          ["field", PRODUCTS.ID, { "join-alias": "Products" }],
-        ],
-        alias: "Products",
-      },
-    ],
-  },
-};
-
-const filter = {
-  name: "Date Filter",
-  slug: "date_filter",
-  id: "23ccbbf",
-  type: "date/all-options",
-  sectionId: "date",
-};
-
-const dashboardDetails = { parameters: [filter] };
-
-describe("issue 17514", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-    cy.intercept("POST", "/api/dataset").as("dataset");
-  });
-
-  describe("scenario 1", () => {
-    beforeEach(() => {
-      cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then(
-        ({ body: card }) => {
-          const { card_id, dashboard_id } = card;
-
-          cy.intercept(
-            "POST",
-            `/api/dashboard/${dashboard_id}/dashcard/*/card/${card_id}/query`,
-          ).as("cardQuery");
-
-          const mapFilterToCard = {
-            parameter_mappings: [
-              {
-                parameter_id: filter.id,
-                card_id,
-                target: ["dimension", ["field", ORDERS.CREATED_AT, null]],
-              },
-            ],
-          };
-
-          cy.editDashboardCard(card, mapFilterToCard);
-
-          visitDashboard(dashboard_id);
-
-          cy.wait("@cardQuery");
-          cy.findByText("110.93").should("be.visible");
-        },
-      );
-    });
-
-    it("should not show the run overlay when we apply dashboard filter on a question with removed column and then click through its title (metabase#17514-1)", () => {
-      editDashboard();
-
-      openVisualizationOptions();
-
-      hideColumn("Products → Ean");
-
-      closeModal();
-
-      saveDashboard();
-      cy.wait("@getDashboard");
-
-      filterWidget().click();
-      setAdHocFilter({ timeBucket: "Years" });
-
-      cy.location("search").should("eq", "?date_filter=past30years");
-      cy.wait("@cardQuery");
-
-      cy.findByText("Previous 30 Years");
-
-      cy.findByText("17514").click();
-      cy.wait("@dataset");
-      cy.findByTextEnsureVisible("Subtotal");
-
-      // Cypress cannot click elements that are blocked by an overlay so this will immediately fail if the issue is not fixed
-      cy.findByText("110.93").click();
-      cy.findByText("Filter by this value");
-    });
-  });
-
-  describe("scenario 2", () => {
-    beforeEach(() => {
-      cy.createQuestion(questionDetails, { visitQuestion: true });
-
-      cy.findByTestId("viz-settings-button").click();
-
-      moveColumnToTop("Subtotal");
-
-      openNotebookMode();
-
-      removeJoinedTable();
-
-      visualize();
-      cy.findByTextEnsureVisible("Subtotal");
-
-      cy.findByText("Save").click();
-
-      cy.get(".Modal").within(() => {
-        cy.button("Save").click();
-      });
-    });
-
-    it("should not show the run overlay because of the references to the orphaned fields (metabase#17514-2)", () => {
-      openNotebookMode();
-
-      cy.findByText("Join data").click();
-      cy.findByText("Products").click();
-
-      visualize();
-      cy.findByTextEnsureVisible("Subtotal");
-
-      // Cypress cannot click elements that are blocked by an overlay so this will immediately fail if the issue is not fixed
-      cy.findByText("110.93").click();
-      cy.findByText("Filter by this value");
-    });
-  });
-});
-
-function openVisualizationOptions() {
-  showDashboardCardActions();
-  cy.icon("palette").click({ force: true });
-}
-
-function hideColumn(columnName) {
-  cy.findByTestId("chartsettings-sidebar").within(() => {
-    cy.findByText(columnName)
-      .siblings(".Icon-close")
-      .click();
-  });
-}
-
-function closeModal() {
-  cy.get(".Modal").within(() => {
-    cy.button("Done").click();
-  });
-}
-
-function openNotebookMode() {
-  cy.icon("notebook").click();
-}
-
-function removeJoinedTable() {
-  cy.findAllByText("Join data")
-    .first()
-    .parent()
-    .findByTestId("remove-step")
-    .click({ force: true });
-}
-
-function moveColumnToTop(column) {
-  cy.findByTestId("sidebar-left").within(() => {
-    cy.findByText(column)
-      .should("be.visible")
-      .closest(".cursor-grab")
-      .trigger("mousedown", 0, 0, { force: true })
-      .trigger("mousemove", 5, 5, { force: true })
-      .trigger("mousemove", 0, -600, { force: true })
-      .trigger("mouseup", 0, -600, { force: true });
-  });
-}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/17514-ui-overlay.js b/frontend/test/metabase/scenarios/question/reproductions/17514-ui-overlay.js
new file mode 100644
index 0000000000000000000000000000000000000000..34bb10e1015a5bce09bc093a46852c50f3f1c00f
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/17514-ui-overlay.js
@@ -0,0 +1,196 @@
+import {
+  restore,
+  showDashboardCardActions,
+  filterWidget,
+  saveDashboard,
+  editDashboard,
+  visualize,
+  visitDashboard,
+} from "__support__/e2e/cypress";
+
+import { setAdHocFilter } from "../../native-filters/helpers/e2e-date-filter-helpers";
+
+import { SAMPLE_DATABASE } from "__support__/e2e/cypress_sample_database";
+
+const { ORDERS, ORDERS_ID, PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE;
+
+const questionDetails = {
+  name: "17514",
+  query: {
+    "source-table": ORDERS_ID,
+    joins: [
+      {
+        fields: "all",
+        "source-table": PRODUCTS_ID,
+        condition: [
+          "=",
+          ["field", ORDERS.PRODUCT_ID, null],
+          ["field", PRODUCTS.ID, { "join-alias": "Products" }],
+        ],
+        alias: "Products",
+      },
+    ],
+  },
+};
+
+const filter = {
+  name: "Date Filter",
+  slug: "date_filter",
+  id: "23ccbbf",
+  type: "date/all-options",
+  sectionId: "date",
+};
+
+const dashboardDetails = { parameters: [filter] };
+
+export function issue17514() {
+  describe("issue 17514", () => {
+    beforeEach(() => {
+      restore();
+      cy.signInAsAdmin();
+      cy.intercept("POST", "/api/dataset").as("dataset");
+    });
+
+    describe("scenario 1", () => {
+      beforeEach(() => {
+        cy.createQuestionAndDashboard({
+          questionDetails,
+          dashboardDetails,
+        }).then(({ body: card }) => {
+          const { card_id, dashboard_id } = card;
+
+          cy.intercept(
+            "POST",
+            `/api/dashboard/${dashboard_id}/dashcard/*/card/${card_id}/query`,
+          ).as("cardQuery");
+
+          const mapFilterToCard = {
+            parameter_mappings: [
+              {
+                parameter_id: filter.id,
+                card_id,
+                target: ["dimension", ["field", ORDERS.CREATED_AT, null]],
+              },
+            ],
+          };
+
+          cy.editDashboardCard(card, mapFilterToCard);
+
+          visitDashboard(dashboard_id);
+
+          cy.wait("@cardQuery");
+          cy.findByText("110.93").should("be.visible");
+        });
+      });
+
+      it("should not show the run overlay when we apply dashboard filter on a question with removed column and then click through its title (metabase#17514-1)", () => {
+        editDashboard();
+
+        openVisualizationOptions();
+
+        hideColumn("Products → Ean");
+
+        closeModal();
+
+        saveDashboard();
+        cy.wait("@getDashboard");
+
+        filterWidget().click();
+        setAdHocFilter({ timeBucket: "Years" });
+
+        cy.location("search").should("eq", "?date_filter=past30years");
+        cy.wait("@cardQuery");
+
+        cy.findByText("Previous 30 Years");
+
+        cy.findByText("17514").click();
+        cy.wait("@dataset");
+        cy.findByTextEnsureVisible("Subtotal");
+
+        // Cypress cannot click elements that are blocked by an overlay so this will immediately fail if the issue is not fixed
+        cy.findByText("110.93").click();
+        cy.findByText("Filter by this value");
+      });
+    });
+
+    describe("scenario 2", () => {
+      beforeEach(() => {
+        cy.createQuestion(questionDetails, { visitQuestion: true });
+
+        cy.findByTestId("viz-settings-button").click();
+
+        moveColumnToTop("Subtotal");
+
+        openNotebookMode();
+
+        removeJoinedTable();
+
+        visualize();
+        cy.findByTextEnsureVisible("Subtotal");
+
+        cy.findByText("Save").click();
+
+        cy.get(".Modal").within(() => {
+          cy.button("Save").click();
+        });
+      });
+
+      it("should not show the run overlay because of the references to the orphaned fields (metabase#17514-2)", () => {
+        openNotebookMode();
+
+        cy.findByText("Join data").click();
+        cy.findByText("Products").click();
+
+        visualize();
+        cy.findByTextEnsureVisible("Subtotal");
+
+        // Cypress cannot click elements that are blocked by an overlay so this will immediately fail if the issue is not fixed
+        cy.findByText("110.93").click();
+        cy.findByText("Filter by this value");
+      });
+    });
+  });
+
+  function openVisualizationOptions() {
+    showDashboardCardActions();
+    cy.icon("palette").click({ force: true });
+  }
+
+  function hideColumn(columnName) {
+    cy.findByTestId("chartsettings-sidebar").within(() => {
+      cy.findByText(columnName)
+        .siblings(".Icon-close")
+        .click();
+    });
+  }
+
+  function closeModal() {
+    cy.get(".Modal").within(() => {
+      cy.button("Done").click();
+    });
+  }
+
+  function openNotebookMode() {
+    cy.icon("notebook").click();
+  }
+
+  function removeJoinedTable() {
+    cy.findAllByText("Join data")
+      .first()
+      .parent()
+      .findByTestId("remove-step")
+      .click({ force: true });
+  }
+
+  function moveColumnToTop(column) {
+    cy.findByTestId("sidebar-left").within(() => {
+      cy.findByText(column)
+        .should("be.visible")
+        .closest(".cursor-grab")
+        .trigger("mousedown", 0, 0, { force: true })
+        .trigger("mousemove", 5, 5, { force: true })
+        .trigger("mousemove", 0, -600, { force: true })
+        .trigger("mouseup", 0, -600, { force: true });
+    });
+  }
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/17963-mongo-filter-expression-compare-two-fields.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/17963-mongo-filter-expression-compare-two-fields.cy.spec.js
deleted file mode 100644
index 2955a392392a16328abe5ba77c10064cd9ff69ce..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/17963-mongo-filter-expression-compare-two-fields.cy.spec.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { restore, popover, visualize } from "__support__/e2e/cypress";
-
-describe("issue 17963", () => {
-  beforeEach(() => {
-    restore("mongo-4");
-    cy.signInAsAdmin();
-
-    cy.visit("/question/new");
-    cy.findByText("Custom question").click();
-    cy.findByText("QA Mongo4").click();
-    cy.findByText("Orders").click();
-  });
-
-  it("should be able to compare two fields using filter expression (metabase#17963)", () => {
-    cy.findByText("Add filters to narrow your answer").click();
-
-    popover()
-      .contains("Custom Expression")
-      .click();
-
-    typeAndSelect([
-      { string: "dis", field: "Discount" },
-      { string: "> qu", field: "Quantity" },
-    ]);
-
-    cy.button("Done").click();
-
-    cy.findByText("Discount > Quantity");
-
-    cy.findByText("Pick the metric you want to see").click();
-    cy.findByText("Count of rows").click();
-
-    visualize();
-
-    cy.get(".ScalarValue").contains("1,337");
-  });
-});
-
-function typeAndSelect(arr) {
-  arr.forEach(({ string, field }) => {
-    cy.get(".ace_text-input").type(string);
-
-    popover()
-      .contains(field)
-      .click();
-  });
-}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/17963-mongo-filter-expression-compare-two-fields.js b/frontend/test/metabase/scenarios/question/reproductions/17963-mongo-filter-expression-compare-two-fields.js
new file mode 100644
index 0000000000000000000000000000000000000000..90fe67be9562674ad1cbad1e4724542e292f533d
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/17963-mongo-filter-expression-compare-two-fields.js
@@ -0,0 +1,49 @@
+import { restore, popover, visualize } from "__support__/e2e/cypress";
+
+export function issue17963() {
+  describe("issue 17963", () => {
+    beforeEach(() => {
+      restore("mongo-4");
+      cy.signInAsAdmin();
+
+      cy.visit("/question/new");
+      cy.findByText("Custom question").click();
+      cy.findByText("QA Mongo4").click();
+      cy.findByText("Orders").click();
+    });
+
+    it("should be able to compare two fields using filter expression (metabase#17963)", () => {
+      cy.findByText("Add filters to narrow your answer").click();
+
+      popover()
+        .contains("Custom Expression")
+        .click();
+
+      typeAndSelect([
+        { string: "dis", field: "Discount" },
+        { string: "> qu", field: "Quantity" },
+      ]);
+
+      cy.button("Done").click();
+
+      cy.findByText("Discount > Quantity");
+
+      cy.findByText("Pick the metric you want to see").click();
+      cy.findByText("Count of rows").click();
+
+      visualize();
+
+      cy.get(".ScalarValue").contains("1,337");
+    });
+  });
+
+  function typeAndSelect(arr) {
+    arr.forEach(({ string, field }) => {
+      cy.get(".ace_text-input").type(string);
+
+      popover()
+        .contains(field)
+        .click();
+    });
+  }
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/18207-string-min-max.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/18207-string-min-max.cy.spec.js
deleted file mode 100644
index a056799442c8dbf2835c60381c7fae6bcd68cb1f..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/18207-string-min-max.cy.spec.js
+++ /dev/null
@@ -1,97 +0,0 @@
-import {
-  enterCustomColumnDetails,
-  popover,
-  restore,
-  visualize,
-} from "__support__/e2e/cypress";
-
-describe("issue 18207", () => {
-  beforeEach(() => {
-    cy.intercept("POST", "/api/dataset").as("dataset");
-
-    restore();
-    cy.signInAsAdmin();
-  });
-
-  it("should be possible to use MIN on a string column (metabase#18207)", () => {
-    cy.visit("/question/new");
-    cy.contains("Custom question").click();
-    cy.contains("Sample Database").click();
-    cy.contains("Products").click();
-
-    cy.contains("Pick the metric").click();
-
-    cy.contains("Minimum of").click();
-    cy.findByText("Price");
-    cy.findByText("Rating");
-    cy.contains("Category").click();
-
-    visualize();
-
-    cy.findByText("Doohickey");
-  });
-
-  it("should be possible to use MAX on a string column (metabase#18207)", () => {
-    cy.visit("/question/new");
-    cy.contains("Custom question").click();
-    cy.contains("Sample Database").click();
-    cy.contains("Products").click();
-
-    cy.contains("Pick the metric").click();
-
-    cy.contains("Maximum of").click();
-    cy.findByText("Price");
-    cy.findByText("Rating");
-    cy.contains("Category").click();
-
-    visualize();
-
-    cy.findByText("Widget");
-  });
-
-  it("should be not possible to use AVERAGE on a string column (metabase#18207)", () => {
-    cy.visit("/question/new");
-    cy.contains("Custom question").click();
-    cy.contains("Sample Database").click();
-    cy.contains("Products").click();
-
-    cy.contains("Pick the metric").click();
-
-    cy.contains("Average of").click();
-    cy.findByText("Price");
-    cy.findByText("Rating");
-    cy.findByText("Category").should("not.exist");
-  });
-
-  it("should be possible to group by a string expression (metabase#18207)", () => {
-    cy.visit("/question/new");
-    cy.contains("Custom question").click();
-    cy.contains("Sample Database").click();
-    cy.contains("Products").click();
-
-    cy.contains("Pick the metric").click();
-    popover()
-      .contains("Custom Expression")
-      .click();
-    popover().within(() => {
-      enterCustomColumnDetails({ formula: "Max([Vendor])" });
-      cy.findByPlaceholderText("Name (required)").type("LastVendor");
-      cy.findByText("Done").click();
-    });
-
-    cy.contains("Pick a column to group by").click();
-    popover()
-      .contains("Category")
-      .click();
-
-    visualize();
-
-    // Why is it not a table?
-    cy.contains("Settings").click();
-    cy.contains("Bar options").click();
-    cy.get("[data-testid=Table-button]").click();
-    cy.contains("Done").click();
-
-    cy.findByText("Zemlak-Wiegand");
-  });
-});
diff --git a/frontend/test/metabase/scenarios/question/reproductions/18207-string-min-max.js b/frontend/test/metabase/scenarios/question/reproductions/18207-string-min-max.js
new file mode 100644
index 0000000000000000000000000000000000000000..5760630808e153f625f7c6301d140e5e1433ab9a
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/18207-string-min-max.js
@@ -0,0 +1,99 @@
+import {
+  enterCustomColumnDetails,
+  popover,
+  restore,
+  visualize,
+} from "__support__/e2e/cypress";
+
+export function issue18207() {
+  describe("issue 18207", () => {
+    beforeEach(() => {
+      cy.intercept("POST", "/api/dataset").as("dataset");
+
+      restore();
+      cy.signInAsAdmin();
+    });
+
+    it("should be possible to use MIN on a string column (metabase#18207)", () => {
+      cy.visit("/question/new");
+      cy.contains("Custom question").click();
+      cy.contains("Sample Database").click();
+      cy.contains("Products").click();
+
+      cy.contains("Pick the metric").click();
+
+      cy.contains("Minimum of").click();
+      cy.findByText("Price");
+      cy.findByText("Rating");
+      cy.contains("Category").click();
+
+      visualize();
+
+      cy.findByText("Doohickey");
+    });
+
+    it("should be possible to use MAX on a string column (metabase#18207)", () => {
+      cy.visit("/question/new");
+      cy.contains("Custom question").click();
+      cy.contains("Sample Database").click();
+      cy.contains("Products").click();
+
+      cy.contains("Pick the metric").click();
+
+      cy.contains("Maximum of").click();
+      cy.findByText("Price");
+      cy.findByText("Rating");
+      cy.contains("Category").click();
+
+      visualize();
+
+      cy.findByText("Widget");
+    });
+
+    it("should be not possible to use AVERAGE on a string column (metabase#18207)", () => {
+      cy.visit("/question/new");
+      cy.contains("Custom question").click();
+      cy.contains("Sample Database").click();
+      cy.contains("Products").click();
+
+      cy.contains("Pick the metric").click();
+
+      cy.contains("Average of").click();
+      cy.findByText("Price");
+      cy.findByText("Rating");
+      cy.findByText("Category").should("not.exist");
+    });
+
+    it("should be possible to group by a string expression (metabase#18207)", () => {
+      cy.visit("/question/new");
+      cy.contains("Custom question").click();
+      cy.contains("Sample Database").click();
+      cy.contains("Products").click();
+
+      cy.contains("Pick the metric").click();
+      popover()
+        .contains("Custom Expression")
+        .click();
+      popover().within(() => {
+        enterCustomColumnDetails({ formula: "Max([Vendor])" });
+        cy.findByPlaceholderText("Name (required)").type("LastVendor");
+        cy.findByText("Done").click();
+      });
+
+      cy.contains("Pick a column to group by").click();
+      popover()
+        .contains("Category")
+        .click();
+
+      visualize();
+
+      // Why is it not a table?
+      cy.contains("Settings").click();
+      cy.contains("Bar options").click();
+      cy.get("[data-testid=Table-button]").click();
+      cy.contains("Done").click();
+
+      cy.findByText("Zemlak-Wiegand");
+    });
+  });
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.cy.spec.js
deleted file mode 100644
index e9c7ce1dad92a38a875cb49d72d5763092edd067..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.cy.spec.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import {
-  restore,
-  popover,
-  openNavigationSidebar,
-  visitQuestion,
-} from "__support__/e2e/cypress";
-
-describe("18978, 18977", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-  });
-
-  it("should not display query editing controls and 'Browse Data' link", () => {
-    cy.createQuestion({
-      query: {
-        "source-table": "card__1",
-      },
-    }).then(({ body: { id } }) => {
-      cy.signIn("nodata");
-      visitQuestion(id);
-      openNavigationSidebar();
-
-      cy.findByText(/Browse data/i).should("not.exist");
-      cy.icon("add").click();
-
-      popover().within(() => {
-        cy.findByText("Question").should("not.exist");
-        cy.findByText(/SQL query/).should("not.exist");
-        cy.findByText(/Native query/).should("not.exist");
-      });
-
-      cy.findByTestId("qb-header-action-panel").within(() => {
-        cy.icon("notebook").should("not.exist");
-        cy.findByText("Filter").should("not.exist");
-        cy.findByText("Summarize").should("not.exist");
-      });
-      cy.findByTestId("viz-type-button").should("not.exist");
-      cy.findByTestId("viz-settings-button").should("not.exist");
-    });
-  });
-});
diff --git a/frontend/test/metabase/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.js b/frontend/test/metabase/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.js
new file mode 100644
index 0000000000000000000000000000000000000000..d888b718a3082a340f5824d850f35bd06c55d087
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.js
@@ -0,0 +1,44 @@
+import {
+  restore,
+  popover,
+  openNavigationSidebar,
+  visitQuestion,
+} from "__support__/e2e/cypress";
+
+export function issue18978() {
+  describe("18978, 18977", () => {
+    beforeEach(() => {
+      restore();
+      cy.signInAsAdmin();
+    });
+
+    it("should not display query editing controls and 'Browse Data' link", () => {
+      cy.createQuestion({
+        query: {
+          "source-table": "card__1",
+        },
+      }).then(({ body: { id } }) => {
+        cy.signIn("nodata");
+        visitQuestion(id);
+        openNavigationSidebar();
+
+        cy.findByText(/Browse data/i).should("not.exist");
+        cy.icon("add").click();
+
+        popover().within(() => {
+          cy.findByText("Question").should("not.exist");
+          cy.findByText(/SQL query/).should("not.exist");
+          cy.findByText(/Native query/).should("not.exist");
+        });
+
+        cy.findByTestId("qb-header-action-panel").within(() => {
+          cy.icon("notebook").should("not.exist");
+          cy.findByText("Filter").should("not.exist");
+          cy.findByText("Summarize").should("not.exist");
+        });
+        cy.findByTestId("viz-type-button").should("not.exist");
+        cy.findByTestId("viz-settings-button").should("not.exist");
+      });
+    });
+  });
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/19341-disabled-nested-queries.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/19341-disabled-nested-queries.cy.spec.js
deleted file mode 100644
index e2f254dc636d94654b32034f68071010ffb0151b..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/19341-disabled-nested-queries.cy.spec.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import { restore, mockSessionProperty, popover } from "__support__/e2e/cypress";
-
-describe("issue 19341", () => {
-  const TEST_NATIVE_QUESTION_NAME = "Native";
-
-  beforeEach(() => {
-    restore();
-    mockSessionProperty("enable-nested-queries", false);
-    cy.signInAsAdmin();
-    cy.createNativeQuestion({
-      name: TEST_NATIVE_QUESTION_NAME,
-      native: {
-        query: "SELECT * FROM products",
-      },
-    });
-    cy.intercept("POST", "/api/card/*/query").as("cardQuery");
-  });
-
-  it("should correctly disable nested queries (metabase#19341)", () => {
-    // Test "Saved Questions" table is hidden in QB data selector
-    cy.visit("/question/new");
-    cy.findByText("Custom question").click();
-    popover().within(() => {
-      // Wait until picker init
-      // When working as expected, the test environment only has "Sample Database" DB
-      // So it should automatically select it as a database
-      // When "Orders" table name appears, it means the picker has selected the sample database
-      cy.findByText("Loading...").should("not.exist");
-      cy.findByText("Orders");
-
-      cy.findByText("Sample Database").click(); // go back to DB list
-      cy.findByText("Saved Questions").should("not.exist");
-
-      // Ensure the search doesn't list saved questions
-      cy.findByPlaceholderText("Search for a table…").type("Ord");
-      cy.findByText("Loading...").should("not.exist");
-      cy.findAllByText(/Saved question in/i).should("not.exist");
-      cy.findAllByText(/Table in/i).should("exist");
-      cy.icon("close").click();
-
-      cy.findByText("Sample Database").click();
-      cy.findByText("Orders").click();
-    });
-
-    cy.icon("join_left_outer").click();
-    popover().within(() => {
-      cy.findByText("Sample Database").click(); // go back to DB list
-      cy.findByText("Saved Questions").should("not.exist");
-    });
-
-    // Test "Explore results" button is hidden for native questions
-    cy.visit("/collection/root");
-    cy.findByText(TEST_NATIVE_QUESTION_NAME).click();
-    cy.wait("@cardQuery");
-    cy.findByText("Explore results").should("not.exist");
-  });
-});
diff --git a/frontend/test/metabase/scenarios/question/reproductions/19341-disabled-nested-queries.js b/frontend/test/metabase/scenarios/question/reproductions/19341-disabled-nested-queries.js
new file mode 100644
index 0000000000000000000000000000000000000000..7583c4226a54c243e29c1441a0f083430c2daaad
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/19341-disabled-nested-queries.js
@@ -0,0 +1,59 @@
+import { restore, mockSessionProperty, popover } from "__support__/e2e/cypress";
+
+export function issue19341() {
+  describe("issue 19341", () => {
+    const TEST_NATIVE_QUESTION_NAME = "Native";
+
+    beforeEach(() => {
+      restore();
+      mockSessionProperty("enable-nested-queries", false);
+      cy.signInAsAdmin();
+      cy.createNativeQuestion({
+        name: TEST_NATIVE_QUESTION_NAME,
+        native: {
+          query: "SELECT * FROM products",
+        },
+      });
+      cy.intercept("POST", "/api/card/*/query").as("cardQuery");
+    });
+
+    it("should correctly disable nested queries (metabase#19341)", () => {
+      // Test "Saved Questions" table is hidden in QB data selector
+      cy.visit("/question/new");
+      cy.findByText("Custom question").click();
+      popover().within(() => {
+        // Wait until picker init
+        // When working as expected, the test environment only has "Sample Database" DB
+        // So it should automatically select it as a database
+        // When "Orders" table name appears, it means the picker has selected the sample database
+        cy.findByText("Loading...").should("not.exist");
+        cy.findByText("Orders");
+
+        cy.findByText("Sample Database").click(); // go back to DB list
+        cy.findByText("Saved Questions").should("not.exist");
+
+        // Ensure the search doesn't list saved questions
+        cy.findByPlaceholderText("Search for a table…").type("Ord");
+        cy.findByText("Loading...").should("not.exist");
+        cy.findAllByText(/Saved question in/i).should("not.exist");
+        cy.findAllByText(/Table in/i).should("exist");
+        cy.icon("close").click();
+
+        cy.findByText("Sample Database").click();
+        cy.findByText("Orders").click();
+      });
+
+      cy.icon("join_left_outer").click();
+      popover().within(() => {
+        cy.findByText("Sample Database").click(); // go back to DB list
+        cy.findByText("Saved Questions").should("not.exist");
+      });
+
+      // Test "Explore results" button is hidden for native questions
+      cy.visit("/collection/root");
+      cy.findByText(TEST_NATIVE_QUESTION_NAME).click();
+      cy.wait("@cardQuery");
+      cy.findByText("Explore results").should("not.exist");
+    });
+  });
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/19742-data-picker-closes-after-hiding-table.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/19742-data-picker-closes-after-hiding-table.cy.spec.js
deleted file mode 100644
index e418ebcaf5c6d7acc1ece668fca777cca695a894..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/19742-data-picker-closes-after-hiding-table.cy.spec.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import {
-  restore,
-  popover,
-  openNavigationSidebar,
-} from "__support__/e2e/cypress";
-
-describe("issue 19742", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-  });
-
-  // In order to reproduce the issue, it's important to only use in-app links
-  // and don't refresh the app state (like by doing cy.visit)
-  it("shouldn't auto-close the data selector after a table was hidden", () => {
-    cy.visit("/");
-    cy.findByText("New").click();
-    selectFromDropdown("Question");
-    selectFromDropdown("Sample Database");
-
-    openNavigationSidebar();
-    cy.icon("gear").click();
-    selectFromDropdown("Admin settings");
-
-    cy.findByText("Data Model").click();
-    hideTable("Orders");
-    cy.findByText("Exit admin").click();
-
-    cy.findByText("New").click();
-    selectFromDropdown("Question");
-    selectFromDropdown("Sample Database");
-
-    popover().within(() => {
-      cy.findByText("Products");
-      cy.findByText("Reviews");
-      cy.findByText("People");
-      cy.findByText("Orders").should("not.exist");
-    });
-  });
-});
-
-function selectFromDropdown(optionName) {
-  popover()
-    .findByText(optionName)
-    .click();
-}
-
-function hideTable(tableName) {
-  cy.findByText(tableName)
-    .find(".Icon-eye_crossed_out")
-    .click({ force: true });
-}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/19742-data-picker-closes-after-hiding-table.js b/frontend/test/metabase/scenarios/question/reproductions/19742-data-picker-closes-after-hiding-table.js
new file mode 100644
index 0000000000000000000000000000000000000000..7010fbbacc390f9b3759e927f6fefaaee06a83c8
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/19742-data-picker-closes-after-hiding-table.js
@@ -0,0 +1,54 @@
+import {
+  restore,
+  popover,
+  openNavigationSidebar,
+} from "__support__/e2e/cypress";
+
+export function issue19742() {
+  describe("issue 19742", () => {
+    beforeEach(() => {
+      restore();
+      cy.signInAsAdmin();
+    });
+
+    // In order to reproduce the issue, it's important to only use in-app links
+    // and don't refresh the app state (like by doing cy.visit)
+    it("shouldn't auto-close the data selector after a table was hidden", () => {
+      cy.visit("/");
+      cy.findByText("New").click();
+      selectFromDropdown("Question");
+      selectFromDropdown("Sample Database");
+
+      openNavigationSidebar();
+      cy.icon("gear").click();
+      selectFromDropdown("Admin settings");
+
+      cy.findByText("Data Model").click();
+      hideTable("Orders");
+      cy.findByText("Exit admin").click();
+
+      cy.findByText("New").click();
+      selectFromDropdown("Question");
+      selectFromDropdown("Sample Database");
+
+      popover().within(() => {
+        cy.findByText("Products");
+        cy.findByText("Reviews");
+        cy.findByText("People");
+        cy.findByText("Orders").should("not.exist");
+      });
+    });
+  });
+
+  function selectFromDropdown(optionName) {
+    popover()
+      .findByText(optionName)
+      .click();
+  }
+
+  function hideTable(tableName) {
+    cy.findByText(tableName)
+      .find(".Icon-eye_crossed_out")
+      .click({ force: true });
+  }
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/20551-filter-starts-with.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/20551-filter-starts-with.cy.spec.js
deleted file mode 100644
index f219a0716ed1685e3cbba98b08c89c876f0dd89d..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/20551-filter-starts-with.cy.spec.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import { restore, openProductsTable, filter } from "__support__/e2e/cypress";
-
-describe("issue 20551", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-  });
-
-  it("should allow filtering with includes, rather than starts with (metabase#20551)", () => {
-    openProductsTable({ mode: "notebook" });
-    filter({ mode: "notebook" });
-    cy.findByText("Category").click();
-
-    // Make sure input field is auto-focused
-    cy.focused()
-      .should("have.attr", "placeholder", "Search the list")
-      .type("i");
-
-    // All categories that contain `i`
-    cy.findByText("Doohickey");
-    cy.findByText("Gizmo");
-    cy.findByText("Widget");
-
-    cy.findByText("Gadget").should("not.exist");
-  });
-});
diff --git a/frontend/test/metabase/scenarios/question/reproductions/20551-filter-starts-with.js b/frontend/test/metabase/scenarios/question/reproductions/20551-filter-starts-with.js
new file mode 100644
index 0000000000000000000000000000000000000000..1ab42d01838afb7a0bc11a54f82524dad61367b3
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/20551-filter-starts-with.js
@@ -0,0 +1,28 @@
+import { restore, openProductsTable, filter } from "__support__/e2e/cypress";
+
+export function issue20551() {
+  describe("issue 20551", () => {
+    beforeEach(() => {
+      restore();
+      cy.signInAsAdmin();
+    });
+
+    it("should allow filtering with includes, rather than starts with (metabase#20551)", () => {
+      openProductsTable({ mode: "notebook" });
+      filter({ mode: "notebook" });
+      cy.findByText("Category").click();
+
+      // Make sure input field is auto-focused
+      cy.focused()
+        .should("have.attr", "placeholder", "Search the list")
+        .type("i");
+
+      // All categories that contain `i`
+      cy.findByText("Doohickey");
+      cy.findByText("Gizmo");
+      cy.findByText("Widget");
+
+      cy.findByText("Gadget").should("not.exist");
+    });
+  });
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/20627-nested-long-names-wrong-aliases.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/20627-nested-long-names-wrong-aliases.cy.spec.js
deleted file mode 100644
index f424689d8182dca04d8119dfcbec77dfc861205c..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/20627-nested-long-names-wrong-aliases.cy.spec.js
+++ /dev/null
@@ -1,60 +0,0 @@
-import {
-  restore,
-  openOrdersTable,
-  popover,
-  enterCustomColumnDetails,
-  visualize,
-} from "__support__/e2e/cypress";
-
-import { SAMPLE_DATABASE } from "__support__/e2e/cypress_sample_database";
-
-const { ORDERS, PRODUCTS_ID } = SAMPLE_DATABASE;
-
-const newColumnName = "Product ID with a very long name";
-const newTableName = "Products with a very long name";
-
-describe("issue 20627", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-
-    renameColumn(ORDERS.PRODUCT_ID, newColumnName);
-    renameTable(PRODUCTS_ID, newTableName);
-  });
-
-  it("nested queries should handle long column and/or table names (metabase#20627)", () => {
-    openOrdersTable({ mode: "notebook" });
-
-    cy.findByText("Join data").click();
-    cy.findByText(newTableName).click();
-
-    cy.findByText("Summarize").click();
-    cy.findByText("Count of rows").click();
-
-    cy.findByText("Pick a column to group by").click();
-    popover().within(() => {
-      cy.contains(newTableName).click();
-
-      cy.findByText("Category").click();
-    });
-
-    cy.findByText("Custom column").click();
-    enterCustomColumnDetails({ formula: "1 + 1", name: "Math" });
-    cy.button("Done").click();
-
-    visualize();
-
-    cy.get(".cellData")
-      .should("contain", "Math")
-      .and("contain", "Doohickey")
-      .and("contain", "3,976");
-  });
-});
-
-function renameColumn(columnId, name) {
-  cy.request("PUT", `/api/field/${columnId}`, { display_name: name });
-}
-
-function renameTable(tableId, name) {
-  cy.request("PUT", `/api/table/${tableId}`, { display_name: name });
-}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/20627-nested-long-names-wrong-aliases.js b/frontend/test/metabase/scenarios/question/reproductions/20627-nested-long-names-wrong-aliases.js
new file mode 100644
index 0000000000000000000000000000000000000000..cfe05d44e0b36390de892e05b051f7b88cbd1d82
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/20627-nested-long-names-wrong-aliases.js
@@ -0,0 +1,62 @@
+import {
+  restore,
+  openOrdersTable,
+  popover,
+  enterCustomColumnDetails,
+  visualize,
+} from "__support__/e2e/cypress";
+
+import { SAMPLE_DATABASE } from "__support__/e2e/cypress_sample_database";
+
+const { ORDERS, PRODUCTS_ID } = SAMPLE_DATABASE;
+
+const newColumnName = "Product ID with a very long name";
+const newTableName = "Products with a very long name";
+
+export function issue20627() {
+  describe("issue 20627", () => {
+    beforeEach(() => {
+      restore();
+      cy.signInAsAdmin();
+
+      renameColumn(ORDERS.PRODUCT_ID, newColumnName);
+      renameTable(PRODUCTS_ID, newTableName);
+    });
+
+    it("nested queries should handle long column and/or table names (metabase#20627)", () => {
+      openOrdersTable({ mode: "notebook" });
+
+      cy.findByText("Join data").click();
+      cy.findByText(newTableName).click();
+
+      cy.findByText("Summarize").click();
+      cy.findByText("Count of rows").click();
+
+      cy.findByText("Pick a column to group by").click();
+      popover().within(() => {
+        cy.contains(newTableName).click();
+
+        cy.findByText("Category").click();
+      });
+
+      cy.findByText("Custom column").click();
+      enterCustomColumnDetails({ formula: "1 + 1", name: "Math" });
+      cy.button("Done").click();
+
+      visualize();
+
+      cy.get(".cellData")
+        .should("contain", "Math")
+        .and("contain", "Doohickey")
+        .and("contain", "3,976");
+    });
+  });
+
+  function renameColumn(columnId, name) {
+    cy.request("PUT", `/api/field/${columnId}`, { display_name: name });
+  }
+
+  function renameTable(tableId, name) {
+    cy.request("PUT", `/api/table/${tableId}`, { display_name: name });
+  }
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/20683-postgres-current-quarter.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/20683-postgres-current-quarter.cy.spec.js
deleted file mode 100644
index 4bb803ac9472c2f21e01b64173e02a9887d8715e..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/20683-postgres-current-quarter.cy.spec.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import { restore, visualize } from "__support__/e2e/cypress";
-
-describe("issue 20683", () => {
-  beforeEach(() => {
-    restore("postgres-12");
-    cy.signInAsAdmin();
-
-    cy.visit("/");
-    cy.findByText("New").click();
-    cy.findByText("Question")
-      .should("be.visible")
-      .click();
-
-    cy.findByText("QA Postgres12").click();
-    cy.findByText("Orders").click();
-  });
-
-  it("should filter postgres with the 'current quarter' filter (metabase#20683)", () => {
-    cy.findByText("Add filters to narrow your answer").click();
-
-    cy.findByText("Created At").click();
-
-    cy.findByText("Previous").click();
-    cy.findByText("Current").click();
-
-    cy.findByText("Day").click();
-    cy.findByText("Quarter").click();
-
-    cy.button("Add filter").click();
-
-    visualize();
-
-    // We don't have entries for the current quarter so we expect no results
-    cy.findByText("No results!");
-  });
-});
diff --git a/frontend/test/metabase/scenarios/question/reproductions/20683-postgres-current-quarter.js b/frontend/test/metabase/scenarios/question/reproductions/20683-postgres-current-quarter.js
new file mode 100644
index 0000000000000000000000000000000000000000..ae435e78cb705f6e2054cb3cdd5cb39a662b2e4e
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/20683-postgres-current-quarter.js
@@ -0,0 +1,38 @@
+import { restore, visualize } from "__support__/e2e/cypress";
+
+export function issue20683() {
+  describe("issue 20683", () => {
+    beforeEach(() => {
+      restore("postgres-12");
+      cy.signInAsAdmin();
+
+      cy.visit("/");
+      cy.findByText("New").click();
+      cy.findByText("Question")
+        .should("be.visible")
+        .click();
+
+      cy.findByText("QA Postgres12").click();
+      cy.findByText("Orders").click();
+    });
+
+    it("should filter postgres with the 'current quarter' filter (metabase#20683)", () => {
+      cy.findByText("Add filters to narrow your answer").click();
+
+      cy.findByText("Created At").click();
+
+      cy.findByText("Previous").click();
+      cy.findByText("Current").click();
+
+      cy.findByText("Day").click();
+      cy.findByText("Quarter").click();
+
+      cy.button("Add filter").click();
+
+      visualize();
+
+      // We don't have entries for the current quarter so we expect no results
+      cy.findByText("No results!");
+    });
+  });
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/4482-temporal-min-max.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/4482-temporal-min-max.cy.spec.js
deleted file mode 100644
index 1594606807015a06089dfb6eb9f25d25ebbac0a7..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/4482-temporal-min-max.cy.spec.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import {
-  restore,
-  visualize,
-  openNotebookEditor,
-} from "__support__/e2e/cypress";
-
-describe("issue 4482", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-
-    openNotebookEditor();
-    cy.contains("Sample Database").click();
-    cy.contains("Products").click();
-  });
-
-  it("should be possible to summarize min of a temporal column (metabase#4482-1)", () => {
-    pickMetric("Minimum of");
-
-    cy.contains("Created At").click();
-
-    visualize();
-
-    cy.findByText("April 1, 2016, 12:00 AM");
-  });
-
-  it("should be possible to summarize max of a temporal column (metabase#4482-2)", () => {
-    pickMetric("Maximum of");
-
-    cy.contains("Created At").click();
-
-    visualize();
-
-    cy.findByText("April 1, 2019, 12:00 AM");
-  });
-
-  it("should be not possible to average a temporal column (metabase#4482-3)", () => {
-    pickMetric("Average of");
-
-    cy.findByText("Created At").should("not.exist");
-  });
-});
-
-function pickMetric(metric) {
-  cy.contains("Pick the metric").click();
-
-  cy.contains(metric).click();
-  cy.findByText("Price");
-  cy.findByText("Rating");
-}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/4482-temporal-min-max.js b/frontend/test/metabase/scenarios/question/reproductions/4482-temporal-min-max.js
new file mode 100644
index 0000000000000000000000000000000000000000..e0bdc6e40ffbed9fe99ea69b8bfa4c21ad863c6e
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/4482-temporal-min-max.js
@@ -0,0 +1,52 @@
+import {
+  restore,
+  visualize,
+  openNotebookEditor,
+} from "__support__/e2e/cypress";
+
+export function issue4482() {
+  describe("issue 4482", () => {
+    beforeEach(() => {
+      restore();
+      cy.signInAsAdmin();
+
+      openNotebookEditor();
+      cy.contains("Sample Database").click();
+      cy.contains("Products").click();
+    });
+
+    it("should be possible to summarize min of a temporal column (metabase#4482-1)", () => {
+      pickMetric("Minimum of");
+
+      cy.contains("Created At").click();
+
+      visualize();
+
+      cy.findByText("April 1, 2016, 12:00 AM");
+    });
+
+    it("should be possible to summarize max of a temporal column (metabase#4482-2)", () => {
+      pickMetric("Maximum of");
+
+      cy.contains("Created At").click();
+
+      visualize();
+
+      cy.findByText("April 1, 2019, 12:00 AM");
+    });
+
+    it("should be not possible to average a temporal column (metabase#4482-3)", () => {
+      pickMetric("Average of");
+
+      cy.findByText("Created At").should("not.exist");
+    });
+  });
+
+  function pickMetric(metric) {
+    cy.contains("Pick the metric").click();
+
+    cy.contains(metric).click();
+    cy.findByText("Price");
+    cy.findByText("Rating");
+  }
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/6239-sort-using-cust-exp.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/6239-sort-using-cust-exp.cy.spec.js
deleted file mode 100644
index 6b76abe6eeb367e9c41c3153768fc8eab875d9cf..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/6239-sort-using-cust-exp.cy.spec.js
+++ /dev/null
@@ -1,74 +0,0 @@
-import {
-  openOrdersTable,
-  popover,
-  restore,
-  visualize,
-  summarize,
-} from "__support__/e2e/cypress";
-
-describe("issue 6239", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-
-    openOrdersTable({ mode: "notebook" });
-
-    summarize({ mode: "notebook" });
-    cy.findByText("Custom Expression").click();
-
-    cy.get(".ace_text-input")
-      .type("CountIf([Total] > 0)")
-      .blur();
-
-    cy.findByPlaceholderText("Name (required)").type("CE");
-    cy.button("Done").click();
-
-    cy.findByText("Pick a column to group by").click();
-    popover()
-      .contains("Created At")
-      .first()
-      .click();
-  });
-
-  it("should be possible to sort by using custom expression (metabase#6239)", () => {
-    cy.findByText("Sort").click();
-    popover()
-      .contains(/^CE$/)
-      .click();
-
-    visualize();
-
-    // Line chart renders initially. Switch to the table view.
-    cy.icon("table2").click();
-
-    cy.get(".cellData")
-      .eq(1)
-      .should("contain", "CE")
-      .and("have.descendants", ".Icon-chevronup");
-
-    cy.get(".cellData")
-      .eq(3)
-      .invoke("text")
-      .should("eq", "1");
-
-    // Go back to the notebook editor
-    cy.icon("notebook").click();
-
-    // Sort descending this time
-    cy.icon("arrow_up").click();
-    cy.icon("arrow_up").should("not.exist");
-    cy.icon("arrow_down");
-
-    visualize();
-
-    cy.get(".cellData")
-      .eq(1)
-      .should("contain", "CE")
-      .and("have.descendants", ".Icon-chevrondown");
-
-    cy.get(".cellData")
-      .eq(3)
-      .invoke("text")
-      .should("eq", "584");
-  });
-});
diff --git a/frontend/test/metabase/scenarios/question/reproductions/6239-sort-using-cust-exp.js b/frontend/test/metabase/scenarios/question/reproductions/6239-sort-using-cust-exp.js
new file mode 100644
index 0000000000000000000000000000000000000000..37ee3104c5b8ba477a2ab21f2ab4c2033acc097a
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/6239-sort-using-cust-exp.js
@@ -0,0 +1,76 @@
+import {
+  openOrdersTable,
+  popover,
+  restore,
+  visualize,
+  summarize,
+} from "__support__/e2e/cypress";
+
+export function issue6239() {
+  describe("issue 6239", () => {
+    beforeEach(() => {
+      restore();
+      cy.signInAsAdmin();
+
+      openOrdersTable({ mode: "notebook" });
+
+      summarize({ mode: "notebook" });
+      cy.findByText("Custom Expression").click();
+
+      cy.get(".ace_text-input")
+        .type("CountIf([Total] > 0)")
+        .blur();
+
+      cy.findByPlaceholderText("Name (required)").type("CE");
+      cy.button("Done").click();
+
+      cy.findByText("Pick a column to group by").click();
+      popover()
+        .contains("Created At")
+        .first()
+        .click();
+    });
+
+    it("should be possible to sort by using custom expression (metabase#6239)", () => {
+      cy.findByText("Sort").click();
+      popover()
+        .contains(/^CE$/)
+        .click();
+
+      visualize();
+
+      // Line chart renders initially. Switch to the table view.
+      cy.icon("table2").click();
+
+      cy.get(".cellData")
+        .eq(1)
+        .should("contain", "CE")
+        .and("have.descendants", ".Icon-chevronup");
+
+      cy.get(".cellData")
+        .eq(3)
+        .invoke("text")
+        .should("eq", "1");
+
+      // Go back to the notebook editor
+      cy.icon("notebook").click();
+
+      // Sort descending this time
+      cy.icon("arrow_up").click();
+      cy.icon("arrow_up").should("not.exist");
+      cy.icon("arrow_down");
+
+      visualize();
+
+      cy.get(".cellData")
+        .eq(1)
+        .should("contain", "CE")
+        .and("have.descendants", ".Icon-chevrondown");
+
+      cy.get(".cellData")
+        .eq(3)
+        .invoke("text")
+        .should("eq", "584");
+    });
+  });
+}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/9027-new-questions-not-in-saved-questions-immediately.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/9027-new-questions-not-in-saved-questions-immediately.cy.spec.js
deleted file mode 100644
index f9c9841dc3dbba699026e8e5446baa7cfc22a600..0000000000000000000000000000000000000000
--- a/frontend/test/metabase/scenarios/question/reproductions/9027-new-questions-not-in-saved-questions-immediately.cy.spec.js
+++ /dev/null
@@ -1,90 +0,0 @@
-import {
-  restore,
-  popover,
-  openNativeEditor,
-  openNotebookEditor,
-  openNavigationSidebar,
-  navigationSidebar,
-} from "__support__/e2e/cypress";
-
-const QUESTION_NAME = "Foo";
-
-describe("issue 9027", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-
-    cy.visit("/question/new");
-    cy.findByText("Custom question").click();
-    cy.findByText("Saved Questions").click();
-
-    // Wait for the existing questions to load
-    cy.findByText("Orders");
-
-    openNativeEditor({ fromCurrentPage: true });
-
-    cy.get(".ace_content").type("select 0");
-    cy.get(".NativeQueryEditor .Icon-play").click();
-
-    saveQuestion(QUESTION_NAME);
-  });
-
-  it("should display newly saved question in the 'Saved Questions' list immediately (metabase#9027)", () => {
-    goToSavedQuestionPickerAndAssertQuestion(QUESTION_NAME);
-    openNavigationSidebar();
-    archiveQuestion(QUESTION_NAME);
-    goToSavedQuestionPickerAndAssertQuestion(QUESTION_NAME, false);
-    openNavigationSidebar();
-    unarchiveQuestion(QUESTION_NAME);
-    goToSavedQuestionPickerAndAssertQuestion(QUESTION_NAME);
-  });
-});
-
-function goToSavedQuestionPickerAndAssertQuestion(questionName, exists = true) {
-  openNotebookEditor({ fromCurrentPage: true });
-  cy.findByText("Saved Questions").click();
-
-  cy.findByText(questionName).should(exists ? "exist" : "not.exist");
-}
-
-function saveQuestion(name) {
-  cy.intercept("POST", "/api/card").as("saveQuestion");
-  cy.findByText("Save").click();
-  cy.findByLabelText("Name")
-    .clear()
-    .type(name);
-  cy.button("Save").click();
-  cy.button("Not now").click();
-  cy.wait("@saveQuestion");
-}
-
-function archiveQuestion(questionName) {
-  navigationSidebar()
-    .findByText("Our analytics")
-    .click();
-  openEllipsisMenuFor(questionName);
-  popover()
-    .findByText("Archive")
-    .click();
-}
-
-function unarchiveQuestion(questionName) {
-  navigationSidebar().within(() => {
-    cy.icon("ellipsis").click();
-  });
-  popover()
-    .findByText("View archive")
-    .click();
-  cy.findByText(questionName)
-    .parent()
-    .within(() => {
-      cy.icon("unarchive").click({ force: true });
-    });
-}
-
-function openEllipsisMenuFor(item) {
-  cy.findByText(item)
-    .closest("tr")
-    .find(".Icon-ellipsis")
-    .click({ force: true });
-}
diff --git a/frontend/test/metabase/scenarios/question/reproductions/9027-new-questions-not-in-saved-questions-immediately.js b/frontend/test/metabase/scenarios/question/reproductions/9027-new-questions-not-in-saved-questions-immediately.js
new file mode 100644
index 0000000000000000000000000000000000000000..c2f8d59f738b07d62d4b566cdc941207d4df8f59
--- /dev/null
+++ b/frontend/test/metabase/scenarios/question/reproductions/9027-new-questions-not-in-saved-questions-immediately.js
@@ -0,0 +1,95 @@
+import {
+  restore,
+  popover,
+  openNativeEditor,
+  openNotebookEditor,
+  openNavigationSidebar,
+  navigationSidebar,
+} from "__support__/e2e/cypress";
+
+const QUESTION_NAME = "Foo";
+
+export function issue9027() {
+  describe("issue 9027", () => {
+    beforeEach(() => {
+      restore();
+      cy.signInAsAdmin();
+
+      cy.visit("/question/new");
+      cy.findByText("Custom question").click();
+      cy.findByText("Saved Questions").click();
+
+      // Wait for the existing questions to load
+      cy.findByText("Orders");
+
+      openNativeEditor({ fromCurrentPage: true });
+
+      cy.get(".ace_content").type("select 0");
+      cy.get(".NativeQueryEditor .Icon-play").click();
+
+      saveQuestion(QUESTION_NAME);
+    });
+
+    it("should display newly saved question in the 'Saved Questions' list immediately (metabase#9027)", () => {
+      goToSavedQuestionPickerAndAssertQuestion(QUESTION_NAME);
+      openNavigationSidebar();
+      archiveQuestion(QUESTION_NAME);
+      goToSavedQuestionPickerAndAssertQuestion(QUESTION_NAME, false);
+      openNavigationSidebar();
+      unarchiveQuestion(QUESTION_NAME);
+      goToSavedQuestionPickerAndAssertQuestion(QUESTION_NAME);
+    });
+  });
+
+  function goToSavedQuestionPickerAndAssertQuestion(
+    questionName,
+    exists = true,
+  ) {
+    openNotebookEditor({ fromCurrentPage: true });
+    cy.findByText("Saved Questions").click();
+
+    cy.findByText(questionName).should(exists ? "exist" : "not.exist");
+  }
+
+  function saveQuestion(name) {
+    cy.intercept("POST", "/api/card").as("saveQuestion");
+    cy.findByText("Save").click();
+    cy.findByLabelText("Name")
+      .clear()
+      .type(name);
+    cy.button("Save").click();
+    cy.button("Not now").click();
+    cy.wait("@saveQuestion");
+  }
+
+  function archiveQuestion(questionName) {
+    navigationSidebar()
+      .findByText("Our analytics")
+      .click();
+    openEllipsisMenuFor(questionName);
+    popover()
+      .findByText("Archive")
+      .click();
+  }
+
+  function unarchiveQuestion(questionName) {
+    navigationSidebar().within(() => {
+      cy.icon("ellipsis").click();
+    });
+    popover()
+      .findByText("View archive")
+      .click();
+    cy.findByText(questionName)
+      .parent()
+      .within(() => {
+        cy.icon("unarchive").click({ force: true });
+      });
+  }
+
+  function openEllipsisMenuFor(item) {
+    cy.findByText(item)
+      .closest("tr")
+      .find(".Icon-ellipsis")
+      .click({ force: true });
+  }
+}