diff --git a/e2e/support/commands.js b/e2e/support/commands.js
index d2f1cf9127e78e004dec83cebf7d211200db98f4..13fbfa233d737d8eaa350c2c303138fb562036e9 100644
--- a/e2e/support/commands.js
+++ b/e2e/support/commands.js
@@ -1,12 +1,7 @@
 import "./commands/ui/button";
 import "./commands/ui/icon";
 
-import "./commands/api/index";
-import "./commands/api/dashboardCard";
-
-import "./commands/api/composite/createNativeQuestionAndDashboard";
-import "./commands/api/composite/createQuestionAndAddToDashboard";
-import "./commands/api/composite/createDashboardWithQuestions";
+import "./commands/api";
 
 import "./commands/user/createUser";
 import "./commands/user/authentication";
diff --git a/e2e/support/commands/api/index.ts b/e2e/support/commands/api.ts
similarity index 60%
rename from e2e/support/commands/api/index.ts
rename to e2e/support/commands/api.ts
index 2bf45fdf25b22b6a15a82bb7ddb7672302d3638a..6b7761f6904d8f9e3c211ec0a0e8a855f6cd2b44 100644
--- a/e2e/support/commands/api/index.ts
+++ b/e2e/support/commands/api.ts
@@ -3,9 +3,13 @@ import {
   archiveDashboard,
   createCollection,
   createDashboard,
+  createDashboardWithQuestions,
   createNativeQuestion,
+  createNativeQuestionAndDashboard,
   createQuestion,
+  createQuestionAndAddToDashboard,
   createQuestionAndDashboard,
+  editDashboardCard,
 } from "e2e/support/helpers";
 
 declare global {
@@ -43,6 +47,14 @@ declare global {
        */
       createDashboard: typeof createDashboard;
 
+      /**
+       * @deprecated Use function helper instead, i.e.
+       * ```
+       * import { createDashboardWithQuestions } from "e2e/support/helpers"
+       * ```
+       */
+      createDashboardWithQuestions: typeof createDashboardWithQuestions;
+
       /**
        * @deprecated Use function helper instead, i.e.
        * ```
@@ -51,6 +63,14 @@ declare global {
        */
       createNativeQuestion: typeof createNativeQuestion;
 
+      /**
+       * @deprecated Use function helper instead, i.e.
+       * ```
+       * import { createNativeQuestionAndDashboard } from "e2e/support/helpers"
+       * ```
+       */
+      createNativeQuestionAndDashboard: typeof createNativeQuestionAndDashboard;
+
       /**
        * @deprecated Use function helper instead, i.e.
        * ```
@@ -59,6 +79,14 @@ declare global {
        */
       createQuestion: typeof createQuestion;
 
+      /**
+       * @deprecated Use function helper instead, i.e.
+       * ```
+       * import { createQuestionAndAddToDashboard } from "e2e/support/helpers"
+       * ```
+       */
+      createQuestionAndAddToDashboard: typeof createQuestionAndAddToDashboard;
+
       /**
        * @deprecated Use function helper instead, i.e.
        * ```
@@ -66,6 +94,14 @@ declare global {
        * ```
        */
       createQuestionAndDashboard: typeof createQuestionAndDashboard;
+
+      /**
+       * @deprecated Use function helper instead, i.e.
+       * ```
+       * import { editDashboardCard } from "e2e/support/helpers"
+       * ```
+       */
+      editDashboardCard: typeof editDashboardCard;
     }
   }
 }
@@ -74,6 +110,19 @@ Cypress.Commands.add("archiveCollection", archiveCollection);
 Cypress.Commands.add("archiveDashboard", archiveDashboard);
 Cypress.Commands.add("createCollection", createCollection);
 Cypress.Commands.add("createDashboard", createDashboard);
+Cypress.Commands.add(
+  "createDashboardWithQuestions",
+  createDashboardWithQuestions,
+);
 Cypress.Commands.add("createNativeQuestion", createNativeQuestion);
