Skip to content

Commit 57e9104

Browse files
committed
test(FR-2652): add E2E tests for admin model card deletion with folder option
- Add tests 5.7 and 5.8 to admin-model-card-delete.spec.ts - 5.7: delete model card + folder together, verify notification and Go to Trash URL with folder filter - 5.8: delete model card only, verify notification and Go to Trash URL without filter - Add getAlsoDeleteFolderCheckbox() and getFolderNameLinkInDeleteDialog() to AdminModelCardPage POM - Update E2E_COVERAGE_REPORT.md: Admin Model Store 22→26 features covered
1 parent 444c84b commit 57e9104

3 files changed

Lines changed: 127 additions & 5 deletions

File tree

e2e/E2E_COVERAGE_REPORT.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# E2E Test Coverage Report
22

3-
> **Last Updated:** 2026-04-13
3+
> **Last Updated:** 2026-04-22
44
> **Router Source:** [`react/src/routes.tsx`](../react/src/routes.tsx)
55
> **E2E Root:** [`e2e/`](.)
66
>
@@ -12,7 +12,7 @@
1212

1313
**Scope:** Coverage metrics apply only to the routes listed below and do **not** include all entries from `react/src/routes.tsx`. Routes such as `/admin-dashboard` (not yet exposed in menu) and `/ai-agent` (experimental) are currently out of scope.
1414

15-
**Overall (in-scope routes): 261 / 408 features covered (64%)**
15+
**Overall (in-scope routes): 265 / 412 features covered (64%)**
1616

1717
| Page | Route | Features | Covered | Status |
1818
|------|-------|:--------:|:-------:|:------:|
@@ -27,7 +27,7 @@
2727
| Service Launcher | `/service/start` | 5 | 0 | ❌ 0% |
2828
| VFolder / Data | `/data` | 45 | 32 | 🔶 71% |
2929
| Model Store | `/model-store` | 6 | 6 | ✅ 100% |
30-
| Admin Model Store | `/admin-model-store` | 22 | 22 | ✅ 100% |
30+
| Admin Model Store | `/admin-model-store` | 26 | 26 | ✅ 100% |
3131
| Storage Host | `/storage-settings/:hostname` | 3 | 0 | ❌ 0% |
3232
| My Environment | `/my-environment` | 2 | 2 | ✅ 100% |
3333
| Environment | `/environment` | 27 | 21 | 🔶 78% |
@@ -47,7 +47,7 @@
4747
| Chat | `/chat/:id?` | 6 | 6 | ✅ 100% |
4848
| Plugin System | (config-based) | 12 | 12 | ✅ 100% |
4949
| RBAC Management | `/rbac` | 22 | 21 | 🔶 95% |
50-
| **Total** | | **408** | **261** | **64%** |
50+
| **Total** | | **412** | **265** | **64%** |
5151

5252
---
5353

@@ -420,14 +420,18 @@
420420
| Cancel edit modal || `admin-model-card-edit.spec.ts` |
421421
| Single delete with confirmation || `admin-model-card-delete.spec.ts` |
422422
| Cancel single delete || `admin-model-card-delete.spec.ts` |
423+
| Delete card + folder together (checkbox) || `admin-model-card-delete.spec.ts` |
424+
| Notification + Go to Trash with folder filter || `admin-model-card-delete.spec.ts` |
425+
| Delete card only, folder kept notification || `admin-model-card-delete.spec.ts` |
426+
| Go to Trash without folder filter || `admin-model-card-delete.spec.ts` |
423427
| Bulk select and delete || `admin-model-card-delete.spec.ts` |
424428
| Cancel bulk delete || `admin-model-card-delete.spec.ts` |
425429
| Clear selection || `admin-model-card-delete.spec.ts` |
426430
| Select all via header checkbox || `admin-model-card-delete.spec.ts` |
427431
| Non-admin access blocked || `admin-model-card-access-control.spec.ts` |
428432
| URL state persistence (filter/sort/pagination) || `admin-model-card-url-state.spec.ts` |
429433

430-
**Coverage: ✅ 22/22 features**
434+
**Coverage: ✅ 26/26 features**
431435

432436
---
433437

