Skip to content
Snippets Groups Projects
Unverified Commit cf543761 authored by Alexander Lesnenko's avatar Alexander Lesnenko Committed by GitHub
Browse files

add static viz e2e tests for multiseries line/area/bar/combo charts (#19396)

parent 781f7c80
No related merge requests found
......@@ -52,7 +52,7 @@ jobs:
uses: actions/setup-java@v2
with:
java-version: 8
distribution: 'temurin'
distribution: "temurin"
- name: Install Clojure CLI
run: |
curl -O https://download.clojure.org/install/linux-install-1.10.3.933.sh &&
......@@ -116,7 +116,7 @@ jobs:
uses: actions/setup-java@v2
with:
java-version: 8
distribution: 'temurin'
distribution: "temurin"
- name: Install Clojure CLI
run: |
curl -O https://download.clojure.org/install/linux-install-1.10.3.933.sh &&
......@@ -132,7 +132,6 @@ jobs:
path: ~/.cache/yarn
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
- run: yarn install --frozen-lockfile --prefer-offline
- uses: actions/download-artifact@v2
name: Retrieve uberjar artifact
with:
......@@ -141,7 +140,8 @@ jobs:
run: |
jar xf target/uberjar/metabase.jar version.properties
mv version.properties resources/
- name: Run maildev
run: docker run -d -p 80:80 -p 25:25 maildev/maildev
- name: Percy Test
run: yarn run test-visual-no-build
env:
......
......@@ -33,7 +33,7 @@ jobs:
uses: actions/setup-java@v2
with:
java-version: 8
distribution: 'temurin'
distribution: "temurin"
- name: Install Clojure CLI
run: |
curl -O https://download.clojure.org/install/linux-install-1.10.3.933.sh &&
......@@ -90,7 +90,7 @@ jobs:
uses: actions/setup-java@v2
with:
java-version: 8
distribution: 'temurin'
distribution: "temurin"
- name: Install Clojure CLI
run: |
curl -O https://download.clojure.org/install/linux-install-1.10.3.933.sh &&
......@@ -115,7 +115,8 @@ jobs:
run: |
jar xf target/uberjar/metabase.jar version.properties
mv version.properties resources/
- name: Run maildev
run: docker run -d -p 80:80 -p 25:25 maildev/maildev
- name: Percy Test
run: yarn run test-visual-no-build
env:
......
......@@ -13,6 +13,7 @@ import "./commands/api/user";
import "./commands/api/composite/createQuestionAndDashboard";
import "./commands/api/composite/createNativeQuestionAndDashboard";
import "./commands/api/composite/createQuestionAndAddToDashboard";
import "./commands/user/createUser";
import "./commands/user/authentication";
......
Cypress.Commands.add(
"createQuestionAndAddToDashboard",
(query, dashboardId) => {
return cy.createQuestion(query).then(response => {
cy.request("POST", `/api/dashboard/${dashboardId}/cards`, {
cardId: response.body.id,
});
});
},
);
Cypress.Commands.add("button", button_name => {
cy.findByRole("button", { name: button_name });
Cypress.Commands.add("button", (button_name, timeout) => {
cy.findByRole("button", { name: button_name, timeout: timeout });
});
......@@ -4,6 +4,7 @@
"integrationFolder": ".",
"supportFile": "frontend/test/__support__/e2e/cypress.js",
"videoUploadOnPasses": false,
"chromeWebSecurity": false,
"viewportHeight": 800,
"viewportWidth": 1280,
"retries": {
......
......@@ -94,3 +94,52 @@ export function interceptPromise(method, path) {
});
return state;
}
const chainStart = Symbol();
/**
* Waits for all Cypress commands similarly to Promise.all.
* Helps to avoid excessive nesting and verbosity
*
* @param {Array.<Cypress.Chainable<any>>} commands - Cypress commands
* @example
* cypressWaitAll([
* cy.createQuestionAndAddToDashboard(firstQuery, 1),
* cy.createQuestionAndAddToDashboard(secondQuery, 1),
* ]).then(() => {
* cy.visit(`/dashboard/1`);
* });
*/
export const cypressWaitAll = function(commands) {
const _ = Cypress._;
const chain = cy.wrap(null, { log: false });
const stopCommand = _.find(cy.queue.commands, {
attributes: { chainerId: chain.chainerId },
});
const startCommand = _.find(cy.queue.commands, {
attributes: { chainerId: commands[0].chainerId },
});
const p = chain.then(() => {
return _(commands)
.map(cmd => {
return cmd[chainStart]
? cmd[chainStart].attributes
: _.find(cy.queue.commands, {
attributes: { chainerId: cmd.chainerId },
}).attributes;
})
.concat(stopCommand.attributes)
.slice(1)
.flatMap(cmd => {
return cmd.prev.get("subject");
})
.value();
});
p[chainStart] = startCommand;
return p;
};
import { restore, setupSMTP, cypressWaitAll } from "__support__/e2e/cypress";
import { USERS } from "__support__/e2e/cypress_data";
import { SAMPLE_DATASET } from "__support__/e2e/cypress_sample_dataset";
const { ORDERS_ID, ORDERS, PRODUCTS } = SAMPLE_DATASET;
const { admin } = USERS;
const visualizationTypes = ["line", "area", "bar", "combo"];
const SENDING_EMAIL_TIMEOUT = 30000;
describe("static visualizations", () => {
beforeEach(() => {
restore();
cy.signInAsAdmin();
setupSMTP();
});
visualizationTypes.map(type => {
it(`${type} chart`, () => {
const dashboardName = `${type} charts dashboard`;
cy.createDashboard({ name: dashboardName })
.then(({ body: { id: dashboardId } }) => {
return cypressWaitAll([
createOneMetricTwoDimensionsQuestion(type, dashboardId),
createOneDimensionTwoMetricsQuestion(type, dashboardId),
]).then(() => {
cy.visit(`/dashboard/${dashboardId}`);
});
})
.then(() => {
cy.icon("share").click();
cy.findByText("Dashboard subscriptions").click();
cy.findByText("Email it").click();
cy.findByPlaceholderText("Enter user names or email addresses")
.click()
.type(`${admin.first_name} ${admin.last_name}{enter}`)
.blur();
cy.button("Send email now").click();
cy.button("Email sent", SENDING_EMAIL_TIMEOUT);
openEmailPage(dashboardName).then(() => {
cy.percySnapshot();
});
});
});
});
});
function createOneDimensionTwoMetricsQuestion(display, dashboardId) {
return cy.createQuestionAndAddToDashboard(
{
name: `${display} one dimension two metrics`,
query: {
"source-table": ORDERS_ID,
aggregation: [["count"], ["avg", ["field", ORDERS.TOTAL, null]]],
breakout: [["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }]],
},
visualization_settings: {
"graph.dimensions": ["CREATED_AT"],
"graph.metrics": ["count", "avg"],
},
display: display,
database: 1,
},
dashboardId,
);
}
function createOneMetricTwoDimensionsQuestion(display, dashboardId) {
return cy.createQuestionAndAddToDashboard(
{
name: `${display} one metric two dimensions`,
query: {
"source-table": ORDERS_ID,
aggregation: [["count"]],
breakout: [
["field", ORDERS.CREATED_AT, { "temporal-unit": "month" }],
["field", PRODUCTS.CATEGORY, { "source-field": ORDERS.PRODUCT_ID }],
],
},
visualization_settings: {
"graph.dimensions": ["CREATED_AT", "CATEGORY"],
"graph.metrics": ["count"],
},
display: display,
database: 1,
},
dashboardId,
);
}
function openEmailPage(emailSubject) {
cy.window().then(win => (win.location.href = "http://localhost"));
cy.findByText(emailSubject).click();
return cy.hash().then(path => {
const htmlPath = `http://localhost${path.slice(1)}/html`;
cy.window().then(win => (win.location.href = htmlPath));
cy.findByText(emailSubject);
});
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment