fix: the address and token screens and the address scan no longer log requests a popup reload cancels (closes #475)
The transaction lists on the address and token screens, the address scan after a wallet is created, and the endpoint checks in Settings now check the signal the popup aborts on pagehide before reporting a failed request, as the home screen and the balance refresh already do. scanForAddresses() takes the signal ahead of its gap limit. End-to-end tests reload the popup on the address screen with Blockscout held, and during the address scan with its requests held. Jest tests show the transaction lists, the scan and the Settings checks report a real failure and stay silent once the popup has closed. The transaction detail and confirmation screens are left out: they do not keep the popup context. Model: opus-5-5
This commit is contained in:
+11
-6
@@ -420,12 +420,12 @@ const HOLD_MAX_MS = 30000;
|
||||
|
||||
// Hold a reply open for as long as the test asks: until opts[name] is false.
|
||||
//
|
||||
// The switch (holdGasEstimate or holdBlockscout) is read here rather than
|
||||
// captured, so a test flips it on the same options object the route was
|
||||
// registered with — the same pattern as seedTokenTransfer. This is the only way
|
||||
// to observe a screen while its request is genuinely in flight; sampling the
|
||||
// screen and hoping to win a race against the network would assert nothing on
|
||||
// a slow machine.
|
||||
// The switch (holdGasEstimate, holdTransactionCount or holdBlockscout) is read
|
||||
// here rather than captured, so a test flips it on the same options object the
|
||||
// route was registered with — the same pattern as seedTokenTransfer. This is
|
||||
// the only way to observe a screen while its request is genuinely in flight;
|
||||
// sampling the screen and hoping to win a race against the network would
|
||||
// assert nothing on a slow machine.
|
||||
//
|
||||
// It never gives up quietly. A hold that outlives the bound is reported like
|
||||
// any other harness fault, because a "pending" state that stopped being
|
||||
@@ -560,6 +560,9 @@ async function handleRpc(route, postData, opts, report) {
|
||||
if (batch.some((req) => req.method === "eth_estimateGas")) {
|
||||
await awaitRelease(opts, "holdGasEstimate", report);
|
||||
}
|
||||
if (batch.some((req) => req.method === "eth_getTransactionCount")) {
|
||||
await awaitRelease(opts, "holdTransactionCount", report);
|
||||
}
|
||||
|
||||
const replies = batch.map((req) => rpcReply(req, opts, report));
|
||||
return jsonResponse(route, Array.isArray(payload) ? replies : replies[0]);
|
||||
@@ -614,6 +617,8 @@ function traceEnabled(raw) {
|
||||
* node-side refusal.
|
||||
* @param {boolean} [opts.holdGasEstimate] hold every batch containing an
|
||||
* eth_estimateGas until this is cleared again.
|
||||
* @param {boolean} [opts.holdTransactionCount] hold every batch containing an
|
||||
* eth_getTransactionCount until this is cleared again.
|
||||
* @param {boolean} [opts.holdBlockscout] hold every Blockscout request until
|
||||
* this is cleared again.
|
||||
* @param {boolean} [opts.failTransactionList] fail every request for an
|
||||
|
||||
+47
-8
@@ -249,8 +249,23 @@ test("the exact confirmation phrase erases the record and reloads into Welcome (
|
||||
}
|
||||
});
|
||||
|
||||
test("wallet creation through the UI reaches the main view", async (env) => {
|
||||
env.phrase = await createWallet(env.page);
|
||||
// The address scan that follows creating the wallet is held, so the popup
|
||||
// reloads while it is in flight. As for the reloads mid-refresh further down,
|
||||
// the assertion for that is the harness's own: a console.error from the page
|
||||
// being reloaded fails this test (#475).
|
||||
test("wallet creation through the UI reaches the main view, and reloading mid-scan reports no failure (#475)", async (env) => {
|
||||
env.routeOpts.holdTransactionCount = true;
|
||||
try {
|
||||
const scanning = env.page.waitForRequest((r) =>
|
||||
(r.postData() || "").includes("eth_getTransactionCount"),
|
||||
);
|
||||
env.phrase = await createWallet(env.page);
|
||||
await scanning;
|
||||
await env.page.reload();
|
||||
} finally {
|
||||
env.routeOpts.holdTransactionCount = false;
|
||||
}
|
||||
await visible(env.page, "#view-main");
|
||||
assert(
|
||||
env.phrase.split(/\s+/).length >= 12,
|
||||
"wallet creation did not yield a recovery phrase",
|
||||
@@ -700,9 +715,8 @@ test("the token contract row links to the explorer's token page (#151)", async (
|
||||
//
|
||||
// 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).
|
||||
// fetch" as a server that cannot be reached. The reload during the address
|
||||
// scan that follows creating a wallet is in the wallet creation test (#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
|
||||
@@ -752,6 +766,30 @@ test("a transaction list that cannot be fetched is still reported (#218)", async
|
||||
}
|
||||
});
|
||||
|
||||
// The address screen's transaction list, held the same way. The popup reopens
|
||||
// on the address screen, which asks for its list as it is drawn, so once the
|
||||
// screen is up its request is in flight (#475).
|
||||
test("reloading the popup on the address screen reports no failure (#475)", async (env) => {
|
||||
await openAddressDetail(env.page);
|
||||
await waitForPersisted(
|
||||
env.page,
|
||||
"currentView",
|
||||
"address",
|
||||
"before reloading the popup",
|
||||
);
|
||||
env.routeOpts.holdBlockscout = true;
|
||||
try {
|
||||
await env.page.reload();
|
||||
await visible(env.page, "#view-address");
|
||||
await env.page.reload();
|
||||
} finally {
|
||||
env.routeOpts.holdBlockscout = false;
|
||||
}
|
||||
await visible(env.page, "#view-address");
|
||||
// Home again, where the tests below expect to start.
|
||||
await goHome(env.page);
|
||||
});
|
||||
|
||||
// -------------------------------------------- recovery phrase (#161)
|
||||
|
||||
// The gear toggles, so pressing it while Settings is already up leaves it.
|
||||
@@ -2163,9 +2201,7 @@ function quantity(wei) {
|
||||
|
||||
// Wait on the main view until a changed balance fixture has been picked up.
|
||||
//
|
||||
// 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).
|
||||
// Not a reload: the popup re-refreshes on a 10-second timer by itself.
|
||||
//
|
||||
// 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
|
||||
@@ -4525,6 +4561,9 @@ async function main() {
|
||||
ethBalanceWei: null,
|
||||
failGasEstimate: false,
|
||||
holdGasEstimate: false,
|
||||
// Whether a JSON-RPC batch asking for a transaction count is held
|
||||
// unanswered: the address scan after creating a wallet (#475).
|
||||
holdTransactionCount: false,
|
||||
// Whether Blockscout requests are held unanswered, and whether an
|
||||
// address's transaction list fails as a network error (#218).
|
||||
holdBlockscout: false,
|
||||
|
||||
Reference in New Issue
Block a user