e2e/admin-model-card/admin-model-card-delete.spec.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,5 +266,115 @@ test.describe(
266266
`${rowCount} selected`,
267267
);
268268
});
269+
270+
// 5.7 Superadmin can delete a model card and its associated folder together
271+
test('Superadmin can delete a model card and its associated folder, and navigate to trash with folder filter', async ({
272+
page,
273+
}) => {
274+
const adminModelCardPage = new AdminModelCardPage(page);
275+
const cardName = `e2e-test-delete-with-folder-${Date.now()}`;
276+
277+
// Setup: create a model card (picks first available VFolder automatically)
278+
await page.goto(`${webuiEndpoint}/admin-serving?tab=model-store`);
279+
await adminModelCardPage.waitForTableLoad();
280+
await adminModelCardPage.createModelCard({ name: cardName });
281+
282+
// Navigate back and filter for the created card
283+
await page.goto(`${webuiEndpoint}/admin-serving?tab=model-store`);
284+
await adminModelCardPage.waitForTableLoad();
285+
await adminModelCardPage.applyNameFilter(cardName);
286+
287+
// Open the delete confirmation dialog
288+
await adminModelCardPage.clickDeleteForRow(cardName);
289+
290+
// Verify the "Also delete the associated model folder" checkbox is visible
291+
await expect(
292+
adminModelCardPage.getAlsoDeleteFolderCheckbox(),
293+
).toBeVisible();
294+
295+
// Read the folder name from the link in the dialog (for URL assertion later)
296+
const folderLink = adminModelCardPage.getFolderNameLinkInDeleteDialog();
297+
await expect(folderLink).toBeVisible();
298+
const folderName = await folderLink.textContent();
299+
expect(folderName).toBeTruthy();
300+
301+
// Check the "Also delete the associated model folder" checkbox
302+
await adminModelCardPage.getAlsoDeleteFolderCheckbox().check();
303+
await expect(
304+
adminModelCardPage.getAlsoDeleteFolderCheckbox(),
305+
).toBeChecked();
306+
307+
// Confirm deletion
308+
await adminModelCardPage.getDeleteConfirmButton().click();
309+
310+
// Verify the success notification for card + folder deletion
311+
await expect(
312+
page.getByText('Model card and folder have been moved to trash.'),
313+
).toBeVisible({ timeout: 15000 });
314+
315+
// Verify "Go to Data > Trash" link is visible in the notification
316+
const goToTrashLink = page.getByText('Go to Data > Trash');
317+
await expect(goToTrashLink).toBeVisible();
318+
319+
// Click "Go to Data > Trash" and verify URL includes folder filter
320+
await goToTrashLink.click();
321+
await page.waitForURL(
322+
(url) =>
323+
url.pathname === '/data' &&
324+
url.searchParams.get('statusCategory') === 'deleted' &&
325+
url.searchParams.get('filter') === `name == "${folderName}"`,
326+
{ timeout: 10000 },
327+
);
328+
});
329+
330+
// 5.8 Superadmin deletes card only: notification shows correct message and Go to Trash navigates correctly
331+
test('Superadmin can delete a model card only and navigate to trash without folder filter', async ({
332+
page,
333+
}) => {
334+
const adminModelCardPage = new AdminModelCardPage(page);
335+
const cardName = `e2e-test-delete-card-only-${Date.now()}`;
336+
337+
// Setup: create a model card
338+
await page.goto(`${webuiEndpoint}/admin-serving?tab=model-store`);
339+
await adminModelCardPage.waitForTableLoad();
340+
await adminModelCardPage.createModelCard({ name: cardName });
341+
342+
// Navigate back and filter
343+
await page.goto(`${webuiEndpoint}/admin-serving?tab=model-store`);
344+
await adminModelCardPage.waitForTableLoad();
345+
await adminModelCardPage.applyNameFilter(cardName);
346+
347+
// Open delete dialog
348+
await adminModelCardPage.clickDeleteForRow(cardName);
349+
350+
// Leave "Also delete folder" checkbox unchecked (default)
351+
await expect(
352+
adminModelCardPage.getAlsoDeleteFolderCheckbox(),
353+
).not.toBeChecked();
354+
355+
// Confirm deletion
356+
await adminModelCardPage.getDeleteConfirmButton().click();
357+
358+
// Verify the notification message for card-only deletion
359+
await expect(
360+
page.getByText(
361+
'Model card has been deleted. The model folder was not deleted.',
362+
),
363+
).toBeVisible({ timeout: 15000 });
364+
365+
// Verify "Go to Data > Trash" link is visible
366+
const goToTrashLink = page.getByText('Go to Data > Trash');
367+
await expect(goToTrashLink).toBeVisible();
368+
369+
// Click "Go to Data > Trash" and verify URL (no folder filter)
370+
await goToTrashLink.click();
371+
await page.waitForURL(
372+
(url) =>
373+
url.pathname === '/data' &&
374+
url.searchParams.get('statusCategory') === 'deleted' &&
375+
!url.searchParams.has('filter'),
376+
{ timeout: 10000 },
377+
);
378+
});
269379
},
270380
);

e2e/utils/classes/AdminModelCardPage.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,14 @@ export class AdminModelCardPage {
301301
});
302302
}
303303

304+
getAlsoDeleteFolderCheckbox(): Locator {
305+
return this.getDeleteConfirmDialog().getByRole('checkbox').first();
306+
}
307+
308+
getFolderNameLinkInDeleteDialog(): Locator {
309+
return this.getDeleteConfirmDialog().getByRole('link').first();
310+
}
311+
304312
// ── Helper: create via UI and return ─────────────────────────────────────
305313

306314
async createModelCard(fields: {

0 commit comments

Comments
 (0)