The Page menu, Help, and the manual from the tooltips

The page and view commands are in a menu under "Page", with grey
titles over the display and size sections.  Help, at the far right,
shows a note for now; with Ctrl (Command on a Mac) held it shows the
explanations of every command in one text, alphabetical, wrapped at
80 columns, a shared name prefixed by its context.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
ackandClaude Fable 5.1 committed 2026-10-14 01:07:53 +02:00
1 parent 8ecf3e94a6
commit 35c4f434f3
5 files changed
+419 -55

No files matched your search

+103
View File
@@ -1484,6 +1484,109 @@ class EndToEndTest(unittest.TestCase):
choose("arrange")
self.assertEqual(cues(), ["text"])
def test_page_menu_and_help(self):
"""Andy, 2026-10-14: the page and view commands are in a Page menu,
a popup of Kokkoja's own under the button, closed by a press on an
item, elsewhere, or Escape; Help shows a note for now; one popup
at a time."""
firefox = self.firefox
firefox.go(self.address("Late"))
self.enter_name("Menuist", "start_session")
self.wait_until(lambda s: s["page"]["number"] == 1, "the page")
hidden = lambda id: firefox.run(f"return document.getElementById('{id}').hidden;")
click = lambda id: firefox.run(f"document.getElementById('{id}').click();")
box = lambda id: firefox.run(f"const b = document.getElementById('{id}').getBoundingClientRect(); return [b.left, b.top, b.right, b.bottom];")
self.assertTrue(hidden("page_menu"))
self.assertIsNone(firefox.run("return document.querySelector('.page_view');"), "the middle group is gone")
# The Page button is the first of the right-hand group; Help the last of all.
self.assertEqual(firefox.run("return [...document.querySelectorAll('.toolbar button')].at(-1).id;"), "help")
self.assertEqual(firefox.run("return document.querySelector('.toolbar_right button').id;"), "page_menu_button")
# Open: below the button, left edges aligned, within the window.
click("page_menu_button")
self.assertFalse(hidden("page_menu"))
self.assertEqual(firefox.run("return document.getElementById('page_menu_button').getAttribute('aria-expanded');"), "true")
button, menu = box("page_menu_button"), box("page_menu")
self.assertAlmostEqual(menu[0], button[0], delta=1)
self.assertGreater(menu[1], button[3])
self.assertLess(menu[2], firefox.run("return window.innerWidth;"))
items = firefox.run("return [...document.querySelectorAll('#page_menu .menu_item')].filter((e) => !e.hidden).map((e) => e.textContent.trim());")
self.assertEqual(items, ["Fit to the window", "A4 scale", "Expand to the window",
"Shrink to the contents", "Extend the page while writing"])
# Two grey titles, over the first two sections, in the muted colour.
self.assertEqual(firefox.run("return [...document.querySelectorAll('#page_menu .menu_title')].map((e) => e.textContent);"),
["Change the display of the page", "Change the size of the page"])
self.assertEqual(firefox.run("const t = document.querySelector('#page_menu .menu_title'); return [getComputedStyle(t).color, getComputedStyle(t).fontStyle];"),
firefox.run("return [getComputedStyle(document.getElementById('undo')).color, 'normal'];"))
# An item's press runs it and closes the menu.
click("zoom_sheet")
self.assertTrue(hidden("page_menu"))
# The checkbox item toggles Extend and closes too.
click("page_menu_button")
self.assertTrue(firefox.run("return document.getElementById('extend').checked;"))
click("extend")
self.assertFalse(firefox.run("return document.getElementById('extend').checked;"))
self.assertTrue(hidden("page_menu"))
click("extend") # back on, for the tests that follow
# Escape closes; so does a press elsewhere.
click("page_menu_button")
self.assertFalse(hidden("page_menu"))
firefox.chord("\ue00c")
self.assertTrue(hidden("page_menu"))
click("page_menu_button")
firefox.run("document.getElementById('page').dispatchEvent(new PointerEvent('pointerdown', {bubbles: true}));")
self.assertTrue(hidden("page_menu"))
# Help: a note for now; opening it closes the menu, and the reverse.
click("page_menu_button")
click("help")
self.assertFalse(hidden("help_popup"))
self.assertTrue(hidden("page_menu"))
# At the far right, the note's right edge aligns with the button's, inside the window.
help_button, note = box("help"), box("help_popup")
self.assertAlmostEqual(note[2], help_button[2], delta=1)
self.assertLess(note[2], firefox.run("return window.innerWidth;"))
self.assertEqual(firefox.run("return document.getElementById('help_popup').textContent.trim();"), "Help is coming!")
click("page_menu_button")
self.assertTrue(hidden("help_popup"))
self.assertFalse(hidden("page_menu"))
firefox.chord("\ue00c")
# Ctrl-click on Help: the tooltips of every command as one text, in
# a window: the title, then each control in alphabetical order,
# its name on a line, its explanation wrapped at 80 columns, and
# a blank line after.
firefox.run("document.getElementById('help').dispatchEvent(new MouseEvent('click', {ctrlKey: true, bubbles: true}));")
self.assertTrue(firefox.run("return document.getElementById('manual_dialog').open;"))
self.assertTrue(hidden("help_popup"), "the note did not open as well")
manual = firefox.run("return document.getElementById('manual_text').textContent;")
self.assertTrue(manual.startswith("User interface actions\n\n"))
blocks = manual.split("\n\n")[1:]
names = [block.split("\n")[0] for block in blocks if block]
self.assertEqual(names, sorted(names, key=str.casefold), "alphabetical")
self.assertIn("Pen", names)
self.assertIn("Color", names) # the swatches as one entry
self.assertIn("Line width", names) # the widths as one entry
self.assertIn("Notebook for the pages of this session", names)
self.assertIn("QR code", names)
# A name two controls share gets each one's context: the nearest heading above it.
self.assertIn("Invitation: Copy", names)
self.assertIn("Log: Copy", names)
self.assertNotIn("Copy", names)
self.assertEqual(len(names), len(set(names)), "no two entries of one name")
self.assertIn("\nPen\nWrite on the page. Only your own writing can be erased.\n", manual)
self.assertIn("\nFit to the window\nShow the whole page in the window.", manual)
self.assertTrue(all(len(line) <= 80 for line in manual.split("\n")), "wrapped at 80")
self.assertTrue(any(len(line) > 60 for line in manual.split("\n")), "filled, not one word a line")
# Every tooltip is in it; those that differ only by a number (the
# line widths) as one entry, so the numbers are set aside.
helps = firefox.run("return [...document.querySelectorAll('[data-help]')].filter((e) => !e.closest('#manual_dialog')).map((e) => e.getAttribute('data-help'));")
unwrapped = re.sub(r"\d+(?:\.\d+)?", "#", manual.replace("\n", " "))
for help in set(helps):
self.assertIn(re.sub(r"\d+(?:\.\d+)?", "#", help), unwrapped, help[:40])
firefox.run("document.getElementById('manual_close').click();")
self.assertFalse(firefox.run("return document.getElementById('manual_dialog').open;"))
def test_text_being_typed_stays_on_the_page_left(self):
"""Andy, 2026-10-06: a guest was typing when the host pressed New,
and the text reappeared on the new page."""