diff --git a/AGENTS.md b/AGENTS.md index e1377c3..031cb2f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -160,13 +160,23 @@ Implication for feature work: The app merge gate (`e2e.yml` / `e2e-tests.yml`) runs `BACKEND=local` (docker Electrum/LND). Staging (`e2e-staging.yml`) and migration (`e2e_migration.yml`) run `BACKEND=regtest` against stag0. -| Tags | Where | -| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `@transfer_2` | Local only (LND channel, no Blocktank) | -| `@transfer_1`, `@transfer_max` | Staging via `@transfer_staging` (keep `@transfer_1` / `@transfer_max` / `@transfer`). `@transfer_1` is not in app `e2e-staging.yml` yet — add the transfer shard once it is 3× green. | -| `@multi_address_2` | Staging via `@multi_address_staging` (keep `@multi_address_2` for other greps). Staging workflow greps `@multi_address_staging` only. | -| `@pubky` / `@paykit` / `@pubky_profile` | Staging pubky shard via `@pubky_staging` (public-payments + profile). Keep `@pubky` / `@paykit` / `@pubky_profile` for other greps. | -| `@hardware_wallet` | iOS local (connect/receive/on-chain); Android full path on staging. Do **not** add `@hardware_wallet_staging` — local merge-gate still greps `@hardware_wallet`. | -| `@migration_*` | Migration workflow (nightly, dispatch, `release-*` PRs) | +Capability tags (`@settings`, `@boost`, `@send`, …) stay on titles so Android local can keep grepping them. iOS queue tags are disjoint from `@staging` and from `*_staging` (mocha grep is a regex substring). + +| Tag | Android local | iOS Mini (`e2e-tests.yml`) | Staging (`e2e-staging.yml`) | +|---|---|---|---| +| `@ios_gate` | ignored | merge gate grep | no | +| `@ios_nightly` | ignored (still run via `@settings` etc.) | no | extra iOS shard (`ios_nightly_ui`), GitHub mac, not Mini | +| `@transfer_2` | yes | `@ios_gate` | no (LND, no Blocktank) | +| `@transfer_1`, `@transfer_max` | no | no | `@transfer_staging` (keep `@transfer_1` / `@transfer_max` / `@transfer`). `@transfer_1` is not in app `e2e-staging.yml` yet — add the transfer shard once it is 3× green. | +| `@multi_address_2` | no | no | `@multi_address_staging` only | +| `@pubky` / `@paykit` / `@pubky_profile` | no | no | `@pubky_staging` (keep capability tags for other greps) | +| `@boost`, `@multi_address_3` | yes | `@ios_gate` (needs exclusive miner) | no | +| `@send_2`, `@send_3`, `@lightning`, `@lnurl`, `@onboarding`, `@backup`, `@onchain_1`, `@onchain_2`, `@receive`, `@multi_address_4` | yes | `@ios_gate` | no | +| `@settings`, `@numberpad`, `@widgets`, `@security`, `@send_1`, `@multi_address_1` | yes | `@ios_nightly` | iOS nightly shard | +| `@onchain_3` | yes (`@onchain`) | no | no | +| `@hardware_wallet` | no (staging only) | `@ios_gate` | Android staging greps `@hardware_wallet`; do **not** add `@hardware_wallet_staging`. iOS Mini greps `@ios_gate` on this describe. No Trezor on GitHub mac. | +| `@migration_*` | migration workflow (nightly, dispatch, `release-*` PRs) | same | no | + +Put `@ios_gate` / `@ios_nightly` on `describe` when the whole file is one iOS queue; on `ciIt` when siblings split (`@send_1` vs `@send_2`, `@multi_address_1` vs `_3`). Poke staging with `gh workflow run e2e-staging.yml` on the app repo (does not queue the iOS Mini). Optional Slack post to `#bitkit-staging-nightly` via dispatch `post_to_slack`. diff --git a/README.md b/README.md index b493bb1..d2bf349 100644 --- a/README.md +++ b/README.md @@ -292,16 +292,17 @@ npm run e2e:android -- --mochaOpts.grep "@onchain|@backup|@onboarding" npm run e2e:android -- --mochaOpts.grep "@backup" --mochaOpts.invert ``` -**Local vs staging (CI):** the app merge gate uses `BACKEND=local` and specific tags (`@transfer_2`, not blob `@transfer`). Staging shards grep dedicated `*_staging` tags: +**Local vs staging (CI):** the app merge gate uses `BACKEND=local`. Android greps capability tags (`@settings`, `@send`, `@boost`, …). iOS Mini greps `@ios_gate`. Staging shards grep dedicated `*_staging` tags, plus iOS-only `@ios_nightly` for UI that Android still runs on local: | Staging grep | Specs | | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | | `@transfer_staging` | `@transfer_1` and `@transfer_max` (keep those tags plus `@transfer` on the describe). `@transfer_1` is not in app `e2e-staging.yml` yet. | | `@multi_address_staging` | Staging multi-address (`@multi_address_2` kept for other greps) | | `@pubky_staging` | Public-payments + pubky-profile (`@pubky` / `@paykit` / `@pubky_profile` kept for other greps) | -| `@hardware_wallet` | Unchanged — do not add `@hardware_wallet_staging` (iOS local merge-gate still greps this) | +| `@ios_nightly` | iOS-only UI shard (`@settings`, `@numberpad`, `@widgets`, `@security`, `@send_1`, `@multi_address_1`). Does not queue the Mini. | +| `@hardware_wallet` | Android staging only — do not add `@hardware_wallet_staging` (iOS Mini greps `@ios_gate` on this describe) | -Bare `@staging` may still be present next to those tags. Migration (`@migration_*`) is a separate nightly / dispatch / `release-*` PR workflow. +Bare `@staging` may still be present next to the `*_staging` tags. Migration (`@migration_*`) is a separate nightly / dispatch / `release-*` PR workflow. See AGENTS.md for the full matrix. --- diff --git a/test/specs/backup.e2e.ts b/test/specs/backup.e2e.ts index 5b449db..76cab5d 100644 --- a/test/specs/backup.e2e.ts +++ b/test/specs/backup.e2e.ts @@ -21,7 +21,7 @@ import { ensureLocalFunds } from '../helpers/regtest'; import { openSettings } from '../helpers/navigation'; import { deleteAllDefaultWidgets } from '../helpers/widgets'; -describe('@backup - Backup', () => { +describe('@backup @ios_gate - Backup', () => { let electrum: Awaited> | undefined; before(async () => { diff --git a/test/specs/boost.e2e.ts b/test/specs/boost.e2e.ts index e7abf5a..0ff6d96 100644 --- a/test/specs/boost.e2e.ts +++ b/test/specs/boost.e2e.ts @@ -21,7 +21,7 @@ import { reinstallApp } from '../helpers/setup'; import { ciIt } from '../helpers/suite'; import { ensureLocalFunds, getExternalAddress, mineBlocks } from '../helpers/regtest'; -describe('@boost - Boost', () => { +describe('@boost @ios_gate - Boost', () => { let electrum: { waitForSync: any; stop: any }; before(async () => { diff --git a/test/specs/hardware-wallet.e2e.ts b/test/specs/hardware-wallet.e2e.ts index d2a1144..2bddb11 100644 --- a/test/specs/hardware-wallet.e2e.ts +++ b/test/specs/hardware-wallet.e2e.ts @@ -30,7 +30,7 @@ import { ensureLocalFunds, getBackend, getExternalAddress } from '../helpers/reg import { reinstallApp } from '../helpers/setup'; import { ciIt } from '../helpers/suite'; -describe('@hardware_wallet - Hardware Wallet', () => { +describe('@hardware_wallet @ios_gate - Hardware Wallet', () => { const walletLabel = 'E2E Trezor'; const renamedWalletLabel = 'E2E Renamed Trezor'; let electrum: Awaited> | undefined; diff --git a/test/specs/lightning.e2e.ts b/test/specs/lightning.e2e.ts index 09bd5bf..70c11ff 100644 --- a/test/specs/lightning.e2e.ts +++ b/test/specs/lightning.e2e.ts @@ -41,7 +41,7 @@ import { ciIt } from '../helpers/suite'; import { ensureLocalFunds, getBitcoinRpc, mineBlocks } from '../helpers/regtest'; import { openSettings } from '../helpers/navigation'; -describe('@lightning - Lightning', () => { +describe('@lightning @ios_gate - Lightning', () => { let electrum: { waitForSync: any; stop: any }; // LND tests only work with BACKEND=local let rpc: ReturnType; diff --git a/test/specs/lnurl.e2e.ts b/test/specs/lnurl.e2e.ts index 5bfa85e..544229b 100644 --- a/test/specs/lnurl.e2e.ts +++ b/test/specs/lnurl.e2e.ts @@ -74,7 +74,7 @@ function msatsToCeilSatsString(msats: number): string { return Math.ceil(msats / 1000).toString(); } -describe('@lnurl - LNURL', () => { +describe('@lnurl @ios_gate - LNURL', () => { let electrum: Awaited> | undefined; let lnurlServer: any; // LND tests only work with BACKEND=local diff --git a/test/specs/multiaddress.e2e.ts b/test/specs/multiaddress.e2e.ts index 26d6355..dd5c828 100644 --- a/test/specs/multiaddress.e2e.ts +++ b/test/specs/multiaddress.e2e.ts @@ -71,7 +71,7 @@ describe('@multi_address - Multi address', () => { await electrum?.stop(); }); - ciIt('@multi_address_1 - Receive to each address type and send max combined', async () => { + ciIt('@multi_address_1 @ios_nightly - Receive to each address type and send max combined', async () => { const addressTypes: addressTypePreference[] = ['p2pkh', 'p2sh-p2wpkh', 'p2wpkh', 'p2tr']; const satsPerAddressType = 100_000; const { totalFundedSats } = await switchAndFundEachAddressType({ @@ -174,7 +174,7 @@ describe('@multi_address - Multi address', () => { ); ciIt( - '@multi_address_3 - Receive to each type, send almost max, verify change to primary, then RBF', + '@multi_address_3 @ios_gate - Receive to each type, send almost max, verify change to primary, then RBF', async () => { const addressTypes: addressTypePreference[] = ['p2pkh', 'p2sh-p2wpkh', 'p2wpkh', 'p2tr']; const satsPerAddressType = 10_000; @@ -248,7 +248,7 @@ describe('@multi_address - Multi address', () => { ); ciIt( - '@multi_address_4 - Receive to each type, open external channel with max, keep Legacy untouched', + '@multi_address_4 @ios_gate - Receive to each type, open external channel with max, keep Legacy untouched', async () => { const rpc = getBitcoinRpc(); const addressTypes: addressTypePreference[] = ['p2pkh', 'p2sh-p2wpkh', 'p2wpkh', 'p2tr']; diff --git a/test/specs/numberpad.e2e.ts b/test/specs/numberpad.e2e.ts index d3d609e..31ee2e7 100644 --- a/test/specs/numberpad.e2e.ts +++ b/test/specs/numberpad.e2e.ts @@ -17,7 +17,7 @@ import { ciIt } from '../helpers/suite'; import { ensureLocalFunds } from '../helpers/regtest'; import { openSettings } from '../helpers/navigation'; -describe('@numberpad - NumberPad', () => { +describe('@numberpad @ios_nightly - NumberPad', () => { let electrum: Awaited> | undefined; before(async () => { diff --git a/test/specs/onboarding.e2e.ts b/test/specs/onboarding.e2e.ts index 54d8777..816b124 100644 --- a/test/specs/onboarding.e2e.ts +++ b/test/specs/onboarding.e2e.ts @@ -15,7 +15,7 @@ import { reinstallApp } from '../helpers/setup'; import { ciIt } from '../helpers/suite'; import { openSettings } from '../helpers/navigation'; -describe('@onboarding - Onboarding', () => { +describe('@onboarding @ios_gate - Onboarding', () => { beforeEach(async () => { await reinstallApp(); }); diff --git a/test/specs/onchain.e2e.ts b/test/specs/onchain.e2e.ts index 7802f75..bfb649e 100644 --- a/test/specs/onchain.e2e.ts +++ b/test/specs/onchain.e2e.ts @@ -55,7 +55,7 @@ describe('@onchain - Onchain', () => { await electrum?.stop(); }); - ciIt('@onchain_1 - Receive and send some out', async () => { + ciIt('@onchain_1 @ios_gate - Receive and send some out', async () => { // receive some first const satsToReceive = 100_000; await receiveOnchainFunds({ sats: satsToReceive, expectHighBalanceWarning: false }); @@ -107,7 +107,7 @@ describe('@onchain - Onchain', () => { // - shows warnings for sending over 100$ or 50% of total // - avoid creating dust output - ciIt('@onchain_2 - Can receive 2 transactions and send them all at once', async () => { + ciIt('@onchain_2 @ios_gate - Can receive 2 transactions and send them all at once', async () => { // - can receive to 2 addresses and tag them // for (let i = 1; i <= 2; i++) { const address = await getReceiveAddress(); diff --git a/test/specs/receive.e2e.ts b/test/specs/receive.e2e.ts index ea297f2..3eb6df4 100644 --- a/test/specs/receive.e2e.ts +++ b/test/specs/receive.e2e.ts @@ -13,7 +13,7 @@ import { import { reinstallApp } from '../helpers/setup'; import { ciIt } from '../helpers/suite'; -describe('@receive - Receive', () => { +describe('@receive @ios_gate - Receive', () => { before(async () => { await reinstallApp(); await completeOnboarding(); diff --git a/test/specs/security.e2e.ts b/test/specs/security.e2e.ts index 43add2d..c5a2d4d 100644 --- a/test/specs/security.e2e.ts +++ b/test/specs/security.e2e.ts @@ -18,7 +18,7 @@ import { ciIt } from '../helpers/suite'; import { ensureLocalFunds, getExternalAddress } from '../helpers/regtest'; import { openSettings } from '../helpers/navigation'; -describe('@security - Security And Privacy', () => { +describe('@security @ios_nightly - Security And Privacy', () => { let electrum: { waitForSync: any; stop: any }; before(async () => { diff --git a/test/specs/send.e2e.ts b/test/specs/send.e2e.ts index 7be8943..d5f92fb 100644 --- a/test/specs/send.e2e.ts +++ b/test/specs/send.e2e.ts @@ -50,11 +50,8 @@ import { openSettings } from '../helpers/navigation'; describe('@send - Send', () => { let electrum: { waitForSync: any; stop: any }; - // LND tests only work with BACKEND=local - let rpc: ReturnType; before(async () => { - rpc = getBitcoinRpc(); await ensureLocalFunds(); electrum = await initElectrum(); }); @@ -69,7 +66,7 @@ describe('@send - Send', () => { electrum?.stop(); }); - ciIt('@send_1 - Validates payment data in the manual input', async () => { + ciIt('@send_1 @ios_nightly - Validates payment data in the manual input', async () => { await tap('Send'); await sleep(1000); await handleAndroidAlert('permission_allow_foreground_only_button'); @@ -98,7 +95,7 @@ describe('@send - Send', () => { } // check validation for address when balance is 0 - const address = await rpc.getNewAddress(); + const address = await getExternalAddress(); console.info({ address }); try { await typeRecipientInput(address, { confirmKeyboard: false }); @@ -184,7 +181,7 @@ describe('@send - Send', () => { } }); - ciIt('@send_2 - Can receive funds and send to different invoices', async () => { + ciIt('@send_2 @ios_gate - Can receive funds and send to different invoices', async () => { // Test plan: // Prepare // - receive onchain funds @@ -201,7 +198,7 @@ describe('@send - Send', () => { await receiveOnchainFunds(); - // send funds to LND node and open a channel + const rpc = getBitcoinRpc(); const { lnd, lndNodeID } = await setupLND(rpc, lndConfig); await electrum?.waitForSync(); @@ -554,10 +551,10 @@ describe('@send - Send', () => { await elementById('Activity-2').waitForDisplayed(); }); - ciIt('@send_3 - Can pay regular invoices with msat precision', async () => { + ciIt('@send_3 @ios_gate - Can pay regular invoices with msat precision', async () => { await receiveOnchainFunds(); - // send funds to LND node and open a channel + const rpc = getBitcoinRpc(); const { lnd, lndNodeID } = await setupLND(rpc, lndConfig); await electrum?.waitForSync(); diff --git a/test/specs/settings.e2e.ts b/test/specs/settings.e2e.ts index 28fc6c1..9fdc46e 100644 --- a/test/specs/settings.e2e.ts +++ b/test/specs/settings.e2e.ts @@ -18,12 +18,12 @@ import { waitForToast, ToastId, } from '../helpers/actions'; -import { electrumHost, electrumPort } from '../helpers/constants'; +import { electrumHost, electrumPort, getBackend } from '../helpers/constants'; import { launchFreshApp, reinstallApp } from '../helpers/setup'; import { ciIt } from '../helpers/suite'; import { openSettings, openSupport } from '../helpers/navigation'; -describe('@settings - Settings', () => { +describe('@settings @ios_nightly - Settings', () => { before(async () => { await reinstallApp(); await completeOnboarding(); @@ -323,6 +323,11 @@ describe('@settings - Settings', () => { }); ciIt('@settings_10 - Can enter wrong Electrum server and get an error message', async () => { + if (getBackend() !== 'local') { + console.info('→ Skipping Electrum TCP/TLS format checks (BACKEND is not local)'); + return; + } + await openSettings('advanced'); await tap('ElectrumConfig'); diff --git a/test/specs/transfer.e2e.ts b/test/specs/transfer.e2e.ts index 4fac660..12cdaa5 100644 --- a/test/specs/transfer.e2e.ts +++ b/test/specs/transfer.e2e.ts @@ -725,7 +725,7 @@ describe('@transfer - Transfer', () => { } ); - ciIt('@transfer_2 - Can open a channel to external node', async () => { + ciIt('@transfer_2 @ios_gate - Can open a channel to external node', async () => { const rpc = getBitcoinRpc(); await receiveOnchainFunds({ sats: 100_000 }); diff --git a/test/specs/widgets.e2e.ts b/test/specs/widgets.e2e.ts index fde00ae..df5dede 100644 --- a/test/specs/widgets.e2e.ts +++ b/test/specs/widgets.e2e.ts @@ -24,7 +24,7 @@ import { type WidgetId, } from '../helpers/widgets'; -describe('@widgets - Widgets', () => { +describe('@widgets @ios_nightly - Widgets', () => { beforeEach(async () => { await reinstallApp(); await completeOnboarding();