From ecbaf6163e0bd6aa25ae1d134950889cfb6fc105 Mon Sep 17 00:00:00 2001
From: Nick Fitzpatrick <nick@metabase.com>
Date: Fri, 24 Mar 2023 13:32:28 -0300
Subject: [PATCH] Update to Cypress 12 (#29396)

* Updating to cypress 12

* updating deps

* Updating Tests. Be Green Plz

* removing custom test id from select button

* Select Button Tuning
---
 e2e/support/helpers/e2e-misc-helpers.js       |  2 +-
 .../helpers/e2e-ui-elements-helpers.js        |  4 +++
 .../admin/settings/localization.cy.spec.js    |  2 +-
 .../settings/sso/group-mappings-widget.js     | 18 +++++++-----
 ...cc-same-name-as-existing-column.cy.spec.js |  2 +-
 .../actions-on-dashboards.cy.spec.js          | 28 +++++++++++++------
 .../dashboard_data_permissions.cy.spec.js     |  5 ----
 .../scenarios/filters/operators.cy.spec.js    |  8 +++---
 e2e/test/scenarios/models/models.cy.spec.js   |  2 +-
 e2e/test/scenarios/native/native.cy.spec.js   |  4 +--
 .../snippets/snippet-permissions.cy.spec.js   |  9 +++++-
 .../onboarding/setup/user_settings.cy.spec.js |  2 +-
 .../moderation-collection.cy.spec.js          |  1 +
 .../timelines-question.cy.spec.js             | 10 +++----
 e2e/test/scenarios/question/nested.cy.spec.js |  7 ++++-
 .../scenarios/question/notebook.cy.spec.js    |  2 +-
 e2e/test/scenarios/question/nulls.cy.spec.js  |  4 +--
 .../18207-string-min-max.cy.spec.js           |  4 +--
 ...977-nested-question-nodata-user.cy.spec.js | 10 +++----
 .../question/summarization.cy.spec.js         |  2 +-
 .../sharing/alert/alert-types.cy.spec.js      |  4 +--
 .../visualizations/pivot_tables.cy.spec.js    |  3 +-
 .../visualizations/trendline.cy.spec.js       |  4 +--
 .../visualizations/waterfall.cy.spec.js       |  4 +--
 .../AccordionList/AccordionList.jsx           | 11 +++++++-
 .../core/components/Select/Select.tsx         |  3 ++
 .../components/NativeQueryEditor.jsx          |  7 ++++-
 .../components/filters/OperatorSelector.jsx   |  1 +
 .../notebook/NotebookStepPreview.jsx          |  2 +-
 .../TableInteractive/TableInteractive.jsx     |  1 +
 package.json                                  |  6 ++--
 yarn.lock                                     | 26 ++++++++---------
 32 files changed, 121 insertions(+), 77 deletions(-)

diff --git a/e2e/support/helpers/e2e-misc-helpers.js b/e2e/support/helpers/e2e-misc-helpers.js
index 6ff42ab9dfd..c75f57f546d 100644
--- a/e2e/support/helpers/e2e-misc-helpers.js
+++ b/e2e/support/helpers/e2e-misc-helpers.js
@@ -36,7 +36,7 @@ export function openNativeEditor({
 
   databaseName && cy.findByText(databaseName).click();
 
-  return cy.get(".ace_content").as(alias).should("be.visible");
+  return cy.findByTestId("native-query-editor").as(alias).should("be.visible");
 }
 
 /**
diff --git a/e2e/support/helpers/e2e-ui-elements-helpers.js b/e2e/support/helpers/e2e-ui-elements-helpers.js
index a412bc5f44c..b635a67ae25 100644
--- a/e2e/support/helpers/e2e-ui-elements-helpers.js
+++ b/e2e/support/helpers/e2e-ui-elements-helpers.js
@@ -22,6 +22,10 @@ export function rightSidebar() {
   return cy.findAllByTestId("sidebar-right");
 }
 
+export function leftSidebar() {
+  return cy.findByTestId("sidebar-left");
+}
+
 export function navigationSidebar() {
   return cy.get("#root aside").first();
 }
diff --git a/e2e/test/scenarios/admin/settings/localization.cy.spec.js b/e2e/test/scenarios/admin/settings/localization.cy.spec.js
index 5ce3c83ede2..69d51a62cda 100644
--- a/e2e/test/scenarios/admin/settings/localization.cy.spec.js
+++ b/e2e/test/scenarios/admin/settings/localization.cy.spec.js
@@ -108,7 +108,7 @@ describe("scenarios > admin > localization", () => {
       { visitQuestion: true },
     );
 
-    cy.get(".TableInteractive-header").next().as("resultTable");
+    cy.findByTestId("TableInteractive-root").as("resultTable");
 
     cy.get("@resultTable").within(() => {
       // The third cell in the first row (CREATED_AT_DAY)
diff --git a/e2e/test/scenarios/admin/settings/sso/group-mappings-widget.js b/e2e/test/scenarios/admin/settings/sso/group-mappings-widget.js
index 63af56002f9..c84aae4fe1c 100644
--- a/e2e/test/scenarios/admin/settings/sso/group-mappings-widget.js
+++ b/e2e/test/scenarios/admin/settings/sso/group-mappings-widget.js
@@ -1,3 +1,5 @@
+import { popover } from "e2e/support/helpers";
+
 export function crudGroupMappingsWidget(authenticationMethod) {
   cy.visit("/admin/settings/authentication/" + authenticationMethod);
   cy.wait("@getSettings");
@@ -84,13 +86,15 @@ const addGroupsToMapping = (mappingName, groups) => {
     });
 
   groups.forEach(group => {
-    cy.findByText(group).click();
-
-    cy.findByText(group)
-      .closest(".List-section")
-      .within(() => {
-        cy.icon("check");
-      });
+    popover().within(() => {
+      cy.findByText(group).click();
+
+      cy.findByText(group)
+        .closest(".List-section")
+        .within(() => {
+          cy.icon("check");
+        });
+    });
   });
 };
 
diff --git a/e2e/test/scenarios/custom-column/reproductions/21135-cc-same-name-as-existing-column.cy.spec.js b/e2e/test/scenarios/custom-column/reproductions/21135-cc-same-name-as-existing-column.cy.spec.js
index 6854a11568d..7a815e0fa1e 100644
--- a/e2e/test/scenarios/custom-column/reproductions/21135-cc-same-name-as-existing-column.cy.spec.js
+++ b/e2e/test/scenarios/custom-column/reproductions/21135-cc-same-name-as-existing-column.cy.spec.js
@@ -31,7 +31,7 @@ describe("issue 21135", () => {
 
     // We should probably use data-testid or some better selector but it is crucial
     // to narrow the results to the preview area to avoid false positive result.
-    cy.get("[class*=TableInteractive]").within(() => {
+    cy.findByTestId("preview-root").within(() => {
       cy.findByText("Rustic Paper Wallet");
 
       cy.findAllByText("Price").should("have.length", 2);
diff --git a/e2e/test/scenarios/dashboard/actions-on-dashboards.cy.spec.js b/e2e/test/scenarios/dashboard/actions-on-dashboards.cy.spec.js
index 843ac1ce546..00a4acf7187 100644
--- a/e2e/test/scenarios/dashboard/actions-on-dashboards.cy.spec.js
+++ b/e2e/test/scenarios/dashboard/actions-on-dashboards.cy.spec.js
@@ -55,7 +55,10 @@ const MODEL_NAME = "Test Action Model";
           restore(`${dialect}-writable`);
           cy.signInAsAdmin();
           resyncDatabase({ dbId: WRITABLE_DB_ID, tableName: TEST_TABLE });
-          createModelFromTableName({ tableName: TEST_TABLE, modelName: MODEL_NAME });
+          createModelFromTableName({
+            tableName: TEST_TABLE,
+            modelName: MODEL_NAME,
+          });
         });
 
         it("adds a custom query action to a dashboard and runs it", () => {
@@ -87,13 +90,13 @@ const MODEL_NAME = "Test Action Model";
           dragField(1, 0);
 
           cy.findByRole("dialog").within(() => {
-            cy.findAllByText("Number").click({ multiple: true })
+            cy.findAllByText("Number").each(el => {
+              cy.wrap(el).click();
+            });
             cy.findByText("Save").click();
           });
 
-          cy.findByPlaceholderText("My new fantastic action").type(
-            ACTION_NAME
-          );
+          cy.findByPlaceholderText("My new fantastic action").type(ACTION_NAME);
           cy.findByText("Create").click();
 
           createDashboardWithActionButton({
@@ -102,7 +105,7 @@ const MODEL_NAME = "Test Action Model";
           });
 
           filterWidget().click();
-          addWidgetStringFilter("1")
+          addWidgetStringFilter("1");
 
           clickHelper("Update Score");
 
@@ -246,8 +249,14 @@ const MODEL_NAME = "Test Action Model";
           resetTestTable({ type: dialect, table: TEST_COLUMNS_TABLE });
           restore(`${dialect}-writable`);
           cy.signInAsAdmin();
-          resyncDatabase({ dbId: WRITABLE_DB_ID, tableName: TEST_COLUMNS_TABLE });
-          createModelFromTableName({ tableName: TEST_COLUMNS_TABLE, modelName: MODEL_NAME });
+          resyncDatabase({
+            dbId: WRITABLE_DB_ID,
+            tableName: TEST_COLUMNS_TABLE,
+          });
+          createModelFromTableName({
+            tableName: TEST_COLUMNS_TABLE,
+            modelName: MODEL_NAME,
+          });
         });
 
         it("can update various data types via implicit actions", () => {
@@ -569,7 +578,8 @@ const MODEL_NAME = "Test Action Model";
           });
         });
       });
-    });
+    },
+  );
 });
 
 function createDashboardWithActionButton({
diff --git a/e2e/test/scenarios/dashboard/dashboard_data_permissions.cy.spec.js b/e2e/test/scenarios/dashboard/dashboard_data_permissions.cy.spec.js
index df8e7c438f3..f021d6fc0a6 100644
--- a/e2e/test/scenarios/dashboard/dashboard_data_permissions.cy.spec.js
+++ b/e2e/test/scenarios/dashboard/dashboard_data_permissions.cy.spec.js
@@ -62,11 +62,6 @@ describe("support > permissions (metabase#8472)", () => {
   });
 
   it("should not allow a nocollection user to visit the page, hence cannot see the filter", () => {
-    cy.server();
-    cy.route("GET", "/api/dashboard/1/params/search/100 Main Street").as(
-      "search",
-    );
-
     cy.signIn("nocollection");
     cy.request({
       method: "GET",
diff --git a/e2e/test/scenarios/filters/operators.cy.spec.js b/e2e/test/scenarios/filters/operators.cy.spec.js
index 6c7e6281fa0..e60a99b7eaf 100644
--- a/e2e/test/scenarios/filters/operators.cy.spec.js
+++ b/e2e/test/scenarios/filters/operators.cy.spec.js
@@ -75,7 +75,7 @@ describe("operators in questions", () => {
         cy.findByText("Is").click();
       });
 
-      popover().within(() => {
+      cy.findByTestId("operator-select-list").within(() => {
         expected.text.expected.map(e => cy.contains(e).should("exist"));
         expected.text.unexpected.map(e => cy.contains(e).should("not.exist"));
       });
@@ -92,7 +92,7 @@ describe("operators in questions", () => {
         cy.findByText("Equal to").click();
       });
 
-      popover().within(() => {
+      cy.findByTestId("operator-select-list").within(() => {
         expected.number.expected.map(e => cy.contains(e).should("exist"));
         expected.number.unexpected.map(e => cy.contains(e).should("not.exist"));
       });
@@ -190,7 +190,7 @@ describe("operators in questions", () => {
         cy.findByText("Is").click();
       });
 
-      popover().within(() => {
+      cy.findByTestId("operator-select-list").within(() => {
         expected.id.expected.map(e => cy.contains(e).should("exist"));
         expected.id.unexpected.map(e => cy.contains(e).should("not.exist"));
       });
@@ -207,7 +207,7 @@ describe("operators in questions", () => {
         cy.findByText("Is").click();
       });
 
-      popover().within(() => {
+      cy.findByTestId("operator-select-list").within(() => {
         expected.geo.expected.map(e => cy.contains(e).should("exist"));
         expected.geo.unexpected.map(e => cy.contains(e).should("not.exist"));
       });
diff --git a/e2e/test/scenarios/models/models.cy.spec.js b/e2e/test/scenarios/models/models.cy.spec.js
index 603f32471ce..b9e65ac727f 100644
--- a/e2e/test/scenarios/models/models.cy.spec.js
+++ b/e2e/test/scenarios/models/models.cy.spec.js
@@ -522,7 +522,7 @@ describe("scenarios > models", () => {
       });
       cy.get(".NativeQueryEditor .Icon-play").click();
       cy.wait("@query");
-      cy.get(".TableInteractive").within(() => {
+      cy.findByTestId("TableInteractive-root").within(() => {
         cy.findByText("USER_ID");
         cy.findByText("PRODUCT_ID");
         cy.findByText("TAX");
diff --git a/e2e/test/scenarios/native/native.cy.spec.js b/e2e/test/scenarios/native/native.cy.spec.js
index c24ece6030a..51c0502ef32 100644
--- a/e2e/test/scenarios/native/native.cy.spec.js
+++ b/e2e/test/scenarios/native/native.cy.spec.js
@@ -4,7 +4,7 @@ import {
   openNativeEditor,
   visitQuestionAdhoc,
   summarize,
-  sidebar,
+  rightSidebar,
   filter,
   filterField,
 } from "e2e/support/helpers";
@@ -152,7 +152,7 @@ describe("scenarios > question > native", () => {
         cy.icon("close").click();
       });
       summarize();
-      sidebar().within(() => {
+      rightSidebar().within(() => {
         cy.icon("close").click();
       });
       cy.findByText("Done").click();
diff --git a/e2e/test/scenarios/native/snippets/snippet-permissions.cy.spec.js b/e2e/test/scenarios/native/snippets/snippet-permissions.cy.spec.js
index 38c8868ee94..9a15872a4dc 100644
--- a/e2e/test/scenarios/native/snippets/snippet-permissions.cy.spec.js
+++ b/e2e/test/scenarios/native/snippets/snippet-permissions.cy.spec.js
@@ -4,6 +4,7 @@ import {
   popover,
   describeEE,
   openNativeEditor,
+  rightSidebar,
 } from "e2e/support/helpers";
 
 import { USER_GROUPS } from "e2e/support/cypress_data";
@@ -52,6 +53,8 @@ describeEE("scenarios > question > snippets", () => {
       collection_id: null,
     });
 
+    cy.intercept("GET", "api/collection/*").as("collection");
+
     openNativeEditor();
 
     // create folder
@@ -74,8 +77,12 @@ describeEE("scenarios > question > snippets", () => {
       .parent()
       .within(() => {
         cy.icon("chevrondown").click({ force: true });
-        cy.findByText("Edit").click();
       });
+
+    rightSidebar().within(() => {
+      cy.findByText("Edit").click();
+    });
+
     modal().within(() => cy.findByText("Top folder").click());
     popover().within(() => cy.findByText("my favorite snippets").click());
     cy.intercept("/api/collection/root/items?namespace=snippets").as(
diff --git a/e2e/test/scenarios/onboarding/setup/user_settings.cy.spec.js b/e2e/test/scenarios/onboarding/setup/user_settings.cy.spec.js
index 32a7f13886e..5ae4b490111 100644
--- a/e2e/test/scenarios/onboarding/setup/user_settings.cy.spec.js
+++ b/e2e/test/scenarios/onboarding/setup/user_settings.cy.spec.js
@@ -84,7 +84,7 @@ describe("user > settings", () => {
     cy.visit("/account/password");
 
     // Validate common passwords
-    cy.findByLabelText("Create a password")
+    cy.findByLabelText(/Create a password/i)
       .as("passwordInput")
       .type("qwerty123")
       .blur();
diff --git a/e2e/test/scenarios/organization/moderation-collection.cy.spec.js b/e2e/test/scenarios/organization/moderation-collection.cy.spec.js
index 20441b2a00f..beaf37c8e88 100644
--- a/e2e/test/scenarios/organization/moderation-collection.cy.spec.js
+++ b/e2e/test/scenarios/organization/moderation-collection.cy.spec.js
@@ -264,6 +264,7 @@ function assertSearchResultBadge(itemName, opts) {
   const { expectBadge } = opts;
   cy.findByText(itemName, opts)
     .parentsUntil("[data-testid=search-result-item]")
+    .last()
     .within(() => {
       cy.icon("badge").should(expectBadge ? "exist" : "not.exist");
     });
diff --git a/e2e/test/scenarios/organization/timelines-question.cy.spec.js b/e2e/test/scenarios/organization/timelines-question.cy.spec.js
index 9809024794c..a131efe736b 100644
--- a/e2e/test/scenarios/organization/timelines-question.cy.spec.js
+++ b/e2e/test/scenarios/organization/timelines-question.cy.spec.js
@@ -1,7 +1,7 @@
 import {
   restore,
   visitQuestion,
-  sidebar,
+  rightSidebar,
   visitQuestionAdhoc,
 } from "e2e/support/helpers";
 import { SAMPLE_DB_ID } from "e2e/support/cypress_data";
@@ -99,7 +99,7 @@ describe("scenarios > organization > timelines > question", () => {
 
       cy.icon("calendar").click();
       cy.findByText("Releases").should("be.visible");
-      sidebar().within(() => cy.icon("ellipsis").click());
+      rightSidebar().within(() => cy.icon("ellipsis").click());
       cy.findByText("Edit event").click();
 
       cy.findByLabelText("Event name").clear().type("RC2");
@@ -125,7 +125,7 @@ describe("scenarios > organization > timelines > question", () => {
 
       cy.icon("calendar").click();
       cy.findByText("Builds").should("be.visible");
-      sidebar().within(() => cy.icon("ellipsis").click());
+      rightSidebar().within(() => cy.icon("ellipsis").click());
       cy.findByText("Move event").click();
       cy.findByText("Releases").click();
       cy.button("Move").click();
@@ -147,7 +147,7 @@ describe("scenarios > organization > timelines > question", () => {
 
       cy.icon("calendar").click();
       cy.findByText("Releases").should("be.visible");
-      sidebar().within(() => cy.icon("ellipsis").click());
+      rightSidebar().within(() => cy.icon("ellipsis").click());
       cy.findByText("Archive event").click();
       cy.wait("@updateEvent");
       cy.findByText("RC1").should("not.exist");
@@ -385,7 +385,7 @@ describe("scenarios > organization > timelines > question", () => {
       cy.icon("calendar").click();
       cy.findByText("Releases").should("be.visible");
       cy.findByText("Add an event").should("not.exist");
-      sidebar().within(() => cy.icon("ellipsis").should("not.exist"));
+      rightSidebar().within(() => cy.icon("ellipsis").should("not.exist"));
     });
   });
 });
diff --git a/e2e/test/scenarios/question/nested.cy.spec.js b/e2e/test/scenarios/question/nested.cy.spec.js
index 1e44ad53784..e68d79fe285 100644
--- a/e2e/test/scenarios/question/nested.cy.spec.js
+++ b/e2e/test/scenarios/question/nested.cy.spec.js
@@ -601,5 +601,10 @@ function visitNestedQueryAdHoc(id) {
 }
 
 function openHeaderCellContextMenu(cell) {
-  cy.findAllByTestId("header-cell").should("be.visible").contains(cell).click();
+  cy.findByTestId("TableInteractive-root").within(() => {
+    cy.findAllByTestId("header-cell")
+      .should("be.visible")
+      .contains(cell)
+      .click();
+  });
 }
diff --git a/e2e/test/scenarios/question/notebook.cy.spec.js b/e2e/test/scenarios/question/notebook.cy.spec.js
index 45d9dee239b..494ecca3390 100644
--- a/e2e/test/scenarios/question/notebook.cy.spec.js
+++ b/e2e/test/scenarios/question/notebook.cy.spec.js
@@ -97,7 +97,7 @@ describe("scenarios > question > notebook", () => {
 
     cy.findByText("ID between 96 97").click();
     cy.findByText("Between").click();
-    popover().within(() => {
+    cy.findByTestId("operator-select-list").within(() => {
       cy.contains("Is not");
       cy.contains("Greater than");
       cy.contains("Less than");
diff --git a/e2e/test/scenarios/question/nulls.cy.spec.js b/e2e/test/scenarios/question/nulls.cy.spec.js
index 5668fad124e..7611e195acd 100644
--- a/e2e/test/scenarios/question/nulls.cy.spec.js
+++ b/e2e/test/scenarios/question/nulls.cy.spec.js
@@ -2,9 +2,9 @@ import {
   restore,
   openOrdersTable,
   popover,
-  sidebar,
   summarize,
   visitDashboard,
+  rightSidebar,
 } from "e2e/support/helpers";
 
 import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
@@ -205,7 +205,7 @@ describe("scenarios > question > null", () => {
       openOrdersTable();
 
       summarize();
-      sidebar().within(() => {
+      rightSidebar().within(() => {
         // remove pre-selected "Count"
         cy.icon("close").click();
       });
diff --git a/e2e/test/scenarios/question/reproductions/18207-string-min-max.cy.spec.js b/e2e/test/scenarios/question/reproductions/18207-string-min-max.cy.spec.js
index fbddc79f3f7..fe4efa9980f 100644
--- a/e2e/test/scenarios/question/reproductions/18207-string-min-max.cy.spec.js
+++ b/e2e/test/scenarios/question/reproductions/18207-string-min-max.cy.spec.js
@@ -5,7 +5,7 @@ import {
   visualize,
   openProductsTable,
   summarize,
-  sidebar,
+  leftSidebar,
 } from "e2e/support/helpers";
 
 describe("issue 18207", () => {
@@ -66,7 +66,7 @@ describe("issue 18207", () => {
 
     // Why is it not a table?
     cy.contains("Visualization").click();
-    sidebar().within(() => {
+    leftSidebar().within(() => {
       cy.icon("table").click();
       cy.findByTestId("Table-button").realHover();
       cy.icon("gear").click();
diff --git a/e2e/test/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.cy.spec.js b/e2e/test/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.cy.spec.js
index 4a6a4d5a1ca..ffe2a4062bc 100644
--- a/e2e/test/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.cy.spec.js
+++ b/e2e/test/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.cy.spec.js
@@ -3,7 +3,7 @@ import {
   appBar,
   popover,
   openNavigationSidebar,
-  sidebar,
+  leftSidebar,
   visitQuestion,
   POPOVER_ELEMENT,
 } from "e2e/support/helpers";
@@ -75,7 +75,7 @@ describe("11914, 18978, 18977", () => {
 function setVisualizationTo(vizName) {
   cy.findByTestId("viz-type-button").click();
 
-  sidebar().within(() => {
+  leftSidebar().within(() => {
     cy.icon(vizName).click();
     cy.icon(vizName).realHover();
     cy.icon("gear").click();
@@ -83,17 +83,17 @@ function setVisualizationTo(vizName) {
   });
   selectFromDropdown("Created At");
 
-  sidebar().within(() => {
+  leftSidebar().within(() => {
     cy.findByText("Y-axis").parent().findByText("Select a field").click();
   });
   selectFromDropdown("Quantity");
 
-  sidebar().findByText("Done").click();
+  leftSidebar().findByText("Done").click();
 }
 
 function addGoalLine() {
   cy.findByTestId("viz-settings-button").click();
-  sidebar().within(() => {
+  leftSidebar().within(() => {
     cy.findByText("Display").click();
     cy.findByText("Goal line").parent().find("input").click();
     cy.findByText("Done").click();
diff --git a/e2e/test/scenarios/question/summarization.cy.spec.js b/e2e/test/scenarios/question/summarization.cy.spec.js
index 77e7552b8e8..2966ccba53d 100644
--- a/e2e/test/scenarios/question/summarization.cy.spec.js
+++ b/e2e/test/scenarios/question/summarization.cy.spec.js
@@ -201,7 +201,7 @@ describe("scenarios > question > summarize sidebar", () => {
       "**The point of failure for ANY non-numeric value reported in v0.36.4**",
     );
     // the default type for "Reviewer" is "No semantic type"
-    popover().within(() => {
+    cy.findByTestId("expression-suggestions-list").within(() => {
       cy.contains("Reviewer");
     });
   });
diff --git a/e2e/test/scenarios/sharing/alert/alert-types.cy.spec.js b/e2e/test/scenarios/sharing/alert/alert-types.cy.spec.js
index cd999850076..78d06295ec9 100644
--- a/e2e/test/scenarios/sharing/alert/alert-types.cy.spec.js
+++ b/e2e/test/scenarios/sharing/alert/alert-types.cy.spec.js
@@ -2,7 +2,7 @@ import {
   restore,
   setupSMTP,
   visitQuestion,
-  sidebar,
+  leftSidebar,
 } from "e2e/support/helpers";
 
 import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
@@ -73,7 +73,7 @@ describe("scenarios > alert > types", { tags: "@external" }, () => {
       visitQuestion(timeSeriesQuestionId);
 
       cy.findByText("Visualization").click();
-      sidebar().within(() => {
+      leftSidebar().within(() => {
         cy.icon("line").realHover();
         cy.icon("gear").click();
       });
diff --git a/e2e/test/scenarios/visualizations/pivot_tables.cy.spec.js b/e2e/test/scenarios/visualizations/pivot_tables.cy.spec.js
index 6b32fbdc0ae..8ad0cac213f 100644
--- a/e2e/test/scenarios/visualizations/pivot_tables.cy.spec.js
+++ b/e2e/test/scenarios/visualizations/pivot_tables.cy.spec.js
@@ -7,6 +7,7 @@ import {
   visitDashboard,
   visitIframe,
   dragField,
+  leftSidebar,
 } from "e2e/support/helpers";
 
 import { SAMPLE_DB_ID } from "e2e/support/cypress_data";
@@ -668,7 +669,7 @@ describe("scenarios > visualizations > pivot tables", () => {
     });
 
     cy.findByText("Visualization").click();
-    sidebar().within(() => {
+    leftSidebar().within(() => {
       // This part is still failing. Uncomment when fixed.
       // cy.findByText("Pivot Table")
       //   .parent()
diff --git a/e2e/test/scenarios/visualizations/trendline.cy.spec.js b/e2e/test/scenarios/visualizations/trendline.cy.spec.js
index 4dd42bcb185..edafc762f44 100644
--- a/e2e/test/scenarios/visualizations/trendline.cy.spec.js
+++ b/e2e/test/scenarios/visualizations/trendline.cy.spec.js
@@ -1,4 +1,4 @@
-import { restore, sidebar } from "e2e/support/helpers";
+import { restore, leftSidebar } from "e2e/support/helpers";
 import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
 
 const { ORDERS_ID, ORDERS } = SAMPLE_DATABASE;
@@ -35,7 +35,7 @@ describe("scenarios > question > trendline", () => {
     cy.get("rect");
 
     // Remove sum of total
-    sidebar().within(() => {
+    leftSidebar().within(() => {
       cy.findByText("Data").click();
       cy.icon("close").last().click();
       cy.findByText("Done").click();
diff --git a/e2e/test/scenarios/visualizations/waterfall.cy.spec.js b/e2e/test/scenarios/visualizations/waterfall.cy.spec.js
index 8134d5bae3b..4c822801b8d 100644
--- a/e2e/test/scenarios/visualizations/waterfall.cy.spec.js
+++ b/e2e/test/scenarios/visualizations/waterfall.cy.spec.js
@@ -284,9 +284,7 @@ describe("scenarios > visualizations > waterfall", () => {
       cy.get(".Visualization .value-label").should("not.exist");
 
       cy.contains("Show values on data points").next().click();
-      cy.get(".Visualization .value-label").within(() => {
-        cy.findByText("(4.56)"); // negative in parentheses
-      });
+      cy.get(".Visualization .value-label").contains(4.56).should("be.visible");
     });
   });
 });
diff --git a/frontend/src/metabase/core/components/AccordionList/AccordionList.jsx b/frontend/src/metabase/core/components/AccordionList/AccordionList.jsx
index 065ba40ec20..02fab86f2d1 100644
--- a/frontend/src/metabase/core/components/AccordionList/AccordionList.jsx
+++ b/frontend/src/metabase/core/components/AccordionList/AccordionList.jsx
@@ -95,6 +95,7 @@ export default class AccordionList extends Component {
     hasInitialFocus: PropTypes.bool,
 
     itemTestId: PropTypes.string,
+    "data-testid": PropTypes.string,
   };
 
   static defaultProps = {
@@ -546,7 +547,13 @@ export default class AccordionList extends Component {
   };
 
   render() {
-    const { id, style, className, sections } = this.props;
+    const {
+      id,
+      style,
+      className,
+      sections,
+      "data-testid": testId,
+    } = this.props;
     const { cursor, scrollToAlignment } = this.state;
 
     const rows = this.getRows();
@@ -567,6 +574,7 @@ export default class AccordionList extends Component {
             width: this.props.width,
             ...style,
           }}
+          data-testid={testId}
         >
           {rows.map((row, index) => (
             <AccordionListCell
@@ -627,6 +635,7 @@ export default class AccordionList extends Component {
         scrollToAlignment={scrollToAlignment}
         containerProps={{
           onKeyDown: this.handleKeyDown,
+          "data-testid": testId,
         }}
         rowRenderer={({ key, index, parent, style }) => {
           return (
diff --git a/frontend/src/metabase/core/components/Select/Select.tsx b/frontend/src/metabase/core/components/Select/Select.tsx
index 4b6847ff139..845f8ebd6ea 100644
--- a/frontend/src/metabase/core/components/Select/Select.tsx
+++ b/frontend/src/metabase/core/components/Select/Select.tsx
@@ -67,6 +67,7 @@ export interface SelectProps<TValue, TOption = SelectOption<TValue>> {
   optionStylesFn?: (option: TOption) => CSSProperties | undefined;
 
   footer?: ReactNode;
+  "data-testid"?: string;
 }
 
 export interface SelectOption<TValue = Key> {
@@ -253,6 +254,7 @@ class Select<TValue, TOption = SelectOption<TValue>> extends Component<
       disabled,
       width,
       footer,
+      "data-testid": testId,
     } = this.props;
 
     const sections = this._getSections();
@@ -321,6 +323,7 @@ class Select<TValue, TOption = SelectOption<TValue>> extends Component<
           searchFuzzy={searchFuzzy}
           searchPlaceholder={searchPlaceholder}
           hideEmptySectionsInSearch={hideEmptySectionsInSearch}
+          data-testid={testId ? `${testId}-list` : null}
         />
         {footer}
       </PopoverWithTrigger>
diff --git a/frontend/src/metabase/query_builder/components/NativeQueryEditor.jsx b/frontend/src/metabase/query_builder/components/NativeQueryEditor.jsx
index 01255ff4087..60e6edcaec4 100644
--- a/frontend/src/metabase/query_builder/components/NativeQueryEditor.jsx
+++ b/frontend/src/metabase/query_builder/components/NativeQueryEditor.jsx
@@ -582,7 +582,12 @@ class NativeQueryEditor extends Component {
             this._editor.resize();
           }}
         >
-          <div className="flex-full" id={ACE_ELEMENT_ID} ref={this.editor} />
+          <div
+            className="flex-full"
+            data-testid="native-query-editor"
+            id={ACE_ELEMENT_ID}
+            ref={this.editor}
+          />
 
           <RightClickPopover
             isOpen={this.state.isSelectedTextPopoverOpen}
diff --git a/frontend/src/metabase/query_builder/components/filters/OperatorSelector.jsx b/frontend/src/metabase/query_builder/components/filters/OperatorSelector.jsx
index aff7ed5a436..61b376a855f 100644
--- a/frontend/src/metabase/query_builder/components/filters/OperatorSelector.jsx
+++ b/frontend/src/metabase/query_builder/components/filters/OperatorSelector.jsx
@@ -19,6 +19,7 @@ export default class OperatorSelector extends Component {
         value={operator}
         onChange={e => onOperatorChange(e.target.value)}
         className={cx("border-medium text-default", className)}
+        data-testid="operator-select"
       >
         {operators.map(o => (
           <Option key={o.name} value={o.name}>
diff --git a/frontend/src/metabase/query_builder/components/notebook/NotebookStepPreview.jsx b/frontend/src/metabase/query_builder/components/notebook/NotebookStepPreview.jsx
index 404e607c435..05eb36165a3 100644
--- a/frontend/src/metabase/query_builder/components/notebook/NotebookStepPreview.jsx
+++ b/frontend/src/metabase/query_builder/components/notebook/NotebookStepPreview.jsx
@@ -61,7 +61,7 @@ class NotebookStepPreview extends React.Component {
       : { stiffness: 170 };
 
     return (
-      <PreviewRoot>
+      <PreviewRoot data-testid="preview-root">
         <PreviewHeader>
           <span className="text-bold">{t`Preview`}</span>
           <PreviewIconContainer>
diff --git a/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx b/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx
index 30b6ef899aa..51fad76bae8 100644
--- a/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx
+++ b/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx
@@ -988,6 +988,7 @@ class TableInteractive extends Component {
               })}
               onMouseEnter={this.handleOnMouseEnter}
               onMouseLeave={this.handleOnMouseLeave}
+              data-testid="TableInteractive-root"
             >
               <canvas
                 className="spread"
diff --git a/package.json b/package.json
index cdee70a05ac..c1ec4043cf7 100644
--- a/package.json
+++ b/package.json
@@ -134,7 +134,7 @@
     "@storybook/client-api": "6.5.15",
     "@storybook/manager-webpack5": "6.5.15",
     "@storybook/react": "6.5.15",
-    "@testing-library/cypress": "^8.0.3",
+    "@testing-library/cypress": "^9.0.0",
     "@testing-library/dom": "^7.29.0",
     "@testing-library/jest-dom": "^5.16.5",
     "@testing-library/react": "^11.0.2",
@@ -211,8 +211,8 @@
     "cross-fetch": "^3.1.5",
     "css-loader": "1.0.1",
     "cy-verify-downloads": "^0.1.12",
-    "cypress": "^10.9.0",
-    "cypress-real-events": "^1.7.1",
+    "cypress": "^12.8.1",
+    "cypress-real-events": "^1.7.6",
     "esbuild": "^0.17.9",
     "eslint": "7.32.0",
     "eslint-import-resolver-webpack": "^0.8.3",
diff --git a/yarn.lock b/yarn.lock
index 6b71af63efa..3a3ec5ce9bc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5141,10 +5141,10 @@
   dependencies:
     defer-to-connect "^1.0.1"
 
-"@testing-library/cypress@^8.0.3":
-  version "8.0.3"
-  resolved "https://registry.yarnpkg.com/@testing-library/cypress/-/cypress-8.0.3.tgz#24ab34df34d7896866603ade705afbdd186e273c"
-  integrity sha512-nY2YaSbmuPo5k6kL0iLj/pGPPfka3iwb3kpTx8QN/vOCns92Saz9wfACqB8FJzcR7+lfA4d5HUOWqmTddBzczg==
+"@testing-library/cypress@^9.0.0":
+  version "9.0.0"
+  resolved "https://registry.yarnpkg.com/@testing-library/cypress/-/cypress-9.0.0.tgz#3facad49c4654a99bbd138f83f33b415d2d6f097"
+  integrity sha512-c1XiCGeHGGTWn0LAU12sFUfoX3qfId5gcSE2yHode+vsyHDWraxDPALjVnHd4/Fa3j4KBcc5k++Ccy6A9qnkMA==
   dependencies:
     "@babel/runtime" "^7.14.6"
     "@testing-library/dom" "^8.1.0"
@@ -9725,15 +9725,15 @@ cyclist@^1.0.1:
   resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
   integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
 
-cypress-real-events@^1.7.1:
-  version "1.7.1"
-  resolved "https://registry.yarnpkg.com/cypress-real-events/-/cypress-real-events-1.7.1.tgz#8f430d67c29ea4f05b9c5b0311780120cbc9b935"
-  integrity sha512-/Bg15RgJ0SYsuXc6lPqH08x19z6j2vmhWN4wXfJqm3z8BTAFiK2MvipZPzxT8Z0jJP0q7kuniWrLIvz/i/8lCQ==
+cypress-real-events@^1.7.6:
+  version "1.7.6"
+  resolved "https://registry.yarnpkg.com/cypress-real-events/-/cypress-real-events-1.7.6.tgz#6f17e0b2ceea1d6dc60f6737d8f84cc517bbbb4c"
+  integrity sha512-yP6GnRrbm6HK5q4DH6Nnupz37nOfZu/xn1xFYqsE2o4G73giPWQOdu6375QYpwfU1cvHNCgyD2bQ2hPH9D7NMw==
 
-cypress@^10.9.0:
-  version "10.9.0"
-  resolved "https://registry.yarnpkg.com/cypress/-/cypress-10.9.0.tgz#273a61a6304766f9d6423e5ac8d4a9a11ed8b485"
-  integrity sha512-MjIWrRpc+bQM9U4kSSdATZWZ2hUqHGFEQTF7dfeZRa4MnalMtc88FIE49USWP2ZVtfy5WPBcgfBX+YorFqGElA==
+cypress@^12.8.1:
+  version "12.8.1"
+  resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.8.1.tgz#0c6e67f34554d553138697aaf349b637d80004eb"
+  integrity sha512-lIFbKdaSYAOarNLHNFa2aPZu6YSF+8UY4VRXMxJrFUnk6RvfG0AWsZ7/qle/aIz30TNUD4aOihz2ZgS4vuQVSA==
   dependencies:
     "@cypress/request" "^2.88.10"
     "@cypress/xvfb" "^1.2.4"
@@ -9752,7 +9752,7 @@ cypress@^10.9.0:
     commander "^5.1.0"
     common-tags "^1.8.0"
     dayjs "^1.10.4"
-    debug "^4.3.2"
+    debug "^4.3.4"
     enquirer "^2.3.6"
     eventemitter2 "6.4.7"
     execa "4.1.0"
-- 
GitLab