feat(editor): a tap opens a device's menu in the simulation; undo and redo drawn

In the simulation a tap on a device chooses it and opens its menu where
the finger was; the three-dot button is gone there, the long press stays.
The context menu moves in from the surface's edge instead of being cut off.
Undo and redo show drawn arrows: the characters took whatever font the
device had and looked squashed on an iPad (the buttons measured 44 x 44 at
every width; the size was not the cause).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-11 08:04:57 +00:00
co-authored by Claude Opus 5.5
parent ae10ee6c31
commit 15498a2bed
8 changed files with 108 additions and 42 deletions
+19 -3
View File
@@ -4,7 +4,8 @@
// anew, set up and pinged across, without a mouse —; two fingers zoom the
// surface and never the page (M7); every action without a right click
// (long press, the three-dot button, the documentation's menu); every
// target at least 44 px, nothing beyond the screen's edge.
// target at least 44 px, nothing beyond the screen's edge; in the simulation
// a tap opens a device's menu.
import { expect, test, type Page } from '@playwright/test';
import { drawing, onDevice, openEditor, scaleOf, serveEditor } from './editorPage.js';
@@ -104,9 +105,8 @@ test('builds FILIUS\' „zwei Rechnernetze“ by finger and pings across (the ac
// The simulation; the command line installed on the first computer; a ping across the router.
await page.getByRole('button', { name: 'Wechselt in den Aktionsmodus' }).tap();
await expect(page.locator('svg.filius-canvas')).toHaveAttribute('data-mode', 'simulation');
// A tap chooses the computer; its three-dot button opens its menu, „Desktop anzeigen“ its desktop as the sheet.
// A tap opens the computer's menu, „Desktop anzeigen“ its desktop as the sheet.
await finger.tap(await onDevice(page, pcA));
await page.getByRole('button', { name: 'Aktionen' }).tap();
await page.getByRole('menuitem', { name: 'Desktop anzeigen' }).tap();
const desktop = page.locator(`section[data-desktop="${pcA}"]`);
await desktop.locator('[data-program="installation"]').tap();
@@ -332,3 +332,19 @@ test('gives every target 44 px at least and keeps the editor within the screen',
expect(await fits()).toBe(true);
expect(await small(targets)).toEqual([]);
});
test('draws undo and redo as arrows of their own, in the middle of their buttons, not as a character of whatever font the device has', async ({ page }) => {
await openEditor(page, server.base, 'zwei_rechnernetze_komplett.fls');
for (const name of ['Rückgängig', 'Wiederholen']) {
const button = page.getByRole('button', { name, exact: true });
await expect(button).toHaveText('');
const [outer, arrow] = [(await button.boundingBox())!, (await button.locator('svg').boundingBox())!];
expect([arrow.width, arrow.height]).toEqual([20, 20]);
expect(Math.abs(arrow.x + arrow.width / 2 - (outer.x + outer.width / 2))).toBeLessThanOrEqual(0.5);
expect(Math.abs(arrow.y + arrow.height / 2 - (outer.y + outer.height / 2))).toBeLessThanOrEqual(0.5);
expect(Math.min(outer.width, outer.height)).toBeGreaterThanOrEqual(44);
}
// Redo is undo's mirror image.
const paths = await page.locator('.editor-toolbar svg g').evaluateAll((groups) => groups.map((group) => group.getAttribute('transform')));
expect(paths).toEqual([null, 'matrix(-1 0 0 1 24 0)']);
});