- Introduced `.prettierrc.json` to enforce consistent code formatting across the project. - Updated unit and e2e test files to address formatting issues, improve readability, and ensure alignment with the new Prettier configuration.
597 lines
22 KiB
TypeScript
597 lines
22 KiB
TypeScript
import { test, expect, Page } from "@playwright/test";
|
|
import { bookingTestData, loginAsOperator } from "./fixtures";
|
|
|
|
type GoalProgressBucket = {
|
|
count: number;
|
|
target: number;
|
|
date_from?: string;
|
|
date_end?: string;
|
|
};
|
|
|
|
type GoalProgressByKey = Record<string, GoalProgressBucket>;
|
|
|
|
type MockGoal = {
|
|
id: number;
|
|
created_by: number;
|
|
departments: number[];
|
|
criteria: {
|
|
label: string;
|
|
type: "REVENUE" | "PRODUCT" | "VISITS";
|
|
target: number;
|
|
start: string;
|
|
end: string;
|
|
products: number[];
|
|
users: number[];
|
|
departments: number[];
|
|
progress_alert_frequency: "NONE" | "DAILY" | "WEEKLY" | "MONTHLY" | "CHANGED";
|
|
progress_alert_destination: "NONE" | "SLACK" | "EMAIL" | "SMS";
|
|
progress_alert_progress_type: string;
|
|
progress_alert_style: string;
|
|
progress_alert_format: string | null;
|
|
progress_alert_weekdays: string[];
|
|
progress_alert_time_of_day: string | null;
|
|
department_daily_targets: Record<string, number>;
|
|
target_duration?: "ENTIRE_DURATION" | "WEEKS" | "MONTHS" | "YEARS" | null;
|
|
target_duration_every?: number | null;
|
|
};
|
|
progress: GoalProgressByKey & {
|
|
departmental_distribution: Record<string, GoalProgressByKey>;
|
|
};
|
|
created_at: string;
|
|
updated_at: string;
|
|
};
|
|
|
|
const makeMockGoal = (params: {
|
|
id: number;
|
|
departmentId: number;
|
|
label: string;
|
|
target: number;
|
|
start: string;
|
|
end: string;
|
|
allCount?: number;
|
|
todayCount?: number;
|
|
weekCount?: number;
|
|
monthCount?: number;
|
|
}): MockGoal => {
|
|
const allCount = params.allCount ?? 0;
|
|
const todayCount = params.todayCount ?? 0;
|
|
const weekCount = params.weekCount ?? allCount;
|
|
const monthCount = params.monthCount ?? allCount;
|
|
|
|
return {
|
|
id: params.id,
|
|
created_by: 11,
|
|
departments: [params.departmentId],
|
|
criteria: {
|
|
label: params.label,
|
|
type: "REVENUE",
|
|
target: params.target,
|
|
start: params.start,
|
|
end: params.end,
|
|
products: [],
|
|
users: [],
|
|
departments: [params.departmentId],
|
|
progress_alert_frequency: "NONE",
|
|
progress_alert_destination: "NONE",
|
|
progress_alert_progress_type: "ALL",
|
|
progress_alert_style: "NONE",
|
|
progress_alert_format: null,
|
|
progress_alert_weekdays: [],
|
|
progress_alert_time_of_day: null,
|
|
department_daily_targets: {},
|
|
},
|
|
progress: {
|
|
all: { count: allCount, target: params.target },
|
|
today: { count: todayCount, target: params.target },
|
|
week: { count: weekCount, target: params.target },
|
|
month: { count: monthCount, target: params.target },
|
|
year: { count: monthCount, target: params.target },
|
|
to_date: { count: allCount, target: params.target },
|
|
departmental_distribution: {
|
|
[String(params.departmentId)]: {
|
|
all: { count: allCount, target: params.target },
|
|
today: { count: todayCount, target: params.target },
|
|
week: { count: weekCount, target: params.target },
|
|
month: { count: monthCount, target: params.target },
|
|
year: { count: monthCount, target: params.target },
|
|
to_date: { count: allCount, target: params.target },
|
|
},
|
|
},
|
|
},
|
|
created_at: new Date().toISOString(),
|
|
updated_at: new Date().toISOString(),
|
|
};
|
|
};
|
|
|
|
const setupGoalsApiMock = async (page: Page, departmentId: number) => {
|
|
let goals: MockGoal[] = [
|
|
makeMockGoal({
|
|
id: 1,
|
|
departmentId,
|
|
label: "Mock Active Goal",
|
|
target: 100,
|
|
allCount: 45,
|
|
todayCount: 10,
|
|
weekCount: 28,
|
|
monthCount: 45,
|
|
start: "2026-01-01",
|
|
end: "2099-01-01",
|
|
}),
|
|
makeMockGoal({
|
|
id: 2,
|
|
departmentId,
|
|
label: "Mock Expired Goal",
|
|
target: 200,
|
|
allCount: 180,
|
|
todayCount: 0,
|
|
weekCount: 0,
|
|
monthCount: 0,
|
|
start: "2024-01-01",
|
|
end: "2024-02-01",
|
|
}),
|
|
];
|
|
|
|
await page.route("**/goals/department/progress-alert/test**", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ data: { destination: "EMAIL" } }),
|
|
});
|
|
});
|
|
|
|
await page.route("**/goals/department**", async (route) => {
|
|
const request = route.request();
|
|
const method = request.method();
|
|
|
|
if (method === "GET") {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ data: goals }),
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (method === "PUT") {
|
|
const body = request.postDataJSON() as { id: number; departments: number[]; criteria: Record<string, unknown> };
|
|
const id = Number(body.id);
|
|
const departments = (body.departments || [departmentId]).map((x) => Number(x));
|
|
|
|
goals = goals.map((goal) => {
|
|
if (goal.id !== id) return goal;
|
|
return {
|
|
...goal,
|
|
departments,
|
|
criteria: {
|
|
...goal.criteria,
|
|
...(body.criteria || {}),
|
|
departments,
|
|
},
|
|
updated_at: new Date().toISOString(),
|
|
};
|
|
});
|
|
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ data: goals.find((g) => g.id === id) || null }),
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (method === "DELETE") {
|
|
const id = Number(new URL(request.url()).searchParams.get("id"));
|
|
goals = goals.filter((goal) => goal.id !== id);
|
|
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ data: { success: true } }),
|
|
});
|
|
return;
|
|
}
|
|
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ data: {} }),
|
|
});
|
|
});
|
|
};
|
|
|
|
test.describe("Admin Module - Goals", () => {
|
|
const getGoalsUrl = (departmentId: string) => `/admin/${departmentId}/modules/goals`;
|
|
|
|
const openGoalAction = async (page: Page, label: string, actionLabel: string) => {
|
|
const card = page.locator(".goal-card", { hasText: label }).first();
|
|
await expect(card).toBeVisible({ timeout: 15000 });
|
|
|
|
const dropdown = card.locator(".dropdown.is-hoverable").first();
|
|
await dropdown.hover();
|
|
await card.locator(".dropdown-item", { hasText: actionLabel }).click({ force: true });
|
|
};
|
|
|
|
const openCreateGoalModalProgrammatically = async (page: Page, departmentId: number) => {
|
|
await page.evaluate(
|
|
async ({ targetDepartmentId }) => {
|
|
const modalModule = await import(
|
|
"/src/views/dashboards/departmentDashboard/modules/goals/functions/showGoalFormModal.js"
|
|
);
|
|
void modalModule.showGoalCreateModal(null, { departments: [targetDepartmentId] });
|
|
},
|
|
{ targetDepartmentId: departmentId }
|
|
);
|
|
};
|
|
|
|
const openEditGoalModalProgrammatically = async (page: Page, goal: MockGoal) => {
|
|
await page.evaluate(
|
|
async ({ editableGoal }) => {
|
|
const modalModule = await import(
|
|
"/src/views/dashboards/departmentDashboard/modules/goals/functions/showGoalFormModal.js"
|
|
);
|
|
void modalModule.showGoalEditModal(null, editableGoal);
|
|
},
|
|
{ editableGoal: goal }
|
|
);
|
|
};
|
|
|
|
const overrideSessionPermissionsForNextReload = async (
|
|
page: Page,
|
|
options: {
|
|
remove?: string[];
|
|
add?: string[];
|
|
}
|
|
) => {
|
|
const removeSet = new Set((options.remove || []).map((permission) => String(permission)));
|
|
const addList = (options.add || []).map((permission) => String(permission));
|
|
|
|
await page.route("**/auth/session", async (route) => {
|
|
const response = await route.fetch();
|
|
const status = response.status();
|
|
const headers = response.headers();
|
|
const body = await response.json();
|
|
const responseDataRoot = body && typeof body === "object" ? body : {};
|
|
|
|
const nestedData = responseDataRoot?.data?.data;
|
|
const flatData = responseDataRoot?.data;
|
|
const sessionPayload =
|
|
nestedData && typeof nestedData === "object"
|
|
? nestedData
|
|
: flatData && typeof flatData === "object"
|
|
? flatData
|
|
: responseDataRoot;
|
|
|
|
const currentPermissions = Array.isArray(sessionPayload?.permissions)
|
|
? sessionPayload.permissions.map((permission) => String(permission))
|
|
: [];
|
|
|
|
const nextPermissions = Array.from(
|
|
new Set(currentPermissions.filter((permission) => !removeSet.has(permission)).concat(addList))
|
|
);
|
|
|
|
if (nestedData && typeof nestedData === "object") {
|
|
responseDataRoot.data.data.permissions = nextPermissions;
|
|
} else if (flatData && typeof flatData === "object") {
|
|
responseDataRoot.data.permissions = nextPermissions;
|
|
} else {
|
|
responseDataRoot.permissions = nextPermissions;
|
|
}
|
|
|
|
await route.fulfill({
|
|
status,
|
|
headers,
|
|
body: JSON.stringify(responseDataRoot),
|
|
});
|
|
});
|
|
};
|
|
|
|
test.beforeEach(async ({ page }, testInfo) => {
|
|
test.skip(testInfo.project.name.toLowerCase().includes("mobile"), "Goals admin suite is desktop-focused");
|
|
test.skip(
|
|
!testInfo.project.name.toLowerCase().includes("chromium"),
|
|
"Goals admin suite is stabilized for Chromium in this environment."
|
|
);
|
|
|
|
await loginAsOperator(page);
|
|
|
|
const departmentId = bookingTestData.departmentId;
|
|
await setupGoalsApiMock(page, departmentId);
|
|
|
|
await page.goto(getGoalsUrl(String(departmentId)));
|
|
await expect(page).toHaveURL(new RegExp(`/admin/${departmentId}/modules/goals`));
|
|
await expect(page.locator("nav.level.box")).toBeVisible({ timeout: 15000 });
|
|
});
|
|
|
|
test("loads goals page and supports status/timeframe tab switching", async ({ page }) => {
|
|
const statusTabs = page.locator(".tabs.is-toggle").first();
|
|
const timeframeTabs = page.locator(".tabs.is-toggle").nth(1);
|
|
|
|
await expect(page.locator(".goal-card")).toHaveCount(1);
|
|
|
|
await statusTabs.locator("li").nth(1).click();
|
|
await expect(statusTabs.locator("li").nth(1)).toHaveClass(/is-active/);
|
|
await expect(page.locator(".goal-card")).toHaveCount(1);
|
|
|
|
await statusTabs.locator("li").nth(2).click();
|
|
await expect(statusTabs.locator("li").nth(2)).toHaveClass(/is-active/);
|
|
await expect(page.locator(".goal-card")).toHaveCount(2);
|
|
|
|
await statusTabs.locator("li").nth(0).click();
|
|
await expect(statusTabs.locator("li").nth(0)).toHaveClass(/is-active/);
|
|
|
|
await timeframeTabs.locator("li", { hasText: "Indtil nu" }).click();
|
|
await expect(timeframeTabs.locator("li", { hasText: "Indtil nu" })).toHaveClass(/is-active/);
|
|
|
|
await timeframeTabs.locator("li").nth(2).click();
|
|
await expect(timeframeTabs.locator("li").nth(2)).toHaveClass(/is-active/);
|
|
|
|
await timeframeTabs.locator("li").nth(3).click();
|
|
await expect(timeframeTabs.locator("li").nth(3)).toHaveClass(/is-active/);
|
|
|
|
await timeframeTabs.locator("li").nth(4).click();
|
|
await expect(timeframeTabs.locator("li").nth(4)).toHaveClass(/is-active/);
|
|
|
|
await timeframeTabs.locator("li").nth(0).click();
|
|
await expect(timeframeTabs.locator("li").nth(0)).toHaveClass(/is-active/);
|
|
});
|
|
|
|
test("updates progress target when timeframe changes for cadence goals", async ({ page }) => {
|
|
const departmentId = bookingTestData.departmentId;
|
|
const nowIso = new Date().toISOString();
|
|
|
|
const cadenceGoal: MockGoal = {
|
|
id: 301,
|
|
created_by: 11,
|
|
departments: [departmentId],
|
|
criteria: {
|
|
label: "Cadence Biweekly Goal",
|
|
type: "PRODUCT",
|
|
target: 7,
|
|
start: "2026-03-24T00:00:00+01:00",
|
|
end: "2026-07-24T23:59:59+01:00",
|
|
products: [1],
|
|
users: [],
|
|
departments: [departmentId],
|
|
progress_alert_frequency: "NONE",
|
|
progress_alert_destination: "NONE",
|
|
progress_alert_progress_type: "ALL",
|
|
progress_alert_style: "NONE",
|
|
progress_alert_format: null,
|
|
progress_alert_weekdays: ["MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"],
|
|
progress_alert_time_of_day: null,
|
|
department_daily_targets: {},
|
|
target_duration: "WEEKS",
|
|
target_duration_every: 2,
|
|
},
|
|
progress: {
|
|
all: { count: 11, target: 63, date_from: "2026-03-24T00:00:00+01:00", date_end: "2026-07-24T23:59:59+01:00" },
|
|
to_date: { count: 6, target: 7, date_from: "2026-03-24T00:00:00+01:00", date_end: "2026-03-24T23:59:59+01:00" },
|
|
today: { count: 1, target: 2, date_from: "2026-04-04T00:00:00+01:00", date_end: "2026-04-04T23:59:59+01:00" },
|
|
week: { count: 4, target: 7, date_from: "2026-03-23T00:00:00+01:00", date_end: "2026-03-29T23:59:59+01:00" },
|
|
month: { count: 9, target: 7, date_from: "2026-04-01T00:00:00+01:00", date_end: "2026-04-30T23:59:59+01:00" },
|
|
year: { count: 20, target: 7, date_from: "2026-01-01T00:00:00+01:00", date_end: "2026-12-31T23:59:59+01:00" },
|
|
every_2_weeks: {
|
|
count: 5,
|
|
target: 14,
|
|
date_from: "2026-03-12T00:00:00+01:00",
|
|
date_end: "2026-03-25T23:59:59+01:00",
|
|
},
|
|
departmental_distribution: {
|
|
[String(departmentId)]: {
|
|
all: { count: 11, target: 63 },
|
|
to_date: { count: 6, target: 7 },
|
|
today: { count: 1, target: 2 },
|
|
week: { count: 4, target: 7 },
|
|
month: { count: 9, target: 7 },
|
|
year: { count: 20, target: 7 },
|
|
every_2_weeks: { count: 5, target: 14 },
|
|
},
|
|
},
|
|
},
|
|
created_at: nowIso,
|
|
updated_at: nowIso,
|
|
};
|
|
|
|
await page.unroute("**/goals/department**");
|
|
await page.route("**/goals/department**", async (route) => {
|
|
const method = route.request().method();
|
|
if (method === "GET") {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ data: [cadenceGoal] }),
|
|
});
|
|
return;
|
|
}
|
|
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ data: {} }),
|
|
});
|
|
});
|
|
|
|
await page.reload();
|
|
const timeframeTabs = page.locator(".tabs.is-toggle").nth(1);
|
|
const card = page.locator(".goal-card", { hasText: "Cadence Biweekly Goal" }).first();
|
|
const progressBar = card.locator("progress.progress").first();
|
|
|
|
const expectProgress = async (value: number, max: number) => {
|
|
await expect(progressBar).toHaveAttribute("value", new RegExp(`^${value}(?:\\.0+)?$`));
|
|
await expect(progressBar).toHaveAttribute("max", new RegExp(`^${max}(?:\\.0+)?$`));
|
|
};
|
|
|
|
await expectProgress(11, 63);
|
|
|
|
await timeframeTabs.locator("li").nth(1).click(); // Indtil nu
|
|
await expect(timeframeTabs.locator("li").nth(1)).toHaveClass(/is-active/);
|
|
await expectProgress(6, 7);
|
|
|
|
await timeframeTabs.locator("li").nth(2).click(); // I dag
|
|
await expect(timeframeTabs.locator("li").nth(2)).toHaveClass(/is-active/);
|
|
await expectProgress(1, 2);
|
|
|
|
await timeframeTabs.locator("li").nth(3).click(); // Denne uge
|
|
await expect(timeframeTabs.locator("li").nth(3)).toHaveClass(/is-active/);
|
|
await expectProgress(5, 14);
|
|
|
|
await timeframeTabs.locator("li").nth(4).click(); // Denne måned
|
|
await expect(timeframeTabs.locator("li").nth(4)).toHaveClass(/is-active/);
|
|
await expectProgress(9, 7);
|
|
|
|
await timeframeTabs.locator("li").nth(5).click(); // År
|
|
await expect(timeframeTabs.locator("li").nth(5)).toHaveClass(/is-active/);
|
|
await expectProgress(20, 63);
|
|
});
|
|
|
|
test("opens create goal modal and supports cancel", async ({ page }) => {
|
|
await openCreateGoalModalProgrammatically(page, bookingTestData.departmentId);
|
|
|
|
const modal = page.locator(".swal2-popup");
|
|
await expect(modal).toBeVisible({ timeout: 15000 });
|
|
|
|
await expect(modal.locator('input[placeholder*="f.eks."]').first()).toBeVisible();
|
|
await expect(modal.locator('input[type="number"]').first()).toBeVisible();
|
|
await expect(modal.locator('input[type="date"]').first()).toBeVisible();
|
|
await modal.locator(".tabs li", { hasText: "Alert Configuration" }).click();
|
|
await expect(modal.locator("textarea").first()).toBeVisible();
|
|
|
|
await modal.locator('button.button:has-text("Annuller")').click();
|
|
await expect(page.locator(".swal2-popup")).toBeHidden({ timeout: 10000 });
|
|
});
|
|
|
|
test("submits edit modal and sends expected update payload", async ({ page }) => {
|
|
const editableGoal = makeMockGoal({
|
|
id: 1,
|
|
departmentId: bookingTestData.departmentId,
|
|
label: "Mock Active Goal",
|
|
target: 100,
|
|
allCount: 45,
|
|
todayCount: 10,
|
|
weekCount: 28,
|
|
monthCount: 45,
|
|
start: "2026-01-01",
|
|
end: "2099-01-01",
|
|
});
|
|
await openEditGoalModalProgrammatically(page, editableGoal);
|
|
|
|
const modal = page.locator(".swal2-popup");
|
|
await expect(modal).toBeVisible({ timeout: 15000 });
|
|
|
|
await modal.locator('input[placeholder*="f.eks."]').first().fill("Mock Active Goal Updated");
|
|
await modal.locator('input[type="number"]').first().fill("321");
|
|
await modal.locator('input[type="date"]').first().fill("2026-02-01");
|
|
await modal.locator('input[type="date"]').nth(1).fill("2026-03-15");
|
|
await modal
|
|
.locator("select")
|
|
.filter({ has: page.locator('option[value="LEGACY"]') })
|
|
.first()
|
|
.selectOption("WEEKS");
|
|
await modal.locator('input[type="number"]').nth(1).fill("2");
|
|
|
|
const putRequestPromise = page.waitForRequest(
|
|
(request) => request.method() === "PUT" && request.url().includes("/goals/department")
|
|
);
|
|
|
|
await modal.locator(".buttons.is-right .button.is-dark").click({ force: true });
|
|
|
|
const putRequest = await putRequestPromise;
|
|
const putPayload = putRequest.postDataJSON() as {
|
|
criteria?: {
|
|
label?: string;
|
|
target?: number;
|
|
target_duration?: string;
|
|
target_duration_every?: number;
|
|
start?: string;
|
|
end?: string;
|
|
};
|
|
};
|
|
|
|
expect(putPayload.criteria?.label).toBe("Mock Active Goal Updated");
|
|
expect(Number(putPayload.criteria?.target)).toBe(321);
|
|
expect(putPayload.criteria?.target_duration).toBe("WEEKS");
|
|
expect(Number(putPayload.criteria?.target_duration_every)).toBe(2);
|
|
expect(putPayload.criteria?.start).toMatch(/^2026-02-01T00:00:00(?:Z|[+-]\d{2}:\d{2})$/);
|
|
expect(putPayload.criteria?.end).toMatch(/^2026-03-15T23:59:59(?:Z|[+-]\d{2}:\d{2})$/);
|
|
|
|
const successDialog = page.locator('.swal2-popup:has-text("Succes")').first();
|
|
await expect(successDialog).toBeVisible({ timeout: 15000 });
|
|
await expect(successDialog).toBeHidden({ timeout: 15000 });
|
|
});
|
|
|
|
test("supports test-alert action and delete request flow", async ({ page }) => {
|
|
await overrideSessionPermissionsForNextReload(page, {
|
|
add: ["goals_department_progress_alert_test", "admin", `department_access_${bookingTestData.departmentId}`],
|
|
});
|
|
await page.reload();
|
|
await expect(page.locator("nav.level.box")).toBeVisible({ timeout: 15000 });
|
|
|
|
const testAlertRequestPromise = page.waitForRequest(
|
|
(request) => request.method() === "POST" && request.url().includes("/goals/department/progress-alert/test")
|
|
);
|
|
|
|
await openGoalAction(page, "Mock Active Goal", "Test alert");
|
|
const modal = page.locator(".swal2-popup");
|
|
await expect(modal).toBeVisible({ timeout: 10000 });
|
|
await modal.locator("#goal-test-alert-destination").selectOption("EMAIL");
|
|
await modal.locator("#goal-test-alert-email-to").fill("tester@example.com");
|
|
await modal.locator("#goal-test-alert-subject").fill("Dept Goal Progress Test");
|
|
await modal.locator(".swal2-confirm").click();
|
|
|
|
const testAlertRequest = await testAlertRequestPromise;
|
|
const testAlertPayload = testAlertRequest.postDataJSON() as {
|
|
id?: number;
|
|
overrideDestination?: string;
|
|
email_to?: string;
|
|
subject?: string;
|
|
};
|
|
|
|
expect(Number(testAlertPayload.id)).toBe(1);
|
|
expect(testAlertPayload.overrideDestination).toBe("EMAIL");
|
|
expect(testAlertPayload.email_to).toBe("tester@example.com");
|
|
expect(testAlertPayload.subject).toBe("Dept Goal Progress Test");
|
|
|
|
await openGoalAction(page, "Mock Active Goal", "Slet");
|
|
await expect(page.locator(".swal2-popup")).toBeVisible({ timeout: 10000 });
|
|
|
|
const deleteRequestPromise = page.waitForRequest(
|
|
(request) => request.method() === "DELETE" && request.url().includes("/goals/department")
|
|
);
|
|
|
|
await page.locator(".swal2-popup .swal2-confirm").click();
|
|
|
|
const deleteRequest = await deleteRequestPromise;
|
|
expect(deleteRequest.url()).toContain("id=");
|
|
await expect(page.locator(".swal2-popup")).toBeHidden({ timeout: 10000 });
|
|
});
|
|
|
|
test("hides create and test-alert controls when permission is missing and reports COMPONENT entries", async ({
|
|
page,
|
|
}) => {
|
|
await overrideSessionPermissionsForNextReload(page, {
|
|
remove: ["goals_department_create", "goals_department_progress_alert_test", "superuser"],
|
|
add: ["admin", `department_access_${bookingTestData.departmentId}`],
|
|
});
|
|
await page.reload();
|
|
await expect(page.locator("nav.level.box")).toBeVisible({ timeout: 15000 });
|
|
|
|
await expect(page.locator("button.button.is-dark:has(.fa-plus)")).toHaveCount(0);
|
|
await expect(page.locator("button.button.is-dark.mt-2")).toHaveCount(0);
|
|
|
|
const card = page.locator(".goal-card", { hasText: "Mock Active Goal" }).first();
|
|
await expect(card).toBeVisible({ timeout: 15000 });
|
|
await card.locator(".dropdown.is-hoverable").first().hover();
|
|
await expect(card.locator(".dropdown-item", { hasText: "Test alert" })).toHaveCount(0);
|
|
|
|
await page.keyboard.press("Shift");
|
|
await page.keyboard.press("Shift");
|
|
await page.keyboard.press("Shift");
|
|
|
|
const missingPermissionsBox = page.locator("[data-testid='request-queue-missing-permissions-box']");
|
|
await expect(missingPermissionsBox).toBeVisible({ timeout: 10000 });
|
|
await expect(missingPermissionsBox).toContainText("goals_department_create");
|
|
await expect(missingPermissionsBox).toContainText("goals_department_progress_alert_test");
|
|
await expect(missingPermissionsBox).toContainText("COMPONENT");
|
|
});
|
|
});
|