From 6676158dfc9bc678501e9ecf9b3a99b20f406148 Mon Sep 17 00:00:00 2001
From: Ryan Laurie <30528226+iethree@users.noreply.github.com>
Date: Tue, 14 Nov 2023 23:53:46 -0700
Subject: [PATCH] Quarantine Flaky e2e Tests (#35676)

* add special flaky group

* tag tests with flakes over 10%

* mark more flaky jobs
---
 .github/actions/build-e2e-matrix/action.yml   |   1 +
 .github/workflows/e2e-tests.yml               |  10 +-
 .../actions/actions-on-dashboards.cy.spec.js  | 158 +++----
 .../dashboard-cards/click-behavior.cy.spec.js | 242 +++++------
 .../dashboard-card-resizing.cy.spec.js        | 140 ++++---
 .../embedding/embedding-smoketests.cy.spec.js | 150 +++----
 .../models/models-metadata.cy.spec.js         |   2 +-
 .../native/native_subquery.cy.spec.js         |  34 +-
 .../search/recently-viewed.cy.spec.js         |   4 +-
 e2e/test/scenarios/onboarding/urls.cy.spec.js |   2 +-
 .../permissions/sandboxes.cy.spec.js          | 386 +++++++++---------
 .../sharing/subscriptions.cy.spec.js          | 140 ++++---
 .../pivot_tables.cy.spec.js                   |   2 +-
 13 files changed, 660 insertions(+), 611 deletions(-)

diff --git a/.github/actions/build-e2e-matrix/action.yml b/.github/actions/build-e2e-matrix/action.yml
index 9108f991ab1..edb2636f7e1 100644
--- a/.github/actions/build-e2e-matrix/action.yml
+++ b/.github/actions/build-e2e-matrix/action.yml
@@ -50,6 +50,7 @@ runs:
             ["visualizations-tabular", {} ],
             ["oss-subset", { edition: 'oss', context: "special" } ],
             ["slow", { runner: beefierRunner, context: "special" } ],
+            ["flaky", { runner: beefierRunner, context: "special" } ],
             ["mongo", { context: "qa-database" } ],
           ];
 
diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml
index a9670da171a..636c011e82c 100644
--- a/.github/workflows/e2e-tests.yml
+++ b/.github/workflows/e2e-tests.yml
@@ -173,11 +173,19 @@ jobs:
           --spec './e2e/test/scenarios/**/*.cy.spec.js' \
           --browser ${{ steps.cypress-prep.outputs.chrome-path }}
 
+      - name: Run Flaky Cypress tests
+        if: matrix.name == 'flaky' && github.event_name != 'schedule'
+        run: |
+          yarn run test-cypress-run \
+          --env grepTags="@flaky",grepOmitFiltered=true \
+          --spec './e2e/test/scenarios/**/*.cy.spec.js' \
+          --browser ${{ steps.cypress-prep.outputs.chrome-path }}
+
       - name: Run EE Cypress tests on ${{ matrix.name }}
         if: matrix.context == 'folder' && github.event_name != 'schedule'
         run: |
           yarn run test-cypress-run \
-          --env grepTags="-@slow+-@mongo --@quarantine",grepOmitFiltered=true \
+          --env grepTags="-@slow+-@mongo+-@flaky --@quarantine",grepOmitFiltered=true \
           --folder ${{ matrix.name }} \
           --browser ${{ steps.cypress-prep.outputs.chrome-path }}
 
diff --git a/e2e/test/scenarios/actions/actions-on-dashboards.cy.spec.js b/e2e/test/scenarios/actions/actions-on-dashboards.cy.spec.js
index b327224d56b..7898669b3d1 100644
--- a/e2e/test/scenarios/actions/actions-on-dashboards.cy.spec.js
+++ b/e2e/test/scenarios/actions/actions-on-dashboards.cy.spec.js
@@ -476,101 +476,105 @@ const MODEL_NAME = "Test Action Model";
           });
         });
 
