import { test, expect, Page } from '@playwright/test'; const BASE = 'http://localhost:8090'; const API_KEY = 'dev-api-key-minimum-32-characters-long'; async function login(page: Page) { await page.goto('/login'); await page.fill('input[name="password"]', 'admin123'); await page.click('button[type="submit"]'); await expect(page).toHaveURL(/\/dashboard/); } test.describe('Audit Log stranica', () => { test.beforeEach(async ({ page }) => { await login(page); }); test('prikazuje naslov Audit Log', async ({ page }) => { await page.goto('/audit'); await expect(page.locator('h1')).toHaveText('Audit Log'); }); test('ima ispravan title', async ({ page }) => { await page.goto('/audit'); await expect(page).toHaveTitle('Audit Log - DAL License Server'); }); test('prikazuje tabelu', async ({ page }) => { await page.goto('/audit'); await expect(page.locator('table')).toBeVisible(); }); test('tabela ima 5 kolona', async ({ page }) => { await page.goto('/audit'); const headers = page.locator('thead th'); await expect(headers).toHaveCount(5); await expect(headers.nth(0)).toHaveText('Vreme'); await expect(headers.nth(1)).toHaveText('Akcija'); await expect(headers.nth(2)).toHaveText('Licenca'); await expect(headers.nth(3)).toHaveText('IP'); await expect(headers.nth(4)).toHaveText('Detalji'); }); test('navbar audit link je aktivan', async ({ page }) => { await page.goto('/audit'); const link = page.locator('a[href="/audit"]'); await expect(link).toHaveClass(/active/); }); test('navigacija iz navbara radi', async ({ page }) => { await page.click('a[href="/audit"]'); await expect(page).toHaveURL(/\/audit/); }); test('kreiranje licence generise CREATE zapis u audit-u', async ({ page }) => { // Kreiraj licencu await page.goto('/licenses/new'); const productSelect = page.locator('select[name="product_id"]'); const options = productSelect.locator('option'); const count = await options.count(); for (let i = 0; i < count; i++) { const text = await options.nth(i).textContent(); if (text && text.includes('LIGHT_TICKET')) { await productSelect.selectOption({ index: i }); break; } } await page.selectOption('select[name="license_type"]', 'MONTHLY'); await page.fill('input[name="customer_name"]', `Audit Create ${Date.now()}`); await page.click('button:has-text("Kreiraj licencu")'); await expect(page).toHaveURL(/\/licenses\/\d+/); // Proveri audit await page.goto('/audit'); await expect(page.locator('.badge', { hasText: 'CREATE' }).first()).toBeVisible(); }); test('audit prikazuje licencni kljuc', async ({ page }) => { await page.goto('/audit'); // Audit zapisi koji imaju licencu prikazuju code element const codeElements = page.locator('tbody code'); const count = await codeElements.count(); if (count > 0) { const firstKey = await codeElements.first().textContent(); expect(firstKey).toMatch(/^(LT|ARV|ESIR)-/); } }); test('audit prikazuje IP adresu', async ({ page }) => { await page.goto('/audit'); // Mora biti bar jedan zapis sa IP adresom const rows = page.locator('tbody tr'); const count = await rows.count(); expect(count).toBeGreaterThan(0); }); test('audit prikazuje vreme u ispravnom formatu', async ({ page }) => { await page.goto('/audit'); const firstTimeCell = page.locator('tbody td').first(); const text = await firstTimeCell.textContent(); // Format: DD.MM.YYYY HH:MM if (text && text.trim() !== 'Nema podataka') { expect(text).toMatch(/\d{2}\.\d{2}\.\d{4}/); } }); test('audit prikazuje detalje kao JSON', async ({ page }) => { await page.goto('/audit'); const details = page.locator('.audit-details'); const count = await details.count(); if (count > 0) { await expect(details.first()).toBeVisible(); } }); }); test.describe('Audit Log — API zapisi', () => { test('aktivacija generise ACTIVATE zapis', async ({ request, page }) => { // Kreiraj licencu const createRes = await request.post(`${BASE}/api/v1/admin/licenses`, { headers: { 'X-API-Key': API_KEY, 'Content-Type': 'application/json' }, data: { product_id: 3, license_type: 'MONTHLY', customer_name: 'Audit Activate Test', }, }); const created = await createRes.json(); // Aktiviraj await request.post(`${BASE}/api/v1/activate`, { data: { license_key: created.license_key, machine_fingerprint: 'sha256:audit-activate-test', app_version: '1.0.0', os: 'linux', hostname: 'AUDIT-PC', }, }); // Proveri audit na UI await login(page); await page.goto('/audit'); await expect(page.locator('.badge', { hasText: 'ACTIVATE' }).first()).toBeVisible(); }); test('deaktivacija generise DEACTIVATE zapis', async ({ request, page }) => { const createRes = await request.post(`${BASE}/api/v1/admin/licenses`, { headers: { 'X-API-Key': API_KEY, 'Content-Type': 'application/json' }, data: { product_id: 3, license_type: 'MONTHLY', customer_name: 'Audit Deactivate Test', }, }); const created = await createRes.json(); const fp = 'sha256:audit-deactivate-test'; await request.post(`${BASE}/api/v1/activate`, { data: { license_key: created.license_key, machine_fingerprint: fp, app_version: '1.0.0', os: 'linux', hostname: 'PC' }, }); await request.post(`${BASE}/api/v1/deactivate`, { data: { license_key: created.license_key, machine_fingerprint: fp }, }); await login(page); await page.goto('/audit'); await expect(page.locator('.badge', { hasText: 'DEACTIVATE' }).first()).toBeVisible(); }); test('validacija generise VALIDATE zapis', async ({ request, page }) => { const createRes = await request.post(`${BASE}/api/v1/admin/licenses`, { headers: { 'X-API-Key': API_KEY, 'Content-Type': 'application/json' }, data: { product_id: 3, license_type: 'MONTHLY', customer_name: 'Audit Validate Test', }, }); const created = await createRes.json(); await request.post(`${BASE}/api/v1/validate`, { data: { license_key: created.license_key, machine_fingerprint: 'sha256:validate-test' }, }); await login(page); await page.goto('/audit'); await expect(page.locator('.badge', { hasText: 'VALIDATE' }).first()).toBeVisible(); }); });