+Cypress.Commands.add(
+  "createNativeQuestionAndDashboard",
+  createNativeQuestionAndDashboard,
+);
 Cypress.Commands.add("createQuestion", createQuestion);
+Cypress.Commands.add(
+  "createQuestionAndAddToDashboard",
+  createQuestionAndAddToDashboard,
+);
 Cypress.Commands.add("createQuestionAndDashboard", createQuestionAndDashboard);
+Cypress.Commands.add("editDashboardCard", editDashboardCard);
diff --git a/e2e/support/commands/api/composite/createDashboardWithQuestions.js b/e2e/support/commands/api/composite/createDashboardWithQuestions.js
deleted file mode 100644
index 824112532fe137f155e4cc1126d0a9ca9f971d00..0000000000000000000000000000000000000000
--- a/e2e/support/commands/api/composite/createDashboardWithQuestions.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import { cypressWaitAll } from "e2e/support/helpers";
-
-Cypress.Commands.add(
-  "createDashboardWithQuestions",
-  ({ dashboardName, dashboardDetails, questions, cards }) => {
-    return cy
-      .createDashboard({ name: dashboardName, ...dashboardDetails })
-      .then(({ body: dashboard }) => {
-        return cypressWaitAll(
-          questions.map((query, index) =>
-            cy.createQuestionAndAddToDashboard(
-              query,
-              dashboard.id,
-              cards ? cards[index] : undefined,
-            ),
-          ),
-        ).then(dashcardResponses => {
-          const questions = dashcardResponses.map(
-            dashcardResponse => dashcardResponse.body.card,
-          );
-          return {
-            questions,
-            dashboard,
-          };
-        });
-      });
-  },
-);
diff --git a/e2e/support/commands/api/composite/createNativeQuestionAndDashboard.js b/e2e/support/commands/api/composite/createNativeQuestionAndDashboard.js
deleted file mode 100644
index daac98d5f1f473b4c9d03368216b38cdc3b5037b..0000000000000000000000000000000000000000
--- a/e2e/support/commands/api/composite/createNativeQuestionAndDashboard.js
+++ /dev/null
@@ -1,37 +0,0 @@
-Cypress.Commands.add(
-  "createNativeQuestionAndDashboard",
-  ({ questionDetails, dashboardDetails } = {}) => {
-    const tabs = dashboardDetails?.tabs ?? [];
-    const defaultTabId = tabs[0]?.id ?? null;
-
-    cy.createNativeQuestion(questionDetails).then(
-      ({ body: { id: questionId } }) => {
-        cy.createDashboard(dashboardDetails).then(
-          ({ body: { id: dashboardId } }) => {
-            cy.request("PUT", `/api/dashboard/${dashboardId}`, {
-              tabs,
-              dashcards: [
-                {
-                  id: -1,
-                  card_id: questionId,
-                  dashboard_tab_id: defaultTabId,
-                  // Add sane defaults for the dashboard card size and position
-                  row: 0,
-                  col: 0,
-                  size_x: 11,
-                  size_y: 6,
-                },
-              ],
-            }).then(response => ({
-              ...response,
-              dashboardId,
-              dashboardTabs: response.body.tabs,
-              body: response.body.dashcards[0],
-              questionId,
-            }));
-          },
-        );
-      },
-    );
-  },
-);
diff --git a/e2e/support/commands/api/composite/createQuestionAndAddToDashboard.js b/e2e/support/commands/api/composite/createQuestionAndAddToDashboard.js
deleted file mode 100644
index aafe7f5087aa23326f3a0161978cf9ce8b51b68c..0000000000000000000000000000000000000000
--- a/e2e/support/commands/api/composite/createQuestionAndAddToDashboard.js
+++ /dev/null
@@ -1,33 +0,0 @@
-Cypress.Commands.add(
-  "createQuestionAndAddToDashboard",
-  (query, dashboardId, card) =>
-    (query.native
-      ? cy.createNativeQuestion(query)
-      : cy.createQuestion(query)
-    ).then(({ body: { id: card_id } }) =>
-      cy
-        .request(`/api/dashboard/${dashboardId}`)
-        .then(({ body: { dashcards } }) =>
-          cy
-            .request("PUT", `/api/dashboard/${dashboardId}`, {
-              dashcards: [
-                ...dashcards,
-                {
-                  id: -1,
-                  card_id,
-                  // Add sane defaults for the dashboard card size and position
-                  row: 0,
-                  col: 0,
-                  size_x: 11,
-                  size_y: 8,
-                  ...card,
-                },
-              ],
-            })
-            .then(response => ({
-              ...response,
-              body: response.body.dashcards.at(-1),
-            })),
-        ),
-    ),
-);
diff --git a/e2e/support/commands/api/dashboardCard.js b/e2e/support/commands/api/dashboardCard.js
deleted file mode 100644
index 92107c742b7cee64c6ca18a3016f472803663324..0000000000000000000000000000000000000000
--- a/e2e/support/commands/api/dashboardCard.js
+++ /dev/null
@@ -1,28 +0,0 @@
-import _ from "underscore";
-
-Cypress.Commands.add(
-  "editDashboardCard",
-  (dashboardCard, updatedProperties) => {
-    const { id, dashboard_id } = dashboardCard;
-
-    const cleanCard = sanitizeCard(dashboardCard);
-
-    const updatedCard = Object.assign({}, cleanCard, updatedProperties);
-
-    cy.log(`Edit dashboard card ${id}`);
-    cy.request("PUT", `/api/dashboard/${dashboard_id}`, {
-      dashcards: [updatedCard],
-    });
-  },
-);
-
-/**
- * Remove `created_at` and `updated_at` fields from the dashboard card that was previously added to the dashboard.
- * We don't want to hard code these fields in the next request that we'll pass the card object to.
- *
- * @param {Object} card - "Old", or the existing dashboard card.
- * @returns {Object}
- */
-function sanitizeCard(card) {
-  return _.omit(card, ["created_at", "updated_at"]);
-}
diff --git a/e2e/support/helpers/api/createDashboardWithQuestions.ts b/e2e/support/helpers/api/createDashboardWithQuestions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d2a269cd292b3ed416b3e574037058282ff4d5f2
--- /dev/null
+++ b/e2e/support/helpers/api/createDashboardWithQuestions.ts
@@ -0,0 +1,49 @@
+import type { Card, Dashboard } from "metabase-types/api";
+
+import { cypressWaitAll } from "../e2e-misc-helpers";
+
+import { type DashboardDetails, createDashboard } from "./createDashboard";
+import type { NativeQuestionDetails } from "./createNativeQuestion";
+import type { StructuredQuestionDetails } from "./createQuestion";
+import { createQuestionAndAddToDashboard } from "./createQuestionAndAddToDashboard";
+
+export const createDashboardWithQuestions = ({
+  dashboardName,
+  dashboardDetails,
+  questions,
+  cards,
+}: {
+  dashboardName?: string;
+  dashboardDetails?: DashboardDetails;
+  questions: (NativeQuestionDetails | StructuredQuestionDetails)[];
+  cards?: Partial<Card>[];
+}): Cypress.Chainable<
+  Cypress.Response<{
+    dashboard: Dashboard;
+    questions: Card;
+  }>
+> => {
+  // @ts-expect-error - Cypress typings don't account for what happens in then() here
+  return createDashboard({ name: dashboardName, ...dashboardDetails }).then(
+    ({ body: dashboard }) => {
+      return cypressWaitAll(
+        questions.map((query, index) =>
+          createQuestionAndAddToDashboard(
+            query,
+            dashboard.id,
+            cards ? cards[index] : undefined,
+          ),
+        ),
+      ).then(dashcardResponses => {
+        const questions = dashcardResponses.map(
+          dashcardResponse => dashcardResponse.body.card,
+        );
+
+        return {
+          questions,
+          dashboard,
+        };
+      });
+    },
+  );
+};
diff --git a/e2e/support/helpers/api/createNativeQuestionAndDashboard.ts b/e2e/support/helpers/api/createNativeQuestionAndDashboard.ts
index f25f828104b0d0f7799ac3e204a8008dc02d9c6c..4f43552a29bf2fa604c219f9e03823ca199e0eec 100644
--- a/e2e/support/helpers/api/createNativeQuestionAndDashboard.ts
+++ b/e2e/support/helpers/api/createNativeQuestionAndDashboard.ts
@@ -1,5 +1,10 @@
 import { createNativeQuestion } from "e2e/support/helpers";
