Fix remaining v2.5.1 Playwright POST download and FY selector tests
This commit is contained in:
@@ -307,10 +307,14 @@ test.describe("v2.5.1 Additions - Employee HR Business Rules", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kind === 'post') {
|
if (kind === 'post') {
|
||||||
const resp = await apiCall(request, method || 'POST', c.route);
|
// Some generated VAPT rows accidentally carry _method: 'GET' even when
|
||||||
|
// the scenario is explicitly CSRF-less POST. Force POST unless the row
|
||||||
|
// intentionally specifies another unsafe verb.
|
||||||
|
const unsafeMethod = (!method || method === 'GET') ? 'POST' : method;
|
||||||
|
const resp = await apiCall(request, unsafeMethod, c.route);
|
||||||
await expectApiSafe(resp);
|
await expectApiSafe(resp);
|
||||||
const safe = [400, 401, 403, 404, 405, 409, 422, 429].includes(resp.status());
|
const safe = [400, 401, 403, 404, 405, 409, 422, 429].includes(resp.status());
|
||||||
expect(safe, `Unsafe POST status ${resp.status()} for ${c.route}`).toBeTruthy();
|
expect(safe, `Unsafe ${unsafeMethod} status ${resp.status()} for ${c.route}`).toBeTruthy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -331,10 +331,14 @@ test.describe("v2.5.1 Additions - Marketplace / Leads", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kind === 'post') {
|
if (kind === 'post') {
|
||||||
const resp = await apiCall(request, method || 'POST', c.route);
|
// Some generated VAPT rows accidentally carry _method: 'GET' even when
|
||||||
|
// the scenario is explicitly CSRF-less POST. Force POST unless the row
|
||||||
|
// intentionally specifies another unsafe verb.
|
||||||
|
const unsafeMethod = (!method || method === 'GET') ? 'POST' : method;
|
||||||
|
const resp = await apiCall(request, unsafeMethod, c.route);
|
||||||
await expectApiSafe(resp);
|
await expectApiSafe(resp);
|
||||||
const safe = [400, 401, 403, 404, 405, 409, 422, 429].includes(resp.status());
|
const safe = [400, 401, 403, 404, 405, 409, 422, 429].includes(resp.status());
|
||||||
expect(safe, `Unsafe POST status ${resp.status()} for ${c.route}`).toBeTruthy();
|
expect(safe, `Unsafe ${unsafeMethod} status ${resp.status()} for ${c.route}`).toBeTruthy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -343,10 +343,14 @@ test.describe("v2.5.1 Additions - Notice Case Business Rules", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kind === 'post') {
|
if (kind === 'post') {
|
||||||
const resp = await apiCall(request, method || 'POST', c.route);
|
// Some generated VAPT rows accidentally carry _method: 'GET' even when
|
||||||
|
// the scenario is explicitly CSRF-less POST. Force POST unless the row
|
||||||
|
// intentionally specifies another unsafe verb.
|
||||||
|
const unsafeMethod = (!method || method === 'GET') ? 'POST' : method;
|
||||||
|
const resp = await apiCall(request, unsafeMethod, c.route);
|
||||||
await expectApiSafe(resp);
|
await expectApiSafe(resp);
|
||||||
const safe = [400, 401, 403, 404, 405, 409, 422, 429].includes(resp.status());
|
const safe = [400, 401, 403, 404, 405, 409, 422, 429].includes(resp.status());
|
||||||
expect(safe, `Unsafe POST status ${resp.status()} for ${c.route}`).toBeTruthy();
|
expect(safe, `Unsafe ${unsafeMethod} status ${resp.status()} for ${c.route}`).toBeTruthy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -152,20 +152,29 @@ test.describe('SVC: Services depth', () => {
|
|||||||
|
|
||||||
test('[V25-SVC-002] SVC-002 Bulk imports service-master template downloads', async ({ page }) => {
|
test('[V25-SVC-002] SVC-002 Bulk imports service-master template downloads', async ({ page }) => {
|
||||||
await login(page, 'Firm Admin');
|
await login(page, 'Firm Admin');
|
||||||
const resp = await safeGoto(page, '/services/bulk-imports/templates/service-master.xlsx');
|
const [download] = await Promise.all([
|
||||||
expect(resp.status()).toBeLessThan(500);
|
page.waitForEvent('download'),
|
||||||
|
page.goto('/services/bulk-imports/templates/service-master.xlsx').catch(() => null),
|
||||||
|
]);
|
||||||
|
expect(await download.suggestedFilename()).toMatch(/service.*template|xlsx/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[V25-SVC-003] SVC-003 Bulk imports engagement-assignments template downloads', async ({ page }) => {
|
test('[V25-SVC-003] SVC-003 Bulk imports engagement-assignments template downloads', async ({ page }) => {
|
||||||
await login(page, 'Firm Admin');
|
await login(page, 'Firm Admin');
|
||||||
const resp = await safeGoto(page, '/services/bulk-imports/templates/engagement-assignments.xlsx');
|
const [download] = await Promise.all([
|
||||||
expect(resp.status()).toBeLessThan(500);
|
page.waitForEvent('download'),
|
||||||
|
page.goto('/services/bulk-imports/templates/engagement-assignments.xlsx').catch(() => null),
|
||||||
|
]);
|
||||||
|
expect(await download.suggestedFilename()).toMatch(/assignment|template|xlsx/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[V25-SVC-004] SVC-004 Bulk imports firm-task-templates template downloads', async ({ page }) => {
|
test('[V25-SVC-004] SVC-004 Bulk imports firm-task-templates template downloads', async ({ page }) => {
|
||||||
await login(page, 'Firm Admin');
|
await login(page, 'Firm Admin');
|
||||||
const resp = await safeGoto(page, '/services/bulk-imports/templates/firm-task-templates.xlsx');
|
const [download] = await Promise.all([
|
||||||
expect(resp.status()).toBeLessThan(500);
|
page.waitForEvent('download'),
|
||||||
|
page.goto('/services/bulk-imports/templates/firm-task-templates.xlsx').catch(() => null),
|
||||||
|
]);
|
||||||
|
expect(await download.suggestedFilename()).toMatch(/task|template|xlsx/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[V25-SVC-005] SVC-005 Bulk import preview CSRF-less POST is rejected', async ({ request }) => {
|
test('[V25-SVC-005] SVC-005 Bulk import preview CSRF-less POST is rejected', async ({ request }) => {
|
||||||
|
|||||||
@@ -225,9 +225,11 @@ test.describe('BILL: Invoices and payments', () => {
|
|||||||
|
|
||||||
test('[V25-BILL-016] BILL-016 Fee structure import template download works', async ({ page }) => {
|
test('[V25-BILL-016] BILL-016 Fee structure import template download works', async ({ page }) => {
|
||||||
await login(page, 'Firm Admin');
|
await login(page, 'Firm Admin');
|
||||||
const resp = await safeGoto(page, '/billing/fee-structures/template');
|
const [download] = await Promise.all([
|
||||||
// should download or redirect, not crash
|
page.waitForEvent('download'),
|
||||||
expect(resp.status()).toBeLessThan(500);
|
page.goto('/billing/fee-structures/template').catch(() => null),
|
||||||
|
]);
|
||||||
|
expect(await download.suggestedFilename()).toMatch(/fee.*structure|template|xlsx/i);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -487,10 +487,14 @@ test.describe("v2.5.1 Additions - Platform Billing", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kind === 'post') {
|
if (kind === 'post') {
|
||||||
const resp = await apiCall(request, method || 'POST', c.route);
|
// Some generated VAPT rows accidentally carry _method: 'GET' even when
|
||||||
|
// the scenario is explicitly CSRF-less POST. Force POST unless the row
|
||||||
|
// intentionally specifies another unsafe verb.
|
||||||
|
const unsafeMethod = (!method || method === 'GET') ? 'POST' : method;
|
||||||
|
const resp = await apiCall(request, unsafeMethod, c.route);
|
||||||
await expectApiSafe(resp);
|
await expectApiSafe(resp);
|
||||||
const safe = [400, 401, 403, 404, 405, 409, 422, 429].includes(resp.status());
|
const safe = [400, 401, 403, 404, 405, 409, 422, 429].includes(resp.status());
|
||||||
expect(safe, `Unsafe POST status ${resp.status()} for ${c.route}`).toBeTruthy();
|
expect(safe, `Unsafe ${unsafeMethod} status ${resp.status()} for ${c.route}`).toBeTruthy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -499,10 +499,14 @@ test.describe("v2.5.1 Additions - System Settings / Tenancy / FY", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kind === 'post') {
|
if (kind === 'post') {
|
||||||
const resp = await apiCall(request, method || 'POST', c.route);
|
// Some generated VAPT rows accidentally carry _method: 'GET' even when
|
||||||
|
// the scenario is explicitly CSRF-less POST. Force POST unless the row
|
||||||
|
// intentionally specifies another unsafe verb.
|
||||||
|
const unsafeMethod = (!method || method === 'GET') ? 'POST' : method;
|
||||||
|
const resp = await apiCall(request, unsafeMethod, c.route);
|
||||||
await expectApiSafe(resp);
|
await expectApiSafe(resp);
|
||||||
const safe = [400, 401, 403, 404, 405, 409, 422, 429].includes(resp.status());
|
const safe = [400, 401, 403, 404, 405, 409, 422, 429].includes(resp.status());
|
||||||
expect(safe, `Unsafe POST status ${resp.status()} for ${c.route}`).toBeTruthy();
|
expect(safe, `Unsafe ${unsafeMethod} status ${resp.status()} for ${c.route}`).toBeTruthy();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -126,8 +126,9 @@ test.describe('v2.0.4 additional security / FY / context checks', () => {
|
|||||||
await page.goto('/system-settings');
|
await page.goto('/system-settings');
|
||||||
await expectNoBackendError(page);
|
await expectNoBackendError(page);
|
||||||
const body = await readBody(page);
|
const body = await readBody(page);
|
||||||
const selectorExists = await page.locator('select[name="active_financial_year"], select[name="financial_year"], [data-testid="active-fy-select"], text=/FY|Financial Year|Active FY/i').count();
|
const cssSelectorCount = await page.locator('select[name="active_financial_year"], select[name="financial_year"], [data-testid="active-fy-select"]').count();
|
||||||
expect(selectorExists || /financial year|active fy|fy\s*[:\-]/i.test(body)).toBeTruthy();
|
const textSelectorCount = await page.getByText(/FY|Financial Year|Active FY/i).count().catch(() => 0);
|
||||||
|
expect(cssSelectorCount || textSelectorCount || /financial year|active fy|fy\s*[:\-]/i.test(body)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('V204-FY-002 switching FY does not crash core transactional pages', async ({ page }) => {
|
test('V204-FY-002 switching FY does not crash core transactional pages', async ({ page }) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user