Vlasnik izlazi iz DAL price za ovaj projekat - postaje samostalan proizvod. Preimenovanje je mehanicko (import putanje, imena fajlova/baze/UI naslova), NIJEDNA linija poslovne logike u internal/handler ili internal/service nije dirana - go build, go vet i go test ./... prolaze cisto pod novim imenom. - go.mod: module dal-license-server -> licence-server; 28 import linija u 13 .go fajlova usaglaseno - internal/config/config.go (+test): default DB_NAME licence_db - HTML sabloni (7 stranica) + 7 Playwright e2e spec fajlova: "DAL License Server" -> "Licence Server" u title/nav-brand, testovi usaglaseni u istom prolazu (nista ne moze da se razdvoji) - package.json/package-lock.json/.gitignore/.claude/project.json: ime projekta/binarnog fajla/work_dir - Usput: package.json je u repository.url nosio OTVORENU Gitea lozinku u cistom tekstu - uklonjena (URL sad bez kredencijala). Lozinka je i dalje u staroj git istoriji - preporuka: rotirati je posebno. - CLAUDE.md/README/API/TESTING/docs/SPEC/ARCHITECTURE/SETUP: naslovi, ASCII dijagrami, git clone URL, mysqldump primer, systemd predlozak u SETUP.md zamenjen stvarnim (obrazac terminia.service - journal log + graceful shutdown, ne stari minimalni predlozak) - Debrendiranje: "Univerzalni licencni server za sve DAL proizvode" -> "za vise proizvoda i klijenata"; potpis "Nenad Djukic / DAL d.o.o." -> "Nenad Djukic". NE dirano: nazivi ESIR/ARV/LIGHT_TICKET (tudji proizvodi, ne DAL brend), "DAL" kao stvaran naziv org-a u RBAC modelu (docs/loggerservice/README.md) - to je podatak, ne branding ovog servera. - docs/asp-terminia/, docs/loggerservice/: prozni pomeni imena servera Baza (dal_license_db -> licence_db) i deploy na 151 idu u posebnom koraku, posle preimenovanja Gitea repoa - vidi CLAUDE.md istorijsku belesku na dnu. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
120 lines
4.4 KiB
TypeScript
120 lines
4.4 KiB
TypeScript
import { test, expect, Page } from '@playwright/test';
|
|
|
|
async function login(page: Page) {
|
|
await page.goto('/login');
|
|
await page.fill('input[name="username"]', 'admin');
|
|
await page.fill('input[name="password"]', 'admin123');
|
|
await page.click('button[type="submit"]');
|
|
await expect(page).toHaveURL(/\/dashboard/);
|
|
}
|
|
|
|
test.describe('Dashboard stranica', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await login(page);
|
|
});
|
|
|
|
test('prikazuje naslov Dashboard', async ({ page }) => {
|
|
await expect(page.locator('h1')).toHaveText('Dashboard');
|
|
});
|
|
|
|
test('prikazuje statistike po proizvodu — 3 kartice', async ({ page }) => {
|
|
await expect(page.locator('.stats-grid')).toBeVisible();
|
|
const statCards = page.locator('.stat-card');
|
|
await expect(statCards).toHaveCount(3);
|
|
});
|
|
|
|
test('svaka kartica prikazuje ime proizvoda', async ({ page }) => {
|
|
const labels = page.locator('.stat-label');
|
|
const texts = await labels.allTextContents();
|
|
expect(texts).toContain('ESIR Fiskalizacija');
|
|
expect(texts).toContain('ARV Evidencija RV');
|
|
expect(texts).toContain('Light-Ticket');
|
|
});
|
|
|
|
test('svaka kartica prikazuje sve metrike', async ({ page }) => {
|
|
const cards = page.locator('.stat-card');
|
|
const count = await cards.count();
|
|
for (let i = 0; i < count; i++) {
|
|
const card = cards.nth(i);
|
|
await expect(card.locator('.stat-row', { hasText: 'Aktivne:' })).toBeVisible();
|
|
await expect(card.locator('.stat-row', { hasText: 'Istekle:' })).toBeVisible();
|
|
await expect(card.locator('.stat-row', { hasText: 'Grace:' })).toBeVisible();
|
|
await expect(card.locator('.stat-row', { hasText: 'Trial:' })).toBeVisible();
|
|
await expect(card.locator('.stat-row', { hasText: 'Aktivacija:' })).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('prikazuje sekciju poslednje aktivnosti', async ({ page }) => {
|
|
await expect(page.locator('h2', { hasText: 'Poslednja aktivnost' })).toBeVisible();
|
|
await expect(page.locator('table').last()).toBeVisible();
|
|
});
|
|
|
|
test('tabela poslednje aktivnosti ima ispravne kolone', async ({ page }) => {
|
|
const lastTable = page.locator('table').last();
|
|
const headers = lastTable.locator('thead th');
|
|
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');
|
|
});
|
|
|
|
test('navbar prikazuje brend', async ({ page }) => {
|
|
await expect(page.locator('.nav-brand')).toHaveText('Licence Server');
|
|
});
|
|
|
|
test('navbar ima link na dashboard (aktivan)', async ({ page }) => {
|
|
const link = page.locator('a[href="/dashboard"]');
|
|
await expect(link).toBeVisible();
|
|
await expect(link).toHaveClass(/active/);
|
|
});
|
|
|
|
test('navbar ima link na licence', async ({ page }) => {
|
|
await expect(page.locator('a[href="/licenses"]')).toBeVisible();
|
|
});
|
|
|
|
test('navbar ima link na audit log', async ({ page }) => {
|
|
await expect(page.locator('a[href="/audit"]')).toBeVisible();
|
|
});
|
|
|
|
test('navbar ima dugme za odjavu', async ({ page }) => {
|
|
await expect(page.locator('button:has-text("Odjava")')).toBeVisible();
|
|
});
|
|
|
|
test('odjava preusmerava na login', async ({ page }) => {
|
|
await page.click('button:has-text("Odjava")');
|
|
await expect(page).toHaveURL(/\/login/);
|
|
});
|
|
|
|
test('posle odjave ne moze na dashboard', async ({ page }) => {
|
|
await page.click('button:has-text("Odjava")');
|
|
await page.goto('/dashboard');
|
|
await expect(page).toHaveURL(/\/login/);
|
|
});
|
|
|
|
test('root (/) preusmerava na dashboard', async ({ page }) => {
|
|
await page.goto('/');
|
|
await expect(page).toHaveURL(/\/dashboard/);
|
|
});
|
|
|
|
test('navigacija sa dashboarda na licence', async ({ page }) => {
|
|
await page.click('a[href="/licenses"]');
|
|
await expect(page).toHaveURL(/\/licenses/);
|
|
await expect(page.locator('h1')).toHaveText('Licence');
|
|
});
|
|
|
|
test('navigacija sa dashboarda na audit', async ({ page }) => {
|
|
await page.click('a[href="/audit"]');
|
|
await expect(page).toHaveURL(/\/audit/);
|
|
await expect(page.locator('h1')).toHaveText('Audit Log');
|
|
});
|
|
|
|
test('dashboard ima ispravan title', async ({ page }) => {
|
|
await expect(page).toHaveTitle('Dashboard - Licence Server');
|
|
});
|
|
|
|
test('htmx je ucitan', async ({ page }) => {
|
|
const htmxLoaded = await page.evaluate(() => typeof (window as any).htmx !== 'undefined');
|
|
expect(htmxLoaded).toBe(true);
|
|
});
|
|
});
|