mirror of
https://github.com/logos-blockchain/lez-programs.git
synced 2026-08-25 06:01:11 +00:00
test(apps/amm): select the funding account before submitting a swap
canSubmit now requires a chosen holding on both swap sides, so the swap e2e test must select them first. The selector auto-selects a single holding, but pick it explicitly (robust to multi-account wallets) via a new selectAccount step that waits for the holdings to load and selects the first match. Expose each side's selector via selectorObjectName (swapSell/BuyAccountSelector) and surface sellHolding/buyHolding in the failure diagnostics.
This commit is contained in:
@@ -533,6 +533,7 @@ Rectangle {
|
||||
label: "Sell"
|
||||
inputObjectName: "swapSellInput"
|
||||
buttonObjectName: "swapSellTokenButton"
|
||||
selectorObjectName: "swapSellAccountSelector"
|
||||
amount: root.sellDisplay
|
||||
token: root.sellToken
|
||||
holdings: root.holdings
|
||||
@@ -595,6 +596,7 @@ Rectangle {
|
||||
label: "Buy"
|
||||
inputObjectName: "swapBuyInput"
|
||||
buttonObjectName: "swapBuyTokenButton"
|
||||
selectorObjectName: "swapBuyAccountSelector"
|
||||
amount: root.buyDisplay
|
||||
token: root.buyToken
|
||||
holdings: root.holdings
|
||||
|
||||
@@ -28,6 +28,9 @@ Rectangle {
|
||||
// objectName forwarded to the token-select button, so tests can open the
|
||||
// right picker by objectId rather than fuzzy text.
|
||||
property alias buttonObjectName: tokenButton.objectName
|
||||
// objectName forwarded to the account selector, so tests can pick the funding
|
||||
// holding for this side deterministically.
|
||||
property alias selectorObjectName: accountSelector.objectName
|
||||
|
||||
signal tokenClicked()
|
||||
signal inputEdited(string newValue)
|
||||
|
||||
@@ -84,6 +84,38 @@ async function pickToken(app, index) {
|
||||
return symbol;
|
||||
}
|
||||
|
||||
// Pick the funding account for a swap side. The selector auto-selects when the
|
||||
// wallet holds the token in exactly one account, but make the choice explicit (and robust
|
||||
// to multi-account wallets with zero-balance holdings): wait for the holdings to populate,
|
||||
// then select the highest-balance match. canSubmit now requires BOTH sides' holdings to be
|
||||
// set, so a swap can't be submitted until this runs.
|
||||
async function selectAccount(app, selectorObjectName) {
|
||||
const id = await idByObjectName(app, selectorObjectName);
|
||||
await app.waitFor(
|
||||
async () => { if ((await prop(app, id, "hasFunds")) !== true) throw new Error("no matching holdings yet"); },
|
||||
{ timeout: 10000, interval: 300, description: `${selectorObjectName} holdings to load` },
|
||||
);
|
||||
// setSelection/accountIdFor/matchingAccounts/valueFor are members of the selector, so
|
||||
// evaluate in its own QML context (same pragmatic style as setSellAmount). tokenHoldings can
|
||||
// include zero-balance holdings for the token, and hasFunds only checks the match COUNT — so
|
||||
// pick the matching account with the largest balanceRaw rather than matchingAccounts[0],
|
||||
// which could be an empty holding the swap transfer can't debit. balanceRaw values are
|
||||
// non-negative base-unit integer strings, so "longer wins, else lexicographic" is an exact
|
||||
// max without needing BigInt.
|
||||
await app.inspector.send("evaluate", {
|
||||
expression:
|
||||
"(function(){var r=matchingAccounts,b=r[0],bb=String(valueFor(b,'balanceRaw')||'0');"
|
||||
+ "for(var i=1;i<r.length;++i){var v=String(valueFor(r[i],'balanceRaw')||'0');"
|
||||
+ "if(v.length>bb.length||(v.length===bb.length&&v>bb)){b=r[i];bb=v;}}"
|
||||
+ "setSelection(accountIdFor(b),false);})()",
|
||||
objectId: id,
|
||||
});
|
||||
await app.waitFor(
|
||||
async () => { if (!(await prop(app, id, "selectedAccountId"))) throw new Error("holding not selected yet"); },
|
||||
{ timeout: 5000, interval: 200, description: `${selectorObjectName} holding selected` },
|
||||
);
|
||||
}
|
||||
|
||||
// Enter the sell amount by setting the SwapCard's state directly. Synthesizing
|
||||
// keystrokes needs the TextInput to hold active focus, which the inspector
|
||||
// can't reliably grant headlessly; setting sellInput updates the property (and
|
||||
@@ -118,6 +150,8 @@ async function cardState(app) {
|
||||
swapError: get("swapError"),
|
||||
canSubmit: get("canSubmit"),
|
||||
submitButtonText: get("submitButtonText"),
|
||||
sellHolding: get("sellHolding"),
|
||||
buyHolding: get("buyHolding"),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -161,6 +195,10 @@ test("amm swap: sell token #1 for token #2", async (app) => {
|
||||
const second = await pickToken(app, 1);
|
||||
console.log(` sell ${first} -> buy ${second}`);
|
||||
|
||||
// 4. Pick the funding account for each side (canSubmit needs both selected).
|
||||
await selectAccount(app, "swapSellAccountSelector");
|
||||
await selectAccount(app, "swapBuyAccountSelector");
|
||||
|
||||
// 5. Enter the sell amount.
|
||||
await setSellAmount(app, SELL_AMOUNT);
|
||||
await app.expectTexts([SELL_AMOUNT]); // the amount should now be visible
|
||||
|
||||
Reference in New Issue
Block a user