feat: F4.6g1 the echo server and the generic client windows

Oracle EchoWindowRun uses Java's echo server and client windows as a
person does; SaveAfterRunRun echo saves what Java keeps after the run.
The room takes setActive with a port, connect/disconnect/send, sends
both views and writes the server's port and the client's target back.
The editor's windows show Java's buttons, fields and lines; a port that
is no port is marked and not handed over (Java's button throws).
Core fix: an empty message (one empty segment with the push, as Java's
erstelleSegmente makes) counted as a repeat and never arrived.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-03 20:04:33 +00:00
co-authored by Claude Opus 5.5
parent 3dc2713f81
commit e31da62ae0
24 changed files with 1481 additions and 18 deletions
+86
View File
@@ -0,0 +1,86 @@
// 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 } 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 at = await onDevice(page, id);
await page.mouse.click(at.x, at.y);
const desktop = page.locator(`section[data-desktop="${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('.desktop-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();
});