Skip to content

Commit db8d3d0

Browse files
test: fixes unit test and addresses cursor comments
1 parent 372de3a commit db8d3d0

File tree

3 files changed

+66
-28
lines changed

3 files changed

+66
-28
lines changed

tests/framework/PageObjectMigrationTestUtils.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,18 @@ function atLeastOnePlaywrightMatcherWasCalled(): void {
6868
(PlaywrightMatchers.getElementById as jest.Mock).mock.calls.length +
6969
(PlaywrightMatchers.getElementByText as jest.Mock).mock.calls.length +
7070
(PlaywrightMatchers.getElementByAccessibilityId as jest.Mock).mock.calls
71-
.length;
71+
.length +
72+
(PlaywrightMatchers.getElementByXPath as jest.Mock).mock.calls.length +
73+
(PlaywrightMatchers.getElementByCatchAll as jest.Mock).mock.calls.length;
7274
expect(playwrightCallCount).toBeGreaterThan(0);
7375
}
7476

7577
function noPlaywrightMatcherWasCalled(): void {
7678
expect(PlaywrightMatchers.getElementById).not.toHaveBeenCalled();
7779
expect(PlaywrightMatchers.getElementByText).not.toHaveBeenCalled();
7880
expect(PlaywrightMatchers.getElementByAccessibilityId).not.toHaveBeenCalled();
81+
expect(PlaywrightMatchers.getElementByXPath).not.toHaveBeenCalled();
82+
expect(PlaywrightMatchers.getElementByCatchAll).not.toHaveBeenCalled();
7983
}
8084

