import { test, expect, Page } from '@playwright/test'; 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/); } async function createLicense(page: Page, customerName: string, productCode = 'LIGHT_TICKET', licenseType = 'MONTHLY'): Promise { 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(productCode)) { await productSelect.selectOption({ index: i }); break; } } await page.selectOption('select[name="license_type"]', licenseType); await page.fill('input[name="customer_name"]', customerName); await page.click('button:has-text("Kreiraj licencu")'); await expect(page).toHaveURL(/\/licenses\/\d+/); return page.url(); } test.describe('Detalji licence — informacije', () => { test.beforeEach(async ({ page }) => { await login(page); }); test('prikazuje licencni kljuc u naslovu', async ({ page }) => { await createLicense(page, 'Detail Info Test'); await expect(page.locator('h1 code')).toBeVisible(); const key = await page.locator('h1 code').textContent(); expect(key).toMatch(/^LT-/); }); test('prikazuje status badge', async ({ page }) => { await createLicense(page, 'Status Badge Test'); await expect(page.locator('.page-header .badge')).toBeVisible(); }); test('prikazuje sekciju Informacije', async ({ page }) => { await createLicense(page, 'Info Section Test'); await expect(page.locator('h3', { hasText: 'Informacije' })).toBeVisible(); await expect(page.locator('.detail-table')).toBeVisible(); }); test('prikazuje sve informacione polja', async ({ page }) => { await createLicense(page, 'All Fields Test'); const table = page.locator('.detail-table'); await expect(table.locator('td', { hasText: 'Proizvod' })).toBeVisible(); await expect(table.locator('td', { hasText: 'Tip' })).toBeVisible(); await expect(table.locator('td', { hasText: 'Firma' })).toBeVisible(); await expect(table.locator('td', { hasText: 'Izdata' })).toBeVisible(); await expect(table.locator('td', { hasText: 'Istice' })).toBeVisible(); await expect(table.locator('td', { hasText: 'Grace period' })).toBeVisible(); await expect(table.locator('td', { hasText: 'Limiti' })).toBeVisible(); await expect(table.locator('td', { hasText: 'Features' })).toBeVisible(); }); test('prikazuje ispravne podatke za LT licencu', async ({ page }) => { await createLicense(page, 'LT Data Check'); const detailText = await page.locator('.detail-table').textContent(); expect(detailText).toContain('LIGHT_TICKET'); expect(detailText).toContain('MONTHLY'); expect(detailText).toContain('LT Data Check'); expect(detailText).toContain('30 dana'); }); test('prikazuje ispravne podatke za ARV licencu', async ({ page }) => { await createLicense(page, 'ARV Data Check', 'ARV', 'ANNUAL'); const detailText = await page.locator('.detail-table').textContent(); expect(detailText).toContain('ARV'); expect(detailText).toContain('ANNUAL'); }); test('PERPETUAL prikazuje Neograniceno', async ({ page }) => { await createLicense(page, 'Perpetual Check', 'ESIR', 'PERPETUAL'); await expect(page.locator('td', { hasText: 'Neograniceno' })).toBeVisible(); }); test('ima ispravan title sa kljucem', async ({ page }) => { await createLicense(page, 'Title Check'); const title = await page.title(); expect(title).toContain('LT-'); expect(title).toContain('DAL License Server'); }); }); test.describe('Detalji licence — aktivacije i audit', () => { test.beforeEach(async ({ page }) => { await login(page); }); test('prikazuje tabelu aktivacija', async ({ page }) => { await createLicense(page, 'Activation Table Test'); await expect(page.locator('h2', { hasText: 'Aktivacije' })).toBeVisible(); }); test('nova licenca nema aktivacija', async ({ page }) => { await createLicense(page, 'No Activations Test'); await expect(page.locator('td', { hasText: 'Nema aktivacija' })).toBeVisible(); }); test('tabela aktivacija ima ispravne kolone', async ({ page }) => { await createLicense(page, 'Activation Cols Test'); const table = page.locator('table').nth(1); // druga tabela const headers = table.locator('thead th'); await expect(headers.nth(0)).toHaveText('Hostname'); await expect(headers.nth(1)).toHaveText('OS'); await expect(headers.nth(2)).toHaveText('Verzija'); await expect(headers.nth(3)).toHaveText('IP'); }); test('prikazuje audit log za licencu', async ({ page }) => { await createLicense(page, 'Audit Log Test'); await expect(page.locator('h2', { hasText: 'Audit Log' })).toBeVisible(); }); test('kreiranje licence generise CREATE audit zapis', async ({ page }) => { await createLicense(page, 'Create Audit Test'); await expect(page.locator('.badge', { hasText: 'CREATE' })).toBeVisible(); }); test('audit tabela ima ispravne kolone', async ({ page }) => { await createLicense(page, 'Audit Cols Test'); const table = page.locator('table').last(); const headers = table.locator('thead th'); await expect(headers.nth(0)).toHaveText('Vreme'); await expect(headers.nth(1)).toHaveText('Akcija'); await expect(headers.nth(2)).toHaveText('IP'); await expect(headers.nth(3)).toHaveText('Detalji'); }); }); test.describe('Detalji licence — akcije', () => { test.beforeEach(async ({ page }) => { await login(page); }); test('prikazuje sekciju Akcije', async ({ page }) => { await createLicense(page, 'Actions Section Test'); await expect(page.locator('h3', { hasText: 'Akcije' })).toBeVisible(); }); test('prikazuje dugme za opoziv', async ({ page }) => { await createLicense(page, 'Revoke Button Test'); await expect(page.locator('button:has-text("Opozovi licencu")')).toBeVisible(); await expect(page.locator('button:has-text("Opozovi licencu")')).toHaveClass(/btn-danger/); }); test('prikazuje dugme za force release', async ({ page }) => { await createLicense(page, 'Release Button Test'); await expect(page.locator('button:has-text("Force Release")')).toBeVisible(); await expect(page.locator('button:has-text("Force Release")')).toHaveClass(/btn-warning/); }); test('prikazuje polje za razlog opoziva', async ({ page }) => { await createLicense(page, 'Reason Field Test'); await expect(page.locator('input[name="reason"]')).toBeVisible(); await expect(page.locator('input[name="reason"]')).toHaveAttribute('placeholder', 'Razlog opoziva'); }); test('revoke licence menja status na Opozvana', async ({ page }) => { await createLicense(page, 'Revoke Status Test'); page.on('dialog', dialog => dialog.accept()); await page.fill('input[name="reason"]', 'E2E test razlog'); await page.click('button:has-text("Opozovi licencu")'); await expect(page).toHaveURL(/\/licenses\/\d+/); await expect(page.locator('.badge.status-revoked')).toBeVisible(); }); test('revoke generise REVOKE audit zapis', async ({ page }) => { await createLicense(page, 'Revoke Audit Test'); page.on('dialog', dialog => dialog.accept()); await page.fill('input[name="reason"]', 'Audit test'); await page.click('button:has-text("Opozovi licencu")'); await expect(page).toHaveURL(/\/licenses\/\d+/); await expect(page.locator('.badge', { hasText: 'REVOKE' })).toBeVisible(); }); test('posle revoke-a dugme za opoziv nestaje', async ({ page }) => { await createLicense(page, 'Revoke Hide Test'); page.on('dialog', dialog => dialog.accept()); await page.click('button:has-text("Opozovi licencu")'); await expect(page).toHaveURL(/\/licenses\/\d+/); await expect(page.locator('button:has-text("Opozovi licencu")')).toHaveCount(0); }); test('posle revoke-a force release dugme ostaje', async ({ page }) => { await createLicense(page, 'Revoke FR Test'); page.on('dialog', dialog => dialog.accept()); await page.click('button:has-text("Opozovi licencu")'); await expect(page).toHaveURL(/\/licenses\/\d+/); await expect(page.locator('button:has-text("Force Release")')).toBeVisible(); }); test('force release funkcionise', async ({ page }) => { await createLicense(page, 'Force Release Test'); page.on('dialog', dialog => dialog.accept()); await page.click('button:has-text("Force Release")'); await expect(page).toHaveURL(/\/licenses\/\d+/); }); test('force release generise FORCE_RELEASE audit zapis', async ({ page }) => { await createLicense(page, 'FR Audit Test'); page.on('dialog', dialog => dialog.accept()); await page.click('button:has-text("Force Release")'); await expect(page).toHaveURL(/\/licenses\/\d+/); await expect(page.locator('.badge', { hasText: 'FORCE_RELEASE' })).toBeVisible(); }); }); test.describe('Detalji licence — navigacija', () => { test.beforeEach(async ({ page }) => { await login(page); }); test('klik na licencu iz liste otvara detalje', async ({ page }) => { await createLicense(page, 'Navigation Test'); await page.goto('/licenses'); const link = page.locator('a:has(code)').first(); await link.click(); await expect(page).toHaveURL(/\/licenses\/\d+/); await expect(page.locator('h1 code')).toBeVisible(); }); test('navbar licence link je aktivan na detalj stranici', async ({ page }) => { await createLicense(page, 'Navbar Active Test'); const link = page.locator('a[href="/licenses"]'); await expect(link).toHaveClass(/active/); }); });