Files
metabase/e2e/test-component/scenarios/embedding-sdk/interactive-dashboard.cy.spec.tsx
Kamil Mielnik 5a1d677444 RFC 118. Prettier - arrowParens: “always” (#55807)
* Update .prettierrc
- remove "arrowParens": "avoid" so that it defaults to "always" instead

* Run "yarn prettier"
2025-03-27 09:18:07 +00:00

194 lines
5.8 KiB
TypeScript

const { H } = cy;
import {
InteractiveDashboard,
InteractiveQuestion,
} from "@metabase/embedding-sdk-react";
import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
import {
ORDERS_DASHBOARD_DASHCARD_ID,
ORDERS_QUESTION_ID,
} from "e2e/support/cypress_sample_instance_data";
import {
mockAuthProviderAndJwtSignIn,
mountSdkContent,
signInAsAdminAndEnableEmbeddingSdk,
} from "e2e/support/helpers/component-testing-sdk";
import { getSdkRoot } from "e2e/support/helpers/e2e-embedding-sdk-helpers";
import { defer } from "metabase/lib/promise";
import { Stack } from "metabase/ui";
import type {
ConcreteFieldReference,
DashboardCard,
Parameter,
} from "metabase-types/api";
const { ORDERS } = SAMPLE_DATABASE;
const DATE_FILTER: Parameter = {
id: "2",
name: "Date filter",
slug: "filter-date",
type: "date/all-options",
};
const CREATED_AT_FIELD_REF: ConcreteFieldReference = [
"field",
ORDERS.CREATED_AT,
{ "base-type": "type/DateTime" },
];
describe("scenarios > embedding-sdk > interactive-dashboard", () => {
beforeEach(() => {
signInAsAdminAndEnableEmbeddingSdk();
const textCard = H.getTextCardDetails({ col: 16, text: "Test text card" });
const questionCard: Partial<DashboardCard> = {
id: ORDERS_DASHBOARD_DASHCARD_ID,
parameter_mappings: [
{
parameter_id: DATE_FILTER.id,
card_id: ORDERS_QUESTION_ID,
target: ["dimension", CREATED_AT_FIELD_REF],
},
],
card_id: ORDERS_QUESTION_ID,
row: 0,
col: 0,
size_x: 16,
size_y: 8,
};
H.createDashboard({
name: "Orders in a dashboard",
dashcards: [questionCard, textCard],
parameters: [DATE_FILTER],
}).then(({ body: dashboard }) => {
cy.wrap(dashboard.id).as("dashboardId");
cy.wrap(dashboard.entity_id).as("dashboardEntityId");
});
cy.signOut();
mockAuthProviderAndJwtSignIn();
cy.intercept("GET", "/api/dashboard/*").as("getDashboard");
cy.intercept("POST", "/api/dashboard/*/dashcard/*/card/*/query").as(
"dashcardQuery",
);
});
it("should be able to display custom question layout when clicking on dashboard cards", () => {
cy.get<string>("@dashboardId").then((dashboardId) => {
mountSdkContent(
<InteractiveDashboard
dashboardId={dashboardId}
renderDrillThroughQuestion={() => (
<Stack>
<InteractiveQuestion.Title />
<InteractiveQuestion.QuestionVisualization />
<div>This is a custom question layout.</div>
</Stack>
)}
/>,
);
});
getSdkRoot().within(() => {
cy.contains("Orders in a dashboard").should("be.visible");
cy.findByText("Orders").click();
cy.contains("Orders").should("be.visible");
cy.contains("This is a custom question layout.");
});
});
describe("loading behavior for both entity IDs and number IDs (metabase#49581)", () => {
const successTestCases = [
{
name: "correct entity ID",
dashboardIdAlias: "@dashboardEntityId",
},
{
name: "correct number ID",
dashboardIdAlias: "@dashboardId",
},
];
const failureTestCases = [
{
name: "wrong entity ID",
dashboardId: "VFCGVYPVtLzCtt4teeoW4",
},
{
name: "one too many entity ID character",
dashboardId: "VFCGVYPVtLzCtt4teeoW49",
},
{
name: "wrong number ID",
dashboardId: 9999,
},
];
successTestCases.forEach(({ name, dashboardIdAlias }) => {
it(`should load dashboard content for ${name}`, () => {
cy.get(dashboardIdAlias).then((dashboardId) => {
mountSdkContent(<InteractiveDashboard dashboardId={dashboardId} />);
});
getSdkRoot().within(() => {
cy.findByText("Orders in a dashboard").should("be.visible");
cy.findByText("Orders").should("be.visible");
H.assertTableRowsCount(2000);
cy.findByText("Test text card").should("be.visible");
});
});
});
failureTestCases.forEach(({ name, dashboardId }) => {
it(`should show an error message for ${name}`, () => {
mountSdkContent(<InteractiveDashboard dashboardId={dashboardId} />);
getSdkRoot().within(() => {
const expectedErrorMessage = `Dashboard ${dashboardId} not found. Make sure you pass the correct ID.`;
cy.findByRole("alert").should("have.text", expectedErrorMessage);
cy.findByText("Orders in a dashboard").should("not.exist");
cy.findByText("Orders").should("not.exist");
H.tableInteractiveBody().should("not.exist");
cy.findByText("Test text card").should("not.exist");
});
});
});
});
it('should drill dashboards with filter values and not showing "Question not found" error (EMB-84)', () => {
cy.get("@dashboardId").then((dashboardId) => {
mountSdkContent(<InteractiveDashboard dashboardId={dashboardId} />);
});
H.filterWidget().eq(0).click();
H.popover().button("Previous 12 months").click();
const { promise, resolve: resolveCardEndpoint } = defer();
/**
* This seems to be the only reliable way to force the error to stay, and we will resolve
* the promise that will cause the error to go away manually after asserting that it's not there.
*/
cy.intercept("get", "/api/card/*", (req) => {
return promise.then(() => {
req.continue();
});
}).as("getCard");
getSdkRoot().within(() => {
H.getDashboardCard().findByText("Orders").click();
cy.findByText("Question not found")
.should("not.exist")
.then(() => {
resolveCardEndpoint();
});
cy.findByText("New question").should("be.visible");
});
});
});