Skip to content
Snippets Groups Projects
Unverified Commit 4c01a8cf authored by Nemanja Glumac's avatar Nemanja Glumac Committed by GitHub
Browse files

Refactor E2E tests in the `sharing` folder (#31455)

* Extract `questionDetails`

* Move `public-sharing` to the `sharing` folder

* Remove redundant test

This part was covered in `public-sharing.cy.spec.js`.

* Create a separate `public-dashboard` E2E spec

- Extract relevant part from `public.cy.spec.js`
- Make all tests in `public-dashboard.cy.spec.js` run in isolation

* Make tests in `public.cy.spec.js` run in isolation

* Remove redundant wait

* Limit the query results to speed test up

* Merge public questions E2E tests

* Merge `downloads` with the `sharing` E2E group

* Remove `downloads` from the folder list

* Refactor `public-dashboard.cy.spec.js`

- Clean up linter warnings by using semantic selectors
- Speed test up by using API
parent 3e47e170
Branches
Tags
No related merge requests found
Showing
with 238 additions and 322 deletions
......@@ -95,7 +95,6 @@ jobs:
- "custom-column"
- "dashboard"
- "dashboard-filters"
- "downloads"
- "embedding"
- "filters"
- "joins"
......@@ -263,7 +262,6 @@ jobs:
- "custom-column"
- "dashboard"
- "dashboard-filters"
- "downloads"
- "embedding"
- "filters"
- "joins"
......
import {
restore,
visitDashboard,
visitPublicDashboard,
filterWidget,
popover,
} from "e2e/support/helpers";
import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
const { PRODUCTS } = SAMPLE_DATABASE;
const questionDetails = {
name: "sql param",
native: {
query: "select count(*) from products where {{c}}",
"template-tags": {
c: {
id: "e126f242-fbaa-1feb-7331-21ac59f021cc",
name: "c",
"display-name": "Category",
type: "dimension",
dimension: ["field", PRODUCTS.CATEGORY, null],
default: null,
"widget-type": "category",
},
},
},
display: "scalar",
};
const filter = {
name: "Text",
slug: "text",
id: "4f37fd0d",
type: "string/=",
sectionId: "string",
};
const dashboardDetails = {
parameters: [filter],
};
const PUBLIC_DASHBOARD_REGEX =
/\/public\/dashboard\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/;
const COUNT_ALL = "200";
const COUNT_DOOHICKEY = "42";
const USERS = {
"admin user": () => cy.signInAsAdmin(),
"user with no permissions": () => cy.signIn("none"),
"anonymous user": () => cy.signOut(),
};
describe("scenarios > public > dashboard", () => {
beforeEach(() => {
restore();
cy.signInAsAdmin();
cy.request("PUT", "/api/setting/enable-public-sharing", { value: true });
cy.createNativeQuestionAndDashboard({
questionDetails,
dashboardDetails,
}).then(({ body: { id, card_id, dashboard_id } }) => {
cy.wrap(dashboard_id).as("dashboardId");
// Connect filter to the card
cy.request("PUT", `/api/dashboard/${dashboard_id}/cards`, {
cards: [
{
id,
card_id,
row: 0,
col: 0,
size_x: 8,
size_y: 6,
parameter_mappings: [
{
parameter_id: filter.id,
card_id,
target: ["dimension", ["template-tag", "c"]],
},
],
},
],
});
});
});
it("should allow users to create public dashboards", () => {
cy.get("@dashboardId").then(id => {
visitDashboard(id);
});
cy.icon("share").click();
cy.findByRole("heading", { name: "Enable sharing" })
.parent()
.findByRole("switch")
.check();
cy.findByRole("heading", { name: "Public link" })
.parent()
.findByDisplayValue(/^http/)
.then($input => {
expect($input.val()).to.match(PUBLIC_DASHBOARD_REGEX);
});
});
Object.entries(USERS).map(([userType, setUser]) =>
describe(`${userType}`, () => {
it(`should be able to view public dashboards`, () => {
cy.get("@dashboardId").then(id => {
cy.request("POST", `/api/dashboard/${id}/public_link`).then(
({ body: { uuid } }) => {
setUser();
cy.visit(`/public/dashboard/${uuid}`);
},
);
});
cy.get(".ScalarValue").should("have.text", COUNT_ALL);
filterWidget().click();
popover().within(() => {
cy.findByText("Doohickey").click();
cy.button("Add filter").click();
});
cy.get(".ScalarValue").should("have.text", COUNT_DOOHICKEY);
});
}),
);
it("should respect 'disable auto-apply filters' in a public dashboard", () => {
cy.get("@dashboardId").then(id => {
cy.request("PUT", `/api/dashboard/${id}`, {
auto_apply_filters: false,
});
visitPublicDashboard(id);
});
cy.get(".ScalarValue").should("have.text", COUNT_ALL);
cy.button("Apply").should("not.exist");
filterWidget().click();
popover().within(() => {
cy.findByText("Doohickey").click();
cy.button("Add filter").click();
});
cy.get(".ScalarValue").should("have.text", COUNT_ALL);
cy.button("Apply").should("be.visible").click();
cy.button("Apply").should("not.exist");
cy.get(".ScalarValue").should("have.text", COUNT_DOOHICKEY);
});
});
......@@ -10,9 +10,9 @@ import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
const { PEOPLE } = SAMPLE_DATABASE;
const questionData = {
name: "7210",
name: "Parameterized Public Question",
native: {
query: "SELECT * FROM PEOPLE WHERE {{birthdate}} AND {{source}}",
query: "SELECT * FROM PEOPLE WHERE {{birthdate}} AND {{source}} limit 5",
"template-tags": {
birthdate: {
id: "08c5ea9d-1579-3503-37f1-cbe4d29e6a28",
......@@ -36,87 +36,121 @@ const questionData = {
},
};
const PUBLIC_QUESTION_REGEX =
/\/public\/question\/[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/;
const EXPECTED_QUERY_PARAMS = "?birthdate=past30years&source=Affiliate";
describe("scenarios > question > public", () => {
const USERS = {
"admin user": () => cy.signInAsAdmin(),
"user with no permissions": () => cy.signIn("none"),
};
describe("scenarios > public > question", () => {
beforeEach(() => {
cy.intercept("POST", `/api/card/*/query`).as("cardQuery");
cy.intercept("GET", `/api/public/card/*/query?*`).as("publicQuery");
restore();
cy.signInAsAdmin();
cy.request("PUT", "/api/setting/enable-public-sharing", { value: true });
});
it("adds filters to url as get params and renders the results correctly (metabase#7120, metabase#17033)", () => {
cy.createNativeQuestion(questionData).then(({ body: { id } }) => {
enableSharingQuestion(id);
cy.wrap(id).as("questionId");
});
});
it("adds filters to url as get params and renders the results correctly (metabase#7120, metabase#17033, metabase#21993)", () => {
cy.get("@questionId").then(id => {
visitQuestion(id);
// Make sure metadata fully loaded before we continue
cy.wait("@cardQuery");
});
cy.icon("share").click();
// Make sure metadata fully loaded before we continue
cy.get(".cellData").contains("Winner");
visitPublicURL();
cy.icon("share").click();
// On page load, query params are added
cy.url().should("include", "/public/question");
cy.url().should("include", EXPECTED_QUERY_PARAMS);
enableSharing();
// Although we already have API helper `visitPublicQuestion`,
// it makes sense to use the UI here in order to check that the
// generated url originally doesn't include query params
visitPublicURL();
filterWidget().contains("Previous 30 Years");
filterWidget().contains("Affiliate");
// On page load, query params are added
cy.location("search").should("eq", EXPECTED_QUERY_PARAMS);
cy.wait("@publicQuery");
// Name of a city from the expected results
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.findByText("Winner");
});
filterWidget().contains("Previous 30 Years");
filterWidget().contains("Affiliate");
it("allows downloading publicly shared questions (metabase#21993)", () => {
const questionData = {
name: "21993",
native: {
query: "select * from orders",
},
};
cy.wait("@publicQuery");
// Name of a city from the expected results
cy.get(".cellData").contains("Winner");
cy.createNativeQuestion(questionData).then(({ body: { id } }) => {
enableSharingQuestion(id);
visitQuestion(id);
cy.icon("share").click();
visitPublicURL();
// Make sure we can download the public question (metabase#21993)
cy.icon("download").click();
cy.url().then(url => {
const publicUid = url.split("/").pop();
cy.get("@uuid").then(publicUid => {
downloadAndAssert(
{ fileType: "xlsx", questionId: id, publicUid },
assertSheetRowsCount(18760),
assertSheetRowsCount(5),
);
});
});
});
Object.entries(USERS).map(([userType, setUser]) =>
describe(`${userType}`, () => {
it(`should be able to view public questions`, () => {
cy.get("@questionId").then(id => {
cy.request("POST", `/api/card/${id}/public_link`).then(
({ body: { uuid } }) => {
setUser();
cy.visit(`/public/question/${uuid}`);
cy.location("search").should("eq", EXPECTED_QUERY_PARAMS);
filterWidget().contains("Previous 30 Years");
filterWidget().contains("Affiliate");
cy.get(".cellData").contains("Winner");
},
);
});
});
}),
);
});
const visitPublicURL = () => {
// Ideally we would just find the first input
// but unless we filter by value
// Cypress finds an input before the copyable inputs are rendered
cy.findByDisplayValue(/^http/)
cy.findByRole("heading", { name: "Public link" })
.parent()
.findByDisplayValue(/^http/)
.invoke("val")
.then(publicURL => {
// Copied URL has no get params
expect(publicURL).not.to.have.string(EXPECTED_QUERY_PARAMS);
expect(publicURL).to.match(PUBLIC_QUESTION_REGEX);
cy.signOut();
cy.visit(publicURL);
});
};
const enableSharingQuestion = id => {
cy.request("POST", `/api/card/${id}/public_link`);
const enableSharing = () => {
cy.intercept("POST", "/api/card/*/public_link").as("sharingEnabled");
cy.findByRole("heading", { name: "Enable sharing" })
.parent()
.findByRole("switch")
.check();
cy.wait("@sharingEnabled").then(
({
response: {
body: { uuid },
},
}) => {
cy.wrap(uuid).as("uuid");
},
);
};
import {
restore,
popover,
modal,
visitQuestion,
visitDashboard,
openQuestionActions,
rightSidebar,
} from "e2e/support/helpers";
import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database";
const { PRODUCTS } = SAMPLE_DATABASE;
const COUNT_ALL = "200";
const COUNT_DOOHICKEY = "42";
const PUBLIC_URL_REGEX = /\/public\/(question|dashboard)\/[0-9a-f-]+$/;
const USERS = {
"admin user": () => cy.signInAsAdmin(),
"user with no permissions": () => cy.signIn("none"),
"anonymous user": () => cy.signOut(),
};
describe("scenarios > public", () => {
let questionId;
before(() => {
restore();
cy.signInAsAdmin();
// setup parameterized question
cy.createNativeQuestion({
name: "sql param",
native: {
query: "select count(*) from products where {{c}}",
"template-tags": {
c: {
id: "e126f242-fbaa-1feb-7331-21ac59f021cc",
name: "c",
"display-name": "Category",
type: "dimension",
dimension: ["field", PRODUCTS.CATEGORY, null],
default: null,
"widget-type": "category",
},
},
},
display: "scalar",
}).then(({ body }) => {
questionId = body.id;
});
});
beforeEach(() => {
cy.signInAsAdmin();
});
let questionPublicLink;
let dashboardId;
let dashboardPublicLink;
describe("questions", () => {
// Note: Test suite is sequential, so individual test cases can't be run individually
it("should allow users to create parameterized dashboards", () => {
visitQuestion(questionId);
openQuestionActions();
popover().within(() => {
cy.findByText("Add to dashboard").click();
});
modal().contains("Create a new dashboard").click();
modal()
.get('input[name="name"]')
.type("parameterized dashboard", { delay: 0 });
modal().contains("Create").click();
cy.icon("filter").click();
popover().within(() => {
cy.findByText("Text or Category").click();
cy.findByText("Is").click();
});
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Select…").click();
popover().contains("Category").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Done").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Save").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.findByText("You're editing this dashboard.").should("not.exist");
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains(COUNT_ALL);
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Text")
.parent()
.parent()
.find("fieldset")
.should("not.exist");
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.findByText("Text").click();
popover().within(() => {
cy.findByText("Doohickey").click();
});
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Add filter").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains(COUNT_DOOHICKEY);
cy.url()
.should("match", /\/dashboard\/\d+[-\w]+\?text=Doohickey$/)
.then(url => {
dashboardId = parseInt(url.match(/dashboard\/(\d+)/)[1]);
});
});
it("should allow users to create public questions", () => {
cy.request("PUT", "/api/setting/enable-public-sharing", { value: true });
visitQuestion(questionId);
cy.icon("share").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Enable sharing")
.parent()
.find("input[type=checkbox]")
.check();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Public link")
.parent()
.find("input")
.should($input => {
expect($input[0].value).to.match(PUBLIC_URL_REGEX);
questionPublicLink = $input[0].value.match(PUBLIC_URL_REGEX)[0];
});
});
it("should allow users to create public dashboards", () => {
cy.request("PUT", "/api/setting/enable-public-sharing", { value: true });
visitDashboard(dashboardId);
cy.icon("share").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Enable sharing")
.parent()
.find("input[type=checkbox]")
.check();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Public link")
.parent()
.find("input")
.should($input => {
expect($input[0].value).to.match(PUBLIC_URL_REGEX);
dashboardPublicLink = $input[0].value.match(PUBLIC_URL_REGEX)[0];
});
});
it("should show shared questions and dashboards in admin settings", () => {
cy.visit("/admin/settings/public-sharing");
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.findByText("Enable Public Sharing").should("be.visible");
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.findByText(
"Enable admins to create publicly viewable links (and embeddable iframes) for Questions and Dashboards.",
).should("be.visible");
// shared questions
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.findByText("sql param").should("be.visible");
// shared dashboard
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.findByText("parameterized dashboard").should("be.visible");
});
Object.entries(USERS).map(([userType, setUser]) =>
describe(`${userType}`, () => {
beforeEach(setUser);
it(`should be able to view public questions`, () => {
cy.visit(questionPublicLink);
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains(COUNT_ALL);
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Category").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Doohickey").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Add filter").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains(COUNT_DOOHICKEY);
});
it(`should be able to view public dashboards`, () => {
cy.visit(dashboardPublicLink);
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains(COUNT_ALL);
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Text").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Doohickey").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Add filter").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains(COUNT_DOOHICKEY);
// Enter full-screen button
cy.icon("expand");
});
}),
);
describe("Disable auto-apply filters", () => {
before(() => {
cy.signInAsAdmin();
visitDashboard(dashboardId);
openDashboardSidebar();
rightSidebar()
.findByLabelText("Auto-apply filters")
.click()
.should("not.be.checked");
});
it("should be able to view public dashboards by anonymous users", () => {
cy.signOut();
cy.visit(dashboardPublicLink);
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains(COUNT_ALL);
cy.button("Apply").should("not.exist");
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Text").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Doohickey").click();
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains("Add filter").click();
cy.button("Apply").should("be.visible").click();
cy.button("Apply").should("not.exist");
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
cy.contains(COUNT_DOOHICKEY);
// Enter full-screen button
cy.icon("expand");
});
});
});
});
function openDashboardSidebar() {
cy.get("main header").within(() => {
cy.icon("info").click();
});
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment