fix(frontend): E2E-Test-Suite vollständig grün machen

- Robuster gegen undefined API-Daten in Mail, ContactDetail, ContactsList, Settings, Sidebar
- E2E-Mocks korrigiert für Kontakt-Detail, Mail-Liste/Folders und Plugin-Toggle
- Auth-Store mit persist-Middleware für E2E-Login
- test-results/ in .gitignore aufgenommen

Playwright E2E: 34/34 passed
This commit is contained in:
Agent Zero
2026-08-07 22:03:11 +02:00
parent 8d2aa58665
commit fdabd2e74c
18 changed files with 368 additions and 401 deletions
@@ -33,6 +33,7 @@ export interface ContactDetailProps {
loading?: boolean;
onEdit?: () => void;
onDeleted: () => void;
dataTestId?: string;
}
function Field({ label, value, fieldName }: { label: string; value?: string | null; fieldName?: string }) {
@@ -156,7 +157,7 @@ function getIcon(name: string): React.ReactNode {
return Icon ? <Icon className="h-4 w-4" /> : <LucideIcons.FileText className="h-4 w-4" />;
}
export function ContactDetail({ contact, loading, onEdit, onDeleted }: ContactDetailProps) {
export function ContactDetail({ contact, loading, onEdit, onDeleted, dataTestId = 'contact-detail' }: ContactDetailProps) {
const { t } = useTranslation();
const toast = useToast();
const deleteMutation = useDeleteUnifiedContact();
@@ -173,9 +174,9 @@ export function ContactDetail({ contact, loading, onEdit, onDeleted }: ContactDe
const [activeTab, setActiveTab] = useState('details');
const manifests = usePluginStore(s => s.manifests);
const pluginTabs = useMemo(
() => manifests
.flatMap((m) => m.detail_tabs)
.filter((t) => t.entity_type === 'contact')
() => (manifests || [])
.flatMap((m) => (Array.isArray(m.detail_tabs) ? m.detail_tabs : []))
.filter((t): t is NonNullable<typeof t> => !!t && t.entity_type === 'contact')
.sort((a, b) => a.order - b.order),
[manifests]
);
@@ -283,7 +284,7 @@ export function ContactDetail({ contact, loading, onEdit, onDeleted }: ContactDe
];
return (
<div className="overflow-y-auto h-full" data-testid="contact-detail">
<div className="overflow-y-auto h-full" data-testid={dataTestId}>
{/* Header */}
<div className="flex items-center justify-between px-4 py-3 border-b border-secondary-200 sticky top-0 bg-white z-10">
<div className="flex items-center gap-3 min-w-0">