From d53b0a7a80568e12d3d139a736f79b92b223386b Mon Sep 17 00:00:00 2001
From: Ryan Laurie <30528226+iethree@users.noreply.github.com>
Date: Tue, 4 Jun 2024 08:06:49 -0600
Subject: [PATCH] Consolidate sharing e2e specs (#43514)

---
 .../sharing/approved-domains.cy.spec.js       |  74 --
 .../10803-timestamp-formatting.cy.spec.js     |  65 --
 ...19-temporal-units-not-formatted.cy.spec.js |  62 --
 ...-syntax-missing-renamed-columns.cy.spec.js | 106 --
 ...-remapped-display-value-dropped.cy.spec.js |  67 --
 ...573-remapped-fields-not-renamed.cy.spec.js |  54 -
 .../18729-date-formatting-x-of-y.cy.spec.js   |  56 --
 ...ative-query-export-column-order.cy.spec.js |  91 --
 .../28834-modified-native-question.cy.spec.js |  47 -
 .../sharing-download-reproductions.cy.spec.js | 512 ++++++++++
 .../sharing/public-sharing.cy.spec.js         |  71 ++
 .../sharing/reproductions.cy.spec.js          | 279 ------
 ...tes-subscription-receives-error.cy.spec.js |  45 -
 ...on-shows-original-question-name.cy.spec.js |  61 --
 ...2-subscription-int64-value-card.cy.spec.js |  59 --
 ...8669-test-email-with-parameters.cy.spec.js |  85 --
 ...ard-nested-card-with-parameters.cy.spec.js |  67 --
 ...subscription-bar-sent-as-scalar.cy.spec.js |  79 --
 ...dates-after-changing-parameters.cy.spec.js |  68 --
 ...ilter-defaults-on-subscriptions.cy.spec.js |  79 --
 ...d-text-filter-asking-for-number.cy.spec.js | 116 ---
 ...6988-embedding-dynamic-settings.cy.spec.js |  67 --
 ...314-new-subscription-form-state.cy.spec.js |  38 -
 .../sharing/sharing-reproductions.cy.spec.js  | 946 ++++++++++++++++++
 24 files changed, 1529 insertions(+), 1665 deletions(-)
 delete mode 100644 e2e/test/scenarios/sharing/approved-domains.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/downloads/reproductions/10803-timestamp-formatting.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/downloads/reproductions/18219-temporal-units-not-formatted.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/downloads/reproductions/18382-old-syntax-missing-renamed-columns.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/downloads/reproductions/18440-remapped-display-value-dropped.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/downloads/reproductions/18573-remapped-fields-not-renamed.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/downloads/reproductions/18729-date-formatting-x-of-y.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/downloads/reproductions/19889-native-query-export-column-order.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/downloads/reproductions/28834-modified-native-question.cy.spec.js
 create mode 100644 e2e/test/scenarios/sharing/downloads/sharing-download-reproductions.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/reproductions.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/reproductions/18009-nodata-creates-subscription-receives-error.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/reproductions/18344-subscription-shows-original-question-name.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/reproductions/18352-subscription-int64-value-card.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/reproductions/18669-test-email-with-parameters.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/reproductions/20393-public-dashboard-nested-card-with-parameters.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/reproductions/21559-subscription-bar-sent-as-scalar.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/reproductions/22524-public-dashboard-updates-after-changing-parameters.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/reproductions/24223-remove-filter-defaults-on-subscriptions.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/reproductions/25473-dashboard-text-filter-asking-for-number.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/reproductions/26988-embedding-dynamic-settings.cy.spec.js
 delete mode 100644 e2e/test/scenarios/sharing/reproductions/30314-new-subscription-form-state.cy.spec.js
 create mode 100644 e2e/test/scenarios/sharing/sharing-reproductions.cy.spec.js

diff --git a/e2e/test/scenarios/sharing/approved-domains.cy.spec.js b/e2e/test/scenarios/sharing/approved-domains.cy.spec.js
deleted file mode 100644
index b3a07f6afc4..00000000000
--- a/e2e/test/scenarios/sharing/approved-domains.cy.spec.js
+++ /dev/null
@@ -1,74 +0,0 @@
-import {
-  ORDERS_QUESTION_ID,
-  ORDERS_DASHBOARD_ID,
-} from "e2e/support/cypress_sample_instance_data";
-import {
-  describeEE,
-  restore,
-  setupSMTP,
-  sidebar,
-  visitQuestion,
-  visitDashboard,
-  setTokenFeatures,
-} from "e2e/support/helpers";
-
-const allowedDomain = "metabase.test";
-const deniedDomain = "metabase.example";
-const deniedEmail = `mailer@${deniedDomain}`;
-const subscriptionError = `You're only allowed to email subscriptions to addresses ending in ${allowedDomain}`;
-const alertError = `You're only allowed to email alerts to addresses ending in ${allowedDomain}`;
-
-describeEE(
-  "scenarios > sharing > approved domains (EE)",
-  { tags: "@external" },
-  () => {
-    beforeEach(() => {
-      restore();
-      cy.signInAsAdmin();
-      setTokenFeatures("all");
-      setupSMTP();
-      setAllowedDomains();
-    });
-
-    it("should validate approved email domains for a question alert", () => {
-      visitQuestion(ORDERS_QUESTION_ID);
-
-      cy.icon("bell").click();
-      cy.button("Set up an alert").click();
-
-      cy.findByRole("heading", { name: "Email" })
-        .closest("li")
-        .within(() => {
-          addEmailRecipient(deniedEmail);
-          cy.findByText(alertError);
-        });
-      cy.button("Done").should("be.disabled");
-    });
-
-    it("should validate approved email domains for a dashboard subscription (metabase#17977)", () => {
-      visitDashboard(ORDERS_DASHBOARD_ID);
-      cy.icon("subscription").click();
-
-      cy.findByRole("heading", { name: "Email it" }).click();
-
-      sidebar().within(() => {
-        addEmailRecipient(deniedEmail);
-
-        // Reproduces metabase#17977
-        cy.button("Send email now").should("be.disabled");
-        cy.button("Done").should("be.disabled");
-        cy.findByText(subscriptionError);
-      });
-    });
-  },
-);
-
-function addEmailRecipient(email) {
-  cy.findByRole("textbox").click().type(`${email}`).blur();
-}
-
-function setAllowedDomains() {
-  cy.request("PUT", "/api/setting/subscription-allowed-domains", {
-    value: allowedDomain,
-  });
-}
diff --git a/e2e/test/scenarios/sharing/downloads/reproductions/10803-timestamp-formatting.cy.spec.js b/e2e/test/scenarios/sharing/downloads/reproductions/10803-timestamp-formatting.cy.spec.js
deleted file mode 100644
index 703fed775be..00000000000
--- a/e2e/test/scenarios/sharing/downloads/reproductions/10803-timestamp-formatting.cy.spec.js
+++ /dev/null
@@ -1,65 +0,0 @@
-import {
-  restore,
-  downloadAndAssert,
-  runNativeQuery,
-} from "e2e/support/helpers";
-
-const testCases = ["csv", "xlsx"];
-
-describe("issue 10803", () => {
-  beforeEach(() => {
-    cy.intercept("POST", "/api/dataset").as("dataset");
-
-    restore();
-    cy.signInAsAdmin();
-
-    cy.createNativeQuestion(
-      {
-        name: "10803",
-        native: {
-          query:
-            "SELECT cast(parsedatetime('2026-06-03', 'yyyy-MM-dd') AS timestamp) AS \"birth_date\", cast(parsedatetime('2026-06-03 23:41:23', 'yyyy-MM-dd HH:mm:ss') AS timestamp) AS \"created_at\"",
-        },
-      },
-      { visitQuestion: true, wrapId: true },
-    );
-  });
-
-  testCases.forEach(fileType => {
-    it(`should format the date properly for ${fileType} in saved questions (metabase#10803)`, () => {
-      cy.get("@questionId").then(questionId => {
-        downloadAndAssert(
-          { fileType, questionId, logResults: true, raw: true },
-          testWorkbookDatetimes,
-        );
-      });
-    });
-
-    it(`should format the date properly for ${fileType} in unsaved questions`, () => {
-      // Add a space at the end of the query to make it "dirty"
-      // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-      cy.contains(/open editor/i).click();
-      cy.get(".ace_editor").type("{movetoend} ");
-
-      runNativeQuery();
-      downloadAndAssert({ fileType, raw: true }, testWorkbookDatetimes);
-    });
-
-    function testWorkbookDatetimes(sheet) {
-      expect(sheet["A1"].v).to.eq("birth_date");
-      expect(sheet["B1"].v).to.eq("created_at");
-
-      // Excel and CSV will have different formats
-      if (fileType === "csv") {
-        expect(sheet["A2"].v).to.eq("June 3, 2026, 12:00 AM");
-        expect(sheet["B2"].v).to.eq("June 3, 2026, 11:41 PM");
-      } else if (fileType === "xlsx") {
-        // We tell the xlsx library to read raw and not parse dates
-        // So for the _date_ format we expect an integer
-        // And for timestamp, we expect a float
-        expect(sheet["A2"].v).to.eq(46176);
-        expect(sheet["B2"].v).to.eq(46176.98707175926);
-      }
-    }
-  });
-});
diff --git a/e2e/test/scenarios/sharing/downloads/reproductions/18219-temporal-units-not-formatted.cy.spec.js b/e2e/test/scenarios/sharing/downloads/reproductions/18219-temporal-units-not-formatted.cy.spec.js
deleted file mode 100644
index 6ed820662c5..00000000000
--- a/e2e/test/scenarios/sharing/downloads/reproductions/18219-temporal-units-not-formatted.cy.spec.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import { restore, downloadAndAssert, visitQuestion } from "e2e/support/helpers";
-
-const { ORDERS, ORDERS_ID } = SAMPLE_DATABASE;
-
-const questionDetails = {
-  name: "18219",
-  query: {
-    "source-table": ORDERS_ID,
-    aggregation: [["count"]],
-    breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": "year" }]],
-  },
-};
-
-const testCases = ["csv", "xlsx"];
-
-describe.skip("issue 18219", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-  });
-
-  testCases.forEach(fileType => {
-    it("should format temporal units on export (metabase#18219)", () => {
-      cy.createQuestion(questionDetails).then(
-        ({ body: { id: questionId } }) => {
-          visitQuestion(questionId);
-
-          cy.findByText("Created At: Year");
-          cy.findByText("2022");
-          cy.findByText("744");
-
-          downloadAndAssert({ fileType, questionId, raw: true }, assertion);
-        },
-      );
-    });
-
-    function assertion(sheet) {
-      expect(sheet["A1"].v).to.eq("Created At: Year");
-
-      if (fileType === "csv") {
-        expect(sheet["A2"].v).to.eq("2022");
-      }
-
-      if (fileType === "xlsx") {
-        /**
-         * Depending on how we end up solving this issue,
-         * the following assertion on the cell type might not be correct.
-         * It's very likely we'll format temporal breakouts as strings.
-         * I.e. we have to take into account Q1, Q2, etc.
-         */
-        // expect(A2.t).to.eq("n");
-
-        /**
-         * Because of the excel date format, we cannot assert on the raw value `v`.
-         * Rather, we have to do it on the parsed value `w`.
-         */
-        expect(sheet["A2"].w).to.eq("2022");
-      }
-    }
-  });
-});
diff --git a/e2e/test/scenarios/sharing/downloads/reproductions/18382-old-syntax-missing-renamed-columns.cy.spec.js b/e2e/test/scenarios/sharing/downloads/reproductions/18382-old-syntax-missing-renamed-columns.cy.spec.js
deleted file mode 100644
index 41769ac3923..00000000000
--- a/e2e/test/scenarios/sharing/downloads/reproductions/18382-old-syntax-missing-renamed-columns.cy.spec.js
+++ /dev/null
@@ -1,106 +0,0 @@
-import { SAMPLE_DB_ID } from "e2e/support/cypress_data";
-import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import {
-  restore,
-  visitQuestionAdhoc,
-  downloadAndAssert,
-} from "e2e/support/helpers";
-
-const { REVIEWS, REVIEWS_ID, PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE;
-
-/**
- * This question might seem a bit overwhelming at the first sight.
- * The whole point of this repro was to try to cover as much of the old syntax as possible.
- * We want to make sure it still works when loaded into a new(er) Metabase version.
- */
-
-const questionDetails = {
-  dataset_query: {
-    database: SAMPLE_DB_ID,
-    type: "query",
-    query: {
-      "source-table": REVIEWS_ID,
-      joins: [
-        {
-          fields: [["joined-field", "Products", ["field-id", PRODUCTS.TITLE]]],
-          "source-table": PRODUCTS_ID,
-          condition: [
-            "=",
-            ["field-id", REVIEWS.PRODUCT_ID],
-            ["joined-field", "Products", ["field-id", PRODUCTS.ID]],
-          ],
-          alias: "Products",
-        },
-      ],
-      filter: ["and", ["=", ["field-id", REVIEWS.RATING], 4]],
-      "order-by": [
-        ["asc", ["joined-field", "Products", ["field-id", PRODUCTS.TITLE]]],
-      ],
-      fields: [
-        ["field-id", REVIEWS.ID],
-        ["field-id", REVIEWS.REVIEWER],
-      ],
-      limit: 5,
-    },
-  },
-  display: "table",
-  visualization_settings: {
-    column_settings: {
-      [`["ref",["field",${REVIEWS.ID},null]]`]: {
-        column_title: "MOD:ID",
-      },
-      [`["ref",["field",${REVIEWS.REVIEWER},null]]`]: {
-        column_title: "MOD:Reviewer",
-      },
-      [`["ref",["field",${PRODUCTS.TITLE},null]]`]: {
-        column_title: "MOD:Title",
-      },
-    },
-    // Reorder columns
-    "table.columns": [
-      {
-        name: "TITLE",
-        fieldRef: ["joined-field", "Products", ["field-id", PRODUCTS.TITLE]],
-        enabled: true,
-      },
-      {
-        name: "ID",
-        fieldRef: ["field-id", REVIEWS.ID],
-        enabled: true,
-      },
-      {
-        name: "REVIEWER",
-        fieldRef: ["field-id", REVIEWS.REVIEWER],
-        enabled: true,
-      },
-    ],
-  },
-};
-
-const testCases = ["csv", "xlsx"];
-
-testCases.forEach(fileType => {
-  describe("issue 18382", () => {
-    beforeEach(() => {
-      // TODO: Please remove this line when issue gets fixed
-      cy.skipOn(fileType === "csv");
-
-      restore();
-      cy.signInAsAdmin();
-
-      visitQuestionAdhoc(questionDetails);
-    });
-
-    it(`should handle the old syntax in downloads for ${fileType} (metabase#18382)`, () => {
-      downloadAndAssert({ fileType }, assertion);
-    });
-  });
-});
-
-function assertion(sheet) {
-  expect(sheet["A1"].v).to.eq("MOD:Title");
-  expect(sheet["B1"].v).to.eq("MOD:ID");
-  expect(sheet["C1"].v).to.eq("MOD:Reviewer");
-
-  expect(sheet["A2"].v).to.eq("Aerodynamic Concrete Bench");
-}
diff --git a/e2e/test/scenarios/sharing/downloads/reproductions/18440-remapped-display-value-dropped.cy.spec.js b/e2e/test/scenarios/sharing/downloads/reproductions/18440-remapped-display-value-dropped.cy.spec.js
deleted file mode 100644
index 02d91d85162..00000000000
--- a/e2e/test/scenarios/sharing/downloads/reproductions/18440-remapped-display-value-dropped.cy.spec.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import { SAMPLE_DB_ID } from "e2e/support/cypress_data";
-import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import {
-  restore,
-  visitQuestionAdhoc,
-  downloadAndAssert,
-  visitQuestion,
-} from "e2e/support/helpers";
-
-const { ORDERS, ORDERS_ID, PRODUCTS } = SAMPLE_DATABASE;
-
-const query = { "source-table": ORDERS_ID, limit: 5 };
-
-const questionDetails = {
-  dataset_query: {
-    type: "query",
-    query,
-    database: SAMPLE_DB_ID,
-  },
-};
-
-const testCases = ["csv", "xlsx"];
-
-describe("issue 18440", () => {
-  beforeEach(() => {
-    cy.intercept("POST", "/api/card").as("saveQuestion");
-
-    restore();
-    cy.signInAsAdmin();
-
-    // Remap Product ID -> Product Title
-    cy.request("POST", `/api/field/${ORDERS.PRODUCT_ID}/dimension`, {
-      name: "Product ID",
-      type: "external",
-      human_readable_field_id: PRODUCTS.TITLE,
-    });
-  });
-
-  testCases.forEach(fileType => {
-    it(`export should include a column with remapped values for ${fileType} (metabase#18440-1)`, () => {
-      visitQuestionAdhoc(questionDetails);
-
-      // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-      cy.findByText("Product ID");
-      // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-      cy.findByText("Awesome Concrete Shoes");
-
-      downloadAndAssert({ fileType }, assertion);
-    });
-
-    it(`export should include a column with remapped values for ${fileType} for a saved question (metabase#18440-2)`, () => {
-      cy.createQuestion({ query }).then(({ body: { id } }) => {
-        visitQuestion(id);
-
-        cy.findByText("Product ID");
-        cy.findByText("Awesome Concrete Shoes");
-
-        downloadAndAssert({ fileType, questionId: id }, assertion);
-      });
-    });
-  });
-});
-
-function assertion(sheet) {
-  expect(sheet["C1"].v).to.eq("Product ID");
-  expect(sheet["C2"].v).to.eq("Awesome Concrete Shoes");
-}
diff --git a/e2e/test/scenarios/sharing/downloads/reproductions/18573-remapped-fields-not-renamed.cy.spec.js b/e2e/test/scenarios/sharing/downloads/reproductions/18573-remapped-fields-not-renamed.cy.spec.js
deleted file mode 100644
index 2cd9c99e2bf..00000000000
--- a/e2e/test/scenarios/sharing/downloads/reproductions/18573-remapped-fields-not-renamed.cy.spec.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import { SAMPLE_DB_ID } from "e2e/support/cypress_data";
-import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import {
-  restore,
-  visitQuestionAdhoc,
-  downloadAndAssert,
-} from "e2e/support/helpers";
-
-const { ORDERS, ORDERS_ID, PRODUCTS } = SAMPLE_DATABASE;
-
-const questionDetails = {
-  dataset_query: {
-    type: "query",
-    query: { "source-table": ORDERS_ID, limit: 2 },
-    database: SAMPLE_DB_ID,
-  },
-  visualization_settings: {
-    column_settings: {
-      [`["ref",["field",${ORDERS.PRODUCT_ID},null]]`]: {
-        column_title: "Foo",
-      },
-    },
-  },
-};
-
-describe("issue 18573", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-
-    // Remap Product ID -> Product Title
-    cy.request("POST", `/api/field/${ORDERS.PRODUCT_ID}/dimension`, {
-      name: "Product ID",
-      type: "external",
-      human_readable_field_id: PRODUCTS.TITLE,
-    });
-  });
-
-  it("for the remapped columns, it should preserve renamed column name in exports for xlsx (metabase#18573)", () => {
-    visitQuestionAdhoc(questionDetails);
-
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Foo");
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Awesome Concrete Shoes");
-
-    downloadAndAssert({ fileType: "xlsx" }, assertion);
-  });
-});
-
-function assertion(sheet) {
-  expect(sheet["C1"].v).to.eq("Foo");
-  expect(sheet["C2"].v).to.eq("Awesome Concrete Shoes");
-}
diff --git a/e2e/test/scenarios/sharing/downloads/reproductions/18729-date-formatting-x-of-y.cy.spec.js b/e2e/test/scenarios/sharing/downloads/reproductions/18729-date-formatting-x-of-y.cy.spec.js
deleted file mode 100644
index c59b8051609..00000000000
--- a/e2e/test/scenarios/sharing/downloads/reproductions/18729-date-formatting-x-of-y.cy.spec.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import { SAMPLE_DB_ID } from "e2e/support/cypress_data";
-import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import {
-  restore,
-  downloadAndAssert,
-  visitQuestionAdhoc,
-} from "e2e/support/helpers";
-
-const { ORDERS, ORDERS_ID, PRODUCTS } = SAMPLE_DATABASE;
-
-const questionDetails = {
-  dataset_query: {
-    database: SAMPLE_DB_ID,
-    query: {
-      "source-table": ORDERS_ID,
-      aggregation: [["count"]],
-      breakout: [
-        ["field", ORDERS.CREATED_AT, { "temporal-unit": "month-of-year" }],
-        ["field", PRODUCTS.CATEGORY, { "source-field": ORDERS.PRODUCT_ID }],
-      ],
-      limit: 2,
-    },
-    type: "query",
-  },
-  display: "line",
-};
-
-describe("issue 18729", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-  });
-
-  ["csv", "xlsx"].forEach(fileType => {
-    it(`should properly format the 'X of Y'dates in ${fileType} exports (metabase#18729)`, () => {
-      visitQuestionAdhoc(questionDetails);
-
-      downloadAndAssert({ fileType }, assertion);
-    });
-  });
-});
-
-function assertion(sheet) {
-  // It currently says only "Created At", but that is already covered in an issue #18219.
-
-  // TODO: When 18219 gets fixed, uncomment the following assertion and delete the `contain` one.
-  // expect(sheet["A1"].v).to.eq("Created At: Month of year");
-  expect(sheet["A1"].v).to.contain("Created At");
-
-  // Based on how this issue gets resolved, the following assertions might need to change!
-
-  expect(sheet["A2"].v).to.eq(1);
-  expect(sheet["A2"].t).to.eq("n");
-  // Parsed values are always in the form of a string
-  expect(sheet["A2"].w).to.eq("1");
-}
diff --git a/e2e/test/scenarios/sharing/downloads/reproductions/19889-native-query-export-column-order.cy.spec.js b/e2e/test/scenarios/sharing/downloads/reproductions/19889-native-query-export-column-order.cy.spec.js
deleted file mode 100644
index d391f4191c8..00000000000
--- a/e2e/test/scenarios/sharing/downloads/reproductions/19889-native-query-export-column-order.cy.spec.js
+++ /dev/null
@@ -1,91 +0,0 @@
-import { restore, downloadAndAssert, visitQuestion } from "e2e/support/helpers";
-
-const questionDetails = {
-  name: "19889",
-  native: {
-    query: 'select 1 "column a", 2 "column b", 3 "column c"',
-  },
-};
-
-const testCases = ["csv", "xlsx"];
-
-describe("issue 19889", () => {
-  beforeEach(() => {
-    cy.intercept("POST", "/api/dataset").as("dataset");
-
-    restore();
-    cy.signInAsAdmin();
-
-    cy.createNativeQuestion(questionDetails, {
-      loadMetadata: true,
-      wrapId: true,
-    });
-
-    // Reorder columns a and b
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("column a").trigger("mousedown", 0, 0).wait(100); //Don't force the first interaction. This ensures things are actually visible to start moving
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("column a")
-      .trigger("mousemove", 10, 10, { force: true })
-      .wait(100);
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("column a")
-      .trigger("mousemove", 100, 0, { force: true })
-      .wait(100);
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("column a")
-      .trigger("mouseup", 100, 0, { force: true })
-      .wait(100);
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Started from").click(); // Give DOM some time to update
-  });
-
-  testCases.forEach(fileType => {
-    it("should order columns correctly in unsaved native query exports", () => {
-      downloadAndAssert({ fileType, raw: true }, sheet => {
-        expect(sheet["A1"].v).to.equal("column b");
-        expect(sheet["B1"].v).to.equal("column a");
-        expect(sheet["C1"].v).to.equal("column c");
-      });
-    });
-
-    it("should order columns correctly in saved native query exports", () => {
-      saveAndOverwrite();
-
-      cy.get("@questionId").then(questionId => {
-        downloadAndAssert({ fileType, questionId, raw: true }, sheet => {
-          expect(sheet["A1"].v).to.equal("column b");
-          expect(sheet["B1"].v).to.equal("column a");
-          expect(sheet["C1"].v).to.equal("column c");
-        });
-      });
-    });
-
-    it("should order columns correctly in saved native query exports when the query was modified but not re-run before save (#19889)", () => {
-      // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-      cy.contains(/open editor/i).click();
-      cy.get(".ace_editor").type(
-        '{selectall}select 1 "column x", 2 "column y", 3 "column c"',
-      );
-
-      saveAndOverwrite();
-
-      cy.get("@questionId").then(questionId => {
-        visitQuestion(questionId);
-
-        downloadAndAssert({ fileType, questionId, raw: true }, sheet => {
-          expect(sheet["A1"].v).to.equal("column x");
-          expect(sheet["B1"].v).to.equal("column y");
-          expect(sheet["C1"].v).to.equal("column c");
-        });
-      });
-    });
-  });
-});
-
-function saveAndOverwrite() {
-  cy.findByText("Save").click();
-  cy.findByTestId("save-question-modal").within(modal => {
-    cy.findByText("Save").click();
-  });
-}
diff --git a/e2e/test/scenarios/sharing/downloads/reproductions/28834-modified-native-question.cy.spec.js b/e2e/test/scenarios/sharing/downloads/reproductions/28834-modified-native-question.cy.spec.js
deleted file mode 100644
index e29322e92cd..00000000000
--- a/e2e/test/scenarios/sharing/downloads/reproductions/28834-modified-native-question.cy.spec.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import { restore, downloadAndAssert } from "e2e/support/helpers";
-
-const questionDetails = {
-  name: "28834",
-  native: {
-    query: 'select 1 "column a"',
-  },
-};
-
-describe("metabase#28834", () => {
-  // I have a test for saved native questions in `QueryBuilder.unit.spec.tsx`.
-  // Initially, this test was planned as a unit test, but with some technical
-  // difficulties, I've decided to test with Cypress instead.
-
-  beforeEach(() => {
-    cy.intercept("POST", "/api/dataset").as("dataset");
-
-    restore();
-    cy.signInAsAdmin();
-
-    cy.createNativeQuestion(questionDetails, {
-      loadMetadata: true,
-      wrapId: true,
-    });
-
-    cy.findByTestId("query-builder-main").findByText("Open Editor").click();
-    cy.get(".ace_editor").should("be.visible").type(', select 2 "column b"');
-  });
-
-  it("should be able to export unsaved native query results as CSV even after the query has changed", () => {
-    const fileType = "csv";
-    downloadAndAssert({ fileType, raw: true }, sheet => {
-      expect(sheet["A1"].v).to.equal("column a");
-      expect(sheet["A2"].v).to.equal("1");
-      expect(sheet["A3"]).to.be.undefined;
-    });
-  });
-
-  it("should be able to export unsaved native query results as XLSX even after the query has changed", () => {
-    const fileType = "xlsx";
-    downloadAndAssert({ fileType, raw: true }, sheet => {
-      expect(sheet["A1"].v).to.equal("column a");
-      expect(sheet["A2"].v).to.equal(1);
-      expect(sheet["A3"]).to.be.undefined;
-    });
-  });
-});
diff --git a/e2e/test/scenarios/sharing/downloads/sharing-download-reproductions.cy.spec.js b/e2e/test/scenarios/sharing/downloads/sharing-download-reproductions.cy.spec.js
new file mode 100644
index 00000000000..f2e4082caf7
--- /dev/null
+++ b/e2e/test/scenarios/sharing/downloads/sharing-download-reproductions.cy.spec.js
@@ -0,0 +1,512 @@
+import { SAMPLE_DB_ID } from "e2e/support/cypress_data";
+import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
+import {
+  restore,
+  downloadAndAssert,
+  runNativeQuery,
+  visitQuestion,
+  visitQuestionAdhoc,
+} from "e2e/support/helpers";
+
+const { ORDERS, ORDERS_ID, REVIEWS, REVIEWS_ID, PRODUCTS, PRODUCTS_ID } =
+  SAMPLE_DATABASE;
+
+describe("issue 10803", () => {
+  const testCases = ["csv", "xlsx"];
+
+  beforeEach(() => {
+    cy.intercept("POST", "/api/dataset").as("dataset");
+
+    restore();
+    cy.signInAsAdmin();
+
+    cy.createNativeQuestion(
+      {
+        name: "10803",
+        native: {
+          query:
+            "SELECT cast(parsedatetime('2026-06-03', 'yyyy-MM-dd') AS timestamp) AS \"birth_date\", cast(parsedatetime('2026-06-03 23:41:23', 'yyyy-MM-dd HH:mm:ss') AS timestamp) AS \"created_at\"",
+        },
+      },
+      { visitQuestion: true, wrapId: true },
+    );
+  });
+
+  testCases.forEach(fileType => {
+    it(`should format the date properly for ${fileType} in saved questions (metabase#10803)`, () => {
+      cy.get("@questionId").then(questionId => {
+        downloadAndAssert(
+          { fileType, questionId, logResults: true, raw: true },
+          testWorkbookDatetimes,
+        );
+      });
+    });
+
+    it(`should format the date properly for ${fileType} in unsaved questions`, () => {
+      // Add a space at the end of the query to make it "dirty"
+      // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+      cy.contains(/open editor/i).click();
+      cy.get(".ace_editor").type("{movetoend} ");
+
+      runNativeQuery();
+      downloadAndAssert({ fileType, raw: true }, testWorkbookDatetimes);
+    });
+
+    function testWorkbookDatetimes(sheet) {
+      expect(sheet["A1"].v).to.eq("birth_date");
+      expect(sheet["B1"].v).to.eq("created_at");
+
+      // Excel and CSV will have different formats
+      if (fileType === "csv") {
+        expect(sheet["A2"].v).to.eq("June 3, 2026, 12:00 AM");
+        expect(sheet["B2"].v).to.eq("June 3, 2026, 11:41 PM");
+      } else if (fileType === "xlsx") {
+        // We tell the xlsx library to read raw and not parse dates
+        // So for the _date_ format we expect an integer
+        // And for timestamp, we expect a float
+        expect(sheet["A2"].v).to.eq(46176);
+        expect(sheet["B2"].v).to.eq(46176.98707175926);
+      }
+    }
+  });
+});
+
+describe.skip("issue 18219", () => {
+  const questionDetails = {
+    name: "18219",
+    query: {
+      "source-table": ORDERS_ID,
+      aggregation: [["count"]],
+      breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": "year" }]],
+    },
+  };
+
+  const testCases = ["csv", "xlsx"];
+
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+  });
+
+  testCases.forEach(fileType => {
+    it("should format temporal units on export (metabase#18219)", () => {
+      cy.createQuestion(questionDetails).then(
+        ({ body: { id: questionId } }) => {
+          visitQuestion(questionId);
+
+          cy.findByText("Created At: Year");
+          cy.findByText("2022");
+          cy.findByText("744");
+
+          downloadAndAssert({ fileType, questionId, raw: true }, assertion);
+        },
+      );
+    });
+
+    function assertion(sheet) {
+      expect(sheet["A1"].v).to.eq("Created At: Year");
+
+      if (fileType === "csv") {
+        expect(sheet["A2"].v).to.eq("2022");
+      }
+
+      if (fileType === "xlsx") {
+        /**
+         * Depending on how we end up solving this issue,
+         * the following assertion on the cell type might not be correct.
+         * It's very likely we'll format temporal breakouts as strings.
+         * I.e. we have to take into account Q1, Q2, etc.
+         */
+        // expect(A2.t).to.eq("n");
+
+        /**
+         * Because of the excel date format, we cannot assert on the raw value `v`.
+         * Rather, we have to do it on the parsed value `w`.
+         */
+        expect(sheet["A2"].w).to.eq("2022");
+      }
+    }
+  });
+});
+
+describe("issue 18382", () => {
+  /**
+   * This question might seem a bit overwhelming at the first sight.
+   * The whole point of this repro was to try to cover as much of the old syntax as possible.
+   * We want to make sure it still works when loaded into a new(er) Metabase version.
+   */
+
+  function assertion(sheet) {
+    expect(sheet["A1"].v).to.eq("MOD:Title");
+    expect(sheet["B1"].v).to.eq("MOD:ID");
+    expect(sheet["C1"].v).to.eq("MOD:Reviewer");
+
+    expect(sheet["A2"].v).to.eq("Aerodynamic Concrete Bench");
+  }
+
+  const questionDetails = {
+    dataset_query: {
+      database: SAMPLE_DB_ID,
+      type: "query",
+      query: {
+        "source-table": REVIEWS_ID,
+        joins: [
+          {
+            fields: [
+              ["joined-field", "Products", ["field-id", PRODUCTS.TITLE]],
+            ],
+            "source-table": PRODUCTS_ID,
+            condition: [
+              "=",
+              ["field-id", REVIEWS.PRODUCT_ID],
+              ["joined-field", "Products", ["field-id", PRODUCTS.ID]],
+            ],
+            alias: "Products",
+          },
+        ],
+        filter: ["and", ["=", ["field-id", REVIEWS.RATING], 4]],
+        "order-by": [
+          ["asc", ["joined-field", "Products", ["field-id", PRODUCTS.TITLE]]],
+        ],
+        fields: [
+          ["field-id", REVIEWS.ID],
+          ["field-id", REVIEWS.REVIEWER],
+        ],
+        limit: 5,
+      },
+    },
+    display: "table",
+    visualization_settings: {
+      column_settings: {
+        [`["ref",["field",${REVIEWS.ID},null]]`]: {
+          column_title: "MOD:ID",
+        },
+        [`["ref",["field",${REVIEWS.REVIEWER},null]]`]: {
+          column_title: "MOD:Reviewer",
+        },
+        [`["ref",["field",${PRODUCTS.TITLE},null]]`]: {
+          column_title: "MOD:Title",
+        },
+      },
+      // Reorder columns
+      "table.columns": [
+        {
+          name: "TITLE",
+          fieldRef: ["joined-field", "Products", ["field-id", PRODUCTS.TITLE]],
+          enabled: true,
+        },
+        {
+          name: "ID",
+          fieldRef: ["field-id", REVIEWS.ID],
+          enabled: true,
+        },
+        {
+          name: "REVIEWER",
+          fieldRef: ["field-id", REVIEWS.REVIEWER],
+          enabled: true,
+        },
+      ],
+    },
+  };
+
+  const testCases = ["csv", "xlsx"];
+
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+    visitQuestionAdhoc(questionDetails);
+  });
+
+  testCases.forEach(fileType => {
+    it(`should handle the old syntax in downloads for ${fileType} (metabase#18382)`, () => {
+      // TODO: Please remove this line when issue gets fixed
+      cy.skipOn(fileType === "csv");
+
+      downloadAndAssert({ fileType }, assertion);
+    });
+  });
+});
+
+describe("issue 18440", () => {
+  const query = { "source-table": ORDERS_ID, limit: 5 };
+
+  const questionDetails = {
+    dataset_query: {
+      type: "query",
+      query,
+      database: SAMPLE_DB_ID,
+    },
+  };
+
+  const testCases = ["csv", "xlsx"];
+
+  function assertion(sheet) {
+    expect(sheet["C1"].v).to.eq("Product ID");
+    expect(sheet["C2"].v).to.eq("Awesome Concrete Shoes");
+  }
+
+  beforeEach(() => {
+    cy.intercept("POST", "/api/card").as("saveQuestion");
+
+    restore();
+    cy.signInAsAdmin();
+
+    // Remap Product ID -> Product Title
+    cy.request("POST", `/api/field/${ORDERS.PRODUCT_ID}/dimension`, {
+      name: "Product ID",
+      type: "external",
+      human_readable_field_id: PRODUCTS.TITLE,
+    });
+  });
+
+  testCases.forEach(fileType => {
+    it(`export should include a column with remapped values for ${fileType} (metabase#18440-1)`, () => {
+      visitQuestionAdhoc(questionDetails);
+
+      // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+      cy.findByText("Product ID");
+      // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+      cy.findByText("Awesome Concrete Shoes");
+
+      downloadAndAssert({ fileType }, assertion);
+    });
+
+    it(`export should include a column with remapped values for ${fileType} for a saved question (metabase#18440-2)`, () => {
+      cy.createQuestion({ query }).then(({ body: { id } }) => {
+        visitQuestion(id);
+
+        cy.findByText("Product ID");
+        cy.findByText("Awesome Concrete Shoes");
+
+        downloadAndAssert({ fileType, questionId: id }, assertion);
+      });
+    });
+  });
+});
+
+describe("issue 18573", () => {
+  const questionDetails = {
+    dataset_query: {
+      type: "query",
+      query: { "source-table": ORDERS_ID, limit: 2 },
+      database: SAMPLE_DB_ID,
+    },
+    visualization_settings: {
+      column_settings: {
+        [`["ref",["field",${ORDERS.PRODUCT_ID},null]]`]: {
+          column_title: "Foo",
+        },
+      },
+    },
+  };
+  function assertion(sheet) {
+    expect(sheet["C1"].v).to.eq("Foo");
+    expect(sheet["C2"].v).to.eq("Awesome Concrete Shoes");
+  }
+
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+
+    // Remap Product ID -> Product Title
+    cy.request("POST", `/api/field/${ORDERS.PRODUCT_ID}/dimension`, {
+      name: "Product ID",
+      type: "external",
+      human_readable_field_id: PRODUCTS.TITLE,
+    });
+  });
+
+  it("for the remapped columns, it should preserve renamed column name in exports for xlsx (metabase#18573)", () => {
+    visitQuestionAdhoc(questionDetails);
+
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Foo");
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Awesome Concrete Shoes");
+
+    downloadAndAssert({ fileType: "xlsx" }, assertion);
+  });
+});
+
+describe("issue 18729", () => {
+  const questionDetails = {
+    dataset_query: {
+      database: SAMPLE_DB_ID,
+      query: {
+        "source-table": ORDERS_ID,
+        aggregation: [["count"]],
+        breakout: [
+          ["field", ORDERS.CREATED_AT, { "temporal-unit": "month-of-year" }],
+          ["field", PRODUCTS.CATEGORY, { "source-field": ORDERS.PRODUCT_ID }],
+        ],
+        limit: 2,
+      },
+      type: "query",
+    },
+    display: "line",
+  };
+
+  function assertion(sheet) {
+    // It currently says only "Created At", but that is already covered in an issue #18219.
+
+    // TODO: When 18219 gets fixed, uncomment the following assertion and delete the `contain` one.
+    // expect(sheet["A1"].v).to.eq("Created At: Month of year");
+    expect(sheet["A1"].v).to.contain("Created At");
+
+    // Based on how this issue gets resolved, the following assertions might need to change!
+
+    expect(sheet["A2"].v).to.eq(1);
+    expect(sheet["A2"].t).to.eq("n");
+    // Parsed values are always in the form of a string
+    expect(sheet["A2"].w).to.eq("1");
+  }
+
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+  });
+
+  ["csv", "xlsx"].forEach(fileType => {
+    it(`should properly format the 'X of Y'dates in ${fileType} exports (metabase#18729)`, () => {
+      visitQuestionAdhoc(questionDetails);
+
+      downloadAndAssert({ fileType }, assertion);
+    });
+  });
+});
+
+describe("issue 19889", () => {
+  const questionDetails = {
+    name: "19889",
+    native: {
+      query: 'select 1 "column a", 2 "column b", 3 "column c"',
+    },
+  };
+
+  const testCases = ["csv", "xlsx"];
+
+  function saveAndOverwrite() {
+    cy.findByText("Save").click();
+    cy.findByTestId("save-question-modal").within(modal => {
+      cy.findByText("Save").click();
+    });
+  }
+
+  beforeEach(() => {
+    cy.intercept("POST", "/api/dataset").as("dataset");
+
+    restore();
+    cy.signInAsAdmin();
+
+    cy.createNativeQuestion(questionDetails, {
+      loadMetadata: true,
+      wrapId: true,
+    });
+
+    // Reorder columns a and b
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("column a").trigger("mousedown", 0, 0).wait(100); //Don't force the first interaction. This ensures things are actually visible to start moving
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("column a")
+      .trigger("mousemove", 10, 10, { force: true })
+      .wait(100);
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("column a")
+      .trigger("mousemove", 100, 0, { force: true })
+      .wait(100);
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("column a")
+      .trigger("mouseup", 100, 0, { force: true })
+      .wait(100);
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Started from").click(); // Give DOM some time to update
+  });
+
+  testCases.forEach(fileType => {
+    it("should order columns correctly in unsaved native query exports", () => {
+      downloadAndAssert({ fileType, raw: true }, sheet => {
+        expect(sheet["A1"].v).to.equal("column b");
+        expect(sheet["B1"].v).to.equal("column a");
+        expect(sheet["C1"].v).to.equal("column c");
+      });
+    });
+
+    it("should order columns correctly in saved native query exports", () => {
+      saveAndOverwrite();
+
+      cy.get("@questionId").then(questionId => {
+        downloadAndAssert({ fileType, questionId, raw: true }, sheet => {
+          expect(sheet["A1"].v).to.equal("column b");
+          expect(sheet["B1"].v).to.equal("column a");
+          expect(sheet["C1"].v).to.equal("column c");
+        });
+      });
+    });
+
+    it("should order columns correctly in saved native query exports when the query was modified but not re-run before save (#19889)", () => {
+      // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+      cy.contains(/open editor/i).click();
+      cy.get(".ace_editor").type(
+        '{selectall}select 1 "column x", 2 "column y", 3 "column c"',
+      );
+
+      saveAndOverwrite();
+
+      cy.get("@questionId").then(questionId => {
+        visitQuestion(questionId);
+
+        downloadAndAssert({ fileType, questionId, raw: true }, sheet => {
+          expect(sheet["A1"].v).to.equal("column x");
+          expect(sheet["B1"].v).to.equal("column y");
+          expect(sheet["C1"].v).to.equal("column c");
+        });
+      });
+    });
+  });
+});
+
+describe("metabase#28834", () => {
+  const questionDetails = {
+    name: "28834",
+    native: {
+      query: 'select 1 "column a"',
+    },
+  };
+
+  // I have a test for saved native questions in `QueryBuilder.unit.spec.tsx`.
+  // Initially, this test was planned as a unit test, but with some technical
+  // difficulties, I've decided to test with Cypress instead.
+
+  beforeEach(() => {
+    cy.intercept("POST", "/api/dataset").as("dataset");
+
+    restore();
+    cy.signInAsAdmin();
+
+    cy.createNativeQuestion(questionDetails, {
+      loadMetadata: true,
+      wrapId: true,
+    });
+
+    cy.findByTestId("query-builder-main").findByText("Open Editor").click();
+    cy.get(".ace_editor").should("be.visible").type(', select 2 "column b"');
+  });
+
+  it("should be able to export unsaved native query results as CSV even after the query has changed", () => {
+    const fileType = "csv";
+    downloadAndAssert({ fileType, raw: true }, sheet => {
+      expect(sheet["A1"].v).to.equal("column a");
+      expect(sheet["A2"].v).to.equal("1");
+      expect(sheet["A3"]).to.be.undefined;
+    });
+  });
+
+  it("should be able to export unsaved native query results as XLSX even after the query has changed", () => {
+    const fileType = "xlsx";
+    downloadAndAssert({ fileType, raw: true }, sheet => {
+      expect(sheet["A1"].v).to.equal("column a");
+      expect(sheet["A2"].v).to.equal(1);
+      expect(sheet["A3"]).to.be.undefined;
+    });
+  });
+});
diff --git a/e2e/test/scenarios/sharing/public-sharing.cy.spec.js b/e2e/test/scenarios/sharing/public-sharing.cy.spec.js
index c79e1947ae4..47c5d0077b3 100644
--- a/e2e/test/scenarios/sharing/public-sharing.cy.spec.js
+++ b/e2e/test/scenarios/sharing/public-sharing.cy.spec.js
@@ -1,11 +1,21 @@
 import { SAMPLE_DB_ID } from "e2e/support/cypress_data";
 import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
