// A computer's firewall on its desktop in Chromium (F4.6g3), on FILIUS' // example email_komplett with the firewall installed on its web server: // Java's boxes, a port refused and one added, a notebook's browser let // through by the rule, ICMP no longer allowed and a ping dropped (both in the // log), the firewall switched off (the boxes beneath it can no longer be // changed), the rule chosen and removed. import { expect, test, type Page } from '@playwright/test'; import { drawing, onDevice, openEditor, serveEditor } from './editorPage.js'; let server: { readonly base: string; readonly close: () => Promise }; test.beforeAll(async () => { server = await serveEditor(); }); test.afterAll(async () => { await server.close(); }); async function desktopOf(page: Page, name: string) { const id = (await drawing(page)).nodes.find((node) => node.name === name)!.id; const at = await onDevice(page, id); await page.mouse.click(at.x, at.y); return page.locator(`section[data-desktop="${id}"]`); } async function install(page: Page, desktop: ReturnType, program: string) { await desktop.locator('[data-program="installation"]').click(); const installation = desktop.locator('[data-program-window="installation"]'); await installation.locator('[data-list="available"] [role="option"]').filter({ hasText: program }).click(); await installation.getByRole('button', { name: 'Installieren' }).click(); await installation.getByRole('button', { name: 'Änderungen annehmen' }).click(); } test('keeps a computer’s firewall as Java’s window does, and the firewall lets through what its rules open', async ({ page }) => { test.setTimeout(120_000); await openEditor(page, server.base, 'email_komplett.fls'); await page.getByRole('button', { name: 'Wechselt in den Aktionsmodus' }).click(); await expect(page.locator('svg.filius-canvas')).toHaveAttribute('data-mode', 'simulation'); const desktop = await desktopOf(page, 'Web-Server'); await install(page, desktop, 'Firewall'); await desktop.locator('[data-program="firewall"]').click(); const window = desktop.locator('[data-program-window="firewall"]'); await expect(window.locator('.program-titlebar h3')).toHaveText('Firewall'); await expect(window.getByRole('tab')).toHaveText(['Konfiguration', 'Log']); const active = window.getByRole('checkbox', { name: 'Firewall aktivieren' }); const icmp = window.getByRole('checkbox', { name: 'Internet Control Message Protocol (Ping etc.) erlauben' }); await expect(active).toBeChecked(); await expect(icmp).toBeChecked(); await expect(window.getByRole('checkbox', { name: 'Aktiviere UDP-Datenverkehrfilter' })).toBeChecked(); await expect(window.getByText('Die Firewall blockiert alle eingehenden IP-Pakete')).toBeVisible(); // A port that is none is marked and not handed over; 80 is added and the field emptied. const port = window.getByRole('textbox', { name: 'Zulässiger Port/Protokoll:' }); const add = window.getByRole('button', { name: 'Hinzufügen' }); await port.fill('70000'); await expect(port).toHaveAttribute('aria-invalid', 'true'); await expect(add).toBeDisabled(); await port.fill('80'); await add.click(); const rows = window.getByRole('table', { name: 'Regeln' }).locator('tbody tr'); await expect(rows).toHaveCount(1); await expect(rows.first().locator('td')).toHaveText(['TCP', '80', 'Alle Absender']); await expect(port).toHaveValue(''); // A notebook's browser is let through by the rule; the log says so. await desktop.locator('.desktop-close').click(); const notebook = await desktopOf(page, 'Rechner 1'); await notebook.locator('[data-program="webBrowser"]').click(); const browser = notebook.locator('[data-program-window="webBrowser"]'); const address = browser.getByRole('textbox', { name: 'Adresse' }); await address.fill('141.99.50.231'); await address.press('Enter'); await expect(browser.frameLocator('iframe[title="Seite"]').locator('body')).not.toBeEmpty({ timeout: 30_000 }); // ICMP no longer allowed: the notebook's ping is dropped. await notebook.locator('.desktop-close').click(); await desktopOf(page, 'Web-Server'); await desktop.locator('[data-program="firewall"]').click(); await icmp.click(); await expect(icmp).not.toBeChecked(); await desktop.locator('.desktop-close').click(); await desktopOf(page, 'Rechner 1'); await install(page, notebook, 'Befehlszeile'); await notebook.locator('[data-program="commandPrompt"]').click(); const input = notebook.locator('input[name="terminalInput"]'); await input.fill('ping 141.99.50.231'); await input.press('Enter'); await expect(notebook.locator('.terminal-text')).toContainText('0 Paket(e) empfangen', { timeout: 60_000 }); await notebook.locator('.desktop-close').click(); await desktopOf(page, 'Web-Server'); await desktop.locator('[data-program="firewall"]').click(); await window.getByRole('tab', { name: 'Log' }).click(); const log = window.getByRole('tabpanel', { name: 'Log' }); await expect(log).toContainText('Portregel wurde hinzugefügt: 80/TCP\nFirewall-Regel hat gegriffen: #1 (*/* -> */*; TCP:80 => ACCEPT) -> akzeptieren'); await expect(log).toContainText('ICMP-Paket verworfen: 141.99.50.181 -> 141.99.50.231 (code: 0, type: 8)'); // Off: the two boxes beneath it can no longer be changed; the rule chosen and removed. await window.getByRole('tab', { name: 'Konfiguration' }).click(); await active.click(); await expect(active).not.toBeChecked(); await expect(icmp).toBeDisabled(); await expect(window.getByRole('button', { name: 'Löschen' })).toBeDisabled(); await rows.first().dispatchEvent('pointerdown'); await window.getByRole('button', { name: 'Löschen' }).click(); await expect(rows).toHaveCount(0); await window.getByRole('tab', { name: 'Log' }).click(); await expect(log).toContainText('Portregel wurde entfernt.'); });