-
Notifications
You must be signed in to change notification settings - Fork 25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FIX] Update E2E test token and related tests #1505
Changes from 7 commits
3ea530f
7c1fc65
1e9a2e9
7e16e3a
3713541
8850176
622aa4c
8fed63c
fd2e8dc
62cd1a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export const TEST_TOKEN_ADDRESS = | ||
"CA5F3Q3KQWGG5J4U6OBCJEFVG4B5JVMHFRGQGMLNZXTEMO7YEO6UYMMD"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
import { test, expect, expectPageToHaveScreenshot } from "./test-fixtures"; | ||
import { loginAndFund, loginToTestAccount, PASSWORD } from "./helpers/login"; | ||
import { TEST_TOKEN_ADDRESS } from "./helpers/test-token"; | ||
|
||
test("Send XLM payment to G address", async ({ page, extensionId }) => { | ||
test.slow(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there a specific reason to drop this? if I recall, it just extends the wait time of a test. I believe I had added this in the event of slow responses from Horizon There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just didn't observe that it added any longer of a timeout but no qualms with restoring, will add back. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool - once we stub out external calls, we shouldn't need this anymore |
||
await loginAndFund({ page, extensionId }); | ||
await page.getByTitle("Send Payment").click({ force: true }); | ||
|
||
|
@@ -72,15 +72,12 @@ test("Send XLM payment to G address", async ({ page, extensionId }) => { | |
}); | ||
|
||
test("Send XLM payment to C address", async ({ page, extensionId }) => { | ||
test.slow(); | ||
await loginToTestAccount({ page, extensionId }); | ||
|
||
// send XLM to C address | ||
await page.getByTitle("Send Payment").click({ force: true }); | ||
await expect(page.getByText("Send To")).toBeVisible(); | ||
await page | ||
.getByTestId("send-to-input") | ||
.fill("CAHX2LUNQ4YKNJTDEFW2LSFOXDAL4QI4736RV52ZUGCIRJK5U7MWQWW6"); | ||
await page.getByTestId("send-to-input").fill(TEST_TOKEN_ADDRESS); | ||
await page.getByText("Continue").click({ force: true }); | ||
|
||
await expect(page.getByText("Send XLM")).toBeVisible(); | ||
|
@@ -172,9 +169,7 @@ test("Send SAC to C address", async ({ page, extensionId }) => { | |
|
||
// send SAC to C address | ||
await page.getByTitle("Send Payment").click({ force: true }); | ||
await page | ||
.getByTestId("send-to-input") | ||
.fill("CAHX2LUNQ4YKNJTDEFW2LSFOXDAL4QI4736RV52ZUGCIRJK5U7MWQWW6"); | ||
await page.getByTestId("send-to-input").fill(TEST_TOKEN_ADDRESS); | ||
await page.getByText("Continue").click({ force: true }); | ||
|
||
await page.getByTestId("send-amount-asset-select").click({ force: true }); | ||
|
@@ -227,17 +222,13 @@ test("Send token payment to C address", async ({ page, extensionId }) => { | |
await expect(page.getByText("Your assets")).toBeVisible(); | ||
await page.getByText("Add an asset").click({ force: true }); | ||
await page.getByText("Add manually").click({ force: true }); | ||
await page | ||
.getByTestId("search-token-input") | ||
.fill("CAHX2LUNQ4YKNJTDEFW2LSFOXDAL4QI4736RV52ZUGCIRJK5U7MWQWW6"); | ||
await page.getByTestId("search-token-input").fill(TEST_TOKEN_ADDRESS); | ||
await page.getByTestId("ManageAssetRowButton").click({ force: true }); | ||
await page.getByTestId("add-asset").dispatchEvent("click"); | ||
|
||
// send E2E token to C address | ||
await page.getByTitle("Send Payment").click({ force: true }); | ||
await page | ||
.getByTestId("send-to-input") | ||
.fill("CAHX2LUNQ4YKNJTDEFW2LSFOXDAL4QI4736RV52ZUGCIRJK5U7MWQWW6"); | ||
await page.getByTestId("send-to-input").fill(TEST_TOKEN_ADDRESS); | ||
await page.getByText("Continue").click({ force: true }); | ||
|
||
await page.getByTestId("send-amount-asset-select").click({ force: true }); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -397,17 +397,26 @@ export const HistoryItem = ({ | |
setIconComponent( | ||
<Icon.ArrowUp className="HistoryItem__icon--sent" />, | ||
); | ||
setIsLoading(true); | ||
|
||
if (!tokenKey) { | ||
// TODO: attempt to fetch token details, not stored | ||
setRowText(operationString); | ||
setTxDetails((_state) => ({ | ||
..._state, | ||
headerTitle: translations("Transaction"), | ||
operationText: operationString, | ||
})); | ||
} else { | ||
const { token, decimals } = balances[tokenKey] as TokenBalance; | ||
try { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that sending transfers from payments is better supported, it became more obvious that we can't rely on client side cached token details for this path because we more often don't have them(user has a classic balance in Freighter but send to C address through SAC transfer for example). This update just fetches token details for every row that is a transfer inline to avoid the inconsistencies. |
||
const tokenDetailsResponse = await getTokenDetails({ | ||
contractId: attrs.contractId, | ||
publicKey, | ||
networkDetails, | ||
}); | ||
|
||
if (!tokenDetailsResponse) { | ||
setRowText(operationString); | ||
setTxDetails((_state) => ({ | ||
..._state, | ||
headerTitle: translations("Transaction"), | ||
operationText: operationString, | ||
})); | ||
} | ||
|
||
const { symbol, decimals } = tokenDetailsResponse!; | ||
const code = symbol === "native" ? "XLM" : symbol; | ||
const formattedTokenAmount = formatTokenAmount( | ||
new BigNumber(attrs.amount), | ||
decimals, | ||
|
@@ -418,7 +427,7 @@ export const HistoryItem = ({ | |
setBodyComponent( | ||
<> | ||
{paymentDifference} | ||
{formattedTokenAmount} {token.code} | ||
{formattedTokenAmount} {code} | ||
</>, | ||
); | ||
setIconComponent( | ||
|
@@ -428,7 +437,7 @@ export const HistoryItem = ({ | |
<Icon.ArrowUp className="HistoryItem__icon--sent" /> | ||
), | ||
); | ||
setRowText(token.code); | ||
setRowText(code); | ||
setDateText( | ||
(_dateText) => | ||
`${ | ||
|
@@ -440,9 +449,19 @@ export const HistoryItem = ({ | |
isRecipient: _isRecipient, | ||
headerTitle: `${ | ||
_isRecipient ? translations("Received") : translations("Sent") | ||
} ${token.code}`, | ||
operationText: `${paymentDifference}${formattedTokenAmount} ${token.code}`, | ||
} ${code}`, | ||
operationText: `${paymentDifference}${formattedTokenAmount} ${code}`, | ||
})); | ||
} catch (error) { | ||
// falls back to only showing contract ID | ||
setRowText(operationString); | ||
setTxDetails((_state) => ({ | ||
..._state, | ||
headerTitle: translations("Transaction"), | ||
operationText: operationString, | ||
})); | ||
} finally { | ||
setIsLoading(false); | ||
} | ||
} else { | ||
setRowText(operationString); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -289,7 +289,7 @@ export const TransactionDetails = ({ goBack }: { goBack: () => void }) => { | |
const isPathPayment = useSelector(isPathPaymentSelector); | ||
const { isMemoValidationEnabled } = useSelector(settingsSelector); | ||
const isSwap = useIsSwap(); | ||
const { scanTx, data: scanResult, isLoading } = useScanTx(); | ||
const { scanTx, data: scanResult, isLoading, setLoading } = useScanTx(); | ||
|
||
const { t } = useTranslation(); | ||
|
||
|
@@ -357,7 +357,9 @@ export const TransactionDetails = ({ goBack }: { goBack: () => void }) => { | |
url, | ||
networkDetails, | ||
); | ||
return; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does this do something the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well I think we could safely drop it but in the case that we |
||
} | ||
setLoading(false); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we need to worry about this loading state for classic tx's, as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no we don't because we seem to be calling that in every case here. I guess maybe I should ask about the intention of the condition to not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh wait I wrote that! lol Yeah curious if you think that's right? I think we probably also want to skip the scan for classic in the same condition. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okay took me a second to understand what was happening, but I get it now: This conditional is just to make sure we've finished simming the tx, which is only necessary for Soroban tx's. So it makes sense that we only have the conditional on scanSorobanTx There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I changed this in fd2e8dc There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah maybe I misunderstand this conditional. I think really what we want here is to never scan the tx is we are rendering the details at confirmation so I will just add a prop that we can pass in explicitly at confirmation to make this less brittle. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But if we go back to tx details from the Tx Success screen, we'll re-scan a classic tx, but we won't re-scan a soroban tx. And that's kind of a weird discrepancy. We probably shouldn't re-scan in either case There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok cool I think we're aligned here, 62cd1a6 is the version that I think handles this best. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice - this lgtm! |
||
}; | ||
const scanClassicTx = async () => { | ||
const transaction = await getBuiltTx( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -106,6 +106,7 @@ export const useScanTx = () => { | |
data, | ||
error, | ||
isLoading, | ||
setLoading, | ||
scanTx, | ||
}; | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -111,6 +111,13 @@ export const parseTokenAmount = (value: string, decimals: number) => { | |
return wholeValue.shiftedBy(decimals).plus(fractionValue); | ||
}; | ||
|
||
export const addressToString = (address: xdr.ScAddress) => { | ||
if (address.switch().name === "scAddressTypeAccount") { | ||
return StrKey.encodeEd25519PublicKey(address.accountId().ed25519()); | ||
} | ||
return StrKey.encodeContract(address.contractId()); | ||
}; | ||
|
||
export const getArgsForTokenInvocation = ( | ||
fnName: string, | ||
args: xdr.ScVal[], | ||
|
@@ -121,18 +128,12 @@ export const getArgsForTokenInvocation = ( | |
|
||
switch (fnName) { | ||
case SorobanTokenInterface.transfer: | ||
from = StrKey.encodeEd25519PublicKey( | ||
args[0].address().accountId().ed25519(), | ||
); | ||
to = StrKey.encodeEd25519PublicKey( | ||
args[1].address().accountId().ed25519(), | ||
); | ||
from = addressToString(args[0].address()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that we support transfers to C addresses, I ran into this where from and to are actually not always |
||
to = addressToString(args[1].address()); | ||
amount = scValToNative(args[2]); | ||
break; | ||
case SorobanTokenInterface.mint: | ||
to = StrKey.encodeEd25519PublicKey( | ||
args[0].address().accountId().ed25519(), | ||
); | ||
to = addressToString(args[0].address()); | ||
amount = scValToNative(args[1]); | ||
break; | ||
default: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't shown right now and also commented out so I assume we will need this again soon.