-import type { CardId, Dashboard, DashboardCard } from "metabase-types/api";
+import type {
+  CardId,
+  Dashboard,
+  DashboardCard,
+  DashboardId,
+} from "metabase-types/api";
 
 import { type DashboardDetails, createDashboard } from "./createDashboard";
 import type { NativeQuestionDetails } from "./createQuestion";
@@ -13,32 +18,42 @@ export const createNativeQuestionAndDashboard = ({
   dashboardDetails?: DashboardDetails;
   cardDetails?: Partial<DashboardCard>;
 }): Cypress.Chainable<
-  Cypress.Response<DashboardCard> & { questionId: CardId }
+  Cypress.Response<DashboardCard> & {
+    dashboardId: DashboardId;
+    dashboardTabs: Dashboard["tabs"];
+    questionId: CardId;
+  }
 > => {
+  const tabs = dashboardDetails?.tabs ?? [];
+  const defaultTabId = tabs[0]?.id ?? null;
+
+  // @ts-expect-error - Cypress typings don't account for what happens in then() here
   return createNativeQuestion(questionDetails).then(
     ({ body: { id: questionId } }) => {
-      return createDashboard(dashboardDetails).then(
+      createDashboard(dashboardDetails).then(
         ({ body: { id: dashboardId } }) => {
-          return cy
-            .request<Dashboard>("PUT", `/api/dashboard/${dashboardId}`, {
-              dashcards: [
-                {
-                  id: -1,
-                  card_id: questionId,
-                  // Add sane defaults for the dashboard card size
-                  row: 0,
-                  col: 0,
-                  size_x: 11,
-                  size_y: 6,
-                  ...cardDetails,
-                },
-              ],
-            })
-            .then(response => ({
-              ...response,
-              body: response.body.dashcards[0],
-              questionId,
-            }));
+          cy.request("PUT", `/api/dashboard/${dashboardId}`, {
+            tabs,
+            dashcards: [
+              {
+                id: -1,
+                card_id: questionId,
+                dashboard_tab_id: defaultTabId,
+                // Add sane defaults for the dashboard card size and position
+                row: 0,
+                col: 0,
+                size_x: 11,
+                size_y: 6,
+                ...cardDetails,
+              },
+            ],
+          }).then(response => ({
+            ...response,
+            dashboardId,
+            dashboardTabs: response.body.tabs,
+            body: response.body.dashcards[0],
+            questionId,
+          }));
         },
       );
     },
diff --git a/e2e/support/helpers/api/createQuestionAndAddToDashboard.ts b/e2e/support/helpers/api/createQuestionAndAddToDashboard.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d974bde1b2fb75febd060305004fe19432186fbc
--- /dev/null
+++ b/e2e/support/helpers/api/createQuestionAndAddToDashboard.ts
@@ -0,0 +1,49 @@
+import type { Card, DashboardCard, DashboardId } from "metabase-types/api";
+
+import {
+  type NativeQuestionDetails,
+  createNativeQuestion,
+} from "./createNativeQuestion";
+import {
+  type StructuredQuestionDetails,
+  createQuestion,
+} from "./createQuestion";
+
+export const createQuestionAndAddToDashboard = (
+  query: NativeQuestionDetails | StructuredQuestionDetails,
+  dashboardId: DashboardId,
+  card?: Partial<Card>,
+): Cypress.Chainable<Cypress.Response<DashboardCard>> =>
+  (isNative(query) ? createNativeQuestion(query) : createQuestion(query)).then(
+    ({ body: { id: card_id } }) =>
+      cy
+        .request(`/api/dashboard/${dashboardId}`)
+        .then(({ body: { dashcards } }) =>
+          cy
+            .request("PUT", `/api/dashboard/${dashboardId}`, {
+              dashcards: [
+                ...dashcards,
+                {
+                  id: -1,
+                  card_id,
+                  // Add sane defaults for the dashboard card size and position
+                  row: 0,
+                  col: 0,
+                  size_x: 11,
+                  size_y: 8,
+                  ...card,
+                },
+              ],
+            })
+            .then(response => ({
+              ...response,
+              body: response.body.dashcards.at(-1),
+            })),
+        ),
+  );
+
+const isNative = (
+  query: NativeQuestionDetails | StructuredQuestionDetails,
+): query is NativeQuestionDetails => {
+  return "native" in query;
+};
diff --git a/e2e/support/helpers/api/editDashboardCard.ts b/e2e/support/helpers/api/editDashboardCard.ts
new file mode 100644
index 0000000000000000000000000000000000000000..676f49edd18d07503a7cbe07228bcdaad35f748f
--- /dev/null
+++ b/e2e/support/helpers/api/editDashboardCard.ts
@@ -0,0 +1,29 @@
+import _ from "underscore";
+
+import type { Dashboard, DashboardCard } from "metabase-types/api";
+
+export const editDashboardCard = (
+  dashboardCard: DashboardCard,
+  updatedProperties: Partial<DashboardCard>,
+): Cypress.Chainable<Cypress.Response<Dashboard>> => {
+  const { id, dashboard_id } = dashboardCard;
+
+  const cleanCard = sanitizeCard(dashboardCard);
+
+  const updatedCard = Object.assign({}, cleanCard, updatedProperties);
+
+  cy.log(`Edit dashboard card ${id}`);
+  return cy.request("PUT", `/api/dashboard/${dashboard_id}`, {
+    dashcards: [updatedCard],
+  });
+};
+
+/**
+ * Remove `created_at` and `updated_at` fields from the dashboard card that was previously added to the dashboard.
+ * We don't want to hard code these fields in the next request that we'll pass the card object to.
+ *
+ * @param card - "Old", or the existing dashboard card.
+ */
+function sanitizeCard(card: DashboardCard) {
+  return _.omit(card, ["created_at", "updated_at"]);
+}
diff --git a/e2e/support/helpers/api/index.ts b/e2e/support/helpers/api/index.ts
index ae10089e5d0542b7e77ab42d6b624a25fd47fa0c..da50b0f46650dd5353e1bbc4236c632536446d8a 100644
--- a/e2e/support/helpers/api/index.ts
+++ b/e2e/support/helpers/api/index.ts
@@ -7,6 +7,7 @@ export { createApiKey } from "./createApiKey";
 export { createCollection } from "./createCollection";
 export { createDashboard } from "./createDashboard";
 export type { DashboardDetails } from "./createDashboard";
+export { createDashboardWithQuestions } from "./createDashboardWithQuestions";
 export { createDashboardWithTabs } from "./createDashboardWithTabs";
 export { createModerationReview } from "./createModerationReview";
 export { createNativeQuestion } from "./createNativeQuestion";
@@ -18,10 +19,12 @@ export type {
   QuestionDetails,
   StructuredQuestionDetails,
 } from "./createQuestion";
+export { createQuestionAndAddToDashboard } from "./createQuestionAndAddToDashboard";
 export { createQuestionAndDashboard } from "./createQuestionAndDashboard";
 export { createTimeline } from "./createTimeline";
 export { createTimelineEvent } from "./createTimelineEvent";
 export { createTimelineWithEvents } from "./createTimelineWithEvents";
+export { editDashboardCard } from "./editDashboardCard";
 export { getCurrentUser } from "./getCurrentUser";
 export { remapDisplayValueToFK } from "./remapDisplayValueToFK";
 export { updateDashboardCards } from "./updateDashboardCards";