test(front): correct frontend test + end2end tests

This commit is contained in:
Edouard Vanbelle
2026-07-20 12:50:19 +02:00
parent 569b67caac
commit 4f3309e087
9 changed files with 82 additions and 47 deletions
+9 -9
View File
@@ -25,14 +25,14 @@ async function openFolderWithChildren(
await apiCreateFolder(page, c2, parent.id);
await page.goto(`/files/${parent.id}`);
await expect(page.getByTestId(c1)).toBeVisible({ timeout: 15_000 });
await page.getByTestId('list-toolbar-view-list-btn').click();
await page.getByTestId('display-mode-view-list-btn').click();
return { c1, c2 };
}
test('select-all then batch favorite', async ({ page }) => {
const { c1 } = await openFolderWithChildren(page);
await page.getByTestId('files-select-all-checkbox').check();
await expect(page.getByTestId('files-batch-bar')).toBeVisible();
await page.getByTestId('resource-list-select-all-checkbox').check();
await expect(page.getByTestId('resource-list-batch-close-btn')).toBeVisible();
await page.getByTestId('files-batch-favorite-btn').click();
// Items remain in the folder after favoriting.
await expect(page.getByTestId(c1)).toBeVisible({ timeout: 15_000 });
@@ -40,8 +40,8 @@ test('select-all then batch favorite', async ({ page }) => {
test('select-all then batch copy and download', async ({ page }) => {
const { c1 } = await openFolderWithChildren(page);
await page.getByTestId('files-select-all-checkbox').check();
await expect(page.getByTestId('files-batch-bar')).toBeVisible();
await page.getByTestId('resource-list-select-all-checkbox').check();
await expect(page.getByTestId('resource-list-batch-close-btn')).toBeVisible();
// Copy → the move dialog (copy mode); cancel.
await page.getByTestId('files-batch-copy-btn').click();
@@ -49,8 +49,8 @@ test('select-all then batch copy and download', async ({ page }) => {
await page.getByTestId('move-dialog-cancel-btn').click();
// Re-select and batch-download (a zip).
await page.getByTestId('files-select-all-checkbox').check();
await expect(page.getByTestId('files-batch-bar')).toBeVisible();
await page.getByTestId('resource-list-select-all-checkbox').check();
await expect(page.getByTestId('resource-list-batch-close-btn')).toBeVisible();
const dl = page.waitForEvent('download', { timeout: 10_000 }).catch(() => null);
await page.getByTestId('files-batch-download-btn').click();
await dl;
@@ -59,8 +59,8 @@ test('select-all then batch copy and download', async ({ page }) => {
test('select-all then batch delete', async ({ page }) => {
const { c1, c2 } = await openFolderWithChildren(page);
await page.getByTestId('files-select-all-checkbox').check();
await expect(page.getByTestId('files-batch-bar')).toBeVisible();
await page.getByTestId('resource-list-select-all-checkbox').check();
await expect(page.getByTestId('resource-list-batch-close-btn')).toBeVisible();
await page.getByTestId('files-batch-delete-btn').click();
await page.getByTestId('dialog-host-confirm-btn').click();
+4 -4
View File
@@ -96,7 +96,7 @@ test('toolbar eye toggle hides and re-shows dotfiles in /files', async ({ page }
// click routes through `preferences.toggleHideDotfiles()` which
// does an optimistic local mutation, so the row update should be
// visible before the debounced PATCH lands.
await page.getByTestId('list-toolbar-dotfile-toggle-btn').click();
await page.getByTestId('display-mode-dotfile-toggle-btn').click();
// Visible row stays; hidden row vanishes.
await expect(page.getByTestId(visible)).toBeVisible();
@@ -104,7 +104,7 @@ test('toolbar eye toggle hides and re-shows dotfiles in /files', async ({ page }
// Flip it back off — the hidden row must reappear. Same button;
// its state flips atomically with `preferences.hideDotfiles`.
await page.getByTestId('list-toolbar-dotfile-toggle-btn').click();
await page.getByTestId('display-mode-dotfile-toggle-btn').click();
await expect(page.getByTestId(hidden)).toBeVisible();
});
@@ -130,7 +130,7 @@ test('empty-state hint appears when a folder holds only dotfiles', async ({ page
// Turn hide on. Folder becomes visually empty — but not the
// generic empty state; the "N hidden items" affordance appears
// instead, offering a one-click "Show hidden files" escape.
await page.getByTestId('list-toolbar-dotfile-toggle-btn').click();
await page.getByTestId('display-mode-dotfile-toggle-btn').click();
const showHiddenBtn = page.getByTestId('files-show-hidden-btn');
await expect(showHiddenBtn).toBeVisible({ timeout: 15_000 });
@@ -181,6 +181,6 @@ test('trash always shows dotfiles even when hide is on', async ({ page }) => {
// we just verify the toolbar toggle reflects the current server
// state via aria-pressed on /files.
await page.goto('/files');
const toggle = page.getByTestId('list-toolbar-dotfile-toggle-btn');
const toggle = page.getByTestId('display-mode-dotfile-toggle-btn');
await expect(toggle).toHaveAttribute('aria-pressed', 'true');
});
+2 -2
View File
@@ -51,9 +51,9 @@ test('favorites batch select-all then move dialog', async ({ page }) => {
await page.goto('/favorites');
await expect(page.getByTestId(f1)).toBeVisible({ timeout: 15_000 });
// The select-all checkbox lives in the list-view header.
await page.getByTestId('list-toolbar-view-list-btn').click();
await page.getByTestId('display-mode-view-list-btn').click();
await page.getByTestId('resource-list-select-all-checkbox').check();
await expect(page.getByTestId('resource-list-batch-toolbar')).toBeVisible();
await expect(page.getByTestId('resource-list-batch-close-btn')).toBeVisible();
// Batch-move opens the move dialog; cancel it.
await page.getByTestId('favorites-batch-move-btn').click();
+17 -14
View File
@@ -20,12 +20,12 @@ test('sort columns and toggle list/grid views', async ({ page }) => {
await page.goto(`/files/${folder.id}`);
await expect(page.getByTestId(SAMPLE_FILES.text().name)).toBeVisible({ timeout: 15_000 });
await page.getByTestId('list-toolbar-view-list-btn').click();
await page.getByTestId('display-mode-view-list-btn').click();
// Column sort buttons live in the list-view header.
await page.getByTestId('files-sort-name-btn').click({ timeout: 5_000 }).catch(() => {});
await page.getByTestId('files-sort-size-btn').click({ timeout: 5_000 }).catch(() => {});
await page.getByTestId('files-sort-modified_at-btn').click({ timeout: 5_000 }).catch(() => {});
await page.getByTestId('list-toolbar-view-grid-btn').click();
await page.getByTestId('display-mode-view-grid-btn').click();
});
test('sort by every column and group by every dimension', async ({ page }) => {
@@ -37,17 +37,17 @@ test('sort by every column and group by every dimension', async ({ page }) => {
await expect(page.getByTestId(SAMPLE_FILES.text().name)).toBeVisible({ timeout: 15_000 });
// List view exposes the column-sort buttons.
await page.getByTestId('list-toolbar-view-list-btn').click();
await page.getByTestId('display-mode-view-list-btn').click();
for (const col of ['name', 'owner', 'type', 'size', 'modified_at']) {
await page.getByTestId(`files-sort-${col}-btn`).click({ timeout: 3_000 }).catch(() => {});
}
// Flip the sort direction.
await page.getByTestId('list-toolbar-sort-direction-btn').click({ timeout: 3_000 }).catch(() => {});
await page.getByTestId('display-mode-sort-direction-btn').click({ timeout: 3_000 }).catch(() => {});
// Cycle through every group-by dimension.
for (const g of ['type', 'size', 'modifiedAt', 'createdAt']) {
await page.getByTestId('list-toolbar-groupby-btn').click({ timeout: 3_000 }).catch(() => {});
await page.getByTestId(`list-toolbar-groupby-${g}-item`).click({ timeout: 3_000 }).catch(() => {});
await page.getByTestId('display-mode-groupby-btn').click({ timeout: 3_000 }).catch(() => {});
await page.getByTestId(`display-mode-groupby-${g}-item`).click({ timeout: 3_000 }).catch(() => {});
}
});
@@ -58,8 +58,8 @@ test('group files by type', async ({ page }) => {
await page.goto(`/files/${folder.id}`);
await expect(page.getByTestId(SAMPLE_FILES.text().name)).toBeVisible({ timeout: 15_000 });
await page.getByTestId('list-toolbar-groupby-btn').click();
await page.getByTestId('list-toolbar-groupby-type-item').click();
await page.getByTestId('display-mode-groupby-btn').click();
await page.getByTestId('display-mode-groupby-type-item').click();
// The grouped (swimlane) view now renders; items remain visible.
await expect(page.getByTestId(SAMPLE_FILES.text().name)).toBeVisible();
});
@@ -109,12 +109,15 @@ test('deep-link ?file= opens the viewer', async ({ page }) => {
await page.goto(`/files/${folder.id}`);
await expect(page.getByTestId(f.name)).toBeVisible({ timeout: 15_000 });
// Extract the file id from a row action button, then deep-link to it.
const tid = await page
.locator('[data-testid^="files-file-share-"]')
// Extract the file id straight off the row — ResourceList tags every
// `.file-item` with `data-item-id={item.id}`. The pre-migration
// approach read `files-file-share-{id}` off a per-row share button
// that no longer exists (Share moved into the context menu).
const fileId = await page
.locator(`.file-item[data-testid="${f.name}"]`)
.first()
.getAttribute('data-testid');
const fileId = (tid ?? '').replace('files-file-share-', '');
.getAttribute('data-item-id');
if (!fileId) throw new Error(`could not resolve file id for ${f.name}`);
await page.goto(`/files/${folder.id}?file=${fileId}`);
await expect(page.getByTestId('file-viewer-dialog')).toBeVisible({ timeout: 15_000 });
await page.getByTestId('file-viewer-close-btn').click();
@@ -194,7 +197,7 @@ test('keyboard select-all and escape in the files list', async ({ page }) => {
await page.locator('.files-page').click({ position: { x: 5, y: 5 } });
await page.keyboard.press('Control+a');
await expect(page.getByTestId('files-batch-bar')).toBeVisible({ timeout: 5_000 }).catch(() => {});
await expect(page.getByTestId('resource-list-batch-close-btn')).toBeVisible({ timeout: 5_000 }).catch(() => {});
await page.keyboard.press('Escape');
});
+5 -5
View File
@@ -23,7 +23,7 @@ test('recent shows accessed items, batch selection, and clear', async ({ page })
await expect(page.getByTestId('appshell-logo-link')).toBeVisible({ timeout: 15_000 });
// Switch to list view (reveals the select-all header) and batch-select.
await page.getByTestId('list-toolbar-view-list-btn').click({ timeout: 3_000 }).catch(() => {});
await page.getByTestId('display-mode-view-list-btn').click({ timeout: 3_000 }).catch(() => {});
const selectAll = page.getByTestId('resource-list-select-all-checkbox');
if (await selectAll.isVisible().catch(() => false)) {
await selectAll.check();
@@ -45,16 +45,16 @@ test('recent grouping and sort cycle (ResourceList toolbar)', async ({ page }) =
await apiRecordRecent(page, 'folder', a.id);
await page.goto('/recent');
await expect(page.getByTestId('appshell-logo-link')).toBeVisible({ timeout: 15_000 });
await page.getByTestId('list-toolbar-view-list-btn').click({ timeout: 3_000 }).catch(() => {});
await page.getByTestId('display-mode-view-list-btn').click({ timeout: 3_000 }).catch(() => {});
// Cycle every group-by dimension exposed by the shared ResourceList toolbar.
for (let i = 0; i < 5; i++) {
await page.getByTestId('list-toolbar-groupby-btn').click({ timeout: 2_000 }).catch(() => {});
await page.getByTestId('display-mode-groupby-btn').click({ timeout: 2_000 }).catch(() => {});
await page
.locator('[data-testid^="list-toolbar-groupby-"][data-testid$="-item"]')
.locator('[data-testid^="display-mode-groupby-"][data-testid$="-item"]')
.nth(i)
.click({ timeout: 2_000 })
.catch(() => {});
}
await page.getByTestId('list-toolbar-sort-direction-btn').click({ timeout: 2_000 }).catch(() => {});
await page.getByTestId('display-mode-sort-direction-btn').click({ timeout: 2_000 }).catch(() => {});
});