+import {
+  ORDERS_QUESTION_ID,
+  ORDERS_DASHBOARD_ID,
+} from "e2e/support/cypress_sample_instance_data";
 import {
   restore,
   modal,
   setActionsEnabledForDB,
   createAction,
   visitDashboardAndCreateTab,
+  describeEE,
+  setupSMTP,
+  sidebar,
+  visitQuestion,
+  visitDashboard,
+  setTokenFeatures,
 } from "e2e/support/helpers";
 
 const { ORDERS_ID } = SAMPLE_DATABASE;
@@ -267,3 +277,64 @@ describe("scenarios > admin > settings > public sharing", () => {
     );
   });
 });
+
+describeEE(
+  "scenarios > sharing > approved domains (EE)",
+  { tags: "@external" },
+  () => {
+    const allowedDomain = "metabase.test";
+    const deniedDomain = "metabase.example";
+    const deniedEmail = `mailer@${deniedDomain}`;
+    const subscriptionError = `You're only allowed to email subscriptions to addresses ending in ${allowedDomain}`;
+    const alertError = `You're only allowed to email alerts to addresses ending in ${allowedDomain}`;
+
+    function addEmailRecipient(email) {
+      cy.findByRole("textbox").click().type(`${email}`).blur();
+    }
+
+    function setAllowedDomains() {
+      cy.request("PUT", "/api/setting/subscription-allowed-domains", {
+        value: allowedDomain,
+      });
+    }
+
+    beforeEach(() => {
+      restore();
+      cy.signInAsAdmin();
+      setTokenFeatures("all");
+      setupSMTP();
+      setAllowedDomains();
+    });
+
+    it("should validate approved email domains for a question alert", () => {
+      visitQuestion(ORDERS_QUESTION_ID);
+
+      cy.icon("bell").click();
+      cy.button("Set up an alert").click();
+
+      cy.findByRole("heading", { name: "Email" })
+        .closest("li")
+        .within(() => {
+          addEmailRecipient(deniedEmail);
+          cy.findByText(alertError);
+        });
+      cy.button("Done").should("be.disabled");
+    });
+
+    it("should validate approved email domains for a dashboard subscription (metabase#17977)", () => {
+      visitDashboard(ORDERS_DASHBOARD_ID);
+      cy.icon("subscription").click();
+
+      cy.findByRole("heading", { name: "Email it" }).click();
+
+      sidebar().within(() => {
+        addEmailRecipient(deniedEmail);
+
+        // Reproduces metabase#17977
+        cy.button("Send email now").should("be.disabled");
+        cy.button("Done").should("be.disabled");
+        cy.findByText(subscriptionError);
+      });
+    });
+  },
+);
diff --git a/e2e/test/scenarios/sharing/reproductions.cy.spec.js b/e2e/test/scenarios/sharing/reproductions.cy.spec.js
deleted file mode 100644
index 8cce0f99b53..00000000000
--- a/e2e/test/scenarios/sharing/reproductions.cy.spec.js
+++ /dev/null
@@ -1,279 +0,0 @@
-import { USERS } from "e2e/support/cypress_data";
-import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import {
-  ADMIN_USER_ID,
-  ORDERS_DASHBOARD_DASHCARD_ID,
-  ORDERS_DASHBOARD_ID,
-  ORDERS_QUESTION_ID,
-} from "e2e/support/cypress_sample_instance_data";
-import {
-  restore,
-  setupSMTP,
-  visitDashboard,
-  getFullName,
-  sidebar,
-  popover,
-  visitQuestion,
-} from "e2e/support/helpers";
-
-const { ORDERS, ORDERS_ID, PEOPLE } = SAMPLE_DATABASE;
-const { admin } = USERS;
-const { first_name, last_name } = admin;
-
-describe("issue 17657", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-
-    createSubscriptionWithoutRecipients();
-  });
-
-  it("frontend should gracefully handle the case of a subscription without a recipient (metabase#17657)", () => {
-    visitDashboard(ORDERS_DASHBOARD_ID);
-
-    cy.icon("subscription").click();
-
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText(/^Emailed monthly/).click();
-
-    sidebar().within(() => {
-      cy.button("Done").should("be.disabled");
-    });
-
-    // Open the popover with all users
-    cy.findByPlaceholderText("Enter user names or email addresses").click();
-    // Pick admin as a recipient
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText(`${first_name} ${last_name}`).click();
-
-    sidebar().within(() => {
-      cy.button("Done").should("not.be.disabled");
-    });
-  });
-});
-
-function createSubscriptionWithoutRecipients() {
-  cy.request("POST", "/api/pulse", {
-    name: "Orders in a dashboard",
-    cards: [
-      {
-        id: ORDERS_QUESTION_ID,
-        collection_id: null,
-        description: null,
-        display: "table",
-        name: "Orders",
-        include_csv: false,
-        include_xls: false,
-        dashboard_card_id: 1,
-        dashboard_id: ORDERS_DASHBOARD_ID,
-        parameter_mappings: [],
-      },
-    ],
-    channels: [
-      {
-        channel_type: "email",
-        enabled: true,
-        // Since the fix (https://github.com/metabase/metabase/pull/17668), this is not even possible to do in the UI anymore.
-        // Backend still doesn't do this validation so we're making sure the FE handles the case of missing recipients gracefully.
-        recipients: [],
-        details: {},
-        schedule_type: "monthly",
-        schedule_day: "mon",
-        schedule_hour: 8,
-        schedule_frame: "first",
-      },
-    ],
-    skip_if_empty: false,
-    collection_id: null,
-    parameters: [],
-    dashboard_id: ORDERS_DASHBOARD_ID,
-  });
-}
-
-describe("issue 17658", { tags: "@external" }, () => {
-  beforeEach(() => {
-    cy.intercept("PUT", "/api/pulse/*").as("deletePulse");
-    restore();
-    cy.signInAsAdmin();
-
-    setupSMTP();
-
-    moveDashboardToCollection("First collection");
-  });
-
-  it("should delete dashboard subscription from any collection (metabase#17658)", () => {
-    visitDashboard(ORDERS_DASHBOARD_ID);
-
-    cy.icon("subscription").click();
-
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText(/^Emailed monthly/).click();
-
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Delete this subscription").click();
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText(/^This dashboard will no longer be emailed to/).click();
-
-    cy.button("Delete").click();
-
-    cy.wait("@deletePulse").then(({ response }) => {
-      expect(response.body.cause).not.to.exist;
-      expect(response.statusCode).not.to.eq(500);
-    });
-
-    cy.button("Delete").should("not.exist");
-  });
-});
-
-function moveDashboardToCollection(collectionName) {
-  const { first_name, last_name, email } = admin;
-
-  cy.request("GET", "/api/collection/tree?tree=true").then(
-    ({ body: collections }) => {
-      const { id } = collections.find(
-        collection => collection.name === collectionName,
-      );
-
-      // Move dashboard
-      cy.request("PUT", `/api/dashboard/${ORDERS_DASHBOARD_ID}`, {
-        collection_id: id,
-      });
-
-      // Create subscription
-      cy.request("POST", "/api/pulse", {
-        name: "Orders in a dashboard",
-        cards: [
-          {
-            id: ORDERS_QUESTION_ID,
-            collection_id: null,
-            description: null,
-            display: "table",
-            name: "Orders",
-            include_csv: false,
-            include_xls: false,
-            dashboard_card_id: ORDERS_DASHBOARD_DASHCARD_ID,
-            dashboard_id: ORDERS_DASHBOARD_ID,
-            parameter_mappings: [],
-          },
-        ],
-        channels: [
-          {
-            channel_type: "email",
-            enabled: true,
-            recipients: [
-              {
-                id: ADMIN_USER_ID,
-                email,
-                first_name,
-                last_name,
-                common_name: getFullName(admin),
-              },
-            ],
-            details: {},
-            schedule_type: "monthly",
-            schedule_day: "mon",
-            schedule_hour: 8,
-            schedule_frame: "first",
-          },
-        ],
-        skip_if_empty: false,
-        collection_id: id,
-        parameters: [],
-        dashboard_id: ORDERS_DASHBOARD_ID,
-      });
-    },
-  );
-}
-
-describe("issue 17547", () => {
-  const questionDetails = {
-    query: {
-      "source-table": ORDERS_ID,
-      breakout: [
-        ["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }],
-        ["field", PEOPLE.SOURCE, { "source-field": ORDERS.USER_ID }],
-      ],
-      aggregation: [["count"]],
-    },
-    display: "area",
-  };
-
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-
-    cy.createQuestion(questionDetails).then(({ body: { id: questionId } }) => {
-      setUpAlert(questionId);
-
-      visitQuestion(questionId);
-    });
-  });
-
-  it("editing an alert should not delete it (metabase#17547)", () => {
-    cy.icon("bell").click();
-    popover().within(() => {
-      cy.findByText("Daily, 12:00 PM");
-      cy.findByText("Edit").click();
-    });
-
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("AM").click();
-    cy.button("Save changes").click();
-
-    cy.wait("@alertQuery");
-
-    cy.icon("bell").click();
-    popover().within(() => {
-      cy.findByText("Daily, 12:00 AM");
-    });
-  });
-});
-
-function setUpAlert(questionId) {
-  cy.request("POST", "/api/alert", {
-    channels: [
-      {
-        schedule_type: "daily",
-        schedule_hour: 12,
-        channel_type: "slack",
-        schedule_frame: null,
-        recipients: [],
-        details: { channel: "#work" },
-        pulse_id: 1,
-        id: 1,
-        schedule_day: null,
-        enabled: true,
-      },
-    ],
-    alert_condition: "rows",
-    name: null,
-    creator_id: ADMIN_USER_ID,
-    card: { id: questionId, include_csv: true, include_xls: false },
-    alert_first_only: false,
-    skip_if_empty: true,
-    parameters: [],
-    dashboard_id: null,
-  }).then(({ body: { id: alertId } }) => {
-    cy.intercept("PUT", `/api/alert/${alertId}`).as("alertQuery");
-  });
-}
-
-describe("issue 16108", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-  });
-
-  it("should display a tooltip for CTA icons on an individual question (metabase#16108)", () => {
-    visitQuestion(ORDERS_QUESTION_ID);
-    cy.icon("download").realHover();
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Download full results");
-    cy.icon("bell").realHover();
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Get alerts");
-    cy.icon("share").realHover();
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Sharing");
-  });
-});
diff --git a/e2e/test/scenarios/sharing/reproductions/18009-nodata-creates-subscription-receives-error.cy.spec.js b/e2e/test/scenarios/sharing/reproductions/18009-nodata-creates-subscription-receives-error.cy.spec.js
deleted file mode 100644
index f9be7fc5928..00000000000
--- a/e2e/test/scenarios/sharing/reproductions/18009-nodata-creates-subscription-receives-error.cy.spec.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import { ORDERS_DASHBOARD_ID } from "e2e/support/cypress_sample_instance_data";
-import {
-  restore,
-  popover,
-  setupSMTP,
-  visitDashboard,
-  sendEmailAndAssert,
-  sidebar,
-} from "e2e/support/helpers";
-
-describe("issue 18009", { tags: "@external" }, () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-
-    setupSMTP();
-
-    cy.signIn("nodata");
-  });
-
-  it("nodata user should be able to create and receive an email subscription without errors (metabase#18009)", () => {
-    visitDashboard(ORDERS_DASHBOARD_ID);
-
-    cy.findByLabelText("subscriptions").click();
-
-    sidebar()
-      .findByPlaceholderText("Enter user names or email addresses")
-      .click();
-    popover()
-      .contains(/^No Data/)
-      .click();
-
-    // Click anywhere to close the popover that covers the "Send email now" button
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("To:").click();
-
-    sendEmailAndAssert(email => {
-      expect(email.html).not.to.include(
-        "An error occurred while displaying this card.",
-      );
-
-      expect(email.html).to.include("37.65");
-    });
-  });
-});
diff --git a/e2e/test/scenarios/sharing/reproductions/18344-subscription-shows-original-question-name.cy.spec.js b/e2e/test/scenarios/sharing/reproductions/18344-subscription-shows-original-question-name.cy.spec.js
deleted file mode 100644
index de56a4a07ed..00000000000
--- a/e2e/test/scenarios/sharing/reproductions/18344-subscription-shows-original-question-name.cy.spec.js
+++ /dev/null
@@ -1,61 +0,0 @@
-import { USERS } from "e2e/support/cypress_data";
-import { ORDERS_DASHBOARD_ID } from "e2e/support/cypress_sample_instance_data";
-import {
-  restore,
-  editDashboard,
-  saveDashboard,
-  setupSMTP,
-  visitDashboard,
-  sendEmailAndAssert,
-  modal,
-} from "e2e/support/helpers";
-
-const {
-  admin: { first_name, last_name },
-} = USERS;
-
-describe("issue 18344", { tags: "@external" }, () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-
-    setupSMTP();
-
-    // Rename the question
-    visitDashboard(ORDERS_DASHBOARD_ID);
-
-    editDashboard();
-
-    // Open visualization options
-    cy.findByTestId("dashcard").realHover();
-    cy.icon("palette").click();
-
-    modal().within(() => {
-      cy.findByDisplayValue("Orders").type("Foo").blur();
-
-      cy.button("Done").click();
-    });
-
-    saveDashboard();
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("OrdersFoo");
-  });
-
-  it("subscription should not include original question name when it's been renamed in the dashboard (metabase#18344)", () => {
-    // Send a test email subscription
-    cy.icon("subscription").click();
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Email it").click();
-
-    cy.findByPlaceholderText("Enter user names or email addresses").click();
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText(`${first_name} ${last_name}`).click();
-    // Click this just to close the popover that is blocking the "Send email now" button
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("To:").click();
-
-    sendEmailAndAssert(email => {
-      expect(email.html).to.include("OrdersFoo");
-    });
-  });
-});
diff --git a/e2e/test/scenarios/sharing/reproductions/18352-subscription-int64-value-card.cy.spec.js b/e2e/test/scenarios/sharing/reproductions/18352-subscription-int64-value-card.cy.spec.js
deleted file mode 100644
index ed8536a60cb..00000000000
--- a/e2e/test/scenarios/sharing/reproductions/18352-subscription-int64-value-card.cy.spec.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import { USERS } from "e2e/support/cypress_data";
-import {
-  restore,
-  setupSMTP,
-  visitQuestion,
-  visitDashboard,
-  sendEmailAndAssert,
-} from "e2e/support/helpers";
-
-const {
-  admin: { first_name, last_name },
-} = USERS;
-
-const questionDetails = {
-  name: "18352",
-  native: {
-    query: "SELECT 'foo', 1 UNION ALL SELECT 'bar', 2",
-  },
-};
-
-describe("issue 18352", { tags: "@external" }, () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-
-    setupSMTP();
-
-    cy.createNativeQuestionAndDashboard({ questionDetails }).then(
-      ({ body: { card_id, dashboard_id } }) => {
-        visitQuestion(card_id);
-
-        visitDashboard(dashboard_id);
-      },
-    );
-  });
-
-  it("should send the card with the INT64 values (metabase#18352)", () => {
-    cy.icon("subscription").click();
-
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Email it").click();
-
-    cy.findByPlaceholderText("Enter user names or email addresses").click();
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText(`${first_name} ${last_name}`).click();
-    // Click this just to close the popover that is blocking the "Send email now" button
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("To:").click();
-
-    sendEmailAndAssert(({ html }) => {
-      expect(html).not.to.include(
-        "An error occurred while displaying this card.",
-      );
-
-      expect(html).to.include("foo");
-      expect(html).to.include("bar");
-    });
-  });
-});
diff --git a/e2e/test/scenarios/sharing/reproductions/18669-test-email-with-parameters.cy.spec.js b/e2e/test/scenarios/sharing/reproductions/18669-test-email-with-parameters.cy.spec.js
deleted file mode 100644
index 2953f8f1f02..00000000000
--- a/e2e/test/scenarios/sharing/reproductions/18669-test-email-with-parameters.cy.spec.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import { USERS, SAMPLE_DB_ID } from "e2e/support/cypress_data";
-import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import {
-  describeEE,
-  popover,
-  restore,
-  setupSMTP,
-  sidebar,
-  visitDashboard,
-  clickSend,
-  setTokenFeatures,
-} from "e2e/support/helpers";
-
-const { admin } = USERS;
-const { PRODUCTS_ID, PRODUCTS } = SAMPLE_DATABASE;
-
-describeEE("issue 18669", { tags: "@external" }, () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-    setTokenFeatures("all");
-    setupSMTP();
-
-    cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then(
-      ({ body: card }) => {
-        cy.editDashboardCard(card, getFilterMapping(card));
-        visitDashboard(card.dashboard_id);
-      },
-    );
-  });
-
-  it("should send a test email with non-default parameters (metabase#18669)", () => {
-    cy.icon("subscription").click();
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Email it").click();
-
-    cy.findByPlaceholderText("Enter user names or email addresses")
-      .click()
-      .type(`${admin.first_name} ${admin.last_name}{enter}`)
-      .blur();
-
-    sidebar().within(() => {
-      cy.findByText("Doohickey").click();
-    });
-
-    popover().within(() => {
-      cy.findByText("Gizmo").click();
-      cy.button("Update filter").click();
-    });
-
-    clickSend();
-  });
-});
-
-const questionDetails = {
-  name: "Product count",
-  database: SAMPLE_DB_ID,
-  type: "query",
-  query: {
-    "source-table": PRODUCTS_ID,
-    aggregation: [["count"]],
-  },
-};
-
-const filterDetails = {
-  name: "Category",
-  slug: "category",
-  id: "c32a49e1",
-  type: "category",
-  default: ["Doohickey"],
-};
-
-const dashboardDetails = {
-  parameters: [filterDetails],
-};
-
-const getFilterMapping = card => ({
-  parameter_mappings: [
-    {
-      parameter_id: filterDetails.id,
-      card_id: card.card_id,
-      target: ["dimension", ["field", PRODUCTS.CATEGORY, null]],
-    },
-  ],
-});
diff --git a/e2e/test/scenarios/sharing/reproductions/20393-public-dashboard-nested-card-with-parameters.cy.spec.js b/e2e/test/scenarios/sharing/reproductions/20393-public-dashboard-nested-card-with-parameters.cy.spec.js
deleted file mode 100644
index c74c040b3ff..00000000000
--- a/e2e/test/scenarios/sharing/reproductions/20393-public-dashboard-nested-card-with-parameters.cy.spec.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import {
-  restore,
-  popover,
-  visitDashboard,
-  editDashboard,
-  setFilter,
-  openNewPublicLinkDropdown,
-} from "e2e/support/helpers";
-
-describe("issue 20393", () => {
-  beforeEach(() => {
-    cy.intercept("POST", "/api/dashboard/*/public_link").as("publicLink");
-
-    restore();
-    cy.signInAsAdmin();
-  });
-
-  it("should show public dashboards with nested cards mapped to parameters (metabase#20393)", () => {
-    createDashboardWithNestedCard();
-
-    editDashboard();
-
-    setFilter("Time", "All Options");
-
-    // map the date parameter to the card
-    cy.findByTestId("dashcard-container").contains("Select").click();
-    popover().contains("CREATED_AT").click();
-
-    // save the dashboard
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Save").click();
-
-    // open the sharing modal and enable sharing
-    openNewPublicLinkDropdown("dashboard");
-
-    // navigate to the public dashboard link
-    cy.wait("@publicLink").then(({ response: { body } }) => {
-      const { uuid } = body;
-
-      cy.signOut();
-      cy.visit(`/public/dashboard/${uuid}`);
-    });
-
-    // verify that the card is visible on the page
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Q2");
-  });
-});
-
-function createDashboardWithNestedCard() {
-  cy.createNativeQuestion({
-    name: "Q1",
-    native: { query: 'SELECT * FROM "ORDERS"', "template-tags": {} },
-  }).then(({ body }) =>
-    cy
-      .createQuestionAndDashboard({
-        questionDetails: {
-          name: "Q2",
-          query: { "source-table": `card__${body.id}` },
-        },
-        dashboardDetails: {
-          name: "Q2 in a dashboard",
-        },
-      })
-      .then(({ body: { dashboard_id } }) => visitDashboard(dashboard_id)),
-  );
-}
diff --git a/e2e/test/scenarios/sharing/reproductions/21559-subscription-bar-sent-as-scalar.cy.spec.js b/e2e/test/scenarios/sharing/reproductions/21559-subscription-bar-sent-as-scalar.cy.spec.js
deleted file mode 100644
index 7a6553cef84..00000000000
--- a/e2e/test/scenarios/sharing/reproductions/21559-subscription-bar-sent-as-scalar.cy.spec.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import { USERS } from "e2e/support/cypress_data";
-import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import {
-  restore,
-  visitDashboard,
-  editDashboard,
-  saveDashboard,
-  setupSMTP,
-  sendEmailAndAssert,
-  chartPathWithFillColor,
-} from "e2e/support/helpers";
-
-const { admin } = USERS;
-
-const { ORDERS, ORDERS_ID, PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE;
-
-const q1Details = {
-  name: "21559-1",
-  query: {
-    "source-table": ORDERS_ID,
-    aggregation: [["avg", ["field", ORDERS.TOTAL, null]]],
-  },
-  display: "scalar",
-};
-
-const q2Details = {
-  name: "21559-2",
-  query: {
-    "source-table": PRODUCTS_ID,
-    aggregation: [["avg", ["field", PRODUCTS.PRICE, null]]],
-  },
-  display: "scalar",
-};
-
-describe("issue 21559", { tags: "@external" }, () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-
-    setupSMTP();
-
-    cy.createQuestionAndDashboard({
-      questionDetails: q1Details,
-    }).then(({ body: { dashboard_id } }) => {
-      cy.createQuestion(q2Details);
-
-      visitDashboard(dashboard_id);
-      editDashboard();
-    });
-  });
-
-  it("should respect dashboard card visualization (metabase#21559)", () => {
-    cy.findByTestId("add-series-button").click({ force: true });
-
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText(q2Details.name).click();
-    cy.findByTestId("add-series-modal").button("Done").click();
-
-    // Make sure visualization changed to bars
-    chartPathWithFillColor("#A989C5").should("have.length", 1);
-    chartPathWithFillColor("#88BF4D").should("have.length", 1);
-
-    saveDashboard();
-
-    cy.icon("subscription").click();
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Email it").click();
-
-    cy.findByPlaceholderText("Enter user names or email addresses")
-      .click()
-      .type(`${admin.first_name} ${admin.last_name}{enter}`)
-      .blur(); // blur is needed to close the popover
-
-    sendEmailAndAssert(email => {
-      expect(email.html).to.include("img"); // Bar chart is sent as img (inline attachment)
-      expect(email.html).not.to.include("80.52"); // Scalar displays its value in HTML
-    });
-  });
-});
diff --git a/e2e/test/scenarios/sharing/reproductions/22524-public-dashboard-updates-after-changing-parameters.cy.spec.js b/e2e/test/scenarios/sharing/reproductions/22524-public-dashboard-updates-after-changing-parameters.cy.spec.js
deleted file mode 100644
index eef5dbb233e..00000000000
--- a/e2e/test/scenarios/sharing/reproductions/22524-public-dashboard-updates-after-changing-parameters.cy.spec.js
+++ /dev/null
@@ -1,68 +0,0 @@
-import {
-  restore,
-  popover,
-  visitDashboard,
-  saveDashboard,
-  editDashboard,
-  setFilter,
-  openNewPublicLinkDropdown,
-} from "e2e/support/helpers";
-
-const questionDetails = {
-  name: "22524 question",
-  native: {
-    query: "select * from people where city = {{city}}",
-    "template-tags": {
-      city: {
-        id: "6d077d39-a420-fd14-0b0b-a5eb611ce1e0",
-        name: "city",
-        "display-name": "City",
-        type: "text",
-      },
-    },
-  },
-};
-
-describe("issue 22524", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-  });
-
-  it("update dashboard cards when changing parameters on publicly shared dashboards (metabase#22524)", () => {
-    cy.createNativeQuestionAndDashboard({ questionDetails }).then(
-      ({ body: { dashboard_id } }) => {
-        cy.intercept("POST", `/api/dashboard/${dashboard_id}/public_link`).as(
-          "publicLink",
-        );
-        visitDashboard(dashboard_id);
-      },
-    );
-
-    editDashboard();
-    setFilter("Text or Category", "Is");
-
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Select…").click();
-    popover().contains("City").click();
-
-    saveDashboard();
-
-    // Share dashboard
-    openNewPublicLinkDropdown("dashboard");
-
-    cy.wait("@publicLink").then(({ response: { body } }) => {
-      const { uuid } = body;
-
-      cy.signOut();
-      cy.visit(`/public/dashboard/${uuid}`);
-    });
-
-    // Set parameter value
-    cy.findByPlaceholderText("Text").clear().type("Rye{enter}");
-
-    // Check results
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("2-7900 Cuerno Verde Road");
-  });
-});
diff --git a/e2e/test/scenarios/sharing/reproductions/24223-remove-filter-defaults-on-subscriptions.cy.spec.js b/e2e/test/scenarios/sharing/reproductions/24223-remove-filter-defaults-on-subscriptions.cy.spec.js
deleted file mode 100644
index b24949b6309..00000000000
--- a/e2e/test/scenarios/sharing/reproductions/24223-remove-filter-defaults-on-subscriptions.cy.spec.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import { USERS } from "e2e/support/cypress_data";
-import { ORDERS_DASHBOARD_ID } from "e2e/support/cypress_sample_instance_data";
-import {
-  describeEE,
-  editDashboard,
-  popover,
-  restore,
-  saveDashboard,
-  sendEmailAndVisitIt,
-  setTokenFeatures,
-  setupSMTP,
-  setFilter,
-} from "e2e/support/helpers";
-
-const { admin } = USERS;
-
-describeEE("issue 24223", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-    setTokenFeatures("all");
-    setupSMTP();
-  });
-
-  it("should clear default filter", () => {
-    cy.visit(`/dashboard/${ORDERS_DASHBOARD_ID}`);
-    addParametersToDashboard();
-    cy.findByLabelText("subscriptions").click();
-    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Email it").click();
-    cy.findByPlaceholderText("Enter user names or email addresses")
-      .click()
-      .type(`${admin.first_name} ${admin.last_name}{enter}`)
-      .blur(); // blur is needed to close the popover
-
-    cy.wait(500); // we need to wait here for some reason for CI to pass
-
-    cy.findAllByText("Doohickey")
-      .last()
-      .closest("fieldset")
-      .icon("close")
-      .click();
-    cy.button("Done").click();
-
-    cy.get("[aria-label='Pulse Card']")
-      .findByText("Text contains is Awesome")
-      .click();
-
-    sendEmailAndVisitIt();
-    cy.get("table.header").within(() => {
-      cy.findByText("Text").should("not.exist");
-      cy.findByText("Awesome").parent().findByText("Text contains");
-    });
-  });
-});
-
-function addParametersToDashboard() {
-  editDashboard();
-
-  setFilter("Text or Category", "Is");
-
-  cy.findByText("Select…").click();
-  popover().findByText("Category").click();
-  cy.findByText("No default").click();
-  popover().within(() => {
-    cy.findByText("Doohickey").click();
-    cy.button("Add filter").click();
-  });
-
-  setFilter("Text or Category", "Contains", "Text contains");
-
-  cy.findByText("Select…").click();
-  popover().findByText("Title").click();
-  cy.findByText("No default").click();
-  popover().find("input").type("Awesome");
-  popover().button("Add filter").click();
-
-  saveDashboard();
-}
diff --git a/e2e/test/scenarios/sharing/reproductions/25473-dashboard-text-filter-asking-for-number.cy.spec.js b/e2e/test/scenarios/sharing/reproductions/25473-dashboard-text-filter-asking-for-number.cy.spec.js
deleted file mode 100644
index 8c3e4ec786f..00000000000
--- a/e2e/test/scenarios/sharing/reproductions/25473-dashboard-text-filter-asking-for-number.cy.spec.js
+++ /dev/null
@@ -1,116 +0,0 @@
-import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import {
-  restore,
-  visitEmbeddedPage,
-  filterWidget,
-  visitPublicDashboard,
-} from "e2e/support/helpers";
-
-const { REVIEWS, REVIEWS_ID } = SAMPLE_DATABASE;
-
-const ccName = "CC Reviewer";
-
-const dashboardFilter = {
-  name: "Text ends with",
-  slug: "text_ends_with",
-  id: "3a8ecdbd",
-  type: "string/ends-with",
-  sectionId: "string",
-};
-
-const questionDetails = {
-  name: "25473",
-  query: {
-    "source-table": REVIEWS_ID,
-    expressions: { [ccName]: ["field", REVIEWS.REVIEWER, null] },
-    limit: 10,
-    // Let's show only a few columns to make it easier to focus on the UI
-    fields: [
-      ["field", REVIEWS.REVIEWER, null],
-      ["field", REVIEWS.RATING, null],
-      ["field", REVIEWS.CREATED_AT, null],
-      ["expression", ccName, null],
-    ],
-  },
-};
-
-const dashboardDetails = {
-  name: "25473D",
-  parameters: [dashboardFilter],
-};
-
-describe("issue 25473", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-
-    cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then(
-      ({ body: { id, card_id, dashboard_id } }) => {
-        cy.request("PUT", `/api/dashboard/${dashboard_id}`, {
-          dashcards: [
-            {
-              id,
-              card_id,
-              row: 0,
-              col: 0,
-              size_x: 16,
-              size_y: 8,
-              series: [],
-              visualization_settings: {},
-              parameter_mappings: [
-                {
-                  parameter_id: dashboardFilter.id,
-                  card_id,
-                  target: ["dimension", ["expression", ccName, null]],
-                },
-              ],
-            },
-          ],
-        });
-
-        cy.wrap(dashboard_id).as("dashboardId");
-      },
-    );
-  });
-
-  it("public sharing: dashboard text filter on a custom column should accept text input (metabase#25473-1)", () => {
-    cy.get("@dashboardId").then(id => {
-      visitPublicDashboard(id);
-    });
-
-    assertOnResults();
-  });
-
-  it("signed embedding: dashboard text filter on a custom column should accept text input (metabase#25473-2)", () => {
-    cy.get("@dashboardId").then(id => {
-      cy.request("PUT", `/api/dashboard/${id}`, {
-        embedding_params: {
-          [dashboardFilter.slug]: "enabled",
-        },
-        enable_embedding: true,
-      });
-
-      const payload = {
-        resource: { dashboard: id },
-        params: {},
-      };
-
-      visitEmbeddedPage(payload);
-    });
-
-    assertOnResults();
-  });
-});
-
-function assertOnResults() {
-  cy.findAllByTestId("column-header").last().should("have.text", ccName);
-  cy.findAllByText("xavier").should("have.length", 2);
-
-  filterWidget().click();
-  cy.findByPlaceholderText("Enter some text").type("e").blur();
-  cy.button("Add filter").click();
-
-  cy.location("search").should("eq", `?${dashboardFilter.slug}=e`);
-  cy.findAllByText("xavier").should("not.exist");
-  cy.findAllByText("cameron.nitzsche").should("have.length", 2);
-}
diff --git a/e2e/test/scenarios/sharing/reproductions/26988-embedding-dynamic-settings.cy.spec.js b/e2e/test/scenarios/sharing/reproductions/26988-embedding-dynamic-settings.cy.spec.js
deleted file mode 100644
index 44b4652d46e..00000000000
--- a/e2e/test/scenarios/sharing/reproductions/26988-embedding-dynamic-settings.cy.spec.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
-import {
-  describeEE,
-  getIframeBody,
-  openStaticEmbeddingModal,
-  popover,
-  restore,
-  setTokenFeatures,
-  visitDashboard,
-} from "e2e/support/helpers";
-
-const { ORDERS_ID } = SAMPLE_DATABASE;
-
-describeEE("issue 26988", () => {
-  beforeEach(() => {
-    restore();
-    cy.intercept("GET", "/api/preview_embed/dashboard/*").as(
-      "previewDashboard",
-    );
-
-    cy.signInAsAdmin();
-    setTokenFeatures("all");
-  });
-
-  it("should apply embedding settings passed in URL on load", () => {
-    cy.createQuestionAndDashboard({
-      questionDetails: {
-        name: "Q1",
-        query: {
-          "source-table": ORDERS_ID,
-          limit: 3,
-        },
-      },
-      dashboardDetails: {
-        enable_embedding: true,
-      },
-    }).then(({ body: card }) => {
-      visitDashboard(card.dashboard_id);
-    });
-
-    openStaticEmbeddingModal({
-      activeTab: "appearance",
-      previewMode: "preview",
-      acceptTerms: false,
-    });
-
-    cy.wait("@previewDashboard");
-    getIframeBody().should("have.css", "font-family", "Lato, sans-serif");
-
-    cy.findByLabelText("Playing with appearance options")
-      .findByLabelText("Font")
-      .as("font-control")
-      .click();
-    popover().findByText("Oswald").click();
-
-    getIframeBody().should("have.css", "font-family", "Oswald, sans-serif");
-
-    cy.get("@font-control").click();
-    popover().findByText("Slabo 27px").click();
-
-    getIframeBody().should(
-      "have.css",
-      "font-family",
-      '"Slabo 27px", sans-serif',
-    );
-  });
-});
diff --git a/e2e/test/scenarios/sharing/reproductions/30314-new-subscription-form-state.cy.spec.js b/e2e/test/scenarios/sharing/reproductions/30314-new-subscription-form-state.cy.spec.js
deleted file mode 100644
index 40e0f3ad991..00000000000
--- a/e2e/test/scenarios/sharing/reproductions/30314-new-subscription-form-state.cy.spec.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import { ORDERS_DASHBOARD_ID } from "e2e/support/cypress_sample_instance_data";
-import {
-  visitDashboard,
-  restore,
-  setupSMTP,
-  dashboardHeader,
-  sidebar,
-} from "e2e/support/helpers";
-
-describe("issue 30314", () => {
-  beforeEach(() => {
-    restore();
-    cy.signInAsAdmin();
-    setupSMTP();
-  });
-
-  it("should clean the new subscription form on cancel (metabase#30314)", () => {
-    visitDashboard(ORDERS_DASHBOARD_ID);
-
-    dashboardHeader().findByLabelText("subscriptions").click();
-    sidebar().within(() => {
-      cy.findByText("Email it").click();
-
-      cy.findByLabelText("Attach results").should("not.be.checked").click();
-      cy.findByLabelText("Questions to attach")
-        .should("not.be.checked")
-        .click();
-
-      cy.button("Cancel").click();
-      cy.findByText("Email it").click();
-
-      cy.findByLabelText("Attach results").should("not.be.checked");
-      cy.findByText("Questions to attach").should("not.exist");
-      cy.findByText(".xlsx").should("not.exist");
-      cy.findByText(".csv").should("not.exist");
-    });
-  });
-});
diff --git a/e2e/test/scenarios/sharing/sharing-reproductions.cy.spec.js b/e2e/test/scenarios/sharing/sharing-reproductions.cy.spec.js
new file mode 100644
index 00000000000..62a057268a9
--- /dev/null
+++ b/e2e/test/scenarios/sharing/sharing-reproductions.cy.spec.js
@@ -0,0 +1,946 @@
+import { USERS, SAMPLE_DB_ID } from "e2e/support/cypress_data";
+import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
+import {
+  ORDERS_DASHBOARD_ID,
+  ADMIN_USER_ID,
+  ORDERS_DASHBOARD_DASHCARD_ID,
+  ORDERS_QUESTION_ID,
+} from "e2e/support/cypress_sample_instance_data";
+import {
+  restore,
+  popover,
+  setupSMTP,
+  visitDashboard,
+  sendEmailAndAssert,
+  sidebar,
+  editDashboard,
+  saveDashboard,
+  modal,
+  visitQuestion,
+  setTokenFeatures,
+  clickSend,
+  openNewPublicLinkDropdown,
+  setFilter,
+  describeEE,
+  chartPathWithFillColor,
+  sendEmailAndVisitIt,
+  visitPublicDashboard,
+  visitEmbeddedPage,
+  getIframeBody,
+  openStaticEmbeddingModal,
+  dashboardHeader,
+  filterWidget,
+  getFullName,
+} from "e2e/support/helpers";
+
+const { admin } = USERS;
+const {
+  ORDERS,
+  ORDERS_ID,
+  PRODUCTS,
+  PRODUCTS_ID,
+  REVIEWS,
+  REVIEWS_ID,
+  PEOPLE,
+} = SAMPLE_DATABASE;
+
+describe("issue 18009", { tags: "@external" }, () => {
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+
+    setupSMTP();
+
+    cy.signIn("nodata");
+  });
+
+  it("nodata user should be able to create and receive an email subscription without errors (metabase#18009)", () => {
+    visitDashboard(ORDERS_DASHBOARD_ID);
+
+    cy.findByLabelText("subscriptions").click();
+
+    sidebar()
+      .findByPlaceholderText("Enter user names or email addresses")
+      .click();
+    popover()
+      .contains(/^No Data/)
+      .click();
+
+    // Click anywhere to close the popover that covers the "Send email now" button
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("To:").click();
+
+    sendEmailAndAssert(email => {
+      expect(email.html).not.to.include(
+        "An error occurred while displaying this card.",
+      );
+
+      expect(email.html).to.include("37.65");
+    });
+  });
+});
+
+describe("issue 18344", { tags: "@external" }, () => {
+  const {
+    admin: { first_name, last_name },
+  } = USERS;
+
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+
+    setupSMTP();
+
+    // Rename the question
+    visitDashboard(ORDERS_DASHBOARD_ID);
+
+    editDashboard();
+
+    // Open visualization options
+    cy.findByTestId("dashcard").realHover();
+    cy.icon("palette").click();
+
+    modal().within(() => {
+      cy.findByDisplayValue("Orders").type("Foo").blur();
+
+      cy.button("Done").click();
+    });
+
+    saveDashboard();
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("OrdersFoo");
+  });
+
+  it("subscription should not include original question name when it's been renamed in the dashboard (metabase#18344)", () => {
+    // Send a test email subscription
+    cy.icon("subscription").click();
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Email it").click();
+
+    cy.findByPlaceholderText("Enter user names or email addresses").click();
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText(`${first_name} ${last_name}`).click();
+    // Click this just to close the popover that is blocking the "Send email now" button
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("To:").click();
+
+    sendEmailAndAssert(email => {
+      expect(email.html).to.include("OrdersFoo");
+    });
+  });
+});
+
+describe("issue 18352", { tags: "@external" }, () => {
+  const {
+    admin: { first_name, last_name },
+  } = USERS;
+
+  const questionDetails = {
+    name: "18352",
+    native: {
+      query: "SELECT 'foo', 1 UNION ALL SELECT 'bar', 2",
+    },
+  };
+
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+
+    setupSMTP();
+
+    cy.createNativeQuestionAndDashboard({ questionDetails }).then(
+      ({ body: { card_id, dashboard_id } }) => {
+        visitQuestion(card_id);
+
+        visitDashboard(dashboard_id);
+      },
+    );
+  });
+
+  it("should send the card with the INT64 values (metabase#18352)", () => {
+    cy.icon("subscription").click();
+
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Email it").click();
+
+    cy.findByPlaceholderText("Enter user names or email addresses").click();
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText(`${first_name} ${last_name}`).click();
+    // Click this just to close the popover that is blocking the "Send email now" button
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("To:").click();
+
+    sendEmailAndAssert(({ html }) => {
+      expect(html).not.to.include(
+        "An error occurred while displaying this card.",
+      );
+
+      expect(html).to.include("foo");
+      expect(html).to.include("bar");
+    });
+  });
+});
+
+describeEE("issue 18669", { tags: "@external" }, () => {
+  const questionDetails = {
+    name: "Product count",
+    database: SAMPLE_DB_ID,
+    type: "query",
+    query: {
+      "source-table": PRODUCTS_ID,
+      aggregation: [["count"]],
+    },
+  };
+
+  const filterDetails = {
+    name: "Category",
+    slug: "category",
+    id: "c32a49e1",
+    type: "category",
+    default: ["Doohickey"],
+  };
+
+  const dashboardDetails = {
+    parameters: [filterDetails],
+  };
+
+  const getFilterMapping = card => ({
+    parameter_mappings: [
+      {
+        parameter_id: filterDetails.id,
+        card_id: card.card_id,
+        target: ["dimension", ["field", PRODUCTS.CATEGORY, null]],
+      },
+    ],
+  });
+
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+    setTokenFeatures("all");
+    setupSMTP();
+
+    cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then(
+      ({ body: card }) => {
+        cy.editDashboardCard(card, getFilterMapping(card));
+        visitDashboard(card.dashboard_id);
+      },
+    );
+  });
+
+  it("should send a test email with non-default parameters (metabase#18669)", () => {
+    cy.icon("subscription").click();
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Email it").click();
+
+    cy.findByPlaceholderText("Enter user names or email addresses")
+      .click()
+      .type(`${admin.first_name} ${admin.last_name}{enter}`)
+      .blur();
+
+    sidebar().within(() => {
+      cy.findByText("Doohickey").click();
+    });
+
+    popover().within(() => {
+      cy.findByText("Gizmo").click();
+      cy.button("Update filter").click();
+    });
+
+    clickSend();
+  });
+});
+
+describe("issue 20393", () => {
+  function createDashboardWithNestedCard() {
+    cy.createNativeQuestion({
+      name: "Q1",
+      native: { query: 'SELECT * FROM "ORDERS"', "template-tags": {} },
+    }).then(({ body }) =>
+      cy
+        .createQuestionAndDashboard({
+          questionDetails: {
+            name: "Q2",
+            query: { "source-table": `card__${body.id}` },
+          },
+          dashboardDetails: {
+            name: "Q2 in a dashboard",
+          },
+        })
+        .then(({ body: { dashboard_id } }) => visitDashboard(dashboard_id)),
+    );
+  }
+
+  beforeEach(() => {
+    cy.intercept("POST", "/api/dashboard/*/public_link").as("publicLink");
+
+    restore();
+    cy.signInAsAdmin();
+  });
+
+  it("should show public dashboards with nested cards mapped to parameters (metabase#20393)", () => {
+    createDashboardWithNestedCard();
+
+    editDashboard();
+
+    setFilter("Time", "All Options");
+
+    // map the date parameter to the card
+    cy.findByTestId("dashcard-container").contains("Select").click();
+    popover().contains("CREATED_AT").click();
+
+    // save the dashboard
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Save").click();
+
+    // open the sharing modal and enable sharing
+    openNewPublicLinkDropdown("dashboard");
+
+    // navigate to the public dashboard link
+    cy.wait("@publicLink").then(({ response: { body } }) => {
+      const { uuid } = body;
+
+      cy.signOut();
+      cy.visit(`/public/dashboard/${uuid}`);
+    });
+
+    // verify that the card is visible on the page
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Q2");
+  });
+});
+
+describe("issue 21559", { tags: "@external" }, () => {
+  const q1Details = {
+    name: "21559-1",
+    query: {
+      "source-table": ORDERS_ID,
+      aggregation: [["avg", ["field", ORDERS.TOTAL, null]]],
+    },
+    display: "scalar",
+  };
+
+  const q2Details = {
+    name: "21559-2",
+    query: {
+      "source-table": PRODUCTS_ID,
+      aggregation: [["avg", ["field", PRODUCTS.PRICE, null]]],
+    },
+    display: "scalar",
+  };
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+
+    setupSMTP();
+
+    cy.createQuestionAndDashboard({
+      questionDetails: q1Details,
+    }).then(({ body: { dashboard_id } }) => {
+      cy.createQuestion(q2Details);
+
+      visitDashboard(dashboard_id);
+      editDashboard();
+    });
+  });
+
+  it("should respect dashboard card visualization (metabase#21559)", () => {
+    cy.findByTestId("add-series-button").click({ force: true });
+
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText(q2Details.name).click();
+    cy.findByTestId("add-series-modal").button("Done").click();
+
+    // Make sure visualization changed to bars
+    chartPathWithFillColor("#A989C5").should("have.length", 1);
+    chartPathWithFillColor("#88BF4D").should("have.length", 1);
+
+    saveDashboard();
+
+    cy.icon("subscription").click();
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Email it").click();
+
+    cy.findByPlaceholderText("Enter user names or email addresses")
+      .click()
+      .type(`${admin.first_name} ${admin.last_name}{enter}`)
+      .blur(); // blur is needed to close the popover
+
+    sendEmailAndAssert(email => {
+      expect(email.html).to.include("img"); // Bar chart is sent as img (inline attachment)
+      expect(email.html).not.to.include("80.52"); // Scalar displays its value in HTML
+    });
+  });
+});
+describe("issue 22524", () => {
+  const questionDetails = {
+    name: "22524 question",
+    native: {
+      query: "select * from people where city = {{city}}",
+      "template-tags": {
+        city: {
+          id: "6d077d39-a420-fd14-0b0b-a5eb611ce1e0",
+          name: "city",
+          "display-name": "City",
+          type: "text",
+        },
+      },
+    },
+  };
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+  });
+
+  it("update dashboard cards when changing parameters on publicly shared dashboards (metabase#22524)", () => {
+    cy.createNativeQuestionAndDashboard({ questionDetails }).then(
+      ({ body: { dashboard_id } }) => {
+        cy.intercept("POST", `/api/dashboard/${dashboard_id}/public_link`).as(
+          "publicLink",
+        );
+        visitDashboard(dashboard_id);
+      },
+    );
+
+    editDashboard();
+    setFilter("Text or Category", "Is");
+
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Select…").click();
+    popover().contains("City").click();
+
+    saveDashboard();
+
+    // Share dashboard
+    openNewPublicLinkDropdown("dashboard");
+
+    cy.wait("@publicLink").then(({ response: { body } }) => {
+      const { uuid } = body;
+
+      cy.signOut();
+      cy.visit(`/public/dashboard/${uuid}`);
+    });
+
+    // Set parameter value
+    cy.findByPlaceholderText("Text").clear().type("Rye{enter}");
+
+    // Check results
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("2-7900 Cuerno Verde Road");
+  });
+});
+
+describeEE("issue 24223", () => {
+  function addParametersToDashboard() {
+    editDashboard();
+
+    setFilter("Text or Category", "Is");
+
+    cy.findByText("Select…").click();
+    popover().findByText("Category").click();
+    cy.findByText("No default").click();
+    popover().within(() => {
+      cy.findByText("Doohickey").click();
+      cy.button("Add filter").click();
+    });
+
+    setFilter("Text or Category", "Contains", "Text contains");
+
+    cy.findByText("Select…").click();
+    popover().findByText("Title").click();
+    cy.findByText("No default").click();
+    popover().find("input").type("Awesome");
+    popover().button("Add filter").click();
+
+    saveDashboard();
+  }
+
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+    setTokenFeatures("all");
+    setupSMTP();
+  });
+
+  it("should clear default filter", () => {
+    cy.visit(`/dashboard/${ORDERS_DASHBOARD_ID}`);
+    addParametersToDashboard();
+    cy.findByLabelText("subscriptions").click();
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Email it").click();
+    cy.findByPlaceholderText("Enter user names or email addresses")
+      .click()
+      .type(`${admin.first_name} ${admin.last_name}{enter}`)
+      .blur(); // blur is needed to close the popover
+
+    cy.wait(500); // we need to wait here for some reason for CI to pass
+
+    cy.findAllByText("Doohickey")
+      .last()
+      .closest("fieldset")
+      .icon("close")
+      .click();
+    cy.button("Done").click();
+
+    cy.get("[aria-label='Pulse Card']")
+      .findByText("Text contains is Awesome")
+      .click();
+
+    sendEmailAndVisitIt();
+    cy.get("table.header").within(() => {
+      cy.findByText("Text").should("not.exist");
+      cy.findByText("Awesome").parent().findByText("Text contains");
+    });
+  });
+});
+
+describe("issue 25473", () => {
+  const ccName = "CC Reviewer";
+
+  const dashboardFilter = {
+    name: "Text ends with",
+    slug: "text_ends_with",
+    id: "3a8ecdbd",
+    type: "string/ends-with",
+    sectionId: "string",
+  };
+
+  const questionDetails = {
+    name: "25473",
+    query: {
+      "source-table": REVIEWS_ID,
+      expressions: { [ccName]: ["field", REVIEWS.REVIEWER, null] },
+      limit: 10,
+      // Let's show only a few columns to make it easier to focus on the UI
+      fields: [
+        ["field", REVIEWS.REVIEWER, null],
+        ["field", REVIEWS.RATING, null],
+        ["field", REVIEWS.CREATED_AT, null],
+        ["expression", ccName, null],
+      ],
+    },
+  };
+
+  const dashboardDetails = {
+    name: "25473D",
+    parameters: [dashboardFilter],
+  };
+
+  function assertOnResults() {
+    cy.findAllByTestId("column-header").last().should("have.text", ccName);
+    cy.findAllByText("xavier").should("have.length", 2);
+
+    filterWidget().click();
+    cy.findByPlaceholderText("Enter some text").type("e").blur();
+    cy.button("Add filter").click();
+
+    cy.location("search").should("eq", `?${dashboardFilter.slug}=e`);
+    cy.findAllByText("xavier").should("not.exist");
+    cy.findAllByText("cameron.nitzsche").should("have.length", 2);
+  }
+
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+
+    cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then(
+      ({ body: { id, card_id, dashboard_id } }) => {
+        cy.request("PUT", `/api/dashboard/${dashboard_id}`, {
+          dashcards: [
+            {
+              id,
+              card_id,
+              row: 0,
+              col: 0,
+              size_x: 16,
+              size_y: 8,
+              series: [],
+              visualization_settings: {},
+              parameter_mappings: [
+                {
+                  parameter_id: dashboardFilter.id,
+                  card_id,
+                  target: ["dimension", ["expression", ccName, null]],
+                },
+              ],
+            },
+          ],
+        });
+
+        cy.wrap(dashboard_id).as("dashboardId");
+      },
+    );
+  });
+
+  it("public sharing: dashboard text filter on a custom column should accept text input (metabase#25473-1)", () => {
+    cy.get("@dashboardId").then(id => {
+      visitPublicDashboard(id);
+    });
+
+    assertOnResults();
+  });
+
+  it("signed embedding: dashboard text filter on a custom column should accept text input (metabase#25473-2)", () => {
+    cy.get("@dashboardId").then(id => {
+      cy.request("PUT", `/api/dashboard/${id}`, {
+        embedding_params: {
+          [dashboardFilter.slug]: "enabled",
+        },
+        enable_embedding: true,
+      });
+
+      const payload = {
+        resource: { dashboard: id },
+        params: {},
+      };
+
+      visitEmbeddedPage(payload);
+    });
+
+    assertOnResults();
+  });
+});
+
+describeEE("issue 26988", () => {
+  beforeEach(() => {
+    restore();
+    cy.intercept("GET", "/api/preview_embed/dashboard/*").as(
+      "previewDashboard",
+    );
+
+    cy.signInAsAdmin();
+    setTokenFeatures("all");
+  });
+
+  it("should apply embedding settings passed in URL on load", () => {
+    cy.createQuestionAndDashboard({
+      questionDetails: {
+        name: "Q1",
+        query: {
+          "source-table": ORDERS_ID,
+          limit: 3,
+        },
+      },
+      dashboardDetails: {
+        enable_embedding: true,
+      },
+    }).then(({ body: card }) => {
+      visitDashboard(card.dashboard_id);
+    });
+
+    openStaticEmbeddingModal({
+      activeTab: "appearance",
+      previewMode: "preview",
+      acceptTerms: false,
+    });
+
+    cy.wait("@previewDashboard");
+    getIframeBody().should("have.css", "font-family", "Lato, sans-serif");
+
+    cy.findByLabelText("Playing with appearance options")
+      .findByLabelText("Font")
+      .as("font-control")
+      .click();
+    popover().findByText("Oswald").click();
+
+    getIframeBody().should("have.css", "font-family", "Oswald, sans-serif");
+
+    cy.get("@font-control").click();
+    popover().findByText("Slabo 27px").click();
+
+    getIframeBody().should(
+      "have.css",
+      "font-family",
+      '"Slabo 27px", sans-serif',
+    );
+  });
+});
+
+describe("issue 30314", () => {
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+    setupSMTP();
+  });
+
+  it("should clean the new subscription form on cancel (metabase#30314)", () => {
+    visitDashboard(ORDERS_DASHBOARD_ID);
+
+    dashboardHeader().findByLabelText("subscriptions").click();
+    sidebar().within(() => {
+      cy.findByText("Email it").click();
+
+      cy.findByLabelText("Attach results").should("not.be.checked").click();
+      cy.findByLabelText("Questions to attach")
+        .should("not.be.checked")
+        .click();
+
+      cy.button("Cancel").click();
+      cy.findByText("Email it").click();
+
+      cy.findByLabelText("Attach results").should("not.be.checked");
+      cy.findByText("Questions to attach").should("not.exist");
+      cy.findByText(".xlsx").should("not.exist");
+      cy.findByText(".csv").should("not.exist");
+    });
+  });
+});
+
+describe("issue 17657", () => {
+  const { first_name, last_name } = admin;
+
+  function createSubscriptionWithoutRecipients() {
+    cy.request("POST", "/api/pulse", {
+      name: "Orders in a dashboard",
+      cards: [
+        {
+          id: ORDERS_QUESTION_ID,
+          collection_id: null,
+          description: null,
+          display: "table",
+          name: "Orders",
+          include_csv: false,
+          include_xls: false,
+          dashboard_card_id: 1,
+          dashboard_id: ORDERS_DASHBOARD_ID,
+          parameter_mappings: [],
+        },
+      ],
+      channels: [
+        {
+          channel_type: "email",
+          enabled: true,
+          // Since the fix (https://github.com/metabase/metabase/pull/17668), this is not even possible to do in the UI anymore.
+          // Backend still doesn't do this validation so we're making sure the FE handles the case of missing recipients gracefully.
+          recipients: [],
+          details: {},
+          schedule_type: "monthly",
+          schedule_day: "mon",
+          schedule_hour: 8,
+          schedule_frame: "first",
+        },
+      ],
+      skip_if_empty: false,
+      collection_id: null,
+      parameters: [],
+      dashboard_id: ORDERS_DASHBOARD_ID,
+    });
+  }
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+
+    createSubscriptionWithoutRecipients();
+  });
+
+  it("frontend should gracefully handle the case of a subscription without a recipient (metabase#17657)", () => {
+    visitDashboard(ORDERS_DASHBOARD_ID);
+
+    cy.icon("subscription").click();
+
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText(/^Emailed monthly/).click();
+
+    sidebar().within(() => {
+      cy.button("Done").should("be.disabled");
+    });
+
+    // Open the popover with all users
+    cy.findByPlaceholderText("Enter user names or email addresses").click();
+    // Pick admin as a recipient
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText(`${first_name} ${last_name}`).click();
+
+    sidebar().within(() => {
+      cy.button("Done").should("not.be.disabled");
+    });
+  });
+});
+
+describe("issue 17658", { tags: "@external" }, () => {
+  function moveDashboardToCollection(collectionName) {
+    const { first_name, last_name, email } = admin;
+
+    cy.request("GET", "/api/collection/tree?tree=true").then(
+      ({ body: collections }) => {
+        const { id } = collections.find(
+          collection => collection.name === collectionName,
+        );
+
+        // Move dashboard
+        cy.request("PUT", `/api/dashboard/${ORDERS_DASHBOARD_ID}`, {
+          collection_id: id,
+        });
+
+        // Create subscription
+        cy.request("POST", "/api/pulse", {
+          name: "Orders in a dashboard",
+          cards: [
+            {
+              id: ORDERS_QUESTION_ID,
+              collection_id: null,
+              description: null,
+              display: "table",
+              name: "Orders",
+              include_csv: false,
+              include_xls: false,
+              dashboard_card_id: ORDERS_DASHBOARD_DASHCARD_ID,
+              dashboard_id: ORDERS_DASHBOARD_ID,
+              parameter_mappings: [],
+            },
+          ],
+          channels: [
+            {
+              channel_type: "email",
+              enabled: true,
+              recipients: [
+                {
+                  id: ADMIN_USER_ID,
+                  email,
+                  first_name,
+                  last_name,
+                  common_name: getFullName(admin),
+                },
+              ],
+              details: {},
+              schedule_type: "monthly",
+              schedule_day: "mon",
+              schedule_hour: 8,
+              schedule_frame: "first",
+            },
+          ],
+          skip_if_empty: false,
+          collection_id: id,
+          parameters: [],
+          dashboard_id: ORDERS_DASHBOARD_ID,
+        });
+      },
+    );
+  }
+
+  beforeEach(() => {
+    cy.intercept("PUT", "/api/pulse/*").as("deletePulse");
+    restore();
+    cy.signInAsAdmin();
+
+    setupSMTP();
+
+    moveDashboardToCollection("First collection");
+  });
+
+  it("should delete dashboard subscription from any collection (metabase#17658)", () => {
+    visitDashboard(ORDERS_DASHBOARD_ID);
+
+    cy.icon("subscription").click();
+
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText(/^Emailed monthly/).click();
+
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Delete this subscription").click();
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText(/^This dashboard will no longer be emailed to/).click();
+
+    cy.button("Delete").click();
+
+    cy.wait("@deletePulse").then(({ response }) => {
+      expect(response.body.cause).not.to.exist;
+      expect(response.statusCode).not.to.eq(500);
+    });
+
+    cy.button("Delete").should("not.exist");
+  });
+});
+
+describe("issue 17547", () => {
+  const questionDetails = {
+    query: {
+      "source-table": ORDERS_ID,
+      breakout: [
+        ["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }],
+        ["field", PEOPLE.SOURCE, { "source-field": ORDERS.USER_ID }],
+      ],
+      aggregation: [["count"]],
+    },
+    display: "area",
+  };
+
+  function setUpAlert(questionId) {
+    cy.request("POST", "/api/alert", {
+      channels: [
+        {
+          schedule_type: "daily",
+          schedule_hour: 12,
+          channel_type: "slack",
+          schedule_frame: null,
+          recipients: [],
+          details: { channel: "#work" },
+          pulse_id: 1,
+          id: 1,
+          schedule_day: null,
+          enabled: true,
+        },
+      ],
+      alert_condition: "rows",
+      name: null,
+      creator_id: ADMIN_USER_ID,
+      card: { id: questionId, include_csv: true, include_xls: false },
+      alert_first_only: false,
+      skip_if_empty: true,
+      parameters: [],
+      dashboard_id: null,
+    }).then(({ body: { id: alertId } }) => {
+      cy.intercept("PUT", `/api/alert/${alertId}`).as("alertQuery");
+    });
+  }
+
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+
+    cy.createQuestion(questionDetails).then(({ body: { id: questionId } }) => {
+      setUpAlert(questionId);
+
+      visitQuestion(questionId);
+    });
+  });
+
+  it("editing an alert should not delete it (metabase#17547)", () => {
+    cy.icon("bell").click();
+    popover().within(() => {
+      cy.findByText("Daily, 12:00 PM");
+      cy.findByText("Edit").click();
+    });
+
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("AM").click();
+    cy.button("Save changes").click();
+
+    cy.wait("@alertQuery");
+
+    cy.icon("bell").click();
+    popover().within(() => {
+      cy.findByText("Daily, 12:00 AM");
+    });
+  });
+});
+
+describe("issue 16108", () => {
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+  });
+
+  it("should display a tooltip for CTA icons on an individual question (metabase#16108)", () => {
+    visitQuestion(ORDERS_QUESTION_ID);
+    cy.icon("download").realHover();
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Download full results");
+    cy.icon("bell").realHover();
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Get alerts");
+    cy.icon("share").realHover();
+    // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+    cy.findByText("Sharing");
+  });
+});
-- 
GitLab