const { test, expect } = require('@playwright/test');

test.describe('Security Headers Tests', () => {
    test('should have all required security headers', async ({ page }) => {
        try {
            // Navigate to the page with a timeout
            await page.goto('http://localhost:8080', { timeout: 30000 });

            // Get response headers
            const response = await page.waitForResponse('http://localhost:8080', { timeout: 30000 });
            const headers = response.headers();

            // Define required headers and their expected values
            const requiredHeaders = {
                'Content-Security-Policy': expect.stringContaining("default-src 'self'"),
                'X-Content-Type-Options': 'nosniff',
                'X-Frame-Options': 'DENY',
                'X-XSS-Protection': '1; mode=block',
                'Referrer-Policy': 'strict-origin-when-cross-origin',
                'Permissions-Policy': expect.stringContaining('geolocation=()'),
                'Strict-Transport-Security': expect.stringContaining('max-age=31536000'),
            };

            // Check each required header
            for (const [header, expectedValue] of Object.entries(requiredHeaders)) {
                const headerValue = headers[header.toLowerCase()];
                console.log(`Checking header: ${header}, Value: ${headerValue}`);
                expect(headerValue, `${header} is not defined`).toBeDefined();
                if (typeof expectedValue === 'string') {
                    expect(headerValue, `${header} does not match expected value`).toBe(expectedValue);
                } else {
                    expect(headerValue, `${header} does not match expected pattern`).toMatch(expectedValue);
                }
            }
        } catch (error) {
            console.error('Error in security headers test:', error);
            throw new Error(`Failed to load local server for security headers test: ${error.message}`);
        }
    });

    test('should have correct CSP directives with hash', async ({ page }) => {
        try {
            await page.goto('http://localhost:8080', { timeout: 30000 });
            const response = await page.waitForResponse('http://localhost:8080', { timeout: 30000 });
            const headers = response.headers();
            const csp = headers['content-security-policy'];

            // Check for essential CSP directives
            console.log('CSP Header:', csp);
            expect(csp, 'CSP header is not defined').toBeDefined();
            expect(csp, 'CSP does not contain default-src directive').toContain("default-src 'none'");
            expect(csp, 'CSP does not contain script-src with hash').toContain("script-src 'self' 'sha256-ryQsJ+aghKKD/CeXgx8jtsnZT3Epp3EjIw8RyHIq544='"); 
            expect(csp, 'CSP does not contain style-src with hash').toContain("style-src 'self' 'sha256-Mo+7o3oPEKpX7fqRvTtunvQHlIDhJ0SxAMG1PCNniCI='"); 
            expect(csp, 'CSP does not contain img-src directive').toContain("img-src 'self' data:");
            expect(csp, 'CSP does not contain font-src directive').toContain("font-src 'self' data:");
            expect(csp, 'CSP does not contain connect-src directive').toContain("connect-src 'self'");
        } catch (error) {
            console.error('Error in CSP directives test:', error);
            throw new Error(`Failed to load local server for CSP test: ${error.message}`);
        }
    });

    test('should have integrity attributes on script tags', async ({ page }) => {
        try {
            await page.goto('http://localhost:8080', { timeout: 30000 });
            
            // Check that all script tags have integrity attributes
            const scripts = await page.$$('script');
            console.log(`Found ${scripts.length} script tags`);
            for (const script of scripts) {
                const hasIntegrity = await script.evaluate(el => el.hasAttribute('integrity'));
                const src = await script.evaluate(el => el.getAttribute('src') || 'inline script');
                console.log(`Script ${src} has integrity: ${hasIntegrity}`);
                expect(hasIntegrity, `Script tag ${src} missing integrity attribute`).toBeTruthy();
            }
        } catch (error) {
            console.error('Error in integrity attributes test:', error);
            throw new Error(`Failed to load local server for integrity test: ${error.message}`);
        }
    });
}); 