Novi Go testovi: - config_test.go: 9 testova (defaults, override, DSN, .env loading) - helpers_test.go: 13 testova (writeJSON, writeError, clientIP) Prosireni E2E testovi za svaku stranicu: - login: 15 testova (forma, auth, redirect, sesije) - dashboard: 18 testova (statistike, navbar, navigacija, odjava) - licenses: 20 testova (tabela, filteri, pretraga, kombinacije) - license-crud: 22 testa (forma, validacija, svi proizvodi/tipovi) - license-detail: 26 testova (info, aktivacije, audit, revoke, release) - audit: 14 testova (tabela, API zapisi, formati) - api-client: 18 testova (activate flow, auth, revoke flow) Azuriran TESTING.md sa kompletnom checklistom Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
238 lines
9.7 KiB
TypeScript
238 lines
9.7 KiB
TypeScript
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<string> {
|
|
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/);
|
|
});
|
|
});
|