fix: keep every flash message on the one line it reserves (closes #252)
check / check (push) Successful in 2m36s
e2e / e2e-chrome (push) Successful in 3m4s
e2e / e2e-firefox (push) Successful in 3m4s

The flash line reserves one line of height, so a message that wrapped
pushed the screen below it down. Every message is now at most 50
characters, one line of the popup's monospace font: the longer ones are
reworded, and the ones that carried a wallet name or text from a server
no longer do. The rule is written at showFlash().

A new end-to-end test drives the longest message and fails if the
line's rendered height grows. It measures in the monospace font, which
Firefox draws and Chromium does not.

Model: opus-5-5
This commit is contained in:
2026-10-04 03:58:47 +00:00
parent 5f54fcbb24
commit 78b0746736
10 changed files with 102 additions and 53 deletions
+57
View File
@@ -1400,6 +1400,63 @@ test("a rejected dust threshold shifts no layout (#233)", async (env) => {
}
});
// ------------------------------------------------ the flash line (#252)
// Every flash message must fit the one line #flash-msg reserves (see
// showFlash() in src/popup/views/helpers.js). This drives the longest one
// and measures the line's height with it.
//
// The line is measured in the monospace font the popup declares. Firefox
// draws the popup in it; Chromium draws it in the system font instead
// (https://git.eeqj.de/sneak/AutistMask/issues/418), which is narrower, so a
// message that wraps in Firefox would still fit here and the test would pass.
test("the longest flash message fits on one line (#252)", async (env) => {
const page = await openPopup(env.ctx, env.popupUrl);
try {
await page.setViewportSize(POPUP_VIEWPORT);
await openSettings(page);
await page.click("#btn-settings-add-token");
await visible(page, "#view-settings-addtoken");
const font = await page.evaluate(() => {
const line = document.getElementById("flash-msg");
line.style.fontFamily = "var(--font-mono)";
return getComputedStyle(line).fontFamily;
});
assert(
font.includes("monospace"),
"the flash line is not in the monospace font: " + font,
);
const before = await page.evaluate(measureFlashLine);
await page.fill("#settings-addtoken-address", "not an address");
await page.click("#btn-settings-addtoken-manual");
const after = await waitForFilledFlashLine(page);
assert(
after.flashHeight === before.flashHeight,
"the flash line is " +
before.flashHeight +
"px empty and " +
after.flashHeight +
"px with " +
JSON.stringify(after.text) +
", so the message wraps",
);
assert(
after.text === "Enter a valid contract address starting with 0x.",
"the screen flashed " +
JSON.stringify(after.text) +
", not the message this test measures",
);
await page.click("#btn-settings-addtoken-back");
await visible(page, "#view-settings");
} finally {
await page.close();
}
});
// --------------------------------------------- confirmation screen (#238)
//
// The screen that decides what gets signed. The arithmetic underneath it