-        it("can update various data types via implicit actions", () => {
-          cy.get("@modelId").then(id => {
-            createImplicitAction({
-              kind: "update",
-              model_id: id,
+        it(
+          "can update various data types via implicit actions",
+          { tags: "@flaky" },
+          () => {
+            cy.get("@modelId").then(id => {
+              createImplicitAction({
+                kind: "update",
+                model_id: id,
+              });
             });
-          });
 
-          createDashboardWithActionButton({
-            actionName: "Update",
-            idFilter: true,
-          });
+            createDashboardWithActionButton({
+              actionName: "Update",
+              idFilter: true,
+            });
 
-          filterWidget().click();
-          addWidgetStringFilter("1");
+            filterWidget().click();
+            addWidgetStringFilter("1");
 
-          cy.findByRole("button", { name: "Update" }).click();
+            cy.findByRole("button", { name: "Update" }).click();
 
-          cy.wait("@prefetchValues");
+            cy.wait("@prefetchValues");
 
-          const oldRow = many_data_types_rows[0];
+            const oldRow = many_data_types_rows[0];
 
-          modal().within(() => {
-            changeValue({
-              fieldName: "UUID",
-              fieldType: "text",
-              oldValue: oldRow.uuid,
-              newValue: "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a77",
-            });
+            modal().within(() => {
+              changeValue({
+                fieldName: "UUID",
+                fieldType: "text",
+                oldValue: oldRow.uuid,
+                newValue: "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a77",
+              });
 
-            changeValue({
-              fieldName: "Integer",
-              fieldType: "number",
-              oldValue: oldRow.integer,
-              newValue: 123,
-            });
+              changeValue({
+                fieldName: "Integer",
+                fieldType: "number",
+                oldValue: oldRow.integer,
+                newValue: 123,
+              });
 
-            changeValue({
-              fieldName: "Float",
-              fieldType: "number",
-              oldValue: oldRow.float,
-              newValue: 2.2,
-            });
+              changeValue({
+                fieldName: "Float",
+                fieldType: "number",
+                oldValue: oldRow.float,
+                newValue: 2.2,
+              });
 
-            cy.findByLabelText("Boolean").should("be.checked").click();
+              cy.findByLabelText("Boolean").should("be.checked").click();
 
-            changeValue({
-              fieldName: "String",
-              fieldType: "text",
-              oldValue: oldRow.string,
-              newValue: "new string",
-            });
+              changeValue({
+                fieldName: "String",
+                fieldType: "text",
+                oldValue: oldRow.string,
+                newValue: "new string",
+              });
 
-            changeValue({
-              fieldName: "Date",
-              fieldType: "date",
-              oldValue: oldRow.date,
-              newValue: "2020-05-01",
-            });
+              changeValue({
+                fieldName: "Date",
+                fieldType: "date",
+                oldValue: oldRow.date,
+                newValue: "2020-05-01",
+              });
 
-            // we can't assert on this value because mysql and postgres seem to
-            // handle timezones differently 🥴
-            cy.findByPlaceholderText("TimestampTZ")
-              .should("have.attr", "type", "datetime-local")
-              .clear()
-              .type("2020-05-01T16:45:00");
+              // we can't assert on this value because mysql and postgres seem to
+              // handle timezones differently 🥴
+              cy.findByPlaceholderText("TimestampTZ")
+                .should("have.attr", "type", "datetime-local")
+                .clear()
+                .type("2020-05-01T16:45:00");
 
-            cy.button("Update").click();
-          });
+              cy.button("Update").click();
+            });
 
-          cy.wait("@executeAction");
+            cy.wait("@executeAction");
 
-          queryWritableDB(
-            `SELECT * FROM ${TEST_COLUMNS_TABLE} WHERE id = 1`,
-            dialect,
-          ).then(result => {
-            expect(result.rows.length).to.equal(1);
+            queryWritableDB(
+              `SELECT * FROM ${TEST_COLUMNS_TABLE} WHERE id = 1`,
+              dialect,
+            ).then(result => {
+              expect(result.rows.length).to.equal(1);
 
-            const row = result.rows[0];
+              const row = result.rows[0];
 
-            expect(row).to.have.property(
-              "uuid",
-              "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a77",
-            );
-            expect(row).to.have.property("integer", 123);
-            expect(row).to.have.property("float", 2.2);
-            expect(row).to.have.property("string", "new string");
-            expect(row).to.have.property(
-              "boolean",
-              dialect === "mysql" ? 0 : false,
-            );
-            expect(row.date).to.include("2020-05-01"); // js converts this to a full date obj
-            expect(row.timestampTZ).to.include("2020-05-01"); // we got timezone issues here
-          });
-        });
+              expect(row).to.have.property(
+                "uuid",
+                "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a77",
+              );
+              expect(row).to.have.property("integer", 123);
+              expect(row).to.have.property("float", 2.2);
+              expect(row).to.have.property("string", "new string");
+              expect(row).to.have.property(
+                "boolean",
+                dialect === "mysql" ? 0 : false,
+              );
+              expect(row.date).to.include("2020-05-01"); // js converts this to a full date obj
+              expect(row.timestampTZ).to.include("2020-05-01"); // we got timezone issues here
+            });
+          },
+        );
 
         it("can insert various data types via implicit actions", () => {
           cy.get("@modelId").then(id => {
diff --git a/e2e/test/scenarios/dashboard-cards/click-behavior.cy.spec.js b/e2e/test/scenarios/dashboard-cards/click-behavior.cy.spec.js
index 8c647c8a361..7a0efd546f2 100644
--- a/e2e/test/scenarios/dashboard-cards/click-behavior.cy.spec.js
+++ b/e2e/test/scenarios/dashboard-cards/click-behavior.cy.spec.js
@@ -925,129 +925,135 @@ describe("scenarios > dashboard > dashboard cards > click behavior", () => {
         .should("have.text", "Open the drill-through menu");
     });
 
-    it("should allow setting dashboard and saved question as custom destination for different columns", () => {
-      cy.createQuestion(TARGET_QUESTION);
-      cy.createDashboard(
-        {
-          ...TARGET_DASHBOARD,
-          parameters: [DASHBOARD_FILTER_TEXT, DASHBOARD_FILTER_TIME],
-        },
-        {
-          wrapId: true,
-          idAlias: "targetDashboardId",
-        },
-      );
-      cy.createQuestionAndDashboard({ questionDetails }).then(
-        ({ body: card }) => {
-          visitDashboard(card.dashboard_id);
-        },
-      );
-
-      editDashboard();
-
-      getDashboardCard().realHover().icon("click").click();
-
-      (function addCustomDashboardDestination() {
-        cy.log("custom destination (dashboard) behavior for 'Count' column");
-
-        getCountToDashboardMapping().should("not.exist");
-        cy.get("aside").findByText(COUNT_COLUMN_NAME).click();
-        addDashboardDestination();
-        cy.get("aside")
-          .findByText("Select a dashboard tab")
-          .should("not.exist");
-        cy.get("aside").findByText("No available targets").should("not.exist");
-        addTextParameter();
-        addTimeParameter();
-        cy.get("aside")
-          .findByRole("textbox")
-          .type(`Count: {{${COUNT_COLUMN_ID}}}`, {
-            parseSpecialCharSequences: false,
-          });
-
-        cy.icon("chevronleft").click();
-
-        getCountToDashboardMapping().should("exist");
-        getDashboardCard()
-          .button()
-          .should("have.text", "1 column has custom behavior");
-      })();
-
-      (function addCustomQuestionDestination() {
-        cy.log(
-          "custom destination (question) behavior for 'Created at' column",
+    it(
+      "should allow setting dashboard and saved question as custom destination for different columns",
+      { tags: "@flaky" },
+      () => {
+        cy.createQuestion(TARGET_QUESTION);
+        cy.createDashboard(
+          {
+            ...TARGET_DASHBOARD,
+            parameters: [DASHBOARD_FILTER_TEXT, DASHBOARD_FILTER_TIME],
+          },
+          {
+            wrapId: true,
+            idAlias: "targetDashboardId",
+          },
+        );
+        cy.createQuestionAndDashboard({ questionDetails }).then(
+          ({ body: card }) => {
+            visitDashboard(card.dashboard_id);
+          },
         );
 
-        getCreatedAtToQuestionMapping().should("not.exist");
-        cy.get("aside").findByText(CREATED_AT_COLUMN_NAME).click();
-        /**
-         * TODO: remove the next line when metabase#34845 is fixed
-         * @see https://github.com/metabase/metabase/issues/34845
-         */
-        cy.get("aside").findByText("Unknown").click();
-        addSavedQuestionDestination();
-        addSavedQuestionCreatedAtParameter();
-        addSavedQuestionQuantityParameter();
-        cy.get("aside")
-          .findByRole("textbox")
-          .type(`Created at: {{${CREATED_AT_COLUMN_ID}}}`, {
-            parseSpecialCharSequences: false,
-          });
-
-        cy.icon("chevronleft").click();
-
-        getCreatedAtToQuestionMapping().should("exist");
-        getDashboardCard()
-          .button()
-          .should("have.text", "2 columns have custom behavior");
-      })();
-
-      cy.get("aside").button("Done").click();
-      saveDashboard();
-
-      (function testDashboardDestinationClick() {
-        cy.log("it handles 'Count' column click");
+        editDashboard();
+
+        getDashboardCard().realHover().icon("click").click();
+
+        (function addCustomDashboardDestination() {
+          cy.log("custom destination (dashboard) behavior for 'Count' column");
+
+          getCountToDashboardMapping().should("not.exist");
+          cy.get("aside").findByText(COUNT_COLUMN_NAME).click();
+          addDashboardDestination();
+          cy.get("aside")
+            .findByText("Select a dashboard tab")
+            .should("not.exist");
+          cy.get("aside")
+            .findByText("No available targets")
+            .should("not.exist");
+          addTextParameter();
+          addTimeParameter();
+          cy.get("aside")
+            .findByRole("textbox")
+            .type(`Count: {{${COUNT_COLUMN_ID}}}`, {
+              parseSpecialCharSequences: false,
+            });
+
+          cy.icon("chevronleft").click();
+
+          getCountToDashboardMapping().should("exist");
+          getDashboardCard()
+            .button()
+            .should("have.text", "1 column has custom behavior");
+        })();
+
+        (function addCustomQuestionDestination() {
+          cy.log(
+            "custom destination (question) behavior for 'Created at' column",
+          );
 
-        getTableCell(COLUMN_INDEX.COUNT)
-          .should("have.text", `Count: ${POINT_COUNT}`)
-          .click();
-        cy.findAllByTestId("field-set")
-          .should("have.length", 2)
-          .should("contain.text", POINT_COUNT)
-          .should("contain.text", POINT_CREATED_AT_FORMATTED);
-        cy.get("@targetDashboardId").then(targetDashboardId => {
-          cy.location().should(({ pathname, search }) => {
-            expect(pathname).to.equal(`/dashboard/${targetDashboardId}`);
-            expect(search).to.equal(
-              `?${DASHBOARD_FILTER_TEXT.slug}=${POINT_COUNT}&${DASHBOARD_FILTER_TIME.slug}=${POINT_CREATED_AT}`,
-            );
+          getCreatedAtToQuestionMapping().should("not.exist");
+          cy.get("aside").findByText(CREATED_AT_COLUMN_NAME).click();
+          /**
+           * TODO: remove the next line when metabase#34845 is fixed
+           * @see https://github.com/metabase/metabase/issues/34845
+           */
+          cy.get("aside").findByText("Unknown").click();
+          addSavedQuestionDestination();
+          addSavedQuestionCreatedAtParameter();
+          addSavedQuestionQuantityParameter();
+          cy.get("aside")
+            .findByRole("textbox")
+            .type(`Created at: {{${CREATED_AT_COLUMN_ID}}}`, {
+              parseSpecialCharSequences: false,
+            });
+
+          cy.icon("chevronleft").click();
+
+          getCreatedAtToQuestionMapping().should("exist");
+          getDashboardCard()
+            .button()
+            .should("have.text", "2 columns have custom behavior");
+        })();
+
+        cy.get("aside").button("Done").click();
+        saveDashboard();
+
+        (function testDashboardDestinationClick() {
+          cy.log("it handles 'Count' column click");
+
+          getTableCell(COLUMN_INDEX.COUNT)
+            .should("have.text", `Count: ${POINT_COUNT}`)
+            .click();
+          cy.findAllByTestId("field-set")
+            .should("have.length", 2)
+            .should("contain.text", POINT_COUNT)
+            .should("contain.text", POINT_CREATED_AT_FORMATTED);
+          cy.get("@targetDashboardId").then(targetDashboardId => {
+            cy.location().should(({ pathname, search }) => {
+              expect(pathname).to.equal(`/dashboard/${targetDashboardId}`);
+              expect(search).to.equal(
+                `?${DASHBOARD_FILTER_TEXT.slug}=${POINT_COUNT}&${DASHBOARD_FILTER_TIME.slug}=${POINT_CREATED_AT}`,
+              );
+            });
           });
-        });
-      })();
-
-      cy.go("back");
-
-      (function testQuestionDestinationClick() {
-        cy.log("it handles 'Created at' column click");
-
-        getTableCell(COLUMN_INDEX.CREATED_AT)
-          .should("have.text", `Created at: ${POINT_CREATED_AT_FORMATTED}`)
-          .click();
-        cy.findByTestId("qb-filters-panel")
-          .should("contain.text", "Created At is August 1–31, 2022")
-          .should("contain.text", "Quantity is equal to 79");
-        cy.location().should(({ hash, pathname }) => {
-          expect(pathname).to.equal("/question");
-          const card = deserializeCardFromUrl(hash);
-          expect(card.name).to.deep.equal(TARGET_QUESTION.name);
-          expect(card.display).to.deep.equal(TARGET_QUESTION.display);
-          expect(card.dataset_query.query).to.deep.equal({
-            ...TARGET_QUESTION.query,
-            filter: ["and", QUERY_FILTER_CREATED_AT, QUERY_FILTER_QUANTITY],
+        })();
+
+        cy.go("back");
+
+        (function testQuestionDestinationClick() {
+          cy.log("it handles 'Created at' column click");
+
+          getTableCell(COLUMN_INDEX.CREATED_AT)
+            .should("have.text", `Created at: ${POINT_CREATED_AT_FORMATTED}`)
+            .click();
+          cy.findByTestId("qb-filters-panel")
+            .should("contain.text", "Created At is August 1–31, 2022")
+            .should("contain.text", "Quantity is equal to 79");
+          cy.location().should(({ hash, pathname }) => {
+            expect(pathname).to.equal("/question");
+            const card = deserializeCardFromUrl(hash);
+            expect(card.name).to.deep.equal(TARGET_QUESTION.name);
+            expect(card.display).to.deep.equal(TARGET_QUESTION.display);
+            expect(card.dataset_query.query).to.deep.equal({
+              ...TARGET_QUESTION.query,
+              filter: ["and", QUERY_FILTER_CREATED_AT, QUERY_FILTER_QUANTITY],
+            });
           });
-        });
-      })();
-    });
+        })();
+      },
+    );
 
     it("should allow setting dashboard tab with parameter for a column", () => {
       cy.createQuestion(TARGET_QUESTION);
diff --git a/e2e/test/scenarios/dashboard-cards/dashboard-card-resizing.cy.spec.js b/e2e/test/scenarios/dashboard-cards/dashboard-card-resizing.cy.spec.js
index a19ac884e2a..6d4a7131039 100644
--- a/e2e/test/scenarios/dashboard-cards/dashboard-card-resizing.cy.spec.js
+++ b/e2e/test/scenarios/dashboard-cards/dashboard-card-resizing.cy.spec.js
@@ -202,92 +202,100 @@ describe("scenarios > dashboard card resizing", () => {
     cy.signInAsAdmin();
   });
 
-  it("should display all visualization cards with their default sizes", () => {
-    TEST_QUESTIONS.forEach(question => {
-      cy.createQuestion(question);
-    });
-    cy.createDashboard().then(({ body: { id: dashId } }) => {
-      visitDashboard(dashId);
-
-      cy.findByTestId("dashboard-header").within(() => {
-        cy.findByLabelText("Edit dashboard").click();
-        cy.findByLabelText("Add questions").click();
-      });
-
+  it(
+    "should display all visualization cards with their default sizes",
+    { tags: "@flaky" },
+    () => {
       TEST_QUESTIONS.forEach(question => {
-        cy.findByLabelText(question.name).click();
+        cy.createQuestion(question);
       });
+      cy.createDashboard().then(({ body: { id: dashId } }) => {
+        visitDashboard(dashId);
 
-      saveDashboard();
+        cy.findByTestId("dashboard-header").within(() => {
+          cy.findByLabelText("Edit dashboard").click();
+          cy.findByLabelText("Add questions").click();
+        });
 
-      cy.request("GET", `/api/dashboard/${dashId}`).then(({ body }) => {
-        body.dashcards.forEach(({ card, size_x, size_y }) => {
-          const { height, width } = getDefaultSize(card.display);
-          expect(size_x).to.equal(width);
-          expect(size_y).to.equal(height);
+        TEST_QUESTIONS.forEach(question => {
+          cy.findByLabelText(question.name).click();
         });
-      });
-    });
-  });
 
-  it(`should not allow cards to be resized smaller than min height`, () => {
-    const cardIds = [];
-    TEST_QUESTIONS.forEach(question => {
-      cy.createQuestion(question).then(({ body: { id } }) => {
-        cardIds.push(id);
-      });
-    });
-    cy.createDashboard().then(({ body: { id: dashId } }) => {
-      cy.request("PUT", `/api/dashboard/${dashId}`, {
-        dashcards: cardIds.map((cardId, index) => ({
-          id: index,
-          card_id: cardId,
-          row: index * 2,
-          col: 0,
-          size_x: 2,
-          size_y: 2,
-        })),
-      });
-      visitDashboard(dashId);
-      editDashboard();
-
-      cy.request("GET", `/api/dashboard/${dashId}`).then(({ body }) => {
-        const dashcards = body.dashcards;
-        dashcards.forEach(({ card }) => {
-          const dashcard = cy.contains(".DashCard", card.name);
-          resizeDashboardCard({
-            card: dashcard,
-            x: getDefaultSize(card.display).width * 100,
-            y: getDefaultSize(card.display).height * 100,
+        saveDashboard();
+
+        cy.request("GET", `/api/dashboard/${dashId}`).then(({ body }) => {
+          body.dashcards.forEach(({ card, size_x, size_y }) => {
+            const { height, width } = getDefaultSize(card.display);
+            expect(size_x).to.equal(width);
+            expect(size_y).to.equal(height);
           });
         });
+      });
+    },
+  );
 
-        saveDashboard();
+  it(
+    `should not allow cards to be resized smaller than min height`,
+    { tags: "@flaky" },
+    () => {
+      const cardIds = [];
+      TEST_QUESTIONS.forEach(question => {
+        cy.createQuestion(question).then(({ body: { id } }) => {
+          cardIds.push(id);
+        });
+      });
+      cy.createDashboard().then(({ body: { id: dashId } }) => {
+        cy.request("PUT", `/api/dashboard/${dashId}`, {
+          dashcards: cardIds.map((cardId, index) => ({
+            id: index,
+            card_id: cardId,
+            row: index * 2,
+            col: 0,
+            size_x: 2,
+            size_y: 2,
+          })),
+        });
+        visitDashboard(dashId);
         editDashboard();
 
-        dashcards.forEach(({ card }) => {
-          const dashcard = cy.contains(".DashCard", card.name);
-          dashcard.within(() => {
+        cy.request("GET", `/api/dashboard/${dashId}`).then(({ body }) => {
+          const dashcards = body.dashcards;
+          dashcards.forEach(({ card }) => {
+            const dashcard = cy.contains(".DashCard", card.name);
             resizeDashboardCard({
               card: dashcard,
-              x: -getDefaultSize(card.display).width * 200,
-              y: -getDefaultSize(card.display).height * 200,
+              x: getDefaultSize(card.display).width * 100,
+              y: getDefaultSize(card.display).height * 100,
             });
           });
-        });
 
-        saveDashboard();
+          saveDashboard();
+          editDashboard();
+
+          dashcards.forEach(({ card }) => {
+            const dashcard = cy.contains(".DashCard", card.name);
+            dashcard.within(() => {
+              resizeDashboardCard({
+                card: dashcard,
+                x: -getDefaultSize(card.display).width * 200,
+                y: -getDefaultSize(card.display).height * 200,
+              });
+            });
+          });
 
-        cy.request("GET", `/api/dashboard/${dashId}`).then(({ body }) => {
-          body.dashcards.forEach(({ card, size_x, size_y }) => {
-            const { height, width } = getMinSize(card.display);
-            expect(size_x).to.equal(width);
-            expect(size_y).to.equal(height);
+          saveDashboard();
+
+          cy.request("GET", `/api/dashboard/${dashId}`).then(({ body }) => {
+            body.dashcards.forEach(({ card, size_x, size_y }) => {
+              const { height, width } = getMinSize(card.display);
+              expect(size_x).to.equal(width);
+              expect(size_y).to.equal(height);
+            });
           });
         });
       });
-    });
-  });
+    },
+  );
 
   describe("metabase#31701 - preventing link dashboard card overflows", () => {
     viewports.forEach(([width, height]) => {
diff --git a/e2e/test/scenarios/embedding/embedding-smoketests.cy.spec.js b/e2e/test/scenarios/embedding/embedding-smoketests.cy.spec.js
index 2d30a89255f..50e63a842c5 100644
--- a/e2e/test/scenarios/embedding/embedding-smoketests.cy.spec.js
+++ b/e2e/test/scenarios/embedding/embedding-smoketests.cy.spec.js
@@ -214,95 +214,99 @@ describe("scenarios > embedding > smoke tests", { tags: "@OSS" }, () => {
       dashboard: ORDERS_DASHBOARD_ID,
     };
     ["question", "dashboard"].forEach(object => {
-      it(`should be able to publish/embed and then unpublish a ${object} without filters`, () => {
-        const embeddableObject = object === "question" ? "card" : "dashboard";
-        const objectName =
-          object === "question" ? "Orders" : "Orders in a dashboard";
-
-        cy.intercept("PUT", `/api/${embeddableObject}/${ids[object]}`).as(
-          "embedObject",
-        );
-        cy.intercept("GET", `/api/${embeddableObject}/embeddable`).as(
-          "currentlyEmbeddedObject",
-        );
+      it(
+        `should be able to publish/embed and then unpublish a ${object} without filters`,
+        { tags: "@flaky" },
+        () => {
+          const embeddableObject = object === "question" ? "card" : "dashboard";
+          const objectName =
+            object === "question" ? "Orders" : "Orders in a dashboard";
+
+          cy.intercept("PUT", `/api/${embeddableObject}/${ids[object]}`).as(
+            "embedObject",
+          );
+          cy.intercept("GET", `/api/${embeddableObject}/embeddable`).as(
+            "currentlyEmbeddedObject",
+          );
 
-        visitAndEnableSharing(object);
+          visitAndEnableSharing(object);
 
-        cy.findByTestId("embedding-settings").within(() => {
-          cy.findByRole("heading", { name: "Style" });
-          cy.findByRole("heading", { name: "Appearance" });
-          cy.findByRole("heading", { name: "Font" }).should("not.exist");
-          cy.findByRole("heading", { name: "Download data" }).should(
-            "not.exist",
-          );
+          cy.findByTestId("embedding-settings").within(() => {
+            cy.findByRole("heading", { name: "Style" });
+            cy.findByRole("heading", { name: "Appearance" });
+            cy.findByRole("heading", { name: "Font" }).should("not.exist");
+            cy.findByRole("heading", { name: "Download data" }).should(
+              "not.exist",
+            );
 
-          cy.findByText("Parameters");
-          cy.findByText(
-            /This (question|dashboard) doesn't have any parameters to configure yet./,
-          );
-          cy.findByText("Parameters");
-        });
+            cy.findByText("Parameters");
+            cy.findByText(
+              /This (question|dashboard) doesn't have any parameters to configure yet./,
+            );
+            cy.findByText("Parameters");
+          });
 
-        cy.findByTestId("embedding-preview").within(() => {
-          cy.findByText(
-            /You will need to publish this (question|dashboard) before you can embed it in another application./,
-          );
+          cy.findByTestId("embedding-preview").within(() => {
+            cy.findByText(
+              /You will need to publish this (question|dashboard) before you can embed it in another application./,
+            );
 
-          cy.button("Publish").click();
-          cy.wait("@embedObject");
-        });
+            cy.button("Publish").click();
+            cy.wait("@embedObject");
+          });
 
-        visitIframe();
+          visitIframe();
 
-        cy.findByTestId("embed-frame").within(() => {
-          cy.findByRole("heading", { name: objectName });
-          cy.get(".cellData").contains("37.65");
-        });
+          cy.findByTestId("embed-frame").within(() => {
+            cy.findByRole("heading", { name: objectName });
+            cy.get(".cellData").contains("37.65");
+          });
 
-        cy.findByRole("contentinfo").within(() => {
-          cy.findByRole("link")
-            .should("have.text", "Powered by Metabase")
-            .and("have.attr", "href")
-            .and("eq", "https://metabase.com/");
-        });
+          cy.findByRole("contentinfo").within(() => {
+            cy.findByRole("link")
+              .should("have.text", "Powered by Metabase")
+              .and("have.attr", "href")
+              .and("eq", "https://metabase.com/");
+          });
 
-        cy.log(
-          `Make sure the ${object} shows up in the standalone embeds page`,
-        );
-        cy.signInAsAdmin();
-        cy.visit(standalonePath);
-        cy.wait("@currentlyEmbeddedObject");
+          cy.log(
+            `Make sure the ${object} shows up in the standalone embeds page`,
+          );
+          cy.signInAsAdmin();
+          cy.visit(standalonePath);
+          cy.wait("@currentlyEmbeddedObject");
 
-        const sectionTestId = new RegExp(`-embedded-${object}s-setting`);
+          const sectionTestId = new RegExp(`-embedded-${object}s-setting`);
 
-        cy.findByTestId(sectionTestId)
-          .find("tbody tr")
-          .should("have.length", 1)
-          .and("contain", objectName);
+          cy.findByTestId(sectionTestId)
+            .find("tbody tr")
+            .should("have.length", 1)
+            .and("contain", objectName);
 
-        cy.log(`Unpublish ${object}`);
-        visitAndEnableSharing(object);
+          cy.log(`Unpublish ${object}`);
+          visitAndEnableSharing(object);
 
-        cy.findByTestId("embedding-settings").within(() => {
-          cy.findByRole("heading", { name: "Danger zone" });
-          cy.findByText(`This will disable embedding for this ${object}.`);
-          cy.button("Unpublish").click();
-          cy.wait("@embedObject");
-        });
+          cy.findByTestId("embedding-settings").within(() => {
+            cy.findByRole("heading", { name: "Danger zone" });
+            cy.findByText(`This will disable embedding for this ${object}.`);
+            cy.button("Unpublish").click();
+            cy.wait("@embedObject");
+          });
 
-        visitIframe();
-        cy.findByTestId("embed-frame").findByText(
-          "Embedding is not enabled for this object.",
-        );
+          visitIframe();
+          cy.findByTestId("embed-frame").findByText(
+            "Embedding is not enabled for this object.",
+          );
 
-        cy.signInAsAdmin();
-        cy.visit(standalonePath);
-        cy.wait("@currentlyEmbeddedObject");
+          cy.signInAsAdmin();
+          cy.visit(standalonePath);
+          cy.wait("@currentlyEmbeddedObject");
 
-        mainPage()
-          .findAllByText(/No (questions|dashboards) have been embedded yet./)
-          .should("have.length", 2);
-      });
+          mainPage()
+            .findAllByText(/No (questions|dashboards) have been embedded yet./)
+            .should("have.length", 2);
+        },
+      );
     });
 
     it("should regenerate embedding token and invalidate previous embed url", () => {
diff --git a/e2e/test/scenarios/models/models-metadata.cy.spec.js b/e2e/test/scenarios/models/models-metadata.cy.spec.js
index bf74e010cf9..47d768e4342 100644
--- a/e2e/test/scenarios/models/models-metadata.cy.spec.js
+++ b/e2e/test/scenarios/models/models-metadata.cy.spec.js
@@ -192,7 +192,7 @@ describe("scenarios > models metadata", () => {
     // Check that the relation is automatically suggested in the notebook once it is implemented.
   });
 
-  it("should keep metadata in sync with the query", () => {
+  it("should keep metadata in sync with the query", { tags: "@flaky" }, () => {
     cy.createNativeQuestion(
       {
         name: "Native Model",
diff --git a/e2e/test/scenarios/native/native_subquery.cy.spec.js b/e2e/test/scenarios/native/native_subquery.cy.spec.js
index 5286c938f53..b4d722e35e2 100644
--- a/e2e/test/scenarios/native/native_subquery.cy.spec.js
+++ b/e2e/test/scenarios/native/native_subquery.cy.spec.js
@@ -308,23 +308,27 @@ describe("scenarios > question > native subquery", () => {
     );
   });
 
-  it("should be able to reference a saved native question that ends with a semicolon `;` (metabase#28218)", () => {
-    const questionDetails = {
-      name: "28218",
-      native: { query: "select 1;" }, // semicolon is important here
-    };
+  it(
+    "should be able to reference a saved native question that ends with a semicolon `;` (metabase#28218)",
+    { tags: "@flaky" },
+    () => {
+      const questionDetails = {
+        name: "28218",
+        native: { query: "select 1;" }, // semicolon is important here
+      };
 
-    cy.createNativeQuestion(questionDetails).then(
-      ({ body: { id: baseQuestionId } }) => {
-        const tagID = `#${baseQuestionId}`;
+      cy.createNativeQuestion(questionDetails).then(
+        ({ body: { id: baseQuestionId } }) => {
+          const tagID = `#${baseQuestionId}`;
 
-        startNewNativeQuestion();
-        SQLFilter.enterParameterizedQuery(`SELECT * FROM {{${tagID}`);
+          startNewNativeQuestion();
+          SQLFilter.enterParameterizedQuery(`SELECT * FROM {{${tagID}`);
 
-        runNativeQuery();
+          runNativeQuery();
 
-        cy.get(".cellData").should("contain", "1");
-      },
-    );
-  });
+          cy.get(".cellData").should("contain", "1");
+        },
+      );
+    },
+  );
 });
diff --git a/e2e/test/scenarios/onboarding/search/recently-viewed.cy.spec.js b/e2e/test/scenarios/onboarding/search/recently-viewed.cy.spec.js
index 4e22e2deec6..7454a2e4a92 100644
--- a/e2e/test/scenarios/onboarding/search/recently-viewed.cy.spec.js
+++ b/e2e/test/scenarios/onboarding/search/recently-viewed.cy.spec.js
@@ -39,13 +39,13 @@ describe("search > recently viewed", () => {
     cy.findByTestId("loading-spinner").should("not.exist");
   });
 
-  it("shows list of recently viewed items", () => {
+  it("shows list of recently viewed items", { tags: "@flaky" }, () => {
     assertRecentlyViewedItem(0, "Orders in a dashboard", "Dashboard");
     assertRecentlyViewedItem(1, "Orders", "Question");
     assertRecentlyViewedItem(2, "People", "Table");
   });
 
-  it("allows to select an item from keyboard", () => {
+  it("allows to select an item from keyboard", { tags: "@flaky" }, () => {
     // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
     cy.findByText("Recently viewed");
     cy.get("body").trigger("keydown", { key: "ArrowDown" });
diff --git a/e2e/test/scenarios/onboarding/urls.cy.spec.js b/e2e/test/scenarios/onboarding/urls.cy.spec.js
index 14513c0c292..3c2c7f8f5bc 100644
--- a/e2e/test/scenarios/onboarding/urls.cy.spec.js
+++ b/e2e/test/scenarios/onboarding/urls.cy.spec.js
@@ -71,7 +71,7 @@ describe("URLs", () => {
     });
   });
 
-  describe("collections", () => {
+  describe("collections", { tags: "@flaky" }, () => {
     it("should slugify collection name", () => {
       cy.visit("/collection/root");
       // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
diff --git a/e2e/test/scenarios/permissions/sandboxes.cy.spec.js b/e2e/test/scenarios/permissions/sandboxes.cy.spec.js
index 288c2663d12..81b457a8259 100644
--- a/e2e/test/scenarios/permissions/sandboxes.cy.spec.js
+++ b/e2e/test/scenarios/permissions/sandboxes.cy.spec.js
@@ -444,219 +444,227 @@ describeEE("formatting > sandboxes", () => {
       cy.findByText("97.44"); // Subtotal for order #10
     });
 
-    describe("with display values remapped to use a foreign key", () => {
-      beforeEach(() => {
-        cy.log("Remap Product ID's display value to `title`");
-        remapDisplayValueToFK({
-          display_value: ORDERS.PRODUCT_ID,
-          name: "Product ID",
-          fk: PRODUCTS.TITLE,
-        });
-      });
-
-      /**
-       * There isn't an exact issue that this test reproduces, but it is basically a version of (metabase-enterprise#520)
-       * that uses a query builder instead of SQL based questions.
-       */
-      it("should be able to sandbox using query builder saved questions", () => {
-        cy.log("Create 'Orders'-based question using QB");
-        cy.createQuestion({
-          name: "520_Orders",
-          query: {
-            "source-table": ORDERS_ID,
-            filter: [">", ["field", ORDERS.TOTAL, null], 10],
-          },
-        }).then(({ body: { id: CARD_ID } }) => {
-          cy.sandboxTable({
-            table_id: ORDERS_ID,
-            card_id: CARD_ID,
-            attribute_remappings: {
-              attr_uid: ["dimension", ["field", ORDERS.USER_ID, null]],
-            },
+    describe(
+      "with display values remapped to use a foreign key",
+      { tags: "@flaky" },
+      () => {
+        beforeEach(() => {
+          cy.log("Remap Product ID's display value to `title`");
+          remapDisplayValueToFK({
+            display_value: ORDERS.PRODUCT_ID,
+            name: "Product ID",
+            fk: PRODUCTS.TITLE,
           });
         });
 
-        cy.log("Create 'Products'-based question using QB");
-        cy.createQuestion({
-          name: "520_Products",
-          query: {
-            "source-table": PRODUCTS_ID,
-            filter: [">", ["field", PRODUCTS.PRICE, null], 10],
-          },
-        }).then(({ body: { id: CARD_ID } }) => {
-          cy.sandboxTable({
-            table_id: PRODUCTS_ID,
-            card_id: CARD_ID,
-            attribute_remappings: {
-              attr_cat: ["dimension", ["field", PRODUCTS.CATEGORY, null]],
-            },
-          });
-        });
+        /**
+         * There isn't an exact issue that this test reproduces, but it is basically a version of (metabase-enterprise#520)
+         * that uses a query builder instead of SQL based questions.
+         */
+        it(
+          "should be able to sandbox using query builder saved questions",
+          { tags: "@flaky" },
+          () => {
+            cy.log("Create 'Orders'-based question using QB");
+            cy.createQuestion({
+              name: "520_Orders",
+              query: {
+                "source-table": ORDERS_ID,
+                filter: [">", ["field", ORDERS.TOTAL, null], 10],
+              },
+            }).then(({ body: { id: CARD_ID } }) => {
+              cy.sandboxTable({
+                table_id: ORDERS_ID,
+                card_id: CARD_ID,
+                attribute_remappings: {
+                  attr_uid: ["dimension", ["field", ORDERS.USER_ID, null]],
+                },
+              });
+            });
 
-        cy.signOut();
-        cy.signInAsSandboxedUser();
+            cy.log("Create 'Products'-based question using QB");
+            cy.createQuestion({
+              name: "520_Products",
+              query: {
+                "source-table": PRODUCTS_ID,
+                filter: [">", ["field", PRODUCTS.PRICE, null], 10],
+              },
+            }).then(({ body: { id: CARD_ID } }) => {
+              cy.sandboxTable({
+                table_id: PRODUCTS_ID,
+                card_id: CARD_ID,
+                attribute_remappings: {
+                  attr_cat: ["dimension", ["field", PRODUCTS.CATEGORY, null]],
+                },
+              });
+            });
 
-        openOrdersTable({
-          callback: xhr => expect(xhr.response.body.error).not.to.exist,
-        });
+            cy.signOut();
+            cy.signInAsSandboxedUser();
 
-        cy.get(".cellData").contains("Awesome Concrete Shoes").click();
-        // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-        cy.findByText(/View details/i).click();
+            openOrdersTable({
+              callback: xhr => expect(xhr.response.body.error).not.to.exist,
+            });
 
-        cy.log(
-          "It should show object details instead of filtering by this Product ID",
+            cy.get(".cellData").contains("Awesome Concrete Shoes").click();
+            // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+            cy.findByText(/View details/i).click();
+
+            cy.log(
+              "It should show object details instead of filtering by this Product ID",
+            );
+            cy.findByTestId("object-detail");
+            cy.findAllByText("McClure-Lockman");
+          },
         );
-        cy.findByTestId("object-detail");
-        cy.findAllByText("McClure-Lockman");
-      });
 
-      /**
-       * This issue (metabase-enterprise#520) has a peculiar quirk:
-       *  - It works ONLY if SQL question is first run (`result_metadata` builds), and then the question is saved.
-       *  - In a real-world scenario it is quite possible for an admin to save that SQL question without running it first. This fails!
-       *  (more info: https://github.com/metabase/metabase-enterprise/issues/520#issuecomment-772528159)
-       *
-       * That's why this test has 2 versions that reflect both scenarios. We'll call them "normal" and "workaround".
-       * Until the underlying issue is fixed, "normal" scenario will be skipped.
-       *
-       * Related issues: metabase#10474, metabase#14629
-       */
-
-      // skipping the workaround test because the function `runAndSaveQuestion`
-      // relies on the existence of a save button on a saved question that is not dirty
-      // which is a bug fixed in ssue metabase#14302
-      ["normal" /* , "workaround" */].forEach(test => {
-        it(`${test.toUpperCase()} version:\n advanced sandboxing should not ignore data model features like object detail of FK (metabase-enterprise#520)`, () => {
-          cy.intercept("POST", "/api/card/*/query").as("cardQuery");
-          cy.intercept("PUT", "/api/card/*").as("questionUpdate");
-
-          cy.createNativeQuestion({
-            name: "EE_520_Q1",
-            native: {
-              query:
-                "SELECT * FROM ORDERS WHERE USER_ID={{sandbox}} AND TOTAL > 10",
-              "template-tags": {
-                sandbox: {
-                  "display-name": "Sandbox",
-                  id: "1115dc4f-6b9d-812e-7f72-b87ab885c88a",
-                  name: "sandbox",
-                  type: "number",
+        /**
+         * This issue (metabase-enterprise#520) has a peculiar quirk:
+         *  - It works ONLY if SQL question is first run (`result_metadata` builds), and then the question is saved.
+         *  - In a real-world scenario it is quite possible for an admin to save that SQL question without running it first. This fails!
+         *  (more info: https://github.com/metabase/metabase-enterprise/issues/520#issuecomment-772528159)
+         *
+         * That's why this test has 2 versions that reflect both scenarios. We'll call them "normal" and "workaround".
+         * Until the underlying issue is fixed, "normal" scenario will be skipped.
+         *
+         * Related issues: metabase#10474, metabase#14629
+         */
+
+        // skipping the workaround test because the function `runAndSaveQuestion`
+        // relies on the existence of a save button on a saved question that is not dirty
+        // which is a bug fixed in ssue metabase#14302
+        ["normal" /* , "workaround" */].forEach(test => {
+          it(`${test.toUpperCase()} version:\n advanced sandboxing should not ignore data model features like object detail of FK (metabase-enterprise#520)`, () => {
+            cy.intercept("POST", "/api/card/*/query").as("cardQuery");
+            cy.intercept("PUT", "/api/card/*").as("questionUpdate");
+
+            cy.createNativeQuestion({
+              name: "EE_520_Q1",
+              native: {
+                query:
+                  "SELECT * FROM ORDERS WHERE USER_ID={{sandbox}} AND TOTAL > 10",
+                "template-tags": {
+                  sandbox: {
+                    "display-name": "Sandbox",
+                    id: "1115dc4f-6b9d-812e-7f72-b87ab885c88a",
+                    name: "sandbox",
+                    type: "number",
+                  },
                 },
               },
-            },
-          }).then(({ body: { id: CARD_ID } }) => {
-            test === "workaround"
-              ? runAndSaveQuestion({ question: CARD_ID, sandboxValue: "1" })
-              : null;
-
-            cy.sandboxTable({
-              table_id: ORDERS_ID,
-              card_id: CARD_ID,
-              attribute_remappings: {
-                attr_uid: ["variable", ["template-tag", "sandbox"]],
-              },
+            }).then(({ body: { id: CARD_ID } }) => {
+              test === "workaround"
+                ? runAndSaveQuestion({ question: CARD_ID, sandboxValue: "1" })
+                : null;
+
+              cy.sandboxTable({
+                table_id: ORDERS_ID,
+                card_id: CARD_ID,
+                attribute_remappings: {
+                  attr_uid: ["variable", ["template-tag", "sandbox"]],
+                },
+              });
             });
-          });
 
-          cy.createNativeQuestion({
-            name: "EE_520_Q2",
-            native: {
-              query:
-                "SELECT * FROM PRODUCTS WHERE CATEGORY={{sandbox}} AND PRICE > 10",
-              "template-tags": {
-                sandbox: {
-                  "display-name": "Sandbox",
-                  id: "3d69ba99-7076-2252-30bd-0bb8810ba895",
-                  name: "sandbox",
-                  type: "text",
+            cy.createNativeQuestion({
+              name: "EE_520_Q2",
+              native: {
+                query:
+                  "SELECT * FROM PRODUCTS WHERE CATEGORY={{sandbox}} AND PRICE > 10",
+                "template-tags": {
+                  sandbox: {
+                    "display-name": "Sandbox",
+                    id: "3d69ba99-7076-2252-30bd-0bb8810ba895",
+                    name: "sandbox",
+                    type: "text",
+                  },
                 },
               },
+            }).then(({ body: { id: CARD_ID } }) => {
+              test === "workaround"
+                ? runAndSaveQuestion({
+                    question: CARD_ID,
+                    sandboxValue: "Widget",
+                  })
+                : null;
+
+              cy.sandboxTable({
+                table_id: PRODUCTS_ID,
+                card_id: CARD_ID,
+                attribute_remappings: {
+                  attr_cat: ["variable", ["template-tag", "sandbox"]],
+                },
+              });
+            });
+
+            cy.signOut();
+            cy.signInAsSandboxedUser();
+
+            openOrdersTable();
+
+            cy.log("Reported failing on v1.36.x");
+
+            cy.log(
+              "It should show remapped Display Values instead of Product ID",
+            );
+            cy.get(".cellData").contains("Awesome Concrete Shoes").click();
+            // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
+            cy.findByText(/View details/i).click();
+
+            cy.log(
+              "It should show object details instead of filtering by this Product ID",
+            );
+            // The name of this Vendor is visible in "details" only
+            cy.findByTestId("object-detail");
+            cy.findAllByText("McClure-Lockman");
+
+            /**
+             * Helper function related to this test only!
+             */
+            function runAndSaveQuestion({ question, sandboxValue } = {}) {
+              // Run the question
+              cy.visit(`/question/${question}?sandbox=${sandboxValue}`);
+              // Wait for results
+              cy.wait("@cardQuery");
+              // Save the question
+              cy.findByText("Save").click();
+              modal().within(() => {
+                cy.button("Save").click();
+              });
+              // Wait for an update so the other queries don't accidentally cancel it
+              cy.wait("@questionUpdate");
+            }
+          });
+        });
+
+        it("simple sandboxing should work (metabase#14629)", () => {
+          cy.sandboxTable({
+            table_id: ORDERS_ID,
+            attribute_remappings: {
+              attr_uid: ["dimension", ["field", ORDERS.USER_ID, null]],
             },
-          }).then(({ body: { id: CARD_ID } }) => {
-            test === "workaround"
-              ? runAndSaveQuestion({
-                  question: CARD_ID,
-                  sandboxValue: "Widget",
-                })
-              : null;
-
-            cy.sandboxTable({
-              table_id: PRODUCTS_ID,
-              card_id: CARD_ID,
-              attribute_remappings: {
-                attr_cat: ["variable", ["template-tag", "sandbox"]],
+          });
+
+          cy.updatePermissionsSchemas({
+            schemas: {
+              PUBLIC: {
+                [PRODUCTS_ID]: "all",
               },
-            });
+            },
           });
 
           cy.signOut();
           cy.signInAsSandboxedUser();
+          openOrdersTable({
+            callback: xhr => expect(xhr.response.body.error).not.to.exist,
+          });
 
-          openOrdersTable();
-
-          cy.log("Reported failing on v1.36.x");
-
-          cy.log(
-            "It should show remapped Display Values instead of Product ID",
-          );
-          cy.get(".cellData").contains("Awesome Concrete Shoes").click();
+          // Title of the first order for User ID = 1
           // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-          cy.findByText(/View details/i).click();
-
-          cy.log(
-            "It should show object details instead of filtering by this Product ID",
-          );
-          // The name of this Vendor is visible in "details" only
-          cy.findByTestId("object-detail");
-          cy.findAllByText("McClure-Lockman");
-
-          /**
-           * Helper function related to this test only!
-           */
-          function runAndSaveQuestion({ question, sandboxValue } = {}) {
-            // Run the question
-            cy.visit(`/question/${question}?sandbox=${sandboxValue}`);
-            // Wait for results
-            cy.wait("@cardQuery");
-            // Save the question
-            cy.findByText("Save").click();
-            modal().within(() => {
-              cy.button("Save").click();
-            });
-            // Wait for an update so the other queries don't accidentally cancel it
-            cy.wait("@questionUpdate");
-          }
+          cy.findByText("Awesome Concrete Shoes");
         });
-      });
-
-      it("simple sandboxing should work (metabase#14629)", () => {
-        cy.sandboxTable({
-          table_id: ORDERS_ID,
-          attribute_remappings: {
-            attr_uid: ["dimension", ["field", ORDERS.USER_ID, null]],
-          },
-        });
-
-        cy.updatePermissionsSchemas({
-          schemas: {
-            PUBLIC: {
-              [PRODUCTS_ID]: "all",
-            },
-          },
-        });
-
-        cy.signOut();
-        cy.signInAsSandboxedUser();
-        openOrdersTable({
-          callback: xhr => expect(xhr.response.body.error).not.to.exist,
-        });
-
-        // Title of the first order for User ID = 1
-        // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-        cy.findByText("Awesome Concrete Shoes");
-      });
-    });
+      },
+    );
 
     ["remapped", "default"].forEach(test => {
       it(`${test.toUpperCase()} version:\n should work on questions with joins, with sandboxed target table, where target fields cannot be filtered (metabase#13642)`, () => {
diff --git a/e2e/test/scenarios/sharing/subscriptions.cy.spec.js b/e2e/test/scenarios/sharing/subscriptions.cy.spec.js
index 18037cc7990..aeee325858e 100644
--- a/e2e/test/scenarios/sharing/subscriptions.cy.spec.js
+++ b/e2e/test/scenarios/sharing/subscriptions.cy.spec.js
@@ -196,99 +196,105 @@ describe("scenarios > dashboard > subscriptions", () => {
       });
     });
 
-    describe("let non-users unsubscribe from subscriptions", () => {
-      it("should allow non-user to unsubscribe from subscription", () => {
-        const nonUserEmail = "non-user@example.com";
-        const dashboardName = "Orders in a dashboard";
+    describe(
+      "let non-users unsubscribe from subscriptions",
+      { tags: "@flaky" },
+      () => {
+        it("should allow non-user to unsubscribe from subscription", () => {
+          const nonUserEmail = "non-user@example.com";
+          const dashboardName = "Orders in a dashboard";
 
-        visitDashboard(ORDERS_DASHBOARD_ID);
+          visitDashboard(ORDERS_DASHBOARD_ID);
 
-        setupSubscriptionWithRecipient(nonUserEmail);
+          setupSubscriptionWithRecipient(nonUserEmail);
 
-        emailSubscriptionRecipients();
+          emailSubscriptionRecipients();
 
-        openEmailPage(dashboardName).then(() => {
-          cy.intercept("/api/session/pulse/unsubscribe").as("unsubscribe");
-          cy.findByText("Unsubscribe").click();
-          cy.wait("@unsubscribe");
-          cy.contains(
-            `You've unsubscribed ${nonUserEmail} from the "${dashboardName}" alert.`,
-          ).should("exist");
+          openEmailPage(dashboardName).then(() => {
+            cy.intercept("/api/session/pulse/unsubscribe").as("unsubscribe");
+            cy.findByText("Unsubscribe").click();
+            cy.wait("@unsubscribe");
+            cy.contains(
+              `You've unsubscribed ${nonUserEmail} from the "${dashboardName}" alert.`,
+            ).should("exist");
+          });
+
+          openDashboardSubscriptions();
+          openPulseSubscription();
+
+          sidebar().findByText(nonUserEmail).should("not.exist");
         });
 
-        openDashboardSubscriptions();
-        openPulseSubscription();
+        it("should allow non-user to undo-unsubscribe from subscription", () => {
+          const nonUserEmail = "non-user@example.com";
+          const dashboardName = "Orders in a dashboard";
+          visitDashboard(ORDERS_DASHBOARD_ID);
 
-        sidebar().findByText(nonUserEmail).should("not.exist");
-      });
+          setupSubscriptionWithRecipient(nonUserEmail);
 
-      it("should allow non-user to undo-unsubscribe from subscription", () => {
-        const nonUserEmail = "non-user@example.com";
-        const dashboardName = "Orders in a dashboard";
-        visitDashboard(ORDERS_DASHBOARD_ID);
+          emailSubscriptionRecipients();
 
-        setupSubscriptionWithRecipient(nonUserEmail);
+          openEmailPage(dashboardName).then(() => {
+            cy.intercept("/api/session/pulse/unsubscribe").as("unsubscribe");
+            cy.intercept("/api/session/pulse/unsubscribe/undo").as(
+              "resubscribe",
+            );
 
-        emailSubscriptionRecipients();
+            cy.findByText("Unsubscribe").click();
+            cy.wait("@unsubscribe");
 
-        openEmailPage(dashboardName).then(() => {
-          cy.intercept("/api/session/pulse/unsubscribe").as("unsubscribe");
-          cy.intercept("/api/session/pulse/unsubscribe/undo").as("resubscribe");
+            cy.contains(
+              `You've unsubscribed ${nonUserEmail} from the "${dashboardName}" alert.`,
+            ).should("exist");
 
-          cy.findByText("Unsubscribe").click();
-          cy.wait("@unsubscribe");
+            cy.findByText("Undo").click();
+            cy.wait("@resubscribe");
 
-          cy.contains(
-            `You've unsubscribed ${nonUserEmail} from the "${dashboardName}" alert.`,
-          ).should("exist");
+            cy.contains(
+              `Okay, ${nonUserEmail} is subscribed to the "${dashboardName}" alert again.`,
+            ).should("exist");
+          });
 
-          cy.findByText("Undo").click();
-          cy.wait("@resubscribe");
+          openDashboardSubscriptions();
+          openPulseSubscription();
 
-          cy.contains(
-            `Okay, ${nonUserEmail} is subscribed to the "${dashboardName}" alert again.`,
-          ).should("exist");
+          sidebar().findByText(nonUserEmail).should("exist");
         });
 
-        openDashboardSubscriptions();
-        openPulseSubscription();
+        it("should show 404 page when missing required parameters", () => {
+          const nonUserEmail = "non-user@example.com";
 
-        sidebar().findByText(nonUserEmail).should("exist");
-      });
+          const params = {
+            hash: "459a8e9f8d9e",
+            email: nonUserEmail,
+          }; // missing pulse-id
 
-      it("should show 404 page when missing required parameters", () => {
-        const nonUserEmail = "non-user@example.com";
+          cy.visit({
+            url: `/unsubscribe`,
+            qs: params,
+          });
 
-        const params = {
-          hash: "459a8e9f8d9e",
-          email: nonUserEmail,
-        }; // missing pulse-id
-
-        cy.visit({
-          url: `/unsubscribe`,
-          qs: params,
+          cy.findByLabelText("error page").should("exist");
         });
 
-        cy.findByLabelText("error page").should("exist");
-      });
+        it("should show error message when server responds with an error", () => {
+          const nonUserEmail = "non-user@example.com";
 
-      it("should show error message when server responds with an error", () => {
-        const nonUserEmail = "non-user@example.com";
+          const params = {
+            hash: "459a8e9f8d9e",
+            email: nonUserEmail,
+            "pulse-id": "f", // invalid pulse-id
+          };
 
-        const params = {
-          hash: "459a8e9f8d9e",
-          email: nonUserEmail,
-          "pulse-id": "f", // invalid pulse-id
-        };
+          cy.visit({
+            url: `/unsubscribe`,
+            qs: params,
+          });
 
-        cy.visit({
-          url: `/unsubscribe`,
-          qs: params,
+          cy.findByLabelText("error message").should("exist");
         });
-
-        cy.findByLabelText("error message").should("exist");
-      });
-    });
+      },
+    );
 
     it("should persist attachments for dashboard subscriptions (metabase#14117)", () => {
       assignRecipient();
diff --git a/e2e/test/scenarios/visualizations-tabular/pivot_tables.cy.spec.js b/e2e/test/scenarios/visualizations-tabular/pivot_tables.cy.spec.js
index 75ba69e7530..de9ac22d5b2 100644
--- a/e2e/test/scenarios/visualizations-tabular/pivot_tables.cy.spec.js
+++ b/e2e/test/scenarios/visualizations-tabular/pivot_tables.cy.spec.js
@@ -462,7 +462,7 @@ describe("scenarios > visualizations > pivot tables", { tags: "@slow" }, () => {
     cy.findByText(/Sort order/).should("not.be.visible");
   });
 
-  it("should allow sorting fields", () => {
+  it("should allow sorting fields", { tags: "@flaky" }, () => {
     // Pivot by a single column with many values (100 bins).
     // Having many values hides values that are sorted to the end.
     // This lets us assert on presence of a certain value.
-- 
GitLab