Skip to content

Commit 9fffcac

Browse files
committed
test(e2e): add detox for evm native staking
1 parent 54bf945 commit 9fffcac

8 files changed

Lines changed: 363 additions & 11 deletions

File tree

.changeset/odd-pillows-smash.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"live-mobile": minor
3+
"@ledgerhq/live-common": minor
4+
---
5+
6+
tests(e2e): add detox for evm native staking

apps/ledger-live-mobile/e2e/page/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import SendPage from "./trade/send.page";
2020
import SettingsGeneralPage from "./settings/settingsGeneral.page";
2121
import SettingsPage from "./settings/settings.page";
2222
import StakePage from "./trade/stake.page";
23+
import EvmDelegatePage from "./trade/evmDelegate.page";
2324
import SwapPage from "./trade/swap.page";
2425
import TransferMenuDrawer from "./wallet/transferMenu.drawer";
2526
import WalletTabNavigatorPage from "./wallet/walletTabNavigator.page";
@@ -73,6 +74,7 @@ export class Application {
7374
private settingsPageInstance = lazyInit(SettingsPage);
7475
private settingsGeneralPageInstance = lazyInit(SettingsGeneralPage);
7576
private stakePageInstance = lazyInit(StakePage);
77+
private evmDelegatePageInstance = lazyInit(EvmDelegatePage);
7678
private swapPageInstance = lazyInit(SwapPage);
7779
private transferMenuDrawerInstance = lazyInit(TransferMenuDrawer);
7880
private walletTabNavigatorPageInstance = lazyInit(WalletTabNavigatorPage);
@@ -185,6 +187,10 @@ export class Application {
185187
return this.stakePageInstance();
186188
}
187189

190+
public get evmDelegate() {
191+
return this.evmDelegatePageInstance();
192+
}
193+
188194
public get swap() {
189195
return this.swapPageInstance();
190196
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { device, expect } from "detox";
2+
import { Step } from "jest-allure2-reporter/api";
3+
4+
export default class EvmDelegatePage {
5+
startStakeButtonId = "account-quick-action-button-cta";
6+
addDelegationButtonId = "account-quick-action-button-addDelegation";
7+
validatorName = "Ledger by Figment";
8+
validatorRowId = "evm-validator-row-seivaloper1mockvalidator000000000000000000000001";
9+
amountInputId = "evm-delegation-amount-input";
10+
useMaxButtonId = "evm-delegation-use-max";
11+
amountContinueButtonId = "enabled-evm-delegation-amount-continue";
12+
delegationSummaryLabel = "Delegated assets";
13+
14+
@Step("Start EVM delegation flow from account quick actions")
15+
async startDelegate() {
16+
await waitForElementById(this.startStakeButtonId);
17+
await device.disableSynchronization();
18+
try {
19+
await tapById(this.startStakeButtonId);
20+
} catch (error) {
21+
await device.enableSynchronization();
22+
throw error;
23+
}
24+
}
25+
26+
@Step("Wait for validator list to be visible")
27+
async waitForValidatorListVisible() {
28+
await waitForElementByText(this.validatorName);
29+
}
30+
31+
@Step("Select the first validator in the list")
32+
async selectFirstValidator() {
33+
try {
34+
await waitForElementByText(this.validatorName);
35+
await tapById(this.validatorRowId);
36+
if (await IsIdVisible(this.useMaxButtonId)) {
37+
return;
38+
}
39+
await tapByText(this.validatorName);
40+
await waitForElementById(this.useMaxButtonId);
41+
} finally {
42+
await device.enableSynchronization();
43+
}
44+
}
45+
46+
@Step("Tap use max amount button")
47+
async useMaxAmount() {
48+
await waitForElementById(this.useMaxButtonId);
49+
await tapById(this.useMaxButtonId);
50+
}
51+
52+
@Step("Continue from amount screen")
53+
async continueAmount() {
54+
await waitForElementById(this.amountContinueButtonId);
55+
await tapById(this.amountContinueButtonId);
56+
}
57+
58+
@Step("Expect delegated assets summary visible")
59+
async expectDelegatedAssetsVisible() {
60+
await waitForElementByText(this.delegationSummaryLabel);
61+
await expect(getElementByText(this.delegationSummaryLabel)).toBeVisible();
62+
}
63+
64+
@Step("Expect add delegation CTA visible")
65+
async expectAddDelegationCtaVisible() {
66+
await waitForElementById(this.addDelegationButtonId);
67+
await expect(getElementById(this.addDelegationButtonId)).toBeVisible();
68+
}
69+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
describe("SEI EVM Native Staking - Delegate flow", () => {
2+
const SEI_CURRENCY_ID = "sei_evm";
3+
const EMPTY_ACCOUNT_ID = "mock:2:sei_evm:0x6EB963EFD0FEF7A4CFAB6CE6F1421C3279D11707:";
4+
const STAKED_ACCOUNT_ID = "mock:2:sei_evm:0x18E9A4F2A5A2B01F35E7D086E75D7D01530A1A9F:";
5+
6+
async function selectAccount(accountId: string) {
7+
const accountRowId = `account-row-${accountId}`;
8+
if (!(await IsIdVisible(accountRowId))) {
9+
await scrollToId(accountRowId);
10+
}
11+
await waitForElementById(accountRowId);
12+
await tapById(accountRowId);
13+
}
14+
15+
beforeAll(async () => {
16+
await app.init({
17+
userdata: "seiEvmStaking",
18+
});
19+
await app.portfolio.waitForPortfolioPageToLoad();
20+
});
21+
22+
it("Delegate happy path: start delegating, validator list is shown, validator selected", async () => {
23+
await app.assetAccountsPage.openViaDeeplink(SEI_CURRENCY_ID);
24+
await selectAccount(EMPTY_ACCOUNT_ID);
25+
await app.evmDelegate.startDelegate();
26+
await app.evmDelegate.selectFirstValidator();
27+
await app.evmDelegate.useMaxAmount();
28+
await app.evmDelegate.continueAmount();
29+
});
30+
31+
it("Already-delegated validator is reflected on the account page", async () => {
32+
await app.assetAccountsPage.openViaDeeplink(SEI_CURRENCY_ID);
33+
await selectAccount(STAKED_ACCOUNT_ID);
34+
await app.evmDelegate.expectDelegatedAssetsVisible();
35+
await app.evmDelegate.expectAddDelegationCtaVisible();
36+
});
37+
});
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
{
2+
"data": {
3+
"SPECTRON_RUN": {
4+
"localStorage": {
5+
"acceptedTermsVersion": "2019-12-04"
6+
}
7+
},
8+
"settings": {
9+
"hasCompletedOnboarding": true,
10+
"counterValue": "USD",
11+
"language": "en",
12+
"theme": "light",
13+
"region": null,
14+
"locale": "en-US",
15+
"orderAccounts": "balance|desc",
16+
"countervalueFirst": false,
17+
"autoLockTimeout": 10,
18+
"selectedTimeRange": "month",
19+
"marketIndicator": "western",
20+
"currenciesSettings": {},
21+
"pairExchanges": {},
22+
"developerMode": false,
23+
"loaded": true,
24+
"shareAnalytics": true,
25+
"sentryLogs": true,
26+
"readOnlyModeEnabled": false,
27+
"hasOrderedNano": true,
28+
"lastUsedVersion": "99.99.99",
29+
"dismissedBanners": [],
30+
"accountsViewMode": "list",
31+
"showAccountsHelperBanner": true,
32+
"hideEmptyTokenAccounts": false,
33+
"sidebarCollapsed": false,
34+
"discreetMode": false,
35+
"preferredDeviceModel": "nanoX",
36+
"hasInstalledApps": true,
37+
"dismissedDynamicCards": [],
38+
"seenDevices": [],
39+
"blacklistedTokenIds": [],
40+
"swapAcceptedProviderIds": [],
41+
"deepLinkUrl": null,
42+
"firstTimeLend": false,
43+
"swapProviders": [],
44+
"showClearCacheBanner": false,
45+
"starredAccountIds": [],
46+
"hasPassword": false
47+
},
48+
"user": {
49+
"id": "08cf3393-c5eb-4ea7-92de-0deea22e3971"
50+
},
51+
"accounts": [
52+
{
53+
"data": {
54+
"id": "mock:2:sei_evm:0x6EB963EFD0FEF7A4CFAB6CE6F1421C3279D11707:",
55+
"seedIdentifier": "0x6EB963EFD0FEF7A4CFAB6CE6F1421C3279D11707",
56+
"name": "SEI Network (EVM) 1",
57+
"starred": false,
58+
"used": true,
59+
"derivationMode": "",
60+
"index": 0,
61+
"freshAddress": "0x6EB963EFD0FEF7A4CFAB6CE6F1421C3279D11707",
62+
"freshAddressPath": "44'/60'/0'/0/0",
63+
"blockHeight": 100000,
64+
"creationDate": "2024-01-01T00:00:00.000Z",
65+
"operationsCount": 0,
66+
"operations": [],
67+
"pendingOperations": [],
68+
"currencyId": "sei_evm",
69+
"unitMagnitude": 18,
70+
"lastSyncDate": "2024-01-01T00:00:00.000Z",
71+
"balance": "10000000000000000000",
72+
"spendableBalance": "10000000000000000000",
73+
"xpub": "0x6EB963EFD0FEF7A4CFAB6CE6F1421C3279D11707",
74+
"stakingResources": {
75+
"delegations": [],
76+
"redelegations": [],
77+
"unbondings": [],
78+
"delegatedBalance": "0",
79+
"pendingRewardsBalance": "0",
80+
"unbondingBalance": "0",
81+
"validators": [
82+
{
83+
"validatorAddress": "seivaloper1mockvalidator000000000000000000000001",
84+
"name": "Ledger by Figment",
85+
"votingPower": 0,
86+
"commission": 0.05,
87+
"estimatedYearlyRewardsRate": 0.12,
88+
"tokens": 123456789000000
89+
},
90+
{
91+
"validatorAddress": "seivaloper1mockvalidator000000000000000000000002",
92+
"name": "Chorus One",
93+
"votingPower": 1,
94+
"commission": 0.07,
95+
"estimatedYearlyRewardsRate": 0.1,
96+
"tokens": 99000000000000
97+
},
98+
{
99+
"validatorAddress": "seivaloper1mockvalidator000000000000000000000003",
100+
"name": "Everstake",
101+
"votingPower": 2,
102+
"commission": 0.1,
103+
"estimatedYearlyRewardsRate": 0.09,
104+
"tokens": 77000000000000
105+
}
106+
]
107+
},
108+
"swapHistory": []
109+
},
110+
"version": 1
111+
},
112+
{
113+
"data": {
114+
"id": "mock:2:sei_evm:0x18E9A4F2A5A2B01F35E7D086E75D7D01530A1A9F:",
115+
"seedIdentifier": "0x6EB963EFD0FEF7A4CFAB6CE6F1421C3279D11707",
116+
"name": "SEI Network (EVM) Staked",
117+
"starred": false,
118+
"used": true,
119+
"derivationMode": "",
120+
"index": 1,
121+
"freshAddress": "0x18E9A4F2A5A2B01F35E7D086E75D7D01530A1A9F",
122+
"freshAddressPath": "44'/60'/1'/0/0",
123+
"blockHeight": 100000,
124+
"creationDate": "2024-01-01T00:00:00.000Z",
125+
"operationsCount": 0,
126+
"operations": [],
127+
"pendingOperations": [],
128+
"currencyId": "sei_evm",
129+
"unitMagnitude": 18,
130+
"lastSyncDate": "2024-01-01T00:00:00.000Z",
131+
"balance": "10000000000000000000",
132+
"spendableBalance": "7500000000000000000",
133+
"xpub": "0x18E9A4F2A5A2B01F35E7D086E75D7D01530A1A9F",
134+
"stakingResources": {
135+
"delegations": [
136+
{
137+
"validatorAddress": "seivaloper1mockvalidator000000000000000000000001",
138+
"amount": "2500000000000000000",
139+
"pendingRewards": "120000000000000000",
140+
"status": "bonded"
141+
}
142+
],
143+
"redelegations": [
144+
{
145+
"validatorSrcAddress": "seivaloper1mockvalidator000000000000000000000002",
146+
"validatorDstAddress": "seivaloper1mockvalidator000000000000000000000003",
147+
"amount": "1000000000000000000",
148+
"completionDate": "2042-01-02T03:04:05.000Z"
149+
}
150+
],
151+
"unbondings": [
152+
{
153+
"validatorAddress": "seivaloper1mockvalidator000000000000000000000001",
154+
"amount": "500000000000000000",
155+
"completionDate": "2042-01-02T03:04:05.000Z"
156+
}
157+
],
158+
"delegatedBalance": "2500000000000000000",
159+
"pendingRewardsBalance": "120000000000000000",
160+
"unbondingBalance": "500000000000000000",
161+
"validators": [
162+
{
163+
"validatorAddress": "seivaloper1mockvalidator000000000000000000000001",
164+
"name": "Ledger by Figment",
165+
"votingPower": 0,
166+
"commission": 0.05,
167+
"estimatedYearlyRewardsRate": 0.12,
168+
"tokens": 123456789000000
169+
},
170+
{
171+
"validatorAddress": "seivaloper1mockvalidator000000000000000000000002",
172+
"name": "Chorus One",
173+
"votingPower": 1,
174+
"commission": 0.07,
175+
"estimatedYearlyRewardsRate": 0.1,
176+
"tokens": 99000000000000
177+
},
178+
{
179+
"validatorAddress": "seivaloper1mockvalidator000000000000000000000003",
180+
"name": "Everstake",
181+
"votingPower": 2,
182+
"commission": 0.1,
183+
"estimatedYearlyRewardsRate": 0.09,
184+
"tokens": 77000000000000
185+
}
186+
]
187+
},
188+
"swapHistory": []
189+
},
190+
"version": 1
191+
}
192+
],
193+
"countervalues": {},
194+
"featureFlags": {
195+
"overrides": {
196+
"evmNativeStaking": {
197+
"enabled": true,
198+
"params": {
199+
"supportedCurrencyIds": ["sei_evm"]
200+
}
201+
},
202+
"llmAccountListUI": {
203+
"enabled": false
204+
}
205+
},
206+
"bannerVisible": false
207+
}
208+
}
209+
}

0 commit comments

Comments
 (0)