From 6dff2cf81c4aefb1d7468cf1a48e449cd8139882 Mon Sep 17 00:00:00 2001 From: Nemanja Glumac <31325167+nemanjaglumac@users.noreply.github.com> Date: Thu, 3 Mar 2022 15:01:50 +0100 Subject: [PATCH] Embedding questions (#20812) * Add test id to the mini-bar * Add initial embedding test for the regular GUI question * Update test with slighlty more complicated formatting * Extract question details into a separate file * Add a test for the quesiton with aggregation * Assert while being signed out * Add test for the nested question * Add test for the joined question --- .../visualizations/components/MiniBar.jsx | 1 + .../embedding/embedding-questions.cy.spec.js | 203 ++++++++++++++++++ .../embedding/embedding-questions.js | 75 +++++++ 3 files changed, 279 insertions(+) create mode 100644 frontend/test/metabase/scenarios/embedding/embedding-questions.cy.spec.js create mode 100644 frontend/test/metabase/scenarios/embedding/embedding-questions.js diff --git a/frontend/src/metabase/visualizations/components/MiniBar.jsx b/frontend/src/metabase/visualizations/components/MiniBar.jsx index f65224de80f..93fbca86bc2 100644 --- a/frontend/src/metabase/visualizations/components/MiniBar.jsx +++ b/frontend/src/metabase/visualizations/components/MiniBar.jsx @@ -52,6 +52,7 @@ const MiniBar = ({ value, extent: [min, max], options, cellHeight }) => { </div> {/* OUTER CONTAINER BAR */} <div + data-testid="mini-bar" className="ml1" style={{ position: "relative", diff --git a/frontend/test/metabase/scenarios/embedding/embedding-questions.cy.spec.js b/frontend/test/metabase/scenarios/embedding/embedding-questions.cy.spec.js new file mode 100644 index 00000000000..2840e353c1d --- /dev/null +++ b/frontend/test/metabase/scenarios/embedding/embedding-questions.cy.spec.js @@ -0,0 +1,203 @@ +import { restore, visitQuestion, popover } from "__support__/e2e/cypress"; +import { SAMPLE_DATABASE } from "__support__/e2e/cypress_sample_database"; + +import { + regularQuestion, + questionWithAggregation, + joinedQuestion, +} from "./embedding-questions"; + +const { ORDERS, PRODUCTS } = SAMPLE_DATABASE; + +describe("scenarios > embedding > questions ", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + // Remap Product ID -> Product Title + cy.request("POST", `/api/field/${ORDERS.PRODUCT_ID}/dimension`, { + name: "Product ID as Title", + type: "external", + human_readable_field_id: PRODUCTS.TITLE, + }); + + // Do not include Subtotal anywhere + cy.request("PUT", `/api/field/${ORDERS.SUBTOTAL}`, { + visibility_type: "sensitive", + }); + }); + + it("should display the regular GUI question correctly", () => { + const { name: title, description } = regularQuestion; + + cy.createQuestion(regularQuestion).then(({ body: { id } }) => { + cy.request("PUT", `/api/card/${id}`, { enable_embedding: true }); + + visitQuestion(id); + }); + + cy.icon("share").click(); + cy.findByText("Embed this question in an application").click(); + + cy.document().then(doc => { + const iframe = doc.querySelector("iframe"); + + cy.signOut(); + cy.visit(iframe.src); + }); + + cy.findByText(title); + + cy.icon("info").realHover(); + popover().contains(description); + + // Data model: Renamed column + cy.findByText("Product ID as Title"); + // Data model: Display value changed to show FK + cy.findByText("Awesome Concrete Shoes"); + // Custom column + cy.findByText("Math"); + // Question settings: Renamed column + cy.findByText("Billed"); + // Question settings: Column formating + cy.findByText("€39.72"); + // Question settings: Abbreviated date, day enabled, 24H clock with seconds + cy.findByText("Mon, Feb 11, 2019, 21:40:27"); + // Question settings: Show mini-bar + cy.findAllByTestId("mini-bar"); + + // Data model: Subtotal is turned off globally + cy.findByText("Subtotal").should("not.exist"); + }); + + it("should display the GUI question with aggregation correctly", () => { + cy.createQuestion(questionWithAggregation).then(({ body: { id } }) => { + cy.request("PUT", `/api/card/${id}`, { enable_embedding: true }); + + visitQuestion(id); + }); + + cy.icon("share").click(); + cy.findByText("Embed this question in an application").click(); + + cy.document().then(doc => { + const iframe = doc.querySelector("iframe"); + + cy.signOut(); + cy.visit(iframe.src); + }); + + assertOnXYAxisLabels({ xLabel: "Created At", yLabel: "Count" }); + + cy.get(".x.axis .tick") + .should("have.length", 5) + .and("contain", "Apr, 2016"); + + cy.get(".y.axis .tick").should("contain", "60"); + + // Check the tooltip for the last point on the line + cy.get(".dot") + .last() + .realHover(); + + popover().within(() => { + testPairedTooltipValues("Created At", "Aug, 2016"); + testPairedTooltipValues("Math", "2"); + testPairedTooltipValues("Count", "79"); + }); + }); + + it("should display the nested GUI question correctly", () => { + cy.createQuestion(regularQuestion).then(({ body: { id } }) => { + const nestedQuestion = { + query: { "source-table": `card__${id}`, limit: 10 }, + }; + + cy.createQuestion(nestedQuestion).then(({ body: { id: nestedId } }) => { + cy.request("PUT", `/api/card/${nestedId}`, { enable_embedding: true }); + + visitQuestion(nestedId); + }); + }); + + cy.icon("share").click(); + cy.findByText("Embed this question in an application").click(); + + cy.document().then(doc => { + const iframe = doc.querySelector("iframe"); + + cy.signOut(); + cy.visit(iframe.src); + }); + + // Global (Data model) settings should be preserved + cy.findByText("Product ID as Title"); + cy.findByText("Awesome Concrete Shoes"); + + // Custom column + cy.findByText("Math"); + + // Base question visualization settings should reset to the defaults (inherit global formatting) + cy.findByText("Total"); + cy.findByText("39.72"); + cy.findByText("February 11, 2019, 9:40 PM"); + + cy.findAllByTestId("mini-bar").should("not.exist"); + + // Data model: Subtotal is turned off globally + cy.findByText("Subtotal").should("not.exist"); + }); + + it("should display GUI question with explicit joins correctly", () => { + cy.createQuestion(joinedQuestion).then(({ body: { id } }) => { + cy.request("PUT", `/api/card/${id}`, { enable_embedding: true }); + + visitQuestion(id); + }); + + cy.icon("share").click(); + cy.findByText("Embed this question in an application").click(); + + cy.document().then(doc => { + const iframe = doc.querySelector("iframe"); + + cy.signOut(); + cy.visit(iframe.src); + }); + + // Base question assertions + cy.findByText("Product ID as Title"); + cy.findByText("Awesome Concrete Shoes"); + cy.findByText("Math"); + cy.findByText("Billed"); + cy.findByText("€39.72"); + cy.findByText("Mon, Feb 11, 2019, 21:40:27"); + cy.findAllByTestId("mini-bar"); + cy.findByText("Subtotal").should("not.exist"); + + // Joined table fields + cy.contains("98.52598640° W"); + + cy.contains("User → Birth Date"); + cy.contains("December 12, 1986"); + + cy.contains("October 7, 2017, 1:34 AM"); + }); +}); + +function testPairedTooltipValues(val1, val2) { + cy.contains(val1) + .closest("td") + .siblings("td") + .findByText(val2); +} + +function assertOnXYAxisLabels({ xLabel, yLabel } = {}) { + cy.get(".x-axis-label") + .invoke("text") + .should("eq", xLabel); + + cy.get(".y-axis-label") + .invoke("text") + .should("eq", yLabel); +} diff --git a/frontend/test/metabase/scenarios/embedding/embedding-questions.js b/frontend/test/metabase/scenarios/embedding/embedding-questions.js new file mode 100644 index 00000000000..d4d132617e7 --- /dev/null +++ b/frontend/test/metabase/scenarios/embedding/embedding-questions.js @@ -0,0 +1,75 @@ +import { SAMPLE_DATABASE } from "__support__/e2e/cypress_sample_database"; + +const { ORDERS, ORDERS_ID, PEOPLE, PEOPLE_ID } = SAMPLE_DATABASE; + +export const regularQuestion = { + name: "Orders4t#7 t3", + description: "Foo", + query: { + "source-table": ORDERS_ID, + limit: 5, + expressions: { Math: ["+", 1, 1] }, + }, + visualization_settings: { + column_settings: { + [`["ref",["field",${ORDERS.CREATED_AT},null]]`]: { + date_abbreviate: true, + date_style: "dddd, MMMM D, YYYY", + time_enabled: "seconds", + time_style: "HH:mm", + }, + [`["ref",["field",${ORDERS.TOTAL},null]]`]: { + column_title: "Billed", + number_style: "currency", + currency_in_header: false, + currency: "EUR", + currency_style: "symbol", + }, + [`["ref",["field",${ORDERS.TAX},null]]`]: { show_mini_bar: true }, + }, + }, +}; + +export const questionWithAggregation = { + ...regularQuestion, + query: { + ...regularQuestion.query, + aggregation: [["count"]], + breakout: [ + [ + "field", + ORDERS.CREATED_AT, + { + "temporal-unit": "month", + }, + ], + ["expression", "Math", null], + ], + }, + display: "line", +}; + +export const joinedQuestion = { + ...regularQuestion, + query: { + ...regularQuestion.query, + joins: [ + { + fields: "all", + "source-table": PEOPLE_ID, + condition: [ + "=", + ["field", ORDERS.USER_ID, null], + [ + "field", + PEOPLE.ID, + { + "join-alias": "User", + }, + ], + ], + alias: "User", + }, + ], + }, +}; -- GitLab