diff --git a/backend/src/app/usecases/multi-agent-personas.test.ts b/backend/src/app/usecases/multi-agent-personas.test.ts
new file mode 100644
index 0000000..ec1141b
--- /dev/null
+++ b/backend/src/app/usecases/multi-agent-personas.test.ts
@@ -0,0 +1,163 @@
+import { test, expect } from '@playwright/test';
+import { PersonaConfigurator } from '../../services/persona-configurator';
+import { AgentPersona } from '../../domain/agent-personas';
+
+test.describe('Multi-Agent Personas Testing', () => {
+ const configurator = new PersonaConfigurator();
+
+ test('Alice (Newbie) - Slow typing, careful', async ({ page }) => {
+ const persona = configurator.getPersona('Alice');
+ expect(persona).toBeDefined();
+ expect(persona?.type).toBe('newbie');
+
+ await page.goto('https://example.com/register');
+
+ // Simulate slow typing
+ const username = 'alice_test';
+ for (const char of username) {
+ await page.locator('#username').type(char, { delay: persona!.typingSpeed });
+ }
+
+ // Slow down for reading prompts
+ await page.waitForTimeout(1000);
+
+ // Fill email
+ await page.fill('#email', 'alice@example.com');
+ await page.fill('#password', 'SecurePass123!');
+
+ // Submit
+ await page.click('#register');
+ await page.waitForSelector('.success', { timeout: 5000 });
+ });
+
+ test('Bob (Cautious) - Reads privacy policy, fills optional fields', async ({ page }) => {
+ const persona = configurator.getPersona('Bob');
+ expect(persona).toBeDefined();
+ expect(persona?.type).toBe('cautious');
+
+ await page.goto('https://example.com/register');
+
+ // Fill basic fields
+ await page.fill('#username', 'bob_test');
+ await page.fill('#email', 'bob@example.com');
+
+ // Read privacy policy (cautious behavior)
+ if (persona!.readsPrivacy) {
+ await page.click('#privacy-link');
+ await page.waitForTimeout(500);
+ await page.goBack();
+ }
+
+ // Fill password
+ await page.fill('#password', 'SecurePass123!');
+
+ // Fill optional fields (phone number)
+ if (persona!.fillsOptional) {
+ await page.fill('#phone', '13800138000');
+ }
+
+ // Submit
+ await page.click('#register');
+ await page.waitForSelector('.success', { timeout: 5000 });
+ });
+
+ test('Charlie (Impatient) - Fast typing, skips optional fields', async ({ page }) => {
+ const persona = configurator.getPersona('Charlie');
+ expect(persona).toBeDefined();
+ expect(persona?.type).toBe('impatient');
+
+ await page.goto('https://example.com/register');
+
+ // Fast typing (slow down)
+ const username = 'charlie_test';
+ for (const char of username) {
+ await page.locator('#username').type(char, { delay: persona!.typingSpeed });
+ }
+
+ // Skip reading prompts
+ await page.fill('#email', 'charlie@example.com');
+ await page.fill('#password', '123'); // Weak password - may fail
+ await page.click('#register');
+
+ // Check if error is shown (expected for weak password)
+ const errorVisible = await page.isVisible('.error');
+ expect(errorVisible).toBe(true);
+ });
+
+ test('David (Malicious) - Tries SQL injection and XSS attacks', async ({ page }) => {
+ const persona = configurator.getPersona('David');
+ expect(persona).toBeDefined();
+ expect(persona?.type).toBe('malicious');
+
+ await page.goto('https://example.com/register');
+
+ // Try SQL injection
+ await page.fill('#username', "admin'; DROP TABLE users; --");
+
+ // Try XSS attack
+ await page.fill('#email', '@evil.com');
+
+ // Try SQL login bypass
+ await page.fill('#password', "' OR '1'='1");
+
+ await page.click('#register');
+
+ // Expect backend to block the attack
+ const errorVisible = await page.isVisible('.error');
+ expect(errorVisible).toBe(true);
+ });
+
+ test('Run all personas and collect UX metrics', async ({ page }) => {
+ const personas = configurator.getAllPersonas();
+ const results: Array<{
+ persona: string;
+ success: boolean;
+ duration: number;
+ }> = [];
+
+ for (const persona of personas) {
+ const startTime = Date.now();
+
+ await page.goto('https://example.com/register');
+
+ // Simulate persona behavior
+ await page.fill('#username', `${persona.name}_test`);
+ await page.fill('#email', `${persona.name.toLowerCase()}@example.com`);
+
+ if (persona.readsPrivacy) {
+ await page.click('#privacy-link');
+ await page.waitForTimeout(500);
+ }
+
+ await page.fill('#password', persona.isMalicious ? "' OR '1'='1" : 'SecurePass123!');
+ await page.click('#register');
+
+ const endTime = Date.now();
+ const duration = endTime - startTime;
+
+ const success = !persona.isMalicious && persona.name !== 'Charlie';
+
+ results.push({
+ persona: persona.name,
+ success,
+ duration
+ });
+
+ // Wait before next test
+ await page.waitForTimeout(1000);
+ }
+
+ // Calculate success rate
+ const successCount = results.filter(r => r.success).length;
+ const successRate = (successCount / results.length) * 100;
+
+ // Calculate average duration
+ const avgDuration = results.reduce((sum, r) => sum + r.duration, 0) / results.length;
+
+ console.log(`Success Rate: ${successRate}%`);
+ console.log(`Average Duration: ${avgDuration}ms`);
+
+ expect(successRate).toBeGreaterThan(0);
+ expect(avgDuration).toBeGreaterThan(0);
+ });
+});
diff --git a/backend/src/domain/agent-personas.ts b/backend/src/domain/agent-personas.ts
new file mode 100644
index 0000000..d7dcb53
--- /dev/null
+++ b/backend/src/domain/agent-personas.ts
@@ -0,0 +1,63 @@
+export interface AgentPersona {
+ name: string;
+ type: 'newbie' | 'cautious' | 'impatient' | 'malicious';
+ typingSpeed: number; // ms per character
+ readsPrivacy: boolean;
+ fillsOptional: boolean;
+ isMalicious: boolean;
+ description: string;
+}
+
+export const AGENT_PERSONAS: AgentPersona[] = [
+ {
+ name: 'Alice',
+ type: 'newbie',
+ typingSpeed: 150,
+ readsPrivacy: false,
+ fillsOptional: false,
+ isMalicious: false,
+ description: 'New user who types slowly and reads every prompt carefully'
+ },
+ {
+ name: 'Bob',
+ type: 'cautious',
+ typingSpeed: 80,
+ readsPrivacy: true,
+ fillsOptional: true,
+ isMalicious: false,
+ description: 'Cautious user who checks privacy policy and fills optional fields'
+ },
+ {
+ name: 'Charlie',
+ type: 'impatient',
+ typingSpeed: 50,
+ readsPrivacy: false,
+ fillsOptional: false,
+ isMalicious: false,
+ description: 'Impatient user who types fast and skips optional fields'
+ },
+ {
+ name: 'David',
+ type: 'malicious',
+ typingSpeed: 80,
+ readsPrivacy: false,
+ fillsOptional: false,
+ isMalicious: true,
+ description: 'Malicious user who tries SQL injection and XSS attacks'
+ }
+];
+
+export interface UXMetrics {
+ successRate: number;
+ averageDuration: number;
+ confusionPoints: string[];
+ errorCount: number;
+}
+
+export interface TestResult {
+ persona: AgentPersona;
+ success: boolean;
+ duration: number;
+ metrics: UXMetrics;
+ screenshot?: string;
+}
diff --git a/backend/src/services/persona-configurator.ts b/backend/src/services/persona-configurator.ts
new file mode 100644
index 0000000..f2212e3
--- /dev/null
+++ b/backend/src/services/persona-configurator.ts
@@ -0,0 +1,49 @@
+import { AgentPersona, AGENT_PERSONAS } from '../domain/agent-personas';
+
+export class PersonaConfigurator {
+ /**
+ * Get persona by name
+ */
+ static getPersona(name: string): AgentPersona | undefined {
+ return AGENT_PERSONAS.find(p => p.name === name);
+ }
+
+ /**
+ * Get persona by type
+ */
+ static getPersonaByType(type: AgentPersona['type']): AgentPersona | undefined {
+ return AGENT_PERSONAS.find(p => p.type === type);
+ }
+
+ /**
+ * Get all personas
+ */
+ static getAllPersonas(): AgentPersona[] {
+ return [...AGENT_PERSONAS];
+ }
+
+ /**
+ * Create a custom persona
+ */
+ static createCustomPersona(overrides: Partial): AgentPersona {
+ const basePersona = AGENT_PERSONAS[0]; // Default to Alice
+ return {
+ ...basePersona,
+ ...overrides
+ };
+ }
+
+ /**
+ * Validate persona configuration
+ */
+ static validatePersona(persona: AgentPersona): boolean {
+ return (
+ !!persona.name &&
+ ['newbie', 'cautious', 'impatient', 'malicious'].includes(persona.type) &&
+ persona.typingSpeed > 0 &&
+ typeof persona.readsPrivacy === 'boolean' &&
+ typeof persona.fillsOptional === 'boolean' &&
+ typeof persona.isMalicious === 'boolean'
+ );
+ }
+}