Repository: trezor/trezor-suite
Pull request #17264: test(suite-native): receive flow e2e test added
Author: login: PeKne
Labels: name: mobile
description: Suite Lite issues and PRs
Created: 2025-02-26T15:48:42Z | Merged: 2025-03-03T13:24:52Z

## Description
- receive flow with on Trezor device confirmation e2e test added



Diff:
diff --git a/suite-native/app/e2e/pageObjects/accountDetailActions.ts b/suite-native/app/e2e/pageObjects/accountDetailActions.ts
index 9e2de003803b..17891c4cecce 100644
--- a/suite-native/app/e2e/pageObjects/accountDetailActions.ts
+++ b/suite-native/app/e2e/pageObjects/accountDetailActions.ts
@@ -16,6 +16,10 @@ class AccountDetailActions {
     async openSend() {
         await element(by.id('@account-detail/send-button')).tap();
     }
+
+    async openReceive() {
+        await element(by.id('@account-detail/receive-button')).tap();
+    }
 }
 
 export const onAccountDetail = new AccountDetailActions();
diff --git a/suite-native/app/e2e/pageObjects/accountReceiveActions.ts b/suite-native/app/e2e/pageObjects/accountReceiveActions.ts
new file mode 100644
index 000000000000..93d056c76c84
--- /dev/null
+++ b/suite-native/app/e2e/pageObjects/accountReceiveActions.ts
@@ -0,0 +1,26 @@
+import { expect as detoxExpect } from 'detox';
+
+class AccountReceiveActions {
+    async waitForScreen() {
+        await waitFor(element(by.id('@screen/ReceiveAccount'))).toBeVisible();
+    }
+
+    async tapShowAddressButton() {
+        const showAddressButton = element(by.id('@receive/show-address-button'));
+
+        await waitFor(showAddressButton).toBeVisible().withTimeout(30000);
+        await showAddressButton.tap();
+
+        // button should be hidden after tap
+        await waitFor(showAddressButton).not.toBeVisible().withTimeout(30000);
+    }
+
+    async verifyReceiveAddress(address: string) {
+        const receiveAddressText = element(by.id('@receive/confirmed-receive-address'));
+
+        await waitFor(receiveAddressText).toBeVisible().withTimeout(30000);
+        detoxExpect(receiveAddressText).toHaveText(address);
+    }
+}
+
+export const onAccountReceive = new AccountReceiveActions();
diff --git a/suite-native/app/e2e/tests/receive.test.ts b/suite-native/app/e2e/tests/receive.test.ts
new file mode 100644
index 000000000000..0ec189a88644
--- /dev/null
+++ b/suite-native/app/e2e/tests/receive.test.ts
@@ -0,0 +1,39 @@
+import { conditionalDescribe } from '@suite-common/test-utils';
+import { TrezorUserEnvLink } from '@trezor/trezor-user-env-link';
+
+import { onAccountDetail } from '../pageObjects/accountDetailActions';
+import { onAccountReceive } from '../pageObjects/accountReceiveActions';
+import { onAlertSheet } from '../pageObjects/alertSheetActions';
+import { onCoinEnablingInit } from '../pageObjects/coinEnablingActions';
+import { onHome } from '../pageObjects/homeActions';
+import { onMyAssets } from '../pageObjects/myAssetsActions';
+import { onOnboarding } from '../pageObjects/onboardingActions';
+import { onTabBar } from '../pageObjects/tabBarActions';
+import { disconnectTrezorUserEnv, openApp, prepareTrezorEmulator } from '../utils';
+
+conditionalDescribe(device.getPlatform() === 'android', 'Receive', () => {
+    it('Generate device confirmed receive address.', async () => {
+        await prepareTrezorEmulator();
+        await openApp({ newInstance: true });
+        await onOnboarding.skipOnboarding();
+
+        await onCoinEnablingInit.waitForScreen();
+        await onCoinEnablingInit.enableNetwork('btc');
+        await onCoinEnablingInit.clickOnConfirmButton();
+        await onAlertSheet.skipViewOnlyMode();
+
+        await onHome.waitForScreen();
+        await onTabBar.navigateToMyAssets();
+
+        await onMyAssets.openAccountDetail({ accountName: 'Bitcoin #1' });
+
+        await onAccountDetail.openReceive();
+        await onAccountReceive.waitForScreen();
+
+        await onAccountReceive.tapShowAddressButton();
+        await TrezorUserEnvLink.pressYes();
+        await onAccountReceive.verifyReceiveAddress('bc1qa55m6kz3crfse5xg2rukulyap4eyp75w0puawz');
+
+        disconnectTrezorUserEnv();
+    });
+});
diff --git a/suite-native/qr-code/src/components/AddressQRCode.tsx b/suite-native/qr-code/src/components/AddressQRCode.tsx
index cbe9e6a6cdc1..1ed3b9e5cdbd 100644
--- a/suite-native/qr-code/src/components/AddressQRCode.tsx
+++ b/suite-native/qr-code/src/components/AddressQRCode.tsx
@@ -39,7 +39,11 @@ export const AddressQRCode = ({ address }: AddressQRCodeProps) => {
         <VStack spacing="sp24">
             <QRCode data={address} />
             <Pressable onLongPress={handleCopyAddress} style={applyStyle(addressContainer)}>
-                <Text variant="titleSmall" textAlign="center">
+                <Text
+                    variant="titleSmall"
+                    textAlign="center"
+                    testID="@receive/confirmed-receive-address"
+                >
                     {address}
                 </Text>
             </Pressable>
diff --git a/suite-native/receive/src/components/ShowAddressButtons.tsx b/suite-native/receive/src/components/ShowAddressButtons.tsx
index b9e40df2e856..b914b0fd57e3 100644
--- a/suite-native/receive/src/components/ShowAddressButtons.tsx
+++ b/suite-native/receive/src/components/ShowAddressButtons.tsx
@@ -37,7 +37,12 @@ export const ShowAddressButtons = ({ onShowAddress }: ShowAddressButtonsProps) =
 
     return (
         <VStack spacing="sp24">
-            <Button viewLeft="eye" size="large" onPress={handleShowAddress}>
+            <Button
+                testID="@receive/show-address-button"
+                viewLeft="eye"
+                size="large"
+                onPress={handleShowAddress}
+            >
                 <Translation
                     id={
                         isPortfolioTrackerDevice


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

<details>
<summary>🧹 Nitpick comments (5)</summary><blockquote>

<details>
<summary>suite-native/app/e2e/pageObjects/accountReceiveActions.ts (2)</summary><blockquote>

`3-3`: **Class naming should use PascalCase.**

The class name uses camelCase (`accountReceiveActions`) which is inconsistent with other action classes in the codebase that use PascalCase (like `AccountDetailActions`).

```diff
-class accountReceiveActions {
+class AccountReceiveActions {
```

---

`26-26`: **Update exported instance name to match class name.**

If you update the class name to PascalCase, make sure to update the exported instance name as well for consistency.

```diff
-export const onAccountReceive = new accountReceiveActions();
+export const onAccountReceive = new AccountReceiveActions();
```

</blockquote></details>
<details>
<summary>suite-native/app/e2e/tests/receive.test.ts (3)</summary><blockquote>

`14-14`: **Consider documenting why this test is Android-specific.**

The `conditionalDescribe` limits execution to Android platforms, but there's no explanation why. If there are platform-specific behaviors or limitations, adding a brief comment would help other developers understand the test's scope.

---

`33-36`: **Replace hardcoded address with a dynamic expectation.**

The test verifies against a hardcoded address (`bc1qa55m6kz3crfse5xg2rukulyap4eyp75w0puawz`), which could make the test brittle if addresses change due to emulator resets or configuration changes.


Consider either:
1. Retrieving the expected address dynamically from the Trezor emulator
2. Using address pattern validation instead of exact matching
3. Adding a comment explaining why this specific address is used

```diff
- await onAccountReceive.verifyReceiveAddress('bc1qa55m6kz3crfse5xg2rukulyap4eyp75w0puawz');
+ // Example of dynamic address retrieval (implementation would depend on your architecture)
+ const expectedAddress = await TrezorUserEnvLink.getFirstAvailableAddress('btc');
+ await onAccountReceive.verifyReceiveAddress(expectedAddress);
```

---

`37-37`: **Consider adding error handling for disconnection.**

The disconnect operation lacks error handling. If the disconnection fails, the test might not clean up properly.


```diff
- disconnectTrezorUserEnv();
+ try {
+   await disconnectTrezorUserEnv();
+ } catch (error) {
+   console.error('Failed to disconnect Trezor user environment:', error);
+   // Consider whether to fail the test or just log the error
+ }
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between fce4f90fd7c5a740d70915d9ee22ccd4f9bb17e0 and 5b33c28f860e0b5a07c88e18f6204655ad3ec306.

</details>

<details>
<summary>📒 Files selected for processing (5)</summary>

* `suite-native/app/e2e/pageObjects/accountDetailActions.ts` (1 hunks)
* `suite-native/app/e2e/pageObjects/accountReceiveActions.ts` (1 hunks)
* `suite-native/app/e2e/tests/receive.test.ts` (1 hunks)
* `suite-native/qr-code/src/components/AddressQRCode.tsx` (1 hunks)
* `suite-native/receive/src/components/ShowAddressButtons.tsx` (1 hunks)

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (3)</summary>

* GitHub Check: prepare_android_test_app
* GitHub Check: Setup and Cache Dependencies
* GitHub Check: Analyze with CodeQL (javascript)

</details>

<details>
<summary>🔇 Additional comments (8)</summary><blockquote>

<details>
<summary>suite-native/app/e2e/pageObjects/accountDetailActions.ts (1)</summary>

`19-22`: **Excellent addition of the openReceive method.**

The implementation follows the same pattern as the existing openSend method, maintaining consistency in the codebase.

</details>
<details>
<summary>suite-native/receive/src/components/ShowAddressButtons.tsx (1)</summary>

`40-45`: **Good testability improvement with testID addition.**

Adding the testID to the Button component enhances the component's testability without changing any functionality, which is exactly what we want for E2E testing support.

</details>
<details>
<summary>suite-native/qr-code/src/components/AddressQRCode.tsx (1)</summary>

`42-46`: **Well-implemented testID for address verification.**

Adding the testID to this Text component is essential for the E2E test to verify the displayed address. Good implementation that doesn't affect the component's core functionality.

</details>
<details>
<summary>suite-native/app/e2e/pageObjects/accountReceiveActions.ts (2)</summary>

`8-16`: **Good implementation of button interaction with appropriate timeouts.**

The method properly waits for the button to become visible with a reasonable timeout, taps it, and then verifies that it's no longer visible after the interaction. This ensures that the test will correctly handle any delays in the UI rendering.

---

`18-23`: **Well-structured address verification method.**

This method appropriately waits for the address text to be visible and then verifies that it matches the expected address. The 30-second timeout provides adequate flexibility for device confirmation processes.

</details>
<details>
<summary>suite-native/app/e2e/tests/receive.test.ts (3)</summary>

`1-13`: **Well-structured imports and dependencies.**

The imports are well-organized, clearly separating test utilities, page objects, and helper functions.

---

`15-29`: **Test flow is clear and follows best practices.**

The test follows a logical progression:
1. Setting up the emulator and application
2. Configuring the environment (enabling Bitcoin network)
3. Navigating to the relevant screen

This organization makes the test easy to understand and maintain.

---

`30-32`: **Good separation of concerns with page objects.**

Using dedicated page objects (`onAccountDetail` and `onAccountReceive`) for different screens follows best practices for E2E testing, improving maintainability and reusability.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: NONE
submitted_at: 2025-02-26T15:51:11Z
user: login: yanascz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T10:47:44Z
user: login: PeKne
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T11:08:16Z
user: login: yanascz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T11:17:17Z
user: login: yanascz
body: Nice!
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-03T11:30:28Z

Review comments:
diff_hunk: @@ -0,0 +1,26 @@
+import { expect as detoxExpect } from 'detox';
+
+class accountReceiveActions {
path: suite-native/app/e2e/pageObjects/accountReceiveActions.ts
user: login: yanascz
body: ```suggestion
class AccountReceiveActions {
```
created_at: 2025-03-03T10:47:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,26 @@
+import { expect as detoxExpect } from 'detox';
+
+class accountReceiveActions {
path: suite-native/app/e2e/pageObjects/accountReceiveActions.ts
user: login: PeKne
body: fixed 8e9669106a
created_at: 2025-03-03T11:08:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,26 @@
+import { expect as detoxExpect } from 'detox';
+
+class AccountReceiveActions {
+    async waitForScreen() {
+        await waitFor(element(by.id('@screen/ReceiveAccount'))).toBeVisible();
+    }
+
+    async clickShowAddressButton() {
path: suite-native/app/e2e/pageObjects/accountReceiveActions.ts
user: login: yanascz
body: We use `tap`, `click` is semantically not correct. Also `tap` is used much more often in our code base.
```suggestion
    async tapShowAddressButton() {
```
created_at: 2025-03-03T11:17:17Z
author_association: CONTRIBUTOR

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-02-26T15:51:08Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: failure by coderabbit.ai -->

> [!CAUTION]
> ## Review failed
> 
> The head commit changed during the review from e3ac7867ffd268d612292c4bc14febc03e89fe30 to aaf0d6a1a61dd35b955b277538c0890d5c4614ee.

<!-- end of auto-generated comment: failure by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough

The changes introduce enhancements to the "Receive" functionality by adding new actions and improving testing capabilities. A new asynchronous method, `openReceive`, is added to the `AccountDetailActions` class for interaction with the receive UI element. Additionally, a new class, `AccountReceiveActions`, is created to encapsulate actions related to receiving an account, including methods for waiting for the receive screen, clicking a button to show the address, and verifying the displayed address. An end-to-end test file for the "Receive" functionality on Android devices is also introduced, simulating user interactions and verifying outcomes. Furthermore, UI components are updated to include `testID` props for improved testability, without affecting existing logic or behavior. These modifications collectively aim to enhance functionality and testing robustness for the receive feature.

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- DwQgtGAEAqAWCWBnSTIEMB26CuAXA9mAOYCmGJATmriQCaQDG+Ats2bgFyQAOFk+AIwBWJBrngA3EsgEBPRvlqU0AgfFwA6NPEgQAfACgjoCEYDEZyAAUASpADK2VmgqyjcEj2wAbb5AokAI7Y0riQ4rjedJAARDSIuAAUiNjqJGAY1JIkAJRcAQwk2ZAAZt74AO6QJABMnvFhaLRKtDGQFWjIKQLM6jT0cuGwntiIlNYkANLk6Bj0qPBKGOIl8NGDuMOQGE4C4wCMAOw1AGwALBowW7aMmJB76AyFiGP01EOeJfi+lfAYRJAAKo2AAyXAA2rBcLhuIgOAB6eFEdSwbACDRMZjw3ABABe+Ao2LxBLAKTS8O4Pm88KOpzOAF1ElCYXDEcjNmiMSwiSR8YScbySWSaBSqTTjucchp3FslIgGBR4NxxPgsPgSh8vL5/EEQgkUHN4AxqNIhu87mRaGACGBLZBErVcuFQpBYJ17iQyOhmtEvnxNp4CkUpKVyhUADTtBAMWAGhjebByhQYVYUZhZVX8LABmDEvhKCRGkiXOCoJq0dTwTPaZjIAjVDBujCFTUNP4AkpUNgVAkAa3u8jIKUV/zNYRzQeKZUqpWwzZVGGQTAoBUi8gqwywaGTqfTC5QyACwXgAXonZYmugecgBaL0oM+mM4CgdvVOBtpHIVH6ClY7C4vD8MIojiFIMjyEwShUKo6haDoj4mFApbIGWW54IQn7KD+mJsMs+RoFUKTOK4A4KFBKhqJo2i6GAhhPqYBjCukmSgSQ8JoNw3Dwo6FJoKQADywFiIg7FPPgc64AAIiQuDaN4ACCYhVouGi4HCBgxJpBgWJA8kAJLEGQWHRER6YkW+MaYKQiAyp4ln/Kafw4oo2Attu5BVJ0sjNrAFCquJyBsJsiiQAABvg3BkDYojBiQoXhPgmqhYpTASdJsnwApSmqog8Xxp0iAlgggUybAIVoD8FQocsyjZVgFQougQJ6dUUS4WEizsPAqzrPIOZ6ZJYUAAJoGJElgEoGXUpOUhgAIeAEBgoWRn8Ej4L27ZNbJ3CPPumawVcngkAAHkg4ijkFZX0OFkUYPYlrxQE6Z/Mgc72aQtCRs9yzaBgm3qMgJRvQuFXqH1iXbVmSUjWNywTTJcnwmMcxzQtqqhUVnjlpWmZvjdUUxdk8UndwmC0HWWzGqTajeJWppvjmyWw1JCOZYpC65Yw3gFaRZAqLTo45qM4z1pFFB+swszehWIN+KN+4BNzP71jN7aRpi3BtV1gtbCdZ2bcjZ7A8poO4LI97mJY8neDQ37KXWEOyqI3N2zl/AaiTBI/gSXgCLTDANhEaw2Q+kAALKleVPq0FwoVec2/C3dFhTZIkOTxX8XM80zqXLOlcns/bGdYKFTEZFkUjsZx3F1LxAlCWpom5yzU2Fzlqm5RpWkPgxZcsdkVdcTxpP1yIwlN+JyzJ7FbcqWpHBdzE2lWwZmHfiZThmfIFlNtZRjydsJBVKsURhaNzfT9ks+FWp8VujInpYE5fm0K5dDq6qGV/aO275S8YUpUnrgS+Uhr7xU2O8MgVMUhK1NPLe2OpYH0BVoTQsP8tzMwNFLS01pCB2jbKOJgNVjqaEOlnf+fx4yJlNJsAIWNEDeRjH5DAAVICXUUHCSARh9iXFCh0dQAAxAk9gFSPzTqFLgyE2GR3oPwtSpQfY5nlHQrAJAtbLBQEsFYawBjyFCkNZRj94QgJIIAiS4DEp7ExJ4QsiB4B+2LAYGovD4xGl7PYMqFR5LNACC8AAQmjDA4jJHFWkcFWR2h5F+k1PNaE+0tHdR0aRfRM02KIE8WAcsvjECoziUtBKHpIC2PsVESM20UK4EjGTD4WApCKh6hTd4OZYmLQPNsRK5QHJ8GKQ49AJRbatg4tKAAzLwup3VZAmO8bQbJiQsnSE4QkEcRB04hNQOwiJAMFH+i2DQEhrUSDtU0V1HqujhqpPhEQ3cdAwCpMyT4hZFjCk9NPtUmMoheyNI6vIvZYQ9zvIpp4Xg+BCwtGltkyASz2z3nkk/RcslmyeAZlsHOQCpl1U5n/FCyBPYUB/O6cKGAzFT1QXFKplV/rjksSMV4WD8ABj4KTPFyBkVY04v7DMGB7w6WtrbTlDtNRKHyq7Rc7tqjHW4F7aIPtKR+yNIHOmIcoAAGFub/3LHQWOWLdLM3RRzYuYU+4VzYhxIetcR4kEEmPRu580Wkuvh3UKoc9LwswC2XF/RY4euTPqVUxLgGksgAAXkPlUf1er7ZpwANwGtLqkGg5dWKDxrmxC1VqQIiVtRJCN7db6LyMBAMARgjVJtNSm7EoQRKpNUqEDuC9NJLx5avIy696CmRcNvDU71pD71Dc6fUJ9PChWrQ0R1rp3R7C9M/FyhRPpRiNLGIhX9kAWhRjafBLpok5hiCYtoQN5wm1pmbKGsKZn4EWDeEghZniY37R1ZAFQqCcWiJnX+qoZaHsvco+xng/b4AYP2CBYR3kAZQhqHMmtqASzaaevyixLgAHUUSZxzA0SMYw6kVXQAwnyzDWHwLdi4IFlAJbRHrHY5gPgTSQGFnwJytUObtEajmU1HKFy3oaB6ZEorBi8BIEyzaOYryCj4IcqjBA+DVIimQQTWxWNGk5ZcPS45NyQo2rCTUqoBD4BcBWUcwLniIEjHIwGijKbntUZkOVo5DFkEjHzBxgLIB+PUEwTO5BcA9goL2KpcwdwnlrJqAjXLdL9PGHIUmLxNrbkLEfMAqpvDyGYIoLGUQ8VlN2S6TIhYiAmgFdusO8h5IvBkogNoYw6qzHoNJ0VLHMGTTkts2ILncBuawGYfYMRLhGEcAIMYwR2CJZWmEGrTnUmQtEXZ9okTTN0apZAcoTRfNtvgJR2BK6aNjD4K4gDsnf2BIKekmcE5A3zJeBxl0AY4V8uEkxzYl5ry0YbIWZhRzePZM2jEAAmtINo9YrkBaC5V6p4yGljkFUgSDshojjbO4FagALNQkxAtEOHlwBF/AqkN1sLoKzylVOQW7QnHtbeeyeVU7VusGA8PwTD2ol1+T8NOKolCExJjW+ITWngEj8ZZRqJ79GqDA786DhTC57OLmwMs8HJ2U4hn3XVU264+wruqjQOY0rsxbEQJFBgiToiQdwBLC2y9dI2ywgg+sOYhUu35WKj10rGVon9gq8QPbQ4ADkj53ulpqsKRCP2qgqtJb9ex4pbq2Du0le7jZB6PfIFDWxB2GvjcxY1yaeINCraSmtCRHXSgbQW3uqfE0D0CBQMAkE0kUAYJclgkryDLBEtM7JABFGwyqUsd2OvWrSTbDJfhNG2zeHaxXdpDjT8fWDGYt4We3zvSg8r19VOwA0a1vAhhY80HGaoNTblCg0Aa8VgU7Styi6AJ1cBL+YA31fDVNiJ6HVYbJ/M4oHMp2Qgk8BuNYYFp4JQqw38AIjMF+JC1+t+Gi98HoXoyWFYpyBSrO1CmoHkYUh+kk8U1AOI9ieAJAxm0YsYqAYw82oUMQQ0FyAOaYNydycOMQGMVwZY2++4tA+ApoLCjQ5uOyR0p0CQm0CussYM/AfA5QyIAcrKv4EBYQsSDYTYzwKAPyoQKgmUAh72IKiw0WNGf0A2xyyw+ufA0SaA6Ee4ZGoQm0lIFAkqYwhUtkbCig+u9Af+bS7oXwlU6kUA/EioP+3gscwAoBYQEgLg8AmAuAQacQ6gUQ9g6Yvgf2l+1s3+GAIRhQNUFAMQegTqUAgI3AtAQ+3hvhRSARQRIREQ4RkR3g0RJCsRRA8RMQiRts0RCQA0IRZBpKdeKYAWVBpK9yMyCyKRTqBgHuiU9Kww22u8NCjsngwhRo9mK4PsTYtAAsRAkYPsDO3woYM4RGPAviq+ieqAcBJQJuPKHBduZ+/+zsLgdub4Du1WTucqAcXUbuSqkA/R6AhxjGxxl6wq5xHsEqUqVxvsLudxwc7QlAng6YSg0+oSuxBe3chaxaJe/clcFyiANedeN+K+Te8IHilQs+/igSN8iAPe+a/ea8Q+kKI+5kXaIxE+lMlJ4JQ6mJXiDyOJeSmKy+jeHUGA6+m+cmjBykYq++aBx+fkp+YxYUASeS4BaJpCNOX+nhC2fwJxgBe2opgS8UHQgUth8B9YiBYJjMAp6A0IiosSuB86MYbSRBBSJBTRcuaSGScOuSi0tBRUDBgeWAzBrB9KzxAyOYesPBo4fBh6AhPsExoh4GWwLSqoAA5A/G6IWASHgQujqN9HWEkm8aFLMeEZ4tiZzP6aqLeiCsoNqEsq5LgFLljH5mYRYUiqGXZKyavk9L9Bod2nOvfrGM0gdjwdqAEBrtLvvleJgIgErMpBKWydhnIUuAgN4LQPeDTrAYksaIxusVCmIIlogiSW8djHtHvnev9Akj1HoWZvtnkhLjIZSiuk8AsvYkoceluiYfplLpWQ+iiOJB1DfvAjrDWcsIzqsVUD7JQH5HwOmZtGIRrJKfsVbC8ZbiKTbmcYxhcd8Xio7n8fKgCe7lAE8RVHyq8VBacSKnzuKpKghb8bKv8TofcUCQEGwk0J4NscgJCfmj3HRIhA2NVnvuhAPsZPQDhP+P4ARKScRPIIMFXtBJRHBDRIYExThOoAAPqLCIBSUBCxYVB0BSUJAuBhCPgGBMUACsAgwywyDANQAAHCUIZScAAAwkBmUCBaVoBmWHAMCGWGUkD7DGUnA1BmVnAnBaU2W0DDKiDDJmUnBiWaXPiQBOUACcJwJw4V+wgVaAJw+waATlaA4VhwJwtAZwJAAgsVwyWlhwAgDltA+wdQAgJQZl+wZwwVIVEAv4vQuAMl5M8lV6awSltAUldo+gQAA== -->

<!-- internal state end -->
<!-- tips_start -->

---

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: NONE
user: login: github-actions[bot]
created_at: 2025-03-03T11:12:18Z
body: <!-- projectId:15998f8a-e75c-4b60-959d-6f68e5ff4936 -->
🚀 Expo preview is ready!

- Project → **trezor-suite-preview**
- Platforms → **android**, **ios**
- Scheme → **trezorsuitelite**
- Runtime Version → **26**
- **[More info](https://expo.dev/projects/15998f8a-e75c-4b60-959d-6f68e5ff4936/updates/16a6ccdd-316c-40b5-aa85-0dce52c285fb)**

<a href="https://qr.expo.dev/eas-update?appScheme=trezor-suite-preview&projectId=15998f8a-e75c-4b60-959d-6f68e5ff4936&groupId=16a6ccdd-316c-40b5-aa85-0dce52c285fb"><img src="https://qr.expo.dev/eas-update?appScheme=trezor-suite-preview&projectId=15998f8a-e75c-4b60-959d-6f68e5ff4936&groupId=16a6ccdd-316c-40b5-aa85-0dce52c285fb" width="250px" height="250px" /></a>

> Learn more about [𝝠 Expo Github Action](https://github.com/expo/expo-github-action/tree/main/preview#example-workflows)
author_association: NONE
user: login: PeKne
created_at: 2025-03-03T11:29:57Z
body: /rebase
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-03-03T11:30:14Z
body: Start rebasing: https://github.com/trezor/trezor-suite/actions/runs/13629853454
author_association: NONE