-
Notifications
You must be signed in to change notification settings - Fork 54
test(swift-sdk): add testnet identity-discovery UI test #3560
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
base: v3.1-dev
Are you sure you want to change the base?
Changes from 2 commits
03af8e2
b3c85a2
7c0ae94
c08f9fa
52312a2
e8eb123
4e4cf1a
296d966
3823ee4
33b6f3c
a228c04
983f89c
4801f03
0e38b24
92cddcd
8cfad23
be5f3fa
a8ada7b
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 |
|---|---|---|
|
|
@@ -109,6 +109,12 @@ struct IdentityDetailView: View { | |
| Text(identity.formattedBalance) | ||
| .foregroundColor(.blue) | ||
| .fontWeight(.medium) | ||
| .accessibilityIdentifier("identityDetail.balanceLabel") | ||
| // Display string is "%.8f DASH" — rounding hides | ||
| // sub-1000-credit deltas. Expose the raw credit | ||
| // count via accessibilityValue for tests that | ||
| // need exact numbers. | ||
| .accessibilityValue("\(UInt64(bitPattern: identity.balance))") | ||
|
Collaborator
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. 🟡 Suggestion:
source: ['claude', 'codex'] 🤖 Fix this with AI agents
Collaborator
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. 🟡 Suggestion:
source: ['claude', 'codex'] 🤖 Fix this with AI agents |
||
| } | ||
|
|
||
| // Top-up entry point. Hidden for purely-local rows | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| // | ||
| // CreditTransferTest.swift | ||
| // SwiftExampleAppUITests | ||
| // | ||
| // Imports a wallet from a known testnet mnemonic that already has a | ||
| // registered identity, runs identity discovery, and asserts that the | ||
| // expected identity surfaces with a non-zero balance. The credit- | ||
| // transfer assertion is deferred to a follow-up. | ||
|
llbartekll marked this conversation as resolved.
Outdated
|
||
| // | ||
| // Skipped automatically when the env var is unset, so the rest of the | ||
| // suite can run locally without test-network credentials. | ||
| // | ||
| // Env var: | ||
| // * UI_TEST_TESTNET_MNEMONIC — sender wallet's 12-word phrase | ||
| // | ||
| // Note on env var forwarding: a previous run on this branch showed that | ||
| // `xcodebuild test ENV=...` did not propagate env vars to the XCUITest | ||
| // runner — only the prefix form `TEST_RUNNER_<NAME>` reached the test | ||
|
Comment on lines
+14
to
+22
Collaborator
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. 💬 Nitpick: PR description references Code (CreditTransferTest.swift:65), the file header (line 18), the in-class comment (line 31), and the CI workflow ( source: ['claude-general', 'codex-general']
Comment on lines
+14
to
+22
Collaborator
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. 💬 Nitpick: PR description references Code (CreditTransferTest.swift:18, regeneration comment), the CI workflow ( source: ['claude-general'] |
||
| // process (Xcode strips the prefix). Try the unprefixed form first; if | ||
| // the env var doesn't reach the test, use the prefixed form. | ||
|
Comment on lines
+16
to
+24
Collaborator
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. 💬 Nitpick: PR description references The PR description names the secret source: ['claude-general'] |
||
| // | ||
|
|
||
| import XCTest | ||
|
|
||
| final class CreditTransferTest: XCTestCase { | ||
| /// The pre-registered identity behind the sender mnemonic. Discovery | ||
| /// must surface this exact ID — that's the regression check on the | ||
| /// discovery path. | ||
| private let expectedSenderIdentityIdBase58 = "3ou98WEERy6ExmmHWYWsFtyhgW8rmr1giceZYTFqdAAA" | ||
|
|
||
| /// walletId derived from the test mnemonic (deterministic). Lets us | ||
| /// detect an already-imported wallet from a prior run and reuse it | ||
| /// instead of failing on `Wallet operation: Wallet already exists`. | ||
| private let expectedSenderWalletIdHex = "2450ec6b6dc2b1b0476875305a6870dee743d47474e3838642b655b68a600793" | ||
|
Comment on lines
+49
to
+57
Collaborator
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. 🟡 Suggestion: Hardcoded sender identityId/walletId silently couple to the rotating CI secret
source: ['claude'] 🤖 Fix this with AI agents |
||
|
|
||
| override func setUpWithError() throws { | ||
| continueAfterFailure = false | ||
| } | ||
|
|
||
| @MainActor | ||
| func testImportWalletAndDiscoverIdentity() throws { | ||
| guard let mnemonic = ProcessInfo.processInfo.environment["UI_TEST_TESTNET_MNEMONIC"], | ||
| !mnemonic.isEmpty | ||
| else { | ||
| throw XCTSkip("Set UI_TEST_TESTNET_MNEMONIC to run this test.") | ||
| } | ||
| XCTAssertEqual( | ||
| mnemonic.split(separator: " ").count, | ||
| 12, | ||
| "UI_TEST_TESTNET_MNEMONIC must be a 12-word phrase." | ||
| ) | ||
|
|
||
| let app = XCUIApplication() | ||
| app.launch() | ||
| failIfRecoveryPromptVisible(in: app, timeout: 2) | ||
|
|
||
| // Force testnet — the simulator may have been left on a non-testnet | ||
| // network by previous runs. Idempotent if already on Testnet. | ||
| switchAppNetworkToTestnet(in: app) | ||
|
llbartekll marked this conversation as resolved.
|
||
|
|
||
| openWalletsTab(in: app) | ||
|
|
||
| // Wallets restored from the persister on cold launch come back | ||
| // watch-only — the SwiftExampleApp comment in SwiftExampleAppApp.swift | ||
| // notes that biometric unlock to rehydrate signing keys is "future | ||
| // work". Identity discovery needs private keys, so a leftover | ||
| // wallet from a prior run is unusable. Delete it (if present) and | ||
| // re-import to get a hot, signing-capable wallet. | ||
| let existingRow = app.descendants(matching: .any) | ||
| .matching(identifier: "wallets.walletRow.\(expectedSenderWalletIdHex)") | ||
| .firstMatch | ||
| if existingRow.waitForExistence(timeout: 5) { | ||
| // accessibilityLabel == wallet.label, so .label gives us the name. | ||
| let staleName = existingRow.label | ||
| bestEffortDeleteWallet(named: staleName, in: app) | ||
| } | ||
|
llbartekll marked this conversation as resolved.
|
||
|
|
||
| let walletName = "ImportTransfer-\(UUID().uuidString.prefix(6))" | ||
| addTeardownBlock { | ||
| MainActor.assumeIsolated { | ||
| let cleanupApp = XCUIApplication() | ||
| cleanupApp.launch() | ||
| bestEffortDeleteWallet(named: walletName, in: cleanupApp) | ||
| cleanupApp.terminate() | ||
| } | ||
| } | ||
| importWallet(named: walletName, mnemonic: mnemonic, in: app) | ||
| assertWalletRowVisible(named: walletName, in: app, exists: true, timeout: 30) | ||
|
|
||
| openIdentitiesTab(in: app) | ||
| runIdentityDiscovery(forWalletNamed: walletName, in: app) | ||
|
|
||
| let senderRow = waitForIdentityRow(idBase58: expectedSenderIdentityIdBase58, in: app) | ||
| senderRow.tap() | ||
|
|
||
| let balance = readIdentityBalanceCredits(in: app) | ||
| XCTAssertGreaterThan( | ||
| balance, | ||
| 0, | ||
| "Discovered identity should have a non-zero balance." | ||
| ) | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.