fix: approval windows open as wide as the page (closes #518)
The approval window was opened 360 pixels wide while the page is 396, so it scrolled sideways and cut off the Reject button. It now opens at 396. The browser counts the window's frame in that width, and a tall screen gives some of it to a vertical scrollbar, so once the approval's screen is up the page widens its own window by however far it would scroll sideways, times the page's zoom. The toolbar popup's window is left alone. The Firefox suite checks that the sign prompt does not scroll sideways; the Chrome suite cannot, as its approval windows open at 1280x720 whatever size is asked. README's Visual Style line now gives the page's real width. Model: opus-5-5
This commit is contained in:
@@ -45,3 +45,77 @@ test("the approval window shows no screen until the background describes the app
|
||||
expect(env.visibleViews()).toEqual(["approve-network"]);
|
||||
expect(env.pageErrors).toEqual([]);
|
||||
});
|
||||
|
||||
// The background opens the approval window as wide as the page, but the
|
||||
// browser counts the window's frame in that width, and a screen taller than
|
||||
// the window takes a vertical scrollbar out of it too
|
||||
// (https://git.eeqj.de/sneak/AutistMask/issues/518). The browser suites run
|
||||
// without frames and at 100% zoom, so the widening is checked here.
|
||||
function windowsStub(type) {
|
||||
const updates = [];
|
||||
return {
|
||||
updates,
|
||||
getCurrent: (done) => done({ id: 7, type, width: 396 }),
|
||||
update: (id, info, done) => {
|
||||
updates.push({ id, info });
|
||||
done({});
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// An approval window at 150% zoom, whose background holds its answer until
|
||||
// the test gives it.
|
||||
async function bootZoomedApprovalWindow(windows) {
|
||||
let answer = null;
|
||||
const env = await bootPopup(unversionedValidProfile(), {
|
||||
search: "?approval=approval-1",
|
||||
runtime: {
|
||||
connect: () => ({ postMessage: () => {} }),
|
||||
sendMessage: (msg, reply) => {
|
||||
if (msg.type === "AUTISTMASK_GET_APPROVAL") answer = reply;
|
||||
},
|
||||
},
|
||||
windows,
|
||||
tabs: { getZoom: (done) => done(1.5) },
|
||||
// At 150% a window 396 screen pixels wide shows 264 page pixels.
|
||||
documentElement: { scrollWidth: 396, clientWidth: 264 },
|
||||
});
|
||||
return { env, answer };
|
||||
}
|
||||
|
||||
test("at 150% zoom the approval window widens by what its screen lacks, scrollbar included", async () => {
|
||||
const windows = windowsStub("popup");
|
||||
const { env, answer } = await bootZoomedApprovalWindow(windows);
|
||||
|
||||
// Not before there is a screen to fit.
|
||||
expect(windows.updates).toEqual([]);
|
||||
|
||||
// The screen is taller than the window, so once it is up a vertical
|
||||
// scrollbar takes 15 screen pixels, 10 page pixels at 150%.
|
||||
env.document.documentElement.clientWidth = 254;
|
||||
answer({
|
||||
type: "network",
|
||||
origin: "https://dapp.example",
|
||||
currentNetworkId: "mainnet",
|
||||
requestedNetworkId: "sepolia",
|
||||
isPhishingDomain: false,
|
||||
});
|
||||
await settle();
|
||||
|
||||
// 396 - 254 = 142 page pixels short, which at 150% is 213 screen pixels.
|
||||
expect(env.visibleViews()).toEqual(["approve-network"]);
|
||||
expect(windows.updates).toEqual([{ id: 7, info: { width: 609 } }]);
|
||||
expect(env.pageErrors).toEqual([]);
|
||||
});
|
||||
|
||||
test("a connection prompt in the toolbar popup leaves the browser window alone", async () => {
|
||||
const windows = windowsStub("normal");
|
||||
const { env, answer } = await bootZoomedApprovalWindow(windows);
|
||||
|
||||
answer({ origin: "https://dapp.example", isPhishingDomain: false });
|
||||
await settle();
|
||||
|
||||
expect(env.visibleViews()).toEqual(["approve-site"]);
|
||||
expect(windows.updates).toEqual([]);
|
||||
expect(env.pageErrors).toEqual([]);
|
||||
});
|
||||
|
||||
@@ -2854,7 +2854,7 @@ describe("where an approval window opens", () => {
|
||||
await settle();
|
||||
|
||||
expect(bg.created).toHaveLength(1);
|
||||
expect(bg.created[0]).toMatchObject({ left: 460, top: 60 });
|
||||
expect(bg.created[0]).toMatchObject({ left: 442, top: 60 });
|
||||
});
|
||||
|
||||
test("not centred on an approval window the user was last in", async () => {
|
||||
@@ -2871,7 +2871,7 @@ describe("where an approval window opens", () => {
|
||||
bg.requestSign();
|
||||
await settle();
|
||||
|
||||
// Centred, it would be at left 900, the position the browser refused.
|
||||
// Centred, it would be at left 882, the position the browser refused.
|
||||
expect(bg.created).toHaveLength(1);
|
||||
expect(bg.created[0].left).toBeUndefined();
|
||||
expect(bg.created[0].top).toBeUndefined();
|
||||
@@ -2893,7 +2893,7 @@ describe("where an approval window opens", () => {
|
||||
await settle();
|
||||
|
||||
expect(bg.created).toHaveLength(2);
|
||||
expect(bg.created[0]).toMatchObject({ left: 1520, top: 750 });
|
||||
expect(bg.created[0]).toMatchObject({ left: 1502, top: 750 });
|
||||
expect(bg.created[1].left).toBeUndefined();
|
||||
expect(bg.created[1].top).toBeUndefined();
|
||||
|
||||
|
||||
@@ -640,6 +640,17 @@ step(
|
||||
await d.switchToWindow(popup);
|
||||
await d.waitVisible("#view-approve-sign");
|
||||
|
||||
// The window is opened as wide as the page, and widened once the
|
||||
// screen is up if it still scrolls sideways
|
||||
// (https://git.eeqj.de/sneak/AutistMask/issues/518). This suite is
|
||||
// where that is checked: the Chrome suite's approval windows open at
|
||||
// 1280x720 whatever width the extension asks for.
|
||||
await d.waitFor(
|
||||
"the sign prompt to fit its window without scrolling sideways",
|
||||
"return document.documentElement.scrollWidth <=" +
|
||||
" document.documentElement.clientWidth;",
|
||||
);
|
||||
|
||||
const screen = await d.execute(
|
||||
`return {
|
||||
origin: document.getElementById("approve-sign-origin").textContent,
|
||||
|
||||
@@ -242,6 +242,13 @@ async function settle() {
|
||||
* "?approval=" and an id for the popup opened as an approval window.
|
||||
* @param {object} [options.runtime] members of chrome.runtime that replace the
|
||||
* stub's own, for a test that has to answer the background's messages.
|
||||
* @param {object} [options.windows] chrome.windows, for a test of the approval
|
||||
* window resizing itself.
|
||||
* @param {object} [options.tabs] chrome.tabs, for the same test: the page's
|
||||
* zoom.
|
||||
* @param {object} [options.documentElement] members of document.documentElement
|
||||
* that replace the stub's own: scrollWidth and clientWidth, which are equal
|
||||
* unless a test says otherwise, so the page does not scroll sideways.
|
||||
* @returns {Promise<object>} handles onto the booted page.
|
||||
*/
|
||||
async function bootPopup(stored, options) {
|
||||
@@ -277,6 +284,11 @@ async function bootPopup(stored, options) {
|
||||
(options && options.storage) ||
|
||||
makeStorageStub(stored === undefined ? {} : { autistmask: stored });
|
||||
const document = makeDocument(POPUP_HTML);
|
||||
Object.assign(
|
||||
document.documentElement,
|
||||
{ scrollWidth: 396, clientWidth: 396 },
|
||||
options && options.documentElement,
|
||||
);
|
||||
const reloads = [];
|
||||
|
||||
globalThis.chrome = {
|
||||
@@ -287,6 +299,8 @@ async function bootPopup(stored, options) {
|
||||
onMessage: { addListener: () => {} },
|
||||
...(options && options.runtime),
|
||||
},
|
||||
windows: options && options.windows,
|
||||
tabs: options && options.tabs,
|
||||
};
|
||||
globalThis.document = document;
|
||||
globalThis.window = {
|
||||
|
||||
Reference in New Issue
Block a user