diff --git a/README.md b/README.md
index 4caa8ce..e2f4c42 100644
--- a/README.md
+++ b/README.md
@@ -500,9 +500,11 @@ papered over:
forced by clicking Reveal and the settings gear in one page task, which a
person cannot do; the case a person can hit, the first decrypt after the popup
opens while libsodium is still loading, is not driven.
-- Approval windows open at 1280x720 whatever size the extension asks for, so
- whether an approval screen fits its window is checked in the Firefox suite
- only.
+- Approval windows open at 1280x720 whatever size the extension asks for. The
+ transaction approval is checked for sideways scrolling at 396x600 by sizing
+ the page itself, which leaves out the window's frame and the page widening its
+ window, so whether an approval screen fits its window is checked in the
+ Firefox suite only.
Any test that drives a failure path on purpose declares the `console.error` it
is about to provoke, via `errors.expect()`. That is not a mute: the declaration
diff --git a/src/popup/index.html b/src/popup/index.html
index ba3197f..b41cf9e 100644
--- a/src/popup/index.html
+++ b/src/popup/index.html
@@ -90,7 +90,7 @@
+ 396x600. -->
Enter your 12 or 24 word recovery phrase below, or
@@ -212,7 +212,7 @@
/>
diff --git a/tests/e2e/run.js b/tests/e2e/run.js
index 2fdd9ad..0efe46c 100644
--- a/tests/e2e/run.js
+++ b/tests/e2e/run.js
@@ -60,6 +60,14 @@ const TEST_TIMEOUT_MS = 120000;
// trailing drain in main().
const TRAILING_WATCH_MS = 1500;
+// The popup's size, as README gives it: `body` in src/popup/styles/main.css
+// is 396px wide, and src/background/index.js opens an approval window at
+// the same 396x600. Pages in this context otherwise get Playwright's
+// 1280x720 default, where the page never scrolls sideways and a button
+// below the popup's fold is still on screen, so a layout measured there
+// passes whatever the page does.
+const POPUP_VIEWPORT = { width: 396, height: 600 };
+
const tests = [];
function test(name, fn) {
@@ -1885,12 +1893,6 @@ test("a network switch in Settings shows and removes the testnet banner at once
// ------------------------------------------------ dust threshold (#233)
-// The popup size README documents the UI as designed for. Pages in this
-// context otherwise get Playwright's 1280x720 default, at which the flash
-// line has room for any plausible message and never wraps — measuring
-// there would pass for every string and prove nothing.
-const POPUP_VIEWPORT = { width: 360, height: 600 };
-
// Everything below the flash line that must not move when it fills, plus
// the height of the line itself. Runs in the page.
//
@@ -2139,7 +2141,7 @@ test("a password error moves nothing on any screen (#297)", async (env) => {
// ------------------------------------------ add wallet Import button (#493)
-// At 360x600 the add wallet screen's Import button already starts near the
+// At 396x600 the add wallet screen's Import button already starts near the
// bottom of the popup, so its password error line sits beside the button
// rather than above it. Measures the button and the line empty and again
// filled with the longest error addWallet.js puts there. Runs in the page.
@@ -3431,10 +3433,14 @@ test("six failed receipt lookups in a row end on the unreachable-network message
// timeout ("';
// What a correctly escaped and capped render of it reads as: the first
// MAX_SYMBOL_LENGTH-1 characters and an ellipsis. Spelled out rather than
@@ -4566,6 +4572,10 @@ test("eth_sendTransaction signs the approved transaction and broadcasts it (#183
JSON.stringify(screen.data),
);
+ // Headless Chromium opens the approval window at 1280x720 whatever size
+ // the extension asks for, and at that width the page can never scroll
+ // sideways. So it is measured at the size the window is opened at.
+ await popup.setViewportSize(POPUP_VIEWPORT);
await assertAddressesFit(popup, "the dApp transaction prompt");
const broadcastBefore = env.routeOpts.broadcastTransactions.length;