fix: Send's balance line is drawn again when a refresh returns (closes #748) #749
@@ -471,7 +471,9 @@ When "Back" returns to a screen that this page load has not drawn yet,
|
|||||||
Home is shown instead. "Back" onto a screen already drawn only unhides it, so
|
Home is shown instead. "Back" onto a screen already drawn only unhides it, so
|
||||||
unsaved input in Settings survives. Home is drawn again on every "Back". When a
|
unsaved input in Settings survives. Home is drawn again on every "Back". When a
|
||||||
balance refresh returns while AddressDetail or AddressToken is showing, that
|
balance refresh returns while AddressDetail or AddressToken is showing, that
|
||||||
screen draws its balances again.
|
screen draws its balances again. When a refresh returns while Send is showing,
|
||||||
|
Send draws its From address and current balance again. Its inputs and dropdown
|
||||||
|
stay as the user left them.
|
||||||
|
|
||||||
A network switch, or a change to "Use Blockscout", cuts the stack at the first
|
A network switch, or a change to "Use Blockscout", cuts the stack at the first
|
||||||
screen that cannot be drawn from saved state. The cut also drops AddressToken
|
screen that cannot be drawn from saved state. The cut also drops AddressToken
|
||||||
|
|||||||
+5
-2
@@ -107,8 +107,10 @@ let refreshTimer = null;
|
|||||||
// tracked token list stays as it is.
|
// tracked token list stays as it is.
|
||||||
//
|
//
|
||||||
// Once the save is done, the wallet list is drawn again. So are the balances
|
// Once the save is done, the wallet list is drawn again. So are the balances
|
||||||
// on AddressDetail or AddressToken when that screen is up. No other screen is
|
// on AddressDetail or AddressToken when that screen is up. When Send is up, its
|
||||||
// drawn again, DeleteAddress and its balance lines included.
|
// From address and current balance are drawn again, and its inputs and dropdown
|
||||||
|
// stay as the user left them. No other screen is drawn again, DeleteAddress and
|
||||||
|
// its balance lines included.
|
||||||
async function doRefreshAndRender() {
|
async function doRefreshAndRender() {
|
||||||
if (refreshInFlight) {
|
if (refreshInFlight) {
|
||||||
refreshAgain = true;
|
refreshAgain = true;
|
||||||
@@ -164,6 +166,7 @@ async function doRefreshAndRender() {
|
|||||||
renderWalletList();
|
renderWalletList();
|
||||||
if (state.currentView === "address") addressDetail.renderBalances();
|
if (state.currentView === "address") addressDetail.renderBalances();
|
||||||
if (state.currentView === "address-token") addressToken.renderBalance();
|
if (state.currentView === "address-token") addressToken.renderBalance();
|
||||||
|
if (state.currentView === "send") send.updateSendBalance();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// No caller waits for this function, so it must never reject. An
|
// No caller waits for this function, so it must never reject. An
|
||||||
// unhandled rejection reports nothing. The save inside it reports its
|
// unhandled rejection reports nothing. The save inside it reports its
|
||||||
|
|||||||
@@ -19,12 +19,17 @@
|
|||||||
// its ETH line reads the same, and Send states it as unknown
|
// its ETH line reads the same, and Send states it as unknown
|
||||||
// (https://git.eeqj.de/sneak/AutistMask/issues/736).
|
// (https://git.eeqj.de/sneak/AutistMask/issues/736).
|
||||||
//
|
//
|
||||||
|
// A refresh that returns while Send is up draws Send's balance line again, and
|
||||||
|
// leaves what the user entered as it is
|
||||||
|
// (https://git.eeqj.de/sneak/AutistMask/issues/748).
|
||||||
|
//
|
||||||
// Driven through the real popup over a stored profile on Ethereum Mainnet,
|
// Driven through the real popup over a stored profile on Ethereum Mainnet,
|
||||||
// with "Show tracked tokens with zero balance" on, as it is by default.
|
// with "Show tracked tokens with zero balance" on, as it is by default.
|
||||||
|
|
||||||
const { HDNodeWallet, Mnemonic } = require("ethers");
|
const { HDNodeWallet, Mnemonic } = require("ethers");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
ADDRESS,
|
||||||
bootPopup,
|
bootPopup,
|
||||||
cleanupPopup,
|
cleanupPopup,
|
||||||
unversionedValidProfile,
|
unversionedValidProfile,
|
||||||
@@ -431,6 +436,62 @@ test("Send for the new token reads its balance as unknown before any refresh has
|
|||||||
await finish([MILLION]);
|
await finish([MILLION]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Send for the new token reads the fetched balance once the refresh returns, without being reopened", async () => {
|
||||||
|
const page = await bootOnAddress();
|
||||||
|
const finish = holdNextRefresh(page);
|
||||||
|
await addNewToken(page);
|
||||||
|
await openToken(page, NEW_TOKEN.toLowerCase());
|
||||||
|
await page.click("btn-address-token-send");
|
||||||
|
expect(page.text("send-balance")).toBe("Current balance: unknown (NEW)");
|
||||||
|
|
||||||
|
await finish([MILLION]);
|
||||||
|
|
||||||
|
expect(page.visibleViews()).toEqual(["send"]);
|
||||||
|
expect(page.text("send-balance")).toBe("Current balance: 1000000.0000 NEW");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("a refresh that returns while Send is up draws an unread ETH balance again and leaves the inputs alone", async () => {
|
||||||
|
const page = await bootPopup(profileNotRead());
|
||||||
|
// The dropdown's first option, which a browser selects by itself.
|
||||||
|
page.node("send-token").value = "ETH";
|
||||||
|
await page.click("btn-main-send");
|
||||||
|
expect(page.text("send-balance")).toBe("Current balance: unknown (ETH)");
|
||||||
|
const recipient = "0x" + "dd".repeat(20);
|
||||||
|
page.node("send-to").value = recipient;
|
||||||
|
page.node("send-amount").value = "0.5";
|
||||||
|
// Stands for the options on the screen, which a refresh leaves as they are.
|
||||||
|
page.node("send-token").innerHTML = "options on the screen";
|
||||||
|
// Stands for the From address from before the refresh.
|
||||||
|
page.node("send-from").innerHTML = "From address before the refresh";
|
||||||
|
|
||||||
|
await refreshOnce(page, []);
|
||||||
|
|
||||||
|
expect(page.visibleViews()).toEqual(["send"]);
|
||||||
|
expect(page.text("send-balance")).toBe("Current balance: 2.0000 ETH");
|
||||||
|
expect(page.node("send-from").innerHTML).toContain(ADDRESS);
|
||||||
|
expect(page.value("send-to")).toBe(recipient);
|
||||||
|
expect(page.value("send-amount")).toBe("0.5");
|
||||||
|
expect(page.value("send-token")).toBe("ETH");
|
||||||
|
expect(page.node("send-token").innerHTML).toBe("options on the screen");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("a refresh that returns while Send is up keeps the token picked in the dropdown and draws its new balance", async () => {
|
||||||
|
const page = await bootOnDerivingWallet();
|
||||||
|
const dropdown = page.node("send-token");
|
||||||
|
dropdown.value = "ETH";
|
||||||
|
await page.click("btn-main-send");
|
||||||
|
dropdown.value = NEW_TOKEN;
|
||||||
|
for (const fn of dropdown.listeners.change) await fn();
|
||||||
|
expect(page.text("send-balance")).toBe("Current balance: 1000000.0000 NEW");
|
||||||
|
page.node("send-amount").value = "0.5";
|
||||||
|
|
||||||
|
await refreshOnce(page, [{ ...MILLION, balance: "3000000.0" }]);
|
||||||
|
|
||||||
|
expect(page.text("send-balance")).toBe("Current balance: 3000000.0000 NEW");
|
||||||
|
expect(page.value("send-token")).toBe(NEW_TOKEN);
|
||||||
|
expect(page.value("send-amount")).toBe("0.5");
|
||||||
|
});
|
||||||
|
|
||||||
test("a token added by contract address on SettingsAddToken reads quantity unknown until the refresh returns", async () => {
|
test("a token added by contract address on SettingsAddToken reads quantity unknown until the refresh returns", async () => {
|
||||||
const page = await bootPopup(unversionedValidProfile());
|
const page = await bootPopup(unversionedValidProfile());
|
||||||
expect(page.visibleViews()).toEqual(["main"]);
|
expect(page.visibleViews()).toEqual(["main"]);
|
||||||
|
|||||||
Reference in New Issue
Block a user