8185
function noDetoxMatcherWasCalled(): void {

tests/page-objects/Onboarding/ImportWalletView.ts

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { encapsulatedAction } from '../../framework/encapsulatedAction';
1212
import PlaywrightMatchers from '../../framework/PlaywrightMatchers';
1313
import { PlatformDetector } from '../../framework/PlatformLocator';
1414
import { getDriver } from '../../framework/PlaywrightUtilities';
15+
import { ImportSRPIDs } from '../../../app/components/Views/ImportNewSecretRecoveryPhrase/SRPImport.testIds';
1516

1617
class ImportWalletView {
1718
get container(): DetoxElement {
@@ -52,6 +53,14 @@ class ImportWalletView {
5253
);
5354
}
5455

56+
/**
57+
* Returns the encapsulated element for the SRP input field at the given word index.
58+
*
59+
* iOS label convention: the first field (index 0) has no label filter;
60+
* subsequent fields use 1-indexed labels offset by one from the word index
61+
* (word 1 → label "2.", word 2 → label "3.", etc.).
62+
* This matches the native iOS SRP form where the first labeled field is "2.".
63+
*/
5564
seedPhraseInput(index: number): EncapsulatedElementType {
5665
return encapsulated({
5766
detox: () =>
@@ -72,7 +81,7 @@ class ImportWalletView {
7281
ios: () =>
7382
PlaywrightMatchers.getElementByXPath(
7483
index !== 0
75-
? `//XCUIElementTypeOther[@name="textfield" and @label="${index}."]`
84+
? `//XCUIElementTypeOther[@name="textfield" and @label="${index + 1}."]`
7685
: '//XCUIElementTypeOther[@name="textfield"]',
7786
),
7887
},
@@ -161,14 +170,42 @@ class ImportWalletView {
161170
});
162171
}
163172

173+
/**
174+
* Returns the input element for the given SRP index
175+
* @param srpIndex - The index of the SRP word
176+
* @param onboarding - Whether the screen is onboarding or not
177+
* @returns The input element for the given SRP index
178+
*/
179+
async inputOfIndex(
180+
srpIndex: number,
181+
onboarding: boolean = true,
182+
): Promise<string> {
183+
if (onboarding) {
184+
if (await PlatformDetector.isAndroid()) {
185+
return `${ImportFromSeedSelectorsIDs.SEED_PHRASE_INPUT_ID}_${srpIndex}`;
186+
}
187+
return `//XCUIElementTypeOther[@name="textfield" and @label="${srpIndex}."]`;
188+
189+
}
190+
if (await PlatformDetector.isAndroid()) {
191+
return `seed-phrase-input_${srpIndex}`;
192+
}
193+
return `//*[@label="${srpIndex + 1}."]`;
194+
195+
196+
}
197+
164198
/**
165199
* Types a secret recovery phrase word-by-word into the SRP input fields.
166-
* Handles platform-specific field indexing:
167-
* - Android: fields indexed from 0 (seed-phrase-input-id_0, _1, ...)
168-
* - iOS: fields indexed from 1 via XPath labels ("1.", "2.", ...)
200+
* Uses seedPhraseInput(i) for consistent selector resolution across platforms.
201+
*
202+
* Onboarding flow matches wdio ImportFromSeedScreen.typeSecretRecoveryPhrase:
203+
* - First word typed with trailing space into field 0
204+
* - Middle words typed with trailing space + tap into fields 1..n-2
205+
* - Last word typed WITHOUT trailing space into field n-1
206+
*
169207
* @param phrase - The secret recovery phrase to type
170208
* @param onboarding - Whether the screen is onboarding or not
171-
* @returns void
172209
*/
173210
async typeSecretRecoveryPhrase(
174211
phrase: string,
@@ -180,47 +217,42 @@ class ImportWalletView {
180217
const isAndroid = await PlatformDetector.isAndroid();
181218

182219
if (onboarding) {
183-
// Type first word into the first field
220+
// Type first word into the first field (with trailing space)
184221
const firstField = await asPlaywrightElement(this.seedPhraseInput(0));
185222
await firstField.type(`${phraseArray[0]} `);
186223

187-
// Type remaining words into indexed fields
188-
for (let i = 1; i < phraseArray.length; i++) {
189-
const fieldIndex = isAndroid ? i : i + 1;
190-
let input;
191-
if (isAndroid) {
192-
input = await PlaywrightMatchers.getElementById(
193-
`${ImportFromSeedSelectorsIDs.SEED_PHRASE_INPUT_ID}_${fieldIndex}`,
194-
);
195-
} else {
196-
input = await PlaywrightMatchers.getElementByXPath(
197-
`//XCUIElementTypeOther[@name="textfield" and @label="${fieldIndex}."]`,
198-
);
199-
}
224+
// Type middle words (with trailing space + tap)
225+
for (let i = 1; i < phraseArray.length - 1; i++) {
226+
const input = await asPlaywrightElement(this.seedPhraseInput(i));
200227
await input.type(`${phraseArray[i]} `);
201228
await input.click();
202229
}
230+
231+
// Type last word (without trailing space, no tap)
232+
const lastIndex = phraseArray.length - 1;
233+
const lastInput = await asPlaywrightElement(
234+
this.seedPhraseInput(lastIndex),
235+
);
236+
await lastInput.type(phraseArray[lastIndex]);
203237
} else {
204238
// Non-onboarding flow (adding additional SRP)
205239
let firstInput;
206240
if (isAndroid) {
207-
firstInput =
208-
await PlaywrightMatchers.getElementById('seed-phrase-input');
241+
firstInput = await PlaywrightMatchers.getElementById(
242+
ImportSRPIDs.SEED_PHRASE_INPUT_ID,
243+
);
209244
} else {
210245
firstInput = await PlaywrightMatchers.getElementById('textfield');
211246
}
212247
await firstInput.type(`${phraseArray[0]} `);
213248

214249
for (let i = 1; i < phraseArray.length; i++) {
250+
const fieldId = await this.inputOfIndex(i, false);
215251
let input;
216252
if (isAndroid) {
217-
input = await PlaywrightMatchers.getElementById(
218-
`seed-phrase-input_${i}`,
219-
);
253+
input = await PlaywrightMatchers.getElementById(fieldId);
220254
} else {
221-
input = await PlaywrightMatchers.getElementByXPath(
222-
`//*[@label="${i + 1}."]`,
223-
);
255+
input = await PlaywrightMatchers.getElementByXPath(fieldId);
224256
}
225257
await input.type(`${phraseArray[i]} `);
226258
await input.click();

tests/page-objects/migrated-page-objects.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ jest.mock('../framework/PlaywrightMatchers.ts', () => ({
2323
getElementById: jest.fn().mockResolvedValue({}),
2424
getElementByText: jest.fn().mockResolvedValue({}),
2525
getElementByAccessibilityId: jest.fn().mockResolvedValue({}),
26+
getElementByXPath: jest.fn().mockResolvedValue({}),
27+
getElementByCatchAll: jest.fn().mockResolvedValue({}),
2628
},
2729
}));
2830

0 commit comments

Comments
 (0)