RFC 118. Prettier - arrowParens: “always” (#55807)
* Update .prettierrc - remove "arrowParens": "avoid" so that it defaults to "always" instead * Run "yarn prettier"
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
{
|
||||
"trailingComma": "all",
|
||||
"arrowParens": "avoid"
|
||||
"trailingComma": "all"
|
||||
}
|
||||
|
||||
@@ -114,10 +114,10 @@ const CypressBackend = {
|
||||
// This is needed until we can use NodeJS native `fetch`.
|
||||
function request(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = http.get(url, res => {
|
||||
const req = http.get(url, (res) => {
|
||||
let body = "";
|
||||
|
||||
res.on("data", chunk => {
|
||||
res.on("data", (chunk) => {
|
||||
body += chunk;
|
||||
});
|
||||
|
||||
@@ -126,7 +126,7 @@ const CypressBackend = {
|
||||
});
|
||||
});
|
||||
|
||||
req.on("error", e => {
|
||||
req.on("error", (e) => {
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,7 +10,7 @@ const DEFAULT_PORT = 4000;
|
||||
const getHost = (port = null) =>
|
||||
`http://localhost:${port ?? process.env.BACKEND_PORT ?? DEFAULT_PORT}`;
|
||||
|
||||
const getSampleAppE2eConfig = suite => ({
|
||||
const getSampleAppE2eConfig = (suite) => ({
|
||||
[suite]: async () => {
|
||||
const { appName, env } = SAMPLE_APP_SETUP_CONFIGS[suite];
|
||||
const { CLIENT_PORT } = env;
|
||||
|
||||
@@ -73,7 +73,7 @@ function unBooleanify(map) {
|
||||
}
|
||||
|
||||
function delay(durationMs) {
|
||||
return new Promise(resolve => setTimeout(resolve, durationMs));
|
||||
return new Promise((resolve) => setTimeout(resolve, durationMs));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -27,7 +27,7 @@ const startServer = async () => {
|
||||
await CypressBackend.start();
|
||||
};
|
||||
|
||||
const runTests = async testSuite => {
|
||||
const runTests = async (testSuite) => {
|
||||
printBold(`Running ${testSuite} Cypress Tests`);
|
||||
await runCypress(testSuite, process.exit);
|
||||
};
|
||||
|
||||
@@ -145,7 +145,7 @@ const cleanup = async (exitCode: string | number = SUCCESS_EXIT_CODE) => {
|
||||
|
||||
init()
|
||||
.then(() => cleanup(SUCCESS_EXIT_CODE))
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
cleanup(FAILURE_EXIT_CODE);
|
||||
});
|
||||
|
||||
@@ -42,7 +42,7 @@ export async function startContainers({
|
||||
}
|
||||
|
||||
if (!process.env.CI) {
|
||||
["exit", "SIGINT", "SIGTERM", "uncaughtException"].forEach(signal => {
|
||||
["exit", "SIGINT", "SIGTERM", "uncaughtException"].forEach((signal) => {
|
||||
process.on(signal, () => {
|
||||
console.log(`Parent received ${signal}, killing stopping app...`);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ describe("snapshots", () => {
|
||||
snapshot("setup");
|
||||
addUsersAndGroups();
|
||||
createCollections();
|
||||
withSampleDatabase(SAMPLE_DATABASE => {
|
||||
withSampleDatabase((SAMPLE_DATABASE) => {
|
||||
ensureTableIdsAreCorrect(SAMPLE_DATABASE);
|
||||
hideNewSampleTables(SAMPLE_DATABASE);
|
||||
createQuestionsAndDashboards(SAMPLE_DATABASE);
|
||||
@@ -112,7 +112,7 @@ describe("snapshots", () => {
|
||||
});
|
||||
|
||||
// update the Sample db connection string so it is valid in both CI and locally
|
||||
cy.request("GET", `/api/database/${SAMPLE_DB_ID}`).then(response => {
|
||||
cy.request("GET", `/api/database/${SAMPLE_DB_ID}`).then((response) => {
|
||||
response.body.details.db =
|
||||
"./plugins/sample-database.db;USER=GUEST;PASSWORD=guest";
|
||||
cy.request("PUT", `/api/database/${SAMPLE_DB_ID}`, response.body);
|
||||
@@ -143,14 +143,14 @@ describe("snapshots", () => {
|
||||
);
|
||||
|
||||
// Create all users except admin, who was already created in one of the previous steps
|
||||
Object.keys(_.omit(USERS, "admin")).forEach(user => {
|
||||
Object.keys(_.omit(USERS, "admin")).forEach((user) => {
|
||||
cy.createUser(user);
|
||||
});
|
||||
|
||||
// Make a call to `/api/user` because some things (personal collections) get created there
|
||||
cy.request("GET", "/api/user");
|
||||
|
||||
Object.keys(USERS).forEach(user => {
|
||||
Object.keys(USERS).forEach((user) => {
|
||||
if (user === "admin") {
|
||||
// we already cached admin user credentials during setup
|
||||
return;
|
||||
@@ -221,17 +221,18 @@ describe("snapshots", () => {
|
||||
}).then(({ body }) => callback && callback(body));
|
||||
}
|
||||
|
||||
postCollection("First collection", undefined, firstCollection => {
|
||||
postCollection("First collection", undefined, (firstCollection) => {
|
||||
logSelectModel(firstCollection.id, "collection");
|
||||
postCollection(
|
||||
"Second collection",
|
||||
firstCollection.id,
|
||||
secondCollection => {
|
||||
(secondCollection) => {
|
||||
logSelectModel(secondCollection.id, "collection");
|
||||
postCollection(
|
||||
"Third collection",
|
||||
secondCollection.id,
|
||||
thirdCollection => logSelectModel(thirdCollection.id, "collection"),
|
||||
(thirdCollection) =>
|
||||
logSelectModel(thirdCollection.id, "collection"),
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -309,9 +310,11 @@ describe("snapshots", () => {
|
||||
FEEDBACK_ID,
|
||||
INVOICES_ID,
|
||||
}) {
|
||||
[ACCOUNTS_ID, ANALYTIC_EVENTS_ID, FEEDBACK_ID, INVOICES_ID].forEach(id => {
|
||||
cy.request("PUT", `/api/table/${id}`, { visibility_type: "hidden" });
|
||||
});
|
||||
[ACCOUNTS_ID, ANALYTIC_EVENTS_ID, FEEDBACK_ID, INVOICES_ID].forEach(
|
||||
(id) => {
|
||||
cy.request("PUT", `/api/table/${id}`, { visibility_type: "hidden" });
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: It'd be nice to have one file per snapshot.
|
||||
@@ -387,8 +390,8 @@ function getDefaultInstanceData() {
|
||||
`/api/collection/${collection.id}/items?models=dashboard`,
|
||||
).then(({ body: { data: dashboards } }) => {
|
||||
for (const dashboard of dashboards) {
|
||||
if (!instanceData.dashboards.find(d => d.id === dashboard.id)) {
|
||||
cy.request(`/api/dashboard/${dashboard.id}`).then(response => {
|
||||
if (!instanceData.dashboards.find((d) => d.id === dashboard.id)) {
|
||||
cy.request(`/api/dashboard/${dashboard.id}`).then((response) => {
|
||||
instanceData.dashboards.push(response.body);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ function restoreAndAuthenticate() {
|
||||
}
|
||||
|
||||
function deleteDatabase(idAlias) {
|
||||
cy.get("@" + idAlias).then(id => {
|
||||
cy.get("@" + idAlias).then((id) => {
|
||||
return cy.request("DELETE", `/api/database/${id}`);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -41,10 +41,10 @@ const githubApi = ({
|
||||
};
|
||||
|
||||
function extractTestsFromCommentText(body: string) {
|
||||
const tableLines = body.split("\n").filter(line => line.includes("|"));
|
||||
const tableLines = body.split("\n").filter((line) => line.includes("|"));
|
||||
const testLines = tableLines.slice(2);
|
||||
const testData = testLines.map(line => {
|
||||
const [fileName, testName] = line.split("|").map(cell => cell.trim());
|
||||
const testData = testLines.map((line) => {
|
||||
const [fileName, testName] = line.split("|").map((cell) => cell.trim());
|
||||
return { fileName, testName };
|
||||
});
|
||||
|
||||
|
||||
@@ -13,10 +13,10 @@ const path = require("path");
|
||||
* @returns
|
||||
*/
|
||||
const collectFailingTests = (on, config) => {
|
||||
on("after:run", async results => {
|
||||
on("after:run", async (results) => {
|
||||
const failedSpecs = results.runs
|
||||
.filter(run => run.stats.failures > 0)
|
||||
.map(run => run.spec.relative);
|
||||
.filter((run) => run.stats.failures > 0)
|
||||
.map((run) => run.spec.relative);
|
||||
|
||||
if (failedSpecs.length > 0) {
|
||||
const failedTestFilePath = "../../cypress/test-results/";
|
||||
|
||||
@@ -2,7 +2,7 @@ const fs = require("fs");
|
||||
|
||||
const path = require("path");
|
||||
|
||||
const removeDirectory = path => {
|
||||
const removeDirectory = (path) => {
|
||||
try {
|
||||
if (fs.existsSync(path)) {
|
||||
fs.rmdirSync(path, { maxRetries: 10, recursive: true });
|
||||
@@ -18,7 +18,7 @@ const removeDirectory = path => {
|
||||
const deleteDownloadsFolder = () =>
|
||||
cy.task("removeDirectory", Cypress.config("downloadsFolder"));
|
||||
|
||||
const isFileExist = path => fs.existsSync(path);
|
||||
const isFileExist = (path) => fs.existsSync(path);
|
||||
|
||||
const findFiles = ({ path, fileName }) => {
|
||||
if (!fs.existsSync(path)) {
|
||||
@@ -27,10 +27,10 @@ const findFiles = ({ path, fileName }) => {
|
||||
|
||||
return fs
|
||||
.readdirSync(path)
|
||||
.filter(file => file.includes(fileName) && isDownloaded(file));
|
||||
.filter((file) => file.includes(fileName) && isDownloaded(file));
|
||||
};
|
||||
|
||||
const isDownloaded = file => !file.endsWith(".crdownload");
|
||||
const isDownloaded = (file) => !file.endsWith(".crdownload");
|
||||
|
||||
// slightly modified version of cy-verify-download
|
||||
// https://github.com/elaichenkov/cy-verify-downloads/blob/master/src/index.js
|
||||
@@ -53,7 +53,7 @@ const verifyDownload = (fileName, options) => {
|
||||
|
||||
let retries = Math.floor(timeout / interval);
|
||||
|
||||
const checkFile = result => {
|
||||
const checkFile = (result) => {
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
@@ -75,7 +75,7 @@ const verifyDownload = (fileName, options) => {
|
||||
if (contains) {
|
||||
result = cy
|
||||
.task("findFiles", { path: downloadsFolder, fileName })
|
||||
.then(files => {
|
||||
.then((files) => {
|
||||
if (files !== null) {
|
||||
if (files.length > 1) {
|
||||
cy.log(
|
||||
@@ -96,7 +96,7 @@ const verifyDownload = (fileName, options) => {
|
||||
return result.then(checkFile);
|
||||
};
|
||||
|
||||
return resolveValue().then(isExist => {
|
||||
return resolveValue().then((isExist) => {
|
||||
expect(isExist, `The ${fileName} file has been downloaded successfully`).to
|
||||
.be.true;
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@ Cypress.Commands.add(
|
||||
// Extract the name of the table, as well as `schema` and `db_id` that we'll need later on for `cy.updatePermissionsSchemas()`
|
||||
cy.request("GET", "/api/table").then(({ body: tables }) => {
|
||||
const { name, schema, db_id } = tables.find(
|
||||
table => table.id === table_id,
|
||||
(table) => table.id === table_id,
|
||||
);
|
||||
const attr = Object.keys(attribute_remappings).join(", "); // Account for the possiblity of passing multiple user attributes
|
||||
|
||||
|
||||
@@ -61,10 +61,10 @@ Cypress.Commands.add(
|
||||
|
||||
const { email: username, password } = USERS[user];
|
||||
cy.request("POST", "/api/session", { username, password }).then(
|
||||
response => {
|
||||
(response) => {
|
||||
if (setupCache) {
|
||||
cy.log("saving login token for user", user);
|
||||
cy.getCookie("metabase.DEVICE").then(deviceCookie => {
|
||||
cy.getCookie("metabase.DEVICE").then((deviceCookie) => {
|
||||
loginCache[user] = {
|
||||
sessionId: response.body.id,
|
||||
deviceId: deviceCookie?.value ?? "my-device-id",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { USERS } from "e2e/support/cypress_data";
|
||||
|
||||
Cypress.Commands.add("createUserFromRawData", user => {
|
||||
Cypress.Commands.add("createUserFromRawData", (user) => {
|
||||
return cy.request("POST", "/api/user", user).then(({ body: user }) => {
|
||||
// Dismiss `it's ok to play around` modal for the created user
|
||||
cy.request("PUT", `/api/user/${user.id}/modal/qbnewb`, {});
|
||||
@@ -8,7 +8,7 @@ Cypress.Commands.add("createUserFromRawData", user => {
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add("createUser", user => {
|
||||
Cypress.Commands.add("createUser", (user) => {
|
||||
cy.log(`Create ${user} user`);
|
||||
cy.createUserFromRawData(USERS[user]);
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ declare global {
|
||||
}
|
||||
}
|
||||
|
||||
Cypress.Commands.add("findByTextEnsureVisible", text => {
|
||||
Cypress.Commands.add("findByTextEnsureVisible", (text) => {
|
||||
cy.findByText(text).should("be.visible");
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ Cypress.Commands.add(
|
||||
{
|
||||
prevSubject: true,
|
||||
},
|
||||
subject => {
|
||||
(subject) => {
|
||||
const viewportTop = 0;
|
||||
const viewportBottom = Cypress.$(cy.state("window")).height();
|
||||
const element = subject[0].getBoundingClientRect();
|
||||
|
||||
@@ -5,10 +5,10 @@ Cypress.Commands.add(
|
||||
{
|
||||
prevSubject: true,
|
||||
},
|
||||
subject => {
|
||||
(subject) => {
|
||||
cy.wrap(subject)
|
||||
.closest(POPOVER_ELEMENT)
|
||||
.then($popover => {
|
||||
.then(($popover) => {
|
||||
/**
|
||||
* Helper function that:
|
||||
* 1. Obtains the value of element's computed property, but it always returns it in px (for example: "12px")
|
||||
|
||||
@@ -37,7 +37,7 @@ const assetsResolverPlugin = {
|
||||
name: "assetsResolver",
|
||||
setup(build) {
|
||||
// Redirect all paths starting with "assets/" to "resources/"
|
||||
build.onResolve({ filter: /^assets\// }, args => {
|
||||
build.onResolve({ filter: /^assets\// }, (args) => {
|
||||
return {
|
||||
path: path.join(
|
||||
__dirname,
|
||||
@@ -53,8 +53,8 @@ const assetsResolverPlugin = {
|
||||
const specBlacklist = ["/embedding-sdk/", "/cross-version/"];
|
||||
|
||||
function getSplittableSpecs(specs) {
|
||||
return specs.filter(spec => {
|
||||
return !specBlacklist.some(blacklistedPath =>
|
||||
return specs.filter((spec) => {
|
||||
return !specBlacklist.some((blacklistedPath) =>
|
||||
spec.includes(blacklistedPath),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -42,7 +42,7 @@ Cypress.on("test:before:run", () => {
|
||||
|
||||
Cypress.on("test:after:run", (test, runnable) => {
|
||||
if (test.state === "failed") {
|
||||
const titleToFileName = title => title.replace(/[>]/g, "");
|
||||
const titleToFileName = (title) => title.replace(/[>]/g, "");
|
||||
let { parent } = runnable;
|
||||
let filename = "";
|
||||
// This while is to be able to support more than one level of parent in the screenshot name
|
||||
@@ -54,7 +54,7 @@ Cypress.on("test:after:run", (test, runnable) => {
|
||||
|
||||
if (isCI) {
|
||||
// cypress-terminal-report
|
||||
Cypress.Mochawesome.context.forEach(ctx => {
|
||||
Cypress.Mochawesome.context.forEach((ctx) => {
|
||||
addContext({ test }, ctx);
|
||||
});
|
||||
}
|
||||
@@ -77,7 +77,7 @@ Cypress.on("test:after:run", (test, runnable) => {
|
||||
|
||||
// required for cypress-terminal-report to be able to find logs after the test
|
||||
// is finished
|
||||
Cypress.Commands.add("addTestContext", context => {
|
||||
Cypress.Commands.add("addTestContext", (context) => {
|
||||
if (!Cypress.Mochawesome) {
|
||||
Cypress.Mochawesome = createMochawesomeObject();
|
||||
}
|
||||
@@ -102,7 +102,7 @@ function createMochawesomeObject() {
|
||||
*
|
||||
* @see https://github.com/cypress-io/cypress/issues/2118
|
||||
*/
|
||||
Cypress.on("window:load", window => {
|
||||
Cypress.on("window:load", (window) => {
|
||||
const addEventListener = window.addEventListener;
|
||||
|
||||
window.addEventListener = function (event) {
|
||||
|
||||
@@ -105,7 +105,7 @@ export async function createTestRoles({
|
||||
}
|
||||
|
||||
return await Promise.all(
|
||||
Object.values(dbRoles).map(async sql => {
|
||||
Object.values(dbRoles).map(async (sql) => {
|
||||
await dbClient.raw(sql);
|
||||
}),
|
||||
);
|
||||
|
||||
@@ -26,7 +26,7 @@ export function addOrUpdateDashboardCard({
|
||||
},
|
||||
],
|
||||
})
|
||||
.then(response => ({
|
||||
.then((response) => ({
|
||||
...response,
|
||||
body: response.body.dashcards[0],
|
||||
}));
|
||||
|
||||
@@ -23,7 +23,7 @@ export const addQuestionToDashboard = ({
|
||||
},
|
||||
],
|
||||
})
|
||||
.then(response => ({
|
||||
.then((response) => ({
|
||||
...response,
|
||||
body: response.body.dashcards.at(-1),
|
||||
})),
|
||||
|
||||
@@ -22,7 +22,7 @@ export const createCollection = ({
|
||||
parent_id,
|
||||
authority_level,
|
||||
})
|
||||
.then(response => {
|
||||
.then((response) => {
|
||||
if (alias) {
|
||||
cy.wrap(response.body.id).as(alias);
|
||||
}
|
||||
|
||||
@@ -31,9 +31,9 @@ export const createDashboardWithQuestions = ({
|
||||
cards ? cards[index] : undefined,
|
||||
),
|
||||
),
|
||||
).then(dashcardResponses => {
|
||||
).then((dashcardResponses) => {
|
||||
const questions = dashcardResponses.map(
|
||||
dashcardResponse => dashcardResponse.body.card,
|
||||
(dashcardResponse) => dashcardResponse.body.card,
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -47,7 +47,7 @@ export const createNativeQuestionAndDashboard = ({
|
||||
...cardDetails,
|
||||
},
|
||||
],
|
||||
}).then(response => ({
|
||||
}).then((response) => ({
|
||||
...response,
|
||||
dashboardId,
|
||||
dashboardTabs: response.body.tabs,
|
||||
|
||||
@@ -35,7 +35,7 @@ export const createQuestionAndAddToDashboard = (
|
||||
},
|
||||
],
|
||||
})
|
||||
.then(response => ({
|
||||
.then((response) => ({
|
||||
...response,
|
||||
body: response.body.dashcards.at(-1),
|
||||
})),
|
||||
|
||||
@@ -36,7 +36,7 @@ export const createQuestionAndDashboard = ({
|
||||
},
|
||||
],
|
||||
})
|
||||
.then(response => ({
|
||||
.then((response) => ({
|
||||
...response,
|
||||
body: response.body.dashcards[0],
|
||||
questionId,
|
||||
|
||||
@@ -23,10 +23,10 @@ export const createTimelineWithEvents = ({
|
||||
// @ts-expect-error - Cypress typings don't account for what happens in then() here
|
||||
return createTimeline(timeline).then(({ body: timeline }) => {
|
||||
return cypressWaitAll(
|
||||
events.map(query =>
|
||||
events.map((query) =>
|
||||
createTimelineEvent({ ...query, timeline_id: timeline.id }),
|
||||
),
|
||||
).then(events => {
|
||||
).then((events) => {
|
||||
return {
|
||||
timeline,
|
||||
events,
|
||||
|
||||
@@ -23,6 +23,6 @@ export function updateDashboardCards({
|
||||
}): Cypress.Chainable<Cypress.Response<Dashboard>> {
|
||||
let id = -1;
|
||||
return cy.request<Dashboard>("PUT", `/api/dashboard/${dashboard_id}`, {
|
||||
dashcards: cards.map(card => ({ ...DEFAULT_CARD, id: id--, ...card })),
|
||||
dashcards: cards.map((card) => ({ ...DEFAULT_CARD, id: id--, ...card })),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ export function mountSdkContentAndAssertNoKnownErrors(
|
||||
mountSdkContentOptions: MountSdkContentOptions = {},
|
||||
) {
|
||||
// Monitor console errors, but don't log them in the Cypress runner UI.
|
||||
cy.window().then(win => {
|
||||
cy.window().then((win) => {
|
||||
cy.stub(win.console, "error").log(false).as("consoleError");
|
||||
});
|
||||
|
||||
@@ -29,8 +29,8 @@ export function mountSdkContentAndAssertNoKnownErrors(
|
||||
cy.findByTestId("loading-indicator").should("not.exist");
|
||||
});
|
||||
|
||||
cy.get<sinon.SinonStub>("@consoleError").should($console => {
|
||||
const lifecycleErrors = $console.args.filter(args => {
|
||||
cy.get<sinon.SinonStub>("@consoleError").should(($console) => {
|
||||
const lifecycleErrors = $console.args.filter((args) => {
|
||||
const message = args.join(" ");
|
||||
|
||||
const hasUnsafeLifecycleWarning = message.includes("UNSAFE_component");
|
||||
|
||||
@@ -23,7 +23,7 @@ export const DEFAULT_SDK_AUTH_PROVIDER_CONFIG = {
|
||||
};
|
||||
|
||||
export const mockAuthProviderAndJwtSignIn = (user = USERS.admin) => {
|
||||
cy.intercept("GET", AUTH_PROVIDER_URL, async req => {
|
||||
cy.intercept("GET", AUTH_PROVIDER_URL, async (req) => {
|
||||
try {
|
||||
const secret = new TextEncoder().encode(JWT_SHARED_SECRET);
|
||||
const token = await new jose.SignJWT({
|
||||
|
||||
@@ -24,7 +24,7 @@ export function mountInteractiveQuestion(
|
||||
cy.intercept("GET", "/api/card/*").as("getCard");
|
||||
cy.intercept("POST", "/api/card/*/query").as("cardQuery");
|
||||
|
||||
cy.get<number>("@questionId").then(questionId => {
|
||||
cy.get<number>("@questionId").then((questionId) => {
|
||||
mountSdkContent(
|
||||
<InteractiveQuestion questionId={questionId} {...extraProps} />,
|
||||
mountSdkContentOptions,
|
||||
@@ -47,7 +47,7 @@ export function mountStaticQuestion(
|
||||
cy.intercept("GET", "/api/card/*").as("getCard");
|
||||
cy.intercept("POST", "/api/card/*/query").as("cardQuery");
|
||||
|
||||
cy.get<number>("@questionId").then(questionId => {
|
||||
cy.get<number>("@questionId").then((questionId) => {
|
||||
mountSdkContent(<StaticQuestion questionId={questionId} {...extraProps} />);
|
||||
});
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ export function visitQuestionAdhoc(
|
||||
runQueryIfNeeded(question, autorun);
|
||||
|
||||
if (mode !== "notebook" && !skipWaiting) {
|
||||
return cy.wait("@" + alias).then(xhr => callback && callback(xhr));
|
||||
return cy.wait("@" + alias).then((xhr) => callback && callback(xhr));
|
||||
}
|
||||
|
||||
// Ensure chainability
|
||||
|
||||
@@ -31,4 +31,4 @@ export const commandPaletteSearch = (query, viewAll = true) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const commandPaletteAction = name => cy.findByRole("option", { name });
|
||||
export const commandPaletteAction = (name) => cy.findByRole("option", { name });
|
||||
|
||||
@@ -60,10 +60,10 @@ export function enterCustomColumnDetails({
|
||||
}
|
||||
|
||||
export function checkExpressionEditorHelperPopoverPosition() {
|
||||
expressionEditorTextfield().then($target => {
|
||||
expressionEditorTextfield().then(($target) => {
|
||||
const textfieldPosition = $target[0].getBoundingClientRect();
|
||||
|
||||
cy.findByTestId("expression-helper-popover").then($target => {
|
||||
cy.findByTestId("expression-helper-popover").then(($target) => {
|
||||
const popoverPosition = $target[0].getBoundingClientRect();
|
||||
|
||||
expect(textfieldPosition.top - popoverPosition.top).to.be.lessThan(
|
||||
@@ -117,7 +117,7 @@ export const CustomExpressionEditor = {
|
||||
|
||||
const parts = text.replaceAll("{{", "{{}{{}").split(/(\{[^}]+\})/);
|
||||
|
||||
parts.forEach(part => {
|
||||
parts.forEach((part) => {
|
||||
cy.wait(delay);
|
||||
switch (part.toLowerCase()) {
|
||||
case "":
|
||||
@@ -183,7 +183,7 @@ export const CustomExpressionEditor = {
|
||||
|
||||
const alphabet =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789^[]()-,.;_!@#$%&*+=/<>\" ':;\\";
|
||||
if (unexpanded.split("").some(char => !alphabet.includes(char))) {
|
||||
if (unexpanded.split("").some((char) => !alphabet.includes(char))) {
|
||||
throw new Error(
|
||||
`unknown character in CustomExpressionEditor.type in ${part}`,
|
||||
);
|
||||
@@ -226,7 +226,7 @@ export const CustomExpressionEditor = {
|
||||
// Get the multiline text content of the editor
|
||||
return CustomExpressionEditor.textbox()
|
||||
.get(".cm-line")
|
||||
.then(lines => {
|
||||
.then((lines) => {
|
||||
const text: string[] = [];
|
||||
lines.each((_, line) => {
|
||||
text.push(line.textContent ?? "");
|
||||
@@ -269,7 +269,7 @@ export const CustomExpressionEditor = {
|
||||
return cy.findByTestId("expression-helper");
|
||||
},
|
||||
paste(content: string) {
|
||||
CustomExpressionEditor.textbox().then(el => {
|
||||
CustomExpressionEditor.textbox().then((el) => {
|
||||
const clipboardData = new DataTransfer();
|
||||
clipboardData.setData("text/plain", content);
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ export function downloadAndAssert(
|
||||
* https://github.com/cypress-io/cypress-example-recipes/blob/master/examples/testing-dom__download/cypress/integration/form-submission-spec.js
|
||||
*/
|
||||
|
||||
cy.intercept(method, endpoint, req => {
|
||||
cy.intercept(method, endpoint, (req) => {
|
||||
/**
|
||||
* We must redirect in order to avoid Cypress being stuck on waiting for the new page to load.
|
||||
* Intentionally redirecting to a non-existing page.
|
||||
@@ -107,7 +107,7 @@ export function downloadAndAssert(
|
||||
if (pivoting != null) {
|
||||
cy.findByTestId("keep-data-pivoted")
|
||||
.as("keep-data-pivoted")
|
||||
.then($checkbox => {
|
||||
.then(($checkbox) => {
|
||||
const isChecked = $checkbox.prop("checked");
|
||||
|
||||
const shouldPivot = pivoting === "pivoted";
|
||||
@@ -122,7 +122,7 @@ export function downloadAndAssert(
|
||||
|
||||
cy.wait("@fileDownload")
|
||||
.its("request")
|
||||
.then(req => {
|
||||
.then((req) => {
|
||||
// The payload for the xlsx is in the binary form
|
||||
fileType === "xlsx" && Object.assign(req, { encoding: "binary" });
|
||||
|
||||
|
||||
@@ -8,12 +8,12 @@ export function dragField(startIndex, dropIndex) {
|
||||
// eslint-disable-next-line no-unsafe-element-filtering
|
||||
cy.get("@dragHandle")
|
||||
.eq(dropIndex)
|
||||
.then($target => {
|
||||
.then(($target) => {
|
||||
const coordsDrop = $target[0].getBoundingClientRect();
|
||||
// eslint-disable-next-line no-unsafe-element-filtering
|
||||
cy.get("@dragHandle")
|
||||
.eq(startIndex)
|
||||
.then(subject => {
|
||||
.then((subject) => {
|
||||
const coordsDrag = subject[0].getBoundingClientRect();
|
||||
cy.wrap(subject)
|
||||
.trigger("mousedown", {
|
||||
|
||||
@@ -38,7 +38,7 @@ export const getInbox = () => {
|
||||
const getInboxWithRetry = (timeout = INBOX_TIMEOUT) => {
|
||||
return cy
|
||||
.request("GET", `http://localhost:${WEB_PORT}/email`)
|
||||
.then(response => {
|
||||
.then((response) => {
|
||||
if (response.body.length) {
|
||||
return cy.wrap(response);
|
||||
} else if (timeout > 0) {
|
||||
@@ -54,22 +54,22 @@ export const clearInbox = () => {
|
||||
return cy.request("DELETE", `http://localhost:${WEB_PORT}/email/all`);
|
||||
};
|
||||
|
||||
export const viewEmailPage = emailSubject => {
|
||||
export const viewEmailPage = (emailSubject) => {
|
||||
const webmailInterface = `http://localhost:${WEB_PORT}`;
|
||||
|
||||
cy.window().then(win => (win.location.href = webmailInterface));
|
||||
cy.window().then((win) => (win.location.href = webmailInterface));
|
||||
cy.findByText(emailSubject).click();
|
||||
};
|
||||
|
||||
export const openEmailPage = emailSubject => {
|
||||
export const openEmailPage = (emailSubject) => {
|
||||
const webmailInterface = `http://localhost:${WEB_PORT}`;
|
||||
|
||||
cy.window().then(win => (win.location.href = webmailInterface));
|
||||
cy.window().then((win) => (win.location.href = webmailInterface));
|
||||
cy.findAllByText(emailSubject).first().click();
|
||||
|
||||
return cy.hash().then(path => {
|
||||
return cy.hash().then((path) => {
|
||||
const htmlPath = `${webmailInterface}${path.slice(1)}/html`;
|
||||
cy.window().then(win => (win.location.href = htmlPath));
|
||||
cy.window().then((win) => (win.location.href = htmlPath));
|
||||
cy.findByText(emailSubject);
|
||||
});
|
||||
};
|
||||
@@ -81,7 +81,7 @@ export const clickSend = () => {
|
||||
cy.wait("@emailSent");
|
||||
};
|
||||
|
||||
export const openAndAddEmailsToSubscriptions = recipients => {
|
||||
export const openAndAddEmailsToSubscriptions = (recipients) => {
|
||||
openSharingMenu("Subscriptions");
|
||||
|
||||
sidebar().findByText("Set up a dashboard subscription").should("be.visible");
|
||||
@@ -91,13 +91,13 @@ export const openAndAddEmailsToSubscriptions = recipients => {
|
||||
const input = cy
|
||||
.findByPlaceholderText("Enter user names or email addresses")
|
||||
.click();
|
||||
recipients.forEach(recipient => {
|
||||
recipients.forEach((recipient) => {
|
||||
input.type(`${recipient}{enter}`);
|
||||
});
|
||||
input.blur();
|
||||
};
|
||||
|
||||
export const setupSubscriptionWithRecipients = recipients => {
|
||||
export const setupSubscriptionWithRecipients = (recipients) => {
|
||||
openAndAddEmailsToSubscriptions(recipients);
|
||||
sidebar().findByText("Done").click();
|
||||
};
|
||||
|
||||
@@ -46,7 +46,7 @@ import { openSharingMenu } from "./e2e-sharing-helpers";
|
||||
* });
|
||||
*/
|
||||
export function visitEmbeddedPage(payload, options) {
|
||||
getEmbeddedPageUrl(payload, options).then(urlOptions => {
|
||||
getEmbeddedPageUrl(payload, options).then((urlOptions) => {
|
||||
// Always visit embedded page logged out
|
||||
cy.signOut();
|
||||
|
||||
@@ -109,7 +109,7 @@ export function getEmbeddedPageUrl(
|
||||
return {
|
||||
url: urlRoot,
|
||||
qs: { ...setFilters, ...qs },
|
||||
onBeforeLoad: window => {
|
||||
onBeforeLoad: (window) => {
|
||||
onBeforeLoad?.(window);
|
||||
if (urlHash) {
|
||||
window.location.hash = urlHash;
|
||||
@@ -157,7 +157,7 @@ export function getEmbeddedPageUrl(
|
||||
* but make sure user is signed out.
|
||||
*/
|
||||
export function visitIframe() {
|
||||
getIframeUrl().then(iframeUrl => {
|
||||
getIframeUrl().then((iframeUrl) => {
|
||||
cy.signOut();
|
||||
cy.visit(iframeUrl);
|
||||
});
|
||||
@@ -166,7 +166,7 @@ export function visitIframe() {
|
||||
function getIframeUrl() {
|
||||
modal().findByText("Preview").click();
|
||||
|
||||
return cy.document().then(doc => {
|
||||
return cy.document().then((doc) => {
|
||||
const iframe = doc.querySelector("iframe");
|
||||
|
||||
return iframe.src;
|
||||
@@ -253,7 +253,7 @@ export function publishChanges(apiPath, callback) {
|
||||
cy.button(/^(Publish|Publish changes)$/).click();
|
||||
|
||||
// TODO this could be simplified when we send one publish request instead of two
|
||||
cy.wait(["@publishChanges", "@publishChanges"]).then(xhrs => {
|
||||
cy.wait(["@publishChanges", "@publishChanges"]).then((xhrs) => {
|
||||
// Unfortunately, the order of requests is not always the same.
|
||||
// Therefore, we must first get the one that has the `embedding_params` and then assert on it.
|
||||
const targetXhr = xhrs.find(({ request }) =>
|
||||
|
||||
@@ -32,7 +32,7 @@ export function saveInteractiveQuestionAsNewQuestion(options: {
|
||||
entityPickerModal().within(() => {
|
||||
cy.findByText("Browse").click();
|
||||
|
||||
collectionPickerPath.forEach(collectionName =>
|
||||
collectionPickerPath.forEach((collectionName) =>
|
||||
cy.findByText(collectionName).click(),
|
||||
);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ const { IS_ENTERPRISE } = Cypress.env();
|
||||
*
|
||||
* @param {("all"|"none")} featuresScope
|
||||
*/
|
||||
export const setTokenFeatures = featuresScope => {
|
||||
export const setTokenFeatures = (featuresScope) => {
|
||||
if (!IS_ENTERPRISE) {
|
||||
throw new Error(
|
||||
"You must run Metabase® Enterprise Edition™ for token to make sense.\nMake sure you have `MB_EDITION=ee` in your environment variables.",
|
||||
@@ -66,9 +66,9 @@ export const deleteToken = () => {
|
||||
});
|
||||
};
|
||||
|
||||
export const mockSessionPropertiesTokenFeatures = features => {
|
||||
cy.intercept({ method: "GET", url: "/api/session/properties" }, request => {
|
||||
request.on("response", response => {
|
||||
export const mockSessionPropertiesTokenFeatures = (features) => {
|
||||
cy.intercept({ method: "GET", url: "/api/session/properties" }, (request) => {
|
||||
request.on("response", (response) => {
|
||||
if (typeof response.body === "object") {
|
||||
response.body = {
|
||||
...response.body,
|
||||
@@ -85,7 +85,7 @@ export const mockSessionPropertiesTokenFeatures = features => {
|
||||
// Gets an object that reflects a *partial* premium feature error - it must
|
||||
// be a partial, otherwise we would need to have a stack trace in this error
|
||||
// object.
|
||||
export const getPartialPremiumFeatureError = name => ({
|
||||
export const getPartialPremiumFeatureError = (name) => ({
|
||||
cause: `${name} is a paid feature not currently available to your instance. Please upgrade to use it. Learn more at metabase.com/upgrade/`,
|
||||
data: {
|
||||
"status-code": 402,
|
||||
|
||||
@@ -46,7 +46,7 @@ export function setFilterListSource({ values }) {
|
||||
.clear()
|
||||
.type(
|
||||
values
|
||||
.map(value => {
|
||||
.map((value) => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.join(", ");
|
||||
}
|
||||
@@ -62,7 +62,7 @@ export function checkFilterListSourceHasValue({ values }) {
|
||||
cy.findByText("Edit").click();
|
||||
|
||||
const expectedString = values
|
||||
.map(value => {
|
||||
.map((value) => {
|
||||
if (Array.isArray(value)) {
|
||||
return value.join(", ");
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export function typeAndBlurUsingLabel(label, value) {
|
||||
}
|
||||
|
||||
export function visitAlias(alias) {
|
||||
cy.get(alias).then(url => {
|
||||
cy.get(alias).then((url) => {
|
||||
cy.visit(url);
|
||||
});
|
||||
}
|
||||
@@ -45,10 +45,10 @@ export function runButtonOverlay() {
|
||||
*/
|
||||
export function interceptPromise(method, path) {
|
||||
const state = {};
|
||||
const promise = new Promise(resolve => {
|
||||
const promise = new Promise((resolve) => {
|
||||
state.resolve = resolve;
|
||||
});
|
||||
cy.intercept(method, path, req => {
|
||||
cy.intercept(method, path, (req) => {
|
||||
return promise.then(() => {
|
||||
req.continue();
|
||||
});
|
||||
@@ -75,7 +75,7 @@ const cypressWaitAllRecursive = (results, commands) => {
|
||||
return;
|
||||
}
|
||||
|
||||
return nextCommand.then(result => {
|
||||
return nextCommand.then((result) => {
|
||||
results.push(result);
|
||||
|
||||
if (nextCommand == null) {
|
||||
@@ -105,7 +105,7 @@ export function visitQuestion(questionIdOrAlias) {
|
||||
}
|
||||
|
||||
if (typeof questionIdOrAlias === "string") {
|
||||
cy.get(questionIdOrAlias).then(id => visitQuestionById(id));
|
||||
cy.get(questionIdOrAlias).then((id) => visitQuestionById(id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ export function visitDashboard(dashboardIdOrAlias, { params = {} } = {}) {
|
||||
}
|
||||
|
||||
if (typeof dashboardIdOrAlias === "string") {
|
||||
cy.get(dashboardIdOrAlias).then(id => visitDashboardById(id, { params }));
|
||||
cy.get(dashboardIdOrAlias).then((id) => visitDashboardById(id, { params }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ function visitDashboardById(dashboard_id, config) {
|
||||
if (tabs?.length > 0 && validQuestions) {
|
||||
const firstTab = tabs[0];
|
||||
validQuestions = validQuestions.filter(
|
||||
card => card.dashboard_tab_id === firstTab.id,
|
||||
(card) => card.dashboard_tab_id === firstTab.id,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ function dashboardHasQuestions(cards) {
|
||||
export function interceptIfNotPreviouslyDefined({ method, url, alias } = {}) {
|
||||
const aliases = Object.keys(cy.state("aliases") ?? {});
|
||||
|
||||
const isAlreadyDefined = aliases.find(a => a === alias);
|
||||
const isAlreadyDefined = aliases.find((a) => a === alias);
|
||||
|
||||
if (!isAlreadyDefined) {
|
||||
cy.intercept(method, url).as(alias);
|
||||
@@ -357,7 +357,7 @@ export function saveSavedQuestion() {
|
||||
cy.intercept("PUT", "/api/card/**").as("updateQuestion");
|
||||
cy.findByText("Save").click();
|
||||
|
||||
cy.findByTestId("save-question-modal").within(modal => {
|
||||
cy.findByTestId("save-question-modal").within((modal) => {
|
||||
cy.findByText("Save").click();
|
||||
});
|
||||
cy.wait("@updateQuestion");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
function mockProperty(propertyOrObject, value, url) {
|
||||
cy.intercept("GET", url, req => {
|
||||
req.reply(res => {
|
||||
cy.intercept("GET", url, (req) => {
|
||||
req.reply((res) => {
|
||||
if (typeof propertyOrObject === "object") {
|
||||
Object.assign(res.body, propertyOrObject);
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@ export function createModelIndex({ modelId, pkName, valueName }) {
|
||||
({ body }) => {
|
||||
const pkRef = [
|
||||
"field",
|
||||
body.fields.find(f => f.name === pkName).id,
|
||||
body.fields.find((f) => f.name === pkName).id,
|
||||
null,
|
||||
];
|
||||
const valueRef = [
|
||||
"field",
|
||||
body.fields.find(f => f.name === valueName).id,
|
||||
body.fields.find((f) => f.name === valueName).id,
|
||||
null,
|
||||
];
|
||||
|
||||
@@ -17,7 +17,7 @@ export function createModelIndex({ modelId, pkName, valueName }) {
|
||||
pk_ref: pkRef,
|
||||
value_ref: valueRef,
|
||||
model_id: modelId,
|
||||
}).then(response => {
|
||||
}).then((response) => {
|
||||
expect(response.body.state).to.equal("indexed");
|
||||
expect(response.body.id).to.equal(1);
|
||||
});
|
||||
|
||||
@@ -78,7 +78,7 @@ export function mapColumnTo({ table, column } = {}) {
|
||||
}
|
||||
|
||||
export function setModelMetadata(modelId, callback) {
|
||||
return cy.request("GET", `/api/card/${modelId}`).then(response => {
|
||||
return cy.request("GET", `/api/card/${modelId}`).then((response) => {
|
||||
const { result_metadata } = response.body;
|
||||
return cy.request("PUT", `/api/card/${modelId}`, {
|
||||
result_metadata: result_metadata.map(callback),
|
||||
|
||||
@@ -72,7 +72,7 @@ function nativeEditorType(
|
||||
|
||||
// HACK: realType does not accept a lot of common escape sequences,
|
||||
// so we implement them manually here for the native editor.
|
||||
parts.forEach(part => {
|
||||
parts.forEach((part) => {
|
||||
switch (part.toLowerCase()) {
|
||||
case "":
|
||||
return;
|
||||
|
||||
@@ -27,7 +27,7 @@ export function modifyPermission(
|
||||
if (shouldPropagate !== null) {
|
||||
cy.findByRole("switch")
|
||||
.as("toggle")
|
||||
.then($el => {
|
||||
.then(($el) => {
|
||||
if ($el.attr("aria-checked") !== shouldPropagate.toString()) {
|
||||
cy.get("@toggle").click();
|
||||
}
|
||||
@@ -56,7 +56,7 @@ export function assertPermissionTable(rows) {
|
||||
.find("tbody > tr")
|
||||
.should("have.length", rows.length);
|
||||
|
||||
rows.forEach(row => {
|
||||
rows.forEach((row) => {
|
||||
const [item, ...permissions] = row;
|
||||
|
||||
getPermissionRowPermissions(item).each(($permissionEl, index) => {
|
||||
@@ -141,14 +141,14 @@ export function assertDatasetReqIsSandboxed(options = {}) {
|
||||
|
||||
// if options to make assertions on a column's data
|
||||
if (columnId && columnAssertion) {
|
||||
const colIndex = data.cols.findIndex(c => c.id === columnId);
|
||||
const colIndex = data.cols.findIndex((c) => c.id === columnId);
|
||||
expect(colIndex).to.be.gte(0);
|
||||
|
||||
const values = data.rows.map(row => row[colIndex]);
|
||||
const values = data.rows.map((row) => row[colIndex]);
|
||||
|
||||
const assertionFn = _.isFunction(columnAssertion)
|
||||
? columnAssertion
|
||||
: val => val === columnAssertion;
|
||||
: (val) => val === columnAssertion;
|
||||
const errMsg = `Expected every result in column to be equal to: ${columnAssertion}`;
|
||||
expect(values.every(assertionFn)).to.equal(true, errMsg);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ function addQADatabase(engine, db_display_name, port, enable_actions = false) {
|
||||
expect(status).to.equal(200);
|
||||
cy.wrap(body.id).as(`${engine}ID`);
|
||||
})
|
||||
.then(dbId => {
|
||||
.then((dbId) => {
|
||||
// Make sure we have all the metadata because we'll need to use it in tests
|
||||
assertOnDatabaseMetadata(engine);
|
||||
|
||||
@@ -96,7 +96,7 @@ function addQADatabase(engine, db_display_name, port, enable_actions = false) {
|
||||
|
||||
function assertOnDatabaseMetadata(engine) {
|
||||
cy.request("GET", "/api/database").then(({ body }) => {
|
||||
const { id } = body.data.find(db => {
|
||||
const { id } = body.data.find((db) => {
|
||||
return db.engine === engine;
|
||||
});
|
||||
|
||||
@@ -145,11 +145,11 @@ function recursiveCheckFields(id, i = 0) {
|
||||
.then(({ body: schema }) => {
|
||||
return schema[0].id;
|
||||
})
|
||||
.then(tableId => {
|
||||
.then((tableId) => {
|
||||
cy.request("GET", `/api/table/${tableId}/query_metadata`).then(
|
||||
({ body: table }) => {
|
||||
const field = table.fields.find(
|
||||
field => field.semantic_type !== "type/PK",
|
||||
(field) => field.semantic_type !== "type/PK",
|
||||
);
|
||||
if (!field.last_analyzed) {
|
||||
recursiveCheckFields(id, ++i);
|
||||
@@ -191,7 +191,7 @@ export const setupWritableDB = (type = "postgres") => {
|
||||
cy.task("connectAndQueryDB", {
|
||||
connectionConfig: connectionConfig[type],
|
||||
query: dbCheckQuery[type],
|
||||
}).then(results => {
|
||||
}).then((results) => {
|
||||
if (!results.rows.length) {
|
||||
cy.log(`**-- Adding ${type} DB for actions --**`);
|
||||
cy.task("connectAndQueryDB", {
|
||||
@@ -237,7 +237,7 @@ export function getTableId({ databaseId = WRITABLE_DB_ID, name }) {
|
||||
return cy
|
||||
.request("GET", `/api/database/${databaseId}/metadata`)
|
||||
.then(({ body }) => {
|
||||
const table = body?.tables?.find(table => table.name === name);
|
||||
const table = body?.tables?.find((table) => table.name === name);
|
||||
return table ? table.id : null;
|
||||
});
|
||||
}
|
||||
@@ -246,7 +246,7 @@ export function getTable({ databaseId = WRITABLE_DB_ID, name }) {
|
||||
return cy
|
||||
.request("GET", `/api/database/${databaseId}/metadata`)
|
||||
.then(({ body }) => {
|
||||
const table = body?.tables?.find(table => table.name === name);
|
||||
const table = body?.tables?.find((table) => table.name === name);
|
||||
return table || null;
|
||||
});
|
||||
}
|
||||
@@ -256,7 +256,7 @@ export const createModelFromTableName = ({
|
||||
modelName = "Test Action Model",
|
||||
idAlias = "modelId",
|
||||
}) => {
|
||||
getTableId({ name: tableName }).then(tableId => {
|
||||
getTableId({ name: tableName }).then((tableId) => {
|
||||
createQuestion(
|
||||
{
|
||||
database: WRITABLE_DB_ID,
|
||||
@@ -297,7 +297,7 @@ export function waitForSyncToFinish({
|
||||
});
|
||||
} else if (tableName) {
|
||||
const table = body.tables.find(
|
||||
table =>
|
||||
(table) =>
|
||||
table.name === tableName && table.initial_sync_status === "complete",
|
||||
);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
export function spyRequestFinished(name = "requestFinishedSpy") {
|
||||
const spy = cy.spy().as(name);
|
||||
return {
|
||||
interceptor: req => req.continue(res => spy(req, res)),
|
||||
interceptor: (req) => req.continue((res) => spy(req, res)),
|
||||
spy,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export function expectSearchResultContent({
|
||||
|
||||
const searchResultItems = cy.get(searchResultItemSelector);
|
||||
|
||||
searchResultItems.then($results => {
|
||||
searchResultItems.then(($results) => {
|
||||
if (strict) {
|
||||
// Check if the length of the search results is the same as the expected length
|
||||
expect($results).to.have.length(expectedSearchResults.length);
|
||||
|
||||
@@ -37,7 +37,7 @@ export const expectGoodSnowplowEvent = (eventData, count = 1) => {
|
||||
"micro/good",
|
||||
({ body }) => {
|
||||
lastReceivedEvent = body?.[0].event?.unstruct_event?.data?.data;
|
||||
lastFoundEventCount = body.filter(snowplowEvent =>
|
||||
lastFoundEventCount = body.filter((snowplowEvent) =>
|
||||
isDeepMatch(
|
||||
snowplowEvent?.event?.unstruct_event?.data?.data,
|
||||
eventData,
|
||||
@@ -101,7 +101,7 @@ function isArrayDeepMatch(array, partialArray) {
|
||||
return true;
|
||||
}
|
||||
|
||||
export const expectGoodSnowplowEvents = count => {
|
||||
export const expectGoodSnowplowEvents = (count) => {
|
||||
retrySnowplowRequest("micro/good", ({ body }) => body.length >= count)
|
||||
.its("body")
|
||||
.should("have.length", count);
|
||||
@@ -111,7 +111,7 @@ export const expectNoBadSnowplowEvents = () => {
|
||||
sendSnowplowRequest("micro/bad").its("body").should("deep.equal", []);
|
||||
};
|
||||
|
||||
const sendSnowplowRequest = url => {
|
||||
const sendSnowplowRequest = (url) => {
|
||||
return cy.request({
|
||||
url: `${SNOWPLOW_URL}/${url}`,
|
||||
json: true,
|
||||
@@ -124,7 +124,7 @@ const retrySnowplowRequest = (
|
||||
messageOrMessageFn = null,
|
||||
timeout = SNOWPLOW_TIMEOUT,
|
||||
) => {
|
||||
return sendSnowplowRequest(url).then(response => {
|
||||
return sendSnowplowRequest(url).then((response) => {
|
||||
if (condition(response)) {
|
||||
return cy.wrap(response);
|
||||
} else if (timeout > 0) {
|
||||
@@ -145,6 +145,6 @@ const retrySnowplowRequest = (
|
||||
});
|
||||
};
|
||||
|
||||
const blockSnowplowRequest = url => {
|
||||
return cy.intercept("POST", `${SNOWPLOW_URL}/${url}`, req => req.destroy());
|
||||
const blockSnowplowRequest = (url) => {
|
||||
return cy.intercept("POST", `${SNOWPLOW_URL}/${url}`, (req) => req.destroy());
|
||||
};
|
||||
|
||||
@@ -66,7 +66,7 @@ export function entityPickerModalTab(name) {
|
||||
|
||||
// displays at least these tabs:
|
||||
export function shouldDisplayTabs(tabs) {
|
||||
tabs.forEach(tab => {
|
||||
tabs.forEach((tab) => {
|
||||
entityPickerModalTab(tab).should("exist");
|
||||
});
|
||||
}
|
||||
@@ -74,7 +74,7 @@ export function shouldDisplayTabs(tabs) {
|
||||
export function tabsShouldBe(selected, tabs) {
|
||||
cy.log(tabs);
|
||||
cy.findAllByRole("tab").should("have.length", tabs.length);
|
||||
tabs.forEach(tab => {
|
||||
tabs.forEach((tab) => {
|
||||
if (tab === selected) {
|
||||
entityPickerModalTab(tab).and("have.attr", "aria-selected", "true");
|
||||
} else {
|
||||
@@ -203,12 +203,12 @@ export function toggleFilterWidgetValues(
|
||||
filterWidget().eq(0).click();
|
||||
|
||||
popover().within(() => {
|
||||
values.forEach(value => cy.findByText(value).click());
|
||||
values.forEach((value) => cy.findByText(value).click());
|
||||
cy.button(buttonLabel).click();
|
||||
});
|
||||
}
|
||||
|
||||
export const openQuestionActions = action => {
|
||||
export const openQuestionActions = (action) => {
|
||||
cy.findByTestId("qb-header-action-panel").icon("ellipsis").click();
|
||||
|
||||
if (action) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export const isScrollableHorizontally = element => {
|
||||
export const isScrollableHorizontally = (element) => {
|
||||
const { clientHeight, offsetHeight } = element;
|
||||
const style = window.getComputedStyle(element);
|
||||
const borderTopWidth = parseInt(style.borderTopWidth, 10);
|
||||
@@ -10,7 +10,7 @@ export const isScrollableHorizontally = element => {
|
||||
return isHorizontalScrollbarVisible;
|
||||
};
|
||||
|
||||
export const isScrollableVertically = element => {
|
||||
export const isScrollableVertically = (element) => {
|
||||
const { clientWidth, offsetWidth } = element;
|
||||
const style = window.getComputedStyle(element);
|
||||
const borderLeftWidth = parseInt(style.borderLeftWidth, 10);
|
||||
@@ -34,7 +34,7 @@ export const assertDescendantNotOverflowsContainer = (
|
||||
return;
|
||||
}
|
||||
|
||||
const getMessage = suffix => {
|
||||
const getMessage = (suffix) => {
|
||||
return [message, suffix].filter(Boolean).join(" ");
|
||||
};
|
||||
|
||||
@@ -48,15 +48,15 @@ export const assertDescendantNotOverflowsContainer = (
|
||||
);
|
||||
};
|
||||
|
||||
export const assertIsEllipsified = element => {
|
||||
export const assertIsEllipsified = (element) => {
|
||||
expect(isEllipsified(element), "is ellipsified").to.equal(true);
|
||||
};
|
||||
|
||||
export const assertIsNotEllipsified = element => {
|
||||
export const assertIsNotEllipsified = (element) => {
|
||||
expect(isEllipsified(element), "is ellipsified").to.equal(false);
|
||||
};
|
||||
|
||||
export const isEllipsified = element => {
|
||||
export const isEllipsified = (element) => {
|
||||
return (
|
||||
element.scrollHeight > element.clientHeight ||
|
||||
element.scrollWidth > element.clientWidth
|
||||
|
||||
@@ -60,7 +60,7 @@ export function uploadFile(
|
||||
cy.intercept("POST", "/api/table/*/append-csv").as("appendCSV");
|
||||
cy.intercept("POST", "/api/table/*/replace-csv").as("replaceCSV");
|
||||
|
||||
cy.fixture(`${FIXTURE_PATH}/${testFile.fileName}`).then(file => {
|
||||
cy.fixture(`${FIXTURE_PATH}/${testFile.fileName}`).then((file) => {
|
||||
cy.get(inputId).selectFile(
|
||||
{
|
||||
contents: Cypress.Buffer.from(file),
|
||||
@@ -97,8 +97,8 @@ export function uploadFile(
|
||||
|
||||
export function headlessUpload(collectionId, file) {
|
||||
cy.fixture(`${FIXTURE_PATH}/${file.fileName}`)
|
||||
.then(file => Cypress.Blob.binaryStringToBlob(file))
|
||||
.then(blob => {
|
||||
.then((file) => Cypress.Blob.binaryStringToBlob(file))
|
||||
.then((blob) => {
|
||||
const formData = new FormData();
|
||||
formData.append("file", blob, file.fileName);
|
||||
formData.append("collection_id", collectionId);
|
||||
|
||||
@@ -20,7 +20,7 @@ export function echartsTriggerBlur() {
|
||||
}
|
||||
|
||||
export function ensureEchartsContainerHasSvg() {
|
||||
return echartsContainer().should(root => {
|
||||
return echartsContainer().should((root) => {
|
||||
// Check if there's an SVG child within the element
|
||||
expect(root.find("svg").length, "SVG exists").to.be.equal(1);
|
||||
});
|
||||
@@ -68,7 +68,7 @@ export function sankeyEdge(color) {
|
||||
}
|
||||
|
||||
export function chartPathsWithFillColors(colors) {
|
||||
return colors.map(color => chartPathWithFillColor(color));
|
||||
return colors.map((color) => chartPathWithFillColor(color));
|
||||
}
|
||||
|
||||
const CIRCLE_PATH = "M1 0A1 1 0 1 1 1 -0.0001";
|
||||
@@ -85,7 +85,7 @@ export function cartesianChartCircleWithColor(color) {
|
||||
}
|
||||
|
||||
export function cartesianChartCircleWithColors(colors) {
|
||||
return colors.map(color => cartesianChartCircleWithColor(color));
|
||||
return colors.map((color) => cartesianChartCircleWithColor(color));
|
||||
}
|
||||
|
||||
export function otherSeriesChartPaths() {
|
||||
@@ -137,7 +137,7 @@ export function pieSliceWithColor(color) {
|
||||
|
||||
export function echartsTooltip() {
|
||||
// ECharts may keep two dom instances of the tooltip
|
||||
return cy.findAllByTestId("echarts-tooltip").should($elements => {
|
||||
return cy.findAllByTestId("echarts-tooltip").should(($elements) => {
|
||||
// Use a custom function to check if the fixed-position tooltip is visible,
|
||||
// as Cypress's ":visible" or "be.visible" fails to identify a fixed-position tooltip as visible.
|
||||
const visibleTooltips = $elements
|
||||
@@ -224,7 +224,7 @@ export function assertEChartsTooltip({ header, rows, footer, blurAfter }) {
|
||||
}
|
||||
|
||||
if (rows != null) {
|
||||
rows.forEach(row => {
|
||||
rows.forEach((row) => {
|
||||
const { name, ...rest } = row;
|
||||
assertTooltipRow(name, rest);
|
||||
});
|
||||
@@ -242,7 +242,7 @@ export function assertEChartsTooltip({ header, rows, footer, blurAfter }) {
|
||||
|
||||
export function assertEChartsTooltipNotContain(rows) {
|
||||
echartsTooltip().within(() => {
|
||||
rows.forEach(row => {
|
||||
rows.forEach((row) => {
|
||||
cy.findByText(row).should("not.exist");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ export function openSeriesSettings(field, isBreakout = false) {
|
||||
.click({ force: true });
|
||||
} else {
|
||||
cy.findAllByTestId("chart-setting-select")
|
||||
.then($elements => {
|
||||
.then(($elements) => {
|
||||
for (const element of $elements) {
|
||||
if (element.value === field) {
|
||||
return cy.wrap(element);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { USERS } from "e2e/support/cypress_data";
|
||||
import { setup } from "./visit-dashboard";
|
||||
|
||||
describe("visitDashboard e2e helper", () => {
|
||||
Object.keys(Cypress._.omit(USERS, "sandboxed")).forEach(user => {
|
||||
Object.keys(Cypress._.omit(USERS, "sandboxed")).forEach((user) => {
|
||||
context(`${user.toUpperCase()}`, () => {
|
||||
beforeEach(() => {
|
||||
H.restore();
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
|
||||
import { ip_addresses_rows, many_data_types_rows } from "./test_tables_data";
|
||||
|
||||
export const colors27745 = async dbClient => {
|
||||
export const colors27745 = async (dbClient) => {
|
||||
const tableName = "colors27745";
|
||||
|
||||
await dbClient.schema.dropTableIfExists(tableName);
|
||||
await dbClient.schema.createTable(tableName, table => {
|
||||
await dbClient.schema.createTable(tableName, (table) => {
|
||||
table.increments("id").primary();
|
||||
table.string("name").unique().notNullable();
|
||||
});
|
||||
@@ -25,11 +25,11 @@ export const colors27745 = async dbClient => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const scoreboard_actions = async dbClient => {
|
||||
export const scoreboard_actions = async (dbClient) => {
|
||||
const tableName = "scoreboard_actions";
|
||||
|
||||
await dbClient.schema.dropTableIfExists(tableName);
|
||||
await dbClient.schema.createTable(tableName, table => {
|
||||
await dbClient.schema.createTable(tableName, (table) => {
|
||||
table.increments("id").primary();
|
||||
table.string("team_name").unique().notNullable();
|
||||
table.integer("score").notNullable().defaultTo(0);
|
||||
@@ -57,12 +57,12 @@ export const scoreboard_actions = async dbClient => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const many_data_types = async dbClient => {
|
||||
export const many_data_types = async (dbClient) => {
|
||||
const tableName = "many_data_types";
|
||||
|
||||
await dbClient.schema.dropTableIfExists(tableName);
|
||||
|
||||
await dbClient.schema.createTable(tableName, table => {
|
||||
await dbClient.schema.createTable(tableName, (table) => {
|
||||
table.increments("id").primary();
|
||||
table.uuid("uuid");
|
||||
|
||||
@@ -102,12 +102,12 @@ export const many_data_types = async dbClient => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const uuid_pk_table = async dbClient => {
|
||||
export const uuid_pk_table = async (dbClient) => {
|
||||
const tableName = "uuid_pk_table";
|
||||
|
||||
await dbClient.schema.dropTableIfExists(tableName);
|
||||
|
||||
await dbClient.schema.createTable(tableName, table => {
|
||||
await dbClient.schema.createTable(tableName, (table) => {
|
||||
table.uuid("id").primary();
|
||||
table.string("name");
|
||||
});
|
||||
@@ -120,12 +120,12 @@ export const uuid_pk_table = async dbClient => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const composite_pk_table = async dbClient => {
|
||||
export const composite_pk_table = async (dbClient) => {
|
||||
const tableName = "composite_pk_table";
|
||||
|
||||
await dbClient.schema.dropTableIfExists(tableName);
|
||||
|
||||
await dbClient.schema.createTable(tableName, table => {
|
||||
await dbClient.schema.createTable(tableName, (table) => {
|
||||
table.integer("id1");
|
||||
table.string("id2");
|
||||
table.string("name");
|
||||
@@ -145,12 +145,12 @@ export const composite_pk_table = async dbClient => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const no_pk_table = async dbClient => {
|
||||
export const no_pk_table = async (dbClient) => {
|
||||
const tableName = "no_pk_table";
|
||||
|
||||
await dbClient.schema.dropTableIfExists(tableName);
|
||||
|
||||
await dbClient.schema.createTable(tableName, table => {
|
||||
await dbClient.schema.createTable(tableName, (table) => {
|
||||
table.string("name");
|
||||
table.integer("score");
|
||||
});
|
||||
@@ -167,12 +167,12 @@ export const no_pk_table = async dbClient => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const bigint_pk_table = async dbClient => {
|
||||
export const bigint_pk_table = async (dbClient) => {
|
||||
const tableName = "bigint_pk_table";
|
||||
|
||||
await dbClient.schema.dropTableIfExists(tableName);
|
||||
|
||||
await dbClient.schema.createTable(tableName, table => {
|
||||
await dbClient.schema.createTable(tableName, (table) => {
|
||||
table.bigInteger("id").primary();
|
||||
table.string("name");
|
||||
});
|
||||
@@ -186,12 +186,12 @@ export const bigint_pk_table = async dbClient => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const decimal_pk_table = async dbClient => {
|
||||
export const decimal_pk_table = async (dbClient) => {
|
||||
const tableName = "decimal_pk_table";
|
||||
|
||||
await dbClient.schema.dropTableIfExists(tableName);
|
||||
|
||||
await dbClient.schema.createTable(tableName, table => {
|
||||
await dbClient.schema.createTable(tableName, (table) => {
|
||||
table.decimal("id", 38, 0).primary();
|
||||
table.string("name");
|
||||
});
|
||||
@@ -205,7 +205,7 @@ export const decimal_pk_table = async dbClient => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const multi_schema = async dbClient => {
|
||||
export const multi_schema = async (dbClient) => {
|
||||
const schemas = {
|
||||
Domestic: {
|
||||
Animals: [
|
||||
@@ -229,7 +229,7 @@ export const multi_schema = async dbClient => {
|
||||
|
||||
for (const [table, rows] of Object.entries(tables)) {
|
||||
await dbClient.schema.withSchema(schema).dropTableIfExists(table);
|
||||
await dbClient.schema.withSchema(schema).createTable(table, t => {
|
||||
await dbClient.schema.withSchema(schema).createTable(table, (t) => {
|
||||
t.string("name");
|
||||
t.integer("score");
|
||||
});
|
||||
@@ -240,12 +240,12 @@ export const multi_schema = async dbClient => {
|
||||
return schemas;
|
||||
};
|
||||
|
||||
export const ip_addresses = async dbClient => {
|
||||
export const ip_addresses = async (dbClient) => {
|
||||
const tableName = "ip_addresses";
|
||||
|
||||
await dbClient.schema.dropTableIfExists(tableName);
|
||||
|
||||
await dbClient.schema.createTable(tableName, table => {
|
||||
await dbClient.schema.createTable(tableName, (table) => {
|
||||
table.text("count");
|
||||
});
|
||||
|
||||
@@ -255,10 +255,10 @@ export const ip_addresses = async dbClient => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const many_schemas = async dbClient => {
|
||||
export const many_schemas = async (dbClient) => {
|
||||
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
|
||||
const schemas = Object.fromEntries(
|
||||
alphabet.map(letter => {
|
||||
alphabet.map((letter) => {
|
||||
const key = `Schema ${letter}`;
|
||||
const value = [
|
||||
"Animals",
|
||||
@@ -277,7 +277,7 @@ export const many_schemas = async dbClient => {
|
||||
await dbClient.schema.createSchemaIfNotExists(schemaName);
|
||||
await dbClient.schema.withSchema(schemaName).dropTableIfExists(table);
|
||||
|
||||
await dbClient.schema.withSchema(schemaName).createTable(table, t => {
|
||||
await dbClient.schema.withSchema(schemaName).createTable(table, (t) => {
|
||||
t.string("name");
|
||||
t.integer("score");
|
||||
});
|
||||
@@ -288,11 +288,11 @@ export const many_schemas = async dbClient => {
|
||||
return schemas;
|
||||
};
|
||||
|
||||
export const cached_table = async dbClient => {
|
||||
export const cached_table = async (dbClient) => {
|
||||
const tableName = "cached_table";
|
||||
|
||||
await dbClient.schema.dropTableIfExists(tableName);
|
||||
await dbClient.schema.createTable(tableName, table => {
|
||||
await dbClient.schema.createTable(tableName, (table) => {
|
||||
table.increments("id").primary();
|
||||
table.string("my_text").notNullable();
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ describe("scenarios > embedding-sdk > collection browser", () => {
|
||||
cy.intercept("GET", "/api/collection/*").as("getCollection");
|
||||
});
|
||||
|
||||
["personal", undefined].forEach(collectionId => {
|
||||
["personal", undefined].forEach((collectionId) => {
|
||||
it(`should show the personal collection when collectionId is ${collectionId ? collectionId : "not passed"}`, () => {
|
||||
cy.intercept("GET", "/api/user/current").as("getCurrentUser");
|
||||
|
||||
@@ -28,7 +28,7 @@ describe("scenarios > embedding-sdk > collection browser", () => {
|
||||
cy.wait("@getCurrentUser").then(({ response }) => {
|
||||
const personalCollectionId = response?.body.personal_collection_id;
|
||||
|
||||
cy.wait("@getCollection").then(collectionInterception => {
|
||||
cy.wait("@getCollection").then((collectionInterception) => {
|
||||
expect(collectionInterception.request.url).to.include(
|
||||
`/api/collection/${personalCollectionId}`,
|
||||
);
|
||||
@@ -44,7 +44,7 @@ describe("scenarios > embedding-sdk > collection browser", () => {
|
||||
it("should use the root collection if collectionId is 'root'", () => {
|
||||
mountSdkContent(<CollectionBrowser collectionId="root" />);
|
||||
|
||||
cy.wait("@getCollection").then(interception => {
|
||||
cy.wait("@getCollection").then((interception) => {
|
||||
expect(interception.request.url).to.include("/api/collection/root");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -36,7 +36,7 @@ describe("scenarios > embedding-sdk > create-dashboard modal", () => {
|
||||
cy.wait("@getCurrentUser").then(({ response }) => {
|
||||
const personalCollectionId = response?.body.personal_collection_id;
|
||||
|
||||
cy.wait("@createDashboard").then(interception => {
|
||||
cy.wait("@createDashboard").then((interception) => {
|
||||
expect(interception.request.body.collection_id).to.equal(
|
||||
personalCollectionId,
|
||||
);
|
||||
@@ -56,7 +56,7 @@ describe("scenarios > embedding-sdk > create-dashboard modal", () => {
|
||||
cy.wait("@getCurrentUser").then(({ response }) => {
|
||||
const personalCollectionId = response?.body.personal_collection_id;
|
||||
|
||||
cy.wait("@createDashboard").then(interception => {
|
||||
cy.wait("@createDashboard").then((interception) => {
|
||||
expect(interception.request.body.collection_id).to.equal(
|
||||
personalCollectionId,
|
||||
);
|
||||
@@ -81,7 +81,7 @@ describe("scenarios > embedding-sdk > create-dashboard modal", () => {
|
||||
|
||||
fillAndSubmitForm();
|
||||
|
||||
cy.wait("@createDashboard").then(interception => {
|
||||
cy.wait("@createDashboard").then((interception) => {
|
||||
expect(interception.request.body.collection_id).to.equal(null);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -110,16 +110,16 @@ describe("scenarios > embedding-sdk > dashboard-click-behavior", () => {
|
||||
it("should not trigger url click behaviors in the sdk (metabase#51099)", () => {
|
||||
// Spies to intercept opening external links.
|
||||
// See "clickLink" in frontend/src/metabase/lib/dom.js to see what we are intercepting.
|
||||
cy.window().then(win => {
|
||||
cy.window().then((win) => {
|
||||
cy.spy(win.HTMLAnchorElement.prototype, "click").as("anchorClick");
|
||||
});
|
||||
|
||||
cy.get<string>("@dashboardId").then(dashboardId => {
|
||||
cy.get<string>("@dashboardId").then((dashboardId) => {
|
||||
mountSdkContent(<InteractiveDashboard dashboardId={dashboardId} />);
|
||||
});
|
||||
|
||||
cy.wait("@dashcardQuery").then(() => {
|
||||
cy.location().then(location => {
|
||||
cy.location().then((location) => {
|
||||
cy.wrap(location.pathname).as("initialPath");
|
||||
});
|
||||
|
||||
@@ -155,7 +155,7 @@ describe("scenarios > embedding-sdk > dashboard-click-behavior", () => {
|
||||
});
|
||||
|
||||
// We should never open a window in new tab in this test.
|
||||
cy.get<sinon.SinonSpy>("@anchorClick").then(clickSpy => {
|
||||
cy.get<sinon.SinonSpy>("@anchorClick").then((clickSpy) => {
|
||||
const blankClicks = clickSpy
|
||||
.getCalls()
|
||||
.filter(
|
||||
@@ -166,7 +166,7 @@ describe("scenarios > embedding-sdk > dashboard-click-behavior", () => {
|
||||
});
|
||||
|
||||
// We should never be navigated away from the current page in this test.
|
||||
cy.location().then(location => {
|
||||
cy.location().then((location) => {
|
||||
cy.get("@initialPath").should("eq", location.pathname);
|
||||
});
|
||||
});
|
||||
@@ -176,7 +176,7 @@ describe("scenarios > embedding-sdk > dashboard-click-behavior", () => {
|
||||
cy.intercept("GET", "/api/card/*").as("getCard");
|
||||
cy.intercept("POST", "/api/dataset/query_metadata").as("datasetMetadata");
|
||||
|
||||
cy.get("@dashboardId").then(dashboardId => {
|
||||
cy.get("@dashboardId").then((dashboardId) => {
|
||||
mountSdkContent(<EditableDashboard dashboardId={dashboardId} />);
|
||||
});
|
||||
|
||||
|
||||
@@ -48,9 +48,9 @@ describe("scenarios > embedding-sdk > interactive-question > creating a question
|
||||
|
||||
describe("multi-stage picker", () => {
|
||||
beforeEach(() => {
|
||||
cy.intercept("GET", "/api/search*", req => {
|
||||
cy.intercept("GET", "/api/search*", (req) => {
|
||||
if (req.query.limit === "0") {
|
||||
req.continue(res => {
|
||||
req.continue((res) => {
|
||||
// The data picker will fall back to multi-stage picker if there are more than or equal 100 tables and models
|
||||
res.body.total = 100;
|
||||
});
|
||||
|
||||
@@ -40,7 +40,7 @@ describe("scenarios > embedding-sdk > editable-dashboard", () => {
|
||||
});
|
||||
|
||||
it("Should not open sidesheet when clicking last edit info (metabase#48354)", () => {
|
||||
cy.get<string>("@dashboardId").then(dashboardId => {
|
||||
cy.get<string>("@dashboardId").then((dashboardId) => {
|
||||
mountSdkContent(<EditableDashboard dashboardId={dashboardId} />);
|
||||
});
|
||||
|
||||
@@ -86,7 +86,7 @@ describe("scenarios > embedding-sdk > editable-dashboard", () => {
|
||||
|
||||
successTestCases.forEach(({ name, dashboardIdAlias }) => {
|
||||
it(`should load dashboard content for ${name}`, () => {
|
||||
cy.get(dashboardIdAlias).then(dashboardId => {
|
||||
cy.get(dashboardIdAlias).then((dashboardId) => {
|
||||
mountSdkContent(<EditableDashboard dashboardId={dashboardId} />);
|
||||
});
|
||||
|
||||
@@ -162,7 +162,7 @@ describe("scenarios > embedding-sdk > editable-dashboard", () => {
|
||||
});
|
||||
|
||||
it('should drill dashboards with filter values and not showing "Question not found" error (EMB-84)', () => {
|
||||
cy.get("@dashboardId").then(dashboardId => {
|
||||
cy.get("@dashboardId").then((dashboardId) => {
|
||||
mountSdkContent(<EditableDashboard dashboardId={dashboardId} />);
|
||||
});
|
||||
|
||||
@@ -172,7 +172,7 @@ describe("scenarios > embedding-sdk > editable-dashboard", () => {
|
||||
* This seems to be the only reliable way to force the error to stay, and we will resolve
|
||||
* the promise that will cause the error to go away manually after asserting that it's not there.
|
||||
*/
|
||||
cy.intercept("get", "/api/card/*", req => {
|
||||
cy.intercept("get", "/api/card/*", (req) => {
|
||||
return promise.then(() => {
|
||||
req.continue();
|
||||
});
|
||||
@@ -191,7 +191,7 @@ describe("scenarios > embedding-sdk > editable-dashboard", () => {
|
||||
});
|
||||
|
||||
it("should not show New Question button in sidebar (metabase#53896)", () => {
|
||||
cy.get("@dashboardId").then(dashboardId => {
|
||||
cy.get("@dashboardId").then((dashboardId) => {
|
||||
mountSdkContent(<EditableDashboard dashboardId={dashboardId} />);
|
||||
});
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ describe("scenarios > embedding-sdk > interactive-dashboard", () => {
|
||||
});
|
||||
|
||||
it("should be able to display custom question layout when clicking on dashboard cards", () => {
|
||||
cy.get<string>("@dashboardId").then(dashboardId => {
|
||||
cy.get<string>("@dashboardId").then((dashboardId) => {
|
||||
mountSdkContent(
|
||||
<InteractiveDashboard
|
||||
dashboardId={dashboardId}
|
||||
@@ -130,7 +130,7 @@ describe("scenarios > embedding-sdk > interactive-dashboard", () => {
|
||||
|
||||
successTestCases.forEach(({ name, dashboardIdAlias }) => {
|
||||
it(`should load dashboard content for ${name}`, () => {
|
||||
cy.get(dashboardIdAlias).then(dashboardId => {
|
||||
cy.get(dashboardIdAlias).then((dashboardId) => {
|
||||
mountSdkContent(<InteractiveDashboard dashboardId={dashboardId} />);
|
||||
});
|
||||
|
||||
@@ -161,7 +161,7 @@ describe("scenarios > embedding-sdk > interactive-dashboard", () => {
|
||||
});
|
||||
|
||||
it('should drill dashboards with filter values and not showing "Question not found" error (EMB-84)', () => {
|
||||
cy.get("@dashboardId").then(dashboardId => {
|
||||
cy.get("@dashboardId").then((dashboardId) => {
|
||||
mountSdkContent(<InteractiveDashboard dashboardId={dashboardId} />);
|
||||
});
|
||||
|
||||
@@ -174,7 +174,7 @@ describe("scenarios > embedding-sdk > interactive-dashboard", () => {
|
||||
* This seems to be the only reliable way to force the error to stay, and we will resolve
|
||||
* the promise that will cause the error to go away manually after asserting that it's not there.
|
||||
*/
|
||||
cy.intercept("get", "/api/card/*", req => {
|
||||
cy.intercept("get", "/api/card/*", (req) => {
|
||||
return promise.then(() => {
|
||||
req.continue();
|
||||
});
|
||||
|
||||
@@ -58,7 +58,7 @@ describe(
|
||||
},
|
||||
};
|
||||
|
||||
cy.get<number>("@questionId").then(questionId => {
|
||||
cy.get<number>("@questionId").then((questionId) => {
|
||||
mountSdkContent(
|
||||
<Box bg={theme.colors?.background} h="100vh">
|
||||
<InteractiveQuestion questionId={questionId} />
|
||||
@@ -78,18 +78,18 @@ describe(
|
||||
cy.findByTestId("notebook-button")
|
||||
.should("be.visible")
|
||||
.realHover()
|
||||
.should($el => haveBackgroundColor($el, buttonHoverBg));
|
||||
.should(($el) => haveBackgroundColor($el, buttonHoverBg));
|
||||
|
||||
// Should be the lightened version of the background color
|
||||
cy.findByTestId("chart-type-selector-button")
|
||||
.should("be.visible")
|
||||
.realHover()
|
||||
.should($el => haveBackgroundColor($el, buttonHoverBg));
|
||||
.should(($el) => haveBackgroundColor($el, buttonHoverBg));
|
||||
|
||||
cy.findByTestId("notebook-button").click();
|
||||
|
||||
// Should be the lightened version of the background color, same as the notebook button hover.
|
||||
cy.get(customColumn).should($el =>
|
||||
cy.get(customColumn).should(($el) =>
|
||||
haveBackgroundColor($el, buttonHoverBg),
|
||||
);
|
||||
|
||||
@@ -97,7 +97,7 @@ describe(
|
||||
cy.get(customColumn)
|
||||
.should("be.visible")
|
||||
.realHover()
|
||||
.should($el =>
|
||||
.should(($el) =>
|
||||
haveBackgroundColor($el, lighten(theme.colors?.background, 0.4)),
|
||||
);
|
||||
});
|
||||
@@ -114,7 +114,7 @@ describe(
|
||||
},
|
||||
};
|
||||
|
||||
cy.get<number>("@questionId").then(questionId => {
|
||||
cy.get<number>("@questionId").then((questionId) => {
|
||||
mountSdkContent(
|
||||
<Box bg={theme.colors?.background} h="100vh">
|
||||
<InteractiveQuestion questionId={questionId} />
|
||||
@@ -131,7 +131,7 @@ describe(
|
||||
cy.findByTestId("notebook-button").click();
|
||||
|
||||
// Should be the slightly darker version of the background color, same as the notebook button hover
|
||||
cy.get(customColumn).should($el =>
|
||||
cy.get(customColumn).should(($el) =>
|
||||
haveBackgroundColor($el, darken(theme.colors?.background, 0.05)),
|
||||
);
|
||||
|
||||
@@ -139,7 +139,7 @@ describe(
|
||||
cy.get(customColumn)
|
||||
.should("be.visible")
|
||||
.realHover()
|
||||
.should($el =>
|
||||
.should(($el) =>
|
||||
haveBackgroundColor($el, darken(theme.colors?.background, 0.1)),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -74,7 +74,7 @@ describe("scenarios > embedding-sdk > interactive-question", () => {
|
||||
// eslint-disable-next-line no-unsafe-element-filtering
|
||||
cy.findAllByTestId("cell-data").last().click();
|
||||
|
||||
cy.on("uncaught:exception", error => {
|
||||
cy.on("uncaught:exception", (error) => {
|
||||
expect(
|
||||
error.message.includes(
|
||||
"Error converting :aggregation reference: no aggregation at index 0",
|
||||
@@ -98,7 +98,7 @@ describe("scenarios > embedding-sdk > interactive-question", () => {
|
||||
const lastColumnName = "Max of Quantity";
|
||||
const columnNames = [firstColumnName, lastColumnName];
|
||||
|
||||
columnNames.forEach(columnName => {
|
||||
columnNames.forEach((columnName) => {
|
||||
tableInteractive().findByText(columnName).should("be.visible");
|
||||
|
||||
tableHeaderClick(columnName);
|
||||
@@ -206,7 +206,7 @@ describe("scenarios > embedding-sdk > interactive-question", () => {
|
||||
</Box>
|
||||
);
|
||||
|
||||
cy.get<string>("@questionId").then(questionId => {
|
||||
cy.get<string>("@questionId").then((questionId) => {
|
||||
mountSdkContent(<TestSuiteComponent questionId={questionId} />);
|
||||
});
|
||||
|
||||
@@ -270,7 +270,7 @@ describe("scenarios > embedding-sdk > interactive-question", () => {
|
||||
const onBeforeSaveSpy = cy.spy().as("onBeforeSaveSpy");
|
||||
const onSaveSpy = cy.spy().as("onSaveSpy");
|
||||
|
||||
cy.get("@questionId").then(questionId => {
|
||||
cy.get("@questionId").then((questionId) => {
|
||||
mountSdkContent(
|
||||
<TestComponent
|
||||
questionId={questionId}
|
||||
@@ -311,13 +311,13 @@ describe("scenarios > embedding-sdk > interactive-question", () => {
|
||||
// Expect the default summarization view to be there.
|
||||
cy.findByTestId("aggregation-picker").should("be.visible");
|
||||
|
||||
cy.on("uncaught:exception", error => {
|
||||
cy.on("uncaught:exception", (error) => {
|
||||
expect(error.message.includes("Stage 1 does not exist")).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
it("does not contain known console errors (metabase#48497)", () => {
|
||||
cy.get<number>("@questionId").then(questionId => {
|
||||
cy.get<number>("@questionId").then((questionId) => {
|
||||
mountSdkContentAndAssertNoKnownErrors(
|
||||
<InteractiveQuestion questionId={questionId} />,
|
||||
);
|
||||
@@ -353,7 +353,7 @@ describe("scenarios > embedding-sdk > interactive-question", () => {
|
||||
|
||||
successTestCases.forEach(({ name, questionIdAlias }) => {
|
||||
it(`should load question content for ${name}`, () => {
|
||||
cy.get(questionIdAlias).then(questionId => {
|
||||
cy.get(questionIdAlias).then((questionId) => {
|
||||
mountInteractiveQuestion({ questionId });
|
||||
});
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ describe("scenarios > embedding-sdk > locale set on MetabaseProvider", () => {
|
||||
it("when locale=de-CH it should fallback to `de.json`", () => {
|
||||
setup({ locale: "de-CH" });
|
||||
|
||||
cy.request("/app/locales/de.json").then(response => {
|
||||
cy.request("/app/locales/de.json").then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
|
||||
@@ -60,7 +60,7 @@ describe("scenarios > embedding-sdk > locale set on MetabaseProvider", () => {
|
||||
it("when locale=pt it should fallback to pt_BR.json", () => {
|
||||
setup({ locale: "pt" });
|
||||
|
||||
cy.request("/app/locales/pt_BR.json").then(response => {
|
||||
cy.request("/app/locales/pt_BR.json").then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
|
||||
@@ -70,7 +70,7 @@ describe("scenarios > embedding-sdk > locale set on MetabaseProvider", () => {
|
||||
it("when locale=zh-TW it use it as it's available", () => {
|
||||
setup({ locale: "zh-TW" });
|
||||
|
||||
cy.request("/app/locales/zh_TW.json").then(response => {
|
||||
cy.request("/app/locales/zh_TW.json").then((response) => {
|
||||
expect(response.status).to.eq(200);
|
||||
});
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ describe("scenarios > embedding-sdk > plugins", () => {
|
||||
});
|
||||
|
||||
it("should open a click actions popover with a custom item", () => {
|
||||
cy.get<string>("@dashboardId").then(dashboardId => {
|
||||
cy.get<string>("@dashboardId").then((dashboardId) => {
|
||||
mountSdkContent(
|
||||
<InteractiveDashboard
|
||||
dashboardId={dashboardId}
|
||||
|
||||
@@ -70,7 +70,7 @@ const slice = createSlice({
|
||||
value: 0,
|
||||
},
|
||||
reducers: {
|
||||
increment: state => {
|
||||
increment: (state) => {
|
||||
state.value += 1;
|
||||
},
|
||||
},
|
||||
|
||||
@@ -49,7 +49,7 @@ describe("scenarios > embedding-sdk > static-dashboard", () => {
|
||||
});
|
||||
|
||||
it("should render dashboard content", () => {
|
||||
cy.get<string>("@dashboardId").then(dashboardId => {
|
||||
cy.get<string>("@dashboardId").then((dashboardId) => {
|
||||
mountSdkContent(<StaticDashboard dashboardId={dashboardId} />);
|
||||
});
|
||||
|
||||
@@ -68,7 +68,7 @@ describe("scenarios > embedding-sdk > static-dashboard", () => {
|
||||
});
|
||||
|
||||
it("should show fullscreen mode control by default", () => {
|
||||
cy.get<string>("@dashboardId").then(dashboardId => {
|
||||
cy.get<string>("@dashboardId").then((dashboardId) => {
|
||||
mountSdkContent(<StaticDashboard dashboardId={dashboardId} />);
|
||||
});
|
||||
|
||||
@@ -110,7 +110,7 @@ describe("scenarios > embedding-sdk > static-dashboard", () => {
|
||||
|
||||
successTestCases.forEach(({ name, dashboardIdAlias }) => {
|
||||
it(`should load dashboard content for ${name}`, () => {
|
||||
cy.get(dashboardIdAlias).then(dashboardId => {
|
||||
cy.get(dashboardIdAlias).then((dashboardId) => {
|
||||
mountSdkContent(<StaticDashboard dashboardId={dashboardId} />);
|
||||
});
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@ describe("scenarios > embedding-sdk > static-question", () => {
|
||||
|
||||
successTestCases.forEach(({ name, questionIdAlias }) => {
|
||||
it(`should load question content for ${name}`, () => {
|
||||
cy.get(questionIdAlias).then(questionId => {
|
||||
cy.get(questionIdAlias).then((questionId) => {
|
||||
mountStaticQuestion({ questionId });
|
||||
});
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ describe("scenarios > embedding-sdk > styles", () => {
|
||||
expect(response?.statusCode).to.equal(200);
|
||||
});
|
||||
|
||||
cy.get("@defaultBrowserFontFamily").then(defaultBrowserFontFamily => {
|
||||
cy.get("@defaultBrowserFontFamily").then((defaultBrowserFontFamily) => {
|
||||
cy.findByText("This is outside of the provider").should(
|
||||
"have.css",
|
||||
"font-family",
|
||||
@@ -182,7 +182,7 @@ describe("scenarios > embedding-sdk > styles", () => {
|
||||
|
||||
cy.wait("@getUser");
|
||||
|
||||
cy.get("@defaultBrowserFontFamily").then(defaultBrowserFontFamily => {
|
||||
cy.get("@defaultBrowserFontFamily").then((defaultBrowserFontFamily) => {
|
||||
cy.findByText("This is outside of the provider").should(
|
||||
"have.css",
|
||||
"font-family",
|
||||
@@ -372,7 +372,7 @@ describe("scenarios > embedding-sdk > styles", () => {
|
||||
{ tag: "textarea", jsx: <textarea>textarea tag text</textarea> },
|
||||
];
|
||||
|
||||
it(`no css rule should match ${elements.map(e => e.tag).join(", ")} outside of the provider`, () => {
|
||||
it(`no css rule should match ${elements.map((e) => e.tag).join(", ")} outside of the provider`, () => {
|
||||
cy.mount(
|
||||
<div>
|
||||
{elements.map(({ jsx }) => jsx)}
|
||||
@@ -393,7 +393,7 @@ describe("scenarios > embedding-sdk > styles", () => {
|
||||
});
|
||||
|
||||
const expectElementToHaveNoAppliedCssRules = (selector: string) => {
|
||||
cy.get(selector).then($el => {
|
||||
cy.get(selector).then(($el) => {
|
||||
const rules = getCssRulesThatApplyToElement($el);
|
||||
if (rules.length > 0) {
|
||||
console.warn("rules matching", selector, rules);
|
||||
@@ -406,12 +406,12 @@ const getCssRulesThatApplyToElement = ($element: JQuery<HTMLElement>) => {
|
||||
const element = $element[0];
|
||||
const rulesThatMatch: CSSStyleRule[] = Array.from(
|
||||
document.styleSheets,
|
||||
).flatMap(sheet => {
|
||||
).flatMap((sheet) => {
|
||||
const cssRules = Array.from(sheet.cssRules).filter(
|
||||
rule => rule instanceof CSSStyleRule,
|
||||
(rule) => rule instanceof CSSStyleRule,
|
||||
) as CSSStyleRule[];
|
||||
|
||||
return cssRules.filter(rule => element.matches(rule.selectorText));
|
||||
return cssRules.filter((rule) => element.matches(rule.selectorText));
|
||||
});
|
||||
|
||||
return rulesThatMatch;
|
||||
@@ -420,7 +420,7 @@ const getCssRulesThatApplyToElement = ($element: JQuery<HTMLElement>) => {
|
||||
function wrapBrowserDefaultFont() {
|
||||
cy.mount(<p>paragraph with default browser font</p>);
|
||||
|
||||
cy.findByText("paragraph with default browser font").then($element => {
|
||||
cy.findByText("paragraph with default browser font").then(($element) => {
|
||||
const fontFamily = $element.css("font-family");
|
||||
cy.wrap(fontFamily).as("defaultBrowserFontFamily");
|
||||
});
|
||||
|
||||
@@ -38,7 +38,7 @@ describe("scenarios > embedding-sdk > tooltip-reproductions", () => {
|
||||
],
|
||||
}),
|
||||
)
|
||||
.then(dashboard => {
|
||||
.then((dashboard) => {
|
||||
cy.wrap(dashboard.body.id).as("dashboardId");
|
||||
});
|
||||
|
||||
@@ -60,8 +60,8 @@ describe("scenarios > embedding-sdk > tooltip-reproductions", () => {
|
||||
{ input: undefined, expected: 201 },
|
||||
];
|
||||
|
||||
testCases.forEach(zIndexTestCase => {
|
||||
cy.get("@dashboardId").then(dashboardId => {
|
||||
testCases.forEach((zIndexTestCase) => {
|
||||
cy.get("@dashboardId").then((dashboardId) => {
|
||||
mountSdkContent(<InteractiveDashboard dashboardId={dashboardId} />, {
|
||||
sdkProviderProps: {
|
||||
theme: {
|
||||
@@ -78,7 +78,7 @@ describe("scenarios > embedding-sdk > tooltip-reproductions", () => {
|
||||
cy.findAllByTestId("echarts-tooltip")
|
||||
.eq(0)
|
||||
.should("exist")
|
||||
.then($tooltip => {
|
||||
.then(($tooltip) => {
|
||||
const tooltipElement = $tooltip[0];
|
||||
|
||||
// a fixed-position tooltip should be visible
|
||||
|
||||
@@ -54,7 +54,7 @@ describe(
|
||||
describe("in dashboard", () => {
|
||||
beforeEach(() => {
|
||||
asAdmin(() => {
|
||||
cy.get("@modelId").then(modelId => {
|
||||
cy.get("@modelId").then((modelId) => {
|
||||
H.createImplicitActions({ modelId });
|
||||
|
||||
H.createQuestionAndDashboard({
|
||||
@@ -103,7 +103,7 @@ describe(
|
||||
|
||||
permissionLevels.forEach(({ name, permissionFn }) => {
|
||||
it(`should be able to run update and delete actions when enabled for a ${name} user`, () => {
|
||||
cy.get("@modelId").then(modelId => {
|
||||
cy.get("@modelId").then((modelId) => {
|
||||
permissionFn(() => {
|
||||
cy.log(
|
||||
`As ${name} user: verify there are no model actions to run`,
|
||||
@@ -130,7 +130,7 @@ describe(
|
||||
cy.log(`As ${name} user: verify update form gets prefilled`);
|
||||
openUpdateObjectModal();
|
||||
actionExecuteModal().within(() => {
|
||||
cy.wait("@prefetchValues").then(request => {
|
||||
cy.wait("@prefetchValues").then((request) => {
|
||||
const firstScoreRow = request.response.body;
|
||||
|
||||
actionForm().within(() => {
|
||||
@@ -155,7 +155,7 @@ describe(
|
||||
);
|
||||
openUpdateObjectModal();
|
||||
actionExecuteModal().within(() => {
|
||||
cy.wait("@prefetchValues").then(request => {
|
||||
cy.wait("@prefetchValues").then((request) => {
|
||||
const secondScoreRow = request.response.body;
|
||||
|
||||
actionForm().within(() => {
|
||||
@@ -191,7 +191,7 @@ describe(
|
||||
|
||||
cy.signInAsAdmin();
|
||||
|
||||
cy.get("@modelId").then(modelId => {
|
||||
cy.get("@modelId").then((modelId) => {
|
||||
H.createImplicitActions({ modelId });
|
||||
visitObjectDetail(modelId, FIRST_SCORE_ROW_ID);
|
||||
openUpdateObjectModal();
|
||||
|
||||
@@ -11,7 +11,7 @@ const TEST_TABLE = "scoreboard_actions";
|
||||
const TEST_COLUMNS_TABLE = "many_data_types";
|
||||
const MODEL_NAME = "Test Action Model";
|
||||
|
||||
["mysql", "postgres"].forEach(dialect => {
|
||||
["mysql", "postgres"].forEach((dialect) => {
|
||||
describe(
|
||||
`Write Actions on Dashboards (${dialect})`,
|
||||
{ tags: ["@external", "@actions"] },
|
||||
@@ -51,7 +51,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
});
|
||||
|
||||
it("action creation modal can be closed on click outside (WRK-67)", () => {
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
cy.visit(`/model/${id}/detail`);
|
||||
cy.wait(["@getModel", "@getModelActions"]);
|
||||
});
|
||||
@@ -79,12 +79,12 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_TABLE} WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(1);
|
||||
expect(result.rows[0].score).to.equal(0);
|
||||
});
|
||||
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
cy.visit(`/model/${id}/detail`);
|
||||
cy.wait(["@getModel", "@getModelActions"]);
|
||||
});
|
||||
@@ -103,7 +103,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
reorderFields();
|
||||
|
||||
cy.findByRole("dialog").within(() => {
|
||||
cy.findAllByText("Number").each(el => {
|
||||
cy.findAllByText("Number").each((el) => {
|
||||
cy.wrap(el).click();
|
||||
});
|
||||
cy.findByText("Save").click();
|
||||
@@ -136,14 +136,14 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_TABLE} WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(1);
|
||||
expect(result.rows[0].score).to.equal(55);
|
||||
});
|
||||
});
|
||||
|
||||
it("adds an implicit create action to a dashboard and runs it", () => {
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
H.createImplicitAction({
|
||||
kind: "create",
|
||||
model_id: id,
|
||||
@@ -172,7 +172,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_TABLE} WHERE team_name = 'Zany Zebras'`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(1);
|
||||
|
||||
expect(result.rows[0].score).to.equal(44);
|
||||
@@ -182,7 +182,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
it("adds an implicit update action to a dashboard and runs it", () => {
|
||||
const actionName = "Update";
|
||||
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
H.createImplicitAction({
|
||||
kind: "update",
|
||||
model_id: id,
|
||||
@@ -224,7 +224,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_TABLE} WHERE team_name = 'Emotional Elephants'`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(1);
|
||||
|
||||
expect(result.rows[0].score).to.equal(88);
|
||||
@@ -235,12 +235,12 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_TABLE} WHERE team_name = 'Cuddly Cats'`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(1);
|
||||
expect(result.rows[0].id).to.equal(3);
|
||||
});
|
||||
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
H.createImplicitAction({
|
||||
kind: "delete",
|
||||
model_id: id,
|
||||
@@ -267,7 +267,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_TABLE} WHERE team_name = 'Cuddly Cats'`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(0);
|
||||
});
|
||||
});
|
||||
@@ -277,7 +277,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
name: "Public Dashboard",
|
||||
};
|
||||
cy.get("@modelId")
|
||||
.then(id => {
|
||||
.then((id) => {
|
||||
H.createImplicitAction({
|
||||
kind: "create",
|
||||
model_id: id,
|
||||
@@ -306,7 +306,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
|
||||
cy.log("Visit public dashboard");
|
||||
cy.get("@dashboardId")
|
||||
.then(dashboardId => {
|
||||
.then((dashboardId) => {
|
||||
H.createPublicDashboardLink(dashboardId);
|
||||
})
|
||||
.then(({ body: { uuid } }) => {
|
||||
@@ -333,7 +333,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
enable_embedding: true,
|
||||
};
|
||||
cy.get("@modelId")
|
||||
.then(id => {
|
||||
.then((id) => {
|
||||
H.createImplicitAction({
|
||||
kind: "create",
|
||||
model_id: id,
|
||||
@@ -381,7 +381,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
|
||||
describe("hidden fields", () => {
|
||||
it("adds an implicit action and runs it", () => {
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
H.createImplicitAction({
|
||||
kind: "create",
|
||||
model_id: id,
|
||||
@@ -408,7 +408,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_TABLE} WHERE team_name = 'Zany Zebras'`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(1);
|
||||
|
||||
expect(result.rows[0].score).to.equal(44);
|
||||
@@ -421,12 +421,12 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_TABLE} WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(1);
|
||||
expect(result.rows[0].score).to.equal(0);
|
||||
});
|
||||
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
cy.visit(`/model/${id}/detail`);
|
||||
cy.wait(["@getModel", "@getModelActions"]);
|
||||
});
|
||||
@@ -444,7 +444,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
reorderFields();
|
||||
|
||||
cy.findByRole("dialog").within(() => {
|
||||
cy.findAllByText("Number").each(el => {
|
||||
cy.findAllByText("Number").each((el) => {
|
||||
cy.wrap(el).click();
|
||||
});
|
||||
|
||||
@@ -490,12 +490,12 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_TABLE} WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(1);
|
||||
expect(result.rows[0].score).to.equal(55);
|
||||
});
|
||||
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
cy.visit(`/model/${id}/detail`);
|
||||
cy.wait(["@getModel", "@getModelActions"]);
|
||||
});
|
||||
@@ -541,7 +541,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_TABLE} WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(1);
|
||||
expect(result.rows[0].score).to.equal(56);
|
||||
});
|
||||
@@ -565,7 +565,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
});
|
||||
|
||||
it("can update various data types via implicit actions", () => {
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
H.createImplicitAction({
|
||||
kind: "update",
|
||||
model_id: id,
|
||||
@@ -644,7 +644,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_COLUMNS_TABLE} WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(1);
|
||||
|
||||
const row = result.rows[0];
|
||||
@@ -666,7 +666,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
});
|
||||
|
||||
it("can insert various data types via implicit actions", () => {
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
H.createImplicitAction({
|
||||
kind: "create",
|
||||
model_id: id,
|
||||
@@ -715,7 +715,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_COLUMNS_TABLE} WHERE string = 'Zany Zebras'`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(1);
|
||||
const row = result.rows[0];
|
||||
|
||||
@@ -751,7 +751,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
});
|
||||
|
||||
it("does not show json, enum, or binary columns for implicit actions", () => {
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
H.createImplicitAction({
|
||||
kind: "create",
|
||||
model_id: id,
|
||||
@@ -775,7 +775,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
});
|
||||
|
||||
it("properly loads and updates date and time fields for implicit update actions", () => {
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
H.createImplicitAction({
|
||||
kind: "update",
|
||||
model_id: id,
|
||||
@@ -853,7 +853,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${TEST_COLUMNS_TABLE} WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
const row = result.rows[0];
|
||||
|
||||
// the driver adds a time to this date so we have to use .include
|
||||
@@ -937,7 +937,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
modelName: MODEL_NAME,
|
||||
});
|
||||
|
||||
cy.get("@modelId").then(modelId => {
|
||||
cy.get("@modelId").then((modelId) => {
|
||||
H.createAction({
|
||||
...SAMPLE_WRITABLE_QUERY_ACTION,
|
||||
model_id: modelId,
|
||||
@@ -1026,7 +1026,7 @@ const MODEL_NAME = "Test Action Model";
|
||||
cy.button(SAMPLE_QUERY_ACTION.name).click();
|
||||
});
|
||||
|
||||
cy.wait("@executeAction").then(interception => {
|
||||
cy.wait("@executeAction").then((interception) => {
|
||||
expect(
|
||||
Object.values(interception.request.body.parameters)
|
||||
.sort()
|
||||
@@ -1069,7 +1069,7 @@ describe("action error handling", { tags: ["@external", "@actions"] }, () => {
|
||||
it("should show detailed form errors for constraint violations when executing model actions", () => {
|
||||
const actionName = "Update";
|
||||
|
||||
cy.get("@modelId").then(modelId => {
|
||||
cy.get("@modelId").then((modelId) => {
|
||||
H.createImplicitAction({ kind: "update", model_id: modelId });
|
||||
});
|
||||
|
||||
@@ -1132,7 +1132,7 @@ describe(
|
||||
it("refetches form values when id changes (metabase#33084)", () => {
|
||||
const actionName = "Update";
|
||||
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
H.createImplicitAction({
|
||||
kind: "update",
|
||||
model_id: id,
|
||||
@@ -1183,7 +1183,7 @@ describe(
|
||||
it("should reflect to updated action on mapping form", () => {
|
||||
const ACTION_NAME = "Update Score";
|
||||
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
cy.visit(`/model/${id}/detail`);
|
||||
cy.wait(["@getModel", "@getModelActions"]);
|
||||
});
|
||||
@@ -1359,7 +1359,7 @@ function reorderFields() {
|
||||
H.dragField(1, 0);
|
||||
}
|
||||
|
||||
const clickHelper = buttonName => {
|
||||
const clickHelper = (buttonName) => {
|
||||
// this is dirty, but it seems to be the only reliable solution to detached elements before cypress v12
|
||||
// https://github.com/cypress-io/cypress/issues/7306
|
||||
cy.wait(100);
|
||||
@@ -1378,7 +1378,7 @@ function waitForValidActions() {
|
||||
cy.wait("@getActions").then(({ response }) => {
|
||||
const { body: actions } = response;
|
||||
|
||||
actions.forEach(action => {
|
||||
actions.forEach((action) => {
|
||||
expect(action.parameters).to.have.length.gt(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -43,8 +43,8 @@ describe("metabase#31587", () => {
|
||||
.last()
|
||||
.should("have.text", "Click Me");
|
||||
|
||||
actionButtonContainer.then(actionButtonElem => {
|
||||
dashCard.then(dashCardElem => {
|
||||
actionButtonContainer.then((actionButtonElem) => {
|
||||
dashCard.then((dashCardElem) => {
|
||||
expect(actionButtonElem[0].scrollHeight).to.eq(
|
||||
dashCardElem[0].scrollHeight,
|
||||
);
|
||||
@@ -71,8 +71,8 @@ describe("metabase#31587", () => {
|
||||
.last()
|
||||
.should("have.text", "Click Me");
|
||||
|
||||
actionButtonContainer.then(actionButtonElem => {
|
||||
dashCard.then(dashCardElem => {
|
||||
actionButtonContainer.then((actionButtonElem) => {
|
||||
dashCard.then((dashCardElem) => {
|
||||
expect(actionButtonElem[0].scrollHeight).to.eq(
|
||||
dashCardElem[0].scrollHeight,
|
||||
);
|
||||
@@ -202,7 +202,7 @@ describe("Issue 32974", { tags: ["@external", "@actions"] }, () => {
|
||||
});
|
||||
|
||||
it("can submit query action linked with dashboard parameters (metabase#32974)", () => {
|
||||
cy.get("@modelId").then(modelId => {
|
||||
cy.get("@modelId").then((modelId) => {
|
||||
H.createAction({ ...QUERY_ACTION, model_id: modelId }).then(
|
||||
({ body: { id: actionId } }) => {
|
||||
cy.wrap(actionId).as("actionId");
|
||||
@@ -421,7 +421,7 @@ describe("issue 32840", () => {
|
||||
},
|
||||
);
|
||||
|
||||
cy.get("@modelId").then(modelId => {
|
||||
cy.get("@modelId").then((modelId) => {
|
||||
H.createAction({
|
||||
type: "implicit",
|
||||
kind: "row/update",
|
||||
|
||||
@@ -89,7 +89,7 @@ describe(
|
||||
});
|
||||
|
||||
it("should allow CRUD operations on model actions", () => {
|
||||
cy.get("@modelId").then(id => {
|
||||
cy.get("@modelId").then((id) => {
|
||||
cy.visit(`/model/${id}/detail`);
|
||||
cy.wait("@getModel");
|
||||
});
|
||||
@@ -180,7 +180,7 @@ describe(
|
||||
|
||||
cy.findByRole("button", { name: "Create" }).click();
|
||||
|
||||
cy.get("@modelId").then(modelId => {
|
||||
cy.get("@modelId").then((modelId) => {
|
||||
cy.url().should("include", `/model/${modelId}/detail/actions`);
|
||||
});
|
||||
});
|
||||
@@ -206,7 +206,7 @@ describe(
|
||||
},
|
||||
});
|
||||
|
||||
cy.get("@modelId").then(modelId => {
|
||||
cy.get("@modelId").then((modelId) => {
|
||||
cy.request("POST", "/api/action", {
|
||||
...SAMPLE_QUERY_ACTION,
|
||||
model_id: modelId,
|
||||
@@ -285,7 +285,7 @@ describe(
|
||||
it("should show detailed form errors for constraint violations when executing model actions", () => {
|
||||
const actionName = "Update";
|
||||
|
||||
cy.get("@modelId").then(modelId => {
|
||||
cy.get("@modelId").then((modelId) => {
|
||||
H.createImplicitActions({ modelId });
|
||||
|
||||
cy.visit(`/model/${modelId}/detail`);
|
||||
@@ -311,7 +311,7 @@ describe(
|
||||
},
|
||||
);
|
||||
|
||||
["postgres", "mysql"].forEach(dialect => {
|
||||
["postgres", "mysql"].forEach((dialect) => {
|
||||
describe(
|
||||
`Write actions on model detail page (${dialect})`,
|
||||
{ tags: "@external" },
|
||||
@@ -347,12 +347,12 @@ describe(
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${WRITABLE_TEST_TABLE} WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
const row = result.rows[0];
|
||||
expect(row.score).to.equal(0);
|
||||
});
|
||||
|
||||
cy.get("@writableModelId").then(modelId => {
|
||||
cy.get("@writableModelId").then((modelId) => {
|
||||
H.createAction({
|
||||
...SAMPLE_WRITABLE_QUERY_ACTION,
|
||||
model_id: modelId,
|
||||
@@ -375,7 +375,7 @@ describe(
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${WRITABLE_TEST_TABLE} WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
const row = result.rows[0];
|
||||
|
||||
expect(row.score).to.equal(22);
|
||||
@@ -385,7 +385,7 @@ describe(
|
||||
it("should allow public sharing of actions and execution of public actions", () => {
|
||||
const IMPLICIT_ACTION_NAME = "Update";
|
||||
|
||||
cy.get("@writableModelId").then(modelId => {
|
||||
cy.get("@writableModelId").then((modelId) => {
|
||||
H.createAction({
|
||||
...SAMPLE_WRITABLE_QUERY_ACTION,
|
||||
model_id: modelId,
|
||||
@@ -409,7 +409,7 @@ describe(
|
||||
|
||||
cy.signOut();
|
||||
|
||||
cy.get("@queryActionPublicUrl").then(url => {
|
||||
cy.get("@queryActionPublicUrl").then((url) => {
|
||||
cy.visit(url);
|
||||
cy.findByLabelText(TEST_PARAMETER.name).type("1");
|
||||
cy.button(SAMPLE_QUERY_ACTION.name).click();
|
||||
@@ -422,14 +422,14 @@ describe(
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${WRITABLE_TEST_TABLE} WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
const row = result.rows[0];
|
||||
|
||||
expect(row.score).to.equal(22);
|
||||
});
|
||||
});
|
||||
|
||||
cy.get("@implicitActionPublicUrl").then(url => {
|
||||
cy.get("@implicitActionPublicUrl").then((url) => {
|
||||
cy.visit(url);
|
||||
|
||||
// team 2 has 10 points, let's give them more
|
||||
@@ -447,7 +447,7 @@ describe(
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${WRITABLE_TEST_TABLE} WHERE id = 2`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
const row = result.rows[0];
|
||||
|
||||
expect(row.score).to.equal(16);
|
||||
@@ -458,7 +458,7 @@ describe(
|
||||
});
|
||||
|
||||
cy.signInAsAdmin();
|
||||
cy.get("@writableModelId").then(modelId => {
|
||||
cy.get("@writableModelId").then((modelId) => {
|
||||
cy.visit(`/model/${modelId}/detail/actions`);
|
||||
cy.wait("@getModel");
|
||||
});
|
||||
@@ -468,14 +468,14 @@ describe(
|
||||
|
||||
cy.signOut();
|
||||
|
||||
cy.get("@queryActionPublicUrl").then(url => {
|
||||
cy.get("@queryActionPublicUrl").then((url) => {
|
||||
cy.visit(url);
|
||||
cy.findByRole("form").should("not.exist");
|
||||
cy.button(SAMPLE_QUERY_ACTION.name).should("not.exist");
|
||||
cy.findByText("Not found").should("be.visible");
|
||||
});
|
||||
|
||||
cy.get("@implicitActionPublicUrl").then(url => {
|
||||
cy.get("@implicitActionPublicUrl").then((url) => {
|
||||
cy.visit(url);
|
||||
cy.findByRole("form").should("not.exist");
|
||||
cy.button(SAMPLE_QUERY_ACTION.name).should("not.exist");
|
||||
@@ -486,7 +486,7 @@ describe(
|
||||
it("should allow query action execution from the model details page", () => {
|
||||
verifyScoreValue(0, dialect);
|
||||
|
||||
cy.get("@writableModelId").then(modelId => {
|
||||
cy.get("@writableModelId").then((modelId) => {
|
||||
H.createAction({
|
||||
...SAMPLE_WRITABLE_QUERY_ACTION,
|
||||
model_id: modelId,
|
||||
@@ -580,7 +580,7 @@ describe(
|
||||
});
|
||||
|
||||
it("should allow implicit action execution from the model details page", () => {
|
||||
cy.get("@writableModelId").then(id => {
|
||||
cy.get("@writableModelId").then((id) => {
|
||||
cy.visit(`/model/${id}/detail`);
|
||||
cy.wait("@getModel");
|
||||
});
|
||||
@@ -622,7 +622,7 @@ describe(
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${WRITABLE_TEST_TABLE} WHERE team_name = 'Zebras'`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
expect(result.rows.length).to.equal(1);
|
||||
|
||||
const row = result.rows[0];
|
||||
@@ -632,7 +632,7 @@ describe(
|
||||
});
|
||||
|
||||
it("should allow public sharing of query action and execution", () => {
|
||||
cy.get("@writableModelId").then(modelId => {
|
||||
cy.get("@writableModelId").then((modelId) => {
|
||||
H.createAction({
|
||||
...SAMPLE_WRITABLE_QUERY_ACTION,
|
||||
model_id: modelId,
|
||||
@@ -667,7 +667,7 @@ describe(
|
||||
|
||||
cy.signOut();
|
||||
|
||||
cy.get("@queryActionPublicUrl").then(url => {
|
||||
cy.get("@queryActionPublicUrl").then((url) => {
|
||||
cy.visit(url);
|
||||
cy.findByLabelText(TEST_PARAMETER.name).type("1");
|
||||
cy.findByLabelText("New Status").should("not.exist");
|
||||
@@ -681,7 +681,7 @@ describe(
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${WRITABLE_TEST_TABLE} WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
const row = result.rows[0];
|
||||
|
||||
expect(row.score).to.equal(22);
|
||||
@@ -690,7 +690,7 @@ describe(
|
||||
});
|
||||
|
||||
it("should allow public sharing of implicit action and execution", () => {
|
||||
cy.get("@writableModelId").then(id => {
|
||||
cy.get("@writableModelId").then((id) => {
|
||||
cy.visit(`/model/${id}/detail`);
|
||||
cy.wait("@getModel");
|
||||
});
|
||||
@@ -714,7 +714,7 @@ describe(
|
||||
|
||||
cy.signOut();
|
||||
|
||||
cy.get("@updatePublicURL").then(url => {
|
||||
cy.get("@updatePublicURL").then((url) => {
|
||||
cy.visit(url);
|
||||
|
||||
// team 2 has 10 points, let's give them more
|
||||
@@ -730,7 +730,7 @@ describe(
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${WRITABLE_TEST_TABLE} WHERE id = 2`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
const row = result.rows[0];
|
||||
|
||||
expect(row.score).to.equal(16);
|
||||
@@ -782,12 +782,12 @@ describe(
|
||||
FROM ${WRITABLE_TEST_TABLE}
|
||||
WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
const row = result.rows[0];
|
||||
expect(row.score).to.equal(0);
|
||||
});
|
||||
|
||||
cy.get("@writableModelId").then(modelId => {
|
||||
cy.get("@writableModelId").then((modelId) => {
|
||||
H.createAction({
|
||||
...SAMPLE_WRITABLE_QUERY_ACTION,
|
||||
model_id: modelId,
|
||||
@@ -813,7 +813,7 @@ describe(
|
||||
FROM ${WRITABLE_TEST_TABLE}
|
||||
WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
const row = result.rows[0];
|
||||
expect(row.score).to.equal(0);
|
||||
});
|
||||
@@ -858,7 +858,7 @@ function enableSharingFor(actionName, { publicUrlAlias }) {
|
||||
cy.wait("@enableActionSharing");
|
||||
cy.findByLabelText("Public action form URL")
|
||||
.invoke("val")
|
||||
.then(url => {
|
||||
.then((url) => {
|
||||
cy.wrap(url).as(publicUrlAlias);
|
||||
});
|
||||
cy.button("Cancel").click();
|
||||
@@ -898,7 +898,7 @@ function verifyScoreValue(value, dialect) {
|
||||
H.queryWritableDB(
|
||||
`SELECT * FROM ${WRITABLE_TEST_TABLE} WHERE id = 1`,
|
||||
dialect,
|
||||
).then(result => {
|
||||
).then((result) => {
|
||||
const row = result.rows[0];
|
||||
|
||||
expect(row.score).to.equal(value);
|
||||
|
||||
@@ -122,7 +122,7 @@ describe("scenarios > admin > settings > user provisioning", () => {
|
||||
// save to compare with masked token
|
||||
scimTokenInput()
|
||||
.invoke("val")
|
||||
.then(val => (initialUnmaskedToken = String(val)));
|
||||
.then((val) => (initialUnmaskedToken = String(val)));
|
||||
cy.findAllByRole("button", { name: /Done/ }).click();
|
||||
});
|
||||
|
||||
@@ -138,7 +138,9 @@ describe("scenarios > admin > settings > user provisioning", () => {
|
||||
.invoke("val")
|
||||
.should("contain", "mb_")
|
||||
.should("contain", "****************************************")
|
||||
.then(val => expect(val).to.contain(initialUnmaskedToken.slice(0, 7)));
|
||||
.then((val) =>
|
||||
expect(val).to.contain(initialUnmaskedToken.slice(0, 7)),
|
||||
);
|
||||
|
||||
cy.log("should be able to regenerate a token");
|
||||
cy.findByRole("button", { name: /Regenerate/ }).click();
|
||||
@@ -155,7 +157,7 @@ describe("scenarios > admin > settings > user provisioning", () => {
|
||||
.invoke("val")
|
||||
.should("not.contain", "Loading")
|
||||
.should("not.contain", "****************************************")
|
||||
.then(val => (regeneratedToken = String(val)));
|
||||
.then((val) => (regeneratedToken = String(val)));
|
||||
cy.findByRole("button", { name: /Done/ }).click();
|
||||
});
|
||||
|
||||
@@ -163,7 +165,7 @@ describe("scenarios > admin > settings > user provisioning", () => {
|
||||
.invoke("val")
|
||||
.should("contain", "mb_")
|
||||
.should("contain", "****************************************")
|
||||
.then(val => expect(val).to.contain(regeneratedToken.slice(0, 7)));
|
||||
.then((val) => expect(val).to.contain(regeneratedToken.slice(0, 7)));
|
||||
|
||||
cy.log("should be able to cancel regenerating a token");
|
||||
cy.findByRole("button", { name: /Regenerate/ }).click();
|
||||
@@ -178,7 +180,7 @@ describe("scenarios > admin > settings > user provisioning", () => {
|
||||
.invoke("val")
|
||||
.should("contain", "mb_")
|
||||
.should("contain", "****************************************")
|
||||
.then(val => expect(val).to.contain(regeneratedToken.slice(0, 7)));
|
||||
.then((val) => expect(val).to.contain(regeneratedToken.slice(0, 7)));
|
||||
|
||||
cy.log("should be able to disable scim and info stay");
|
||||
scimToggle().click();
|
||||
@@ -237,7 +239,7 @@ describe("scenarios > admin > settings > user provisioning", () => {
|
||||
"should show error when scim token fails to generate when scim is enabled",
|
||||
);
|
||||
// enable scim and stop mocking get scim api key request
|
||||
cy.intercept("GET", "/api/ee/scim/api_key", req => {
|
||||
cy.intercept("GET", "/api/ee/scim/api_key", (req) => {
|
||||
req.continue();
|
||||
});
|
||||
cy.request("PUT", "api/setting/scim-enabled", { value: true });
|
||||
|
||||
@@ -26,7 +26,7 @@ describe("error reporting modal", () => {
|
||||
cy.button(/Download/i).click();
|
||||
});
|
||||
|
||||
getDiagnosticInfoFile().then(fileContent => {
|
||||
getDiagnosticInfoFile().then((fileContent) => {
|
||||
expect(fileContent.entityName).to.equal(undefined);
|
||||
expect(fileContent).to.have.property("frontendErrors");
|
||||
expect(fileContent).to.have.property("backendErrors");
|
||||
@@ -93,7 +93,7 @@ describe("error reporting modal", () => {
|
||||
cy.button(/Download/i).click();
|
||||
});
|
||||
|
||||
getDiagnosticInfoFile().then(fileContent => {
|
||||
getDiagnosticInfoFile().then((fileContent) => {
|
||||
expect(fileContent.entityName).to.equal("question");
|
||||
expect(fileContent).to.have.property("frontendErrors");
|
||||
expect(fileContent).to.have.property("backendErrors");
|
||||
@@ -116,7 +116,7 @@ describe("error reporting modal", () => {
|
||||
cy.button(/Download/i).click();
|
||||
});
|
||||
|
||||
getDiagnosticInfoFile().then(fileContent => {
|
||||
getDiagnosticInfoFile().then((fileContent) => {
|
||||
expect(fileContent.entityName).to.equal("question");
|
||||
expect(fileContent).to.have.property("frontendErrors");
|
||||
expect(fileContent).to.have.property("backendErrors");
|
||||
@@ -149,7 +149,7 @@ describe("error reporting modal", () => {
|
||||
cy.button(/Download/i).click();
|
||||
});
|
||||
|
||||
getDiagnosticInfoFile().then(fileContent => {
|
||||
getDiagnosticInfoFile().then((fileContent) => {
|
||||
expect(fileContent.entityName).to.equal("question");
|
||||
expect(fileContent).to.have.property("frontendErrors");
|
||||
expect(fileContent).to.have.property("backendErrors");
|
||||
@@ -177,7 +177,7 @@ describe("error reporting modal", () => {
|
||||
cy.button(/Download/i).click();
|
||||
});
|
||||
|
||||
getDiagnosticInfoFile().then(fileContent => {
|
||||
getDiagnosticInfoFile().then((fileContent) => {
|
||||
expect(fileContent.entityName).to.equal("dashboard");
|
||||
expect(fileContent.url).to.include("/dashboard/");
|
||||
|
||||
|
||||
@@ -151,7 +151,9 @@ describe("scenarios > admin > people", () => {
|
||||
|
||||
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
|
||||
cy.findByText(FULL_NAME);
|
||||
cy.location().should(loc => expect(loc.pathname).to.eq("/admin/people"));
|
||||
cy.location().should((loc) =>
|
||||
expect(loc.pathname).to.eq("/admin/people"),
|
||||
);
|
||||
});
|
||||
|
||||
it("should allow admin to create new users without first name or last name (metabase#22754)", () => {
|
||||
@@ -219,7 +221,7 @@ describe("scenarios > admin > people", () => {
|
||||
cy.findByText("Deactivate user").click();
|
||||
clickButton("Deactivate");
|
||||
cy.findByText(FULL_NAME).should("not.exist");
|
||||
cy.location().should(loc =>
|
||||
cy.location().should((loc) =>
|
||||
expect(loc.pathname).to.eq("/admin/people"),
|
||||
);
|
||||
|
||||
@@ -229,7 +231,7 @@ describe("scenarios > admin > people", () => {
|
||||
cy.icon("refresh").click();
|
||||
cy.findByText(`Reactivate ${FULL_NAME}?`);
|
||||
clickButton("Reactivate");
|
||||
cy.location().should(loc =>
|
||||
cy.location().should((loc) =>
|
||||
expect(loc.pathname).to.eq("/admin/people"),
|
||||
);
|
||||
});
|
||||
@@ -256,7 +258,9 @@ describe("scenarios > admin > people", () => {
|
||||
|
||||
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
|
||||
cy.findByText(NEW_FULL_NAME);
|
||||
cy.location().should(loc => expect(loc.pathname).to.eq("/admin/people"));
|
||||
cy.location().should((loc) =>
|
||||
expect(loc.pathname).to.eq("/admin/people"),
|
||||
);
|
||||
});
|
||||
|
||||
it("should reset user password without SMTP set up", () => {
|
||||
@@ -272,7 +276,9 @@ describe("scenarios > admin > people", () => {
|
||||
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
|
||||
cy.findByText(/^temporary password$/i);
|
||||
clickButton("Done");
|
||||
cy.location().should(loc => expect(loc.pathname).to.eq("/admin/people"));
|
||||
cy.location().should((loc) =>
|
||||
expect(loc.pathname).to.eq("/admin/people"),
|
||||
);
|
||||
});
|
||||
|
||||
it("should not offer to reset passwords when password login is disabled", () => {
|
||||
@@ -589,7 +595,7 @@ describe("scenarios > admin > people", () => {
|
||||
cy.contains(
|
||||
`We’ve sent an invite to ${email} with instructions to log in. If this user is unable to authenticate then you can reset their password.`,
|
||||
);
|
||||
cy.url().then(url => {
|
||||
cy.url().then((url) => {
|
||||
const URL_REGEX = /\/admin\/people\/(?<userId>\d+)\/success/;
|
||||
const { userId } = URL_REGEX.exec(url).groups;
|
||||
assertLinkMatchesUrl(
|
||||
@@ -878,7 +884,7 @@ function assertTableRowsCount(length) {
|
||||
}
|
||||
|
||||
function generateUsers(count, groupIds) {
|
||||
const users = _.range(count).map(index => ({
|
||||
const users = _.range(count).map((index) => ({
|
||||
first_name: `FirstName ${index}`,
|
||||
last_name: `LastName ${index}`,
|
||||
email: `user_${index}@metabase.com`,
|
||||
@@ -886,13 +892,13 @@ function generateUsers(count, groupIds) {
|
||||
groupIds,
|
||||
}));
|
||||
|
||||
users.forEach(u => cy.createUserFromRawData(u));
|
||||
users.forEach((u) => cy.createUserFromRawData(u));
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
function generateGroups(count) {
|
||||
_.range(count).map(index => {
|
||||
_.range(count).map((index) => {
|
||||
cy.request("POST", "api/permissions/group", { name: "Group" + index });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ H.describeWithSnowplow("scenarios > admin > settings", () => {
|
||||
it("should display an error if the https redirect check fails", () => {
|
||||
cy.visit("/admin/settings/general");
|
||||
|
||||
cy.intercept("GET", "**/api/health", req => {
|
||||
cy.intercept("GET", "**/api/health", (req) => {
|
||||
req.reply({ forceNetworkError: true });
|
||||
}).as("httpsCheck");
|
||||
// switch site url to use https
|
||||
@@ -238,7 +238,7 @@ H.describeWithSnowplow("scenarios > admin > settings", () => {
|
||||
// 1. Get the array of ALL available settings
|
||||
cy.request("GET", "/api/setting").then(({ body }) => {
|
||||
// 2. Create a stubbed version of that array by passing modified "site-url" settings
|
||||
const STUBBED_BODY = body.map(setting => {
|
||||
const STUBBED_BODY = body.map((setting) => {
|
||||
if (setting.key === "site-url") {
|
||||
const STUBBED_SITE_URL = Object.assign({}, setting, {
|
||||
is_env_setting: true,
|
||||
@@ -251,7 +251,7 @@ H.describeWithSnowplow("scenarios > admin > settings", () => {
|
||||
});
|
||||
|
||||
// 3. Stub the whole response
|
||||
cy.intercept("GET", "/api/setting", req => {
|
||||
cy.intercept("GET", "/api/setting", (req) => {
|
||||
req.reply({ body: STUBBED_BODY });
|
||||
}).as("appSettings");
|
||||
});
|
||||
@@ -402,8 +402,8 @@ describe.skip(
|
||||
|
||||
refresh();
|
||||
|
||||
getCellText().then(res => {
|
||||
cy.get("@tempResult").then(temp => {
|
||||
getCellText().then((res) => {
|
||||
cy.get("@tempResult").then((temp) => {
|
||||
if (res === temp) {
|
||||
cy.wrap(res).as("cachedResult");
|
||||
} else {
|
||||
@@ -441,7 +441,7 @@ describe.skip(
|
||||
H.NativeEditor.type(nativeQuery);
|
||||
H.runNativeQuery();
|
||||
|
||||
getCellText().then(res => {
|
||||
getCellText().then((res) => {
|
||||
cy.wrap(res).as("tempResult");
|
||||
});
|
||||
|
||||
@@ -451,7 +451,7 @@ describe.skip(
|
||||
it("should respect previously set cache duration (metabase#18458)", () => {
|
||||
refreshUntilCached();
|
||||
|
||||
cy.get("@cachedResult").then(cachedValue => {
|
||||
cy.get("@cachedResult").then((cachedValue) => {
|
||||
/**
|
||||
* 5s is longer than what we set the cache to last:
|
||||
* Approx 2s for an Average Runtime x multiplier of 2.
|
||||
@@ -462,7 +462,7 @@ describe.skip(
|
||||
|
||||
refresh();
|
||||
|
||||
getCellText().then(newValue => {
|
||||
getCellText().then((newValue) => {
|
||||
expect(newValue).to.not.eq(cachedValue);
|
||||
});
|
||||
});
|
||||
@@ -645,7 +645,7 @@ describe("scenarios > admin > license and billing", () => {
|
||||
const STORE_MANAGED_FEATURE_KEY = "metabase-store-managed";
|
||||
const NO_UPSELL_FEATURE_HEY = "no-upsell";
|
||||
// mocks data the will be returned by enterprise useLicense hook
|
||||
const mockBillingTokenFeatures = features => {
|
||||
const mockBillingTokenFeatures = (features) => {
|
||||
return cy.intercept("GET", "/api/premium-features/token/status", {
|
||||
"valid-thru": "2099-12-31T12:00:00",
|
||||
valid: true,
|
||||
@@ -685,10 +685,10 @@ describe("scenarios > admin > license and billing", () => {
|
||||
// create an admin user who is also connected to our test harbormaster account
|
||||
cy.request("GET", "/api/permissions/group")
|
||||
.then(({ body: groups }) => {
|
||||
const adminGroup = groups.find(g => g.name === "Administrators");
|
||||
const adminGroup = groups.find((g) => g.name === "Administrators");
|
||||
return cy
|
||||
.createUserFromRawData(harborMasterConnectedAccount)
|
||||
.then(user => Promise.resolve([adminGroup.id, user]));
|
||||
.then((user) => Promise.resolve([adminGroup.id, user]));
|
||||
})
|
||||
.then(([adminGroupId, user]) => {
|
||||
const data = { user_id: user.id, group_id: adminGroupId };
|
||||
@@ -696,7 +696,7 @@ describe("scenarios > admin > license and billing", () => {
|
||||
.request("POST", "/api/permissions/membership", data)
|
||||
.then(() => Promise.resolve(user));
|
||||
})
|
||||
.then(user => {
|
||||
.then((user) => {
|
||||
cy.signOut(); // stop being normal admin user and be store connected admin user
|
||||
return cy.request("POST", "/api/session", {
|
||||
username: user.email,
|
||||
@@ -729,7 +729,7 @@ describe("scenarios > admin > license and billing", () => {
|
||||
NO_UPSELL_FEATURE_HEY,
|
||||
]);
|
||||
// force an error
|
||||
cy.intercept("GET", "/api/ee/billing", req => {
|
||||
cy.intercept("GET", "/api/ee/billing", (req) => {
|
||||
req.reply({ statusCode: 500 });
|
||||
});
|
||||
cy.visit("/admin/settings/license");
|
||||
@@ -1018,7 +1018,7 @@ describe("scenarios > admin > settings > map settings", () => {
|
||||
);
|
||||
// eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
|
||||
cy.findByText("Load").click();
|
||||
cy.wait("@load").then(interception => {
|
||||
cy.wait("@load").then((interception) => {
|
||||
expect(interception.response.statusCode).to.eq(200);
|
||||
});
|
||||
});
|
||||
@@ -1067,7 +1067,7 @@ describe("scenarios > admin > settings > map settings", () => {
|
||||
|
||||
it("should show an informative error when adding a calid URL that contains GeoJSON that does not use lat/lng coordinates", () => {
|
||||
//intercept call to api/geojson and return projected.geojson. Call to load file actually happens in the BE
|
||||
cy.fixture("../../e2e/support/assets/projected.geojson").then(data => {
|
||||
cy.fixture("../../e2e/support/assets/projected.geojson").then((data) => {
|
||||
cy.intercept("GET", "/api/geojson*", data);
|
||||
});
|
||||
|
||||
@@ -1098,7 +1098,7 @@ describe("notifications", { tags: "@external" }, () => {
|
||||
failOnStatusCode: false,
|
||||
url: `${H.WEBHOOK_TEST_HOST}/api/session/${H.WEBHOOK_TEST_SESSION_ID}/requests`,
|
||||
method: "DELETE",
|
||||
}).then(response => {
|
||||
}).then((response) => {
|
||||
cy.log("Deleted requests.");
|
||||
});
|
||||
});
|
||||
@@ -1161,13 +1161,13 @@ describe("notifications", { tags: "@external" }, () => {
|
||||
},
|
||||
];
|
||||
|
||||
AUTH_METHODS.forEach(auth => {
|
||||
AUTH_METHODS.forEach((auth) => {
|
||||
it(`${auth.display} Auth`, () => {
|
||||
cy.visit("/admin/settings/notifications");
|
||||
cy.findByRole("heading", { name: "Add a webhook" }).click();
|
||||
|
||||
H.modal().within(() => {
|
||||
COMMON_FIELDS.forEach(field => {
|
||||
COMMON_FIELDS.forEach((field) => {
|
||||
cy.findByLabelText(field.label).type(field.value);
|
||||
});
|
||||
|
||||
@@ -1284,7 +1284,7 @@ describe("admin > settings > updates", () => {
|
||||
cy.visit("/admin/settings/updates");
|
||||
|
||||
cy.intercept("GET", "/api/session/properties", (req, res) => {
|
||||
req.continue(res => {
|
||||
req.continue((res) => {
|
||||
res.body["version-info"] = versionInfo;
|
||||
res.body.version.tag = currentVersion;
|
||||
return res.body;
|
||||
|
||||
@@ -240,7 +240,7 @@ const getLdapCard = () => {
|
||||
return cy.findByText("LDAP").parent().parent();
|
||||
};
|
||||
|
||||
const enterLdapPort = value => {
|
||||
const enterLdapPort = (value) => {
|
||||
H.typeAndBlurUsingLabel("LDAP Port", value);
|
||||
};
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ const getSamlCard = () => {
|
||||
};
|
||||
|
||||
const enterSamlSettings = () => {
|
||||
getSamlCertificate().then(certificate => {
|
||||
getSamlCertificate().then((certificate) => {
|
||||
H.typeAndBlurUsingLabel(
|
||||
/SAML Identity Provider URL/,
|
||||
"https://example.test",
|
||||
|
||||
@@ -61,7 +61,7 @@ export function checkGroupConsistencyAfterDeletingMappings(
|
||||
cy.findByText("readonly");
|
||||
}
|
||||
|
||||
const deleteMappingWithGroups = mappingName => {
|
||||
const deleteMappingWithGroups = (mappingName) => {
|
||||
cy.findByText(mappingName)
|
||||
.closest("tr")
|
||||
.within(() => {
|
||||
@@ -72,7 +72,7 @@ const deleteMappingWithGroups = mappingName => {
|
||||
cy.button("Remove mapping and delete groups").click();
|
||||
};
|
||||
|
||||
const createMapping = name => {
|
||||
const createMapping = (name) => {
|
||||
cy.button("New mapping").click();
|
||||
cy.findByLabelText("new-group-mapping-name-input").type(name);
|
||||
cy.button("Add").click();
|
||||
@@ -85,7 +85,7 @@ const addGroupsToMapping = (mappingName, groups) => {
|
||||
cy.findByText("Default").click();
|
||||
});
|
||||
|
||||
groups.forEach(group => {
|
||||
groups.forEach((group) => {
|
||||
popover().within(() => {
|
||||
cy.findByText(group).click();
|
||||
|
||||
@@ -100,7 +100,7 @@ const addGroupsToMapping = (mappingName, groups) => {
|
||||
cy.realPress("{esc}");
|
||||
};
|
||||
|
||||
const checkThatGroupHasNoMembers = name => {
|
||||
const checkThatGroupHasNoMembers = (name) => {
|
||||
cy.findByText(name)
|
||||
.closest("tr")
|
||||
.within(() => cy.findByText("0"));
|
||||
|
||||
@@ -18,7 +18,7 @@ export const getSamlCertificate = () => {
|
||||
};
|
||||
|
||||
export const setupSaml = () => {
|
||||
getSamlCertificate().then(certificate => {
|
||||
getSamlCertificate().then((certificate) => {
|
||||
cy.request("PUT", "/api/setting", {
|
||||
"saml-enabled": true,
|
||||
"saml-identity-provider-uri": "https://example.test",
|
||||
|
||||
@@ -8,7 +8,7 @@ function checkFavicon(url) {
|
||||
}
|
||||
|
||||
function checkLogo() {
|
||||
cy.readFile("e2e/support/assets/logo.jpeg", "base64").then(logo_data => {
|
||||
cy.readFile("e2e/support/assets/logo.jpeg", "base64").then((logo_data) => {
|
||||
cy.get(`img[src="data:image/jpeg;base64,${logo_data}"]`).should("exist");
|
||||
});
|
||||
}
|
||||
@@ -106,7 +106,7 @@ describe("formatting > whitelabel", { tags: "@EE" }, () => {
|
||||
beforeEach(() => {
|
||||
cy.log("Add a logo");
|
||||
cy.readFile("e2e/support/assets/logo.jpeg", "base64").then(
|
||||
logo_data => {
|
||||
(logo_data) => {
|
||||
H.updateSetting(
|
||||
"application-logo-url",
|
||||
`data:image/jpeg;base64,${logo_data}`,
|
||||
@@ -159,7 +159,7 @@ describe("formatting > whitelabel", { tags: "@EE" }, () => {
|
||||
);
|
||||
H.undoToast().findByText("Changes saved").should("be.visible");
|
||||
cy.readFile("e2e/support/assets/favicon.ico", "base64").then(
|
||||
base64Url => {
|
||||
(base64Url) => {
|
||||
const faviconUrl = `data:image/jpeg;base64,${base64Url}`;
|
||||
cy.wrap(faviconUrl).as("faviconUrl");
|
||||
checkFavicon(faviconUrl);
|
||||
@@ -167,7 +167,7 @@ describe("formatting > whitelabel", { tags: "@EE" }, () => {
|
||||
);
|
||||
cy.signInAsNormalUser();
|
||||
cy.visit("/");
|
||||
cy.get("@faviconUrl").then(faviconUrl => {
|
||||
cy.get("@faviconUrl").then((faviconUrl) => {
|
||||
cy.get('head link[rel="icon"]')
|
||||
.get(`[href="${faviconUrl}"]`)
|
||||
.should("have.length", 1);
|
||||
@@ -280,7 +280,7 @@ describe("formatting > whitelabel", { tags: "@EE" }, () => {
|
||||
H.undoToast().findByText("Changes saved").should("be.visible");
|
||||
|
||||
cy.readFile("e2e/support/assets/logo.jpeg", "base64").then(
|
||||
logo_data => {
|
||||
(logo_data) => {
|
||||
const backgroundImage = `url("data:image/jpeg;base64,${logo_data}")`;
|
||||
cy.signOut();
|
||||
cy.visit("/");
|
||||
@@ -347,7 +347,7 @@ describe("formatting > whitelabel", { tags: "@EE" }, () => {
|
||||
H.undoToast().findByText("Changes saved").should("be.visible");
|
||||
|
||||
cy.readFile("e2e/support/assets/logo.jpeg", "base64").then(
|
||||
logo_data => {
|
||||
(logo_data) => {
|
||||
const backgroundImage = `url("data:image/jpeg;base64,${logo_data}")`;
|
||||
cy.visit("/");
|
||||
cy.findByTestId("landing-page-illustration").should(
|
||||
@@ -413,7 +413,7 @@ describe("formatting > whitelabel", { tags: "@EE" }, () => {
|
||||
|
||||
H.visitDashboard("@dashboardId");
|
||||
cy.readFile("e2e/support/assets/logo.jpeg", "base64").then(
|
||||
logo_data => {
|
||||
(logo_data) => {
|
||||
const imageDataUrl = `data:image/jpeg;base64,${logo_data}`;
|
||||
cy.wrap(imageDataUrl).as("imageDataUrl");
|
||||
cy.findByAltText("No results").should(
|
||||
@@ -425,7 +425,7 @@ describe("formatting > whitelabel", { tags: "@EE" }, () => {
|
||||
);
|
||||
|
||||
H.visitQuestion("@questionId");
|
||||
cy.get("@imageDataUrl").then(imageDataUrl => {
|
||||
cy.get("@imageDataUrl").then((imageDataUrl) => {
|
||||
cy.findByAltText("No results").should(
|
||||
"have.attr",
|
||||
"src",
|
||||
@@ -484,7 +484,7 @@ describe("formatting > whitelabel", { tags: "@EE" }, () => {
|
||||
H.modal().findByTestId("collection-picker-button").click();
|
||||
H.entityPickerModal().within(() => {
|
||||
cy.readFile("e2e/support/assets/logo.jpeg", "base64").then(
|
||||
logo_data => {
|
||||
(logo_data) => {
|
||||
const imageDataUrl = `data:image/jpeg;base64,${logo_data}`;
|
||||
cy.wrap(imageDataUrl).as("imageDataUrl");
|
||||
},
|
||||
@@ -494,7 +494,7 @@ describe("formatting > whitelabel", { tags: "@EE" }, () => {
|
||||
cy.findByPlaceholderText("Search…").type(
|
||||
"This aren't the objects you're looking for",
|
||||
);
|
||||
cy.get("@imageDataUrl").then(imageDataUrl => {
|
||||
cy.get("@imageDataUrl").then((imageDataUrl) => {
|
||||
cy.findByAltText("No results").should(
|
||||
"have.attr",
|
||||
"src",
|
||||
|
||||
@@ -66,7 +66,7 @@ describe("issue 21532", () => {
|
||||
cy.findByTestId("admin-layout-content");
|
||||
|
||||
cy.go("back");
|
||||
cy.location().should(location => {
|
||||
cy.location().should((location) => {
|
||||
expect(location.pathname).to.eq("/");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -19,7 +19,7 @@ describe(
|
||||
"admin > database > external databases > enable actions",
|
||||
{ tags: ["@external", "@actions"] },
|
||||
() => {
|
||||
["mysql", "postgres"].forEach(dialect => {
|
||||
["mysql", "postgres"].forEach((dialect) => {
|
||||
it(`should show ${dialect} writable_db with actions enabled`, () => {
|
||||
H.restore(`${dialect}-writable`);
|
||||
cy.signInAsAdmin();
|
||||
@@ -61,7 +61,7 @@ describe("admin > database > add", () => {
|
||||
function mockUploadServiceAccountJSON(fileContents) {
|
||||
// create blob to act as selected file
|
||||
cy.get("input[type=file]")
|
||||
.then(async input => {
|
||||
.then(async (input) => {
|
||||
const blob = await Cypress.Blob.binaryStringToBlob(fileContents);
|
||||
const file = new File([blob], "service-account.json");
|
||||
const dataTransfer = new DataTransfer();
|
||||
@@ -75,7 +75,7 @@ describe("admin > database > add", () => {
|
||||
}
|
||||
|
||||
function mockSuccessfulDatabaseSave() {
|
||||
cy.intercept("POST", "/api/database", req => {
|
||||
cy.intercept("POST", "/api/database", (req) => {
|
||||
req.reply({ statusCode: 200, body: { id: 42 }, delay: 100 });
|
||||
}).as("createDatabase");
|
||||
|
||||
@@ -90,7 +90,7 @@ describe("admin > database > add", () => {
|
||||
}
|
||||
cy.wait("@getDatabases").then(({ response }) => {
|
||||
if (
|
||||
response.body.data.some(db => db.initial_sync_status !== "complete")
|
||||
response.body.data.some((db) => db.initial_sync_status !== "complete")
|
||||
) {
|
||||
waitForDbSync(maxRetries - 1);
|
||||
}
|
||||
@@ -172,8 +172,8 @@ describe("admin > database > add", () => {
|
||||
});
|
||||
|
||||
const confirmSSLFields = (visible, hidden) => {
|
||||
visible.forEach(field => cy.findByText(field));
|
||||
hidden.forEach(field => cy.findByText(field).should("not.exist"));
|
||||
visible.forEach((field) => cy.findByText(field));
|
||||
hidden.forEach((field) => cy.findByText(field).should("not.exist"));
|
||||
};
|
||||
|
||||
const ssl = "Use a secure connection (SSL)",
|
||||
@@ -465,8 +465,8 @@ describe("scenarios > admin > databases > exceptions", () => {
|
||||
});
|
||||
|
||||
it("should handle malformed (null) database details (metabase#25715)", () => {
|
||||
cy.intercept("GET", `/api/database/${SAMPLE_DB_ID}`, req => {
|
||||
req.reply(res => {
|
||||
cy.intercept("GET", `/api/database/${SAMPLE_DB_ID}`, (req) => {
|
||||
req.reply((res) => {
|
||||
res.body.details = null;
|
||||
});
|
||||
}).as("loadDatabase");
|
||||
@@ -486,8 +486,8 @@ describe("scenarios > admin > databases > exceptions", () => {
|
||||
});
|
||||
|
||||
it("should handle is_attached_dwh databases", () => {
|
||||
cy.intercept("GET", `/api/database/${SAMPLE_DB_ID}`, req => {
|
||||
req.reply(res => {
|
||||
cy.intercept("GET", `/api/database/${SAMPLE_DB_ID}`, (req) => {
|
||||
req.reply((res) => {
|
||||
res.body.details = null;
|
||||
res.body.is_attached_dwh = true;
|
||||
});
|
||||
@@ -512,7 +512,7 @@ describe("scenarios > admin > databases > exceptions", () => {
|
||||
});
|
||||
|
||||
it("should show error upon a bad request", () => {
|
||||
cy.intercept("POST", "/api/database", req => {
|
||||
cy.intercept("POST", "/api/database", (req) => {
|
||||
req.reply({
|
||||
statusCode: 400,
|
||||
body: "DATABASE CONNECTION ERROR",
|
||||
@@ -558,7 +558,7 @@ describe("scenarios > admin > databases > exceptions", () => {
|
||||
}
|
||||
: null,
|
||||
},
|
||||
req => {
|
||||
(req) => {
|
||||
req.reply({
|
||||
statusCode: 500,
|
||||
body: { message: errorMessage },
|
||||
|
||||
@@ -14,7 +14,7 @@ describe("scenarios > admin > datamodel > field > field type", () => {
|
||||
const ordersColumns = ["PRODUCT_ID", "QUANTITY"];
|
||||
|
||||
function waitAndAssertOnResponse(alias) {
|
||||
cy.wait("@" + alias).then(xhr => {
|
||||
cy.wait("@" + alias).then((xhr) => {
|
||||
expect(xhr.response.body.errors).to.not.exist;
|
||||
});
|
||||
}
|
||||
@@ -51,7 +51,7 @@ describe("scenarios > admin > datamodel > field > field type", () => {
|
||||
H.restore();
|
||||
cy.signInAsAdmin();
|
||||
|
||||
ordersColumns.forEach(column => {
|
||||
ordersColumns.forEach((column) => {
|
||||
cy.wrap(
|
||||
`/admin/datamodel/database/${SAMPLE_DB_ID}/schema/${SAMPLE_DB_SCHEMA_ID}/table/${ORDERS_ID}/field/${ORDERS[column]}/general`,
|
||||
).as(`ORDERS_${column}_URL`);
|
||||
@@ -106,7 +106,7 @@ describe("scenarios > admin > datamodel > field", () => {
|
||||
H.restore();
|
||||
cy.signInAsAdmin();
|
||||
|
||||
["CREATED_AT", "PRODUCT_ID", "QUANTITY"].forEach(name => {
|
||||
["CREATED_AT", "PRODUCT_ID", "QUANTITY"].forEach((name) => {
|
||||
cy.wrap(
|
||||
`/admin/datamodel/database/${SAMPLE_DB_ID}/schema/${SAMPLE_DB_SCHEMA_ID}/table/${ORDERS_ID}/field/${ORDERS[name]}/general`,
|
||||
).as(`ORDERS_${name}_URL`);
|
||||
@@ -473,7 +473,7 @@ describe("scenarios > admin > datamodel > metadata", () => {
|
||||
|
||||
cy.log("Numeric ratings should be remapped to custom strings");
|
||||
H.openReviewsTable();
|
||||
Object.values(customMap).forEach(rating => {
|
||||
Object.values(customMap).forEach((rating) => {
|
||||
cy.findAllByText(rating);
|
||||
});
|
||||
});
|
||||
@@ -755,7 +755,7 @@ describe("scenarios > admin > datamodel > segments", () => {
|
||||
});
|
||||
|
||||
it("should not crash when editing field in segment field detail page (metabase#55322)", () => {
|
||||
cy.get("@segmentId").then(segmentId => {
|
||||
cy.get("@segmentId").then((segmentId) => {
|
||||
cy.visit(`/reference/segments/${segmentId}/fields/${ORDERS.TAX}`);
|
||||
});
|
||||
|
||||
|
||||
@@ -634,7 +634,7 @@ describe("scenarios > admin > datamodel > editor", () => {
|
||||
});
|
||||
|
||||
const setDataModelPermissions = ({ tableIds = [] }) => {
|
||||
const permissions = Object.fromEntries(tableIds.map(id => [id, "all"]));
|
||||
const permissions = Object.fromEntries(tableIds.map((id) => [id, "all"]));
|
||||
|
||||
cy.updatePermissionsGraph({
|
||||
[ALL_USERS_GROUP]: {
|
||||
@@ -676,7 +676,7 @@ const setValueAndBlurInput = (oldValue, newValue) => {
|
||||
cy.findByDisplayValue(oldValue).clear().type(newValue).blur();
|
||||
};
|
||||
|
||||
const clearAndBlurInput = oldValue => {
|
||||
const clearAndBlurInput = (oldValue) => {
|
||||
cy.findByDisplayValue(oldValue).clear().blur();
|
||||
};
|
||||
|
||||
@@ -684,17 +684,17 @@ const searchAndSelectValue = (newValue, searchText = newValue) => {
|
||||
H.popover().findByText(newValue).click();
|
||||
};
|
||||
|
||||
const getFieldSection = fieldName => {
|
||||
const getFieldSection = (fieldName) => {
|
||||
return cy.findByLabelText(fieldName);
|
||||
};
|
||||
|
||||
const setTableOrder = order => {
|
||||
const setTableOrder = (order) => {
|
||||
cy.findByLabelText("Sort").click();
|
||||
H.popover().findByText(order).click();
|
||||
cy.wait("@updateTable");
|
||||
};
|
||||
|
||||
const assertTableHeader = columns => {
|
||||
const assertTableHeader = (columns) => {
|
||||
cy.findAllByTestId("header-cell").should("have.length", columns.length);
|
||||
|
||||
columns.forEach((column, index) => {
|
||||
|
||||
@@ -234,7 +234,7 @@ describe("issue 53595", () => {
|
||||
.type("cu");
|
||||
|
||||
H.popover().findByText("Currency").should("be.visible");
|
||||
H.popover().then($popover => {
|
||||
H.popover().then(($popover) => {
|
||||
expect(H.isScrollableVertically($popover[0])).to.be.false;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,7 +20,7 @@ describe("server clock", () => {
|
||||
});
|
||||
|
||||
it("can advance the server clock by one day", () => {
|
||||
cy.request("GET", "/api/setting/report-timezone-long").then(response => {
|
||||
cy.request("GET", "/api/setting/report-timezone-long").then((response) => {
|
||||
cy.wrap(response.body).as("serverTimeZone");
|
||||
});
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ export const freezeServerTime = ({
|
||||
"add-ms": addMilliseconds,
|
||||
time,
|
||||
})
|
||||
.then(response => {
|
||||
.then((response) => {
|
||||
if (wrapServerTimeAs) {
|
||||
cy.wrap(response.body.time).as(wrapServerTimeAs);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ describe(
|
||||
getTableId({
|
||||
databaseId: WRITABLE_DB_ID,
|
||||
name: WRITABLE_TEST_TABLE,
|
||||
}).then(tableId => {
|
||||
}).then((tableId) => {
|
||||
createQuestion(
|
||||
{
|
||||
name: "Cached question",
|
||||
|
||||
@@ -80,7 +80,7 @@ describe("scenarios > admin > performance > schedule strategy", () => {
|
||||
|
||||
];
|
||||
|
||||
(["root", "database"] as CacheableModel[]).forEach(model => {
|
||||
(["root", "database"] as CacheableModel[]).forEach((model) => {
|
||||
schedules.forEach(([schedule, cronExpression]) => {
|
||||
it(`can set on ${model}: ${
|
||||
Object.values(schedule).join(" ") || "default values"
|
||||
@@ -105,7 +105,7 @@ describe("scenarios > admin > performance > schedule strategy", () => {
|
||||
});
|
||||
}
|
||||
});
|
||||
saveCacheStrategyForm().then(xhr => {
|
||||
saveCacheStrategyForm().then((xhr) => {
|
||||
const { body } = xhr.request;
|
||||
expect(body.model).to.eq(model);
|
||||
expect(body.strategy.schedule).to.eq(cronExpression);
|
||||
@@ -147,10 +147,10 @@ describe("scenarios > admin > performance > schedule strategy", () => {
|
||||
cacheStrategyForm()
|
||||
.findByLabelText("Describe how often the cache should be invalidated")
|
||||
.find("[aria-label]")
|
||||
.then($labels => {
|
||||
.then(($labels) => {
|
||||
const labels = $labels
|
||||
.get()
|
||||
.map($el => $el.getAttribute("aria-label"));
|
||||
.map(($el) => $el.getAttribute("aria-label"));
|
||||
expect(labels).to.deep.equal(expectedFieldLabels);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -192,7 +192,7 @@ describe("scenarios > admin > performance > strategy form", () => {
|
||||
}
|
||||
};
|
||||
|
||||
["default policy", "Sample Database"].forEach(itemName => {
|
||||
["default policy", "Sample Database"].forEach((itemName) => {
|
||||
const model = itemName === "default policy" ? "root" : "database";
|
||||
const expectedNumberOfOptions = itemName === "default policy" ? 4 : 5;
|
||||
|
||||
@@ -298,8 +298,8 @@ describe("scenarios > admin > performance > strategy form", () => {
|
||||
});
|
||||
|
||||
it(`can save a new daily schedule policy - for ${itemName}`, () => {
|
||||
[12, 1, 11].forEach(time => {
|
||||
["AM", "PM"].forEach(amPm => {
|
||||
[12, 1, 11].forEach((time) => {
|
||||
["AM", "PM"].forEach((amPm) => {
|
||||
cy.log(`Test daily at ${time} ${amPm}`);
|
||||
selectScheduleType("daily");
|
||||
cy.findAllByRole("textbox").eq(1).click();
|
||||
@@ -336,10 +336,10 @@ describe("scenarios > admin > performance > strategy form", () => {
|
||||
cy.findByLabelText(amPm).next().click();
|
||||
saveCacheStrategyForm({ strategyType: "schedule", model });
|
||||
formLauncher(itemName, "currently", "Scheduled: weekly");
|
||||
cy.findAllByRole("textbox").then(searchBoxes => {
|
||||
cy.findAllByRole("textbox").then((searchBoxes) => {
|
||||
const values = Cypress._.map(
|
||||
searchBoxes,
|
||||
box => (box as HTMLInputElement).value,
|
||||
(box) => (box as HTMLInputElement).value,
|
||||
);
|
||||
expect(values).to.deep.equal(["weekly", day, hour]);
|
||||
});
|
||||
|
||||
@@ -93,13 +93,13 @@ describe("query validator", { tags: "@external" }, () => {
|
||||
cy.request(`/api/database/${WRITABLE_DB_ID}/schema/public`).then(
|
||||
({ body: tables }) => {
|
||||
const scoreboardTable = tables.find(
|
||||
table => table.name === SCOREBOARD_TABLE,
|
||||
(table) => table.name === SCOREBOARD_TABLE,
|
||||
);
|
||||
|
||||
cy.request(`/api/table/${scoreboardTable.id}/query_metadata`).then(
|
||||
({ body: { fields } }) => {
|
||||
const teamNameField = fields.find(
|
||||
field => field.name === "team_name",
|
||||
(field) => field.name === "team_name",
|
||||
);
|
||||
|
||||
H.createQuestion({
|
||||
@@ -118,12 +118,14 @@ describe("query validator", { tags: "@external" }, () => {
|
||||
|
||||
cy.request(`/api/database/${WRITABLE_DB_ID}/schema/public`).then(
|
||||
({ body: tables }) => {
|
||||
const colorsTable = tables.find(table => table.name === COLORS_TABLE);
|
||||
const colorsTable = tables.find(
|
||||
(table) => table.name === COLORS_TABLE,
|
||||
);
|
||||
|
||||
cy.request(`/api/table/${colorsTable.id}/query_metadata`).then(
|
||||
({ body: { fields } }) => {
|
||||
const colorNameField = fields.find(
|
||||
field => field.name === "name",
|
||||
(field) => field.name === "name",
|
||||
);
|
||||
|
||||
H.createQuestion({
|
||||
|
||||
@@ -83,8 +83,8 @@ describe("scenarios > admin > troubleshooting > tasks", () => {
|
||||
function stubPageResponses({ page, alias }) {
|
||||
const offset = page * limit;
|
||||
|
||||
cy.intercept("GET", `/api/task?limit=${limit}&offset=${offset}`, req => {
|
||||
req.reply(res => {
|
||||
cy.intercept("GET", `/api/task?limit=${limit}&offset=${offset}`, (req) => {
|
||||
req.reply((res) => {
|
||||
res.body = {
|
||||
data: stubPageRows(page),
|
||||
limit,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user