/**
 * Tests for E2ETestGenerator
 */

import { E2ETestGenerator } from './e2e-test-generator';
import { WorkflowEngine } from '../../engine/workflow-engine';

describe('E2ETestGenerator', () => {
  let generator: E2ETestGenerator;

  beforeEach(() => {
    generator = new E2ETestGenerator();
  });

  it('should have correct metadata', () => {
    expect(generator.id).toBe('e2e-tests');
    expect(generator.name).toBe('E2E Test Generator');
    expect(generator.testFramework).toBe('playwright');
  });

  it('should generate empty result for workflow without e2e tests', () => {
    const workflow = {
      workflow: {
        id: 'test',
        name: 'Test',
        version: '1.0.0',
        description: 'Test',
      },
      stack: {
        'web-app': {
          type: 'frontend',
          technology: 'react',
        },
      },
    };

    const engine = new WorkflowEngine();
    const executionPlan = engine.analyze(workflow as any);

    const result = generator.generate({
      workflow: workflow as any,
      executionPlan,
      outputDirectory: '/test',
    });

    expect(result.files).toHaveLength(0);
  });

  it('should generate Playwright E2E tests', () => {
    const workflow = {
      workflow: {
        id: 'test',
        name: 'Test',
        version: '1.0.0',
        description: 'Test',
      },
      stack: {
        'web-app': {
          type: 'frontend',
          technology: 'react',
        },
      },
      testing: {
        e2e_tests: [
          {
            name: 'user-can-login',
            tool: 'playwright',
            steps: [
              'Navigate to /login',
              'Fill email field with "test@example.com"',
              'Click login button',
              'Assert URL is /dashboard',
            ],
          },
        ],
      },
    };

    const engine = new WorkflowEngine();
    const executionPlan = engine.analyze(workflow as any);

    const result = generator.generate({
      workflow: workflow as any,
      executionPlan,
      outputDirectory: '/test',
    });

    expect(result.files.length).toBeGreaterThan(0);

    const testFile = result.files.find(f => f.path.includes('user-can-login.spec.ts'));
    expect(testFile).toBeDefined();
    expect(testFile?.content).toContain('@playwright/test');
    expect(testFile?.content).toContain('page.goto');
    expect(testFile?.content).toContain('page.fill');
    expect(testFile?.content).toContain('page.click');
  });

  it('should generate Playwright config', () => {
    const workflow = {
      workflow: {
        id: 'test',
        name: 'Test',
        version: '1.0.0',
        description: 'Test',
      },
      stack: {
        'web-app': {
          type: 'frontend',
          technology: 'react',
        },
      },
      testing: {
        e2e_tests: [
          {
            name: 'test',
            tool: 'playwright',
            steps: ['test'],
          },
        ],
      },
    };

    const engine = new WorkflowEngine();
    const executionPlan = engine.analyze(workflow as any);

    const result = generator.generate({
      workflow: workflow as any,
      executionPlan,
      outputDirectory: '/test',
    });

    const playwrightConfig = result.files.find(f => f.path.includes('playwright.config.ts'));
    expect(playwrightConfig).toBeDefined();
    expect(playwrightConfig?.content).toContain('defineConfig');
    expect(playwrightConfig?.content).toContain('chromium');
    expect(playwrightConfig?.content).toContain('webServer');
  });

  it('should generate test fixtures', () => {
    const workflow = {
      workflow: {
        id: 'test',
        name: 'Test',
        version: '1.0.0',
        description: 'Test',
      },
      stack: {
        'web-app': {
          type: 'frontend',
          technology: 'react',
        },
      },
      testing: {
        e2e_tests: [
          {
            name: 'test',
            tool: 'playwright',
            steps: ['test'],
          },
        ],
      },
    };

    const engine = new WorkflowEngine();
    const executionPlan = engine.analyze(workflow as any);

    const result = generator.generate({
      workflow: workflow as any,
      executionPlan,
      outputDirectory: '/test',
    });

    const fixtures = result.files.find(f => f.path.includes('fixtures.ts'));
    expect(fixtures).toBeDefined();
    expect(fixtures?.content).toContain('authenticatedPage');
  });

  it('should not overwrite playwright config', () => {
    const workflow = {
      workflow: {
        id: 'test',
        name: 'Test',
        version: '1.0.0',
        description: 'Test',
      },
      stack: {
        'web-app': {
          type: 'frontend',
          technology: 'react',
        },
      },
      testing: {
        e2e_tests: [
          {
            name: 'test',
            tool: 'playwright',
            steps: ['test'],
          },
        ],
      },
    };

    const engine = new WorkflowEngine();
    const executionPlan = engine.analyze(workflow as any);

    const result = generator.generate({
      workflow: workflow as any,
      executionPlan,
      outputDirectory: '/test',
    });

    const playwrightConfig = result.files.find(f => f.path.includes('playwright.config.ts'));
    expect(playwrightConfig?.overwrite).toBe(false);
  });

  it('should return warning when no frontend component found', () => {
    const workflow = {
      workflow: {
        id: 'test',
        name: 'Test',
        version: '1.0.0',
        description: 'Test',
      },
      stack: {
        api: {
          type: 'backend',
          technology: 'typescript/express',
        },
      },
      testing: {
        e2e_tests: [
          {
            name: 'test',
            tool: 'playwright',
            steps: ['test'],
          },
        ],
      },
    };

    const engine = new WorkflowEngine();
    const executionPlan = engine.analyze(workflow as any);

    const result = generator.generate({
      workflow: workflow as any,
      executionPlan,
      outputDirectory: '/test',
    });

    expect(result.warnings).toBeDefined();
    expect(result.warnings).toContain('No frontend component found for E2E tests');
  });
});
