Files
leocrm/frontend/e2e/contact-crud.spec.ts
T

133 lines
5.5 KiB
TypeScript
Raw Normal View History

import { test, expect } from '@playwright/test';
import { setupApiMocks, login, navigateTo, MOCK_CONTACTS } from './helpers';
test.describe('Contact CRUD E2E', () => {
test.beforeEach(async ({ page }) => {
await setupApiMocks(page);
await login(page);
});
test('create a new company contact', async ({ page }) => {
await navigateTo(page, '/contacts');
// Wait for contacts page to load
await expect(page.locator('[data-testid="contact-list-view"], [data-testid="contact-list-empty"], [data-testid="contact-list-loading"]')).toBeVisible({ timeout: 15_000 });
// Click the "new" toolbar button (Plus icon in plugin toolbar)
const newBtn = page.locator('[data-testid="plugin-toolbar"] button').filter({ hasText: /new|neu|erstellen|create/i }).first();
await newBtn.click();
// Contact edit modal should appear
await expect(page.locator('[data-testid="contact-type-select"]')).toBeVisible({ timeout: 10_000 });
// Select company type (should be default)
await expect(page.locator('[data-testid="contact-name-input"]')).toBeVisible();
// Fill in company name
await page.locator('[data-testid="contact-name-input"]').fill('Test Company GmbH');
// Fill in email
await page.locator('input[type="email"]').first().fill('test@company.test');
// Submit
await page.locator('[data-testid="contact-submit-btn"]').click();
// Modal should close (success)
await expect(page.locator('[data-testid="contact-type-select"]')).not.toBeVisible({ timeout: 10_000 });
});
test('view contact detail and edit', async ({ page }) => {
await navigateTo(page, '/contacts');
// Wait for list to load
await expect(page.locator('[data-testid="contact-list-view"], [data-testid="contact-list-empty"]')).toBeVisible({ timeout: 15_000 });
// Click on first contact in the list
const firstContact = page.locator('[data-testid="contact-list-view"] > div, [data-testid="contact-list-view"] button').first();
if (await firstContact.isVisible()) {
await firstContact.click();
// Detail should appear
await expect(page.locator('[data-testid="contact-detail"]')).toBeVisible({ timeout: 10_000 });
// Click edit button in detail
const editBtn = page.locator('[data-testid="contact-detail"] button').filter({ hasText: /edit|bearbeiten/i }).first();
if (await editBtn.isVisible()) {
await editBtn.click();
// Edit modal should appear
await expect(page.locator('[data-testid="contact-type-select"]')).toBeVisible({ timeout: 10_000 });
// Modify name
await page.locator('[data-testid="contact-name-input"]').fill('Updated Company GmbH');
// Save
await page.locator('[data-testid="contact-submit-btn"]').click();
// Modal should close
await expect(page.locator('[data-testid="contact-type-select"]')).not.toBeVisible({ timeout: 10_000 });
}
}
});
test('add ansprechpartner (contact person) to a company', async ({ page }) => {
await navigateTo(page, '/contacts');
// Wait for list and click first contact
await expect(page.locator('[data-testid="contact-list-view"], [data-testid="contact-list-empty"]')).toBeVisible({ timeout: 15_000 });
const firstContact = page.locator('[data-testid="contact-list-view"] > div, [data-testid="contact-list-view"] button').first();
if (await firstContact.isVisible()) {
await firstContact.click();
await expect(page.locator('[data-testid="contact-detail"]')).toBeVisible({ timeout: 10_000 });
// Find and click "Add Person" button
const addPersonBtn = page.locator('[data-testid="contact-detail"] button').filter({ hasText: /add.*person|ansprechpartner.*hinzuf/i }).first();
if (await addPersonBtn.isVisible()) {
await addPersonBtn.click();
// Person modal should appear
await expect(page.locator('[data-testid="person-save-btn"]')).toBeVisible({ timeout: 10_000 });
// Fill person details
const inputs = page.locator('[data-testid="contact-detail"] input, .modal input, [role="dialog"] input');
const firstNameInput = inputs.nth(0);
const lastNameInput = inputs.nth(1);
await firstNameInput.fill('Anna');
await lastNameInput.fill('Schmidt');
// Save person
await page.locator('[data-testid="person-save-btn"]').click();
// Modal should close
await expect(page.locator('[data-testid="person-save-btn"]')).not.toBeVisible({ timeout: 10_000 });
}
}
});
test('delete a contact', async ({ page }) => {
await navigateTo(page, '/contacts');
await expect(page.locator('[data-testid="contact-list-view"], [data-testid="contact-list-empty"]')).toBeVisible({ timeout: 15_000 });
const firstContact = page.locator('[data-testid="contact-list-view"] > div, [data-testid="contact-list-view"] button').first();
if (await firstContact.isVisible()) {
await firstContact.click();
await expect(page.locator('[data-testid="contact-detail"]')).toBeVisible({ timeout: 10_000 });
// Set up confirm dialog handler
page.on('dialog', (dialog) => dialog.accept());
// Click delete button
const deleteBtn = page.locator('[data-testid="contact-detail"] button').filter({ hasText: /delete|löschen/i }).first();
if (await deleteBtn.isVisible()) {
await deleteBtn.click();
// Detail should become empty after deletion
await expect(page.locator('[data-testid="contact-detail-empty"], [data-testid="contact-detail-loading"]')).toBeVisible({ timeout: 10_000 });
}
}
});
});