fix: a popup reload mid-refresh no longer logs the requests it cancels (closes #218)
Chrome cancels a closing popup's open requests just after pagehide, and in the page a cancelled fetch() fails with the same "Failed to fetch" as a server that cannot be reached. The home screen's transaction list and the balance refresh logged an error for each, and the e2e suite failed on them. The popup now aborts an AbortController on pagehide, and those failure reports check its signal first. End-to-end tests reload the popup with Blockscout held and require nothing logged, and fail the transaction list for real and require the failure reported; a unit test covers the balance refresh. The address and token screens and the new-wallet address scan are #475. Model: opus-5-5
This commit is contained in:
+63
-4
@@ -696,6 +696,62 @@ test("the token contract row links to the explorer's token page (#151)", async (
|
||||
);
|
||||
});
|
||||
|
||||
// ------------------------------------------- reload mid-refresh (#218)
|
||||
//
|
||||
// Reloading or closing the popup makes Chrome cancel the requests it still has
|
||||
// open, and in the page a cancelled fetch() fails with the same "Failed to
|
||||
// fetch" as a server that cannot be reached. Here rather than straight after
|
||||
// wallet creation because a reload also cancels the address scan that follows
|
||||
// it, which still logs (#475).
|
||||
|
||||
// Blockscout is held, so the home screen's transaction list and token balances
|
||||
// cannot have been answered when the popup reloads. The assertion is the
|
||||
// harness's own: a console.error from the page being reloaded fails this test.
|
||||
test("reloading the popup mid-refresh reports no failure (#218)", async (env) => {
|
||||
await goHome(env.page);
|
||||
env.routeOpts.holdBlockscout = true;
|
||||
try {
|
||||
const inFlight = Promise.all([
|
||||
env.page.waitForRequest((r) => r.url().endsWith("/transactions")),
|
||||
env.page.waitForRequest((r) => r.url().endsWith("/token-balances")),
|
||||
]);
|
||||
await env.page.reload();
|
||||
await inFlight;
|
||||
await env.page.reload();
|
||||
} finally {
|
||||
env.routeOpts.holdBlockscout = false;
|
||||
}
|
||||
await visible(env.page, "#view-main");
|
||||
});
|
||||
|
||||
// The same "Failed to fetch" from a server that really cannot be reached is
|
||||
// still reported, so it still fails the run unless a test declares it. Chrome
|
||||
// reports the failed request itself as well, which a cancelled one does not.
|
||||
test("a transaction list that cannot be fetched is still reported (#218)", async (env) => {
|
||||
env.errors.expect(
|
||||
"loadHomeTxs failed",
|
||||
/loadHomeTxs failed: Failed to fetch/,
|
||||
);
|
||||
env.errors.expect(
|
||||
"Chrome's report of the failed request",
|
||||
/Failed to load resource: net::ERR_FAILED/,
|
||||
);
|
||||
env.routeOpts.failTransactionList = true;
|
||||
try {
|
||||
// Drawn again by the next ten-second refresh.
|
||||
await env.page.waitForFunction(
|
||||
() =>
|
||||
document
|
||||
.getElementById("home-tx-list")
|
||||
.textContent.includes("Failed to load transactions."),
|
||||
null,
|
||||
{ timeout: 15000 },
|
||||
);
|
||||
} finally {
|
||||
env.routeOpts.failTransactionList = false;
|
||||
}
|
||||
});
|
||||
|
||||
// -------------------------------------------- recovery phrase (#161)
|
||||
|
||||
// The gear toggles, so pressing it while Settings is already up leaves it.
|
||||
@@ -2107,10 +2163,9 @@ function quantity(wei) {
|
||||
|
||||
// Wait on the main view until a changed balance fixture has been picked up.
|
||||
//
|
||||
// Deliberately not a reload: the popup re-refreshes on a 10-second timer by
|
||||
// itself, and reloading aborts whatever fetch the home screen has open at
|
||||
// that instant, which the extension reports through log.errorf and the
|
||||
// harness — correctly — fails the run on.
|
||||
// Not a reload: the popup re-refreshes on a 10-second timer by itself, and a
|
||||
// reload on the address screen still logs the transaction list it cancels
|
||||
// (#475).
|
||||
//
|
||||
// It also deliberately settles on MAIN rather than on the address screen.
|
||||
// The address screen builds the send screen's token dropdown once, from the
|
||||
@@ -4470,6 +4525,10 @@ async function main() {
|
||||
ethBalanceWei: null,
|
||||
failGasEstimate: false,
|
||||
holdGasEstimate: false,
|
||||
// Whether Blockscout requests are held unanswered, and whether an
|
||||
// address's transaction list fails as a network error (#218).
|
||||
holdBlockscout: false,
|
||||
failTransactionList: false,
|
||||
// What decimals() answers for the stub token, when it is to answer
|
||||
// something other than the value the same fixture reports through
|
||||
// Blockscout. The token that lies about its scale (#305).
|
||||
|
||||
Reference in New Issue
Block a user