Files
mdg-filius/packages/editor/browser/echo.spec.ts
T
julian.kiedaischandClaude Opus 5.5 16d9cc2095 feat(editor): the simulation opens sheets, not windows in the window
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>
2026-10-10 17:18:25 +00:00

85 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// The echo server and the generic client on two computers' desktops in
// Chromium (F4.6g1), on browser/fixtures/web-pages.fls: installed while the
// simulation runs; the server started on a port typed (one that is no port
// marked and not handed over), the client connected, a message sent and
// echoed, the fields locked while connected, the server's lines, "Trennen".
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { expect, test, type Page } from '@playwright/test';
import { drawing, onDevice, 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();
});
const FIXTURE = join(dirname(fileURLToPath(import.meta.url)), 'fixtures/web-pages.fls');
async function openPages(page: Page): Promise<void> {
await page.goto(`${server.base}?example=new`);
await page.waitForSelector('svg.filius-canvas');
await page.locator('input[type="file"]').first().setInputFiles(FIXTURE);
await expect.poll(async () => (await drawing(page).catch(() => ({ nodes: [] }))).nodes.length).toBe(4);
await page.getByRole('button', { name: 'Wechselt in den Aktionsmodus' }).click();
await expect(page.locator('svg.filius-canvas')).toHaveAttribute('data-mode', 'simulation');
}
/** A computer's desktop opened with a tap, a program installed on it, and its window opened. */
async function install(page: Page, name: string, program: string, label: string) {
const id = (await drawing(page)).nodes.find((node) => node.name === name)!.id;
const desktop = await showDesktop(page, id);
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: label }).click();
await installation.getByRole('button', { name: 'Installieren' }).click();
await installation.getByRole('button', { name: 'Änderungen annehmen' }).click();
await desktop.locator(`[data-program="${program}"]`).click();
return { desktop, window: desktop.locator(`[data-program-window="${program}"]`) };
}
test('echoes a message from the generic client, as Java’s windows do', async ({ page }) => {
test.setTimeout(120_000);
await openPages(page);
const echo = await install(page, 'Server', 'echoServer', 'Echo-Server');
await expect(echo.window.locator('.program-titlebar h3')).toHaveText('Echo-Server');
const port = echo.window.getByRole('textbox', { name: 'Port:' });
await expect(port).toHaveValue('55555');
// A port that is no port: marked, the button does nothing.
await port.fill('abc');
await expect(port).toHaveAttribute('aria-invalid', 'true');
await echo.window.getByRole('button', { name: 'Starten' }).click();
await expect(echo.window.getByRole('button', { name: 'Starten' })).toBeVisible();
await port.fill('7777');
await echo.window.getByRole('button', { name: 'Starten' }).click();
await expect(echo.window.getByRole('button', { name: 'Anhalten' })).toBeVisible();
await expect(port).toHaveAttribute('readonly', '');
const serverLog = echo.window.getByLabel('Ausgabe');
await expect(serverLog).toHaveText('Annahme von Verbindungsanfragen gestartet\n');
await echo.desktop.locator('.simulation-sheet__close').click();
const client = await install(page, 'Browser', 'simpleClient', 'Einfacher Client');
const send = client.window.getByRole('button', { name: 'Senden' });
await expect(send).toBeDisabled();
await client.window.getByRole('textbox', { name: 'Server-Adresse:' }).fill('192.168.0.20');
await client.window.getByRole('textbox', { name: 'Server-Port:' }).fill('7777');
await client.window.getByRole('button', { name: 'Verbinden' }).click();
await expect(client.window.getByRole('button', { name: 'Trennen' })).toBeVisible({ timeout: 30_000 });
await expect(client.window.getByRole('textbox', { name: 'Server-Adresse:' })).toHaveAttribute('readonly', '');
const output = client.window.getByLabel('Ausgabe');
await expect(output).toHaveText('Verbindung hergestellt\n');
await client.window.getByRole('textbox', { name: 'Nachricht:' }).fill('Hallo Echo');
await send.click();
await expect(client.window.getByRole('textbox', { name: 'Nachricht:' })).toHaveValue('');
await expect(output).toHaveText('Verbindung hergestellt\n<<Hallo Echo\n>>Hallo Echo\n', { timeout: 30_000 });
await client.window.getByRole('button', { name: 'Trennen' }).click();
await expect(client.window.getByRole('button', { name: 'Verbinden' })).toBeVisible({ timeout: 30_000 });
await expect(output).toContainText('Verbindung getrennt');
await expect(send).toBeDisabled();
});