A tap on a device in the simulation now only chooses it; its three-dot button (or a long press) opens what Java's click opened: the desktop, and newly a switch's SAT table and a home router's NAT table, beside each card's data exchange. The desktop, the tables and the data exchange are no windows in the window any more but the simulation's sheet (SimulationSheet), after the dashboard's AppSheet: below the toolbar to the bottom, a head with icon, title, who else has it open, see-through and close. One at a time — it covers the surface. It stays over a return to the design with the program open on a desktop; a sheet whose device was removed closes. See-through fades the body (0.55) and keeps the head; the choice is kept in the browser. Java opens these as movable windows, several at once, with a click; named in CHANGES.md. Tests open through the menu (showFromMenu, showDesktop in editorPage.ts). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
98 lines
5.4 KiB
TypeScript
98 lines
5.4 KiB
TypeScript
// The DNS server on a computer's desktop in Chromium (F4.6g2), on FILIUS'
|
||
// example email_komplett: Java's button and box, the address field with the
|
||
// computer's own address, a record refused with Java's valid example, one
|
||
// added, a cell written and one refused, a row removed, the MX tab, the
|
||
// server stopped; and another computer's command line resolving the new name.
|
||
|
||
import { expect, test, type Page } from '@playwright/test';
|
||
import { drawing, onDevice, openEditor, serveEditor, showDesktop } from './editorPage.js';
|
||
|
||
let server: { readonly base: string; readonly close: () => Promise<void> };
|
||
|
||
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;
|
||
return showDesktop(page, id);
|
||
}
|
||
|
||
test('keeps the records as Java’s DNS window does, and the server answers with them', 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, 'DNS-Server');
|
||
await desktop.locator('[data-program="dnsServer"]').click();
|
||
const window = desktop.locator('[data-program-window="dnsServer"]');
|
||
await expect(window.locator('.program-titlebar h3')).toHaveText('DNS-Server');
|
||
await expect(window.getByRole('button', { name: 'Beenden' })).toBeVisible();
|
||
await expect(window.getByRole('tab')).toHaveText(['Adressen (A)', 'Mailaustausch (MX)', 'Nameserver (NS)']);
|
||
const name = window.getByRole('textbox', { name: 'Host-/Domainname:' });
|
||
const address = window.getByRole('textbox', { name: 'IP-Adresse:' });
|
||
await expect(address).toHaveValue('141.99.50.230');
|
||
const rows = window.getByRole('table', { name: 'Einträge' }).locator('tbody tr');
|
||
const before = await rows.count();
|
||
|
||
// Not taken: Java's valid example.
|
||
await name.fill('kein name!');
|
||
await expect(name).toHaveAttribute('aria-invalid', 'true');
|
||
await window.getByRole('button', { name: 'Hinzufügen' }).click();
|
||
await expect(window.getByRole('alert')).toHaveText('Eingaben sind ungültig! Valides Beispiel: \n> IP-Adresse: 192.168.0.10\n> Domainname: www.filius.de');
|
||
await name.fill('neu.schule.de');
|
||
await address.fill('10.0.0.1');
|
||
await window.getByRole('button', { name: 'Hinzufügen' }).click();
|
||
await expect(rows).toHaveCount(before + 1);
|
||
await expect([await name.inputValue(), await address.inputValue()]).toEqual(['', '']);
|
||
const last = rows.last();
|
||
await expect(last.locator('input').first()).toHaveValue('neu.schule.de.');
|
||
|
||
// A cell written; one the check does not take is marked and goes back.
|
||
const cell = last.locator('input').nth(1);
|
||
await cell.fill('10.0.0.2');
|
||
await cell.press('Enter');
|
||
await expect(cell).toHaveValue('10.0.0.2');
|
||
await cell.fill('10.0.0');
|
||
await expect(cell).toHaveAttribute('aria-invalid', 'true');
|
||
await cell.blur();
|
||
await expect(cell).toHaveValue('10.0.0.2');
|
||
|
||
// A computer whose DNS server it is resolves the new name (the desktop closed, which covered it).
|
||
await desktop.locator('.simulation-sheet__close').click();
|
||
const web = await desktopOf(page, 'Web-Server');
|
||
await web.locator('[data-program="installation"]').click();
|
||
const installation = web.locator('[data-program-window="installation"]');
|
||
await installation.locator('[data-list="available"] [role="option"]').filter({ hasText: 'Befehlszeile' }).click();
|
||
await installation.getByRole('button', { name: 'Installieren' }).click();
|
||
await installation.getByRole('button', { name: 'Änderungen annehmen' }).click();
|
||
await web.locator('[data-program="commandPrompt"]').click();
|
||
const input = web.locator('input[name="terminalInput"]');
|
||
await input.fill('host neu.schule.de');
|
||
await input.press('Enter');
|
||
await expect(web.locator('.terminal-text')).toContainText('10.0.0.2', { timeout: 30_000 });
|
||
await web.locator('.simulation-sheet__close').click();
|
||
await desktopOf(page, 'DNS-Server');
|
||
await desktop.locator('[data-program="dnsServer"]').click();
|
||
|
||
// A row chosen and removed; the MX tab; the box and the button.
|
||
await rows.last().locator('td').first().dispatchEvent('pointerdown');
|
||
await window.getByRole('button', { name: 'Auswahl entfernen' }).click();
|
||
await expect(rows).toHaveCount(before);
|
||
await window.getByRole('tab', { name: 'Mailaustausch (MX)' }).click();
|
||
await window.getByRole('textbox', { name: 'Maildomain:' }).fill('schule.de');
|
||
await window.getByRole('textbox', { name: 'Domainname Mailserver:' }).fill('mail.schule.de');
|
||
await window.getByRole('button', { name: 'Hinzufügen' }).click();
|
||
await expect(rows.last().locator('input').nth(1)).toHaveValue('mail.schule.de.');
|
||
await window.getByRole('checkbox', { name: 'Aktiviere rekursive Domain-Auflösung' }).click();
|
||
await expect(window.getByRole('checkbox', { name: 'Aktiviere rekursive Domain-Auflösung' })).toBeChecked();
|
||
await window.getByRole('checkbox', { name: 'Aktiviere rekursive Domain-Auflösung' }).click();
|
||
await expect(window.getByRole('checkbox', { name: 'Aktiviere rekursive Domain-Auflösung' })).not.toBeChecked();
|
||
await window.getByRole('button', { name: 'Beenden' }).click();
|
||
await expect(window.getByRole('button', { name: 'Starten' })).toBeVisible();
|
||
});
|