import { test, expect } from '@playwright/test'; import * as fs from 'fs'; test.describe('Environment Management', () => { test('should not allow removing DEFAULT environment', async ({ page }) => { await page.goto('/'); await page.click('button:has-text("Create new")'); const removeButton = page.locator('button.btn-danger[title="Remove environment"]'); await expect(removeButton).toBeDisabled(); }); test('should remove non-DEFAULT environment', async ({ page }) => { await page.goto('/'); await page.click('button:has-text("Create new")'); page.once('dialog', async dialog => { await dialog.accept('toRemove'); }); await page.click('button.btn-success[title="Add environment"]'); await page.waitForTimeout(500); await expect(page.locator('#environments option')).toHaveCount(2); page.once('dialog', async dialog => { await dialog.accept(); }); await page.click('button.btn-danger[title="Remove environment"]'); await page.waitForTimeout(300); await expect(page.locator('#environments option')).toHaveCount(1); }); test('should create new environment and switch without errors', async ({ page }) => { await page.goto('/'); await page.click('button:has-text("Create new")'); page.once('dialog', async dialog => { await dialog.accept('env1'); }); await page.click('button.btn-success[title="Add environment"]'); await page.waitForTimeout(500); await expect(page.locator('#environments option')).toHaveCount(2); await page.locator('#environments').selectOption({ index: 0 }); await page.waitForTimeout(300); await page.locator('#environments').selectOption('env1'); await page.waitForTimeout(300); await expect(page.locator('#environments')).toBeVisible(); }); test('should create multiple environments and switch between them', async ({ page }) => { await page.goto('/'); await page.click('button:has-text("Create new")'); page.once('dialog', async dialog => { await dialog.accept('env1'); }); await page.click('button.btn-success[title="Add environment"]'); await page.waitForTimeout(500); page.once('dialog', async dialog => { await dialog.accept('env2'); }); await page.click('button.btn-success[title="Add environment"]'); await page.waitForTimeout(500); await expect(page.locator('#environments option')).toHaveCount(3); await page.locator('#environments').selectOption({ index: 0 }); await page.waitForTimeout(200); await page.locator('#environments').selectOption('env1'); await page.waitForTimeout(200); await page.locator('#environments').selectOption('env2'); await page.waitForTimeout(200); await expect(page.locator('#environments')).toBeVisible(); }); test('should add params and edit template manually', async ({ page }) => { await page.goto('/'); await page.click('button:has-text("Create new")'); const nameInput = page.locator('input[placeholder="name"]').first(); const valueInput = page.locator('input[placeholder="value"]').first(); const addButton = page.locator('button.btn-success').first(); await nameInput.fill('host'); await valueInput.fill('localhost:8080'); await addButton.click(); await page.waitForTimeout(500); await nameInput.fill('port'); await valueInput.fill('9090'); await addButton.click(); await page.waitForTimeout(500); await page.click('a:has-text("Content Template")'); await page.waitForTimeout(500); await expect(page.locator('button:has-text("Edit")')).toBeVisible(); await page.click('button:has-text("Edit")'); await page.waitForTimeout(500); const textarea = page.locator('textarea'); await expect(textarea).toBeVisible(); await textarea.fill('{\n "!!! host": "@host@",\n "!!! port": "@port@",\n "!!! custom": "@custom@"\n}'); await page.waitForTimeout(300); await page.click('button:has-text("Save")'); await page.waitForTimeout(500); await expect(page.locator('button:has-text("Edit")')).toBeVisible(); const pageContent = await page.content(); expect(pageContent).toContain('!!! custom'); }); test('should not duplicate params when placeholder already exists', async ({ page }) => { await page.goto('/'); await page.click('button:has-text("Create new")'); const nameInput = page.locator('input[placeholder="name"]').first(); const valueInput = page.locator('input[placeholder="value"]').first(); const addButton = page.locator('button.btn-success').first(); await nameInput.fill('host'); await valueInput.fill('localhost:8080'); await addButton.click(); await page.waitForTimeout(500); await page.click('a:has-text("Content Template")'); await page.waitForTimeout(500); await page.click('button:has-text("Edit")'); await page.waitForTimeout(300); const textarea = page.locator('textarea'); await textarea.fill('{\n "!!! host": "@host@",\n "apiUrl": "http://@host@/api"\n}'); await page.waitForTimeout(300); await page.click('button:has-text("Save")'); await page.waitForTimeout(500); await page.click('a:has-text("Env")'); await page.waitForTimeout(300); await nameInput.fill('host'); await valueInput.fill('updated-host:9090'); await addButton.click(); await page.waitForTimeout(500); await page.click('a:has-text("Content Template")'); await page.waitForTimeout(500); const templateContent = await page.locator('.config-template-editor').textContent(); const hostKeyCount = (templateContent.match(/!!! host/g) || []).length; expect(hostKeyCount).toBe(1); const hostPlaceholderCount = (templateContent.match(/@host@/g) || []).length; expect(hostPlaceholderCount).toBe(2); }); test('should download config file with correct filename', async ({ page }) => { await page.goto('/'); await page.click('button:has-text("Create new")'); await page.waitForTimeout(500); const [download] = await Promise.all([ page.waitForEvent('download'), page.click('button:has-text("Download")') ]); const filename = download.suggestedFilename(); expect(filename).toMatch(/^config_\d{2}-\d{2}-\d{2}-\d{4}\.json\.xml$/); // Save and read the file to verify content await download.saveAs('temp-config.xml'); const contentStr = fs.readFileSync('temp-config.xml', 'utf8'); expect(contentStr).toContain('engine'); expect(contentStr).toContain('DEFAULT'); expect(contentStr).toContain('template'); fs.unlinkSync('temp-config.xml'); }); });