From 7038b2e4c21c18938ce5ca957721a6a977288c26 Mon Sep 17 00:00:00 2001 From: Ryan Laurie <30528226+iethree@users.noreply.github.com> Date: Fri, 31 May 2024 14:16:40 -0600 Subject: [PATCH] Combine Filters Reproduction into new e2e job (#43328) * combine reproductions into new filters e2e job * fix import * gee thanks sloan --- .github/actions/build-e2e-matrix/action.yml | 1 + ...ta-permissions-connected-filter.cy.spec.js | 108 - .../12985-dropdown-search.cy.spec.js | 143 - ...ta-should-use-dashboard-filters.cy.spec.js | 115 - .../16663-filters-can-stay-in-url.cy.spec.js | 79 - ...-false-no-matching-filter-alert.cy.spec.js | 77 - ...e-today-in-all-time-next-filter.cy.spec.js | 74 - ...17775-filter-custom-column-date.cy.spec.js | 86 - ...ue-multiple-cards-same-question.cy.spec.js | 108 - ...r-user-without-card-permissions.cy.spec.js | 83 - ...-id-filter-map-to-a-wrong-field.cy.spec.js | 136 - .../22482-round-relative-ranges.cy.spec.js | 53 - ...flter-cc-dropped-on-second-edit.cy.spec.js | 111 - .../24235-exclude-all-date-options.cy.spec.js | 87 - ...ully-deal-with-corrupted-filter.cy.spec.js | 139 - .../25322-loading-list-values.cy.spec.js | 79 - ...-multi-series-parameter-mapping.cy.spec.js | 96 - ...d-values-not-passed-to-question.cy.spec.js | 114 - ...ontains-filter-case-sensitivity.cy.spec.js | 81 - ...y-filter-incorrectly-positioned.cy.spec.js | 101 - ...vigation-between-two-dashboards.cy.spec.js | 63 - ...-cc-filter-appears-disconnected.cy.spec.js | 76 - .../29347-remapped-field-values.cy.spec.js | 257 -- ...62-between-filter-default-value.cy.spec.js | 42 - ...tive-dashcard-id-switching-tabs.cy.spec.js | 91 - .../43154-model-parameter-target.cy.spec.js | 92 - ...2444-reload-card-without-change.cy.spec.js | 188 -- ...dashboard-filters-reproductions.cy.spec.js | 2484 +++++++++++++++++ .../filters-reproductions.cy.spec.js | 985 +++++++ .../filters/filter-reproductions.cy.spec.js | 42 - ...12496-drill-through-filter-date.cy.spec.js | 108 - ...ultiple-filters-with-same-value.cy.spec.js | 34 - ...on-filter-disrupts-drillthrough.cy.spec.js | 49 - .../20551-filter-starts-with.cy.spec.js | 28 - .../20683-postgres-current-quarter.cy.spec.js | 42 - .../21979-exclude-day-of-the-week.cy.spec.js | 59 - ...30-filter-on-aggregation-max-of.cy.spec.js | 56 - .../22730-table-column-time-filter.cy.spec.js | 40 - .../24664-multiple-filters-editing.cy.spec.js | 39 - .../24994-update-filters.cy.spec.js | 67 - ...25378-relative-date-on-breakout.cy.spec.js | 51 - ...mn-filters-not-working-after-cc.cy.spec.js | 53 - .../25990-filter-nested-join.cy.spec.js | 63 - ...een-after-summarize-not-working.cy.spec.js | 48 - .../26861-exclude-breaks-native.cy.spec.js | 56 - ...clude-always-shows-days-of-week.cy.spec.js | 34 - ...-non-boolean-custom-expressions.cy.spec.js | 37 - ...ill-filter-on-aggregated-column.cy.spec.js | 56 - ...long-column-name-search-results.cy.spec.js | 57 - ...filter-popover-navigation-error.cy.spec.js | 31 - ...36508-number-of-distinct-values.cy.spec.ts | 44 - .../9339-clipboard-numeric-filter.cy.spec.js | 27 - 52 files changed, 3470 insertions(+), 3800 deletions(-) delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/12720-no-data-permissions-connected-filter.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/12985-dropdown-search.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/16112-nodata-should-use-dashboard-filters.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/16663-filters-can-stay-in-url.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/17211-false-no-matching-filter-alert.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/17551-include-today-in-all-time-next-filter.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/17775-filter-custom-column-date.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/19494-wrong-default-value-multiple-cards-same-question.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/20656-dashboard-breaks-for-user-without-card-permissions.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/21528-dashboard-id-filter-map-to-a-wrong-field.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/22482-round-relative-ranges.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/22788-flter-cc-dropped-on-second-edit.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/24235-exclude-all-date-options.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/24500-gracefully-deal-with-corrupted-filter.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/25322-loading-list-values.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/25355-multi-series-parameter-mapping.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/25374-comma-separated-values-not-passed-to-question.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/25908-contains-filter-case-sensitivity.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/26230-dashboard-sticky-filter-incorrectly-positioned.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/27356-navigation-between-two-dashboards.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/27768-cc-filter-appears-disconnected.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/29347-remapped-field-values.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/31662-between-filter-default-value.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/38245-negative-dashcard-id-switching-tabs.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/43154-model-parameter-target.cy.spec.js delete mode 100644 e2e/test/scenarios/dashboard-filters/reproductions/8030-32444-reload-card-without-change.cy.spec.js create mode 100644 e2e/test/scenarios/filters-reproductions/dashboard-filters-reproductions.cy.spec.js create mode 100644 e2e/test/scenarios/filters-reproductions/filters-reproductions.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/filter-reproductions.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/12496-drill-through-filter-date.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/16621-create-multiple-filters-with-same-value.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/18770-post-aggregation-filter-disrupts-drillthrough.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/20551-filter-starts-with.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/20683-postgres-current-quarter.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/21979-exclude-day-of-the-week.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/22230-filter-on-aggregation-max-of.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/22730-table-column-time-filter.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/24664-multiple-filters-editing.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/24994-update-filters.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/25378-relative-date-on-breakout.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/25927-column-filters-not-working-after-cc.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/25990-filter-nested-join.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/25994-between-after-summarize-not-working.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/26861-exclude-breaks-native.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/27123-exclude-always-shows-days-of-week.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/29094-non-boolean-custom-expressions.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/30312-drill-filter-on-aggregated-column.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/31340-long-column-name-search-results.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/34794-filter-popover-navigation-error.cy.spec.js delete mode 100644 e2e/test/scenarios/filters/reproductions/36508-number-of-distinct-values.cy.spec.ts delete mode 100644 e2e/test/scenarios/filters/reproductions/9339-clipboard-numeric-filter.cy.spec.js diff --git a/.github/actions/build-e2e-matrix/action.yml b/.github/actions/build-e2e-matrix/action.yml index 9a42ad9977c..0716d951a84 100644 --- a/.github/actions/build-e2e-matrix/action.yml +++ b/.github/actions/build-e2e-matrix/action.yml @@ -36,6 +36,7 @@ runs: ["dashboard-filters", {} ], ["embedding", {} ], ["filters", {} ], + ["filters-reproductions", {}], ["joins", {} ], ["metrics", {} ], ["models", {} ], diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/12720-no-data-permissions-connected-filter.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/12720-no-data-permissions-connected-filter.cy.spec.js deleted file mode 100644 index 8fe15aa54f3..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/12720-no-data-permissions-connected-filter.cy.spec.js +++ /dev/null @@ -1,108 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - ORDERS_DASHBOARD_DASHCARD_ID, - ORDERS_DASHBOARD_ID, - ORDERS_QUESTION_ID, -} from "e2e/support/cypress_sample_instance_data"; -import { - restore, - visitDashboard, - filterWidget, - updateDashboardCards, -} from "e2e/support/helpers"; - -const { ORDERS } = SAMPLE_DATABASE; - -// After January 1st, 2026 -const dashboardFilter = { - default: "2026-01-01~", - id: "d3b78b27", - name: "Date Filter", - slug: "date_filter", - type: "date/all-options", -}; - -const questionDetails = { - name: "12720_SQL", - native: { - query: "SELECT * FROM ORDERS WHERE {{filter}}", - "template-tags": { - filter: { - id: "1d006bb7-045f-6c57-e41b-2661a7648276", - name: "filter", - "display-name": "Filter", - type: "dimension", - dimension: ["field", ORDERS.CREATED_AT, null], - "widget-type": "date/all-options", - default: null, - }, - }, - }, -}; - -describe("issue 12720", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - // In this test we're using already present question ("Orders") and the dashboard with that question ("Orders in a dashboard") - cy.request("PUT", `/api/dashboard/${ORDERS_DASHBOARD_ID}`, { - parameters: [dashboardFilter], - }); - - cy.createNativeQuestion(questionDetails).then( - ({ body: { id: SQL_ID } }) => { - updateDashboardCards({ - dashboard_id: ORDERS_DASHBOARD_ID, - cards: [ - { - card_id: SQL_ID, - row: 0, - col: 6, // making sure it doesn't overlap the existing card - size_x: 7, - size_y: 5, - parameter_mappings: [ - { - parameter_id: dashboardFilter.id, - card_id: SQL_ID, - target: ["dimension", ["template-tag", "filter"]], - }, - ], - }, - // add filter to existing card - { - id: ORDERS_DASHBOARD_DASHCARD_ID, - card_id: ORDERS_QUESTION_ID, - row: 0, - col: 0, - size_x: 7, - size_y: 5, - parameter_mappings: [ - { - parameter_id: dashboardFilter.id, - card_id: ORDERS_QUESTION_ID, - target: ["dimension", ["field", ORDERS.CREATED_AT, null]], - }, - ], - }, - ], - }); - }, - ); - }); - - it("should show QB question on a dashboard with filter connected to card without data-permission (metabase#12720)", () => { - cy.signIn("readonly"); - - clickThrough("12720_SQL"); - clickThrough("Orders"); - }); -}); - -function clickThrough(title) { - visitDashboard(ORDERS_DASHBOARD_ID); - cy.findAllByTestId("dashcard-container").contains(title).click(); - - cy.location("search").should("contain", dashboardFilter.default); - filterWidget().contains("After January 1, 2026"); -} diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/12985-dropdown-search.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/12985-dropdown-search.cy.spec.js deleted file mode 100644 index 707fa9bb4d0..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/12985-dropdown-search.cy.spec.js +++ /dev/null @@ -1,143 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - restore, - filterWidget, - popover, - visitDashboard, -} from "e2e/support/helpers"; - -const { PRODUCTS_ID, PRODUCTS } = SAMPLE_DATABASE; - -const categoryFilter = { - name: "Category", - slug: "category", - id: "2a12e66c", - type: "string/=", - sectionId: "string", -}; - -const dashboardDetails = { parameters: [categoryFilter] }; - -describe("issue 12985 > dashboard filter dropdown/search", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should work for saved nested questions (metabase#12985-1)", () => { - cy.createQuestion({ - name: "Q1", - query: { "source-table": PRODUCTS_ID }, - }).then(({ body: { id: Q1_ID } }) => { - // Create nested card based on the first one - const nestedQuestion = { - name: "Q2", - query: { "source-table": `card__${Q1_ID}` }, - }; - - cy.createQuestionAndDashboard({ - questionDetails: nestedQuestion, - dashboardDetails, - }).then(({ body: { id, card_id, dashboard_id } }) => { - cy.log("Connect dashboard filters to the nested card"); - - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - dashcards: [ - { - id, - card_id, - row: 0, - col: 0, - size_x: 13, - size_y: 8, - series: [], - visualization_settings: {}, - // Connect filter to the card - parameter_mappings: [ - { - parameter_id: categoryFilter.id, - card_id, - target: ["dimension", ["field", PRODUCTS.CATEGORY, null]], - }, - ], - }, - ], - }); - - visitDashboard(dashboard_id); - }); - }); - - filterWidget().contains("Category").click(); - cy.log("Failing to show dropdown in v0.36.0 through v.0.37.0"); - - popover().within(() => { - cy.findByText("Doohickey"); - cy.findByText("Gizmo"); - cy.findByText("Widget"); - cy.findByText("Gadget").click(); - }); - cy.button("Add filter").click(); - - cy.location("search").should("eq", "?category=Gadget"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Ergonomic Silk Coat"); - }); - - it.skip("should work for aggregated questions (metabase#12985-2)", () => { - const questionDetails = { - name: "12985-v2", - query: { - "source-query": { - "source-table": PRODUCTS_ID, - aggregation: [["count"]], - breakout: [["field", PRODUCTS.CATEGORY, null]], - }, - filter: [">", ["field", "count", { "base-type": "type/Integer" }], 1], - }, - }; - - cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( - ({ body: { id, card_id, dashboard_id } }) => { - cy.log("Connect dashboard filter to the aggregated card"); - - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - dashcards: [ - { - id, - card_id, - row: 0, - col: 0, - size_x: 11, - size_y: 6, - series: [], - visualization_settings: {}, - // Connect filter to the card - parameter_mappings: [ - { - parameter_id: categoryFilter.id, - card_id, - target: [ - "dimension", - ["field", "CATEGORY", { "base-type": "type/Text" }], - ], - }, - ], - }, - ], - }); - - visitDashboard(dashboard_id); - }, - ); - - filterWidget().contains("Category").click(); - // It will fail at this point until the issue is fixed because popover never appears - popover().contains("Gadget").click(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Add filter").click(); - cy.url().should("contain", "?category=Gadget"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Ergonomic Silk Coat"); - }); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/16112-nodata-should-use-dashboard-filters.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/16112-nodata-should-use-dashboard-filters.cy.spec.js deleted file mode 100644 index d916ed19553..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/16112-nodata-should-use-dashboard-filters.cy.spec.js +++ /dev/null @@ -1,115 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - restore, - popover, - visitDashboard, - editDashboard, - sidebar, -} from "e2e/support/helpers"; - -const { REVIEWS, REVIEWS_ID } = SAMPLE_DATABASE; - -describe("issues 15119 and 16112", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - cy.request("PUT", `/api/field/${REVIEWS.REVIEWER}`, { - has_field_values: "list", - semantic_type: "type/Category", - }); - - cy.request("PUT", `/api/field/${REVIEWS.RATING}`, { - has_field_values: "list", - semantic_type: "type/Category", - }); - }); - - it("user without data permissions should be able to use dashboard filters (metabase#15119, metabase#16112)", () => { - const questionDetails = { - name: "15119", - query: { "source-table": REVIEWS_ID }, - }; - - const ratingFilter = { - name: "Rating Filter", - slug: "rating", - id: "5dfco74e", - type: "string/=", - sectionId: "string", - }; - - const reviewerFilter = { - name: "Reviewer Filter", - slug: "reviewer", - id: "ad1c877e", - type: "string/=", - sectionId: "string", - }; - - const dashboardDetails = { parameters: [reviewerFilter, ratingFilter] }; - - cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( - ({ body: { id, card_id, dashboard_id } }) => { - // Connect filters to the card - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - dashcards: [ - { - id, - card_id, - row: 0, - col: 0, - size_x: 16, - size_y: 9, - visualization_settings: {}, - parameter_mappings: [ - { - parameter_id: ratingFilter.id, - card_id, - target: ["dimension", ["field", REVIEWS.RATING, null]], - }, - { - parameter_id: reviewerFilter.id, - card_id, - target: ["dimension", ["field", REVIEWS.REVIEWER, null]], - }, - ], - }, - ], - }); - - // Actually need to setup the linked filter: - visitDashboard(dashboard_id); - editDashboard(); - cy.findByText("Rating Filter").click(); - cy.findByText("Linked filters").click(); - - // turn on the toggle - sidebar().findByRole("switch").parent().get("label").click(); - - cy.findByText("Save").click(); - - cy.signIn("nodata"); - visitDashboard(dashboard_id); - }, - ); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText(reviewerFilter.name).click(); - popover().contains("adam").click(); - cy.button("Add filter").click(); - - cy.findByTestId("dashcard-container").should("contain", "adam"); - cy.location("search").should("eq", "?reviewer=adam&rating="); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText(ratingFilter.name).click(); - - popover().contains("5").click(); - cy.button("Add filter").click(); - - cy.findByTestId("dashcard-container").should("contain", "adam"); - cy.findByTestId("dashcard-container").should("contain", "5"); - cy.location("search").should("eq", "?reviewer=adam&rating=5"); - }); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/16663-filters-can-stay-in-url.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/16663-filters-can-stay-in-url.cy.spec.js deleted file mode 100644 index c4eca70af42..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/16663-filters-can-stay-in-url.cy.spec.js +++ /dev/null @@ -1,79 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - addOrUpdateDashboardCard, - commandPalette, - commandPaletteSearch, - restore, - visitDashboard, -} from "e2e/support/helpers"; - -const { ORDERS, ORDERS_ID } = SAMPLE_DATABASE; - -const questionDetails = { - query: { - "source-table": ORDERS_ID, - }, -}; - -const FILTER = { - name: "Quarter and Year", - slug: "quarter_and_year", - id: "f8ae0c97", - type: "date/quarter-year", - sectionId: "date", - default: "Q1-2023", -}; - -const dashboardDetails = { parameters: [FILTER] }; - -describe("issue 16663", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should remove filter value from url after going to another dashboard (metabase#16663)", () => { - const dashboardToRedirect = "Orders in a dashboard"; - const queryParam = "quarter_and_year=Q1"; - - cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( - ({ body: dashboardCard }) => { - const { dashboard_id } = dashboardCard; - - addOrUpdateDashboardCard({ - dashboard_id: dashboardCard.dashboard_id, - card_id: dashboardCard.card_id, - card: { - parameter_mappings: [ - { - parameter_id: FILTER.id, - card_id: dashboardCard.card_id, - target: [ - "dimension", - [ - "field", - ORDERS.CREATED_AT, - { - "base-type": "type/DateTime", - }, - ], - ], - }, - ], - }, - }); - visitDashboard(dashboard_id); - }, - ); - - cy.url().should("include", queryParam); - - commandPaletteSearch(dashboardToRedirect, false); - commandPalette().within(() => { - cy.findByRole("option", { name: dashboardToRedirect }).click(); - }); - - cy.url().should("include", "orders-in-a-dashboard"); - cy.url().should("not.include", queryParam); - }); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/17211-false-no-matching-filter-alert.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/17211-false-no-matching-filter-alert.cy.spec.js deleted file mode 100644 index ad789ec3a75..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/17211-false-no-matching-filter-alert.cy.spec.js +++ /dev/null @@ -1,77 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { restore, filterWidget, visitDashboard } from "e2e/support/helpers"; - -const { ORDERS, ORDERS_ID, PEOPLE } = SAMPLE_DATABASE; - -const questionDetails = { - query: { - "source-table": ORDERS_ID, - }, -}; - -const filter = { - name: "Location", - slug: "location", - id: "96917420", - type: "string/=", - sectionId: "location", -}; - -const dashboardDetails = { - parameters: [filter], -}; - -describe("issue 17211", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( - ({ body: { id, card_id, dashboard_id } }) => { - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - dashcards: [ - { - id, - card_id, - row: 0, - col: 0, - size_x: 11, - size_y: 6, - series: [], - visualization_settings: {}, - parameter_mappings: [ - { - parameter_id: filter.id, - card_id, - target: [ - "dimension", - [ - "field", - PEOPLE.CITY, - { - "source-field": ORDERS.USER_ID, - }, - ], - ], - }, - ], - }, - ], - }); - - visitDashboard(dashboard_id); - }, - ); - }); - - it("should not falsely alert that no matching dashboard filter has been found (metabase#17211)", () => { - filterWidget().click(); - - cy.findByPlaceholderText("Search by City").type("abb"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Abbeville").click(); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.contains("No matching City found").should("not.exist"); - }); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/17551-include-today-in-all-time-next-filter.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/17551-include-today-in-all-time-next-filter.cy.spec.js deleted file mode 100644 index 955e2b7be04..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/17551-include-today-in-all-time-next-filter.cy.spec.js +++ /dev/null @@ -1,74 +0,0 @@ -import { restore, filterWidget, visitDashboard } from "e2e/support/helpers"; - -import { setAdHocFilter } from "../../native-filters/helpers/e2e-date-filter-helpers"; - -describe("issue 17551", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - cy.createNativeQuestion({ - native: { - query: - "select 'yesterday' as \"text\", dateadd('day', -1, current_date::date) as \"date\" union all\nselect 'today', current_date::date union all\nselect 'tomorrow', dateadd('day', 1, current_date::date)\n", - }, - }).then(({ body: { id: baseQuestionId } }) => { - const questionDetails = { - name: "17551 QB", - query: { "source-table": `card__${baseQuestionId}` }, - }; - - const filter = { - name: "Date Filter", - slug: "date_filter", - id: "888188ad", - type: "date/all-options", - sectionId: "date", - }; - - const dashboardDetails = { parameters: [filter] }; - - cy.createQuestionAndDashboard({ - questionDetails, - dashboardDetails, - }).then(({ body: card }) => { - const { card_id, dashboard_id } = card; - - const mapFilterToCard = { - parameter_mappings: [ - { - parameter_id: filter.id, - card_id, - target: [ - "dimension", - [ - "field", - "date", - { - "base-type": "type/DateTime", - }, - ], - ], - }, - ], - }; - - cy.editDashboardCard(card, mapFilterToCard); - - visitDashboard(dashboard_id); - }); - }); - }); - - it("should include today in the 'All time' date filter when chosen 'Next' (metabase#17551)", () => { - filterWidget().click(); - setAdHocFilter({ condition: "Next", includeCurrent: true }); - - cy.url().should("include", "?date_filter=next30days~"); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("tomorrow"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("today"); - }); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/17775-filter-custom-column-date.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/17775-filter-custom-column-date.cy.spec.js deleted file mode 100644 index e2136b87895..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/17775-filter-custom-column-date.cy.spec.js +++ /dev/null @@ -1,86 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - restore, - popover, - filterWidget, - editDashboard, - saveDashboard, - visitDashboard, -} from "e2e/support/helpers"; - -import { setQuarterAndYear } from "../../native-filters/helpers/e2e-date-filter-helpers"; - -const { ORDERS, ORDERS_ID } = SAMPLE_DATABASE; - -const questionDetails = { - query: { - "source-table": ORDERS_ID, - expressions: { - "CC Date": ["field", ORDERS.CREATED_AT, { "base-type": "type/DateTime" }], - }, - "order-by": [ - ["asc", ["field", ORDERS.ID, { "base-type": "type/BigInteger" }]], - ], - }, -}; - -const parameters = [ - { - name: "Quarter and Year", - slug: "quarter_and_year", - id: "f8ae0c97", - type: "date/quarter-year", - sectionId: "date", - }, -]; - -const dashboardDetails = { parameters }; - -describe("issue 17775", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( - ({ body: dashboardCard }) => { - const { dashboard_id } = dashboardCard; - - const updatedSize = { size_x: 21, size_y: 8 }; - - cy.editDashboardCard(dashboardCard, updatedSize); - - visitDashboard(dashboard_id); - }, - ); - - editDashboard(); - - // Make sure filter can be connected to the custom column using UI, rather than using API. - cy.findByTestId("edit-dashboard-parameters-widget-container") - .find(".Icon-gear") - .click(); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Column to filter on") - .parent() - .parent() - .within(() => { - cy.findByText("Select…").click(); - }); - - popover().within(() => { - cy.findByText("CC Date").click(); - }); - - saveDashboard(); - }); - - it("should be able to apply dashboard filter to a custom column (metabase#17775)", () => { - filterWidget().click(); - - setQuarterAndYear({ quarter: "Q1", year: "2023" }); - - cy.findAllByText("44.43").should("have.length", 2); - cy.findAllByText("March 26, 2023, 8:45 AM").should("have.length", 2); - }); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/19494-wrong-default-value-multiple-cards-same-question.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/19494-wrong-default-value-multiple-cards-same-question.cy.spec.js deleted file mode 100644 index 2b6ecd87ece..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/19494-wrong-default-value-multiple-cards-same-question.cy.spec.js +++ /dev/null @@ -1,108 +0,0 @@ -import { - ORDERS_DASHBOARD_ID, - ORDERS_QUESTION_ID, -} from "e2e/support/cypress_sample_instance_data"; -import { - restore, - popover, - editDashboard, - saveDashboard, - visitDashboard, - updateDashboardCards, - undoToast, -} from "e2e/support/helpers"; - -const filter1 = { - name: "Card 1 Filter", - slug: "card1_filter", - id: "ab6f631", - type: "string/=", - sectionId: "string", -}; - -const filter2 = { - name: "Card 2 Filter", - slug: "card2_filter", - id: "a9801ade", - type: "string/=", - sectionId: "string", -}; - -describe("issue 19494", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - // Add two "Orders" questions to the existing "Orders in a dashboard" dashboard - updateDashboardCards({ - dashboard_id: ORDERS_DASHBOARD_ID, - cards: [ - { - card_id: ORDERS_QUESTION_ID, - row: 0, - col: 0, - size_x: 11, - size_y: 8, - }, - { - card_id: ORDERS_QUESTION_ID, - row: 0, - col: 8, - size_x: 11, - size_y: 8, - }, - ], - }); - - // Add two dashboard filters (not yet connected to any of the cards) - cy.request("PUT", `/api/dashboard/${ORDERS_DASHBOARD_ID}`, { - parameters: [filter1, filter2], - }); - }); - - it("should correctly apply different filters with default values to all cards of the same question (metabase#19494)", () => { - // Instead of using the API to connect filters to the cards, - // let's use UI to replicate user experience as closely as possible - visitDashboard(ORDERS_DASHBOARD_ID); - - editDashboard(); - - connectFilterToCard({ filterName: "Card 1 Filter", cardPosition: 0 }); - setDefaultFilter("Doohickey"); - undoToast().findByText("Undo auto-connection").click(); - - connectFilterToCard({ filterName: "Card 2 Filter", cardPosition: -1 }); - setDefaultFilter("Gizmo"); - undoToast().findByText("Undo auto-connection").click(); - - saveDashboard(); - - checkAppliedFilter("Card 1 Filter", "Doohickey"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("148.23"); - - checkAppliedFilter("Card 2 Filter", "Gizmo"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("110.93"); - }); -}); - -function connectFilterToCard({ filterName, cardPosition }) { - cy.findByText(filterName).find(".Icon-gear").click(); - - cy.findAllByText("Select…").eq(cardPosition).click(); - - popover().contains("Category").click(); -} - -function setDefaultFilter(value) { - cy.findByText("No default").click(); - - popover().contains(value).click(); - - cy.button("Add filter").click(); -} - -function checkAppliedFilter(name, value) { - cy.findByText(name).closest("fieldset").contains(value); -} diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/20656-dashboard-breaks-for-user-without-card-permissions.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/20656-dashboard-breaks-for-user-without-card-permissions.cy.spec.js deleted file mode 100644 index d8c29c6f61b..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/20656-dashboard-breaks-for-user-without-card-permissions.cy.spec.js +++ /dev/null @@ -1,83 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { ADMIN_PERSONAL_COLLECTION_ID } from "e2e/support/cypress_sample_instance_data"; -import { - restore, - filterWidget, - visitDashboard, - editDashboard, - getDashboardCard, -} from "e2e/support/helpers"; - -const { PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE; - -const filter = { - name: "ID", - slug: "id", - id: "11d79abe", - type: "id", - sectionId: "id", -}; - -const questionDetails = { - query: { "source-table": PRODUCTS_ID, limit: 2 }, - // Admin's personal collection is always the first one (hence, the id 1) - collection_id: ADMIN_PERSONAL_COLLECTION_ID, -}; - -const dashboardDetails = { - parameters: [filter], -}; - -describe("issue 20656", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should allow a user to visit a dashboard even without a permission to see the dashboard card (metabase#20656, metabase#24536)", () => { - cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( - ({ body: { id, card_id, dashboard_id } }) => { - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - dashcards: [ - { - id, - card_id, - row: 0, - col: 0, - size_x: 24, - size_y: 10, - parameter_mappings: [ - { - parameter_id: filter.id, - card_id, - target: ["dimension", ["field", PRODUCTS.ID, null]], - }, - ], - }, - ], - }); - - cy.signInAsNormalUser(); - - visitDashboard(dashboard_id); - }, - ); - - // Make sure the filter widget is there - filterWidget(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Sorry, you don't have permission to see this card."); - - // Trying to edit the filter should not show mapping fields and shouldn't break frontend (metabase#24536) - editDashboard(); - - cy.findByTestId("edit-dashboard-parameters-widget-container") - .find(".Icon-gear") - .click(); - - getDashboardCard().within(() => { - cy.findByText("Column to filter on"); - cy.icon("key"); - }); - }); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/21528-dashboard-id-filter-map-to-a-wrong-field.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/21528-dashboard-id-filter-map-to-a-wrong-field.cy.spec.js deleted file mode 100644 index 263e919a490..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/21528-dashboard-id-filter-map-to-a-wrong-field.cy.spec.js +++ /dev/null @@ -1,136 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - addOrUpdateDashboardCard, - appBar, - dashboardParametersContainer, - navigationSidebar, - openNavigationSidebar, - popover, - restore, -} from "e2e/support/helpers"; - -const { ORDERS, PRODUCTS } = SAMPLE_DATABASE; - -const NATIVE_QUESTION_DETAILS = { - name: "Orders with Product ID filter", - native: { - query: "select * from ORDERS where {{product_id}}", - "template-tags": { - product_id: { - type: "dimension", - name: "product_id", - id: "56708d23-6f01-42b7-98ed-f930295d31b9", - "display-name": "Product ID", - dimension: ["field", ORDERS.PRODUCT_ID, null], - "widget-type": "id", - }, - }, - }, - parameters: [ - { - id: "56708d23-6f01-42b7-98ed-f930295d31b9", - type: "id", - target: ["dimension", ["template-tag", "product_id"]], - name: "Product ID", - slug: "product_id", - }, - ], -}; - -const DASHBOARD_DETAILS = { - name: "Dashboard with ID filter", - parameters: [ - { - id: "9f85cd3d", - name: "Product ID", - sectionId: "id", - slug: "product_id", - type: "id", - }, - ], -}; - -describe("issue 21528", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - cy.createNativeQuestion(NATIVE_QUESTION_DETAILS, { - wrapId: true, - idAlias: "questionId", - }); - - cy.log( - "set Orders.Product_ID `Filtering on this field`: `A list of all values`", - ); - cy.request("PUT", `/api/field/${ORDERS.PRODUCT_ID}`, { - has_field_values: "list", - }); - - cy.log("set Orders.Product_ID `Display values`: `Use foreign key > Title`"); - cy.request("POST", `/api/field/${ORDERS.PRODUCT_ID}/dimension`, { - type: "external", - name: "Product ID", - human_readable_field_id: PRODUCTS.TITLE, - }); - - cy.createDashboard(DASHBOARD_DETAILS).then( - ({ body: { id: dashboardId } }) => { - cy.wrap(dashboardId).as("dashboardId"); - }, - ); - - cy.then(function () { - addOrUpdateDashboardCard({ - card_id: this.questionId, - dashboard_id: this.dashboardId, - card: { - parameter_mappings: [ - { - card_id: this.questionId, - parameter_id: "9f85cd3d", - target: ["dimension", ["template-tag", "product_id"]], - }, - ], - }, - }); - }); - }); - - it("should show dashboard ID filter values when mapped to a native question with a foreign key field filter", () => { - cy.get("@questionId").then(questionId => { - cy.visit(`/question/${questionId}`); - }); - - cy.findByTestId("native-query-top-bar").findByText("Product ID").click(); - popover().contains("Rustic Paper Wallet - 1").should("be.visible"); - - // Navigating to another page via JavaScript is faster than using `cy.visit("/dashboard/:dashboard-id")` to load the whole page again. - openNavigationSidebar(); - navigationSidebar().findByText("Our analytics").click(); - cy.findByRole("main").findByText(DASHBOARD_DETAILS.name).click(); - - dashboardParametersContainer().findByText("Product ID").click(); - popover().contains("Aerodynamic Bronze Hat - 144").should("be.visible"); - - cy.log("The following scenario breaks on 46"); - // Navigating to another page via JavaScript is faster than using `cy.visit("/admin/datamodel")` to load the whole page again. - appBar().icon("gear").click(); - popover().findByText("Admin settings").click(); - appBar().findByText("Table Metadata").click(); - cy.findByRole("main") - .findByText( - "Select any table to see its schema and add or edit metadata.", - ) - .should("be.visible"); - cy.findByRole("navigation").findByText("Exit admin").click(); - - openNavigationSidebar(); - navigationSidebar().findByText("Our analytics").click(); - cy.findByRole("main").findByText(DASHBOARD_DETAILS.name).click(); - - // Assert that the dashboard ID filter values is still showing correctly again. - dashboardParametersContainer().findByText("Product ID").click(); - popover().contains("Aerodynamic Bronze Hat - 144").should("be.visible"); - }); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/22482-round-relative-ranges.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/22482-round-relative-ranges.cy.spec.js deleted file mode 100644 index 1be36245e74..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/22482-round-relative-ranges.cy.spec.js +++ /dev/null @@ -1,53 +0,0 @@ -import moment from "moment-timezone"; // eslint-disable-line no-restricted-imports -- deprecated usage - -import { ORDERS_DASHBOARD_ID } from "e2e/support/cypress_sample_instance_data"; -import { - restore, - popover, - filterWidget, - editDashboard, - saveDashboard, - setFilter, - visitDashboard, -} from "e2e/support/helpers"; - -describe("issue 22482", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - visitDashboard(ORDERS_DASHBOARD_ID); - - editDashboard(); - setFilter("Time", "All Options"); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Select…").click(); - popover().contains("Created At").eq(0).click(); - - saveDashboard(); - - filterWidget().click(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Relative dates...").click(); - }); - - it("should round relative date range (metabase#22482)", () => { - cy.findByTestId("relative-datetime-value").clear().type(15); - cy.findByTestId("relative-datetime-unit").click(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("months").click(); - - const expectedRange = getFormattedRange( - moment().startOf("month").add(-15, "month"), - moment().add(-1, "month").endOf("month"), - ); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText(expectedRange); - }); -}); - -function getFormattedRange(start, end) { - return `${start.format("MMM D, YYYY")} - ${end.format("MMM D, YYYY")}`; -} diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/22788-flter-cc-dropped-on-second-edit.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/22788-flter-cc-dropped-on-second-edit.cy.spec.js deleted file mode 100644 index e385cdf27b1..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/22788-flter-cc-dropped-on-second-edit.cy.spec.js +++ /dev/null @@ -1,111 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - restore, - visitDashboard, - filterWidget, - editDashboard, - saveDashboard, - sidebar, - getDashboardCard, -} from "e2e/support/helpers"; - -const { PRODUCTS_ID, PRODUCTS } = SAMPLE_DATABASE; - -const ccName = "Custom Category"; -const ccDisplayName = "Product.Custom Category"; - -const questionDetails = { - name: "22788", - query: { - "source-table": PRODUCTS_ID, - expressions: { [ccName]: ["field", PRODUCTS.CATEGORY, null] }, - limit: 5, - }, -}; - -const filter = { - name: "Text", - slug: "text", - id: "a7565817", - type: "string/=", - sectionId: "string", -}; - -const dashboardDetails = { - name: "22788D", - parameters: [filter], -}; - -describe("issue 22788", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( - ({ body: { dashboard_id, card_id, id } }) => { - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - dashcards: [ - { - id, - card_id, - row: 0, - col: 0, - size_x: 11, - size_y: 6, - parameter_mappings: [ - { - parameter_id: filter.id, - card_id, - target: ["dimension", ["expression", ccName, null]], - }, - ], - }, - ], - }); - - visitDashboard(dashboard_id); - }, - ); - }); - - it("should not drop filter connected to a custom column on a second dashboard edit (metabase#22788)", () => { - addFilterAndAssert(); - - editDashboard(); - - openFilterSettings(); - - // Make sure the filter is still connected to the custom column - - getDashboardCard().within(() => { - cy.findByText("Column to filter on"); - cy.findByText(ccDisplayName); - }); - - // need to actually change the dashboard to test a real save - sidebar().within(() => { - cy.findByDisplayValue("Text").clear().type("my filter text"); - cy.button("Done").click(); - }); - - saveDashboard(); - - cy.findAllByText("Gizmo"); - cy.findAllByText("Doohickey").should("not.exist"); - }); -}); - -function addFilterAndAssert() { - filterWidget().click(); - cy.findByPlaceholderText("Enter some text").type("Gizmo{enter}"); - cy.button("Add filter").click(); - - cy.findAllByText("Gizmo"); - cy.findAllByText("Doohickey").should("not.exist"); -} - -function openFilterSettings() { - cy.findByTestId("edit-dashboard-parameters-widget-container") - .find(".Icon-gear") - .click(); -} diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/24235-exclude-all-date-options.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/24235-exclude-all-date-options.cy.spec.js deleted file mode 100644 index abbc7ac5664..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/24235-exclude-all-date-options.cy.spec.js +++ /dev/null @@ -1,87 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - popover, - restore, - visitDashboard, - filterWidget, -} from "e2e/support/helpers"; - -const { PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE; - -const questionDetails = { - query: { "source-table": PRODUCTS_ID, limit: 5 }, -}; - -const parameter = { - id: "727b06c1", - name: "Date Filter", - sectionId: "date", - slug: "date_filter", - type: "date/all-options", -}; - -const parameterTarget = [ - "dimension", - ["field", PRODUCTS.CREATED_AT, { "temporal-unit": "month" }], -]; - -const dashboardDetails = { parameters: [parameter] }; - -describe("issue 24235", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - cy.intercept("POST", "/api/dashboard/**/query").as("getCardQuery"); - }); - - it("should remove filter when all exclude options are selected (metabase#24235)", () => { - cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( - ({ body: { id, card_id, dashboard_id } }) => { - mapParameterToDashboardCard({ id, card_id, dashboard_id }); - visitDashboard(dashboard_id); - }, - ); - - filterWidget().contains(parameter.name).click(); - popover().within(() => { - cy.findByText("Exclude...").click(); - cy.findByText("Days of the week...").click(); - cy.findByText("Select none...").click(); - cy.findByText("Add filter").click(); - }); - - filterWidget().click(); - popover().within(() => { - cy.findByText("Select all...").click(); - cy.findByText("Update filter").click(); - }); - - cy.wait("@getCardQuery"); - cy.get("[data-testid=cell-data]").should( - "contain", - "Price, Schultz and Daniel", - ); - }); -}); - -const mapParameterToDashboardCard = ({ id, card_id, dashboard_id }) => { - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - dashcards: [ - { - id, - card_id, - row: 0, - col: 0, - size_x: 24, - size_y: 10, - parameter_mappings: [ - { - card_id, - parameter_id: parameter.id, - target: parameterTarget, - }, - ], - }, - ], - }); -}; diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/24500-gracefully-deal-with-corrupted-filter.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/24500-gracefully-deal-with-corrupted-filter.cy.spec.js deleted file mode 100644 index 61a307e2e59..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/24500-gracefully-deal-with-corrupted-filter.cy.spec.js +++ /dev/null @@ -1,139 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - restore, - filterWidget, - visitDashboard, - popover, - editDashboard, - saveDashboard, -} from "e2e/support/helpers"; - -const { PEOPLE, PEOPLE_ID } = SAMPLE_DATABASE; - -const listFilter = { - name: "List", - slug: "list", - id: "6fe14171", - type: "string/=", - sectionId: "string", -}; - -const searchFilter = { - name: "Search", - slug: "search", - id: "4db4913a", - type: "string/=", - sectionId: "string", -}; - -// This filter is corrupted because it's missing `name` and `slug` -const corruptedFilter = { - name: "", - slug: "", - id: "af72ce9c", - type: "string/=", - sectionId: "string", -}; - -const parameters = [listFilter, searchFilter, corruptedFilter]; - -const questionDetails = { - name: "15279", - query: { "source-table": PEOPLE_ID }, -}; - -const dashboardDetails = { parameters }; - -describe("issues 15279 and 24500", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("corrupted dashboard filter should still appear in the UI without breaking other filters (metabase#15279, metabase#24500)", () => { - cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( - ({ body: { id, card_id, dashboard_id } }) => { - // Connect filters to the question - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - dashcards: [ - { - id, - card_id, - row: 0, - col: 0, - size_x: 24, - size_y: 8, - series: [], - visualization_settings: {}, - parameter_mappings: [ - { - parameter_id: listFilter.id, - card_id, - target: ["dimension", ["field", PEOPLE.SOURCE, null]], - }, - { - parameter_id: searchFilter.id, - card_id, - target: ["dimension", ["field", PEOPLE.NAME, null]], - }, - ], - }, - ], - }); - - visitDashboard(dashboard_id); - }, - ); - - cy.intercept("GET", "/api/dashboard/*/params/*/values").as("values"); - - // Check that list filter works - filterWidget().contains("List").click(); - cy.wait("@values"); - - cy.findByPlaceholderText("Search the list").type("Or").blur(); - popover().contains("Organic").click(); - cy.button("Add filter").click(); - - cy.findByTestId("dashcard-container") - .should("contain", "Lora Cronin") - .and("contain", "Dagmar Fay"); - - // Check that the search filter works - filterWidget().contains("Search").click(); - cy.findByPlaceholderText("Search by Name").type("Lora Cronin"); - cy.button("Add filter").click(); - - cy.findByTestId("dashcard-container") - .should("contain", "Lora Cronin") - .and("not.contain", "Dagmar Fay"); - - // The corrupted filter is now present in the UI, but it doesn't work (as expected) - // People can now easily remove it - editDashboard(); - cy.findByTestId("edit-dashboard-parameters-widget-container") - .findByText("unnamed") - .icon("gear") - .click(); - cy.findByRole("button", { name: "Remove" }).click(); - saveDashboard(); - - // Check the list filter again - filterWidget().contains("List").parent().click(); - cy.wait("@values"); - - cy.log("Check that the search filter works"); - - // reset filter value - filterWidget().contains("Search").parent().icon("close").click(); - - filterWidget().contains("Search").click(); - - cy.findByPlaceholderText("Search by Name").type("Lora Cronin"); - cy.button("Add filter").click(); - - cy.findByTestId("dashcard-container") - .should("contain", "Lora Cronin") - .and("not.contain", "Dagmar Fay"); - }); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/25322-loading-list-values.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/25322-loading-list-values.cy.spec.js deleted file mode 100644 index d0622244f94..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/25322-loading-list-values.cy.spec.js +++ /dev/null @@ -1,79 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - addOrUpdateDashboardCard, - popover, - restore, - visitDashboard, -} from "e2e/support/helpers"; - -const { PEOPLE, PEOPLE_ID } = SAMPLE_DATABASE; - -const parameterDetails = { - name: "Location", - slug: "location", - id: "f8ec7c71", - type: "string/=", - sectionId: "location", -}; - -const questionDetails = { - name: "People", - query: { "source-table": PEOPLE_ID }, -}; - -const dashboardDetails = { - name: "Dashboard", - parameters: [parameterDetails], -}; - -describe("issue 25322", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should show a loader when loading field values (metabase#25322)", () => { - createDashboard().then(({ dashboard_id }) => { - visitDashboard(dashboard_id); - throttleFieldValuesRequest(dashboard_id); - }); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText(parameterDetails.name).click(); - popover().findByTestId("loading-spinner").should("exist"); - }); -}); - -const createDashboard = () => { - return cy - .createQuestion(questionDetails) - .then(({ body: { id: card_id } }) => { - cy.createDashboard(dashboardDetails).then( - ({ body: { id: dashboard_id } }) => { - addOrUpdateDashboardCard({ - dashboard_id, - card_id, - card: { - parameter_mappings: [ - { - card_id, - parameter_id: parameterDetails.id, - target: ["dimension", ["field", PEOPLE.STATE, null]], - }, - ], - }, - }).then(() => ({ dashboard_id })); - }, - ); - }); -}; - -const throttleFieldValuesRequest = dashboard_id => { - const matcher = { - method: "GET", - url: `/api/dashboard/${dashboard_id}/params/${parameterDetails.id}/values`, - middleware: true, - }; - - cy.intercept(matcher, req => req.on("response", res => res.setDelay(100))); -}; diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/25355-multi-series-parameter-mapping.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/25355-multi-series-parameter-mapping.cy.spec.js deleted file mode 100644 index 2b367f35f83..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/25355-multi-series-parameter-mapping.cy.spec.js +++ /dev/null @@ -1,96 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - editDashboard, - popover, - restore, - visitDashboard, -} from "e2e/support/helpers"; - -const { ORDERS, ORDERS_ID } = SAMPLE_DATABASE; - -const question1Details = { - name: "Q1", - display: "line", - query: { - "source-table": ORDERS_ID, - aggregation: [["count"]], - breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }]], - }, - visualization_settings: { - "graph.metrics": ["count"], - "graph.dimensions": ["CREATED_AT"], - }, -}; - -const question2Details = { - name: "Q2", - display: "line", - query: { - "source-table": ORDERS_ID, - aggregation: [["count"], ["avg", ["field", ORDERS.TOTAL, null]]], - breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }]], - }, - visualization_settings: { - "graph.metrics": ["avg"], - "graph.dimensions": ["CREATED_AT"], - }, -}; - -const parameterDetails = { - name: "Date Filter", - slug: "date_filter", - id: "888188ad", - type: "date/all-options", - sectionId: "date", -}; - -const dashboardDetails = { - name: "25248", - parameters: [parameterDetails], -}; - -describe("issue 25248", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should allow mapping parameters to combined cards individually (metabase#25248)", () => { - createDashboard(); - editDashboard(); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText(parameterDetails.name).click(); - cy.findAllByText("Select…").first().click(); - popover().findAllByText("Created At").first().click(); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Order.Created At").should("be.visible"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Select…").should("be.visible"); - }); -}); - -const createDashboard = () => { - cy.createQuestionAndDashboard({ - questionDetails: question1Details, - dashboardDetails, - }).then(({ body: { id, card_id, dashboard_id } }) => { - cy.createQuestion(question2Details).then(({ body: { id: card_2_id } }) => { - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - dashcards: [ - { - id, - card_id, - series: [{ id: card_2_id }], - row: 0, - col: 0, - size_x: 16, - size_y: 8, - }, - ], - }); - }); - visitDashboard(dashboard_id); - }); -}; diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/25374-comma-separated-values-not-passed-to-question.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/25374-comma-separated-values-not-passed-to-question.cy.spec.js deleted file mode 100644 index 9aa53e7310e..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/25374-comma-separated-values-not-passed-to-question.cy.spec.js +++ /dev/null @@ -1,114 +0,0 @@ -import { restore, visitDashboard, filterWidget } from "e2e/support/helpers"; - -const questionDetails = { - name: "25374", - native: { - "template-tags": { - num: { - id: "f7672b4d-1e84-1fa8-bf02-b5e584cd4535", - name: "num", - "display-name": "Num", - type: "number", - default: null, - }, - }, - query: "select count(*) from orders where id in ({{num}})", - }, - parameters: [ - { - id: "f7672b4d-1e84-1fa8-bf02-b5e584cd4535", - type: "number/=", - target: ["variable", ["template-tag", "num"]], - name: "Num", - slug: "num", - default: null, - }, - ], -}; - -const filterDetails = { - name: "Equal to", - slug: "equal_to", - id: "10c0d4ba", - type: "number/=", - sectionId: "number", -}; - -const dashboardDetails = { - name: "25374D", - parameters: [filterDetails], -}; - -describe("issue 25374", () => { - beforeEach(() => { - cy.intercept("POST", "/api/card/*/query").as("cardQuery"); - - restore(); - cy.signInAsAdmin(); - - cy.createNativeQuestionAndDashboard({ - questionDetails, - dashboardDetails, - }).then(({ body: { id, card_id, dashboard_id } }) => { - // Connect filter to the card - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - dashcards: [ - { - id, - card_id, - row: 0, - col: 0, - size_x: 11, - size_y: 6, - parameter_mappings: [ - { - parameter_id: filterDetails.id, - card_id, - target: ["variable", ["template-tag", "num"]], - }, - ], - }, - ], - }); - - visitDashboard(dashboard_id); - - filterWidget().type("1,2,3{enter}"); - cy.findByDisplayValue("1,2,3"); - - cy.get(".CardVisualization") - .should("contain", "COUNT(*)") - .and("contain", "3"); - - cy.location("search").should("eq", "?equal_to=1%2C2%2C3"); - }); - }); - - it("should pass comma-separated values down to the connected question (metabase#25374-1)", () => { - // Drill-through and go to the question - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText(questionDetails.name).click(); - cy.wait("@cardQuery"); - - cy.get("[data-testid=cell-data]") - .should("contain", "COUNT(*)") - .and("contain", "3"); - - cy.location("search").should("eq", "?num=1%2C2%2C3"); - }); - - it("should retain comma-separated values on refresh (metabase#25374-2)", () => { - cy.reload(); - - // Make sure filter widget still has all the values - cy.findByDisplayValue("1,2,3"); - - // Make sure the result in the card is correct - cy.get(".CardVisualization") - .should("contain", "COUNT(*)") - .and("contain", "3"); - - // Make sure URL search params are correct - cy.location("search").should("eq", "?equal_to=1%2C2%2C3"); - }); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/25908-contains-filter-case-sensitivity.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/25908-contains-filter-case-sensitivity.cy.spec.js deleted file mode 100644 index 5bfaf4981c0..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/25908-contains-filter-case-sensitivity.cy.spec.js +++ /dev/null @@ -1,81 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { restore } from "e2e/support/helpers"; - -const { PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE; - -const questionDetails = { - name: "25908", - query: { - "source-table": PRODUCTS_ID, - }, -}; - -const dashboardFilter = { - name: "Text contains", - slug: "text_contains", - id: "28c6ada9", - type: "string/contains", - sectionId: "string", -}; - -const dashboardDetails = { - parameters: [dashboardFilter], -}; - -const CASE_INSENSITIVE_ROWS = 30; - -describe("issue 25908", () => { - beforeEach(() => { - cy.intercept("POST", "/api/dataset").as("dataset"); - - restore(); - cy.signInAsAdmin(); - - cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( - ({ body: { id, card_id, dashboard_id } }) => { - cy.intercept( - "POST", - `/api/dashboard/${dashboard_id}/dashcard/${id}/card/${card_id}/query`, - ).as("dashcardQuery"); - - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - dashcards: [ - { - id, - card_id, - row: 0, - col: 0, - size_x: 17, - size_y: 8, - series: [], - visualization_settings: {}, - parameter_mappings: [ - { - parameter_id: dashboardFilter.id, - card_id, - target: ["dimension", ["field", PRODUCTS.TITLE, null]], - }, - ], - }, - ], - }); - - // Note the capital first letter - cy.visit(`/dashboard/${dashboard_id}?text_contains=Li`); - cy.wait("@dashcardQuery"); - cy.contains(new RegExp(`^Rows 1-\\d+ of ${CASE_INSENSITIVE_ROWS}$`)); - }, - ); - }); - - it("`contains` dashboard filter should respect case insensitivity on a title-drill-through (metabase#25908)", () => { - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText(questionDetails.name).click(); - cy.wait("@dataset"); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Title contains Li"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText(`Showing ${CASE_INSENSITIVE_ROWS} rows`); - }); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/26230-dashboard-sticky-filter-incorrectly-positioned.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/26230-dashboard-sticky-filter-incorrectly-positioned.cy.spec.js deleted file mode 100644 index c8adf3cb8c8..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/26230-dashboard-sticky-filter-incorrectly-positioned.cy.spec.js +++ /dev/null @@ -1,101 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { ORDERS_QUESTION_ID } from "e2e/support/cypress_sample_instance_data"; -import { restore, visitDashboard } from "e2e/support/helpers"; -import { createMockDashboardCard } from "metabase-types/api/mocks"; - -const { ORDERS, PEOPLE } = SAMPLE_DATABASE; - -describe("issue 26230", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - prepareAndVisitDashboards(); - }); - - it("should not preserve the sticky filter behavior when navigating to the second dashboard (metabase#26230)", () => { - cy.findByRole("main").scrollTo("bottom"); // This line is essential for the reproduction! - - cy.button("Toggle sidebar").click(); - cy.findByRole("main") - .findByDisplayValue("dashboard with a tall card 2") - .should("not.be.visible"); - - cy.findByTestId("dashboard-parameters-widget-container").should( - "have.css", - "position", - "sticky", - ); - - cy.intercept("GET", "/api/dashboard/*").as("loadDashboard"); - cy.findByRole("listitem", { name: "dashboard with a tall card" }).click(); - cy.wait("@loadDashboard"); - }); -}); - -const FILTER_1 = { - id: "12345678", - name: "Text", - slug: "text", - type: "string/=", - sectionId: "string", -}; - -const FILTER_2 = { - id: "87654321", - name: "Text", - slug: "text", - type: "string/=", - sectionId: "string", -}; - -function prepareAndVisitDashboards() { - cy.createDashboard({ - name: "dashboard with a tall card", - parameters: [FILTER_1], - }).then(({ body: { id } }) => { - createDashCard(id, FILTER_1); - bookmarkDashboard(id); - }); - - cy.createDashboard({ - name: "dashboard with a tall card 2", - parameters: [FILTER_2], - }).then(({ body: { id } }) => { - createDashCard(id, FILTER_2); - bookmarkDashboard(id); - visitDashboard(id); - }); -} - -function bookmarkDashboard(dashboardId) { - cy.request("POST", `/api/bookmark/dashboard/${dashboardId}`); -} - -function createDashCard(dashboardId, mappedFilter) { - cy.request("PUT", `/api/dashboard/${dashboardId}`, { - dashcards: [ - createMockDashboardCard({ - id: -dashboardId, - dashboard_id: dashboardId, - size_x: 5, - size_y: 20, - card_id: ORDERS_QUESTION_ID, - parameter_mappings: [ - { - parameter_id: mappedFilter.id, - card_id: ORDERS_QUESTION_ID, - target: [ - "dimension", - [ - "field", - PEOPLE.NAME, - { "base-type": "type/Text", "source-field": ORDERS.USER_ID }, - ], - ], - }, - ], - }), - ], - }); -} diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/27356-navigation-between-two-dashboards.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/27356-navigation-between-two-dashboards.cy.spec.js deleted file mode 100644 index 9000d99706b..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/27356-navigation-between-two-dashboards.cy.spec.js +++ /dev/null @@ -1,63 +0,0 @@ -import { - restore, - openNavigationSidebar, - visitDashboard, -} from "e2e/support/helpers"; - -const ratingFilter = { - name: "Text", - slug: "text", - id: "5dfco74e", - type: "string/=", - sectionId: "string", -}; - -const paramDashboard = { - name: "Dashboard With Params", - parameters: [ratingFilter], -}; - -const regularDashboard = { - name: "Dashboard Without Params", -}; - -describe("issue 27356", () => { - beforeEach(() => { - cy.intercept("GET", "/api/dashboard/*").as("getDashboard"); - restore(); - cy.signInAsAdmin(); - - cy.createDashboard(paramDashboard).then(({ body: { id } }) => { - cy.request("POST", `/api/bookmark/dashboard/${id}`); - }); - - cy.createDashboard(regularDashboard).then(({ body: { id } }) => { - cy.request("POST", `/api/bookmark/dashboard/${id}`); - visitDashboard(id); - }); - }); - - it( - "should seamlessly move between dashboards with or without filters without triggering an error (metabase#27356)", - { tags: "@flaky" }, - () => { - openNavigationSidebar(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText(paramDashboard.name).click(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("This dashboard is looking empty."); - - openNavigationSidebar(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText(regularDashboard.name).click({ force: true }); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("This dashboard is looking empty."); - - openNavigationSidebar(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText(paramDashboard.name).click({ force: true }); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("This dashboard is looking empty."); - }, - ); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/27768-cc-filter-appears-disconnected.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/27768-cc-filter-appears-disconnected.cy.spec.js deleted file mode 100644 index 7dd414c7b85..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/27768-cc-filter-appears-disconnected.cy.spec.js +++ /dev/null @@ -1,76 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - restore, - popover, - visitDashboard, - editDashboard, - saveDashboard, - filterWidget, - getDashboardCard, -} from "e2e/support/helpers"; - -const { PRODUCTS_ID, PRODUCTS } = SAMPLE_DATABASE; - -const questionDetails = { - name: "27768", - query: { - "source-table": PRODUCTS_ID, - limit: 5, - expressions: { CCategory: ["field", PRODUCTS.CATEGORY, null] }, - }, -}; - -const filter = { - name: "Cat", - slug: "cat", - id: "b3b436dd", - type: "string/=", - sectionId: "string", -}; - -describe("issue 27768", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - cy.createQuestionAndDashboard({ questionDetails }).then( - ({ body: { dashboard_id } }) => { - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - parameters: [filter], - }); - - visitDashboard(dashboard_id, { queryParams: { cat: "Gizmo" } }); - }, - ); - }); - - it("filter connected to custom column should visually indicate it is connected (metabase#27768)", () => { - // We need to manually connect the filter to the custom column using the UI, - // but when we fix the issue, it should be safe to do this via API - editDashboard(); - getFilterOptions(filter.name); - - getDashboardCard().findByText("Select…").click(); - popover().contains("CCategory").click(); - saveDashboard(); - - filterWidget().click(); - cy.findByPlaceholderText("Enter some text").type("Gizmo").blur(); - cy.button("Add filter").click(); - - cy.findAllByText("Doohickey").should("not.exist"); - - // Make sure the filter is still connected to the custom column - editDashboard(); - getFilterOptions(filter.name); - - getDashboardCard().within(() => { - cy.findByText("Select…").should("not.exist"); - cy.contains("Product.CCategory"); - }); - }); -}); - -function getFilterOptions(filterName) { - cy.findByText(filterName).find(".Icon-gear").click(); -} diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/29347-remapped-field-values.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/29347-remapped-field-values.cy.spec.js deleted file mode 100644 index 0aa9e806925..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/29347-remapped-field-values.cy.spec.js +++ /dev/null @@ -1,257 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - filterWidget, - getDashboardCard, - popover, - restore, - visitDashboard, - visitEmbeddedPage, - visitPublicDashboard, -} from "e2e/support/helpers"; - -const { ORDERS, ORDERS_ID } = SAMPLE_DATABASE; - -const filterValue = 100; - -const filterDetails = { - name: "Text", - slug: "text", - id: "11d79abe", - type: "string/=", - sectionId: "string", -}; - -const questionDetails = { - query: { - "source-table": ORDERS_ID, - }, -}; - -const editableDashboardDetails = { - parameters: [filterDetails], - enable_embedding: true, - embedding_params: { - [filterDetails.slug]: "enabled", - }, -}; - -const lockedDashboardDetails = { - parameters: [filterDetails], - enable_embedding: true, - embedding_params: { - [filterDetails.slug]: "locked", - }, -}; - -describe("issues 29347, 29346", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - addFieldRemapping(ORDERS.QUANTITY); - }); - - describe("regular dashboards", () => { - beforeEach(() => { - cy.intercept("GET", "/api/dashboard/*").as("dashboard"); - cy.intercept("POST", "/api/dashboard/**/card/*/query").as("cardQuery"); - }); - - it("should be able to filter on remapped values (metabase#29347, metabase#29346)", () => { - createDashboard(); - visitDashboard("@dashboardId"); - cy.wait("@dashboard"); - cy.wait("@cardQuery"); - - filterOnRemappedValues(filterValue); - cy.wait("@cardQuery"); - - verifyRemappedValues(filterValue); - }); - - it("should be able to filter on remapped values in the url (metabase#29347, metabase#29346)", () => { - createDashboard(); - visitDashboard("@dashboardId", { - params: { [filterDetails.slug]: filterValue }, - }); - - cy.wait("@dashboard"); - cy.wait("@cardQuery"); - - verifyRemappedValues(filterValue); - }); - }); - - describe("embedded dashboards", () => { - beforeEach(() => { - cy.intercept("GET", "/api/embed/dashboard/*").as("dashboard"); - cy.intercept("GET", "/api/embed/dashboard/**/card/*").as("cardQuery"); - }); - - it("should be able to filter on remapped values (metabase#29347, metabase#29346)", () => { - createDashboard(); - cy.get("@dashboardId").then(dashboardId => - visitEmbeddedPage({ - resource: { dashboard: dashboardId }, - params: {}, - }), - ); - cy.wait("@dashboard"); - cy.wait("@cardQuery"); - - filterOnRemappedValues(filterValue); - cy.wait("@cardQuery"); - - verifyRemappedValues(filterValue); - }); - - it("should be able to filter on remapped values in the token (metabase#29347, metabase#29346)", () => { - createDashboard({ dashboardDetails: lockedDashboardDetails }); - cy.get("@dashboardId").then(dashboardId => { - visitEmbeddedPage({ - resource: { dashboard: dashboardId }, - params: { - [filterDetails.slug]: filterValue, - }, - }); - }); - cy.wait("@dashboard"); - cy.wait("@cardQuery"); - - verifyRemappedCardValues(filterValue); - }); - - it("should be able to filter on remapped values in the url (metabase#29347, metabase#29346)", () => { - createDashboard(); - cy.get("@dashboardId").then(dashboardId => { - visitEmbeddedPage( - { - resource: { dashboard: dashboardId }, - params: {}, - }, - { - setFilters: { [filterDetails.slug]: filterValue }, - }, - ); - }); - cy.wait("@dashboard"); - cy.wait("@cardQuery"); - - verifyRemappedValues(filterValue); - }); - }); - - describe("public dashboards", () => { - beforeEach(() => { - cy.intercept("GET", "/api/public/dashboard/*").as("dashboard"); - cy.intercept("GET", "/api/public/dashboard/**/card/*").as("cardQuery"); - }); - - it("should be able to filter on remapped values (metabase#29347, metabase#29346)", () => { - createDashboard(); - cy.get("@dashboardId").then(dashboardId => - visitPublicDashboard(dashboardId), - ); - cy.wait("@dashboard"); - cy.wait("@cardQuery"); - - filterOnRemappedValues(filterValue); - cy.wait("@cardQuery"); - - verifyRemappedValues(filterValue); - }); - - it("should be able to filter on remapped values in the url (metabase#29347, metabase#29346)", () => { - createDashboard(); - cy.get("@dashboardId").then(dashboardId => { - visitPublicDashboard(dashboardId, { - params: { [filterDetails.slug]: filterValue }, - }); - }); - cy.wait("@dashboard"); - cy.wait("@cardQuery"); - - verifyRemappedValues(filterValue); - }); - }); -}); - -const getRemappedValue = fieldValue => { - return `N${fieldValue}`; -}; - -const addFieldRemapping = fieldId => { - cy.request("PUT", `/api/field/${fieldId}`, { - semantic_type: "type/Category", - }); - - cy.request("POST", `/api/field/${fieldId}/dimension`, { - name: "Quantity", - type: "internal", - }); - - cy.request("GET", `/api/field/${fieldId}/values`).then( - ({ body: { values } }) => { - cy.request("POST", `/api/field/${fieldId}/values`, { - values: values.map(([value]) => [value, getRemappedValue(value)]), - }); - }, - ); -}; - -const createDashboard = ({ - dashboardDetails = editableDashboardDetails, -} = {}) => { - cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( - ({ body: { id, card_id, dashboard_id } }) => { - cy.request("PUT", `/api/dashboard/${dashboard_id}`, { - dashcards: [ - { - id, - card_id, - row: 0, - col: 0, - size_x: 24, - size_y: 10, - parameter_mappings: [ - { - parameter_id: filterDetails.id, - card_id, - target: ["dimension", ["field", ORDERS.QUANTITY, null]], - }, - ], - }, - ], - }); - - cy.wrap(dashboard_id).as("dashboardId"); - }, - ); -}; - -const filterOnRemappedValues = fieldValue => { - filterWidget().within(() => { - cy.findByText(filterDetails.name).click(); - }); - - popover().within(() => { - cy.findByText(getRemappedValue(fieldValue)).click(); - cy.button("Add filter").click(); - }); -}; - -const verifyRemappedValues = fieldValue => { - verifyRemappedFilterValues(filterValue); - verifyRemappedCardValues(fieldValue); -}; - -const verifyRemappedFilterValues = fieldValue => { - filterWidget().within(() => { - cy.findByText(getRemappedValue(fieldValue)).should("be.visible"); - }); -}; - -const verifyRemappedCardValues = fieldValue => { - getDashboardCard().within(() => { - cy.findAllByText(getRemappedValue(fieldValue)).should("have.length", 2); - }); -}; diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/31662-between-filter-default-value.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/31662-between-filter-default-value.cy.spec.js deleted file mode 100644 index 68d31baf7cb..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/31662-between-filter-default-value.cy.spec.js +++ /dev/null @@ -1,42 +0,0 @@ -import { editDashboard, popover, restore, sidebar } from "e2e/support/helpers"; - -const parameterDetails = { - name: "Between", - slug: "between", - id: "b6ed2d71", - type: "number/between", - sectionId: "number", - default: [3, 5], -}; - -const dashboardDetails = { - name: "Dashboard", - parameters: [parameterDetails], -}; - -describe("issue 31662", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - cy.intercept("/api/dashboard/*").as("dashboard"); - }); - - it("should allow setting default values for a not connected between filter (metabase#31662)", () => { - cy.createDashboard(dashboardDetails).then( - ({ body: { id: dashboardId } }) => { - cy.visit(`dashboard/${dashboardId}?between=10&between=20`); - cy.wait("@dashboard"); - }, - ); - cy.findByTestId("dashboard-empty-state").should("be.visible"); - editDashboard(); - cy.findByTestId("edit-dashboard-parameters-widget-container") - .findByText("Between") - .click(); - sidebar().findByText("2 selections").click(); - popover().within(() => { - cy.findByDisplayValue("3").should("be.visible"); - cy.findByDisplayValue("5").should("be.visible"); - }); - }); -}); diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/38245-negative-dashcard-id-switching-tabs.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/38245-negative-dashcard-id-switching-tabs.cy.spec.js deleted file mode 100644 index 087e18557c1..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/38245-negative-dashcard-id-switching-tabs.cy.spec.js +++ /dev/null @@ -1,91 +0,0 @@ -import { - editDashboard, - getDashboardCard, - goToTab, - openQuestionsSidebar, - restore, - selectDashboardFilter, - sidebar, - visitDashboard, -} from "e2e/support/helpers"; -import { createMockParameter } from "metabase-types/api/mocks"; - -const TAB_1 = { - id: 1, - name: "Tab 1", -}; - -const TAB_2 = { - id: 2, - name: "Tab 2", -}; - -const DASHBOARD_TEXT_FILTER = createMockParameter({ - id: "3", - name: "Text filter", - slug: "filter-text", - type: "string/contains", -}); - -describe("issue 38245", () => { - beforeEach(() => { - cy.intercept("POST", "/api/card/*/query").as("cardQuery"); - restore(); - cy.signInAsNormalUser(); - }); - - it("should not make a request to the server if the parameters are not saved (metabase#38245)", () => { - createDashboardWithTabs({ - tabs: [TAB_1, TAB_2], - parameters: [DASHBOARD_TEXT_FILTER], - dashcards: [], - }).then(dashboard => visitDashboard(dashboard.id)); - - editDashboard(); - openQuestionsSidebar(); - - sidebar().findByText("Orders").click(); - - cy.wait("@cardQuery"); - - mapDashCardToFilter( - getDashboardCard(), - DASHBOARD_TEXT_FILTER.name, - "Source", - ); - - goToTab(TAB_2.name); - goToTab(TAB_1.name); - - getDashboardCard().within(() => { - cy.findByText("Orders").should("exist"); - cy.findByText("Product ID").should("exist"); - cy.findByText(/(Problem|Error)/i).should("not.exist"); - }); - - cy.get("@cardQuery.all").should("have.length", 2); - cy.get("@cardQuery").should(({ response }) => { - expect(response.statusCode).not.to.eq(500); - }); - }); -}); - -function createDashboardWithTabs({ dashcards, tabs, ...dashboardDetails }) { - return cy.createDashboard(dashboardDetails).then(({ body: dashboard }) => { - cy.request("PUT", `/api/dashboard/${dashboard.id}`, { - ...dashboard, - dashcards, - tabs, - }).then(({ body: dashboard }) => cy.wrap(dashboard)); - }); -} - -function filterPanel() { - return cy.findByTestId("edit-dashboard-parameters-widget-container"); -} - -function mapDashCardToFilter(dashcardElement, filterName, columnName) { - filterPanel().findByText(filterName).click(); - selectDashboardFilter(dashcardElement, columnName); - sidebar().button("Done").click(); -} diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/43154-model-parameter-target.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/43154-model-parameter-target.cy.spec.js deleted file mode 100644 index 9a072885ad7..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/43154-model-parameter-target.cy.spec.js +++ /dev/null @@ -1,92 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - createQuestion, - editDashboard, - filterWidget, - getDashboardCard, - popover, - restore, - saveDashboard, - setFilter, - visitDashboard, -} from "e2e/support/helpers"; - -const { ORDERS_ID, ORDERS, PEOPLE_ID, PEOPLE } = SAMPLE_DATABASE; - -const modelDetails = { - name: "Model", - type: "model", - query: { - "source-table": ORDERS_ID, - joins: [ - { - fields: "all", - alias: "People - User", - condition: [ - "=", - ["field", ORDERS.USER_ID, { "base-type": "type/Integer" }], - [ - "field", - PEOPLE.ID, - { "base-type": "type/BigInteger", "join-alias": "People - User" }, - ], - ], - "source-table": PEOPLE_ID, - }, - ], - }, -}; - -const questionDetails = modelId => ({ - name: "Question", - type: "question", - query: { - "source-table": `card__${modelId}`, - }, -}); - -const questionWithAggregationDetails = modelId => ({ - name: "Question", - type: "question", - query: { - "source-table": `card__${modelId}`, - aggregation: [["count"]], - }, -}); - -describe("issue 43154", () => { - beforeEach(() => { - restore(); - cy.signInAsNormalUser(); - }); - - it("should be able to see field values with a model-based question (metabase#43154)", () => { - verifyNestedFilter(questionDetails); - }); - - it("should be able to see field values with a model-based question with aggregation (metabase#43154)", () => { - verifyNestedFilter(questionWithAggregationDetails); - }); -}); - -function verifyNestedFilter(questionDetails) { - createQuestion(modelDetails).then(({ body: model }) => { - cy.createDashboardWithQuestions({ - questions: [questionDetails(model.id)], - }).then(({ dashboard }) => { - visitDashboard(dashboard.id); - }); - }); - - editDashboard(); - setFilter("Text or Category", "Is"); - getDashboardCard().findByText("Select…").click(); - popover().findByText("People - User → Source").click(); - saveDashboard(); - - filterWidget().click(); - popover().within(() => { - cy.findByText("Twitter").click(); - cy.button("Add filter").click(); - }); -} diff --git a/e2e/test/scenarios/dashboard-filters/reproductions/8030-32444-reload-card-without-change.cy.spec.js b/e2e/test/scenarios/dashboard-filters/reproductions/8030-32444-reload-card-without-change.cy.spec.js deleted file mode 100644 index 348db975e75..00000000000 --- a/e2e/test/scenarios/dashboard-filters/reproductions/8030-32444-reload-card-without-change.cy.spec.js +++ /dev/null @@ -1,188 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - restore, - popover, - updateDashboardCards, - visitDashboard, - filterWidget, - editDashboard, - setFilter, - saveDashboard, - selectDashboardFilter, -} from "e2e/support/helpers"; - -const { ORDERS, ORDERS_ID, PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE; - -const filterDetails = { - name: "ID Column", - slug: "id", - id: "11d79abe", - type: "id", - sectionId: "id", -}; - -const question1Details = { - name: "Q1", - query: { "source-table": PRODUCTS_ID, limit: 2 }, -}; - -const question2Details = { - name: "Q2", - query: { "source-table": ORDERS_ID, limit: 2 }, -}; - -const questionWithFilter = { - name: "Question with Filter", - type: "query", - query: { - "source-table": ORDERS_ID, - limit: 2, - filter: [">", ["field", ORDERS.TOTAL, null], 100], - }, -}; - -const dashboardDetails = { - name: "Filters", - parameters: [filterDetails], -}; - -describe("issue 8030", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should not reload dashboard cards not connected to a filter (metabase#8030)", () => { - createQuestionsAndDashboard().then( - ({ dashboard_id, card1_id, card2_id }) => { - interceptRequests({ dashboard_id, card1_id, card2_id }); - setFilterMapping({ dashboard_id, card1_id, card2_id }).then(() => { - cy.visit(`/dashboard/${dashboard_id}`); - cy.wait("@getDashboard"); - cy.wait("@getCardQuery1"); - cy.wait("@getCardQuery2"); - - cy.findByText(filterDetails.name).click(); - popover().within(() => { - // the filter is connected only to the first card - cy.get("input").type("1{enter}"); - cy.findByText("Add filter").click(); - }); - cy.wait("@getCardQuery1"); - cy.get("@getCardQuery1.all").should("have.length", 2); - cy.get("@getCardQuery2.all").should("have.length", 1); - }); - }, - ); - }); -}); - -describe("issue 32444", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should not reload dashboard cards not connected to a filter (metabase#32444)", () => { - cy.createDashboardWithQuestions({ - questions: [question1Details, questionWithFilter], - }).then(({ dashboard }) => { - cy.intercept( - "POST", - `/api/dashboard/${dashboard.id}/dashcard/*/card/*/query`, - ).as("getCardQuery"); - - visitDashboard(dashboard.id); - editDashboard(dashboard.id); - - cy.get("@getCardQuery.all").should("have.length", 2); - - setFilter("Text or Category", "Is"); - selectDashboardFilter(cy.findAllByTestId("dashcard").first(), "Title"); - cy.findAllByTestId("dashcard") - .eq(1) - .findByLabelText("Disconnect") - .click(); - - saveDashboard(); - - cy.wait("@getCardQuery"); - cy.get("@getCardQuery.all").should("have.length", 4); - - addFilterValue("Aerodynamic Bronze Hat"); - - cy.wait("@getCardQuery"); - cy.get("@getCardQuery.all").should("have.length", 5); - }); - }); -}); - -const createQuestionsAndDashboard = () => { - return cy - .createQuestion(question1Details) - .then(({ body: { id: card1_id } }) => { - return cy - .createQuestion(question2Details) - .then(({ body: { id: card2_id } }) => { - return cy - .createDashboard(dashboardDetails) - .then(({ body: { id: dashboard_id } }) => { - return { dashboard_id, card1_id, card2_id }; - }); - }); - }); -}; - -const setFilterMapping = ({ dashboard_id, card1_id, card2_id }) => { - return updateDashboardCards({ - dashboard_id, - cards: [ - { - card_id: card1_id, - row: 0, - col: 0, - size_x: 5, - size_y: 4, - parameter_mappings: [ - { - parameter_id: filterDetails.id, - card_id: card1_id, - target: ["dimension", ["field", PRODUCTS.ID, null]], - }, - ], - }, - { - card_id: card2_id, - row: 0, - col: 4, - size_x: 5, - size_y: 4, - parameter_mappings: [ - { - parameter_id: filterDetails.id, - card_id: card1_id, - target: ["dimension", ["field", ORDERS.ID, null]], - }, - ], - }, - ].filter(Boolean), - }); -}; - -const interceptRequests = ({ dashboard_id, card1_id, card2_id }) => { - cy.intercept("GET", `/api/dashboard/${dashboard_id}`).as("getDashboard"); - cy.intercept( - "POST", - `/api/dashboard/${dashboard_id}/dashcard/*/card/${card1_id}/query`, - ).as("getCardQuery1"); - cy.intercept( - "POST", - `/api/dashboard/${dashboard_id}/dashcard/*/card/${card2_id}/query`, - ).as("getCardQuery2"); -}; - -function addFilterValue(value) { - filterWidget().click(); - cy.findByText(value).click(); - cy.button("Add filter").click(); -} diff --git a/e2e/test/scenarios/filters-reproductions/dashboard-filters-reproductions.cy.spec.js b/e2e/test/scenarios/filters-reproductions/dashboard-filters-reproductions.cy.spec.js new file mode 100644 index 00000000000..93a9d0701c8 --- /dev/null +++ b/e2e/test/scenarios/filters-reproductions/dashboard-filters-reproductions.cy.spec.js @@ -0,0 +1,2484 @@ +import moment from "moment-timezone"; // eslint-disable-line no-restricted-imports -- deprecated usage + +import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; +import { + ORDERS_DASHBOARD_DASHCARD_ID, + ORDERS_DASHBOARD_ID, + ORDERS_QUESTION_ID, + ADMIN_PERSONAL_COLLECTION_ID, +} from "e2e/support/cypress_sample_instance_data"; +import { + restore, + popover, + updateDashboardCards, + visitDashboard, + filterWidget, + editDashboard, + setFilter, + saveDashboard, + selectDashboardFilter, + sidebar, + commandPaletteSearch, + commandPalette, + addOrUpdateDashboardCard, + undoToast, + getDashboardCard, + openNavigationSidebar, + appBar, + dashboardParametersContainer, + navigationSidebar, + visitPublicDashboard, + goToTab, + openQuestionsSidebar, + visitEmbeddedPage, + createQuestion, +} from "e2e/support/helpers"; +import { + createMockDashboardCard, + createMockParameter, +} from "metabase-types/api/mocks"; + +import { + setQuarterAndYear, + setAdHocFilter, +} from "../native-filters/helpers/e2e-date-filter-helpers"; + +const { + ORDERS, + ORDERS_ID, + PRODUCTS, + PRODUCTS_ID, + REVIEWS, + REVIEWS_ID, + PEOPLE, + PEOPLE_ID, +} = SAMPLE_DATABASE; + +describe("issue 8030 + 32444", () => { + const filterDetails = { + name: "ID Column", + slug: "id", + id: "11d79abe", + type: "id", + sectionId: "id", + }; + + const question1Details = { + name: "Q1", + query: { "source-table": PRODUCTS_ID, limit: 2 }, + }; + + const question2Details = { + name: "Q2", + query: { "source-table": ORDERS_ID, limit: 2 }, + }; + + const questionWithFilter = { + name: "Question with Filter", + type: "query", + query: { + "source-table": ORDERS_ID, + limit: 2, + filter: [">", ["field", ORDERS.TOTAL, null], 100], + }, + }; + + const dashboardDetails = { + name: "Filters", + parameters: [filterDetails], + }; + const createQuestionsAndDashboard = () => { + return cy + .createQuestion(question1Details) + .then(({ body: { id: card1_id } }) => { + return cy + .createQuestion(question2Details) + .then(({ body: { id: card2_id } }) => { + return cy + .createDashboard(dashboardDetails) + .then(({ body: { id: dashboard_id } }) => { + return { dashboard_id, card1_id, card2_id }; + }); + }); + }); + }; + + const setFilterMapping = ({ dashboard_id, card1_id, card2_id }) => { + return updateDashboardCards({ + dashboard_id, + cards: [ + { + card_id: card1_id, + row: 0, + col: 0, + size_x: 5, + size_y: 4, + parameter_mappings: [ + { + parameter_id: filterDetails.id, + card_id: card1_id, + target: ["dimension", ["field", PRODUCTS.ID, null]], + }, + ], + }, + { + card_id: card2_id, + row: 0, + col: 4, + size_x: 5, + size_y: 4, + parameter_mappings: [ + { + parameter_id: filterDetails.id, + card_id: card1_id, + target: ["dimension", ["field", ORDERS.ID, null]], + }, + ], + }, + ].filter(Boolean), + }); + }; + + const interceptRequests = ({ dashboard_id, card1_id, card2_id }) => { + cy.intercept("GET", `/api/dashboard/${dashboard_id}`).as("getDashboard"); + cy.intercept( + "POST", + `/api/dashboard/${dashboard_id}/dashcard/*/card/${card1_id}/query`, + ).as("getCardQuery1"); + cy.intercept( + "POST", + `/api/dashboard/${dashboard_id}/dashcard/*/card/${card2_id}/query`, + ).as("getCardQuery2"); + }; + + const addFilterValue = value => { + filterWidget().click(); + cy.findByText(value).click(); + cy.button("Add filter").click(); + }; + + describe("issue 8030", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should not reload dashboard cards not connected to a filter (metabase#8030)", () => { + createQuestionsAndDashboard().then( + ({ dashboard_id, card1_id, card2_id }) => { + interceptRequests({ dashboard_id, card1_id, card2_id }); + setFilterMapping({ dashboard_id, card1_id, card2_id }).then(() => { + cy.visit(`/dashboard/${dashboard_id}`); + cy.wait("@getDashboard"); + cy.wait("@getCardQuery1"); + cy.wait("@getCardQuery2"); + + cy.findByText(filterDetails.name).click(); + popover().within(() => { + // the filter is connected only to the first card + cy.get("input").type("1{enter}"); + cy.findByText("Add filter").click(); + }); + cy.wait("@getCardQuery1"); + cy.get("@getCardQuery1.all").should("have.length", 2); + cy.get("@getCardQuery2.all").should("have.length", 1); + }); + }, + ); + }); + }); + + describe("issue 32444", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should not reload dashboard cards not connected to a filter (metabase#32444)", () => { + cy.createDashboardWithQuestions({ + questions: [question1Details, questionWithFilter], + }).then(({ dashboard }) => { + cy.intercept( + "POST", + `/api/dashboard/${dashboard.id}/dashcard/*/card/*/query`, + ).as("getCardQuery"); + + visitDashboard(dashboard.id); + editDashboard(dashboard.id); + + cy.get("@getCardQuery.all").should("have.length", 2); + + setFilter("Text or Category", "Is"); + selectDashboardFilter(cy.findAllByTestId("dashcard").first(), "Title"); + cy.findAllByTestId("dashcard") + .eq(1) + .findByLabelText("Disconnect") + .click(); + + saveDashboard(); + + cy.wait("@getCardQuery"); + cy.get("@getCardQuery.all").should("have.length", 4); + + addFilterValue("Aerodynamic Bronze Hat"); + + cy.wait("@getCardQuery"); + cy.get("@getCardQuery.all").should("have.length", 5); + }); + }); + }); +}); + +describe("issue 12720", () => { + function clickThrough(title) { + visitDashboard(ORDERS_DASHBOARD_ID); + cy.findAllByTestId("dashcard-container").contains(title).click(); + + cy.location("search").should("contain", dashboardFilter.default); + filterWidget().contains("After January 1, 2026"); + } + // After January 1st, 2026 + const dashboardFilter = { + default: "2026-01-01~", + id: "d3b78b27", + name: "Date Filter", + slug: "date_filter", + type: "date/all-options", + }; + + const questionDetails = { + name: "12720_SQL", + native: { + query: "SELECT * FROM ORDERS WHERE {{filter}}", + "template-tags": { + filter: { + id: "1d006bb7-045f-6c57-e41b-2661a7648276", + name: "filter", + "display-name": "Filter", + type: "dimension", + dimension: ["field", ORDERS.CREATED_AT, null], + "widget-type": "date/all-options", + default: null, + }, + }, + }, + }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + // In this test we're using already present question ("Orders") and the dashboard with that question ("Orders in a dashboard") + cy.request("PUT", `/api/dashboard/${ORDERS_DASHBOARD_ID}`, { + parameters: [dashboardFilter], + }); + + cy.createNativeQuestion(questionDetails).then( + ({ body: { id: SQL_ID } }) => { + updateDashboardCards({ + dashboard_id: ORDERS_DASHBOARD_ID, + cards: [ + { + card_id: SQL_ID, + row: 0, + col: 6, // making sure it doesn't overlap the existing card + size_x: 7, + size_y: 5, + parameter_mappings: [ + { + parameter_id: dashboardFilter.id, + card_id: SQL_ID, + target: ["dimension", ["template-tag", "filter"]], + }, + ], + }, + // add filter to existing card + { + id: ORDERS_DASHBOARD_DASHCARD_ID, + card_id: ORDERS_QUESTION_ID, + row: 0, + col: 0, + size_x: 7, + size_y: 5, + parameter_mappings: [ + { + parameter_id: dashboardFilter.id, + card_id: ORDERS_QUESTION_ID, + target: ["dimension", ["field", ORDERS.CREATED_AT, null]], + }, + ], + }, + ], + }); + }, + ); + }); + + it("should show QB question on a dashboard with filter connected to card without data-permission (metabase#12720)", () => { + cy.signIn("readonly"); + + clickThrough("12720_SQL"); + clickThrough("Orders"); + }); +}); + +describe("issue 12985 > dashboard filter dropdown/search", () => { + const categoryFilter = { + name: "Category", + slug: "category", + id: "2a12e66c", + type: "string/=", + sectionId: "string", + }; + + const dashboardDetails = { parameters: [categoryFilter] }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should work for saved nested questions (metabase#12985-1)", () => { + cy.createQuestion({ + name: "Q1", + query: { "source-table": PRODUCTS_ID }, + }).then(({ body: { id: Q1_ID } }) => { + // Create nested card based on the first one + const nestedQuestion = { + name: "Q2", + query: { "source-table": `card__${Q1_ID}` }, + }; + + cy.createQuestionAndDashboard({ + questionDetails: nestedQuestion, + dashboardDetails, + }).then(({ body: { id, card_id, dashboard_id } }) => { + cy.log("Connect dashboard filters to the nested card"); + + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + dashcards: [ + { + id, + card_id, + row: 0, + col: 0, + size_x: 13, + size_y: 8, + series: [], + visualization_settings: {}, + // Connect filter to the card + parameter_mappings: [ + { + parameter_id: categoryFilter.id, + card_id, + target: ["dimension", ["field", PRODUCTS.CATEGORY, null]], + }, + ], + }, + ], + }); + + visitDashboard(dashboard_id); + }); + }); + + filterWidget().contains("Category").click(); + cy.log("Failing to show dropdown in v0.36.0 through v.0.37.0"); + + popover().within(() => { + cy.findByText("Doohickey"); + cy.findByText("Gizmo"); + cy.findByText("Widget"); + cy.findByText("Gadget").click(); + }); + cy.button("Add filter").click(); + + cy.location("search").should("eq", "?category=Gadget"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Ergonomic Silk Coat"); + }); + + it.skip("should work for aggregated questions (metabase#12985-2)", () => { + const questionDetails = { + name: "12985-v2", + query: { + "source-query": { + "source-table": PRODUCTS_ID, + aggregation: [["count"]], + breakout: [["field", PRODUCTS.CATEGORY, null]], + }, + filter: [">", ["field", "count", { "base-type": "type/Integer" }], 1], + }, + }; + + cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( + ({ body: { id, card_id, dashboard_id } }) => { + cy.log("Connect dashboard filter to the aggregated card"); + + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + dashcards: [ + { + id, + card_id, + row: 0, + col: 0, + size_x: 11, + size_y: 6, + series: [], + visualization_settings: {}, + // Connect filter to the card + parameter_mappings: [ + { + parameter_id: categoryFilter.id, + card_id, + target: [ + "dimension", + ["field", "CATEGORY", { "base-type": "type/Text" }], + ], + }, + ], + }, + ], + }); + + visitDashboard(dashboard_id); + }, + ); + + filterWidget().contains("Category").click(); + // It will fail at this point until the issue is fixed because popover never appears + popover().contains("Gadget").click(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Add filter").click(); + cy.url().should("contain", "?category=Gadget"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Ergonomic Silk Coat"); + }); +}); + +describe("issues 15119 and 16112", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + cy.request("PUT", `/api/field/${REVIEWS.REVIEWER}`, { + has_field_values: "list", + semantic_type: "type/Category", + }); + + cy.request("PUT", `/api/field/${REVIEWS.RATING}`, { + has_field_values: "list", + semantic_type: "type/Category", + }); + }); + + it("user without data permissions should be able to use dashboard filters (metabase#15119, metabase#16112)", () => { + const questionDetails = { + name: "15119", + query: { "source-table": REVIEWS_ID }, + }; + + const ratingFilter = { + name: "Rating Filter", + slug: "rating", + id: "5dfco74e", + type: "string/=", + sectionId: "string", + }; + + const reviewerFilter = { + name: "Reviewer Filter", + slug: "reviewer", + id: "ad1c877e", + type: "string/=", + sectionId: "string", + }; + + const dashboardDetails = { parameters: [reviewerFilter, ratingFilter] }; + + cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( + ({ body: { id, card_id, dashboard_id } }) => { + // Connect filters to the card + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + dashcards: [ + { + id, + card_id, + row: 0, + col: 0, + size_x: 16, + size_y: 9, + visualization_settings: {}, + parameter_mappings: [ + { + parameter_id: ratingFilter.id, + card_id, + target: ["dimension", ["field", REVIEWS.RATING, null]], + }, + { + parameter_id: reviewerFilter.id, + card_id, + target: ["dimension", ["field", REVIEWS.REVIEWER, null]], + }, + ], + }, + ], + }); + + // Actually need to setup the linked filter: + visitDashboard(dashboard_id); + editDashboard(); + cy.findByText("Rating Filter").click(); + cy.findByText("Linked filters").click(); + + // turn on the toggle + sidebar().findByRole("switch").parent().get("label").click(); + + cy.findByText("Save").click(); + + cy.signIn("nodata"); + visitDashboard(dashboard_id); + }, + ); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText(reviewerFilter.name).click(); + popover().contains("adam").click(); + cy.button("Add filter").click(); + + cy.findByTestId("dashcard-container").should("contain", "adam"); + cy.location("search").should("eq", "?reviewer=adam&rating="); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText(ratingFilter.name).click(); + + popover().contains("5").click(); + cy.button("Add filter").click(); + + cy.findByTestId("dashcard-container").should("contain", "adam"); + cy.findByTestId("dashcard-container").should("contain", "5"); + cy.location("search").should("eq", "?reviewer=adam&rating=5"); + }); +}); + +describe("issue 16663", () => { + const questionDetails = { + query: { + "source-table": ORDERS_ID, + }, + }; + + const FILTER = { + name: "Quarter and Year", + slug: "quarter_and_year", + id: "f8ae0c97", + type: "date/quarter-year", + sectionId: "date", + default: "Q1-2023", + }; + + const dashboardDetails = { parameters: [FILTER] }; + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should remove filter value from url after going to another dashboard (metabase#16663)", () => { + const dashboardToRedirect = "Orders in a dashboard"; + const queryParam = "quarter_and_year=Q1"; + + cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( + ({ body: dashboardCard }) => { + const { dashboard_id } = dashboardCard; + + addOrUpdateDashboardCard({ + dashboard_id: dashboardCard.dashboard_id, + card_id: dashboardCard.card_id, + card: { + parameter_mappings: [ + { + parameter_id: FILTER.id, + card_id: dashboardCard.card_id, + target: [ + "dimension", + [ + "field", + ORDERS.CREATED_AT, + { + "base-type": "type/DateTime", + }, + ], + ], + }, + ], + }, + }); + visitDashboard(dashboard_id); + }, + ); + + cy.url().should("include", queryParam); + + commandPaletteSearch(dashboardToRedirect, false); + commandPalette().within(() => { + cy.findByRole("option", { name: dashboardToRedirect }).click(); + }); + + cy.url().should("include", "orders-in-a-dashboard"); + cy.url().should("not.include", queryParam); + }); +}); + +describe("issue 17211", () => { + const questionDetails = { + query: { + "source-table": ORDERS_ID, + }, + }; + + const filter = { + name: "Location", + slug: "location", + id: "96917420", + type: "string/=", + sectionId: "location", + }; + + const dashboardDetails = { + parameters: [filter], + }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( + ({ body: { id, card_id, dashboard_id } }) => { + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + dashcards: [ + { + id, + card_id, + row: 0, + col: 0, + size_x: 11, + size_y: 6, + series: [], + visualization_settings: {}, + parameter_mappings: [ + { + parameter_id: filter.id, + card_id, + target: [ + "dimension", + [ + "field", + PEOPLE.CITY, + { + "source-field": ORDERS.USER_ID, + }, + ], + ], + }, + ], + }, + ], + }); + + visitDashboard(dashboard_id); + }, + ); + }); + + it("should not falsely alert that no matching dashboard filter has been found (metabase#17211)", () => { + filterWidget().click(); + + cy.findByPlaceholderText("Search by City").type("abb"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Abbeville").click(); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.contains("No matching City found").should("not.exist"); + }); +}); + +describe("issue 17551", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + cy.createNativeQuestion({ + native: { + query: + "select 'yesterday' as \"text\", dateadd('day', -1, current_date::date) as \"date\" union all\nselect 'today', current_date::date union all\nselect 'tomorrow', dateadd('day', 1, current_date::date)\n", + }, + }).then(({ body: { id: baseQuestionId } }) => { + const questionDetails = { + name: "17551 QB", + query: { "source-table": `card__${baseQuestionId}` }, + }; + + const filter = { + name: "Date Filter", + slug: "date_filter", + id: "888188ad", + type: "date/all-options", + sectionId: "date", + }; + + const dashboardDetails = { parameters: [filter] }; + + cy.createQuestionAndDashboard({ + questionDetails, + dashboardDetails, + }).then(({ body: card }) => { + const { card_id, dashboard_id } = card; + + const mapFilterToCard = { + parameter_mappings: [ + { + parameter_id: filter.id, + card_id, + target: [ + "dimension", + [ + "field", + "date", + { + "base-type": "type/DateTime", + }, + ], + ], + }, + ], + }; + + cy.editDashboardCard(card, mapFilterToCard); + + visitDashboard(dashboard_id); + }); + }); + }); + + it("should include today in the 'All time' date filter when chosen 'Next' (metabase#17551)", () => { + filterWidget().click(); + setAdHocFilter({ condition: "Next", includeCurrent: true }); + + cy.url().should("include", "?date_filter=next30days~"); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("tomorrow"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("today"); + }); +}); + +describe("issue 17775", () => { + const questionDetails = { + query: { + "source-table": ORDERS_ID, + expressions: { + "CC Date": [ + "field", + ORDERS.CREATED_AT, + { "base-type": "type/DateTime" }, + ], + }, + "order-by": [ + ["asc", ["field", ORDERS.ID, { "base-type": "type/BigInteger" }]], + ], + }, + }; + + const parameters = [ + { + name: "Quarter and Year", + slug: "quarter_and_year", + id: "f8ae0c97", + type: "date/quarter-year", + sectionId: "date", + }, + ]; + + const dashboardDetails = { parameters }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( + ({ body: dashboardCard }) => { + const { dashboard_id } = dashboardCard; + + const updatedSize = { size_x: 21, size_y: 8 }; + + cy.editDashboardCard(dashboardCard, updatedSize); + + visitDashboard(dashboard_id); + }, + ); + + editDashboard(); + + // Make sure filter can be connected to the custom column using UI, rather than using API. + cy.findByTestId("edit-dashboard-parameters-widget-container") + .find(".Icon-gear") + .click(); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Column to filter on") + .parent() + .parent() + .within(() => { + cy.findByText("Select…").click(); + }); + + popover().within(() => { + cy.findByText("CC Date").click(); + }); + + saveDashboard(); + }); + + it("should be able to apply dashboard filter to a custom column (metabase#17775)", () => { + filterWidget().click(); + + setQuarterAndYear({ quarter: "Q1", year: "2023" }); + + cy.findAllByText("44.43").should("have.length", 2); + cy.findAllByText("March 26, 2023, 8:45 AM").should("have.length", 2); + }); +}); + +describe("issue 19494", () => { + const filter1 = { + name: "Card 1 Filter", + slug: "card1_filter", + id: "ab6f631", + type: "string/=", + sectionId: "string", + }; + + const filter2 = { + name: "Card 2 Filter", + slug: "card2_filter", + id: "a9801ade", + type: "string/=", + sectionId: "string", + }; + function connectFilterToCard({ filterName, cardPosition }) { + cy.findByText(filterName).find(".Icon-gear").click(); + + cy.findAllByText("Select…").eq(cardPosition).click(); + + popover().contains("Category").click(); + } + + function setDefaultFilter(value) { + cy.findByText("No default").click(); + + popover().contains(value).click(); + + cy.button("Add filter").click(); + } + + function checkAppliedFilter(name, value) { + cy.findByText(name).closest("fieldset").contains(value); + } + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + // Add two "Orders" questions to the existing "Orders in a dashboard" dashboard + updateDashboardCards({ + dashboard_id: ORDERS_DASHBOARD_ID, + cards: [ + { + card_id: ORDERS_QUESTION_ID, + row: 0, + col: 0, + size_x: 11, + size_y: 8, + }, + { + card_id: ORDERS_QUESTION_ID, + row: 0, + col: 8, + size_x: 11, + size_y: 8, + }, + ], + }); + + // Add two dashboard filters (not yet connected to any of the cards) + cy.request("PUT", `/api/dashboard/${ORDERS_DASHBOARD_ID}`, { + parameters: [filter1, filter2], + }); + }); + + it("should correctly apply different filters with default values to all cards of the same question (metabase#19494)", () => { + // Instead of using the API to connect filters to the cards, + // let's use UI to replicate user experience as closely as possible + visitDashboard(ORDERS_DASHBOARD_ID); + + editDashboard(); + + connectFilterToCard({ filterName: "Card 1 Filter", cardPosition: 0 }); + setDefaultFilter("Doohickey"); + undoToast().findByText("Undo auto-connection").click(); + + connectFilterToCard({ filterName: "Card 2 Filter", cardPosition: -1 }); + setDefaultFilter("Gizmo"); + undoToast().findByText("Undo auto-connection").click(); + + saveDashboard(); + + checkAppliedFilter("Card 1 Filter", "Doohickey"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("148.23"); + + checkAppliedFilter("Card 2 Filter", "Gizmo"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("110.93"); + }); +}); + +describe("issue 20656", () => { + const filter = { + name: "ID", + slug: "id", + id: "11d79abe", + type: "id", + sectionId: "id", + }; + + const questionDetails = { + query: { "source-table": PRODUCTS_ID, limit: 2 }, + // Admin's personal collection is always the first one (hence, the id 1) + collection_id: ADMIN_PERSONAL_COLLECTION_ID, + }; + + const dashboardDetails = { + parameters: [filter], + }; + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should allow a user to visit a dashboard even without a permission to see the dashboard card (metabase#20656, metabase#24536)", () => { + cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( + ({ body: { id, card_id, dashboard_id } }) => { + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + dashcards: [ + { + id, + card_id, + row: 0, + col: 0, + size_x: 24, + size_y: 10, + parameter_mappings: [ + { + parameter_id: filter.id, + card_id, + target: ["dimension", ["field", PRODUCTS.ID, null]], + }, + ], + }, + ], + }); + + cy.signInAsNormalUser(); + + visitDashboard(dashboard_id); + }, + ); + + // Make sure the filter widget is there + filterWidget(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Sorry, you don't have permission to see this card."); + + // Trying to edit the filter should not show mapping fields and shouldn't break frontend (metabase#24536) + editDashboard(); + + cy.findByTestId("edit-dashboard-parameters-widget-container") + .find(".Icon-gear") + .click(); + + getDashboardCard().within(() => { + cy.findByText("Column to filter on"); + cy.icon("key"); + }); + }); +}); + +describe("issue 21528", () => { + const NATIVE_QUESTION_DETAILS = { + name: "Orders with Product ID filter", + native: { + query: "select * from ORDERS where {{product_id}}", + "template-tags": { + product_id: { + type: "dimension", + name: "product_id", + id: "56708d23-6f01-42b7-98ed-f930295d31b9", + "display-name": "Product ID", + dimension: ["field", ORDERS.PRODUCT_ID, null], + "widget-type": "id", + }, + }, + }, + parameters: [ + { + id: "56708d23-6f01-42b7-98ed-f930295d31b9", + type: "id", + target: ["dimension", ["template-tag", "product_id"]], + name: "Product ID", + slug: "product_id", + }, + ], + }; + + const DASHBOARD_DETAILS = { + name: "Dashboard with ID filter", + parameters: [ + { + id: "9f85cd3d", + name: "Product ID", + sectionId: "id", + slug: "product_id", + type: "id", + }, + ], + }; + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + cy.createNativeQuestion(NATIVE_QUESTION_DETAILS, { + wrapId: true, + idAlias: "questionId", + }); + + cy.log( + "set Orders.Product_ID `Filtering on this field`: `A list of all values`", + ); + cy.request("PUT", `/api/field/${ORDERS.PRODUCT_ID}`, { + has_field_values: "list", + }); + + cy.log("set Orders.Product_ID `Display values`: `Use foreign key > Title`"); + cy.request("POST", `/api/field/${ORDERS.PRODUCT_ID}/dimension`, { + type: "external", + name: "Product ID", + human_readable_field_id: PRODUCTS.TITLE, + }); + + cy.createDashboard(DASHBOARD_DETAILS).then( + ({ body: { id: dashboardId } }) => { + cy.wrap(dashboardId).as("dashboardId"); + }, + ); + + cy.then(function () { + addOrUpdateDashboardCard({ + card_id: this.questionId, + dashboard_id: this.dashboardId, + card: { + parameter_mappings: [ + { + card_id: this.questionId, + parameter_id: "9f85cd3d", + target: ["dimension", ["template-tag", "product_id"]], + }, + ], + }, + }); + }); + }); + + it("should show dashboard ID filter values when mapped to a native question with a foreign key field filter", () => { + cy.get("@questionId").then(questionId => { + cy.visit(`/question/${questionId}`); + }); + + cy.findByTestId("native-query-top-bar").findByText("Product ID").click(); + popover().contains("Rustic Paper Wallet - 1").should("be.visible"); + + // Navigating to another page via JavaScript is faster than using `cy.visit("/dashboard/:dashboard-id")` to load the whole page again. + openNavigationSidebar(); + navigationSidebar().findByText("Our analytics").click(); + cy.findByRole("main").findByText(DASHBOARD_DETAILS.name).click(); + + dashboardParametersContainer().findByText("Product ID").click(); + popover().contains("Aerodynamic Bronze Hat - 144").should("be.visible"); + + cy.log("The following scenario breaks on 46"); + // Navigating to another page via JavaScript is faster than using `cy.visit("/admin/datamodel")` to load the whole page again. + appBar().icon("gear").click(); + popover().findByText("Admin settings").click(); + appBar().findByText("Table Metadata").click(); + cy.findByRole("main") + .findByText( + "Select any table to see its schema and add or edit metadata.", + ) + .should("be.visible"); + cy.findByRole("navigation").findByText("Exit admin").click(); + + openNavigationSidebar(); + navigationSidebar().findByText("Our analytics").click(); + cy.findByRole("main").findByText(DASHBOARD_DETAILS.name).click(); + + // Assert that the dashboard ID filter values is still showing correctly again. + dashboardParametersContainer().findByText("Product ID").click(); + popover().contains("Aerodynamic Bronze Hat - 144").should("be.visible"); + }); +}); + +describe("issue 22482", () => { + function getFormattedRange(start, end) { + return `${start.format("MMM D, YYYY")} - ${end.format("MMM D, YYYY")}`; + } + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + visitDashboard(ORDERS_DASHBOARD_ID); + + editDashboard(); + setFilter("Time", "All Options"); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Select…").click(); + popover().contains("Created At").eq(0).click(); + + saveDashboard(); + + filterWidget().click(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Relative dates...").click(); + }); + + it("should round relative date range (metabase#22482)", () => { + cy.findByTestId("relative-datetime-value").clear().type(15); + cy.findByTestId("relative-datetime-unit").click(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("months").click(); + + const expectedRange = getFormattedRange( + moment().startOf("month").add(-15, "month"), + moment().add(-1, "month").endOf("month"), + ); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText(expectedRange); + }); +}); + +describe("issue 22788", () => { + const ccName = "Custom Category"; + const ccDisplayName = "Product.Custom Category"; + + const questionDetails = { + name: "22788", + query: { + "source-table": PRODUCTS_ID, + expressions: { [ccName]: ["field", PRODUCTS.CATEGORY, null] }, + limit: 5, + }, + }; + + const filter = { + name: "Text", + slug: "text", + id: "a7565817", + type: "string/=", + sectionId: "string", + }; + + const dashboardDetails = { + name: "22788D", + parameters: [filter], + }; + + function addFilterAndAssert() { + filterWidget().click(); + cy.findByPlaceholderText("Enter some text").type("Gizmo{enter}"); + cy.button("Add filter").click(); + + cy.findAllByText("Gizmo"); + cy.findAllByText("Doohickey").should("not.exist"); + } + + function openFilterSettings() { + cy.findByTestId("edit-dashboard-parameters-widget-container") + .find(".Icon-gear") + .click(); + } + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( + ({ body: { dashboard_id, card_id, id } }) => { + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + dashcards: [ + { + id, + card_id, + row: 0, + col: 0, + size_x: 11, + size_y: 6, + parameter_mappings: [ + { + parameter_id: filter.id, + card_id, + target: ["dimension", ["expression", ccName, null]], + }, + ], + }, + ], + }); + + visitDashboard(dashboard_id); + }, + ); + }); + + it("should not drop filter connected to a custom column on a second dashboard edit (metabase#22788)", () => { + addFilterAndAssert(); + + editDashboard(); + + openFilterSettings(); + + // Make sure the filter is still connected to the custom column + + getDashboardCard().within(() => { + cy.findByText("Column to filter on"); + cy.findByText(ccDisplayName); + }); + + // need to actually change the dashboard to test a real save + sidebar().within(() => { + cy.findByDisplayValue("Text").clear().type("my filter text"); + cy.button("Done").click(); + }); + + saveDashboard(); + + cy.findAllByText("Gizmo"); + cy.findAllByText("Doohickey").should("not.exist"); + }); +}); + +describe("issue 24235", () => { + const questionDetails = { + query: { "source-table": PRODUCTS_ID, limit: 5 }, + }; + + const parameter = { + id: "727b06c1", + name: "Date Filter", + sectionId: "date", + slug: "date_filter", + type: "date/all-options", + }; + + const parameterTarget = [ + "dimension", + ["field", PRODUCTS.CREATED_AT, { "temporal-unit": "month" }], + ]; + + const dashboardDetails = { parameters: [parameter] }; + + const mapParameterToDashboardCard = ({ id, card_id, dashboard_id }) => { + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + dashcards: [ + { + id, + card_id, + row: 0, + col: 0, + size_x: 24, + size_y: 10, + parameter_mappings: [ + { + card_id, + parameter_id: parameter.id, + target: parameterTarget, + }, + ], + }, + ], + }); + }; + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + cy.intercept("POST", "/api/dashboard/**/query").as("getCardQuery"); + }); + + it("should remove filter when all exclude options are selected (metabase#24235)", () => { + cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( + ({ body: { id, card_id, dashboard_id } }) => { + mapParameterToDashboardCard({ id, card_id, dashboard_id }); + visitDashboard(dashboard_id); + }, + ); + + filterWidget().contains(parameter.name).click(); + popover().within(() => { + cy.findByText("Exclude...").click(); + cy.findByText("Days of the week...").click(); + cy.findByText("Select none...").click(); + cy.findByText("Add filter").click(); + }); + + filterWidget().click(); + popover().within(() => { + cy.findByText("Select all...").click(); + cy.findByText("Update filter").click(); + }); + + cy.wait("@getCardQuery"); + cy.get("[data-testid=cell-data]").should( + "contain", + "Price, Schultz and Daniel", + ); + }); +}); + +describe("issues 15279 and 24500", () => { + const listFilter = { + name: "List", + slug: "list", + id: "6fe14171", + type: "string/=", + sectionId: "string", + }; + + const searchFilter = { + name: "Search", + slug: "search", + id: "4db4913a", + type: "string/=", + sectionId: "string", + }; + + // This filter is corrupted because it's missing `name` and `slug` + const corruptedFilter = { + name: "", + slug: "", + id: "af72ce9c", + type: "string/=", + sectionId: "string", + }; + + const parameters = [listFilter, searchFilter, corruptedFilter]; + + const questionDetails = { + name: "15279", + query: { "source-table": PEOPLE_ID }, + }; + + const dashboardDetails = { parameters }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("corrupted dashboard filter should still appear in the UI without breaking other filters (metabase#15279, metabase#24500)", () => { + cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( + ({ body: { id, card_id, dashboard_id } }) => { + // Connect filters to the question + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + dashcards: [ + { + id, + card_id, + row: 0, + col: 0, + size_x: 24, + size_y: 8, + series: [], + visualization_settings: {}, + parameter_mappings: [ + { + parameter_id: listFilter.id, + card_id, + target: ["dimension", ["field", PEOPLE.SOURCE, null]], + }, + { + parameter_id: searchFilter.id, + card_id, + target: ["dimension", ["field", PEOPLE.NAME, null]], + }, + ], + }, + ], + }); + + visitDashboard(dashboard_id); + }, + ); + + cy.intercept("GET", "/api/dashboard/*/params/*/values").as("values"); + + // Check that list filter works + filterWidget().contains("List").click(); + cy.wait("@values"); + + cy.findByPlaceholderText("Search the list").type("Or").blur(); + popover().contains("Organic").click(); + cy.button("Add filter").click(); + + cy.findByTestId("dashcard-container") + .should("contain", "Lora Cronin") + .and("contain", "Dagmar Fay"); + + // Check that the search filter works + filterWidget().contains("Search").click(); + cy.findByPlaceholderText("Search by Name").type("Lora Cronin"); + cy.button("Add filter").click(); + + cy.findByTestId("dashcard-container") + .should("contain", "Lora Cronin") + .and("not.contain", "Dagmar Fay"); + + // The corrupted filter is now present in the UI, but it doesn't work (as expected) + // People can now easily remove it + editDashboard(); + cy.findByTestId("edit-dashboard-parameters-widget-container") + .findByText("unnamed") + .icon("gear") + .click(); + cy.findByRole("button", { name: "Remove" }).click(); + saveDashboard(); + + // Check the list filter again + filterWidget().contains("List").parent().click(); + cy.wait("@values"); + + cy.log("Check that the search filter works"); + + // reset filter value + filterWidget().contains("Search").parent().icon("close").click(); + + filterWidget().contains("Search").click(); + + cy.findByPlaceholderText("Search by Name").type("Lora Cronin"); + cy.button("Add filter").click(); + + cy.findByTestId("dashcard-container") + .should("contain", "Lora Cronin") + .and("not.contain", "Dagmar Fay"); + }); +}); + +describe("issue 25322", () => { + const parameterDetails = { + name: "Location", + slug: "location", + id: "f8ec7c71", + type: "string/=", + sectionId: "location", + }; + + const questionDetails = { + name: "People", + query: { "source-table": PEOPLE_ID }, + }; + + const dashboardDetails = { + name: "Dashboard", + parameters: [parameterDetails], + }; + + const createDashboard = () => { + return cy + .createQuestion(questionDetails) + .then(({ body: { id: card_id } }) => { + cy.createDashboard(dashboardDetails).then( + ({ body: { id: dashboard_id } }) => { + addOrUpdateDashboardCard({ + dashboard_id, + card_id, + card: { + parameter_mappings: [ + { + card_id, + parameter_id: parameterDetails.id, + target: ["dimension", ["field", PEOPLE.STATE, null]], + }, + ], + }, + }).then(() => ({ dashboard_id })); + }, + ); + }); + }; + + const throttleFieldValuesRequest = dashboard_id => { + const matcher = { + method: "GET", + url: `/api/dashboard/${dashboard_id}/params/${parameterDetails.id}/values`, + middleware: true, + }; + + cy.intercept(matcher, req => req.on("response", res => res.setDelay(100))); + }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should show a loader when loading field values (metabase#25322)", () => { + createDashboard().then(({ dashboard_id }) => { + visitDashboard(dashboard_id); + throttleFieldValuesRequest(dashboard_id); + }); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText(parameterDetails.name).click(); + popover().findByTestId("loading-spinner").should("exist"); + }); +}); + +describe("issue 25248", () => { + const question1Details = { + name: "Q1", + display: "line", + query: { + "source-table": ORDERS_ID, + aggregation: [["count"]], + breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }]], + }, + visualization_settings: { + "graph.metrics": ["count"], + "graph.dimensions": ["CREATED_AT"], + }, + }; + + const question2Details = { + name: "Q2", + display: "line", + query: { + "source-table": ORDERS_ID, + aggregation: [["count"], ["avg", ["field", ORDERS.TOTAL, null]]], + breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }]], + }, + visualization_settings: { + "graph.metrics": ["avg"], + "graph.dimensions": ["CREATED_AT"], + }, + }; + + const parameterDetails = { + name: "Date Filter", + slug: "date_filter", + id: "888188ad", + type: "date/all-options", + sectionId: "date", + }; + + const dashboardDetails = { + name: "25248", + parameters: [parameterDetails], + }; + + const createDashboard = () => { + cy.createQuestionAndDashboard({ + questionDetails: question1Details, + dashboardDetails, + }).then(({ body: { id, card_id, dashboard_id } }) => { + cy.createQuestion(question2Details).then( + ({ body: { id: card_2_id } }) => { + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + dashcards: [ + { + id, + card_id, + series: [{ id: card_2_id }], + row: 0, + col: 0, + size_x: 16, + size_y: 8, + }, + ], + }); + }, + ); + visitDashboard(dashboard_id); + }); + }; + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should allow mapping parameters to combined cards individually (metabase#25248)", () => { + createDashboard(); + editDashboard(); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText(parameterDetails.name).click(); + cy.findAllByText("Select…").first().click(); + popover().findAllByText("Created At").first().click(); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Order.Created At").should("be.visible"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Select…").should("be.visible"); + }); +}); + +describe("issue 25374", () => { + const questionDetails = { + name: "25374", + native: { + "template-tags": { + num: { + id: "f7672b4d-1e84-1fa8-bf02-b5e584cd4535", + name: "num", + "display-name": "Num", + type: "number", + default: null, + }, + }, + query: "select count(*) from orders where id in ({{num}})", + }, + parameters: [ + { + id: "f7672b4d-1e84-1fa8-bf02-b5e584cd4535", + type: "number/=", + target: ["variable", ["template-tag", "num"]], + name: "Num", + slug: "num", + default: null, + }, + ], + }; + + const filterDetails = { + name: "Equal to", + slug: "equal_to", + id: "10c0d4ba", + type: "number/=", + sectionId: "number", + }; + + const dashboardDetails = { + name: "25374D", + parameters: [filterDetails], + }; + + beforeEach(() => { + cy.intercept("POST", "/api/card/*/query").as("cardQuery"); + + restore(); + cy.signInAsAdmin(); + + cy.createNativeQuestionAndDashboard({ + questionDetails, + dashboardDetails, + }).then(({ body: { id, card_id, dashboard_id } }) => { + // Connect filter to the card + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + dashcards: [ + { + id, + card_id, + row: 0, + col: 0, + size_x: 11, + size_y: 6, + parameter_mappings: [ + { + parameter_id: filterDetails.id, + card_id, + target: ["variable", ["template-tag", "num"]], + }, + ], + }, + ], + }); + + visitDashboard(dashboard_id); + + filterWidget().type("1,2,3{enter}"); + cy.findByDisplayValue("1,2,3"); + + cy.get(".CardVisualization") + .should("contain", "COUNT(*)") + .and("contain", "3"); + + cy.location("search").should("eq", "?equal_to=1%2C2%2C3"); + }); + }); + + it("should pass comma-separated values down to the connected question (metabase#25374-1)", () => { + // Drill-through and go to the question + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText(questionDetails.name).click(); + cy.wait("@cardQuery"); + + cy.get("[data-testid=cell-data]") + .should("contain", "COUNT(*)") + .and("contain", "3"); + + cy.location("search").should("eq", "?num=1%2C2%2C3"); + }); + + it("should retain comma-separated values on refresh (metabase#25374-2)", () => { + cy.reload(); + + // Make sure filter widget still has all the values + cy.findByDisplayValue("1,2,3"); + + // Make sure the result in the card is correct + cy.get(".CardVisualization") + .should("contain", "COUNT(*)") + .and("contain", "3"); + + // Make sure URL search params are correct + cy.location("search").should("eq", "?equal_to=1%2C2%2C3"); + }); +}); +describe("issue 25908", () => { + const questionDetails = { + name: "25908", + query: { + "source-table": PRODUCTS_ID, + }, + }; + + const dashboardFilter = { + name: "Text contains", + slug: "text_contains", + id: "28c6ada9", + type: "string/contains", + sectionId: "string", + }; + + const dashboardDetails = { + parameters: [dashboardFilter], + }; + + const CASE_INSENSITIVE_ROWS = 30; + + beforeEach(() => { + cy.intercept("POST", "/api/dataset").as("dataset"); + + restore(); + cy.signInAsAdmin(); + + cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( + ({ body: { id, card_id, dashboard_id } }) => { + cy.intercept( + "POST", + `/api/dashboard/${dashboard_id}/dashcard/${id}/card/${card_id}/query`, + ).as("dashcardQuery"); + + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + dashcards: [ + { + id, + card_id, + row: 0, + col: 0, + size_x: 17, + size_y: 8, + series: [], + visualization_settings: {}, + parameter_mappings: [ + { + parameter_id: dashboardFilter.id, + card_id, + target: ["dimension", ["field", PRODUCTS.TITLE, null]], + }, + ], + }, + ], + }); + + // Note the capital first letter + cy.visit(`/dashboard/${dashboard_id}?text_contains=Li`); + cy.wait("@dashcardQuery"); + cy.contains(new RegExp(`^Rows 1-\\d+ of ${CASE_INSENSITIVE_ROWS}$`)); + }, + ); + }); + + it("`contains` dashboard filter should respect case insensitivity on a title-drill-through (metabase#25908)", () => { + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText(questionDetails.name).click(); + cy.wait("@dataset"); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Title contains Li"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText(`Showing ${CASE_INSENSITIVE_ROWS} rows`); + }); +}); + +describe("issue 26230", () => { + const FILTER_1 = { + id: "12345678", + name: "Text", + slug: "text", + type: "string/=", + sectionId: "string", + }; + + const FILTER_2 = { + id: "87654321", + name: "Text", + slug: "text", + type: "string/=", + sectionId: "string", + }; + + function prepareAndVisitDashboards() { + cy.createDashboard({ + name: "dashboard with a tall card", + parameters: [FILTER_1], + }).then(({ body: { id } }) => { + createDashCard(id, FILTER_1); + bookmarkDashboard(id); + }); + + cy.createDashboard({ + name: "dashboard with a tall card 2", + parameters: [FILTER_2], + }).then(({ body: { id } }) => { + createDashCard(id, FILTER_2); + bookmarkDashboard(id); + visitDashboard(id); + }); + } + + function bookmarkDashboard(dashboardId) { + cy.request("POST", `/api/bookmark/dashboard/${dashboardId}`); + } + + function createDashCard(dashboardId, mappedFilter) { + cy.request("PUT", `/api/dashboard/${dashboardId}`, { + dashcards: [ + createMockDashboardCard({ + id: -dashboardId, + dashboard_id: dashboardId, + size_x: 5, + size_y: 20, + card_id: ORDERS_QUESTION_ID, + parameter_mappings: [ + { + parameter_id: mappedFilter.id, + card_id: ORDERS_QUESTION_ID, + target: [ + "dimension", + [ + "field", + PEOPLE.NAME, + { "base-type": "type/Text", "source-field": ORDERS.USER_ID }, + ], + ], + }, + ], + }), + ], + }); + } + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + prepareAndVisitDashboards(); + }); + + it("should not preserve the sticky filter behavior when navigating to the second dashboard (metabase#26230)", () => { + cy.findByRole("main").scrollTo("bottom"); // This line is essential for the reproduction! + + cy.button("Toggle sidebar").click(); + cy.findByRole("main") + .findByDisplayValue("dashboard with a tall card 2") + .should("not.be.visible"); + + cy.findByTestId("dashboard-parameters-widget-container").should( + "have.css", + "position", + "sticky", + ); + + cy.intercept("GET", "/api/dashboard/*").as("loadDashboard"); + cy.findByRole("listitem", { name: "dashboard with a tall card" }).click(); + cy.wait("@loadDashboard"); + }); +}); + +describe("issue 27356", () => { + const ratingFilter = { + name: "Text", + slug: "text", + id: "5dfco74e", + type: "string/=", + sectionId: "string", + }; + + const paramDashboard = { + name: "Dashboard With Params", + parameters: [ratingFilter], + }; + + const regularDashboard = { + name: "Dashboard Without Params", + }; + + beforeEach(() => { + cy.intercept("GET", "/api/dashboard/*").as("getDashboard"); + restore(); + cy.signInAsAdmin(); + + cy.createDashboard(paramDashboard).then(({ body: { id } }) => { + cy.request("POST", `/api/bookmark/dashboard/${id}`); + }); + + cy.createDashboard(regularDashboard).then(({ body: { id } }) => { + cy.request("POST", `/api/bookmark/dashboard/${id}`); + visitDashboard(id); + }); + }); + + it( + "should seamlessly move between dashboards with or without filters without triggering an error (metabase#27356)", + { tags: "@flaky" }, + () => { + openNavigationSidebar(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText(paramDashboard.name).click(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("This dashboard is looking empty."); + + openNavigationSidebar(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText(regularDashboard.name).click({ force: true }); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("This dashboard is looking empty."); + + openNavigationSidebar(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText(paramDashboard.name).click({ force: true }); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("This dashboard is looking empty."); + }, + ); +}); + +describe("issue 27768", () => { + const questionDetails = { + name: "27768", + query: { + "source-table": PRODUCTS_ID, + limit: 5, + expressions: { CCategory: ["field", PRODUCTS.CATEGORY, null] }, + }, + }; + + const filter = { + name: "Cat", + slug: "cat", + id: "b3b436dd", + type: "string/=", + sectionId: "string", + }; + + function getFilterOptions(filterName) { + cy.findByText(filterName).find(".Icon-gear").click(); + } + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + cy.createQuestionAndDashboard({ questionDetails }).then( + ({ body: { dashboard_id } }) => { + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + parameters: [filter], + }); + + visitDashboard(dashboard_id, { queryParams: { cat: "Gizmo" } }); + }, + ); + }); + + it("filter connected to custom column should visually indicate it is connected (metabase#27768)", () => { + // We need to manually connect the filter to the custom column using the UI, + // but when we fix the issue, it should be safe to do this via API + editDashboard(); + getFilterOptions(filter.name); + + getDashboardCard().findByText("Select…").click(); + popover().contains("CCategory").click(); + saveDashboard(); + + filterWidget().click(); + cy.findByPlaceholderText("Enter some text").type("Gizmo").blur(); + cy.button("Add filter").click(); + + cy.findAllByText("Doohickey").should("not.exist"); + + // Make sure the filter is still connected to the custom column + editDashboard(); + getFilterOptions(filter.name); + + getDashboardCard().within(() => { + cy.findByText("Select…").should("not.exist"); + cy.contains("Product.CCategory"); + }); + }); +}); + +describe("issues 29347, 29346", () => { + const filterValue = 100; + + const filterDetails = { + name: "Text", + slug: "text", + id: "11d79abe", + type: "string/=", + sectionId: "string", + }; + + const questionDetails = { + query: { + "source-table": ORDERS_ID, + }, + }; + + const editableDashboardDetails = { + parameters: [filterDetails], + enable_embedding: true, + embedding_params: { + [filterDetails.slug]: "enabled", + }, + }; + + const lockedDashboardDetails = { + parameters: [filterDetails], + enable_embedding: true, + embedding_params: { + [filterDetails.slug]: "locked", + }, + }; + + const getRemappedValue = fieldValue => { + return `N${fieldValue}`; + }; + + const addFieldRemapping = fieldId => { + cy.request("PUT", `/api/field/${fieldId}`, { + semantic_type: "type/Category", + }); + + cy.request("POST", `/api/field/${fieldId}/dimension`, { + name: "Quantity", + type: "internal", + }); + + cy.request("GET", `/api/field/${fieldId}/values`).then( + ({ body: { values } }) => { + cy.request("POST", `/api/field/${fieldId}/values`, { + values: values.map(([value]) => [value, getRemappedValue(value)]), + }); + }, + ); + }; + + const createDashboard = ({ + dashboardDetails = editableDashboardDetails, + } = {}) => { + cy.createQuestionAndDashboard({ questionDetails, dashboardDetails }).then( + ({ body: { id, card_id, dashboard_id } }) => { + cy.request("PUT", `/api/dashboard/${dashboard_id}`, { + dashcards: [ + { + id, + card_id, + row: 0, + col: 0, + size_x: 24, + size_y: 10, + parameter_mappings: [ + { + parameter_id: filterDetails.id, + card_id, + target: ["dimension", ["field", ORDERS.QUANTITY, null]], + }, + ], + }, + ], + }); + + cy.wrap(dashboard_id).as("dashboardId"); + }, + ); + }; + + const filterOnRemappedValues = fieldValue => { + filterWidget().within(() => { + cy.findByText(filterDetails.name).click(); + }); + + popover().within(() => { + cy.findByText(getRemappedValue(fieldValue)).click(); + cy.button("Add filter").click(); + }); + }; + + const verifyRemappedValues = fieldValue => { + verifyRemappedFilterValues(filterValue); + verifyRemappedCardValues(fieldValue); + }; + + const verifyRemappedFilterValues = fieldValue => { + filterWidget().within(() => { + cy.findByText(getRemappedValue(fieldValue)).should("be.visible"); + }); + }; + + const verifyRemappedCardValues = fieldValue => { + getDashboardCard().within(() => { + cy.findAllByText(getRemappedValue(fieldValue)).should("have.length", 2); + }); + }; + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + addFieldRemapping(ORDERS.QUANTITY); + }); + + describe("regular dashboards", () => { + beforeEach(() => { + cy.intercept("GET", "/api/dashboard/*").as("dashboard"); + cy.intercept("POST", "/api/dashboard/**/card/*/query").as("cardQuery"); + }); + + it("should be able to filter on remapped values (metabase#29347, metabase#29346)", () => { + createDashboard(); + visitDashboard("@dashboardId"); + cy.wait("@dashboard"); + cy.wait("@cardQuery"); + + filterOnRemappedValues(filterValue); + cy.wait("@cardQuery"); + + verifyRemappedValues(filterValue); + }); + + it("should be able to filter on remapped values in the url (metabase#29347, metabase#29346)", () => { + createDashboard(); + visitDashboard("@dashboardId", { + params: { [filterDetails.slug]: filterValue }, + }); + + cy.wait("@dashboard"); + cy.wait("@cardQuery"); + + verifyRemappedValues(filterValue); + }); + }); + + describe("embedded dashboards", () => { + beforeEach(() => { + cy.intercept("GET", "/api/embed/dashboard/*").as("dashboard"); + cy.intercept("GET", "/api/embed/dashboard/**/card/*").as("cardQuery"); + }); + + it("should be able to filter on remapped values (metabase#29347, metabase#29346)", () => { + createDashboard(); + cy.get("@dashboardId").then(dashboardId => + visitEmbeddedPage({ + resource: { dashboard: dashboardId }, + params: {}, + }), + ); + cy.wait("@dashboard"); + cy.wait("@cardQuery"); + + filterOnRemappedValues(filterValue); + cy.wait("@cardQuery"); + + verifyRemappedValues(filterValue); + }); + + it("should be able to filter on remapped values in the token (metabase#29347, metabase#29346)", () => { + createDashboard({ dashboardDetails: lockedDashboardDetails }); + cy.get("@dashboardId").then(dashboardId => { + visitEmbeddedPage({ + resource: { dashboard: dashboardId }, + params: { + [filterDetails.slug]: filterValue, + }, + }); + }); + cy.wait("@dashboard"); + cy.wait("@cardQuery"); + + verifyRemappedCardValues(filterValue); + }); + + it("should be able to filter on remapped values in the url (metabase#29347, metabase#29346)", () => { + createDashboard(); + cy.get("@dashboardId").then(dashboardId => { + visitEmbeddedPage( + { + resource: { dashboard: dashboardId }, + params: {}, + }, + { + setFilters: { [filterDetails.slug]: filterValue }, + }, + ); + }); + cy.wait("@dashboard"); + cy.wait("@cardQuery"); + + verifyRemappedValues(filterValue); + }); + }); + + describe("public dashboards", () => { + beforeEach(() => { + cy.intercept("GET", "/api/public/dashboard/*").as("dashboard"); + cy.intercept("GET", "/api/public/dashboard/**/card/*").as("cardQuery"); + }); + + it("should be able to filter on remapped values (metabase#29347, metabase#29346)", () => { + createDashboard(); + cy.get("@dashboardId").then(dashboardId => + visitPublicDashboard(dashboardId), + ); + cy.wait("@dashboard"); + cy.wait("@cardQuery"); + + filterOnRemappedValues(filterValue); + cy.wait("@cardQuery"); + + verifyRemappedValues(filterValue); + }); + + it("should be able to filter on remapped values in the url (metabase#29347, metabase#29346)", () => { + createDashboard(); + cy.get("@dashboardId").then(dashboardId => { + visitPublicDashboard(dashboardId, { + params: { [filterDetails.slug]: filterValue }, + }); + }); + cy.wait("@dashboard"); + cy.wait("@cardQuery"); + + verifyRemappedValues(filterValue); + }); + }); +}); + +describe("issue 31662", () => { + const parameterDetails = { + name: "Between", + slug: "between", + id: "b6ed2d71", + type: "number/between", + sectionId: "number", + default: [3, 5], + }; + const dashboardDetails = { + name: "Dashboard", + parameters: [parameterDetails], + }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + cy.intercept("/api/dashboard/*").as("dashboard"); + }); + + it("should allow setting default values for a not connected between filter (metabase#31662)", () => { + cy.createDashboard(dashboardDetails).then( + ({ body: { id: dashboardId } }) => { + cy.visit(`dashboard/${dashboardId}?between=10&between=20`); + cy.wait("@dashboard"); + }, + ); + cy.findByTestId("dashboard-empty-state").should("be.visible"); + editDashboard(); + cy.findByTestId("edit-dashboard-parameters-widget-container") + .findByText("Between") + .click(); + sidebar().findByText("2 selections").click(); + popover().within(() => { + cy.findByDisplayValue("3").should("be.visible"); + cy.findByDisplayValue("5").should("be.visible"); + }); + }); +}); +describe("issue 38245", () => { + function createDashboardWithTabs({ dashcards, tabs, ...dashboardDetails }) { + return cy.createDashboard(dashboardDetails).then(({ body: dashboard }) => { + cy.request("PUT", `/api/dashboard/${dashboard.id}`, { + ...dashboard, + dashcards, + tabs, + }).then(({ body: dashboard }) => cy.wrap(dashboard)); + }); + } + + function filterPanel() { + return cy.findByTestId("edit-dashboard-parameters-widget-container"); + } + + function mapDashCardToFilter(dashcardElement, filterName, columnName) { + filterPanel().findByText(filterName).click(); + selectDashboardFilter(dashcardElement, columnName); + sidebar().button("Done").click(); + } + const TAB_1 = { + id: 1, + name: "Tab 1", + }; + + const TAB_2 = { + id: 2, + name: "Tab 2", + }; + + const DASHBOARD_TEXT_FILTER = createMockParameter({ + id: "3", + name: "Text filter", + slug: "filter-text", + type: "string/contains", + }); + beforeEach(() => { + cy.intercept("POST", "/api/card/*/query").as("cardQuery"); + restore(); + cy.signInAsNormalUser(); + }); + + it("should not make a request to the server if the parameters are not saved (metabase#38245)", () => { + createDashboardWithTabs({ + tabs: [TAB_1, TAB_2], + parameters: [DASHBOARD_TEXT_FILTER], + dashcards: [], + }).then(dashboard => visitDashboard(dashboard.id)); + + editDashboard(); + openQuestionsSidebar(); + + sidebar().findByText("Orders").click(); + + cy.wait("@cardQuery"); + + mapDashCardToFilter( + getDashboardCard(), + DASHBOARD_TEXT_FILTER.name, + "Source", + ); + + goToTab(TAB_2.name); + goToTab(TAB_1.name); + + getDashboardCard().within(() => { + cy.findByText("Orders").should("exist"); + cy.findByText("Product ID").should("exist"); + cy.findByText(/(Problem|Error)/i).should("not.exist"); + }); + + cy.get("@cardQuery.all").should("have.length", 2); + cy.get("@cardQuery").should(({ response }) => { + expect(response.statusCode).not.to.eq(500); + }); + }); +}); + +describe("issue 43154", () => { + const modelDetails = { + name: "Model", + type: "model", + query: { + "source-table": ORDERS_ID, + joins: [ + { + fields: "all", + alias: "People - User", + condition: [ + "=", + ["field", ORDERS.USER_ID, { "base-type": "type/Integer" }], + [ + "field", + PEOPLE.ID, + { "base-type": "type/BigInteger", "join-alias": "People - User" }, + ], + ], + "source-table": PEOPLE_ID, + }, + ], + }, + }; + + const questionDetails = modelId => ({ + name: "Question", + type: "question", + query: { + "source-table": `card__${modelId}`, + }, + }); + + const questionWithAggregationDetails = modelId => ({ + name: "Question", + type: "question", + query: { + "source-table": `card__${modelId}`, + aggregation: [["count"]], + }, + }); + + function verifyNestedFilter(questionDetails) { + createQuestion(modelDetails).then(({ body: model }) => { + cy.createDashboardWithQuestions({ + questions: [questionDetails(model.id)], + }).then(({ dashboard }) => { + visitDashboard(dashboard.id); + }); + }); + + editDashboard(); + setFilter("Text or Category", "Is"); + getDashboardCard().findByText("Select…").click(); + popover().findByText("People - User → Source").click(); + saveDashboard(); + + filterWidget().click(); + popover().within(() => { + cy.findByText("Twitter").click(); + cy.button("Add filter").click(); + }); + } + beforeEach(() => { + restore(); + cy.signInAsNormalUser(); + }); + + it("should be able to see field values with a model-based question (metabase#43154)", () => { + verifyNestedFilter(questionDetails); + }); + + it("should be able to see field values with a model-based question with aggregation (metabase#43154)", () => { + verifyNestedFilter(questionWithAggregationDetails); + }); +}); diff --git a/e2e/test/scenarios/filters-reproductions/filters-reproductions.cy.spec.js b/e2e/test/scenarios/filters-reproductions/filters-reproductions.cy.spec.js new file mode 100644 index 00000000000..ac4942db448 --- /dev/null +++ b/e2e/test/scenarios/filters-reproductions/filters-reproductions.cy.spec.js @@ -0,0 +1,985 @@ +import { SAMPLE_DB_ID, SAMPLE_DB_SCHEMA_ID } from "e2e/support/cypress_data"; +import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; +import { + openOrdersTable, + restore, + selectFilterOperator, + popover, + cartesianChartCircle, + openProductsTable, + visualize, + filter, + filterWidget, + entityPickerModal, + entityPickerModalTab, + getNotebookStep, + queryBuilderMain, + startNewQuestion, + visitQuestionAdhoc, + assertQueryBuilderRowCount, + queryBuilderHeader, + modal, + enterCustomColumnDetails, + createQuestion, + tableHeaderClick, +} from "e2e/support/helpers"; + +const { ORDERS_ID, PRODUCTS, PRODUCTS_ID, ORDERS, REVIEWS, PEOPLE, PEOPLE_ID } = + SAMPLE_DATABASE; + +describe("issue 9339", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should not paste non-numeric values into single-value numeric filters (metabase#9339)", () => { + openOrdersTable(); + + tableHeaderClick("Total"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Filter by this column").click(); + selectFilterOperator("Greater than"); + cy.findByPlaceholderText("Enter a number").type("9339,1234").blur(); + cy.findByDisplayValue("9339").should("be.visible"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("1,234").should("not.exist"); + cy.button("Add filter").should("be.enabled"); + }); +}); + +describe.skip("issue 12496", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + const datePickerInput = (picker, input) => + cy + .findAllByTestId("specific-date-picker") + .eq(picker) + .find("input") + .eq(input); + const setup = unit => { + cy.createQuestion( + { + name: `Orders by Created At: ${unit}`, + query: { + "source-table": ORDERS_ID, + aggregation: [["count"]], + breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": unit }]], + filter: [ + "between", + ["field", ORDERS.CREATED_AT, null], + "2022-04-01", + "2022-05-31", + ], + }, + display: "line", + }, + { visitQuestion: true }, + ); + // When a filter is added above, we have to unhide the filter pills: + cy.findByTestId("filters-visibility-control").click(); + }; + it("should display correct day range in filter pill when drilling into a week", () => { + setup("week"); + cartesianChartCircle().eq(0).click({ force: true }); + popover().contains("See this Order").click(); + cy.findByTestId("qb-filters-panel") + .contains("Created At is April 24–30, 2022") + .click(); + popover().within(() => { + cy.findByTestId("between-date-picker").within(() => { + datePickerInput(0, 0).should("have.value", "04/24/2022"); + datePickerInput(1, 0).should("have.value", "04/30/2022"); + }); + }); + }); + it("should display correct day range in filter pill when drilling into a month", () => { + setup("month"); + cartesianChartCircle().eq(0).click({ force: true }); + popover().contains("See this Order").click(); + cy.findByTestId("qb-filters-panel") + .contains("Created At is April 2022") + .click(); + popover().within(() => { + cy.findByTestId("between-date-picker").within(() => { + datePickerInput(0, 0).should("have.value", "04/01/2022"); + datePickerInput(1, 0).should("have.value", "04/30/2022"); + }); + }); + }); + it("should display correct day range in filter pill when drilling into a hour", () => { + setup("hour"); + cartesianChartCircle().eq(0).click({ force: true }); + popover().contains("See this Order").click(); + cy.findByTestId("qb-filters-panel") + .contains("Created At is April 30, 2022, 6:00–59 PM") + .click(); + popover().within(() => { + cy.findByTestId("between-date-picker").within(() => { + datePickerInput(0, 0).should("have.value", "04/30/2022"); + datePickerInput(0, 1).should("have.value", "6"); + datePickerInput(0, 2).should("have.value", "00"); + datePickerInput(1, 0).should("have.value", "04/30/2022"); + datePickerInput(1, 1).should("have.value", "6"); + datePickerInput(1, 2).should("have.value", "59"); + }); + }); + }); + it("should display correct minute in filter pill when drilling into a minute", () => { + setup("minute"); + cartesianChartCircle().eq(0).click({ force: true }); + popover().contains("See this Order").click(); + cy.findByTestId("qb-filters-panel") + .contains("Created At is April 30, 2022, 6:56 PM") + .click(); + popover().within(() => { + datePickerInput(0, 0).should("have.value", "04/30/2022"); + datePickerInput(0, 1).should("have.value", "6"); + datePickerInput(0, 2).should("have.value", "56"); + }); + }); + it("should display correct minute in filter pill when drilling into a day", () => { + setup("day"); + cartesianChartCircle().eq(0).click({ force: true }); + popover().contains("See this Order").click(); + cy.findByTestId("qb-filters-panel") + .contains("Created At is April 30, 2022") + .click(); + popover().within(() => { + datePickerInput(0, 0).should("have.value", "04/30/2022"); + }); + }); +}); + +describe("issue 16621", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + openProductsTable({ limit: 3 }); + }); + + it("should be possible to create multiple filter that start with the same value (metabase#16621)", () => { + tableHeaderClick("Category"); + popover().within(() => { + cy.findByText("Filter by this column").click(); + cy.findByPlaceholderText("Search the list").type("Gadget"); + cy.findByText("Gadget").click(); + cy.button("Add filter").click(); + }); + cy.findByTestId("qb-filters-panel").within(() => { + cy.findByText("Category is Gadget").click(); + }); + popover().within(() => { + cy.findByText("Gizmo").click(); + cy.button("Update filter").click(); + }); + cy.findByTestId("qb-filters-panel") + .findByText("Category is 2 selections") + .should("be.visible"); + }); +}); + +describe.skip("issue 18770", () => { + const questionDetails = { + name: "18770", + query: { + "source-query": { + aggregation: [["count"]], + "source-table": ORDERS_ID, + breakout: [ + ["field", PRODUCTS.TITLE, { "source-field": ORDERS.PRODUCT_ID }], + ], + }, + filter: [">", ["field", "count", { "base-type": "type/Integer" }], 0], + }, + }; + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + cy.createQuestion(questionDetails, { visitQuestion: true }); + }); + + it("post-aggregation filter shouldn't affect the drill-through options (metabase#18770)", () => { + cy.icon("notebook").click(); + // It is important to manually triger "visualize" in order to generate `result_metadata` + // Otherwise, we might get false negative even when this issue gets resolved. + // In order to do that, we have to change the breakout field first or it will never generate and send POST /api/dataset request. + cy.findAllByTestId("notebook-cell-item") + .contains(/Products? → Title/) + .click(); + popover().findByText("Category").click(); + cy.findAllByTestId("notebook-cell-item").contains(/Products? → Category/); + + visualize(); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("4,784").click(); + popover() + .should("contain", "See these Orders") + .and("contain", "Break out by a…") + .and("contain", "Filter by this value") + .and("contain", "Automatic explorations"); + }); +}); + +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" }); + + popover().within(() => { + cy.findByText("Category").click(); + cy.findByPlaceholderText("Search the list").type("i"); + + cy.findByText("Doohickey").should("be.visible"); + cy.findByText("Gizmo").should("be.visible"); + cy.findByText("Widget").should("be.visible"); + cy.findByText("Gadget").should("not.exist"); + }); + }); +}); + +describe("issue 20683", { tags: "@external" }, () => { + beforeEach(() => { + restore("postgres-12"); + cy.signInAsAdmin(); + }); + + it("should filter postgres with the 'current quarter' filter (metabase#20683)", () => { + startNewQuestion(); + entityPickerModal().within(() => { + entityPickerModalTab("Tables").click(); + cy.findByText("QA Postgres12").click(); + cy.findByText("Orders").click(); + }); + + getNotebookStep("filter") + .findByText(/Add filter/) + .click(); + + popover().within(() => { + cy.findByText("Created At").click(); + cy.findByText("Relative dates…").click(); + cy.findByText("Past").click(); + cy.findByText("Current").click(); + cy.findByText("Quarter").click(); + }); + + visualize(); + + queryBuilderMain().findByText("No results!").should("be.visible"); + }); +}); + +describe("issue 21979", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + cy.intercept("POST", "/api/dataset").as("dataset"); + }); + + it("exclude 'day of the week' should show the correct day reference in the UI (metabase#21979)", () => { + openProductsTable({ mode: "notebook" }); + + filter({ mode: "notebook" }); + popover().within(() => { + cy.findByText("Created At").click(); + cy.findByText("Exclude…").click(); + cy.findByText("Days of the week…").click(); + cy.findByLabelText("Monday").click(); + cy.button("Add filter").click(); + }); + + getNotebookStep("filter") + .findByText("Created At excludes Mondays") + .should("be.visible"); + + visualize(); + + // Make sure the query is correct + // (a product called "Enormous Marble Wallet" is created on Monday) + queryBuilderMain().findByText("Enormous Marble Wallet").should("not.exist"); + + cy.findByTestId("qb-filters-panel") + .findByText("Created At excludes Mondays") + .click(); + + popover().within(() => { + cy.findByLabelText("Monday").click(); + cy.findByLabelText("Thursday").click(); + cy.button("Update filter").click(); + }); + cy.wait("@dataset"); + + queryBuilderMain() + .findByText("Enormous Marble Wallet") + .should("be.visible"); + + cy.findByTestId("qb-filters-panel") + .findByText("Created At excludes Thursdays") + .should("be.visible"); + }); +}); + +describe("issue 22230", () => { + const questionDetails = { + dataset_query: { + database: SAMPLE_DB_ID, + query: { + "source-table": PEOPLE_ID, + aggregation: [["max", ["field", PEOPLE.NAME, null]]], + breakout: [["field", PEOPLE.SOURCE, null]], + }, + type: "query", + display: "table", + }, + }; + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + visitQuestionAdhoc(questionDetails, { mode: "notebook" }); + }); + + it("should be able to filter on an aggregation (metabase#22230)", () => { + cy.findAllByTestId("action-buttons").last().findByText("Filter").click(); + + popover().within(() => { + cy.findByText("Max of Name").click(); + cy.findByDisplayValue("Is").click(); + }); + cy.findByRole("listbox").findByText("Starts with").click(); + + popover().within(() => { + cy.findByPlaceholderText("Enter some text").type("Zo").blur(); + cy.button("Add filter").click(); + }); + + visualize(); + + assertQueryBuilderRowCount(2); + queryBuilderMain(() => { + cy.findByText("Zora Schamberger").should("be.visible"); + cy.findByText("Zoie Kozey").should("be.visible"); + }); + }); +}); + +describe("issue 22730", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + cy.createNativeQuestion( + { + name: "22730", + native: { + query: + "select '14:02:13'::time \"time\", 'before-row' \"name\" union all select '14:06:13'::time \"time\", 'after-row' ", + }, + }, + { visitQuestion: true }, + ); + + cy.intercept("POST", "/api/dataset").as("dataset"); + }); + + it("allows filtering by time column (metabase#22730)", () => { + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Explore results").click(); + cy.wait("@dataset"); + + tableHeaderClick("time"); + + popover().within(() => { + cy.findByText("Filter by this column").click(); + cy.findByDisplayValue("00:00").clear().type("14:03"); + cy.button("Add filter").click(); + }); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("before-row"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("after-row").should("not.exist"); + }); +}); + +describe("issue 24664", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + openProductsTable({ limit: 3 }); + }); + + it("should be possible to create multiple filter that start with the same value (metabase#24664)", () => { + tableHeaderClick("Category"); + popover().within(() => { + cy.findByText("Filter by this column").click(); + cy.findByText("Doohickey").click(); + cy.button("Add filter").click(); + }); + + tableHeaderClick("Category"); + popover().within(() => { + cy.findByText("Filter by this column").click(); + cy.findByText("Gizmo").click(); + cy.button("Add filter").click(); + }); + + cy.findByTestId("qb-filters-panel").findByText("Category is Gizmo").click(); + popover().within(() => { + cy.findByText("Widget").click(); + cy.button("Update filter").click(); + }); + + // First filter is still there + cy.findByTestId("qb-filters-panel").findByText("Category is Doohickey"); + }); +}); + +describe("issue 24994", () => { + const questionDetails = { + query: { + "source-query": { + "source-table": PRODUCTS_ID, + filter: [ + "and", + ["=", ["field", PRODUCTS.CATEGORY, null], "Gadget", "Gizmo"], + [ + "time-interval", + ["field", PRODUCTS.CREATED_AT, null], + -30, + "year", + { + include_current: false, + }, + ], + ], + aggregation: [["count"]], + breakout: [["field", PRODUCTS.CATEGORY, null]], + }, + filter: [ + ">", + [ + "field", + "count", + { + "base-type": "type/Integer", + }, + ], + 0, + ], + }, + }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should allow updating filters (metabase#24994)", () => { + cy.createQuestion(questionDetails, { visitQuestion: true }); + + // Three filters + cy.findByTestId("filters-visibility-control").contains("3").click(); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Category is 2 selections").click(); + assertFilterValueIsSelected("Gadget"); + assertFilterValueIsSelected("Gizmo"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Doohickey").click(); + assertFilterValueIsSelected("Doohickey"); + cy.button("Update filter").should("not.be.disabled").click(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Category is 3 selections"); + }); +}); + +function assertFilterValueIsSelected(value) { + cy.findByRole("checkbox", { name: value }).should("be.checked"); +} + +describe("issue 25378", () => { + const questionDetails = { + name: "25378", + dataset_query: { + type: "query", + query: { + "source-table": ORDERS_ID, + aggregation: [["count"]], + breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }]], + }, + database: SAMPLE_DB_ID, + }, + display: "line", + }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + visitQuestionAdhoc(questionDetails, { mode: "notebook" }); + }); + + it("should be able to use relative date filter on a breakout after the aggregation (metabase#25378)", () => { + cy.findAllByTestId("action-buttons").last().findByText("Filter").click(); + + popover().within(() => { + cy.findByText("Created At: Month").click(); + cy.findByText("Relative dates…").click(); + cy.findByDisplayValue("days").click(); + }); + cy.findByRole("listbox").findByText("months").click(); + popover().findByLabelText("Options").click(); + popover().last().findByText("Starting from…").click(); + + popover().button("Add filter").click(); + + visualize(response => { + expect(response.body.error).to.not.exist; + }); + }); +}); + +describe("issue 25927", () => { + const query = { + dataset_query: { + database: SAMPLE_DB_ID, + query: { + "source-query": { + "source-table": ORDERS_ID, + aggregation: [["count"]], + breakout: [ + ["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }], + ], + }, + expressions: { + "Custom Count": ["field", "count", { "base-type": "type/Integer" }], + }, + }, + type: "query", + }, + display: "table", + }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + visitQuestionAdhoc(query); + }); + + it("column filter should work for questions with custom column (metabase#25927)", () => { + tableHeaderClick("Created At: Month"); + popover().within(() => { + cy.findByText("Filter by this column").click(); + cy.findByText("Last 30 days").click(); + }); + + cy.wait("@dataset"); + + // Click on the filter again to try updating it + cy.findByTestId("qb-filters-panel") + .contains("Created At: Month is in the previous 30 days") + .click(); + + popover().button("Update filter").should("not.be.disabled"); + }); +}); + +describe("issue 25990", () => { + const questionDetails = { + dataset_query: { + type: "query", + database: SAMPLE_DB_ID, + query: { + "source-query": { + "source-table": ORDERS_ID, + joins: [ + { + fields: "all", + "source-table": PEOPLE_ID, + condition: [ + "=", + ["field", ORDERS.USER_ID, null], + ["field", PEOPLE.ID, { "join-alias": "People - User" }], + ], + alias: "People - User", + }, + ], + aggregation: [["count"]], + breakout: [ + ["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }], + ], + }, + filter: [">", ["field", "count", { "base-type": "type/Integer" }], 0], + }, + }, + }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + cy.intercept("POST", "/api/dataset").as("dataset"); + }); + + it("should allow to filter by a column in a joined table (metabase#25990)", () => { + visitQuestionAdhoc(questionDetails); + + queryBuilderHeader().button("Filter").click(); + + modal().within(() => { + cy.findByText("Person").click(); + cy.findByPlaceholderText("Enter an ID").type("10").blur(); + cy.button("Apply filters").click(); + }); + + cy.wait("@dataset"); + + cy.findByTestId("qb-filters-panel") + .findByText("People - User → ID is 10") + .should("be.visible"); + }); +}); + +describe("issue 25994", () => { + const questionDetails = { + dataset_query: { + type: "query", + query: { + "source-table": PRODUCTS_ID, + aggregation: [ + ["min", ["field", PRODUCTS.CREATED_AT, { "temporal-unit": "day" }]], + ], + breakout: [["field", PRODUCTS.CATEGORY, null]], + }, + database: SAMPLE_DB_ID, + }, + }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + visitQuestionAdhoc(questionDetails, { mode: "notebook" }); + }); + + it("should be possible to use 'between' dates filter after aggregation (metabase#25994)", () => { + cy.findAllByTestId("action-buttons").last().findByText("Filter").click(); + + popover().within(() => { + cy.findByText("Min of Created At: Day").click(); + cy.findByText("Specific dates…").click(); + + // It doesn't really matter which dates we select so let's go with whatever is offered + cy.button("Add filter").click(); + }); + + visualize(response => { + expect(response.body.error).to.not.exist; + }); + }); +}); + +describe.skip("issue 26861", () => { + const filter = { + id: "a3b95feb-b6d2-33b6-660b-bb656f59b1d7", + name: "filter", + "display-name": "Filter", + type: "dimension", + dimension: ["field", ORDERS.CREATED_AT, null], + "widget-type": "date/all-options", + default: null, + }; + + const nativeQuery = { + name: "26861", + native: { + query: "select * from orders where {{filter}} limit 2", + "template-tags": { + filter, + }, + }, + }; + beforeEach(() => { + cy.intercept("POST", "/api/dataset").as("dataset"); + + restore(); + cy.signInAsAdmin(); + + cy.createNativeQuestion(nativeQuery, { visitQuestion: true }); + }); + + it("exclude filter shouldn't break native questions with field filters (metabase#26861)", () => { + filterWidget().click(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Exclude...").click(); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Days of the week...").click(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Tuesday").click(); + + cy.button("Update filter").click(); + // In all other places in application, POST /api/dataset fires immediately after "Update filter" + // A part of this bug is that we have to manually run the query so the next step will fail + cy.wait("@dataset"); + + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("CREATED_AT excludes Tuesday"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("117.03").should("not.exist"); + }); +}); + +describe("issue 27123", () => { + const questionDetails = { + query: { + "source-table": ORDERS_ID, + limit: 100, + }, + }; + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + cy.createQuestion(questionDetails, { visitQuestion: true }); + }); + + it("exclude filter should not resolve to 'Days of the week' regardless of the chosen granularity (metabase#27123)", () => { + tableHeaderClick("Created At"); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Filter by this column").click(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Exclude…").click(); + // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage + cy.findByText("Months of the year…").click(); + + popover() + .should("contain", "Months of the year…") + .and("contain", "January"); + }); +}); + +describe("issue 29094", () => { + beforeEach(() => { + restore(); + cy.signInAsNormalUser(); + }); + + it("disallows adding a filter using non-boolean custom expression (metabase#29094)", () => { + startNewQuestion(); + + entityPickerModal().within(() => { + entityPickerModalTab("Tables").click(); + cy.findByText("Orders").click(); + }); + + getNotebookStep("filter") + .findByText("Add filters to narrow your answer") + .click(); + + popover().within(() => { + cy.findByText("Custom Expression").click(); + enterCustomColumnDetails({ formula: "[Tax] * 22" }); + cy.realPress("Tab"); + cy.button("Done").should("be.disabled"); + cy.findByText("Invalid expression").should("exist"); + }); + }); +}); + +describe("issue 30312", () => { + const CREATED_AT_BREAKOUT = [ + "field", + ORDERS.CREATED_AT, + { + "base-type": "type/DateTime", + "temporal-unit": "month", + }, + ]; + beforeEach(() => { + restore(); + cy.signInAsNormalUser(); + }); + + it("can use a drill filter on an aggregated column (metabase#30312)", () => { + cy.createQuestion( + { + query: { + "source-table": ORDERS_ID, + aggregation: [["count"]], + breakout: [CREATED_AT_BREAKOUT], + limit: 5, // optimization + }, + display: "table", + }, + { visitQuestion: true }, + ); + + cy.findAllByTestId("header-cell").eq(1).should("have.text", "Count"); + + tableHeaderClick("Count"); + + popover().findByText("Filter by this column").click(); + selectFilterOperator("Equal to"); + popover().within(() => { + cy.findByPlaceholderText("Enter a number").type("10"); + cy.realPress("Tab"); + cy.button("Add filter").should("be.enabled").click(); + }); + + cy.findByTestId("filter-pill").should("have.text", "Count is equal to 10"); + queryBuilderMain().findByText("No results!").should("be.visible"); + }); +}); + +describe("issue 31340", () => { + const LONG_COLUMN_NAME = + "Some very very very very long column name that should have a line break"; + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + + cy.intercept("PUT", "/api/field/*").as("fieldUpdate"); + cy.intercept("GET", "/api/field/*/search/*").as("search"); + + cy.visit( + `/admin/datamodel/database/${SAMPLE_DB_ID}/schema/${SAMPLE_DB_SCHEMA_ID}/table/${PEOPLE_ID}`, + ); + + cy.findByTestId("column-PASSWORD") + .findByDisplayValue("Password") + .type(`{selectAll}${LONG_COLUMN_NAME}`) + .blur(); + + cy.wait("@fieldUpdate"); + + cy.createQuestion( + { + query: { + "source-table": PEOPLE_ID, + limit: 2, + }, + }, + { visitQuestion: true }, + ); + }); + + it("should properly display long column names in filter options search results (metabase#31340)", () => { + tableHeaderClick(LONG_COLUMN_NAME); + + popover().findByText("Filter by this column").click(); + selectFilterOperator("Is"); + popover().within(() => { + cy.findByPlaceholderText(`Search by ${LONG_COLUMN_NAME}`).type( + "nonexistingvalue", + ); + cy.wait("@search"); + }); + }); +}); + +describe("issue 34794", () => { + beforeEach(() => { + restore(); + cy.signInAsNormalUser(); + }); + + it("should not crash when navigating to filter popover's custom expression section (metabase#34794)", () => { + openOrdersTable({ mode: "notebook" }); + + filter({ mode: "notebook" }); + popover().within(() => { + cy.findByText("Created At").click(); + cy.icon("chevronleft").click(); // go back to the main filter popover + cy.findByText("Custom Expression").click(); + cy.findByLabelText("Expression").type("[Total] > 10").blur(); + cy.button("Done").click(); + }); + + getNotebookStep("filter") + .findByText("Total is greater than 10") + .should("be.visible"); + }); +}); + +describe("issue 36508", () => { + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should treat 'Number of distinct values' aggregation as numerical (metabase#36508)", () => { + createQuestion( + { + query: { + "source-table": PEOPLE_ID, + aggregation: [ + ["distinct", ["field", PEOPLE.EMAIL, { "base-type": "type/Text" }]], + ], + breakout: [["field", PEOPLE.SOURCE, { "base-type": "type/Text" }]], + limit: 5, + }, + }, + { visitQuestion: true }, + ); + + cy.button("Filter").click(); + + modal().within(() => { + cy.findByText("Summaries").click(); + + cy.findByTestId("filter-column-Distinct values of Email") + .findByText("between") + .should("exist") + .click(); + }); + + popover().within(() => { + cy.findByText("Equal to").should("exist"); + cy.findByText("Greater than").should("exist"); + cy.findByText("Less than").should("exist"); + }); + }); +}); + +describe("metabase#32985", () => { + const questionDetails = { + database: SAMPLE_DB_ID, + query: { + "source-table": PEOPLE_ID, + }, + type: "query", + }; + + beforeEach(() => { + restore(); + cy.signInAsAdmin(); + }); + + it("should not crash when searching large field values sets in filters popover (metabase#32985)", () => { + // we need to mess with the field metadata to make the field values crazy + cy.request("PUT", `/api/field/${REVIEWS.REVIEWER}`, { + semantic_type: "type/PK", + }); + cy.request("PUT", `/api/field/${PEOPLE.EMAIL}`, { + semantic_type: "type/FK", + }); + cy.request("PUT", `/api/field/${PEOPLE.EMAIL}`, { + fk_target_field_id: REVIEWS.REVIEWER, + }); + + cy.createQuestion(questionDetails, { visitQuestion: true }); + + tableHeaderClick("Email"); + + popover().within(() => { + cy.findByText("Filter by this column").click(); + cy.findByPlaceholderText("Search by Email").type("foo"); + }); + }); +}); diff --git a/e2e/test/scenarios/filters/filter-reproductions.cy.spec.js b/e2e/test/scenarios/filters/filter-reproductions.cy.spec.js deleted file mode 100644 index cbb25624d7a..00000000000 --- a/e2e/test/scenarios/filters/filter-reproductions.cy.spec.js +++ /dev/null @@ -1,42 +0,0 @@ -import { SAMPLE_DB_ID } from "e2e/support/cypress_data"; -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { restore, popover, tableHeaderClick } from "e2e/support/helpers"; - -const { REVIEWS, PEOPLE, PEOPLE_ID } = SAMPLE_DATABASE; - -describe("filter bug reproductions", () => { - const questionDetails = { - database: SAMPLE_DB_ID, - query: { - "source-table": PEOPLE_ID, - }, - type: "query", - }; - - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should not crash when searching large field values sets in filters popover (metabase#32985)", () => { - // we need to mess with the field metadata to make the field values crazy - cy.request("PUT", `/api/field/${REVIEWS.REVIEWER}`, { - semantic_type: "type/PK", - }); - cy.request("PUT", `/api/field/${PEOPLE.EMAIL}`, { - semantic_type: "type/FK", - }); - cy.request("PUT", `/api/field/${PEOPLE.EMAIL}`, { - fk_target_field_id: REVIEWS.REVIEWER, - }); - - cy.createQuestion(questionDetails, { visitQuestion: true }); - - tableHeaderClick("Email"); - - popover().within(() => { - cy.findByText("Filter by this column").click(); - cy.findByPlaceholderText("Search by Email").type("foo"); - }); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/12496-drill-through-filter-date.cy.spec.js b/e2e/test/scenarios/filters/reproductions/12496-drill-through-filter-date.cy.spec.js deleted file mode 100644 index 7603301abb4..00000000000 --- a/e2e/test/scenarios/filters/reproductions/12496-drill-through-filter-date.cy.spec.js +++ /dev/null @@ -1,108 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { popover, restore, cartesianChartCircle } from "e2e/support/helpers"; -const { ORDERS, ORDERS_ID } = SAMPLE_DATABASE; - -describe.skip("issue 12496", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - const datePickerInput = (picker, input) => - cy - .findAllByTestId("specific-date-picker") - .eq(picker) - .find("input") - .eq(input); - const setup = unit => { - cy.createQuestion( - { - name: `Orders by Created At: ${unit}`, - query: { - "source-table": ORDERS_ID, - aggregation: [["count"]], - breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": unit }]], - filter: [ - "between", - ["field", ORDERS.CREATED_AT, null], - "2022-04-01", - "2022-05-31", - ], - }, - display: "line", - }, - { visitQuestion: true }, - ); - // When a filter is added above, we have to unhide the filter pills: - cy.findByTestId("filters-visibility-control").click(); - }; - it("should display correct day range in filter pill when drilling into a week", () => { - setup("week"); - cartesianChartCircle().eq(0).click({ force: true }); - popover().contains("See this Order").click(); - cy.findByTestId("qb-filters-panel") - .contains("Created At is April 24–30, 2022") - .click(); - popover().within(() => { - cy.findByTestId("between-date-picker").within(() => { - datePickerInput(0, 0).should("have.value", "04/24/2022"); - datePickerInput(1, 0).should("have.value", "04/30/2022"); - }); - }); - }); - it("should display correct day range in filter pill when drilling into a month", () => { - setup("month"); - cartesianChartCircle().eq(0).click({ force: true }); - popover().contains("See this Order").click(); - cy.findByTestId("qb-filters-panel") - .contains("Created At is April 2022") - .click(); - popover().within(() => { - cy.findByTestId("between-date-picker").within(() => { - datePickerInput(0, 0).should("have.value", "04/01/2022"); - datePickerInput(1, 0).should("have.value", "04/30/2022"); - }); - }); - }); - it("should display correct day range in filter pill when drilling into a hour", () => { - setup("hour"); - cartesianChartCircle().eq(0).click({ force: true }); - popover().contains("See this Order").click(); - cy.findByTestId("qb-filters-panel") - .contains("Created At is April 30, 2022, 6:00–59 PM") - .click(); - popover().within(() => { - cy.findByTestId("between-date-picker").within(() => { - datePickerInput(0, 0).should("have.value", "04/30/2022"); - datePickerInput(0, 1).should("have.value", "6"); - datePickerInput(0, 2).should("have.value", "00"); - datePickerInput(1, 0).should("have.value", "04/30/2022"); - datePickerInput(1, 1).should("have.value", "6"); - datePickerInput(1, 2).should("have.value", "59"); - }); - }); - }); - it("should display correct minute in filter pill when drilling into a minute", () => { - setup("minute"); - cartesianChartCircle().eq(0).click({ force: true }); - popover().contains("See this Order").click(); - cy.findByTestId("qb-filters-panel") - .contains("Created At is April 30, 2022, 6:56 PM") - .click(); - popover().within(() => { - datePickerInput(0, 0).should("have.value", "04/30/2022"); - datePickerInput(0, 1).should("have.value", "6"); - datePickerInput(0, 2).should("have.value", "56"); - }); - }); - it("should display correct minute in filter pill when drilling into a day", () => { - setup("day"); - cartesianChartCircle().eq(0).click({ force: true }); - popover().contains("See this Order").click(); - cy.findByTestId("qb-filters-panel") - .contains("Created At is April 30, 2022") - .click(); - popover().within(() => { - datePickerInput(0, 0).should("have.value", "04/30/2022"); - }); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/16621-create-multiple-filters-with-same-value.cy.spec.js b/e2e/test/scenarios/filters/reproductions/16621-create-multiple-filters-with-same-value.cy.spec.js deleted file mode 100644 index 17db4312c88..00000000000 --- a/e2e/test/scenarios/filters/reproductions/16621-create-multiple-filters-with-same-value.cy.spec.js +++ /dev/null @@ -1,34 +0,0 @@ -import { - restore, - openProductsTable, - popover, - tableHeaderClick, -} from "e2e/support/helpers"; - -describe("issue 16621", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - openProductsTable({ limit: 3 }); - }); - - it("should be possible to create multiple filter that start with the same value (metabase#16621)", () => { - tableHeaderClick("Category"); - popover().within(() => { - cy.findByText("Filter by this column").click(); - cy.findByPlaceholderText("Search the list").type("Gadget"); - cy.findByText("Gadget").click(); - cy.button("Add filter").click(); - }); - cy.findByTestId("qb-filters-panel").within(() => { - cy.findByText("Category is Gadget").click(); - }); - popover().within(() => { - cy.findByText("Gizmo").click(); - cy.button("Update filter").click(); - }); - cy.findByTestId("qb-filters-panel") - .findByText("Category is 2 selections") - .should("be.visible"); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/18770-post-aggregation-filter-disrupts-drillthrough.cy.spec.js b/e2e/test/scenarios/filters/reproductions/18770-post-aggregation-filter-disrupts-drillthrough.cy.spec.js deleted file mode 100644 index e635c78bd19..00000000000 --- a/e2e/test/scenarios/filters/reproductions/18770-post-aggregation-filter-disrupts-drillthrough.cy.spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { restore, popover, visualize } from "e2e/support/helpers"; - -const { ORDERS_ID, PRODUCTS, ORDERS } = SAMPLE_DATABASE; - -const questionDetails = { - name: "18770", - query: { - "source-query": { - aggregation: [["count"]], - "source-table": ORDERS_ID, - breakout: [ - ["field", PRODUCTS.TITLE, { "source-field": ORDERS.PRODUCT_ID }], - ], - }, - filter: [">", ["field", "count", { "base-type": "type/Integer" }], 0], - }, -}; - -describe.skip("issue 18770", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - cy.createQuestion(questionDetails, { visitQuestion: true }); - }); - - it("post-aggregation filter shouldn't affect the drill-through options (metabase#18770)", () => { - cy.icon("notebook").click(); - // It is important to manually triger "visualize" in order to generate `result_metadata` - // Otherwise, we might get false negative even when this issue gets resolved. - // In order to do that, we have to change the breakout field first or it will never generate and send POST /api/dataset request. - cy.findAllByTestId("notebook-cell-item") - .contains(/Products? → Title/) - .click(); - popover().findByText("Category").click(); - cy.findAllByTestId("notebook-cell-item").contains(/Products? → Category/); - - visualize(); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("4,784").click(); - popover() - .should("contain", "See these Orders") - .and("contain", "Break out by a…") - .and("contain", "Filter by this value") - .and("contain", "Automatic explorations"); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/20551-filter-starts-with.cy.spec.js b/e2e/test/scenarios/filters/reproductions/20551-filter-starts-with.cy.spec.js deleted file mode 100644 index 670365cb798..00000000000 --- a/e2e/test/scenarios/filters/reproductions/20551-filter-starts-with.cy.spec.js +++ /dev/null @@ -1,28 +0,0 @@ -import { - restore, - openProductsTable, - filter, - popover, -} from "e2e/support/helpers"; - -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" }); - - popover().within(() => { - cy.findByText("Category").click(); - cy.findByPlaceholderText("Search the list").type("i"); - - cy.findByText("Doohickey").should("be.visible"); - cy.findByText("Gizmo").should("be.visible"); - cy.findByText("Widget").should("be.visible"); - cy.findByText("Gadget").should("not.exist"); - }); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/20683-postgres-current-quarter.cy.spec.js b/e2e/test/scenarios/filters/reproductions/20683-postgres-current-quarter.cy.spec.js deleted file mode 100644 index 3a8d773bd76..00000000000 --- a/e2e/test/scenarios/filters/reproductions/20683-postgres-current-quarter.cy.spec.js +++ /dev/null @@ -1,42 +0,0 @@ -import { - entityPickerModal, - entityPickerModalTab, - getNotebookStep, - popover, - queryBuilderMain, - restore, - startNewQuestion, - visualize, -} from "e2e/support/helpers"; - -describe("issue 20683", { tags: "@external" }, () => { - beforeEach(() => { - restore("postgres-12"); - cy.signInAsAdmin(); - }); - - it("should filter postgres with the 'current quarter' filter (metabase#20683)", () => { - startNewQuestion(); - entityPickerModal().within(() => { - entityPickerModalTab("Tables").click(); - cy.findByText("QA Postgres12").click(); - cy.findByText("Orders").click(); - }); - - getNotebookStep("filter") - .findByText(/Add filter/) - .click(); - - popover().within(() => { - cy.findByText("Created At").click(); - cy.findByText("Relative dates…").click(); - cy.findByText("Past").click(); - cy.findByText("Current").click(); - cy.findByText("Quarter").click(); - }); - - visualize(); - - queryBuilderMain().findByText("No results!").should("be.visible"); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/21979-exclude-day-of-the-week.cy.spec.js b/e2e/test/scenarios/filters/reproductions/21979-exclude-day-of-the-week.cy.spec.js deleted file mode 100644 index 6a5aed0c63f..00000000000 --- a/e2e/test/scenarios/filters/reproductions/21979-exclude-day-of-the-week.cy.spec.js +++ /dev/null @@ -1,59 +0,0 @@ -import { - filter, - openProductsTable, - restore, - popover, - getNotebookStep, - visualize, - queryBuilderMain, -} from "e2e/support/helpers"; - -describe("issue 21979", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - cy.intercept("POST", "/api/dataset").as("dataset"); - }); - - it("exclude 'day of the week' should show the correct day reference in the UI (metabase#21979)", () => { - openProductsTable({ mode: "notebook" }); - - filter({ mode: "notebook" }); - popover().within(() => { - cy.findByText("Created At").click(); - cy.findByText("Exclude…").click(); - cy.findByText("Days of the week…").click(); - cy.findByLabelText("Monday").click(); - cy.button("Add filter").click(); - }); - - getNotebookStep("filter") - .findByText("Created At excludes Mondays") - .should("be.visible"); - - visualize(); - - // Make sure the query is correct - // (a product called "Enormous Marble Wallet" is created on Monday) - queryBuilderMain().findByText("Enormous Marble Wallet").should("not.exist"); - - cy.findByTestId("qb-filters-panel") - .findByText("Created At excludes Mondays") - .click(); - - popover().within(() => { - cy.findByLabelText("Monday").click(); - cy.findByLabelText("Thursday").click(); - cy.button("Update filter").click(); - }); - cy.wait("@dataset"); - - queryBuilderMain() - .findByText("Enormous Marble Wallet") - .should("be.visible"); - - cy.findByTestId("qb-filters-panel") - .findByText("Created At excludes Thursdays") - .should("be.visible"); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/22230-filter-on-aggregation-max-of.cy.spec.js b/e2e/test/scenarios/filters/reproductions/22230-filter-on-aggregation-max-of.cy.spec.js deleted file mode 100644 index 6a67978e66b..00000000000 --- a/e2e/test/scenarios/filters/reproductions/22230-filter-on-aggregation-max-of.cy.spec.js +++ /dev/null @@ -1,56 +0,0 @@ -import { SAMPLE_DB_ID } from "e2e/support/cypress_data"; -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - assertQueryBuilderRowCount, - restore, - visitQuestionAdhoc, - popover, - visualize, - queryBuilderMain, -} from "e2e/support/helpers"; - -const { PEOPLE, PEOPLE_ID } = SAMPLE_DATABASE; - -const questionDetails = { - dataset_query: { - database: SAMPLE_DB_ID, - query: { - "source-table": PEOPLE_ID, - aggregation: [["max", ["field", PEOPLE.NAME, null]]], - breakout: [["field", PEOPLE.SOURCE, null]], - }, - type: "query", - display: "table", - }, -}; - -describe("issue 22230", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - visitQuestionAdhoc(questionDetails, { mode: "notebook" }); - }); - - it("should be able to filter on an aggregation (metabase#22230)", () => { - cy.findAllByTestId("action-buttons").last().findByText("Filter").click(); - - popover().within(() => { - cy.findByText("Max of Name").click(); - cy.findByDisplayValue("Is").click(); - }); - cy.findByRole("listbox").findByText("Starts with").click(); - - popover().within(() => { - cy.findByPlaceholderText("Enter some text").type("Zo").blur(); - cy.button("Add filter").click(); - }); - - visualize(); - - assertQueryBuilderRowCount(2); - queryBuilderMain(() => { - cy.findByText("Zora Schamberger").should("be.visible"); - cy.findByText("Zoie Kozey").should("be.visible"); - }); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/22730-table-column-time-filter.cy.spec.js b/e2e/test/scenarios/filters/reproductions/22730-table-column-time-filter.cy.spec.js deleted file mode 100644 index 8511ee9682f..00000000000 --- a/e2e/test/scenarios/filters/reproductions/22730-table-column-time-filter.cy.spec.js +++ /dev/null @@ -1,40 +0,0 @@ -import { restore, popover, tableHeaderClick } from "e2e/support/helpers"; - -describe("issue 22730", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - cy.createNativeQuestion( - { - name: "22730", - native: { - query: - "select '14:02:13'::time \"time\", 'before-row' \"name\" union all select '14:06:13'::time \"time\", 'after-row' ", - }, - }, - { visitQuestion: true }, - ); - - cy.intercept("POST", "/api/dataset").as("dataset"); - }); - - it("allows filtering by time column (metabase#22730)", () => { - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Explore results").click(); - cy.wait("@dataset"); - - tableHeaderClick("time"); - - popover().within(() => { - cy.findByText("Filter by this column").click(); - cy.findByDisplayValue("00:00").clear().type("14:03"); - cy.button("Add filter").click(); - }); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("before-row"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("after-row").should("not.exist"); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/24664-multiple-filters-editing.cy.spec.js b/e2e/test/scenarios/filters/reproductions/24664-multiple-filters-editing.cy.spec.js deleted file mode 100644 index 864bc4df5bc..00000000000 --- a/e2e/test/scenarios/filters/reproductions/24664-multiple-filters-editing.cy.spec.js +++ /dev/null @@ -1,39 +0,0 @@ -import { - restore, - openProductsTable, - popover, - tableHeaderClick, -} from "e2e/support/helpers"; - -describe("issue 24664", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - openProductsTable({ limit: 3 }); - }); - - it("should be possible to create multiple filter that start with the same value (metabase#24664)", () => { - tableHeaderClick("Category"); - popover().within(() => { - cy.findByText("Filter by this column").click(); - cy.findByText("Doohickey").click(); - cy.button("Add filter").click(); - }); - - tableHeaderClick("Category"); - popover().within(() => { - cy.findByText("Filter by this column").click(); - cy.findByText("Gizmo").click(); - cy.button("Add filter").click(); - }); - - cy.findByTestId("qb-filters-panel").findByText("Category is Gizmo").click(); - popover().within(() => { - cy.findByText("Widget").click(); - cy.button("Update filter").click(); - }); - - // First filter is still there - cy.findByTestId("qb-filters-panel").findByText("Category is Doohickey"); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/24994-update-filters.cy.spec.js b/e2e/test/scenarios/filters/reproductions/24994-update-filters.cy.spec.js deleted file mode 100644 index 1df16a80a96..00000000000 --- a/e2e/test/scenarios/filters/reproductions/24994-update-filters.cy.spec.js +++ /dev/null @@ -1,67 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { restore } from "e2e/support/helpers"; - -const { PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE; - -const questionDetails = { - query: { - "source-query": { - "source-table": PRODUCTS_ID, - filter: [ - "and", - ["=", ["field", PRODUCTS.CATEGORY, null], "Gadget", "Gizmo"], - [ - "time-interval", - ["field", PRODUCTS.CREATED_AT, null], - -30, - "year", - { - include_current: false, - }, - ], - ], - aggregation: [["count"]], - breakout: [["field", PRODUCTS.CATEGORY, null]], - }, - filter: [ - ">", - [ - "field", - "count", - { - "base-type": "type/Integer", - }, - ], - 0, - ], - }, -}; - -describe("issue 24994", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should allow updating filters (metabase#24994)", () => { - cy.createQuestion(questionDetails, { visitQuestion: true }); - - // Three filters - cy.findByTestId("filters-visibility-control").contains("3").click(); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Category is 2 selections").click(); - assertFilterValueIsSelected("Gadget"); - assertFilterValueIsSelected("Gizmo"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Doohickey").click(); - assertFilterValueIsSelected("Doohickey"); - cy.button("Update filter").should("not.be.disabled").click(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Category is 3 selections"); - }); -}); - -function assertFilterValueIsSelected(value) { - cy.findByRole("checkbox", { name: value }).should("be.checked"); -} diff --git a/e2e/test/scenarios/filters/reproductions/25378-relative-date-on-breakout.cy.spec.js b/e2e/test/scenarios/filters/reproductions/25378-relative-date-on-breakout.cy.spec.js deleted file mode 100644 index 636de0a19a2..00000000000 --- a/e2e/test/scenarios/filters/reproductions/25378-relative-date-on-breakout.cy.spec.js +++ /dev/null @@ -1,51 +0,0 @@ -import { SAMPLE_DB_ID } from "e2e/support/cypress_data"; -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - restore, - visitQuestionAdhoc, - popover, - visualize, -} from "e2e/support/helpers"; - -const { ORDERS, ORDERS_ID } = SAMPLE_DATABASE; - -const questionDetails = { - name: "25378", - dataset_query: { - type: "query", - query: { - "source-table": ORDERS_ID, - aggregation: [["count"]], - breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }]], - }, - database: SAMPLE_DB_ID, - }, - display: "line", -}; - -describe("issue 25378", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - visitQuestionAdhoc(questionDetails, { mode: "notebook" }); - }); - - it("should be able to use relative date filter on a breakout after the aggregation (metabase#25378)", () => { - cy.findAllByTestId("action-buttons").last().findByText("Filter").click(); - - popover().within(() => { - cy.findByText("Created At: Month").click(); - cy.findByText("Relative dates…").click(); - cy.findByDisplayValue("days").click(); - }); - cy.findByRole("listbox").findByText("months").click(); - popover().findByLabelText("Options").click(); - popover().last().findByText("Starting from…").click(); - - popover().button("Add filter").click(); - - visualize(response => { - expect(response.body.error).to.not.exist; - }); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/25927-column-filters-not-working-after-cc.cy.spec.js b/e2e/test/scenarios/filters/reproductions/25927-column-filters-not-working-after-cc.cy.spec.js deleted file mode 100644 index 6eb7d131528..00000000000 --- a/e2e/test/scenarios/filters/reproductions/25927-column-filters-not-working-after-cc.cy.spec.js +++ /dev/null @@ -1,53 +0,0 @@ -import { SAMPLE_DB_ID } from "e2e/support/cypress_data"; -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - popover, - restore, - tableHeaderClick, - visitQuestionAdhoc, -} from "e2e/support/helpers"; - -const { ORDERS, ORDERS_ID } = SAMPLE_DATABASE; - -const query = { - dataset_query: { - database: SAMPLE_DB_ID, - query: { - "source-query": { - "source-table": ORDERS_ID, - aggregation: [["count"]], - breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }]], - }, - expressions: { - "Custom Count": ["field", "count", { "base-type": "type/Integer" }], - }, - }, - type: "query", - }, - display: "table", -}; - -describe("issue 25927", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - visitQuestionAdhoc(query); - }); - - it("column filter should work for questions with custom column (metabase#25927)", () => { - tableHeaderClick("Created At: Month"); - popover().within(() => { - cy.findByText("Filter by this column").click(); - cy.findByText("Last 30 days").click(); - }); - - cy.wait("@dataset"); - - // Click on the filter again to try updating it - cy.findByTestId("qb-filters-panel") - .contains("Created At: Month is in the previous 30 days") - .click(); - - popover().button("Update filter").should("not.be.disabled"); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/25990-filter-nested-join.cy.spec.js b/e2e/test/scenarios/filters/reproductions/25990-filter-nested-join.cy.spec.js deleted file mode 100644 index 8fffb16662a..00000000000 --- a/e2e/test/scenarios/filters/reproductions/25990-filter-nested-join.cy.spec.js +++ /dev/null @@ -1,63 +0,0 @@ -import { SAMPLE_DB_ID } from "e2e/support/cypress_data"; -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - restore, - visitQuestionAdhoc, - queryBuilderHeader, - modal, -} from "e2e/support/helpers"; - -const { ORDERS, ORDERS_ID, PEOPLE, PEOPLE_ID } = SAMPLE_DATABASE; - -const questionDetails = { - dataset_query: { - type: "query", - database: SAMPLE_DB_ID, - query: { - "source-query": { - "source-table": ORDERS_ID, - joins: [ - { - fields: "all", - "source-table": PEOPLE_ID, - condition: [ - "=", - ["field", ORDERS.USER_ID, null], - ["field", PEOPLE.ID, { "join-alias": "People - User" }], - ], - alias: "People - User", - }, - ], - aggregation: [["count"]], - breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }]], - }, - filter: [">", ["field", "count", { "base-type": "type/Integer" }], 0], - }, - }, -}; - -describe("issue 25990", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - cy.intercept("POST", "/api/dataset").as("dataset"); - }); - - it("should allow to filter by a column in a joined table (metabase#25990)", () => { - visitQuestionAdhoc(questionDetails); - - queryBuilderHeader().button("Filter").click(); - - modal().within(() => { - cy.findByText("Person").click(); - cy.findByPlaceholderText("Enter an ID").type("10").blur(); - cy.button("Apply filters").click(); - }); - - cy.wait("@dataset"); - - cy.findByTestId("qb-filters-panel") - .findByText("People - User → ID is 10") - .should("be.visible"); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/25994-between-after-summarize-not-working.cy.spec.js b/e2e/test/scenarios/filters/reproductions/25994-between-after-summarize-not-working.cy.spec.js deleted file mode 100644 index 45f9edf1202..00000000000 --- a/e2e/test/scenarios/filters/reproductions/25994-between-after-summarize-not-working.cy.spec.js +++ /dev/null @@ -1,48 +0,0 @@ -import { SAMPLE_DB_ID } from "e2e/support/cypress_data"; -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - restore, - visitQuestionAdhoc, - popover, - visualize, -} from "e2e/support/helpers"; - -const { PRODUCTS, PRODUCTS_ID } = SAMPLE_DATABASE; - -const questionDetails = { - dataset_query: { - type: "query", - query: { - "source-table": PRODUCTS_ID, - aggregation: [ - ["min", ["field", PRODUCTS.CREATED_AT, { "temporal-unit": "day" }]], - ], - breakout: [["field", PRODUCTS.CATEGORY, null]], - }, - database: SAMPLE_DB_ID, - }, -}; - -describe("issue 25994", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - visitQuestionAdhoc(questionDetails, { mode: "notebook" }); - }); - - it("should be possible to use 'between' dates filter after aggregation (metabase#25994)", () => { - cy.findAllByTestId("action-buttons").last().findByText("Filter").click(); - - popover().within(() => { - cy.findByText("Min of Created At: Day").click(); - cy.findByText("Specific dates…").click(); - - // It doesn't really matter which dates we select so let's go with whatever is offered - cy.button("Add filter").click(); - }); - - visualize(response => { - expect(response.body.error).to.not.exist; - }); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/26861-exclude-breaks-native.cy.spec.js b/e2e/test/scenarios/filters/reproductions/26861-exclude-breaks-native.cy.spec.js deleted file mode 100644 index c39830f747a..00000000000 --- a/e2e/test/scenarios/filters/reproductions/26861-exclude-breaks-native.cy.spec.js +++ /dev/null @@ -1,56 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { restore, filterWidget } from "e2e/support/helpers"; - -const { ORDERS } = SAMPLE_DATABASE; - -const filter = { - id: "a3b95feb-b6d2-33b6-660b-bb656f59b1d7", - name: "filter", - "display-name": "Filter", - type: "dimension", - dimension: ["field", ORDERS.CREATED_AT, null], - "widget-type": "date/all-options", - default: null, -}; - -const nativeQuery = { - name: "26861", - native: { - query: "select * from orders where {{filter}} limit 2", - "template-tags": { - filter, - }, - }, -}; - -describe.skip("issue 26861", () => { - beforeEach(() => { - cy.intercept("POST", "/api/dataset").as("dataset"); - - restore(); - cy.signInAsAdmin(); - - cy.createNativeQuestion(nativeQuery, { visitQuestion: true }); - }); - - it("exclude filter shouldn't break native questions with field filters (metabase#26861)", () => { - filterWidget().click(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Exclude...").click(); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Days of the week...").click(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Tuesday").click(); - - cy.button("Update filter").click(); - // In all other places in application, POST /api/dataset fires immediately after "Update filter" - // A part of this bug is that we have to manually run the query so the next step will fail - cy.wait("@dataset"); - - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("CREATED_AT excludes Tuesday"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("117.03").should("not.exist"); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/27123-exclude-always-shows-days-of-week.cy.spec.js b/e2e/test/scenarios/filters/reproductions/27123-exclude-always-shows-days-of-week.cy.spec.js deleted file mode 100644 index 3c43384c021..00000000000 --- a/e2e/test/scenarios/filters/reproductions/27123-exclude-always-shows-days-of-week.cy.spec.js +++ /dev/null @@ -1,34 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { restore, popover, tableHeaderClick } from "e2e/support/helpers"; - -const { ORDERS_ID } = SAMPLE_DATABASE; - -const questionDetails = { - query: { - "source-table": ORDERS_ID, - limit: 100, - }, -}; - -describe("issue 27123", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - cy.createQuestion(questionDetails, { visitQuestion: true }); - }); - - it("exclude filter should not resolve to 'Days of the week' regardless of the chosen granularity (metabase#27123)", () => { - tableHeaderClick("Created At"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Filter by this column").click(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Exclude…").click(); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Months of the year…").click(); - - popover() - .should("contain", "Months of the year…") - .and("contain", "January"); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/29094-non-boolean-custom-expressions.cy.spec.js b/e2e/test/scenarios/filters/reproductions/29094-non-boolean-custom-expressions.cy.spec.js deleted file mode 100644 index c3af8293005..00000000000 --- a/e2e/test/scenarios/filters/reproductions/29094-non-boolean-custom-expressions.cy.spec.js +++ /dev/null @@ -1,37 +0,0 @@ -import { - enterCustomColumnDetails, - entityPickerModal, - entityPickerModalTab, - getNotebookStep, - popover, - restore, - startNewQuestion, -} from "e2e/support/helpers"; - -describe("issue 29094", () => { - beforeEach(() => { - restore(); - cy.signInAsNormalUser(); - }); - - it("disallows adding a filter using non-boolean custom expression (metabase#29094)", () => { - startNewQuestion(); - - entityPickerModal().within(() => { - entityPickerModalTab("Tables").click(); - cy.findByText("Orders").click(); - }); - - getNotebookStep("filter") - .findByText("Add filters to narrow your answer") - .click(); - - popover().within(() => { - cy.findByText("Custom Expression").click(); - enterCustomColumnDetails({ formula: "[Tax] * 22" }); - cy.realPress("Tab"); - cy.button("Done").should("be.disabled"); - cy.findByText("Invalid expression").should("exist"); - }); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/30312-drill-filter-on-aggregated-column.cy.spec.js b/e2e/test/scenarios/filters/reproductions/30312-drill-filter-on-aggregated-column.cy.spec.js deleted file mode 100644 index 1292acc9a96..00000000000 --- a/e2e/test/scenarios/filters/reproductions/30312-drill-filter-on-aggregated-column.cy.spec.js +++ /dev/null @@ -1,56 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - popover, - queryBuilderMain, - restore, - selectFilterOperator, - tableHeaderClick, -} from "e2e/support/helpers"; - -const { ORDERS, ORDERS_ID } = SAMPLE_DATABASE; - -const CREATED_AT_BREAKOUT = [ - "field", - ORDERS.CREATED_AT, - { - "base-type": "type/DateTime", - "temporal-unit": "month", - }, -]; - -describe("issue 30312", () => { - beforeEach(() => { - restore(); - cy.signInAsNormalUser(); - }); - - it("can use a drill filter on an aggregated column (metabase#30312)", () => { - cy.createQuestion( - { - query: { - "source-table": ORDERS_ID, - aggregation: [["count"]], - breakout: [CREATED_AT_BREAKOUT], - limit: 5, // optimization - }, - display: "table", - }, - { visitQuestion: true }, - ); - - cy.findAllByTestId("header-cell").eq(1).should("have.text", "Count"); - - tableHeaderClick("Count"); - - popover().findByText("Filter by this column").click(); - selectFilterOperator("Equal to"); - popover().within(() => { - cy.findByPlaceholderText("Enter a number").type("10"); - cy.realPress("Tab"); - cy.button("Add filter").should("be.enabled").click(); - }); - - cy.findByTestId("filter-pill").should("have.text", "Count is equal to 10"); - queryBuilderMain().findByText("No results!").should("be.visible"); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/31340-long-column-name-search-results.cy.spec.js b/e2e/test/scenarios/filters/reproductions/31340-long-column-name-search-results.cy.spec.js deleted file mode 100644 index 7235ede263c..00000000000 --- a/e2e/test/scenarios/filters/reproductions/31340-long-column-name-search-results.cy.spec.js +++ /dev/null @@ -1,57 +0,0 @@ -import { SAMPLE_DB_ID, SAMPLE_DB_SCHEMA_ID } from "e2e/support/cypress_data"; -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { - popover, - restore, - selectFilterOperator, - tableHeaderClick, -} from "e2e/support/helpers"; - -const { PEOPLE_ID } = SAMPLE_DATABASE; - -const LONG_COLUMN_NAME = - "Some very very very very long column name that should have a line break"; - -describe("issue 31340", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - - cy.intercept("PUT", "/api/field/*").as("fieldUpdate"); - cy.intercept("GET", "/api/field/*/search/*").as("search"); - - cy.visit( - `/admin/datamodel/database/${SAMPLE_DB_ID}/schema/${SAMPLE_DB_SCHEMA_ID}/table/${PEOPLE_ID}`, - ); - - cy.findByTestId("column-PASSWORD") - .findByDisplayValue("Password") - .type(`{selectAll}${LONG_COLUMN_NAME}`) - .blur(); - - cy.wait("@fieldUpdate"); - - cy.createQuestion( - { - query: { - "source-table": PEOPLE_ID, - limit: 2, - }, - }, - { visitQuestion: true }, - ); - }); - - it("should properly display long column names in filter options search results (metabase#31340)", () => { - tableHeaderClick(LONG_COLUMN_NAME); - - popover().findByText("Filter by this column").click(); - selectFilterOperator("Is"); - popover().within(() => { - cy.findByPlaceholderText(`Search by ${LONG_COLUMN_NAME}`).type( - "nonexistingvalue", - ); - cy.wait("@search"); - }); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/34794-filter-popover-navigation-error.cy.spec.js b/e2e/test/scenarios/filters/reproductions/34794-filter-popover-navigation-error.cy.spec.js deleted file mode 100644 index cd975570517..00000000000 --- a/e2e/test/scenarios/filters/reproductions/34794-filter-popover-navigation-error.cy.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -import { - filter, - getNotebookStep, - openOrdersTable, - popover, - restore, -} from "e2e/support/helpers"; - -describe("issue 34794", () => { - beforeEach(() => { - restore(); - cy.signInAsNormalUser(); - }); - - it("should not crash when navigating to filter popover's custom expression section (metabase#34794)", () => { - openOrdersTable({ mode: "notebook" }); - - filter({ mode: "notebook" }); - popover().within(() => { - cy.findByText("Created At").click(); - cy.icon("chevronleft").click(); // go back to the main filter popover - cy.findByText("Custom Expression").click(); - cy.findByLabelText("Expression").type("[Total] > 10").blur(); - cy.button("Done").click(); - }); - - getNotebookStep("filter") - .findByText("Total is greater than 10") - .should("be.visible"); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/36508-number-of-distinct-values.cy.spec.ts b/e2e/test/scenarios/filters/reproductions/36508-number-of-distinct-values.cy.spec.ts deleted file mode 100644 index 1121b3b1f26..00000000000 --- a/e2e/test/scenarios/filters/reproductions/36508-number-of-distinct-values.cy.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; -import { createQuestion, modal, popover, restore } from "e2e/support/helpers"; - -const { PEOPLE, PEOPLE_ID } = SAMPLE_DATABASE; - -describe("issue 36508", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should treat 'Number of distinct values' aggregation as numerical (metabase#36508)", () => { - createQuestion( - { - query: { - "source-table": PEOPLE_ID, - aggregation: [ - ["distinct", ["field", PEOPLE.EMAIL, { "base-type": "type/Text" }]], - ], - breakout: [["field", PEOPLE.SOURCE, { "base-type": "type/Text" }]], - limit: 5, - }, - }, - { visitQuestion: true }, - ); - - cy.button("Filter").click(); - - modal().within(() => { - cy.findByText("Summaries").click(); - - cy.findByTestId("filter-column-Distinct values of Email") - .findByText("between") - .should("exist") - .click(); - }); - - popover().within(() => { - cy.findByText("Equal to").should("exist"); - cy.findByText("Greater than").should("exist"); - cy.findByText("Less than").should("exist"); - }); - }); -}); diff --git a/e2e/test/scenarios/filters/reproductions/9339-clipboard-numeric-filter.cy.spec.js b/e2e/test/scenarios/filters/reproductions/9339-clipboard-numeric-filter.cy.spec.js deleted file mode 100644 index 2f591dfb481..00000000000 --- a/e2e/test/scenarios/filters/reproductions/9339-clipboard-numeric-filter.cy.spec.js +++ /dev/null @@ -1,27 +0,0 @@ -import { - openOrdersTable, - restore, - selectFilterOperator, - tableHeaderClick, -} from "e2e/support/helpers"; - -describe("issue 9339", () => { - beforeEach(() => { - restore(); - cy.signInAsAdmin(); - }); - - it("should not paste non-numeric values into single-value numeric filters (metabase#9339)", () => { - openOrdersTable(); - - tableHeaderClick("Total"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("Filter by this column").click(); - selectFilterOperator("Greater than"); - cy.findByPlaceholderText("Enter a number").type("9339,1234").blur(); - cy.findByDisplayValue("9339").should("be.visible"); - // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage - cy.findByText("1,234").should("not.exist"); - cy.button("Add filter").should("be.enabled"); - }); -}); -- GitLab