Phase 5.4-5.11: Playwright E2E test infrastructure with 7 spec files

- playwright.config.ts: chromium project, webServer, baseURL, trace/screenshot/video
- e2e/helpers.ts: API mock setup, login/logout helpers, mock data for all entities
- 7 E2E spec files (1164 lines total):
  - auth.spec.ts: login/logout workflow
  - contact-crud.spec.ts: create/edit/delete contacts, add persons
  - search.spec.ts: global search, filter, results
  - plugin-toggle.spec.ts: enable/disable plugins, UI changes
  - mail.spec.ts: mail account setup, folders, mail viewing
  - dms.spec.ts: folder creation, file upload, preview, share
  - calendar.spec.ts: appointment creation, calendar switch, kanban view
- @playwright/test added as devDependency
- e2e scripts added to package.json
- TSC: 0 new errors (only pre-existing Dms.tsx)
This commit is contained in:
Agent Zero
2026-07-23 22:35:03 +02:00
parent 7a034b3124
commit 42b19040ce
11 changed files with 1256 additions and 2 deletions
+67
View File
@@ -0,0 +1,67 @@
import { test, expect } from '@playwright/test';
import { setupApiMocks, login, navigateTo, MOCK_PLUGINS } from './helpers';
test.describe('Plugin Toggle E2E', () => {
test.beforeEach(async ({ page }) => {
await setupApiMocks(page);
await login(page);
});
test('settings plugins page renders with plugin list', async ({ page }) => {
await navigateTo(page, '/settings/plugins');
await expect(page.locator('[data-testid="settings-plugins-page"]')).toBeVisible({ timeout: 10_000 });
});
test('activate an inactive plugin', async ({ page }) => {
await navigateTo(page, '/settings/plugins');
await expect(page.locator('[data-testid="settings-plugins-page"]')).toBeVisible({ timeout: 10_000 });
// Find the inactive plugin (entity_links) and click activate
const activateBtn = page.locator('[data-testid="activate-plugin-entity_links"]');
if (await activateBtn.isVisible({ timeout: 10_000 })) {
await activateBtn.click();
// Button should change (deactivate should appear)
await expect(page.locator('[data-testid="deactivate-plugin-entity_links"]')).toBeVisible({ timeout: 10_000 });
}
});
test('deactivate an active plugin', async ({ page }) => {
await navigateTo(page, '/settings/plugins');
await expect(page.locator('[data-testid="settings-plugins-page"]')).toBeVisible({ timeout: 10_000 });
// Find the active plugin (tags) and click deactivate
const deactivateBtn = page.locator('[data-testid="deactivate-plugin-tags"]');
if (await deactivateBtn.isVisible({ timeout: 10_000 })) {
await deactivateBtn.click();
// Button should change (activate should appear)
await expect(page.locator('[data-testid="activate-plugin-tags"]')).toBeVisible({ timeout: 10_000 });
}
});
test('refresh plugins button works', async ({ page }) => {
await navigateTo(page, '/settings/plugins');
await expect(page.locator('[data-testid="settings-plugins-page"]')).toBeVisible({ timeout: 10_000 });
const refreshBtn = page.locator('[data-testid="refresh-plugins-btn"]');
await expect(refreshBtn).toBeVisible();
await refreshBtn.click();
// Page should still be visible
await expect(page.locator('[data-testid="settings-plugins-page"]')).toBeVisible();
});
test('plugin install section is visible', async ({ page }) => {
await navigateTo(page, '/settings/plugins');
await expect(page.locator('[data-testid="settings-plugins-page"]')).toBeVisible({ timeout: 10_000 });
// Upload and URL install options should be present
await expect(page.locator('[data-testid="plugin-zip-upload-input"], [data-testid="plugin-upload-btn"], [data-testid="plugin-url-input"], [data-testid="plugin-install-url-btn"]')).toBeVisible({ timeout: 10_000 });
});
});