388 lines
12 KiB
TypeScript
388 lines
12 KiB
TypeScript
import type { Page } from "@playwright/test";
|
|
|
|
/** Matches LoginPage DD Admin quick-login row */
|
|
export const E2E_DD_ADMIN = {
|
|
id: "18",
|
|
fullName: "Lince",
|
|
email: "lince@royalenfield.com",
|
|
password: "Admin@123",
|
|
role: "DD Admin",
|
|
} as const;
|
|
|
|
/** Shared list/detail payloads for Termination → Resignation → Relocation → Constitutional flows */
|
|
export const E2E_IDS = {
|
|
termination: "e2e-term-uuid-01",
|
|
resignation: "e2e-res-uuid-01",
|
|
relocation: "e2e-rel-uuid-01",
|
|
constitutionalPublicId: "CCR-E2E-001",
|
|
constitutionalInternalId: "e2e-cc-internal-01",
|
|
} as const;
|
|
|
|
const terminationListRow = {
|
|
id: E2E_IDS.termination,
|
|
requestId: "TERM-E2E-001",
|
|
severity: "High",
|
|
status: "Awaiting SCN Review",
|
|
currentStage: "Show Cause Notice",
|
|
category: "Performance Issues",
|
|
reason: "E2E termination scenario",
|
|
proposedLwd: "2026-12-31",
|
|
createdAt: new Date().toISOString(),
|
|
dealer: {
|
|
businessName: "E2E Termination Dealer",
|
|
legalName: "E2E Termination Dealer Pvt Ltd",
|
|
registeredAddress: "Chennai, TN",
|
|
dealerCode: { dealerCode: "E2E-T01", code: "E2E-T01" },
|
|
},
|
|
};
|
|
|
|
const terminationDetail = {
|
|
...terminationListRow,
|
|
documents: [],
|
|
uploadedDocuments: [],
|
|
timeline: [{ stage: "Show Cause Notice", action: "Moved to SCN", remarks: "E2E stub", timestamp: new Date().toISOString() }],
|
|
};
|
|
|
|
const resignationListRow = {
|
|
id: E2E_IDS.resignation,
|
|
resignationId: "RES-E2E-001",
|
|
status: "Pending DD Admin Clearance",
|
|
currentStage: "DD Admin",
|
|
resignationType: "Voluntary",
|
|
reason: "E2E resignation flow",
|
|
submittedOn: new Date().toISOString(),
|
|
dealer: {
|
|
dealerProfile: {
|
|
businessName: "E2E Resignation Dealer",
|
|
dealerCode: { dealerCode: "E2E-R01" },
|
|
registeredAddress: "Bangalore, KA",
|
|
},
|
|
},
|
|
outlet: { name: "Main Outlet", code: "OUT-E2E-1", city: "Bangalore", state: "KA" },
|
|
};
|
|
|
|
const resignationDetail = {
|
|
...resignationListRow,
|
|
dealer: {
|
|
fullName: "E2E Resignation Dealer",
|
|
email: "resign.e2e@example.com",
|
|
dealerProfile: resignationListRow.dealer.dealerProfile,
|
|
},
|
|
documents: [],
|
|
uploadedDocuments: [],
|
|
timeline: [],
|
|
};
|
|
|
|
const relocationListRow = {
|
|
id: E2E_IDS.relocation,
|
|
requestId: "REL-E2E-001",
|
|
status: "Pending ASM Review",
|
|
currentStage: "ASM Review",
|
|
currentLocation: "Old Industrial Area",
|
|
proposedLocation: "New Highway Plot",
|
|
distance: "25 km",
|
|
progressPercentage: 25,
|
|
createdAt: new Date().toISOString(),
|
|
outlet: { code: "OUT-REL-E2E", name: "E2E Relocation Outlet" },
|
|
dealerName: "E2E Relocation Dealer",
|
|
dealer: { fullName: "E2E Relocation Dealer" },
|
|
};
|
|
|
|
const relocationDetail = {
|
|
...relocationListRow,
|
|
timeline: [],
|
|
documents: [],
|
|
dealer: { fullName: "E2E Relocation Dealer" },
|
|
};
|
|
|
|
const constitutionalListRow = {
|
|
id: E2E_IDS.constitutionalInternalId,
|
|
requestId: E2E_IDS.constitutionalPublicId,
|
|
status: "Pending ASM Review",
|
|
currentStage: "ASM Review",
|
|
changeType: "Partnership",
|
|
description: "E2E constitutional change",
|
|
createdAt: new Date().toISOString(),
|
|
outlet: { name: "CCR Outlet", code: "CCR-OUT", city: "Coimbatore", state: "TN", type: "Proprietorship", address: "Road 1" },
|
|
dealer: {
|
|
fullName: "E2E Constitutional Dealer",
|
|
dealerProfile: {
|
|
businessName: "E2E Constitutional Dealer",
|
|
dealerCode: { dealerCode: "E2E-C01", salesCode: "S", serviceCode: "V", gmaCode: "G", gearCode: "GR" },
|
|
registeredAddress: "Industrial Estate",
|
|
application: { loiRequests: [], loaRequests: [] },
|
|
},
|
|
},
|
|
progressPercentage: 10,
|
|
};
|
|
|
|
const constitutionalDetail = {
|
|
...constitutionalListRow,
|
|
timeline: [{ action: "SUBMITTED", stage: "Submitted", remarks: "E2E stub", timestamp: new Date().toISOString(), user: "Dealer" }],
|
|
documents: [],
|
|
};
|
|
|
|
/**
|
|
* Stubs REST APIs so lifecycle E2E runs headless against Vite without a backend.
|
|
*/
|
|
export async function installLifecycleModuleApiStubs(page: Page): Promise<void> {
|
|
await page.route("**/api/auth/login", async (route) => {
|
|
if (route.request().method() !== "POST") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
token: "e2e-playwright-token",
|
|
user: {
|
|
id: E2E_DD_ADMIN.id,
|
|
fullName: E2E_DD_ADMIN.fullName,
|
|
email: E2E_DD_ADMIN.email,
|
|
role: E2E_DD_ADMIN.role,
|
|
},
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.route("**/api/auth/me", async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
user: {
|
|
id: E2E_DD_ADMIN.id,
|
|
fullName: E2E_DD_ADMIN.fullName,
|
|
email: E2E_DD_ADMIN.email,
|
|
role: E2E_DD_ADMIN.role,
|
|
roleCode: E2E_DD_ADMIN.role,
|
|
},
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.route("**/api/communication/notifications**", async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ success: true, data: [] }),
|
|
});
|
|
});
|
|
|
|
await page.route("**/api/termination", async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
success: true,
|
|
terminations: [terminationListRow],
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.route(`**/api/termination/${E2E_IDS.termination}**`, async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
success: true,
|
|
termination: terminationDetail,
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.route("**/api/resignation", async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
success: true,
|
|
resignations: { rows: [resignationListRow] },
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.route(`**/api/resignation/${E2E_IDS.resignation}**`, async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
success: true,
|
|
resignation: resignationDetail,
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.route("**/api/relocation", async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
success: true,
|
|
requests: [relocationListRow],
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.route(`**/api/relocation/${E2E_IDS.relocation}**`, async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
success: true,
|
|
request: relocationDetail,
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.route("**/api/constitutional-change**", async (route) => {
|
|
const method = route.request().method();
|
|
if (method !== "GET") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
const path = new URL(route.request().url()).pathname.replace(/\/$/, "");
|
|
const pub = `/api/constitutional-change/${E2E_IDS.constitutionalPublicId}`;
|
|
|
|
if (path.endsWith("/constitutional-change/meta")) {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
success: true,
|
|
structureTargets: [
|
|
{ value: "Partnership", label: "Partnership" },
|
|
{ value: "LLP", label: "LLP" },
|
|
],
|
|
}),
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (path === pub) {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
success: true,
|
|
request: constitutionalDetail,
|
|
}),
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (path === "/api/constitutional-change") {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
success: true,
|
|
requests: [constitutionalListRow],
|
|
}),
|
|
});
|
|
return;
|
|
}
|
|
|
|
await route.continue();
|
|
});
|
|
|
|
await page.route("**/api/dealer*", async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
const path = new URL(route.request().url()).pathname;
|
|
if (!path.startsWith("/api/dealer") || path.includes("/bank-details")) {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
success: true,
|
|
data: [
|
|
{
|
|
id: "dealer-e2e-1",
|
|
legalName: "Stub Dealer Legal",
|
|
businessName: "Stub Dealer",
|
|
gstNumber: "27AAAAA0000A1Z5",
|
|
registeredAddress: "Test",
|
|
status: "active",
|
|
constitutionType: "Proprietorship",
|
|
dealerCode: { dealerCode: "STUB-01" },
|
|
user: {
|
|
id: "user-dealer-e2e",
|
|
email: "dealer@e2e.test",
|
|
mobileNumber: "9000000000",
|
|
status: "active",
|
|
isActive: true,
|
|
},
|
|
application: { preferredLocation: "Test", city: "Chennai", state: "TN" },
|
|
},
|
|
],
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.route("**/api/master/outlets**", async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({
|
|
success: true,
|
|
outlets: [{ id: "outlet-e2e-1", code: "OUT-1", name: "Outlet One", dealerId: "user-dealer-e2e" }],
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.route("**/api/audit/logs**", async (route) => {
|
|
if (route.request().method() !== "GET") {
|
|
await route.continue();
|
|
return;
|
|
}
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ success: true, data: [] }),
|
|
});
|
|
});
|
|
}
|