diff --git a/frontend/test/metabase/scenarios/question/question-reproductions.cy.spec.js b/frontend/test/metabase/scenarios/question/question-reproductions.cy.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..caec455e0827bc64d05d16ed31db778d50fe4a2e --- /dev/null +++ b/frontend/test/metabase/scenarios/question/question-reproductions.cy.spec.js @@ -0,0 +1,39 @@ +import { issue4482 } from "./reproductions/4482-temporal-min-max"; +import { issue6239 } from "./reproductions/6239-sort-using-cust-exp"; +import { issue9027 } from "./reproductions/9027-new-questions-not-in-saved-questions-immediately"; +import { issue13097 } from "./reproductions/13097-mongo-apply-distinct-count-multiple-columns"; +import { issue13263 } from "./reproductions/13263-postgres-show-row-details-on-pk-click"; +import { issue14957 } from "./reproductions/14957-unable-to-save-question-before-query-executed"; +import { issue15714 } from "./reproductions/15714-cc-postgres-percentile-accepts-two-params"; +import { issue15876 } from "./reproductions/15876-postgres-cast-time"; +import { issue16621 } from "./reproductions/16621-create-multiple-filters-with-same-value"; +import { issue17512 } from "./reproductions/17512"; +import { issue17514 } from "./reproductions/17514-ui-overlay"; +import { issue17963 } from "./reproductions/17963-mongo-filter-expression-compare-two-fields"; +import { issue18207 } from "./reproductions/18207-string-min-max"; +import { issue18978 } from "./reproductions/18978-18977-nested-question-nodata-user"; +import { issue19341 } from "./reproductions/19341-disabled-nested-queries"; +import { issue19742 } from "./reproductions/19742-data-picker-closes-after-hiding-table"; +import { issue20551 } from "./reproductions/20551-filter-starts-with"; +import { issue20627 } from "./reproductions/20627-nested-long-names-wrong-aliases"; +import { issue20683 } from "./reproductions/20683-postgres-current-quarter"; + +issue4482(); +issue6239(); +issue9027(); +issue13097(); +issue13263(); +issue14957(); +issue15714(); +issue15876(); +issue16621(); +issue17512(); +issue17514(); +issue17963(); +issue18207(); +issue18978(); +issue19341(); +issue19742(); +issue20551(); +issue20627(); +issue20683(); diff --git a/frontend/test/metabase/scenarios/question/reproductions/13097-mongo-apply-distinct-count-multiple-columns.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/13097-mongo-apply-distinct-count-multiple-columns.cy.spec.js deleted file mode 100644 index 416197fcad816dda40a959886fc3ea8e2c64bcf6..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/13097-mongo-apply-distinct-count-multiple-columns.cy.spec.js +++ /dev/null @@ -1,54 +0,0 @@ -import { - restore, - visualize, - withDatabase, - adhocQuestionHash, - summarize, -} from "__support__/e2e/cypress"; - -const MONGO_DB_ID = 2; - -describe("issue 13097", () => { - beforeEach(() => { - restore("mongo-4"); - cy.signInAsAdmin(); - - withDatabase(MONGO_DB_ID, ({ PEOPLE_ID }) => { - const questionDetails = { - dataset_query: { - type: "query", - query: { "source-table": PEOPLE_ID, limit: 5 }, - database: MONGO_DB_ID, - }, - }; - - const hash = adhocQuestionHash(questionDetails); - - cy.visit(`/question/notebook#${hash}`); - }); - }); - - it("should correctly apply distinct count on multiple columns (metabase#13097)", () => { - summarize({ mode: "notebook" }); - - cy.findByText("Number of distinct values of ...").click(); - cy.findByText("City").click(); - - cy.findAllByTestId("notebook-cell-item") - .find(".Icon-add") - .click(); - - cy.findByText("Number of distinct values of ...").click(); - cy.findByText("State").click(); - - visualize(); - - // cy.log("Reported failing on stats ~v0.36.3"); - cy.get(".cellData") - .should("have.length", 4) - .and("contain", "Distinct values of City") - .and("contain", "1,966") - .and("contain", "Distinct values of State") - .and("contain", "49"); - }); -}); diff --git a/frontend/test/metabase/scenarios/question/reproductions/13097-mongo-apply-distinct-count-multiple-columns.js b/frontend/test/metabase/scenarios/question/reproductions/13097-mongo-apply-distinct-count-multiple-columns.js new file mode 100644 index 0000000000000000000000000000000000000000..fad2051ddfcc8640c807300fdbc609f118f49ebb --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/13097-mongo-apply-distinct-count-multiple-columns.js @@ -0,0 +1,56 @@ +import { + restore, + visualize, + withDatabase, + adhocQuestionHash, + summarize, +} from "__support__/e2e/cypress"; + +const MONGO_DB_ID = 2; + +export function issue13097() { + describe("issue 13097", () => { + beforeEach(() => { + restore("mongo-4"); + cy.signInAsAdmin(); + + withDatabase(MONGO_DB_ID, ({ PEOPLE_ID }) => { + const questionDetails = { + dataset_query: { + type: "query", + query: { "source-table": PEOPLE_ID, limit: 5 }, + database: MONGO_DB_ID, + }, + }; + + const hash = adhocQuestionHash(questionDetails); + + cy.visit(`/question/notebook#${hash}`); + }); + }); + + it("should correctly apply distinct count on multiple columns (metabase#13097)", () => { + summarize({ mode: "notebook" }); + + cy.findByText("Number of distinct values of ...").click(); + cy.findByText("City").click(); + + cy.findAllByTestId("notebook-cell-item") + .find(".Icon-add") + .click(); + + cy.findByText("Number of distinct values of ...").click(); + cy.findByText("State").click(); + + visualize(); + + // cy.log("Reported failing on stats ~v0.36.3"); + cy.get(".cellData") + .should("have.length", 4) + .and("contain", "Distinct values of City") + .and("contain", "1,966") + .and("contain", "Distinct values of State") + .and("contain", "49"); + }); + }); +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/13263-postgres-show-row-details-on-pk-click.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/13263-postgres-show-row-details-on-pk-click.cy.spec.js deleted file mode 100644 index a22a3ae3060a10e5150e5734bb7212a53e8d9344..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/13263-postgres-show-row-details-on-pk-click.cy.spec.js +++ /dev/null @@ -1,35 +0,0 @@ -import { restore } from "__support__/e2e/cypress"; - -const PG_DB_NAME = "QA Postgres12"; - -describe("postgres > user > query", () => { - beforeEach(() => { - restore("postgres-12"); - cy.signInAsAdmin(); - - cy.visit("/question/new"); - cy.findByText("Simple question").click(); - cy.findByText(PG_DB_NAME) - .should("be.visible") - .click(); - cy.findByTextEnsureVisible("Orders").click(); - }); - - it("should show row details when clicked on its entity key (metabase#13263)", () => { - // We're clicking on ID: 1 (the first order) => do not change! - // It is tightly coupled to the assertion ("37.65"), which is "Subtotal" value for that order. - cy.get(".Table-ID") - .eq(0) - .click(); - - // Wait until "doing science" spinner disappears (DOM is ready for assertions) - // TODO: if this proves to be reliable, extract it as a helper function for waiting on DOM to render - cy.findByTestId("loading-spinner").should("not.exist"); - - // Assertions - cy.log("Fails in v0.36.6"); - // This could be omitted because real test is searching for "37.65" on the page - cy.findByText("There was a problem with your question").should("not.exist"); - cy.contains("37.65"); - }); -}); diff --git a/frontend/test/metabase/scenarios/question/reproductions/13263-postgres-show-row-details-on-pk-click.js b/frontend/test/metabase/scenarios/question/reproductions/13263-postgres-show-row-details-on-pk-click.js new file mode 100644 index 0000000000000000000000000000000000000000..216964b5a56f71e9c6de2f06752de72524ad6fa7 --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/13263-postgres-show-row-details-on-pk-click.js @@ -0,0 +1,39 @@ +import { restore } from "__support__/e2e/cypress"; + +const PG_DB_NAME = "QA Postgres12"; + +export function issue13263() { + describe("postgres > user > query", () => { + beforeEach(() => { + restore("postgres-12"); + cy.signInAsAdmin(); + + cy.visit("/question/new"); + cy.findByText("Simple question").click(); + cy.findByText(PG_DB_NAME) + .should("be.visible") + .click(); + cy.findByTextEnsureVisible("Orders").click(); + }); + + it("should show row details when clicked on its entity key (metabase#13263)", () => { + // We're clicking on ID: 1 (the first order) => do not change! + // It is tightly coupled to the assertion ("37.65"), which is "Subtotal" value for that order. + cy.get(".Table-ID") + .eq(0) + .click(); + + // Wait until "doing science" spinner disappears (DOM is ready for assertions) + // TODO: if this proves to be reliable, extract it as a helper function for waiting on DOM to render + cy.findByTestId("loading-spinner").should("not.exist"); + + // Assertions + cy.log("Fails in v0.36.6"); + // This could be omitted because real test is searching for "37.65" on the page + cy.findByText("There was a problem with your question").should( + "not.exist", + ); + cy.contains("37.65"); + }); + }); +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/14957-unable-to-save-question-before-query-executed.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/14957-unable-to-save-question-before-query-executed.cy.spec.js deleted file mode 100644 index caa4985d03825152f426ee7e7cce660a62e92969..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/14957-unable-to-save-question-before-query-executed.cy.spec.js +++ /dev/null @@ -1,27 +0,0 @@ -import { restore, modal } from "__support__/e2e/cypress"; - -const PG_DB_NAME = "QA Postgres12"; - -describe.skip("issue 14957", () => { - beforeEach(() => { - restore("postgres-12"); - cy.signInAsAdmin(); - - cy.visit("/question/new"); - cy.findByText("Native query").click(); - cy.findByText(PG_DB_NAME) - .should("be.visible") - .click(); - }); - - it("should save a question before query has been executed (metabase#14957)", () => { - cy.get(".ace_content").type("select pg_sleep(60)"); - - cy.findByText("Save").click(); - - cy.findByLabelText("Name").type("14957"); - cy.button("Save").click(); - - modal().should("not.exist"); - }); -}); diff --git a/frontend/test/metabase/scenarios/question/reproductions/14957-unable-to-save-question-before-query-executed.js b/frontend/test/metabase/scenarios/question/reproductions/14957-unable-to-save-question-before-query-executed.js new file mode 100644 index 0000000000000000000000000000000000000000..e80cebb96bbe00d7441805cb0c4bc88a23d5e2eb --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/14957-unable-to-save-question-before-query-executed.js @@ -0,0 +1,29 @@ +import { restore, modal } from "__support__/e2e/cypress"; + +const PG_DB_NAME = "QA Postgres12"; + +export function issue14957() { + describe.skip("issue 14957", () => { + beforeEach(() => { + restore("postgres-12"); + cy.signInAsAdmin(); + + cy.visit("/question/new"); + cy.findByText("Native query").click(); + cy.findByText(PG_DB_NAME) + .should("be.visible") + .click(); + }); + + it("should save a question before query has been executed (metabase#14957)", () => { + cy.get(".ace_content").type("select pg_sleep(60)"); + + cy.findByText("Save").click(); + + cy.findByLabelText("Name").type("14957"); + cy.button("Save").click(); + + modal().should("not.exist"); + }); + }); +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/15714-cc-postgres-percentile-accepts-two-params.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/15714-cc-postgres-percentile-accepts-two-params.cy.spec.js deleted file mode 100644 index 13c85520aa3995c81be4cd385078bdc2b1b98093..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/15714-cc-postgres-percentile-accepts-two-params.cy.spec.js +++ /dev/null @@ -1,33 +0,0 @@ -import { enterCustomColumnDetails, restore } from "__support__/e2e/cypress"; - -const PG_DB_NAME = "QA Postgres12"; - -describe("postgres > question > custom columns", () => { - beforeEach(() => { - restore("postgres-12"); - cy.signInAsAdmin(); - - cy.visit("/question/new"); - cy.findByText("Custom question").click(); - cy.findByText(PG_DB_NAME) - .should("be.visible") - .click(); - cy.findByTextEnsureVisible("Orders").click(); - }); - - it("`Percentile` custom expression function should accept two parameters (metabase#15714)", () => { - cy.findByText("Pick the metric you want to see").click(); - cy.findByText("Custom Expression").click(); - enterCustomColumnDetails({ formula: "Percentile([Subtotal], 0.1)" }); - cy.findByPlaceholderText("Name (required)") - .as("description") - .click(); - - cy.findByText("Function Percentile expects 1 argument").should("not.exist"); - cy.get("@description").type("A"); - cy.button("Done") - .should("not.be.disabled") - .click(); - // Todo: Add positive assertions once this is fixed - }); -}); diff --git a/frontend/test/metabase/scenarios/question/reproductions/15714-cc-postgres-percentile-accepts-two-params.js b/frontend/test/metabase/scenarios/question/reproductions/15714-cc-postgres-percentile-accepts-two-params.js new file mode 100644 index 0000000000000000000000000000000000000000..06217c2ba29ebac955056585463c8730766e395b --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/15714-cc-postgres-percentile-accepts-two-params.js @@ -0,0 +1,37 @@ +import { enterCustomColumnDetails, restore } from "__support__/e2e/cypress"; + +const PG_DB_NAME = "QA Postgres12"; + +export function issue15714() { + describe("postgres > question > custom columns", () => { + beforeEach(() => { + restore("postgres-12"); + cy.signInAsAdmin(); + + cy.visit("/question/new"); + cy.findByText("Custom question").click(); + cy.findByText(PG_DB_NAME) + .should("be.visible") + .click(); + cy.findByTextEnsureVisible("Orders").click(); + }); + + it("`Percentile` custom expression function should accept two parameters (metabase#15714)", () => { + cy.findByText("Pick the metric you want to see").click(); + cy.findByText("Custom Expression").click(); + enterCustomColumnDetails({ formula: "Percentile([Subtotal], 0.1)" }); + cy.findByPlaceholderText("Name (required)") + .as("description") + .click(); + + cy.findByText("Function Percentile expects 1 argument").should( + "not.exist", + ); + cy.get("@description").type("A"); + cy.button("Done") + .should("not.be.disabled") + .click(); + // Todo: Add positive assertions once this is fixed + }); + }); +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/15876-postgres-cast-time.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/15876-postgres-cast-time.js similarity index 73% rename from frontend/test/metabase/scenarios/question/reproductions/15876-postgres-cast-time.cy.spec.js rename to frontend/test/metabase/scenarios/question/reproductions/15876-postgres-cast-time.js index 77df532a3ff9cfb33ab910696be3a00f1f87b916..8ee07785924355406fb9bc3b10bd012a79e216af 100644 --- a/frontend/test/metabase/scenarios/question/reproductions/15876-postgres-cast-time.cy.spec.js +++ b/frontend/test/metabase/scenarios/question/reproductions/15876-postgres-cast-time.js @@ -41,21 +41,23 @@ const correctValues = [ }, ]; -describe("issue 15876", () => { - beforeEach(() => { - restore("postgres-12"); - cy.signInAsAdmin(); - }); +export function issue15876() { + describe("issue 15876", () => { + beforeEach(() => { + restore("postgres-12"); + cy.signInAsAdmin(); + }); - it("should correctly cast to `TIME` (metabase#15876)", () => { - cy.createNativeQuestion(questionDetails, { visitQuestion: true }); + it("should correctly cast to `TIME` (metabase#15876)", () => { + cy.createNativeQuestion(questionDetails, { visitQuestion: true }); - cy.get(".Visualization").within(() => { - correctValues.forEach(({ value, rows }) => { - const count = rows * castColumns; + cy.get(".Visualization").within(() => { + correctValues.forEach(({ value, rows }) => { + const count = rows * castColumns; - cy.findAllByText(value).should("have.length", count); + cy.findAllByText(value).should("have.length", count); + }); }); }); }); -}); +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/16621-create-multiple-filters-with-same-value.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/16621-create-multiple-filters-with-same-value.cy.spec.js deleted file mode 100644 index a4060086b6bf3a632e4d8030ee70af5bdba3e1bf..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/16621-create-multiple-filters-with-same-value.cy.spec.js +++ /dev/null @@ -1,21 +0,0 @@ -import { restore, openProductsTable } from "__support__/e2e/cypress"; - -describe("issue 16661", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - openProductsTable({ limit: 3 }); - }); - - it("should be possible to create multiple filter that start with the same value (metabase#16621)", () => { - cy.findByText("Category").click(); - cy.findByText("Filter by this column").click(); - cy.findByPlaceholderText("Search the list").type("Doo{enter}"); - cy.findByTestId("Doo-filter-value").click(); - cy.button("Update filter").click(); - cy.findByText("Category is Doo").click(); - cy.findByTestId("Doohickey-filter-value").click(); - cy.button("Update filter").click(); - cy.findByText("Category is 2 selections"); - }); -}); diff --git a/frontend/test/metabase/scenarios/question/reproductions/16621-create-multiple-filters-with-same-value.js b/frontend/test/metabase/scenarios/question/reproductions/16621-create-multiple-filters-with-same-value.js new file mode 100644 index 0000000000000000000000000000000000000000..95e2e5664086625d1c503294f972c0604ea714f1 --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/16621-create-multiple-filters-with-same-value.js @@ -0,0 +1,23 @@ +import { restore, openProductsTable } from "__support__/e2e/cypress"; + +export function issue16621() { + describe("issue 16661", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + openProductsTable({ limit: 3 }); + }); + + it("should be possible to create multiple filter that start with the same value (metabase#16621)", () => { + cy.findByText("Category").click(); + cy.findByText("Filter by this column").click(); + cy.findByPlaceholderText("Search the list").type("Doo{enter}"); + cy.findByTestId("Doo-filter-value").click(); + cy.button("Update filter").click(); + cy.findByText("Category is Doo").click(); + cy.findByTestId("Doohickey-filter-value").click(); + cy.button("Update filter").click(); + cy.findByText("Category is 2 selections"); + }); + }); +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/17512.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/17512.cy.spec.js deleted file mode 100644 index 6728eba85061c637e0a58c5d78386181a460679d..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/17512.cy.spec.js +++ /dev/null @@ -1,63 +0,0 @@ -import { - restore, - openOrdersTable, - popover, - visualize, - summarize, -} from "__support__/e2e/cypress"; - -describe("issue 17512", () => { - beforeEach(() => { - cy.intercept("POST", "/api/dataset").as("dataset"); - - restore(); - cy.signInAsAdmin(); - }); - - it("custom expression should work with `case` in nested queries (metabase#17512)", () => { - openOrdersTable({ mode: "notebook" }); - - addSummarizeCustomExpression( - "Distinct(case([Discount] > 0, [Subtotal], [Total]))", - "CE", - ); - - cy.findByText("Pick a column to group by").click(); - cy.findByText("Created At").click(); - - addCustomColumn("1 + 1", "CC"); - - visualize(({ body }) => { - expect(body.error).to.not.exist; - }); - - cy.findByText("CE"); - cy.findByText("CC"); - }); -}); - -function addSummarizeCustomExpression(formula, name) { - summarize({ mode: "notebook" }); - popover() - .contains("Custom Expression") - .click(); - - popover().within(() => { - cy.get(".ace_text-input") - .type(formula) - .blur(); - cy.findByPlaceholderText("Name (required)").type(name); - cy.button("Done").click(); - }); -} - -function addCustomColumn(formula, name) { - cy.findByText("Custom column").click(); - popover().within(() => { - cy.get(".ace_text-input") - .type(formula) - .blur(); - cy.findByPlaceholderText("Something nice and descriptive").type(name); - cy.button("Done").click(); - }); -} diff --git a/frontend/test/metabase/scenarios/question/reproductions/17512.js b/frontend/test/metabase/scenarios/question/reproductions/17512.js new file mode 100644 index 0000000000000000000000000000000000000000..a77aa859ae250c03f96dee2e0ffc7d160a1dc461 --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/17512.js @@ -0,0 +1,65 @@ +import { + restore, + openOrdersTable, + popover, + visualize, + summarize, +} from "__support__/e2e/cypress"; + +export function issue17512() { + describe("issue 17512", () => { + beforeEach(() => { + cy.intercept("POST", "/api/dataset").as("dataset"); + + restore(); + cy.signInAsAdmin(); + }); + + it("custom expression should work with `case` in nested queries (metabase#17512)", () => { + openOrdersTable({ mode: "notebook" }); + + addSummarizeCustomExpression( + "Distinct(case([Discount] > 0, [Subtotal], [Total]))", + "CE", + ); + + cy.findByText("Pick a column to group by").click(); + cy.findByText("Created At").click(); + + addCustomColumn("1 + 1", "CC"); + + visualize(({ body }) => { + expect(body.error).to.not.exist; + }); + + cy.findByText("CE"); + cy.findByText("CC"); + }); + }); + + function addSummarizeCustomExpression(formula, name) { + summarize({ mode: "notebook" }); + popover() + .contains("Custom Expression") + .click(); + + popover().within(() => { + cy.get(".ace_text-input") + .type(formula) + .blur(); + cy.findByPlaceholderText("Name (required)").type(name); + cy.button("Done").click(); + }); + } + + function addCustomColumn(formula, name) { + cy.findByText("Custom column").click(); + popover().within(() => { + cy.get(".ace_text-input") + .type(formula) + .blur(); + cy.findByPlaceholderText("Something nice and descriptive").type(name); + cy.button("Done").click(); + }); + } +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/17514-ui-overlay.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/17514-ui-overlay.cy.spec.js deleted file mode 100644 index 7d7625d560f7a85210e7041a1ff9aa83071c3e8e..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/17514-ui-overlay.cy.spec.js +++ /dev/null @@ -1,193 +0,0 @@ -import { - restore, - showDashboardCardActions, - filterWidget, - saveDashboard, - editDashboard, - visualize, - visitDashboard, -} from "__support__/e2e/cypress"; - -import { setAdHocFilter } from "../../native-filters/helpers/e2e-date-filter-helpers"; - -import { SAMPLE_DATABASE } from "__support__/e2e/cypress_sample_database"; - -const { ORDERS, ORDERS_ID, PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE; - -const questionDetails = { - name: "17514", - query: { - "source-table": ORDERS_ID, - joins: [ - { - fields: "all", - "source-table": PRODUCTS_ID, - condition: [ - "=", - ["field", ORDERS.PRODUCT_ID, null], - ["field", PRODUCTS.ID, { "join-alias": "Products" }], - ], - alias: "Products", - }, - ], - }, -}; - -const filter = { - name: "Date Filter", - slug: "date_filter", - id: "23ccbbf", - type: "date/all-options", - sectionId: "date", -}; - -const dashboardDetails = { parameters: [filter] }; - -describe("issue 17514", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - cy.intercept("POST", "/api/dataset").as("dataset"); - }); - - describe("scenario 1", () => { - beforeEach(() => { - cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( - ({ body: card }) => { - const { card_id, dashboard_id } = card; - - cy.intercept( - "POST", - `/api/dashboard/${dashboard_id}/dashcard/*/card/${card_id}/query`, - ).as("cardQuery"); - - const mapFilterToCard = { - parameter_mappings: [ - { - parameter_id: filter.id, - card_id, - target: ["dimension", ["field", ORDERS.CREATED_AT, null]], - }, - ], - }; - - cy.editDashboardCard(card, mapFilterToCard); - - visitDashboard(dashboard_id); - - cy.wait("@cardQuery"); - cy.findByText("110.93").should("be.visible"); - }, - ); - }); - - it("should not show the run overlay when we apply dashboard filter on a question with removed column and then click through its title (metabase#17514-1)", () => { - editDashboard(); - - openVisualizationOptions(); - - hideColumn("Products → Ean"); - - closeModal(); - - saveDashboard(); - cy.wait("@getDashboard"); - - filterWidget().click(); - setAdHocFilter({ timeBucket: "Years" }); - - cy.location("search").should("eq", "?date_filter=past30years"); - cy.wait("@cardQuery"); - - cy.findByText("Previous 30 Years"); - - cy.findByText("17514").click(); - cy.wait("@dataset"); - cy.findByTextEnsureVisible("Subtotal"); - - // Cypress cannot click elements that are blocked by an overlay so this will immediately fail if the issue is not fixed - cy.findByText("110.93").click(); - cy.findByText("Filter by this value"); - }); - }); - - describe("scenario 2", () => { - beforeEach(() => { - cy.createQuestion(questionDetails, { visitQuestion: true }); - - cy.findByTestId("viz-settings-button").click(); - - moveColumnToTop("Subtotal"); - - openNotebookMode(); - - removeJoinedTable(); - - visualize(); - cy.findByTextEnsureVisible("Subtotal"); - - cy.findByText("Save").click(); - - cy.get(".Modal").within(() => { - cy.button("Save").click(); - }); - }); - - it("should not show the run overlay because of the references to the orphaned fields (metabase#17514-2)", () => { - openNotebookMode(); - - cy.findByText("Join data").click(); - cy.findByText("Products").click(); - - visualize(); - cy.findByTextEnsureVisible("Subtotal"); - - // Cypress cannot click elements that are blocked by an overlay so this will immediately fail if the issue is not fixed - cy.findByText("110.93").click(); - cy.findByText("Filter by this value"); - }); - }); -}); - -function openVisualizationOptions() { - showDashboardCardActions(); - cy.icon("palette").click({ force: true }); -} - -function hideColumn(columnName) { - cy.findByTestId("chartsettings-sidebar").within(() => { - cy.findByText(columnName) - .siblings(".Icon-close") - .click(); - }); -} - -function closeModal() { - cy.get(".Modal").within(() => { - cy.button("Done").click(); - }); -} - -function openNotebookMode() { - cy.icon("notebook").click(); -} - -function removeJoinedTable() { - cy.findAllByText("Join data") - .first() - .parent() - .findByTestId("remove-step") - .click({ force: true }); -} - -function moveColumnToTop(column) { - cy.findByTestId("sidebar-left").within(() => { - cy.findByText(column) - .should("be.visible") - .closest(".cursor-grab") - .trigger("mousedown", 0, 0, { force: true }) - .trigger("mousemove", 5, 5, { force: true }) - .trigger("mousemove", 0, -600, { force: true }) - .trigger("mouseup", 0, -600, { force: true }); - }); -} diff --git a/frontend/test/metabase/scenarios/question/reproductions/17514-ui-overlay.js b/frontend/test/metabase/scenarios/question/reproductions/17514-ui-overlay.js new file mode 100644 index 0000000000000000000000000000000000000000..34bb10e1015a5bce09bc093a46852c50f3f1c00f --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/17514-ui-overlay.js @@ -0,0 +1,196 @@ +import { + restore, + showDashboardCardActions, + filterWidget, + saveDashboard, + editDashboard, + visualize, + visitDashboard, +} from "__support__/e2e/cypress"; + +import { setAdHocFilter } from "../../native-filters/helpers/e2e-date-filter-helpers"; + +import { SAMPLE_DATABASE } from "__support__/e2e/cypress_sample_database"; + +const { ORDERS, ORDERS_ID, PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE; + +const questionDetails = { + name: "17514", + query: { + "source-table": ORDERS_ID, + joins: [ + { + fields: "all", + "source-table": PRODUCTS_ID, + condition: [ + "=", + ["field", ORDERS.PRODUCT_ID, null], + ["field", PRODUCTS.ID, { "join-alias": "Products" }], + ], + alias: "Products", + }, + ], + }, +}; + +const filter = { + name: "Date Filter", + slug: "date_filter", + id: "23ccbbf", + type: "date/all-options", + sectionId: "date", +}; + +const dashboardDetails = { parameters: [filter] }; + +export function issue17514() { + describe("issue 17514", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + cy.intercept("POST", "/api/dataset").as("dataset"); + }); + + describe("scenario 1", () => { + beforeEach(() => { + cy.createQuestionAndDashboard({ + questionDetails, + dashboardDetails, + }).then(({ body: card }) => { + const { card_id, dashboard_id } = card; + + cy.intercept( + "POST", + `/api/dashboard/${dashboard_id}/dashcard/*/card/${card_id}/query`, + ).as("cardQuery"); + + const mapFilterToCard = { + parameter_mappings: [ + { + parameter_id: filter.id, + card_id, + target: ["dimension", ["field", ORDERS.CREATED_AT, null]], + }, + ], + }; + + cy.editDashboardCard(card, mapFilterToCard); + + visitDashboard(dashboard_id); + + cy.wait("@cardQuery"); + cy.findByText("110.93").should("be.visible"); + }); + }); + + it("should not show the run overlay when we apply dashboard filter on a question with removed column and then click through its title (metabase#17514-1)", () => { + editDashboard(); + + openVisualizationOptions(); + + hideColumn("Products → Ean"); + + closeModal(); + + saveDashboard(); + cy.wait("@getDashboard"); + + filterWidget().click(); + setAdHocFilter({ timeBucket: "Years" }); + + cy.location("search").should("eq", "?date_filter=past30years"); + cy.wait("@cardQuery"); + + cy.findByText("Previous 30 Years"); + + cy.findByText("17514").click(); + cy.wait("@dataset"); + cy.findByTextEnsureVisible("Subtotal"); + + // Cypress cannot click elements that are blocked by an overlay so this will immediately fail if the issue is not fixed + cy.findByText("110.93").click(); + cy.findByText("Filter by this value"); + }); + }); + + describe("scenario 2", () => { + beforeEach(() => { + cy.createQuestion(questionDetails, { visitQuestion: true }); + + cy.findByTestId("viz-settings-button").click(); + + moveColumnToTop("Subtotal"); + + openNotebookMode(); + + removeJoinedTable(); + + visualize(); + cy.findByTextEnsureVisible("Subtotal"); + + cy.findByText("Save").click(); + + cy.get(".Modal").within(() => { + cy.button("Save").click(); + }); + }); + + it("should not show the run overlay because of the references to the orphaned fields (metabase#17514-2)", () => { + openNotebookMode(); + + cy.findByText("Join data").click(); + cy.findByText("Products").click(); + + visualize(); + cy.findByTextEnsureVisible("Subtotal"); + + // Cypress cannot click elements that are blocked by an overlay so this will immediately fail if the issue is not fixed + cy.findByText("110.93").click(); + cy.findByText("Filter by this value"); + }); + }); + }); + + function openVisualizationOptions() { + showDashboardCardActions(); + cy.icon("palette").click({ force: true }); + } + + function hideColumn(columnName) { + cy.findByTestId("chartsettings-sidebar").within(() => { + cy.findByText(columnName) + .siblings(".Icon-close") + .click(); + }); + } + + function closeModal() { + cy.get(".Modal").within(() => { + cy.button("Done").click(); + }); + } + + function openNotebookMode() { + cy.icon("notebook").click(); + } + + function removeJoinedTable() { + cy.findAllByText("Join data") + .first() + .parent() + .findByTestId("remove-step") + .click({ force: true }); + } + + function moveColumnToTop(column) { + cy.findByTestId("sidebar-left").within(() => { + cy.findByText(column) + .should("be.visible") + .closest(".cursor-grab") + .trigger("mousedown", 0, 0, { force: true }) + .trigger("mousemove", 5, 5, { force: true }) + .trigger("mousemove", 0, -600, { force: true }) + .trigger("mouseup", 0, -600, { force: true }); + }); + } +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/17963-mongo-filter-expression-compare-two-fields.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/17963-mongo-filter-expression-compare-two-fields.cy.spec.js deleted file mode 100644 index 2955a392392a16328abe5ba77c10064cd9ff69ce..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/17963-mongo-filter-expression-compare-two-fields.cy.spec.js +++ /dev/null @@ -1,47 +0,0 @@ -import { restore, popover, visualize } from "__support__/e2e/cypress"; - -describe("issue 17963", () => { - beforeEach(() => { - restore("mongo-4"); - cy.signInAsAdmin(); - - cy.visit("/question/new"); - cy.findByText("Custom question").click(); - cy.findByText("QA Mongo4").click(); - cy.findByText("Orders").click(); - }); - - it("should be able to compare two fields using filter expression (metabase#17963)", () => { - cy.findByText("Add filters to narrow your answer").click(); - - popover() - .contains("Custom Expression") - .click(); - - typeAndSelect([ - { string: "dis", field: "Discount" }, - { string: "> qu", field: "Quantity" }, - ]); - - cy.button("Done").click(); - - cy.findByText("Discount > Quantity"); - - cy.findByText("Pick the metric you want to see").click(); - cy.findByText("Count of rows").click(); - - visualize(); - - cy.get(".ScalarValue").contains("1,337"); - }); -}); - -function typeAndSelect(arr) { - arr.forEach(({ string, field }) => { - cy.get(".ace_text-input").type(string); - - popover() - .contains(field) - .click(); - }); -} diff --git a/frontend/test/metabase/scenarios/question/reproductions/17963-mongo-filter-expression-compare-two-fields.js b/frontend/test/metabase/scenarios/question/reproductions/17963-mongo-filter-expression-compare-two-fields.js new file mode 100644 index 0000000000000000000000000000000000000000..90fe67be9562674ad1cbad1e4724542e292f533d --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/17963-mongo-filter-expression-compare-two-fields.js @@ -0,0 +1,49 @@ +import { restore, popover, visualize } from "__support__/e2e/cypress"; + +export function issue17963() { + describe("issue 17963", () => { + beforeEach(() => { + restore("mongo-4"); + cy.signInAsAdmin(); + + cy.visit("/question/new"); + cy.findByText("Custom question").click(); + cy.findByText("QA Mongo4").click(); + cy.findByText("Orders").click(); + }); + + it("should be able to compare two fields using filter expression (metabase#17963)", () => { + cy.findByText("Add filters to narrow your answer").click(); + + popover() + .contains("Custom Expression") + .click(); + + typeAndSelect([ + { string: "dis", field: "Discount" }, + { string: "> qu", field: "Quantity" }, + ]); + + cy.button("Done").click(); + + cy.findByText("Discount > Quantity"); + + cy.findByText("Pick the metric you want to see").click(); + cy.findByText("Count of rows").click(); + + visualize(); + + cy.get(".ScalarValue").contains("1,337"); + }); + }); + + function typeAndSelect(arr) { + arr.forEach(({ string, field }) => { + cy.get(".ace_text-input").type(string); + + popover() + .contains(field) + .click(); + }); + } +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/18207-string-min-max.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/18207-string-min-max.cy.spec.js deleted file mode 100644 index a056799442c8dbf2835c60381c7fae6bcd68cb1f..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/18207-string-min-max.cy.spec.js +++ /dev/null @@ -1,97 +0,0 @@ -import { - enterCustomColumnDetails, - popover, - restore, - visualize, -} from "__support__/e2e/cypress"; - -describe("issue 18207", () => { - beforeEach(() => { - cy.intercept("POST", "/api/dataset").as("dataset"); - - restore(); - cy.signInAsAdmin(); - }); - - it("should be possible to use MIN on a string column (metabase#18207)", () => { - cy.visit("/question/new"); - cy.contains("Custom question").click(); - cy.contains("Sample Database").click(); - cy.contains("Products").click(); - - cy.contains("Pick the metric").click(); - - cy.contains("Minimum of").click(); - cy.findByText("Price"); - cy.findByText("Rating"); - cy.contains("Category").click(); - - visualize(); - - cy.findByText("Doohickey"); - }); - - it("should be possible to use MAX on a string column (metabase#18207)", () => { - cy.visit("/question/new"); - cy.contains("Custom question").click(); - cy.contains("Sample Database").click(); - cy.contains("Products").click(); - - cy.contains("Pick the metric").click(); - - cy.contains("Maximum of").click(); - cy.findByText("Price"); - cy.findByText("Rating"); - cy.contains("Category").click(); - - visualize(); - - cy.findByText("Widget"); - }); - - it("should be not possible to use AVERAGE on a string column (metabase#18207)", () => { - cy.visit("/question/new"); - cy.contains("Custom question").click(); - cy.contains("Sample Database").click(); - cy.contains("Products").click(); - - cy.contains("Pick the metric").click(); - - cy.contains("Average of").click(); - cy.findByText("Price"); - cy.findByText("Rating"); - cy.findByText("Category").should("not.exist"); - }); - - it("should be possible to group by a string expression (metabase#18207)", () => { - cy.visit("/question/new"); - cy.contains("Custom question").click(); - cy.contains("Sample Database").click(); - cy.contains("Products").click(); - - cy.contains("Pick the metric").click(); - popover() - .contains("Custom Expression") - .click(); - popover().within(() => { - enterCustomColumnDetails({ formula: "Max([Vendor])" }); - cy.findByPlaceholderText("Name (required)").type("LastVendor"); - cy.findByText("Done").click(); - }); - - cy.contains("Pick a column to group by").click(); - popover() - .contains("Category") - .click(); - - visualize(); - - // Why is it not a table? - cy.contains("Settings").click(); - cy.contains("Bar options").click(); - cy.get("[data-testid=Table-button]").click(); - cy.contains("Done").click(); - - cy.findByText("Zemlak-Wiegand"); - }); -}); diff --git a/frontend/test/metabase/scenarios/question/reproductions/18207-string-min-max.js b/frontend/test/metabase/scenarios/question/reproductions/18207-string-min-max.js new file mode 100644 index 0000000000000000000000000000000000000000..5760630808e153f625f7c6301d140e5e1433ab9a --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/18207-string-min-max.js @@ -0,0 +1,99 @@ +import { + enterCustomColumnDetails, + popover, + restore, + visualize, +} from "__support__/e2e/cypress"; + +export function issue18207() { + describe("issue 18207", () => { + beforeEach(() => { + cy.intercept("POST", "/api/dataset").as("dataset"); + + restore(); + cy.signInAsAdmin(); + }); + + it("should be possible to use MIN on a string column (metabase#18207)", () => { + cy.visit("/question/new"); + cy.contains("Custom question").click(); + cy.contains("Sample Database").click(); + cy.contains("Products").click(); + + cy.contains("Pick the metric").click(); + + cy.contains("Minimum of").click(); + cy.findByText("Price"); + cy.findByText("Rating"); + cy.contains("Category").click(); + + visualize(); + + cy.findByText("Doohickey"); + }); + + it("should be possible to use MAX on a string column (metabase#18207)", () => { + cy.visit("/question/new"); + cy.contains("Custom question").click(); + cy.contains("Sample Database").click(); + cy.contains("Products").click(); + + cy.contains("Pick the metric").click(); + + cy.contains("Maximum of").click(); + cy.findByText("Price"); + cy.findByText("Rating"); + cy.contains("Category").click(); + + visualize(); + + cy.findByText("Widget"); + }); + + it("should be not possible to use AVERAGE on a string column (metabase#18207)", () => { + cy.visit("/question/new"); + cy.contains("Custom question").click(); + cy.contains("Sample Database").click(); + cy.contains("Products").click(); + + cy.contains("Pick the metric").click(); + + cy.contains("Average of").click(); + cy.findByText("Price"); + cy.findByText("Rating"); + cy.findByText("Category").should("not.exist"); + }); + + it("should be possible to group by a string expression (metabase#18207)", () => { + cy.visit("/question/new"); + cy.contains("Custom question").click(); + cy.contains("Sample Database").click(); + cy.contains("Products").click(); + + cy.contains("Pick the metric").click(); + popover() + .contains("Custom Expression") + .click(); + popover().within(() => { + enterCustomColumnDetails({ formula: "Max([Vendor])" }); + cy.findByPlaceholderText("Name (required)").type("LastVendor"); + cy.findByText("Done").click(); + }); + + cy.contains("Pick a column to group by").click(); + popover() + .contains("Category") + .click(); + + visualize(); + + // Why is it not a table? + cy.contains("Settings").click(); + cy.contains("Bar options").click(); + cy.get("[data-testid=Table-button]").click(); + cy.contains("Done").click(); + + cy.findByText("Zemlak-Wiegand"); + }); + }); +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.cy.spec.js deleted file mode 100644 index e9c7ce1dad92a38a875cb49d72d5763092edd067..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.cy.spec.js +++ /dev/null @@ -1,42 +0,0 @@ -import { - restore, - popover, - openNavigationSidebar, - visitQuestion, -} from "__support__/e2e/cypress"; - -describe("18978, 18977", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should not display query editing controls and 'Browse Data' link", () => { - cy.createQuestion({ - query: { - "source-table": "card__1", - }, - }).then(({ body: { id } }) => { - cy.signIn("nodata"); - visitQuestion(id); - openNavigationSidebar(); - - cy.findByText(/Browse data/i).should("not.exist"); - cy.icon("add").click(); - - popover().within(() => { - cy.findByText("Question").should("not.exist"); - cy.findByText(/SQL query/).should("not.exist"); - cy.findByText(/Native query/).should("not.exist"); - }); - - cy.findByTestId("qb-header-action-panel").within(() => { - cy.icon("notebook").should("not.exist"); - cy.findByText("Filter").should("not.exist"); - cy.findByText("Summarize").should("not.exist"); - }); - cy.findByTestId("viz-type-button").should("not.exist"); - cy.findByTestId("viz-settings-button").should("not.exist"); - }); - }); -}); diff --git a/frontend/test/metabase/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.js b/frontend/test/metabase/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.js new file mode 100644 index 0000000000000000000000000000000000000000..d888b718a3082a340f5824d850f35bd06c55d087 --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/18978-18977-nested-question-nodata-user.js @@ -0,0 +1,44 @@ +import { + restore, + popover, + openNavigationSidebar, + visitQuestion, +} from "__support__/e2e/cypress"; + +export function issue18978() { + describe("18978, 18977", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should not display query editing controls and 'Browse Data' link", () => { + cy.createQuestion({ + query: { + "source-table": "card__1", + }, + }).then(({ body: { id } }) => { + cy.signIn("nodata"); + visitQuestion(id); + openNavigationSidebar(); + + cy.findByText(/Browse data/i).should("not.exist"); + cy.icon("add").click(); + + popover().within(() => { + cy.findByText("Question").should("not.exist"); + cy.findByText(/SQL query/).should("not.exist"); + cy.findByText(/Native query/).should("not.exist"); + }); + + cy.findByTestId("qb-header-action-panel").within(() => { + cy.icon("notebook").should("not.exist"); + cy.findByText("Filter").should("not.exist"); + cy.findByText("Summarize").should("not.exist"); + }); + cy.findByTestId("viz-type-button").should("not.exist"); + cy.findByTestId("viz-settings-button").should("not.exist"); + }); + }); + }); +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/19341-disabled-nested-queries.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/19341-disabled-nested-queries.cy.spec.js deleted file mode 100644 index e2f254dc636d94654b32034f68071010ffb0151b..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/19341-disabled-nested-queries.cy.spec.js +++ /dev/null @@ -1,57 +0,0 @@ -import { restore, mockSessionProperty, popover } from "__support__/e2e/cypress"; - -describe("issue 19341", () => { - const TEST_NATIVE_QUESTION_NAME = "Native"; - - beforeEach(() => { - restore(); - mockSessionProperty("enable-nested-queries", false); - cy.signInAsAdmin(); - cy.createNativeQuestion({ - name: TEST_NATIVE_QUESTION_NAME, - native: { - query: "SELECT * FROM products", - }, - }); - cy.intercept("POST", "/api/card/*/query").as("cardQuery"); - }); - - it("should correctly disable nested queries (metabase#19341)", () => { - // Test "Saved Questions" table is hidden in QB data selector - cy.visit("/question/new"); - cy.findByText("Custom question").click(); - popover().within(() => { - // Wait until picker init - // When working as expected, the test environment only has "Sample Database" DB - // So it should automatically select it as a database - // When "Orders" table name appears, it means the picker has selected the sample database - cy.findByText("Loading...").should("not.exist"); - cy.findByText("Orders"); - - cy.findByText("Sample Database").click(); // go back to DB list - cy.findByText("Saved Questions").should("not.exist"); - - // Ensure the search doesn't list saved questions - cy.findByPlaceholderText("Search for a table…").type("Ord"); - cy.findByText("Loading...").should("not.exist"); - cy.findAllByText(/Saved question in/i).should("not.exist"); - cy.findAllByText(/Table in/i).should("exist"); - cy.icon("close").click(); - - cy.findByText("Sample Database").click(); - cy.findByText("Orders").click(); - }); - - cy.icon("join_left_outer").click(); - popover().within(() => { - cy.findByText("Sample Database").click(); // go back to DB list - cy.findByText("Saved Questions").should("not.exist"); - }); - - // Test "Explore results" button is hidden for native questions - cy.visit("/collection/root"); - cy.findByText(TEST_NATIVE_QUESTION_NAME).click(); - cy.wait("@cardQuery"); - cy.findByText("Explore results").should("not.exist"); - }); -}); diff --git a/frontend/test/metabase/scenarios/question/reproductions/19341-disabled-nested-queries.js b/frontend/test/metabase/scenarios/question/reproductions/19341-disabled-nested-queries.js new file mode 100644 index 0000000000000000000000000000000000000000..7583c4226a54c243e29c1441a0f083430c2daaad --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/19341-disabled-nested-queries.js @@ -0,0 +1,59 @@ +import { restore, mockSessionProperty, popover } from "__support__/e2e/cypress"; + +export function issue19341() { + describe("issue 19341", () => { + const TEST_NATIVE_QUESTION_NAME = "Native"; + + beforeEach(() => { + restore(); + mockSessionProperty("enable-nested-queries", false); + cy.signInAsAdmin(); + cy.createNativeQuestion({ + name: TEST_NATIVE_QUESTION_NAME, + native: { + query: "SELECT * FROM products", + }, + }); + cy.intercept("POST", "/api/card/*/query").as("cardQuery"); + }); + + it("should correctly disable nested queries (metabase#19341)", () => { + // Test "Saved Questions" table is hidden in QB data selector + cy.visit("/question/new"); + cy.findByText("Custom question").click(); + popover().within(() => { + // Wait until picker init + // When working as expected, the test environment only has "Sample Database" DB + // So it should automatically select it as a database + // When "Orders" table name appears, it means the picker has selected the sample database + cy.findByText("Loading...").should("not.exist"); + cy.findByText("Orders"); + + cy.findByText("Sample Database").click(); // go back to DB list + cy.findByText("Saved Questions").should("not.exist"); + + // Ensure the search doesn't list saved questions + cy.findByPlaceholderText("Search for a table…").type("Ord"); + cy.findByText("Loading...").should("not.exist"); + cy.findAllByText(/Saved question in/i).should("not.exist"); + cy.findAllByText(/Table in/i).should("exist"); + cy.icon("close").click(); + + cy.findByText("Sample Database").click(); + cy.findByText("Orders").click(); + }); + + cy.icon("join_left_outer").click(); + popover().within(() => { + cy.findByText("Sample Database").click(); // go back to DB list + cy.findByText("Saved Questions").should("not.exist"); + }); + + // Test "Explore results" button is hidden for native questions + cy.visit("/collection/root"); + cy.findByText(TEST_NATIVE_QUESTION_NAME).click(); + cy.wait("@cardQuery"); + cy.findByText("Explore results").should("not.exist"); + }); + }); +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/19742-data-picker-closes-after-hiding-table.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/19742-data-picker-closes-after-hiding-table.cy.spec.js deleted file mode 100644 index e418ebcaf5c6d7acc1ece668fca777cca695a894..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/19742-data-picker-closes-after-hiding-table.cy.spec.js +++ /dev/null @@ -1,52 +0,0 @@ -import { - restore, - popover, - openNavigationSidebar, -} from "__support__/e2e/cypress"; - -describe("issue 19742", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - // In order to reproduce the issue, it's important to only use in-app links - // and don't refresh the app state (like by doing cy.visit) - it("shouldn't auto-close the data selector after a table was hidden", () => { - cy.visit("/"); - cy.findByText("New").click(); - selectFromDropdown("Question"); - selectFromDropdown("Sample Database"); - - openNavigationSidebar(); - cy.icon("gear").click(); - selectFromDropdown("Admin settings"); - - cy.findByText("Data Model").click(); - hideTable("Orders"); - cy.findByText("Exit admin").click(); - - cy.findByText("New").click(); - selectFromDropdown("Question"); - selectFromDropdown("Sample Database"); - - popover().within(() => { - cy.findByText("Products"); - cy.findByText("Reviews"); - cy.findByText("People"); - cy.findByText("Orders").should("not.exist"); - }); - }); -}); - -function selectFromDropdown(optionName) { - popover() - .findByText(optionName) - .click(); -} - -function hideTable(tableName) { - cy.findByText(tableName) - .find(".Icon-eye_crossed_out") - .click({ force: true }); -} diff --git a/frontend/test/metabase/scenarios/question/reproductions/19742-data-picker-closes-after-hiding-table.js b/frontend/test/metabase/scenarios/question/reproductions/19742-data-picker-closes-after-hiding-table.js new file mode 100644 index 0000000000000000000000000000000000000000..7010fbbacc390f9b3759e927f6fefaaee06a83c8 --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/19742-data-picker-closes-after-hiding-table.js @@ -0,0 +1,54 @@ +import { + restore, + popover, + openNavigationSidebar, +} from "__support__/e2e/cypress"; + +export function issue19742() { + describe("issue 19742", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + // In order to reproduce the issue, it's important to only use in-app links + // and don't refresh the app state (like by doing cy.visit) + it("shouldn't auto-close the data selector after a table was hidden", () => { + cy.visit("/"); + cy.findByText("New").click(); + selectFromDropdown("Question"); + selectFromDropdown("Sample Database"); + + openNavigationSidebar(); + cy.icon("gear").click(); + selectFromDropdown("Admin settings"); + + cy.findByText("Data Model").click(); + hideTable("Orders"); + cy.findByText("Exit admin").click(); + + cy.findByText("New").click(); + selectFromDropdown("Question"); + selectFromDropdown("Sample Database"); + + popover().within(() => { + cy.findByText("Products"); + cy.findByText("Reviews"); + cy.findByText("People"); + cy.findByText("Orders").should("not.exist"); + }); + }); + }); + + function selectFromDropdown(optionName) { + popover() + .findByText(optionName) + .click(); + } + + function hideTable(tableName) { + cy.findByText(tableName) + .find(".Icon-eye_crossed_out") + .click({ force: true }); + } +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/20551-filter-starts-with.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/20551-filter-starts-with.cy.spec.js deleted file mode 100644 index f219a0716ed1685e3cbba98b08c89c876f0dd89d..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/20551-filter-starts-with.cy.spec.js +++ /dev/null @@ -1,26 +0,0 @@ -import { restore, openProductsTable, filter } from "__support__/e2e/cypress"; - -describe("issue 20551", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should allow filtering with includes, rather than starts with (metabase#20551)", () => { - openProductsTable({ mode: "notebook" }); - filter({ mode: "notebook" }); - cy.findByText("Category").click(); - - // Make sure input field is auto-focused - cy.focused() - .should("have.attr", "placeholder", "Search the list") - .type("i"); - - // All categories that contain `i` - cy.findByText("Doohickey"); - cy.findByText("Gizmo"); - cy.findByText("Widget"); - - cy.findByText("Gadget").should("not.exist"); - }); -}); diff --git a/frontend/test/metabase/scenarios/question/reproductions/20551-filter-starts-with.js b/frontend/test/metabase/scenarios/question/reproductions/20551-filter-starts-with.js new file mode 100644 index 0000000000000000000000000000000000000000..1ab42d01838afb7a0bc11a54f82524dad61367b3 --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/20551-filter-starts-with.js @@ -0,0 +1,28 @@ +import { restore, openProductsTable, filter } from "__support__/e2e/cypress"; + +export function issue20551() { + describe("issue 20551", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should allow filtering with includes, rather than starts with (metabase#20551)", () => { + openProductsTable({ mode: "notebook" }); + filter({ mode: "notebook" }); + cy.findByText("Category").click(); + + // Make sure input field is auto-focused + cy.focused() + .should("have.attr", "placeholder", "Search the list") + .type("i"); + + // All categories that contain `i` + cy.findByText("Doohickey"); + cy.findByText("Gizmo"); + cy.findByText("Widget"); + + cy.findByText("Gadget").should("not.exist"); + }); + }); +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/20627-nested-long-names-wrong-aliases.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/20627-nested-long-names-wrong-aliases.cy.spec.js deleted file mode 100644 index f424689d8182dca04d8119dfcbec77dfc861205c..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/20627-nested-long-names-wrong-aliases.cy.spec.js +++ /dev/null @@ -1,60 +0,0 @@ -import { - restore, - openOrdersTable, - popover, - enterCustomColumnDetails, - visualize, -} from "__support__/e2e/cypress"; - -import { SAMPLE_DATABASE } from "__support__/e2e/cypress_sample_database"; - -const { ORDERS, PRODUCTS_ID } = SAMPLE_DATABASE; - -const newColumnName = "Product ID with a very long name"; -const newTableName = "Products with a very long name"; - -describe("issue 20627", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - renameColumn(ORDERS.PRODUCT_ID, newColumnName); - renameTable(PRODUCTS_ID, newTableName); - }); - - it("nested queries should handle long column and/or table names (metabase#20627)", () => { - openOrdersTable({ mode: "notebook" }); - - cy.findByText("Join data").click(); - cy.findByText(newTableName).click(); - - cy.findByText("Summarize").click(); - cy.findByText("Count of rows").click(); - - cy.findByText("Pick a column to group by").click(); - popover().within(() => { - cy.contains(newTableName).click(); - - cy.findByText("Category").click(); - }); - - cy.findByText("Custom column").click(); - enterCustomColumnDetails({ formula: "1 + 1", name: "Math" }); - cy.button("Done").click(); - - visualize(); - - cy.get(".cellData") - .should("contain", "Math") - .and("contain", "Doohickey") - .and("contain", "3,976"); - }); -}); - -function renameColumn(columnId, name) { - cy.request("PUT", `/api/field/${columnId}`, { display_name: name }); -} - -function renameTable(tableId, name) { - cy.request("PUT", `/api/table/${tableId}`, { display_name: name }); -} diff --git a/frontend/test/metabase/scenarios/question/reproductions/20627-nested-long-names-wrong-aliases.js b/frontend/test/metabase/scenarios/question/reproductions/20627-nested-long-names-wrong-aliases.js new file mode 100644 index 0000000000000000000000000000000000000000..cfe05d44e0b36390de892e05b051f7b88cbd1d82 --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/20627-nested-long-names-wrong-aliases.js @@ -0,0 +1,62 @@ +import { + restore, + openOrdersTable, + popover, + enterCustomColumnDetails, + visualize, +} from "__support__/e2e/cypress"; + +import { SAMPLE_DATABASE } from "__support__/e2e/cypress_sample_database"; + +const { ORDERS, PRODUCTS_ID } = SAMPLE_DATABASE; + +const newColumnName = "Product ID with a very long name"; +const newTableName = "Products with a very long name"; + +export function issue20627() { + describe("issue 20627", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + renameColumn(ORDERS.PRODUCT_ID, newColumnName); + renameTable(PRODUCTS_ID, newTableName); + }); + + it("nested queries should handle long column and/or table names (metabase#20627)", () => { + openOrdersTable({ mode: "notebook" }); + + cy.findByText("Join data").click(); + cy.findByText(newTableName).click(); + + cy.findByText("Summarize").click(); + cy.findByText("Count of rows").click(); + + cy.findByText("Pick a column to group by").click(); + popover().within(() => { + cy.contains(newTableName).click(); + + cy.findByText("Category").click(); + }); + + cy.findByText("Custom column").click(); + enterCustomColumnDetails({ formula: "1 + 1", name: "Math" }); + cy.button("Done").click(); + + visualize(); + + cy.get(".cellData") + .should("contain", "Math") + .and("contain", "Doohickey") + .and("contain", "3,976"); + }); + }); + + function renameColumn(columnId, name) { + cy.request("PUT", `/api/field/${columnId}`, { display_name: name }); + } + + function renameTable(tableId, name) { + cy.request("PUT", `/api/table/${tableId}`, { display_name: name }); + } +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/20683-postgres-current-quarter.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/20683-postgres-current-quarter.cy.spec.js deleted file mode 100644 index 4bb803ac9472c2f21e01b64173e02a9887d8715e..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/20683-postgres-current-quarter.cy.spec.js +++ /dev/null @@ -1,36 +0,0 @@ -import { restore, visualize } from "__support__/e2e/cypress"; - -describe("issue 20683", () => { - beforeEach(() => { - restore("postgres-12"); - cy.signInAsAdmin(); - - cy.visit("/"); - cy.findByText("New").click(); - cy.findByText("Question") - .should("be.visible") - .click(); - - cy.findByText("QA Postgres12").click(); - cy.findByText("Orders").click(); - }); - - it("should filter postgres with the 'current quarter' filter (metabase#20683)", () => { - cy.findByText("Add filters to narrow your answer").click(); - - cy.findByText("Created At").click(); - - cy.findByText("Previous").click(); - cy.findByText("Current").click(); - - cy.findByText("Day").click(); - cy.findByText("Quarter").click(); - - cy.button("Add filter").click(); - - visualize(); - - // We don't have entries for the current quarter so we expect no results - cy.findByText("No results!"); - }); -}); diff --git a/frontend/test/metabase/scenarios/question/reproductions/20683-postgres-current-quarter.js b/frontend/test/metabase/scenarios/question/reproductions/20683-postgres-current-quarter.js new file mode 100644 index 0000000000000000000000000000000000000000..ae435e78cb705f6e2054cb3cdd5cb39a662b2e4e --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/20683-postgres-current-quarter.js @@ -0,0 +1,38 @@ +import { restore, visualize } from "__support__/e2e/cypress"; + +export function issue20683() { + describe("issue 20683", () => { + beforeEach(() => { + restore("postgres-12"); + cy.signInAsAdmin(); + + cy.visit("/"); + cy.findByText("New").click(); + cy.findByText("Question") + .should("be.visible") + .click(); + + cy.findByText("QA Postgres12").click(); + cy.findByText("Orders").click(); + }); + + it("should filter postgres with the 'current quarter' filter (metabase#20683)", () => { + cy.findByText("Add filters to narrow your answer").click(); + + cy.findByText("Created At").click(); + + cy.findByText("Previous").click(); + cy.findByText("Current").click(); + + cy.findByText("Day").click(); + cy.findByText("Quarter").click(); + + cy.button("Add filter").click(); + + visualize(); + + // We don't have entries for the current quarter so we expect no results + cy.findByText("No results!"); + }); + }); +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/4482-temporal-min-max.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/4482-temporal-min-max.cy.spec.js deleted file mode 100644 index 1594606807015a06089dfb6eb9f25d25ebbac0a7..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/4482-temporal-min-max.cy.spec.js +++ /dev/null @@ -1,50 +0,0 @@ -import { - restore, - visualize, - openNotebookEditor, -} from "__support__/e2e/cypress"; - -describe("issue 4482", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - openNotebookEditor(); - cy.contains("Sample Database").click(); - cy.contains("Products").click(); - }); - - it("should be possible to summarize min of a temporal column (metabase#4482-1)", () => { - pickMetric("Minimum of"); - - cy.contains("Created At").click(); - - visualize(); - - cy.findByText("April 1, 2016, 12:00 AM"); - }); - - it("should be possible to summarize max of a temporal column (metabase#4482-2)", () => { - pickMetric("Maximum of"); - - cy.contains("Created At").click(); - - visualize(); - - cy.findByText("April 1, 2019, 12:00 AM"); - }); - - it("should be not possible to average a temporal column (metabase#4482-3)", () => { - pickMetric("Average of"); - - cy.findByText("Created At").should("not.exist"); - }); -}); - -function pickMetric(metric) { - cy.contains("Pick the metric").click(); - - cy.contains(metric).click(); - cy.findByText("Price"); - cy.findByText("Rating"); -} diff --git a/frontend/test/metabase/scenarios/question/reproductions/4482-temporal-min-max.js b/frontend/test/metabase/scenarios/question/reproductions/4482-temporal-min-max.js new file mode 100644 index 0000000000000000000000000000000000000000..e0bdc6e40ffbed9fe99ea69b8bfa4c21ad863c6e --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/4482-temporal-min-max.js @@ -0,0 +1,52 @@ +import { + restore, + visualize, + openNotebookEditor, +} from "__support__/e2e/cypress"; + +export function issue4482() { + describe("issue 4482", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + openNotebookEditor(); + cy.contains("Sample Database").click(); + cy.contains("Products").click(); + }); + + it("should be possible to summarize min of a temporal column (metabase#4482-1)", () => { + pickMetric("Minimum of"); + + cy.contains("Created At").click(); + + visualize(); + + cy.findByText("April 1, 2016, 12:00 AM"); + }); + + it("should be possible to summarize max of a temporal column (metabase#4482-2)", () => { + pickMetric("Maximum of"); + + cy.contains("Created At").click(); + + visualize(); + + cy.findByText("April 1, 2019, 12:00 AM"); + }); + + it("should be not possible to average a temporal column (metabase#4482-3)", () => { + pickMetric("Average of"); + + cy.findByText("Created At").should("not.exist"); + }); + }); + + function pickMetric(metric) { + cy.contains("Pick the metric").click(); + + cy.contains(metric).click(); + cy.findByText("Price"); + cy.findByText("Rating"); + } +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/6239-sort-using-cust-exp.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/6239-sort-using-cust-exp.cy.spec.js deleted file mode 100644 index 6b76abe6eeb367e9c41c3153768fc8eab875d9cf..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/6239-sort-using-cust-exp.cy.spec.js +++ /dev/null @@ -1,74 +0,0 @@ -import { - openOrdersTable, - popover, - restore, - visualize, - summarize, -} from "__support__/e2e/cypress"; - -describe("issue 6239", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - openOrdersTable({ mode: "notebook" }); - - summarize({ mode: "notebook" }); - cy.findByText("Custom Expression").click(); - - cy.get(".ace_text-input") - .type("CountIf([Total] > 0)") - .blur(); - - cy.findByPlaceholderText("Name (required)").type("CE"); - cy.button("Done").click(); - - cy.findByText("Pick a column to group by").click(); - popover() - .contains("Created At") - .first() - .click(); - }); - - it("should be possible to sort by using custom expression (metabase#6239)", () => { - cy.findByText("Sort").click(); - popover() - .contains(/^CE$/) - .click(); - - visualize(); - - // Line chart renders initially. Switch to the table view. - cy.icon("table2").click(); - - cy.get(".cellData") - .eq(1) - .should("contain", "CE") - .and("have.descendants", ".Icon-chevronup"); - - cy.get(".cellData") - .eq(3) - .invoke("text") - .should("eq", "1"); - - // Go back to the notebook editor - cy.icon("notebook").click(); - - // Sort descending this time - cy.icon("arrow_up").click(); - cy.icon("arrow_up").should("not.exist"); - cy.icon("arrow_down"); - - visualize(); - - cy.get(".cellData") - .eq(1) - .should("contain", "CE") - .and("have.descendants", ".Icon-chevrondown"); - - cy.get(".cellData") - .eq(3) - .invoke("text") - .should("eq", "584"); - }); -}); diff --git a/frontend/test/metabase/scenarios/question/reproductions/6239-sort-using-cust-exp.js b/frontend/test/metabase/scenarios/question/reproductions/6239-sort-using-cust-exp.js new file mode 100644 index 0000000000000000000000000000000000000000..37ee3104c5b8ba477a2ab21f2ab4c2033acc097a --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/6239-sort-using-cust-exp.js @@ -0,0 +1,76 @@ +import { + openOrdersTable, + popover, + restore, + visualize, + summarize, +} from "__support__/e2e/cypress"; + +export function issue6239() { + describe("issue 6239", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + openOrdersTable({ mode: "notebook" }); + + summarize({ mode: "notebook" }); + cy.findByText("Custom Expression").click(); + + cy.get(".ace_text-input") + .type("CountIf([Total] > 0)") + .blur(); + + cy.findByPlaceholderText("Name (required)").type("CE"); + cy.button("Done").click(); + + cy.findByText("Pick a column to group by").click(); + popover() + .contains("Created At") + .first() + .click(); + }); + + it("should be possible to sort by using custom expression (metabase#6239)", () => { + cy.findByText("Sort").click(); + popover() + .contains(/^CE$/) + .click(); + + visualize(); + + // Line chart renders initially. Switch to the table view. + cy.icon("table2").click(); + + cy.get(".cellData") + .eq(1) + .should("contain", "CE") + .and("have.descendants", ".Icon-chevronup"); + + cy.get(".cellData") + .eq(3) + .invoke("text") + .should("eq", "1"); + + // Go back to the notebook editor + cy.icon("notebook").click(); + + // Sort descending this time + cy.icon("arrow_up").click(); + cy.icon("arrow_up").should("not.exist"); + cy.icon("arrow_down"); + + visualize(); + + cy.get(".cellData") + .eq(1) + .should("contain", "CE") + .and("have.descendants", ".Icon-chevrondown"); + + cy.get(".cellData") + .eq(3) + .invoke("text") + .should("eq", "584"); + }); + }); +} diff --git a/frontend/test/metabase/scenarios/question/reproductions/9027-new-questions-not-in-saved-questions-immediately.cy.spec.js b/frontend/test/metabase/scenarios/question/reproductions/9027-new-questions-not-in-saved-questions-immediately.cy.spec.js deleted file mode 100644 index f9c9841dc3dbba699026e8e5446baa7cfc22a600..0000000000000000000000000000000000000000 --- a/frontend/test/metabase/scenarios/question/reproductions/9027-new-questions-not-in-saved-questions-immediately.cy.spec.js +++ /dev/null @@ -1,90 +0,0 @@ -import { - restore, - popover, - openNativeEditor, - openNotebookEditor, - openNavigationSidebar, - navigationSidebar, -} from "__support__/e2e/cypress"; - -const QUESTION_NAME = "Foo"; - -describe("issue 9027", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - cy.visit("/question/new"); - cy.findByText("Custom question").click(); - cy.findByText("Saved Questions").click(); - - // Wait for the existing questions to load - cy.findByText("Orders"); - - openNativeEditor({ fromCurrentPage: true }); - - cy.get(".ace_content").type("select 0"); - cy.get(".NativeQueryEditor .Icon-play").click(); - - saveQuestion(QUESTION_NAME); - }); - - it("should display newly saved question in the 'Saved Questions' list immediately (metabase#9027)", () => { - goToSavedQuestionPickerAndAssertQuestion(QUESTION_NAME); - openNavigationSidebar(); - archiveQuestion(QUESTION_NAME); - goToSavedQuestionPickerAndAssertQuestion(QUESTION_NAME, false); - openNavigationSidebar(); - unarchiveQuestion(QUESTION_NAME); - goToSavedQuestionPickerAndAssertQuestion(QUESTION_NAME); - }); -}); - -function goToSavedQuestionPickerAndAssertQuestion(questionName, exists = true) { - openNotebookEditor({ fromCurrentPage: true }); - cy.findByText("Saved Questions").click(); - - cy.findByText(questionName).should(exists ? "exist" : "not.exist"); -} - -function saveQuestion(name) { - cy.intercept("POST", "/api/card").as("saveQuestion"); - cy.findByText("Save").click(); - cy.findByLabelText("Name") - .clear() - .type(name); - cy.button("Save").click(); - cy.button("Not now").click(); - cy.wait("@saveQuestion"); -} - -function archiveQuestion(questionName) { - navigationSidebar() - .findByText("Our analytics") - .click(); - openEllipsisMenuFor(questionName); - popover() - .findByText("Archive") - .click(); -} - -function unarchiveQuestion(questionName) { - navigationSidebar().within(() => { - cy.icon("ellipsis").click(); - }); - popover() - .findByText("View archive") - .click(); - cy.findByText(questionName) - .parent() - .within(() => { - cy.icon("unarchive").click({ force: true }); - }); -} - -function openEllipsisMenuFor(item) { - cy.findByText(item) - .closest("tr") - .find(".Icon-ellipsis") - .click({ force: true }); -} diff --git a/frontend/test/metabase/scenarios/question/reproductions/9027-new-questions-not-in-saved-questions-immediately.js b/frontend/test/metabase/scenarios/question/reproductions/9027-new-questions-not-in-saved-questions-immediately.js new file mode 100644 index 0000000000000000000000000000000000000000..c2f8d59f738b07d62d4b566cdc941207d4df8f59 --- /dev/null +++ b/frontend/test/metabase/scenarios/question/reproductions/9027-new-questions-not-in-saved-questions-immediately.js @@ -0,0 +1,95 @@ +import { + restore, + popover, + openNativeEditor, + openNotebookEditor, + openNavigationSidebar, + navigationSidebar, +} from "__support__/e2e/cypress"; + +const QUESTION_NAME = "Foo"; + +export function issue9027() { + describe("issue 9027", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + cy.visit("/question/new"); + cy.findByText("Custom question").click(); + cy.findByText("Saved Questions").click(); + + // Wait for the existing questions to load + cy.findByText("Orders"); + + openNativeEditor({ fromCurrentPage: true }); + + cy.get(".ace_content").type("select 0"); + cy.get(".NativeQueryEditor .Icon-play").click(); + + saveQuestion(QUESTION_NAME); + }); + + it("should display newly saved question in the 'Saved Questions' list immediately (metabase#9027)", () => { + goToSavedQuestionPickerAndAssertQuestion(QUESTION_NAME); + openNavigationSidebar(); + archiveQuestion(QUESTION_NAME); + goToSavedQuestionPickerAndAssertQuestion(QUESTION_NAME, false); + openNavigationSidebar(); + unarchiveQuestion(QUESTION_NAME); + goToSavedQuestionPickerAndAssertQuestion(QUESTION_NAME); + }); + }); + + function goToSavedQuestionPickerAndAssertQuestion( + questionName, + exists = true, + ) { + openNotebookEditor({ fromCurrentPage: true }); + cy.findByText("Saved Questions").click(); + + cy.findByText(questionName).should(exists ? "exist" : "not.exist"); + } + + function saveQuestion(name) { + cy.intercept("POST", "/api/card").as("saveQuestion"); + cy.findByText("Save").click(); + cy.findByLabelText("Name") + .clear() + .type(name); + cy.button("Save").click(); + cy.button("Not now").click(); + cy.wait("@saveQuestion"); + } + + function archiveQuestion(questionName) { + navigationSidebar() + .findByText("Our analytics") + .click(); + openEllipsisMenuFor(questionName); + popover() + .findByText("Archive") + .click(); + } + + function unarchiveQuestion(questionName) { + navigationSidebar().within(() => { + cy.icon("ellipsis").click(); + }); + popover() + .findByText("View archive") + .click(); + cy.findByText(questionName) + .parent() + .within(() => { + cy.icon("unarchive").click({ force: true }); + }); + } + + function openEllipsisMenuFor(item) { + cy.findByText(item) + .closest("tr") + .find(".Icon-ellipsis") + .click({ force: true }); + } +}