Skip to content
Snippets Groups Projects
Unverified Commit ccd3b577 authored by Kamil Mielnik's avatar Kamil Mielnik Committed by GitHub
Browse files

Refactor e2e helpers and commands to TypeScript function helpers (#47237)

* Convert e2e-custom-column-helpers to TS

* Refactor createTimeline, createTimelineEvent & createTimelineWithEvents to TS

* Fix circular imports
parent c73c198a
Branches
Tags
No related merge requests found
......@@ -3,12 +3,10 @@ import "./commands/ui/icon";
import "./commands/api/index";
import "./commands/api/dashboardCard";
import "./commands/api/timeline";
import "./commands/api/composite/createNativeQuestionAndDashboard";
import "./commands/api/composite/createQuestionAndAddToDashboard";
import "./commands/api/composite/createDashboardWithQuestions";
import "./commands/api/composite/createTimelineWithEvents";
import "./commands/user/createUser";
import "./commands/user/authentication";
......
import { cypressWaitAll } from "e2e/support/helpers";
Cypress.Commands.add("createTimelineWithEvents", ({ timeline, events }) => {
return cy.createTimeline(timeline).then(({ body: timeline }) => {
return cypressWaitAll(
events.map(query =>
cy.createTimelineEvent({ ...query, timeline_id: timeline.id }),
),
).then(events => {
return {
timeline,
events,
};
});
});
});
Cypress.Commands.add(
"createTimeline",
({
name = "Timeline",
description,
icon = "star",
collection_id,
default: is_default = false,
archived = false,
} = {}) => {
return cy.request("POST", "/api/timeline", {
name,
description,
icon,
collection_id,
default: is_default,
archived,
});
},
);
Cypress.Commands.add(
"createTimelineEvent",
({
name = "Event",
description,
icon = "star",
timestamp = "2020-01-01T00:00:00Z",
time_matters = false,
timezone = "UTC",
timeline_id,
archived = false,
}) => {
return cy.request("POST", "/api/timeline-event", {
name,
description,
icon,
timestamp,
time_matters,
timezone,
timeline_id,
archived,
});
},
);
import type { CreateTimelineRequest, Timeline } from "metabase-types/api";
export const createTimeline = ({
name = "Timeline",
icon = "star",
default: isDefault = false,
archived = false,
...params
}: Partial<CreateTimelineRequest> = {}): Cypress.Chainable<
Cypress.Response<Timeline>
> => {
return cy.request("POST", "/api/timeline", {
...params,
name,
icon,
default: isDefault,
archived,
});
};
import type {
CreateTimelineEventRequest,
TimelineEvent,
} from "metabase-types/api";
export const createTimelineEvent = ({
name = "Event",
icon = "star",
timestamp = "2020-01-01T00:00:00Z",
time_matters = false,
timezone = "UTC",
archived = false,
...params
}: CreateTimelineEventRequest): Cypress.Chainable<
Cypress.Response<TimelineEvent>
> => {
return cy.request("POST", "/api/timeline-event", {
...params,
name,
icon,
timestamp,
time_matters,
timezone,
archived,
});
};
import type {
CreateTimelineEventRequest,
CreateTimelineRequest,
Timeline,
TimelineEvent,
} from "metabase-types/api";
import { cypressWaitAll } from "../e2e-misc-helpers";
import { createTimeline } from "./createTimeline";
import { createTimelineEvent } from "./createTimelineEvent";
export const createTimelineWithEvents = ({
timeline,
events,
}: {
timeline: CreateTimelineRequest;
events: CreateTimelineEventRequest[];
}): {
timeline: Timeline;
events: TimelineEvent[];
} => {
// @ts-expect-error - Cypress typings don't account for what happens in then() here
return createTimeline(timeline).then(({ body: timeline }) => {
return cypressWaitAll(
events.map(query =>
createTimelineEvent({ ...query, timeline_id: timeline.id }),
),
).then(events => {
return {
timeline,
events,
};
});
});
};
......@@ -18,6 +18,9 @@ export type {
StructuredQuestionDetails,
} from "./createQuestion";
export { createQuestionAndDashboard } from "./createQuestionAndDashboard";
export { createTimeline } from "./createTimeline";
export { createTimelineEvent } from "./createTimelineEvent";
export { createTimelineWithEvents } from "./createTimelineWithEvents";
export { getCurrentUser } from "./getCurrentUser";
export { remapDisplayValueToFK } from "./remapDisplayValueToFK";
export { updateDashboardCards } from "./updateDashboardCards";
......@@ -8,7 +8,16 @@ export function expressionEditorWidget() {
* @param {string=} option.name
* @param {boolean} option.blur true by default. However, if you need to examine the popover in the test, it should be set to false so the popover is not dismissed
*/
export function enterCustomColumnDetails({ formula, name, blur = true }) {
export function enterCustomColumnDetails({
formula,
name,
blur = true,
}: {
formula: string;
name?: string;
blur?: boolean;
}) {
cy.get(".ace_text-input")
.first()
.as("formula")
......@@ -32,13 +41,13 @@ export function checkExpressionEditorHelperPopoverPosition() {
cy.findByTestId("expression-editor-textfield").then($target => {
const textfieldPosition = $target[0].getBoundingClientRect();
cy.findByTestId("expression-helper-popover", $target => {
cy.findByTestId("expression-helper-popover").then($target => {
const popoverPosition = $target[0].getBoundingClientRect();
expect(textfieldPosition.top - popoverPosition.top).toBeLessThan(
expect(textfieldPosition.top - popoverPosition.top).to.be.lessThan(
textfieldPosition.height * 2,
);
expect(textfieldPosition.left - popoverPosition.left).toBeLessThan(10);
expect(textfieldPosition.left - popoverPosition.left).to.be.lessThan(10);
});
});
}
import { USERS } from "e2e/support/cypress_data";
import {
createTimeline,
createTimelineWithEvents,
describeWithSnowplow,
enableTracking,
entityPickerModal,
......@@ -84,7 +86,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should search for events", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
events: [
{ name: "RC1" },
{ name: "RC2" },
......@@ -221,7 +223,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should edit an event", () => {
cy.createTimelineWithEvents({ events: [{ name: "RC1" }] });
createTimelineWithEvents({ events: [{ name: "RC1" }] });
cy.visit("/collection/root/timelines");
openMenu("RC1");
......@@ -236,11 +238,11 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should move an event", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1" }],
});
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Metrics" },
events: [{ name: "RC2" }],
});
......@@ -268,11 +270,11 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should move an event and undo", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1" }],
});
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Metrics" },
events: [{ name: "RC2" }],
});
......@@ -298,7 +300,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should archive an event when editing this event", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1" }, { name: "RC2" }],
});
......@@ -319,7 +321,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should archive an event from the timeline and undo", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1" }, { name: "RC2" }],
});
......@@ -341,7 +343,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should unarchive an event from the archive and undo", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1", archived: true }],
});
......@@ -369,7 +371,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should delete an event", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1", archived: true }],
});
......@@ -392,8 +394,8 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should allow navigating back to the list of timelines", () => {
cy.createTimeline({ name: "Releases" });
cy.createTimeline({ name: "Metrics" });
createTimeline({ name: "Releases" });
createTimeline({ name: "Metrics" });
cy.visit("/collection/root/timelines/1");
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
......@@ -407,7 +409,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should not allow navigating back when there is only one timeline in a collection", () => {
cy.createTimeline({ name: "Releases" });
createTimeline({ name: "Releases" });
cy.visit("/collection/root/timelines/1");
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
......@@ -416,7 +418,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should create an additional timeline", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1" }],
});
......@@ -437,7 +439,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should edit a timeline", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1" }],
});
......@@ -456,7 +458,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should move a timeline", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Events", default: true },
events: [{ name: "RC1" }],
});
......@@ -481,7 +483,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should archive a timeline and undo", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1" }, { name: "RC2" }],
});
......@@ -510,12 +512,12 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should support markdown in timeline description", () => {
cy.createTimeline({
createTimeline({
name: "Releases",
description: "[Release notes](https://metabase.test)",
});
cy.createTimeline({
createTimeline({
name: "Holidays",
description: "[Holiday list](https://metabase.test)",
});
......@@ -528,7 +530,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should support markdown in event description", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: {
name: "Releases",
},
......@@ -546,7 +548,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should archive and unarchive a timeline", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1" }, { name: "RC2" }],
});
......@@ -575,7 +577,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should archive and delete a timeline", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1" }, { name: "RC2" }],
});
......@@ -639,7 +641,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should use custom date formatting settings", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
events: [{ name: "RC1", timestamp: "2022-10-12T18:15:30Z" }],
});
setFormattingSettings({
......@@ -660,7 +662,7 @@ describe("scenarios > organization > timelines > collection", () => {
});
it("should use custom time formatting settings", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
events: [{ name: "RC1", timestamp: "2022-10-12T18:15:30Z" }],
});
setFormattingSettings({
......@@ -695,7 +697,7 @@ describe("scenarios > organization > timelines > collection", () => {
it("should not allow creating new events in existing timelines", () => {
cy.signInAsAdmin();
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1" }],
});
......
......@@ -2,6 +2,8 @@ import { SAMPLE_DB_ID } from "e2e/support/cypress_data";
import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
import { ORDERS_BY_YEAR_QUESTION_ID } from "e2e/support/cypress_sample_instance_data";
import {
createTimeline,
createTimelineWithEvents,
echartsIcon,
popover,
restore,
......@@ -47,7 +49,7 @@ describe("scenarios > organization > timelines > question", () => {
});
it("should create an event within the default timeline", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1", timestamp: "2024-10-20T00:00:00Z" }],
});
......@@ -75,7 +77,7 @@ describe("scenarios > organization > timelines > question", () => {
});
it("should display all events in data view", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [
{ name: "v1", timestamp: "2027-01-01T00:00:00Z" },
......@@ -107,7 +109,7 @@ describe("scenarios > organization > timelines > question", () => {
});
it("should edit an event", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1", timestamp: "2024-10-20T00:00:00Z" }],
});
......@@ -136,10 +138,8 @@ describe("scenarios > organization > timelines > question", () => {
});
it("should move an event", () => {
cy.createTimeline({
name: "Releases",
});
cy.createTimelineWithEvents({
createTimeline({ name: "Releases" });
createTimelineWithEvents({
timeline: { name: "Builds" },
events: [{ name: "RC2", timestamp: "2024-10-20T00:00:00Z" }],
});
......@@ -167,7 +167,7 @@ describe("scenarios > organization > timelines > question", () => {
});
it("should archive and unarchive an event", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1", timestamp: "2024-10-20T00:00:00Z" }],
});
......@@ -195,7 +195,7 @@ describe("scenarios > organization > timelines > question", () => {
});
it("should support markdown in event description", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: {
name: "Releases",
},
......@@ -218,7 +218,7 @@ describe("scenarios > organization > timelines > question", () => {
});
it("should show events for ad-hoc questions", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1", timestamp: "2024-10-20T00:00:00Z" }],
});
......@@ -246,7 +246,7 @@ describe("scenarios > organization > timelines > question", () => {
});
it("should not show events for non-timeseries questions", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1", timestamp: "2024-10-20T00:00:00Z" }],
});
......@@ -276,7 +276,7 @@ describe("scenarios > organization > timelines > question", () => {
});
it("should show events for native queries", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1", timestamp: "2024-10-20T00:00:00Z" }],
});
......@@ -306,14 +306,14 @@ describe("scenarios > organization > timelines > question", () => {
name: "Parent",
parent_id: null,
}).then(({ body: { id: PARENT_COLLECTION_ID } }) => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [
{ name: "RC1", timestamp: "2024-10-20T00:00:00Z", icon: "cloud" },
],
});
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: {
name: "Timeline for collection",
collection_id: PARENT_COLLECTION_ID,
......@@ -404,7 +404,7 @@ describe("scenarios > organization > timelines > question", () => {
});
it("should color the event icon when hovering", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [
{ name: "RC1", timestamp: "2024-10-20T00:00:00Z", icon: "star" },
......@@ -419,7 +419,7 @@ describe("scenarios > organization > timelines > question", () => {
});
it("should open the sidebar when clicking an event icon", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [
{ name: "RC1", timestamp: "2024-10-20T00:00:00Z", icon: "star" },
......@@ -450,7 +450,7 @@ describe("scenarios > organization > timelines > question", () => {
});
it("should not filter out events in last period (metabase#23336)", () => {
cy.createTimelineWithEvents({
createTimelineWithEvents({
events: [
{ name: "Last week", timestamp: "2026-04-21T12:00:00Z" },
{ name: "Last month", timestamp: "2026-04-27T12:00:00Z" },
......@@ -534,7 +534,7 @@ describe("scenarios > organization > timelines > question", () => {
it("should not allow creating or editing events", () => {
cy.signInAsAdmin();
cy.createTimelineWithEvents({
createTimelineWithEvents({
timeline: { name: "Releases" },
events: [{ name: "RC1", timestamp: "2024-10-20T00:00:00Z" }],
});
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment