Compare commits
1
Commits
70f0feee28
...
df89f20099
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df89f20099 |
@@ -619,14 +619,13 @@ The jobs **report, they do not gate.** A failure is a red mark against the
|
|||||||
commit that a reviewer has to account for, not a hard block: whether a check
|
commit that a reviewer has to account for, not a hard block: whether a check
|
||||||
blocks a merge is Gitea branch protection, which this repo does not configure.
|
blocks a merge is Gitea branch protection, which this repo does not configure.
|
||||||
|
|
||||||
That is not only a statement about configuration. The Chrome suite is
|
That is not only a statement about configuration. One report of the Chrome suite
|
||||||
**measurably flaky under load** — two of six runs of unmutated code on a busy
|
**failing under load** is still open:
|
||||||
machine lost the approval popup out from under the dApp signing wait, always in
|
[#290](https://git.eeqj.de/sneak/AutistMask/issues/290) records runs on a busy
|
||||||
the `#183` section, tracked as
|
machine failing with `the extension opened no approval window within 30000ms`.
|
||||||
[#287](https://git.eeqj.de/sneak/AutistMask/issues/287). So a red `e2e-chrome`
|
So a red `e2e-chrome` has to be read before it is believed, and that report is
|
||||||
has to be read before it is believed, and that flake is the blocker to ever
|
the blocker to ever making this a required check. Do not answer it with a retry
|
||||||
making this a required check. Do not answer it with a retry wrapper: a suite
|
wrapper: a suite that reruns until it is green stops being evidence.
|
||||||
that reruns until it is green stops being evidence.
|
|
||||||
|
|
||||||
Nothing in either job can pass vacuously. There is no `continue-on-error` and no
|
Nothing in either job can pass vacuously. There is no `continue-on-error` and no
|
||||||
`|| true`; both scripts exit non-zero when docker is missing, when the image
|
`|| true`; both scripts exit non-zero when docker is missing, when the image
|
||||||
|
|||||||
@@ -45,6 +45,17 @@ but the review is broader than any of them.
|
|||||||
|
|
||||||
# Completed Steps
|
# Completed Steps
|
||||||
|
|
||||||
|
- 2026-10-05: The extension no longer opens a window for a site-connection
|
||||||
|
prompt already answered
|
||||||
|
([#287](https://git.eeqj.de/sneak/AutistMask/issues/287)). When the prompt was
|
||||||
|
decided before the toolbar popup raised for it had loaded, that popup was torn
|
||||||
|
down, `chrome.action.openPopup()` rejected, and the background opened its
|
||||||
|
fallback window for the answered approval and then removed it. In the Chrome
|
||||||
|
end-to-end suite the next test could take that window for its own prompt and
|
||||||
|
lose it under its wait. `openApprovalWindow()` now opens nothing for an
|
||||||
|
approval that is no longer pending. The blocklist test's Reject, whose window
|
||||||
|
closes itself, is clicked as the other site Reject is, with the click
|
||||||
|
witnessed.
|
||||||
- 2026-10-04: A popup boot in the tests loads transactions without failing
|
- 2026-10-04: A popup boot in the tests loads transactions without failing
|
||||||
([#429](https://git.eeqj.de/sneak/AutistMask/issues/429)). The stand-in for
|
([#429](https://git.eeqj.de/sneak/AutistMask/issues/429)). The stand-in for
|
||||||
`filterTransactions` in `tests/support/popupBoot.js` returned a bare list,
|
`filterTransactions` in `tests/support/popupBoot.js` returned a bare list,
|
||||||
|
|||||||
@@ -413,7 +413,7 @@ function releaseApproval(approval) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open approval in a separate popup window.
|
// Open approval in a separate popup window, unless it is no longer pending.
|
||||||
// This is the primary mechanism for tx/sign approvals (triggered programmatically,
|
// This is the primary mechanism for tx/sign approvals (triggered programmatically,
|
||||||
// not from a user gesture) and the fallback for site-connection approvals.
|
// not from a user gesture) and the fallback for site-connection approvals.
|
||||||
// Never rejects. Its callers raise it from inside a Promise executor and drop
|
// Never rejects. Its callers raise it from inside a Promise executor and drop
|
||||||
@@ -446,6 +446,10 @@ async function openApprovalWindow(id) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Already answered: a site-connection prompt decided before the toolbar
|
||||||
|
// popup raised for it had loaded, whose openPopup() rejects only now.
|
||||||
|
if (!pendingApprovals[id]) return;
|
||||||
|
|
||||||
let win = null;
|
let win = null;
|
||||||
try {
|
try {
|
||||||
win = await windowsCreate(opts);
|
win = await windowsCreate(opts);
|
||||||
|
|||||||
@@ -2235,6 +2235,27 @@ describe("a site connection decided as the popup closes", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The prompt is decided before the toolbar popup raised for it has
|
||||||
|
// loaded; that popup is torn down and openPopup() rejects only after.
|
||||||
|
test("a toolbar prompt already decided opens no window when openPopup() rejects", async () => {
|
||||||
|
const bg = loadBackground({ actionPopup: true });
|
||||||
|
const opening = deferred();
|
||||||
|
bg.openPopup.mockImplementation(() => opening.promise);
|
||||||
|
const pending = bg.requestSite();
|
||||||
|
await settle();
|
||||||
|
|
||||||
|
const port = bg.connectApproval(pending.id());
|
||||||
|
port.decide(true, false);
|
||||||
|
port.disconnect();
|
||||||
|
await settle();
|
||||||
|
expect(pending.result()).toEqual({ result: [signer.address] });
|
||||||
|
|
||||||
|
opening.reject(new Error("the toolbar popup closed before it loaded"));
|
||||||
|
await settle();
|
||||||
|
|
||||||
|
expect(bg.created).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
// The port carries a decision now, so it carries the sender check the
|
// The port carries a decision now, so it carries the sender check the
|
||||||
// one-off message used to carry. A content script that guessed an
|
// one-off message used to carry. A content script that guessed an
|
||||||
// approval id must not be able to connect the site it is running on.
|
// approval id must not be able to connect the site it is running on.
|
||||||
|
|||||||
+4
-2
@@ -2738,7 +2738,7 @@ async function closeApprovalPages(ctx) {
|
|||||||
// #btn-reject on the site prompt — NOT self-proving. A page that went away
|
// #btn-reject on the site prompt — NOT self-proving. A page that went away
|
||||||
// without the click landing disconnects the approval port, the background
|
// without the click landing disconnects the approval port, the background
|
||||||
// settles that as 4001, and 4001 is exactly what assertUserRejection
|
// settles that as 4001, and 4001 is exactly what assertUserRejection
|
||||||
// accepts. That call site arms the click trace below and asserts it.
|
// accepts. Both call sites arm the click trace below and assert it.
|
||||||
//
|
//
|
||||||
// A button that is missing or unclickable raises a different error, which is
|
// A button that is missing or unclickable raises a different error, which is
|
||||||
// rethrown.
|
// rethrown.
|
||||||
@@ -3124,7 +3124,9 @@ test("a connect request from a blocklisted site is flagged (#219)", async (env)
|
|||||||
// Not remembered: a remembered decision for this origin would
|
// Not remembered: a remembered decision for this origin would
|
||||||
// outlive the test.
|
// outlive the test.
|
||||||
await popup.uncheck("#approve-remember");
|
await popup.uncheck("#approve-remember");
|
||||||
await popup.click("#btn-reject");
|
await armClickTrace(env, popup, "#btn-reject");
|
||||||
|
await clickAndClose(popup, "#btn-reject");
|
||||||
|
await assertClickLanded(env, "#btn-reject");
|
||||||
|
|
||||||
await assertUserRejection(
|
await assertUserRejection(
|
||||||
phishingDapp,
|
phishingDapp,
|
||||||
|
|||||||
Reference in New Issue
Block a user