From d4a39282f3c02e47e562647f45f082fff01c3b78 Mon Sep 17 00:00:00 2001 From: Miki-Session Date: Tue, 12 Nov 2024 09:59:37 +1100 Subject: [PATCH 1/6] new test specs for onboarding back button/warning modals --- run/test/specs/locators/onboarding.ts | 27 +++++++++++++++++++ .../specs/warning_modal_new_account.spec.ts | 27 +++++++++++++++++++ .../warning_modal_restore_account.spec.ts | 24 +++++++++++++++++ run/types/testing.ts | 7 ++--- 4 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 run/test/specs/warning_modal_new_account.spec.ts create mode 100644 run/test/specs/warning_modal_restore_account.spec.ts diff --git a/run/test/specs/locators/onboarding.ts b/run/test/specs/locators/onboarding.ts index c44ad616..dfb9fd5e 100644 --- a/run/test/specs/locators/onboarding.ts +++ b/run/test/specs/locators/onboarding.ts @@ -1,3 +1,4 @@ +import { StrategyExtractionObj } from '../../../types/testing'; import { LocatorsInterface } from './index'; // SHARED LOCATORS @@ -20,6 +21,32 @@ export class ErrorMessage extends LocatorsInterface { } } +export class BackButton extends LocatorsInterface { + public build() { + switch (this.platform) { + case 'android': + return { + strategy: 'id', + selector: 'network.loki.messenger:id/back_button', + } as const; + case 'ios': + return { + strategy: 'accessibility id', + selector: 'Back', + } as const; + } + } +} + +export class WarningModalQuitButton extends LocatorsInterface { + public build(): StrategyExtractionObj { + return { + strategy: 'id', + selector: 'Quit' + } as const + } +} + // SPLASH SCREEN export class CreateAccountButton extends LocatorsInterface { public build() { diff --git a/run/test/specs/warning_modal_new_account.spec.ts b/run/test/specs/warning_modal_new_account.spec.ts new file mode 100644 index 00000000..622a9c3d --- /dev/null +++ b/run/test/specs/warning_modal_new_account.spec.ts @@ -0,0 +1,27 @@ +import { bothPlatformsIt } from "../../types/sessionIt"; +import { CreateAccountButton, BackButton, DisplayNameInput, SlowModeRadio, ContinueButton, WarningModalQuitButton } from "./locators/onboarding"; +import { SupportedPlatformsType } from "./utils/open_app"; +import { openAppOnPlatformSingleDevice, closeApp } from "./utils/open_app"; +import { USERNAME } from "../../types/testing"; + +bothPlatformsIt('Warning modal new account', 'medium', warningModalNewAccount) + +async function warningModalNewAccount(platform: SupportedPlatformsType) { + const { device } = await openAppOnPlatformSingleDevice(platform); + await device.clickOnElementAll(new CreateAccountButton(device)); + await device.inputText(USERNAME.ALICE, new DisplayNameInput(device)); + await device.clickOnElementAll(new ContinueButton(device)); + // Checking that we're on the Message Notifications screen + await device.doesElementExist(new SlowModeRadio(device)); + // Pressing Back on the Message Notifications screen + await device.clickOnElementAll(new BackButton(device)); + // Verifying that pressing Back from the Message Notifications screen does not bring up a modal but instead shows the Display Name input field + await device.doesElementExist(new DisplayNameInput(device)); + await device.clickOnElementAll(new BackButton(device)); + await device.checkModalStrings( + 'warning', + 'onboardingBackAccountCreation' + ) + await device.clickOnElementAll(new WarningModalQuitButton(device)); + await closeApp(device); +} \ No newline at end of file diff --git a/run/test/specs/warning_modal_restore_account.spec.ts b/run/test/specs/warning_modal_restore_account.spec.ts new file mode 100644 index 00000000..c8e8e5e1 --- /dev/null +++ b/run/test/specs/warning_modal_restore_account.spec.ts @@ -0,0 +1,24 @@ +import { bothPlatformsIt } from "../../types/sessionIt"; +import { SeedPhraseInput, BackButton, SlowModeRadio, ContinueButton, AccountRestoreButton, WarningModalQuitButton } from "./locators/onboarding"; +import { SupportedPlatformsType } from "./utils/open_app"; +import { openAppOnPlatformSingleDevice, closeApp } from "./utils/open_app"; + +bothPlatformsIt('Warning modal restore account', 'medium', warningModalRestoreAccount) + +async function warningModalRestoreAccount(platform: SupportedPlatformsType) { + const { device } = await openAppOnPlatformSingleDevice(platform); + const seedPhrase = 'eldest fazed hybrid buzzer nasty domestic digit pager unusual purged makeup assorted domestic' + await device.clickOnElementAll(new AccountRestoreButton(device)); + await device.inputText(seedPhrase, new SeedPhraseInput(device)); + await device.clickOnElementAll(new ContinueButton(device)); + // Checking that we're on the Message Notifications screen + await device.doesElementExist(new SlowModeRadio(device).build()); + // Pressing Back on the Message Notifications screen + await device.clickOnElementAll(new BackButton(device)); + await device.checkModalStrings( + 'warning', + 'onboardingBackLoadAccount' + ) + await device.clickOnElementAll(new WarningModalQuitButton(device)); + await closeApp(device); +} \ No newline at end of file diff --git a/run/types/testing.ts b/run/types/testing.ts index 71898daf..1d3d88bf 100644 --- a/run/types/testing.ts +++ b/run/types/testing.ts @@ -360,9 +360,10 @@ export type Id = | 'network.loki.messenger:id/action_apply' | 'Save' | 'android:id/content_preview_text' - | 'network.loki.messenger:id/search_result_title'; - | 'Error message'; - | 'network.loki.messenger:id/action_apply'; + | 'network.loki.messenger:id/search_result_title' + | 'network.loki.messenger:id/action_apply' + | 'network.loki.messenger:id/back_button' + | 'Quit'; export type testRisk = | 'high' From 2dd5d84f08b03f23a5f73ca0c330f5280cb65e33 Mon Sep 17 00:00:00 2001 From: Miki-Session Date: Tue, 12 Nov 2024 10:00:43 +1100 Subject: [PATCH 2/6] checkModalStrings was missing modal description confirmation --- run/types/DeviceWrapper.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/run/types/DeviceWrapper.ts b/run/types/DeviceWrapper.ts index 2ead5252..7a5ac256 100644 --- a/run/types/DeviceWrapper.ts +++ b/run/types/DeviceWrapper.ts @@ -1795,13 +1795,13 @@ export class DeviceWrapper { }); } const actualHeading = await this.getTextFromElement(elHeading); - if (expectedHeading === actualHeading) { - console.log('Modal heading is correct'); - } else { + if (expectedHeading !== actualHeading) { throw new Error( // eslint-disable-next-line @typescript-eslint/restrict-template-expressions `Modal heading is incorrect. Expected heading: ${expectedHeading}, Actual heading: ${actualHeading}` ); + } else { + console.log('Modal heading is correct'); } // Now check modal description // let expectedDescription; @@ -1828,6 +1828,8 @@ export class DeviceWrapper { throw new Error( `Modal description is incorrect. Expected description: ${expectedDescription}, Actual description: ${formattedDescription}` ); + } else { + console.log('Modal description is correct') } } From a765d8a9cc0bca3afad51f4db16707706a7a3bc7 Mon Sep 17 00:00:00 2001 From: Miki-Session Date: Wed, 13 Nov 2024 15:12:20 +1100 Subject: [PATCH 3/6] remove redundant entries from testing.ts --- run/types/testing.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/run/types/testing.ts b/run/types/testing.ts index c17a1cb4..49a2e788 100644 --- a/run/types/testing.ts +++ b/run/types/testing.ts @@ -329,9 +329,7 @@ export type AccessibilityId = | 'Error message' | 'Open URL' | 'Terms of Service' - | 'Terms of service button' | 'Privacy Policy' - | 'Privacy policy button' | 'TabBarItemTitle' | 'URL' | 'Save'; From 692d700c0592140988f48d1aa1688b5a410ffef1 Mon Sep 17 00:00:00 2001 From: Miki-Session Date: Thu, 14 Nov 2024 09:23:38 +1100 Subject: [PATCH 4/6] make warning modal test case comments more consistent --- run/test/specs/warning_modal_new_account.spec.ts | 1 + run/test/specs/warning_modal_restore_account.spec.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/run/test/specs/warning_modal_new_account.spec.ts b/run/test/specs/warning_modal_new_account.spec.ts index 622a9c3d..7288debc 100644 --- a/run/test/specs/warning_modal_new_account.spec.ts +++ b/run/test/specs/warning_modal_new_account.spec.ts @@ -17,6 +17,7 @@ async function warningModalNewAccount(platform: SupportedPlatformsType) { await device.clickOnElementAll(new BackButton(device)); // Verifying that pressing Back from the Message Notifications screen does not bring up a modal but instead shows the Display Name input field await device.doesElementExist(new DisplayNameInput(device)); + // Pressing Back on the Display Name screen to trigger the Warning modal await device.clickOnElementAll(new BackButton(device)); await device.checkModalStrings( 'warning', diff --git a/run/test/specs/warning_modal_restore_account.spec.ts b/run/test/specs/warning_modal_restore_account.spec.ts index c8e8e5e1..fb783d06 100644 --- a/run/test/specs/warning_modal_restore_account.spec.ts +++ b/run/test/specs/warning_modal_restore_account.spec.ts @@ -13,7 +13,7 @@ async function warningModalRestoreAccount(platform: SupportedPlatformsType) { await device.clickOnElementAll(new ContinueButton(device)); // Checking that we're on the Message Notifications screen await device.doesElementExist(new SlowModeRadio(device).build()); - // Pressing Back on the Message Notifications screen + // Pressing Back on the Message Notifications screen to trigger the Warning modal await device.clickOnElementAll(new BackButton(device)); await device.checkModalStrings( 'warning', From b379ccdd1b4959a004c2a16f2d6611276b0d4a2c Mon Sep 17 00:00:00 2001 From: Miki-Session Date: Thu, 14 Nov 2024 09:26:42 +1100 Subject: [PATCH 5/6] chore: yarn lint --- .github/workflows/android-regression.yml | 2 +- run/localizer/Localizer.ts | 2 +- run/test/specs/community_tests_image.spec.ts | 2 +- run/test/specs/disappear_after_send.spec.ts | 7 +- .../disappearing_community_invite.spec.ts | 6 +- .../group_disappearing_messages_image.spec.ts | 2 +- run/test/specs/group_message_delete.spec.ts | 2 +- .../specs/group_tests_add_contact.spec.ts | 2 +- .../specs/group_tests_create_group.spec.ts | 2 +- .../onboarding_incorrect_seed.spec.ts | 47 ++++--- .../onboarding_long_name.spec.ts | 31 +++-- .../onboarding_no_name.spec.ts | 20 +-- .../onboarding_no_seed.spec.ts | 52 ++++---- .../onboarding_wrong_seed.spec.ts | 51 +++---- run/test/specs/invite_a_friend_share.spec.ts | 72 +++++----- run/test/specs/linked_device.spec.ts | 2 +- run/test/specs/linked_group_leave.spec.ts | 2 +- run/test/specs/locators/browsers.ts | 94 ++++++------- run/test/specs/locators/conversation.ts | 14 +- run/test/specs/locators/global.ts | 10 +- run/test/specs/locators/global_search.ts | 31 +++-- run/test/specs/locators/home.ts | 40 +++--- run/test/specs/locators/onboarding.ts | 82 ++++++------ run/test/specs/locators/start_conversation.ts | 124 +++++++++--------- .../specs/message_requests_accept.spec.ts | 2 +- run/test/specs/message_requests_block.spec.ts | 2 +- .../specs/message_requests_clear_all.spec.ts | 2 +- run/test/specs/onboarding_pp.spec.ts | 67 +++++----- run/test/specs/onboarding_tos.spec.ts | 67 +++++----- .../specs/utils/chrome_first_time_open.ts | 24 ++-- .../specs/warning_modal_new_account.spec.ts | 54 ++++---- .../warning_modal_restore_account.spec.ts | 47 ++++--- run/types/DeviceWrapper.ts | 4 +- run/types/RangeType.ts | 6 +- run/types/sessionIt.ts | 2 +- run/types/testing.ts | 6 +- 36 files changed, 514 insertions(+), 468 deletions(-) diff --git a/.github/workflows/android-regression.yml b/.github/workflows/android-regression.yml index 70ab3b3e..e297dfe0 100644 --- a/.github/workflows/android-regression.yml +++ b/.github/workflows/android-regression.yml @@ -3,7 +3,7 @@ on: workflow_dispatch: inputs: tags: - description: "APK.tar.gz url to test" + description: 'APK.tar.gz url to test' required: true type: string # push: diff --git a/run/localizer/Localizer.ts b/run/localizer/Localizer.ts index b0215482..2c40bc35 100644 --- a/run/localizer/Localizer.ts +++ b/run/localizer/Localizer.ts @@ -68,4 +68,4 @@ export type I18nMethods = { export type SetupI18nReturnType = I18nMethods & (( ...[token, args]: GetMessageArgs - ) => R); \ No newline at end of file + ) => R); diff --git a/run/test/specs/community_tests_image.spec.ts b/run/test/specs/community_tests_image.spec.ts index 727a15a6..75b94232 100644 --- a/run/test/specs/community_tests_image.spec.ts +++ b/run/test/specs/community_tests_image.spec.ts @@ -7,7 +7,7 @@ import { newContact } from './utils/create_contact'; import { joinCommunity } from './utils/join_community'; import { SupportedPlatformsType, closeApp, openAppTwoDevices } from './utils/open_app'; -iosIt('Send image to community','medium', sendImageCommunityiOS); +iosIt('Send image to community', 'medium', sendImageCommunityiOS); androidIt('Send image to community', 'medium', sendImageCommunityAndroid); async function sendImageCommunityiOS(platform: SupportedPlatformsType) { diff --git a/run/test/specs/disappear_after_send.spec.ts b/run/test/specs/disappear_after_send.spec.ts index 92aa18db..78b29d59 100644 --- a/run/test/specs/disappear_after_send.spec.ts +++ b/run/test/specs/disappear_after_send.spec.ts @@ -1,5 +1,10 @@ import { bothPlatformsIt } from '../../types/sessionIt'; -import { DisappearActions, DISAPPEARING_TIMES, DisappearModes, USERNAME } from '../../types/testing'; +import { + DisappearActions, + DISAPPEARING_TIMES, + DisappearModes, + USERNAME, +} from '../../types/testing'; import { sleepFor } from './utils'; import { newUser } from './utils/create_account'; import { newContact } from './utils/create_contact'; diff --git a/run/test/specs/disappearing_community_invite.spec.ts b/run/test/specs/disappearing_community_invite.spec.ts index 3eb2e4b0..573cc038 100644 --- a/run/test/specs/disappearing_community_invite.spec.ts +++ b/run/test/specs/disappearing_community_invite.spec.ts @@ -10,7 +10,11 @@ import { setDisappearingMessage } from './utils/set_disappearing_messages'; import { testCommunityLink, testCommunityName } from './../../constants/community'; iosIt('Disappearing community invite message 1o1', 'low', disappearingCommunityInviteMessage1o1Ios); -androidIt('Disappearing community invite message 1o1', 'low', disappearingCommunityInviteMessage1o1Android); +androidIt( + 'Disappearing community invite message 1o1', + 'low', + disappearingCommunityInviteMessage1o1Android +); const time = DISAPPEARING_TIMES.THIRTY_SECONDS; const timerType = 'Disappear after send option'; diff --git a/run/test/specs/group_disappearing_messages_image.spec.ts b/run/test/specs/group_disappearing_messages_image.spec.ts index dcb13c0f..c5c65656 100644 --- a/run/test/specs/group_disappearing_messages_image.spec.ts +++ b/run/test/specs/group_disappearing_messages_image.spec.ts @@ -7,7 +7,7 @@ import { SupportedPlatformsType, closeApp, openAppThreeDevices } from './utils/o import { setDisappearingMessage } from './utils/set_disappearing_messages'; iosIt('Disappearing image message to group', 'low', disappearingImageMessageGroup); -// TODO write Android test +// TODO write Android test async function disappearingImageMessageGroup(platform: SupportedPlatformsType) { const { device1, device2, device3 } = await openAppThreeDevices(platform); diff --git a/run/test/specs/group_message_delete.spec.ts b/run/test/specs/group_message_delete.spec.ts index fe70673e..3112707c 100644 --- a/run/test/specs/group_message_delete.spec.ts +++ b/run/test/specs/group_message_delete.spec.ts @@ -82,4 +82,4 @@ async function deleteMessageGroupAndroid(platform: SupportedPlatformsType) { }); // Excellent await closeApp(device1, device2, device3); -} \ No newline at end of file +} diff --git a/run/test/specs/group_tests_add_contact.spec.ts b/run/test/specs/group_tests_add_contact.spec.ts index 5c4c2e3c..92dd5c54 100644 --- a/run/test/specs/group_tests_add_contact.spec.ts +++ b/run/test/specs/group_tests_add_contact.spec.ts @@ -1,5 +1,5 @@ import { englishStripped } from '../../localizer/i18n/localizedString'; -import { bothPlatformsIt,} from '../../types/sessionIt'; +import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { ApplyChanges, EditGroup, InviteContactsButton, InviteContactsMenuItem } from './locators'; import { runOnlyOnAndroid, runOnlyOnIOS, sleepFor } from './utils'; diff --git a/run/test/specs/group_tests_create_group.spec.ts b/run/test/specs/group_tests_create_group.spec.ts index 6a0fe023..707c186e 100644 --- a/run/test/specs/group_tests_create_group.spec.ts +++ b/run/test/specs/group_tests_create_group.spec.ts @@ -4,7 +4,7 @@ import { newUser } from './utils/create_account'; import { createGroup } from './utils/create_group'; import { SupportedPlatformsType, closeApp, openAppThreeDevices } from './utils/open_app'; -bothPlatformsIt("Create group", 'high', groupCreation); +bothPlatformsIt('Create group', 'high', groupCreation); async function groupCreation(platform: SupportedPlatformsType) { const testGroupName = 'Test group'; diff --git a/run/test/specs/input_validations/onboarding_incorrect_seed.spec.ts b/run/test/specs/input_validations/onboarding_incorrect_seed.spec.ts index 097937b9..1427568d 100644 --- a/run/test/specs/input_validations/onboarding_incorrect_seed.spec.ts +++ b/run/test/specs/input_validations/onboarding_incorrect_seed.spec.ts @@ -1,32 +1,37 @@ import { bothPlatformsIt } from '../../../types/sessionIt'; -import { AccountRestoreButton, SeedPhraseInput, ContinueButton, ErrorMessage } from '../locators/onboarding'; +import { + AccountRestoreButton, + SeedPhraseInput, + ContinueButton, + ErrorMessage, +} from '../locators/onboarding'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from '../utils/open_app'; import { localize } from '../../../localizer/i18n/localizedString'; bothPlatformsIt('Onboarding incorrect seed', 'low', onboardingIncorrectSeed); // the word 'zork' is not on the mnemonic word list which triggers the expected error -const incorrectSeed = 'ruby bakery illness push rift reef nabbing bawled hope zork silk lobster hope' +const incorrectSeed = + 'ruby bakery illness push rift reef nabbing bawled hope zork silk lobster hope'; // the expected error is 'Some words are incorrect' which is represented by the following localized string const expectedError = localize('recoveryPasswordErrorMessageIncorrect').strip().toString(); async function onboardingIncorrectSeed(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); - await device.clickOnElementAll(new AccountRestoreButton(device)); - await device.inputText(incorrectSeed, new SeedPhraseInput(device)); - // Trigger the validation by pressing Continue - await device.clickOnElementAll(new ContinueButton(device)); - // Wait for, and fetch the error message on Android - const error = await device.waitForTextElementToBePresent(new ErrorMessage(device).build()); - const errorMessage = await device.getTextFromElement(error); - console.log(`The error message is "${errorMessage}"`); - console.log(`The expected error is "${expectedError}"`); - // Compare the fetched string with the expected string - if (errorMessage === expectedError) { - console.log('The observed error message matches the expected'); - } - else { - throw new Error ('The observed error message does not match the expected'); - } - await closeApp(device); -} \ No newline at end of file + const { device } = await openAppOnPlatformSingleDevice(platform); + await device.clickOnElementAll(new AccountRestoreButton(device)); + await device.inputText(incorrectSeed, new SeedPhraseInput(device)); + // Trigger the validation by pressing Continue + await device.clickOnElementAll(new ContinueButton(device)); + // Wait for, and fetch the error message on Android + const error = await device.waitForTextElementToBePresent(new ErrorMessage(device).build()); + const errorMessage = await device.getTextFromElement(error); + console.log(`The error message is "${errorMessage}"`); + console.log(`The expected error is "${expectedError}"`); + // Compare the fetched string with the expected string + if (errorMessage === expectedError) { + console.log('The observed error message matches the expected'); + } else { + throw new Error('The observed error message does not match the expected'); + } + await closeApp(device); +} diff --git a/run/test/specs/input_validations/onboarding_long_name.spec.ts b/run/test/specs/input_validations/onboarding_long_name.spec.ts index fae8dc42..7000a237 100644 --- a/run/test/specs/input_validations/onboarding_long_name.spec.ts +++ b/run/test/specs/input_validations/onboarding_long_name.spec.ts @@ -1,36 +1,43 @@ import { bothPlatformsIt } from '../../../types/sessionIt'; -import { CreateAccountButton, DisplayNameInput, ContinueButton, ErrorMessage } from '../locators/onboarding'; +import { + CreateAccountButton, + DisplayNameInput, + ContinueButton, + ErrorMessage, +} from '../locators/onboarding'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from '../utils/open_app'; import { localize } from '../../../localizer/i18n/localizedString'; bothPlatformsIt('Onboarding long name', 'low', onboardingLongName); // the libSession limit for display names is 100 bytes - this string is 101 chars (i.e. 101 bytes) -const tooLongName = 'One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed int'; +const tooLongName = + 'One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed int'; // the expected error is 'Please enter a shorter display name' which is represented by the following localized string const expectedError = localize('displayNameErrorDescriptionShorter').strip().toString(); -async function onboardingLongName(platform:SupportedPlatformsType) { +async function onboardingLongName(platform: SupportedPlatformsType) { const { device } = await openAppOnPlatformSingleDevice(platform); await device.clickOnElementAll(new CreateAccountButton(device)); - // this check is to avoid false positives - if (tooLongName.length <= 100) { - throw new Error (`The string to test the display name length check is too short. It is only ${tooLongName.length} characters long but needs to be >100.`); + // this check is to avoid false positives + if (tooLongName.length <= 100) { + throw new Error( + `The string to test the display name length check is too short. It is only ${tooLongName.length} characters long but needs to be >100.` + ); } await device.inputText(tooLongName, new DisplayNameInput(device)); // Trigger the validation by pressing Continue await device.clickOnElementAll(new ContinueButton(device)); - // Wait for, and fetch the error message + // Wait for, and fetch the error message const error = await device.waitForTextElementToBePresent(new ErrorMessage(device).build()); const errorMessage = await device.getTextFromElement(error); console.log(`The error message is "${errorMessage}"`); console.log(`The expected error is "${expectedError}"`); // Compare the fetched string with the expected string - if (errorMessage === expectedError) { + if (errorMessage === expectedError) { console.log('The observed error message matches the expected'); - } - else { - throw new Error ('The observed error message does not match the expected'); + } else { + throw new Error('The observed error message does not match the expected'); } await closeApp(device); -} \ No newline at end of file +} diff --git a/run/test/specs/input_validations/onboarding_no_name.spec.ts b/run/test/specs/input_validations/onboarding_no_name.spec.ts index 390359f5..76736d50 100644 --- a/run/test/specs/input_validations/onboarding_no_name.spec.ts +++ b/run/test/specs/input_validations/onboarding_no_name.spec.ts @@ -1,5 +1,10 @@ import { bothPlatformsIt } from '../../../types/sessionIt'; -import { CreateAccountButton, DisplayNameInput, ContinueButton, ErrorMessage} from '../locators/onboarding'; +import { + CreateAccountButton, + DisplayNameInput, + ContinueButton, + ErrorMessage, +} from '../locators/onboarding'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from '../utils/open_app'; import { localize } from '../../../localizer/i18n/localizedString'; @@ -9,12 +14,12 @@ const emptyName = ''; // the expected error is 'Please enter a display name' which is represented by the following localized string const expectedError = localize('displayNameErrorDescription').strip().toString(); -async function onboardingNoName(platform:SupportedPlatformsType) { +async function onboardingNoName(platform: SupportedPlatformsType) { const { device } = await openAppOnPlatformSingleDevice(platform); await device.clickOnElementAll(new CreateAccountButton(device)); // this check is to avoid false positives if (emptyName.length > 0) { - throw new Error ('The emptyName string is not empty but it must be.') + throw new Error('The emptyName string is not empty but it must be.'); } await device.inputText(emptyName, new DisplayNameInput(device)); // Trigger the validation by pressing Continue @@ -25,11 +30,10 @@ async function onboardingNoName(platform:SupportedPlatformsType) { console.log(`The error message is "${errorMessage}"`); console.log(`The expected error is "${expectedError}"`); // Compare the fetched text with the expected 'Please enter a display name' string - if (errorMessage === expectedError) { + if (errorMessage === expectedError) { console.log('The observed error message matches the expected'); - } - else { - throw new Error ('The observed error message does not match the expected'); + } else { + throw new Error('The observed error message does not match the expected'); } await closeApp(device); -} \ No newline at end of file +} diff --git a/run/test/specs/input_validations/onboarding_no_seed.spec.ts b/run/test/specs/input_validations/onboarding_no_seed.spec.ts index 77d63427..819ca67f 100644 --- a/run/test/specs/input_validations/onboarding_no_seed.spec.ts +++ b/run/test/specs/input_validations/onboarding_no_seed.spec.ts @@ -1,5 +1,10 @@ import { bothPlatformsIt } from '../../../types/sessionIt'; -import { AccountRestoreButton, SeedPhraseInput, ContinueButton, ErrorMessage} from '../locators/onboarding'; +import { + AccountRestoreButton, + SeedPhraseInput, + ContinueButton, + ErrorMessage, +} from '../locators/onboarding'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from '../utils/open_app'; import { localize } from '../../../localizer/i18n/localizedString'; @@ -10,26 +15,25 @@ const emptySeed = ''; const expectedError = localize('recoveryPasswordErrorMessageShort').strip().toString(); async function onboardingNoSeed(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); - await device.clickOnElementAll(new AccountRestoreButton(device)); - // this check is to avoid false positives - if (emptySeed.length > 0) { - throw new Error ('The emptySeed string is not empty but it must be.') - } - await device.inputText(emptySeed, new SeedPhraseInput(device)); - // Trigger the validation by pressing Continue - await device.clickOnElementAll(new ContinueButton(device)); - // Wait for, and fetch the error message - const error = await device.waitForTextElementToBePresent(new ErrorMessage(device).build()); - const errorMessage = await device.getTextFromElement(error); - console.log(`The error message is "${errorMessage}"`); - console.log(`The expected error is "${expectedError}"`); - // Compare the fetched string with the expected string - if (errorMessage === expectedError) { - console.log('The observed error message matches the expected'); - } - else { - throw new Error ('The observed error message does not match the expected'); - } - await closeApp(device); -} \ No newline at end of file + const { device } = await openAppOnPlatformSingleDevice(platform); + await device.clickOnElementAll(new AccountRestoreButton(device)); + // this check is to avoid false positives + if (emptySeed.length > 0) { + throw new Error('The emptySeed string is not empty but it must be.'); + } + await device.inputText(emptySeed, new SeedPhraseInput(device)); + // Trigger the validation by pressing Continue + await device.clickOnElementAll(new ContinueButton(device)); + // Wait for, and fetch the error message + const error = await device.waitForTextElementToBePresent(new ErrorMessage(device).build()); + const errorMessage = await device.getTextFromElement(error); + console.log(`The error message is "${errorMessage}"`); + console.log(`The expected error is "${expectedError}"`); + // Compare the fetched string with the expected string + if (errorMessage === expectedError) { + console.log('The observed error message matches the expected'); + } else { + throw new Error('The observed error message does not match the expected'); + } + await closeApp(device); +} diff --git a/run/test/specs/input_validations/onboarding_wrong_seed.spec.ts b/run/test/specs/input_validations/onboarding_wrong_seed.spec.ts index 79a4adf3..27cde0c8 100644 --- a/run/test/specs/input_validations/onboarding_wrong_seed.spec.ts +++ b/run/test/specs/input_validations/onboarding_wrong_seed.spec.ts @@ -1,33 +1,38 @@ import { bothPlatformsIt } from '../../../types/sessionIt'; -import { AccountRestoreButton, SeedPhraseInput, ContinueButton, ErrorMessage } from '../locators/onboarding'; +import { + AccountRestoreButton, + SeedPhraseInput, + ContinueButton, + ErrorMessage, +} from '../locators/onboarding'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from '../utils/open_app'; import { localize } from '../../../localizer/i18n/localizedString'; bothPlatformsIt('Onboarding wrong seed', 'low', onboardingIncorrectSeed); -// the seed phrase is too long but contains only valid mnemonics which triggers the generic error -const wrongSeed = 'ruby bakery illness push rift reef nabbing bawled hope ruby silk lobster hope ruby ruby ruby' +// the seed phrase is too long but contains only valid mnemonics which triggers the generic error +const wrongSeed = + 'ruby bakery illness push rift reef nabbing bawled hope ruby silk lobster hope ruby ruby ruby'; // the expected error is 'Please check your recovery password' which is represented by the following localized string const expectedError = localize('recoveryPasswordErrorMessageGeneric').strip().toString(); async function onboardingIncorrectSeed(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); - await device.clickOnElementAll(new AccountRestoreButton(device)); - await device.inputText(wrongSeed, new SeedPhraseInput(device)); - // Trigger the validation by pressing Continue - await device.clickOnElementAll(new ContinueButton(device)); - // Wait for, and fetch the error message - const error = await device.waitForTextElementToBePresent(new ErrorMessage(device).build()); - const errorMessage = await device.getTextFromElement(error); - console.log(`The error message is "${errorMessage}"`); - console.log(`The expected error is "${expectedError}"`); - // Compare the fetched string with the expected string - if (errorMessage === expectedError) { - console.log('The observed error message matches the expected'); - } - else { - throw new Error ('The observed error message does not match the expected'); - } - // } - await closeApp(device); -} \ No newline at end of file + const { device } = await openAppOnPlatformSingleDevice(platform); + await device.clickOnElementAll(new AccountRestoreButton(device)); + await device.inputText(wrongSeed, new SeedPhraseInput(device)); + // Trigger the validation by pressing Continue + await device.clickOnElementAll(new ContinueButton(device)); + // Wait for, and fetch the error message + const error = await device.waitForTextElementToBePresent(new ErrorMessage(device).build()); + const errorMessage = await device.getTextFromElement(error); + console.log(`The error message is "${errorMessage}"`); + console.log(`The expected error is "${expectedError}"`); + // Compare the fetched string with the expected string + if (errorMessage === expectedError) { + console.log('The observed error message matches the expected'); + } else { + throw new Error('The observed error message does not match the expected'); + } + // } + await closeApp(device); +} diff --git a/run/test/specs/invite_a_friend_share.spec.ts b/run/test/specs/invite_a_friend_share.spec.ts index 211ef5ce..f6b24b11 100644 --- a/run/test/specs/invite_a_friend_share.spec.ts +++ b/run/test/specs/invite_a_friend_share.spec.ts @@ -6,41 +6,41 @@ import { PlusButton } from './locators/home'; import { AccountIDField, InviteAFriendOption, ShareButton } from './locators/start_conversation'; import { IOS_XPATHS } from '../../constants'; -bothPlatformsIt('Invite a friend', 'high', inviteAFriend) +bothPlatformsIt('Invite a friend', 'high', inviteAFriend); async function inviteAFriend(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); - let messageElement; - // This is a const so that the user.accountID can be used later on - const user = await newUser(device, USERNAME.ALICE, platform); - // Hit the plus button - await device.clickOnElementAll(new PlusButton(device)); - // Select Invite a Friend - await device.clickOnElementAll(new InviteAFriendOption(device)); - // Check for presence of Account ID field - await device.waitForTextElementToBePresent(new AccountIDField(device)); - // Tap Share - await device.clickOnElementAll(new ShareButton(device)); - // defining the "Hey..." message element to retrieve the share message from - if (platform === 'ios') { - messageElement = await device.waitForTextElementToBePresent({ - strategy: 'xpath', - selector: IOS_XPATHS.INVITE_A_FRIEND_SHARE, - }); - } - else { - messageElement = await device.waitForTextElementToBePresent({ - strategy: 'id', - selector: 'android:id/content_preview_text', - }) - } - // Retrieve the Share message and validate that it contains the user's Account ID - const retrievedShareMessage = await device.getTextFromElement(messageElement) - if (retrievedShareMessage.includes(user.accountID)) { - console.log("The Invite a Friend message snippet contains the user's Account ID") - } - else { - throw new Error(`The Invite a Friend message snippet does not contain the user's Account ID\nThe message goes ${retrievedShareMessage}`) - } - await closeApp(device); - } \ No newline at end of file + const { device } = await openAppOnPlatformSingleDevice(platform); + let messageElement; + // This is a const so that the user.accountID can be used later on + const user = await newUser(device, USERNAME.ALICE, platform); + // Hit the plus button + await device.clickOnElementAll(new PlusButton(device)); + // Select Invite a Friend + await device.clickOnElementAll(new InviteAFriendOption(device)); + // Check for presence of Account ID field + await device.waitForTextElementToBePresent(new AccountIDField(device)); + // Tap Share + await device.clickOnElementAll(new ShareButton(device)); + // defining the "Hey..." message element to retrieve the share message from + if (platform === 'ios') { + messageElement = await device.waitForTextElementToBePresent({ + strategy: 'xpath', + selector: IOS_XPATHS.INVITE_A_FRIEND_SHARE, + }); + } else { + messageElement = await device.waitForTextElementToBePresent({ + strategy: 'id', + selector: 'android:id/content_preview_text', + }); + } + // Retrieve the Share message and validate that it contains the user's Account ID + const retrievedShareMessage = await device.getTextFromElement(messageElement); + if (retrievedShareMessage.includes(user.accountID)) { + console.log("The Invite a Friend message snippet contains the user's Account ID"); + } else { + throw new Error( + `The Invite a Friend message snippet does not contain the user's Account ID\nThe message goes ${retrievedShareMessage}` + ); + } + await closeApp(device); +} diff --git a/run/test/specs/linked_device.spec.ts b/run/test/specs/linked_device.spec.ts index 88ee5c22..2c97de99 100644 --- a/run/test/specs/linked_device.spec.ts +++ b/run/test/specs/linked_device.spec.ts @@ -5,7 +5,7 @@ import { runOnlyOnAndroid, runOnlyOnIOS } from './utils'; import { linkedDevice } from './utils/link_device'; import { SupportedPlatformsType, closeApp, openAppTwoDevices } from './utils/open_app'; -bothPlatformsIt("Link device", 'high', linkDevice); +bothPlatformsIt('Link device', 'high', linkDevice); async function linkDevice(platform: SupportedPlatformsType) { // Open server and two devices diff --git a/run/test/specs/linked_group_leave.spec.ts b/run/test/specs/linked_group_leave.spec.ts index 485d15a6..0b32006e 100644 --- a/run/test/specs/linked_group_leave.spec.ts +++ b/run/test/specs/linked_group_leave.spec.ts @@ -8,7 +8,7 @@ import { createGroup } from './utils/create_group'; import { linkedDevice } from './utils/link_device'; import { SupportedPlatformsType, closeApp, openAppFourDevices } from './utils/open_app'; -bothPlatformsIt("Leave group linked device", 'high', leaveGroupLinkedDevice); +bothPlatformsIt('Leave group linked device', 'high', leaveGroupLinkedDevice); async function leaveGroupLinkedDevice(platform: SupportedPlatformsType) { const testGroupName = 'Leave group linked device'; diff --git a/run/test/specs/locators/browsers.ts b/run/test/specs/locators/browsers.ts index 6e9a4d9c..7e89ed84 100644 --- a/run/test/specs/locators/browsers.ts +++ b/run/test/specs/locators/browsers.ts @@ -1,64 +1,64 @@ -import { LocatorsInterface } from "."; +import { LocatorsInterface } from '.'; // SHARED LOCATORS export class URLInputField extends LocatorsInterface { - public build() { - switch (this.platform) { - case 'android': - return { - strategy: 'id', - selector: 'com.android.chrome:id/url_bar' - } as const; - case 'ios': - return { - strategy: 'accessibility id', - selector: 'URL' - } as const; - } + public build() { + switch (this.platform) { + case 'android': + return { + strategy: 'id', + selector: 'com.android.chrome:id/url_bar', + } as const; + case 'ios': + return { + strategy: 'accessibility id', + selector: 'URL', + } as const; } + } } -// ANDROID ONLY +// ANDROID ONLY export class ChromeUseWithoutAnAccount extends LocatorsInterface { - public build() { - switch (this.platform) { - case 'android': - return { - strategy: 'id', - selector: 'com.android.chrome:id/signin_fre_dismiss_button', - maxWait: 500, - } as const; - case 'ios': - throw new Error('Unsupported platform') - } + public build() { + switch (this.platform) { + case 'android': + return { + strategy: 'id', + selector: 'com.android.chrome:id/signin_fre_dismiss_button', + maxWait: 500, + } as const; + case 'ios': + throw new Error('Unsupported platform'); } + } } export class ChromeNotificationsNegativeButton extends LocatorsInterface { - public build() { - switch (this.platform) { - case 'android': - return { - strategy: 'id', - selector: 'com.android.chrome:id/negative_button', - } as const; - case 'ios': - throw new Error('Unsupported platform') - } + public build() { + switch (this.platform) { + case 'android': + return { + strategy: 'id', + selector: 'com.android.chrome:id/negative_button', + } as const; + case 'ios': + throw new Error('Unsupported platform'); } + } } // iOS ONLY export class SafariAddressBar extends LocatorsInterface { - public build() { - switch (this.platform) { - case 'android': - throw new Error('Unsupported platform') - case 'ios': - return { - strategy: 'accessibility id', - selector: 'TabBarItemTitle' - } as const; - } + public build() { + switch (this.platform) { + case 'android': + throw new Error('Unsupported platform'); + case 'ios': + return { + strategy: 'accessibility id', + selector: 'TabBarItemTitle', + } as const; } -} \ No newline at end of file + } +} diff --git a/run/test/specs/locators/conversation.ts b/run/test/specs/locators/conversation.ts index a3d2c888..27858735 100644 --- a/run/test/specs/locators/conversation.ts +++ b/run/test/specs/locators/conversation.ts @@ -1,10 +1,10 @@ import { LocatorsInterface } from './index'; export class MessageInput extends LocatorsInterface { - public build() { - return { - strategy: 'accessibility id', - selector: 'Message input box', - } as const; - } -} \ No newline at end of file + public build() { + return { + strategy: 'accessibility id', + selector: 'Message input box', + } as const; + } +} diff --git a/run/test/specs/locators/global.ts b/run/test/specs/locators/global.ts index cb7171ad..907ff0ac 100644 --- a/run/test/specs/locators/global.ts +++ b/run/test/specs/locators/global.ts @@ -70,9 +70,9 @@ export class DeleteContactModalConfirm extends LocatorsInterface { export class EnableLinkPreviewsModalButton extends LocatorsInterface { public build() { - return { - strategy: 'accessibility id', - selector: 'Enable', - } as const; + return { + strategy: 'accessibility id', + selector: 'Enable', + } as const; } -} \ No newline at end of file +} diff --git a/run/test/specs/locators/global_search.ts b/run/test/specs/locators/global_search.ts index ab8c3ad3..fddbe538 100644 --- a/run/test/specs/locators/global_search.ts +++ b/run/test/specs/locators/global_search.ts @@ -1,21 +1,20 @@ import { StrategyExtractionObj } from '../../../types/testing'; import { LocatorsInterface } from './index'; - export class NoteToSelfOption extends LocatorsInterface { - public build(): StrategyExtractionObj { - switch (this.platform) { - case 'android': - return { - strategy: 'id', - selector: 'network.loki.messenger:id/search_result_title', - text: 'Note to Self' - }; - case 'ios': - return { - strategy: 'accessibility id', - selector: 'Note to Self', - }; - } + public build(): StrategyExtractionObj { + switch (this.platform) { + case 'android': + return { + strategy: 'id', + selector: 'network.loki.messenger:id/search_result_title', + text: 'Note to Self', + }; + case 'ios': + return { + strategy: 'accessibility id', + selector: 'Note to Self', + }; } - } \ No newline at end of file + } +} diff --git a/run/test/specs/locators/home.ts b/run/test/specs/locators/home.ts index 8b2c9fb4..eb293fbf 100644 --- a/run/test/specs/locators/home.ts +++ b/run/test/specs/locators/home.ts @@ -2,27 +2,27 @@ import { StrategyExtractionObj } from '../../../types/testing'; import { LocatorsInterface } from './index'; export class PlusButton extends LocatorsInterface { - public build() { - return { - strategy: 'accessibility id', - selector: 'New conversation button', - } as const; - } + public build() { + return { + strategy: 'accessibility id', + selector: 'New conversation button', + } as const; + } } export class SearchButton extends LocatorsInterface { - public build(): StrategyExtractionObj { - switch (this.platform) { - case 'android': - return { - strategy: 'accessibility id', - selector: `Search icon`, - }; - case 'ios': - return { - strategy: 'accessibility id', - selector: 'Search button', - }; - } + public build(): StrategyExtractionObj { + switch (this.platform) { + case 'android': + return { + strategy: 'accessibility id', + selector: `Search icon`, + }; + case 'ios': + return { + strategy: 'accessibility id', + selector: 'Search button', + }; } - } \ No newline at end of file + } +} diff --git a/run/test/specs/locators/onboarding.ts b/run/test/specs/locators/onboarding.ts index a927254f..bf836668 100644 --- a/run/test/specs/locators/onboarding.ts +++ b/run/test/specs/locators/onboarding.ts @@ -41,9 +41,9 @@ export class BackButton extends LocatorsInterface { export class WarningModalQuitButton extends LocatorsInterface { public build(): StrategyExtractionObj { return { - strategy: 'id', - selector: 'Quit' - } as const + strategy: 'id', + selector: 'Quit', + } as const; } } @@ -58,55 +58,55 @@ export class CreateAccountButton extends LocatorsInterface { } export class AccountRestoreButton extends LocatorsInterface { - public build() { - return { - strategy: 'accessibility id', - selector: 'Restore your session button', - } as const; - } + public build() { + return { + strategy: 'accessibility id', + selector: 'Restore your session button', + } as const; + } } export class SplashScreenLinks extends LocatorsInterface { - public build() { - return { - strategy: 'accessibility id', - selector: 'Open URL', - } as const; - } + public build() { + return { + strategy: 'accessibility id', + selector: 'Open URL', + } as const; + } } export class TermsOfServiceButton extends LocatorsInterface { - public build() { - switch (this.platform) { - case 'android': - return { - strategy: 'id', - selector: 'Terms of Service', - } as const; - case 'ios': - return { - strategy: 'accessibility id', - selector: 'Terms of Service', - } as const; - } + public build() { + switch (this.platform) { + case 'android': + return { + strategy: 'id', + selector: 'Terms of Service', + } as const; + case 'ios': + return { + strategy: 'accessibility id', + selector: 'Terms of Service', + } as const; } + } } export class PrivacyPolicyButton extends LocatorsInterface { - public build() { - switch (this.platform) { - case 'android': - return { - strategy: 'id', - selector: 'Privacy Policy', - } as const; - case 'ios': - return { - strategy: 'accessibility id', - selector: 'Privacy Policy', - } as const; - } + public build() { + switch (this.platform) { + case 'android': + return { + strategy: 'id', + selector: 'Privacy Policy', + } as const; + case 'ios': + return { + strategy: 'accessibility id', + selector: 'Privacy Policy', + } as const; } + } } // CREATE ACCOUNT FLOW diff --git a/run/test/specs/locators/start_conversation.ts b/run/test/specs/locators/start_conversation.ts index b2b70c31..0322ea04 100644 --- a/run/test/specs/locators/start_conversation.ts +++ b/run/test/specs/locators/start_conversation.ts @@ -2,90 +2,90 @@ import { StrategyExtractionObj } from '../../../types/testing'; import { LocatorsInterface } from './index'; export class NewMessageOption extends LocatorsInterface { - public build() { - return { - strategy: 'accessibility id', - selector: 'New direct message', - } as const; - } + public build() { + return { + strategy: 'accessibility id', + selector: 'New direct message', + } as const; + } } export class CreateGroupOption extends LocatorsInterface { - public build() { - return { - strategy: 'accessibility id', - selector: 'Create group', - } as const; - } + public build() { + return { + strategy: 'accessibility id', + selector: 'Create group', + } as const; + } } export class JoinCommunityOption extends LocatorsInterface { - public build(): StrategyExtractionObj { - switch (this.platform) { - case 'android': - return { - strategy: 'accessibility id', - selector: 'Join community button', - }; - case 'ios': - return { - strategy: 'accessibility id', - selector: 'Join Community', - }; - } + public build(): StrategyExtractionObj { + switch (this.platform) { + case 'android': + return { + strategy: 'accessibility id', + selector: 'Join community button', + }; + case 'ios': + return { + strategy: 'accessibility id', + selector: 'Join Community', + }; } } +} export class InviteAFriendOption extends LocatorsInterface { - public build() { - return { - strategy: 'accessibility id', - selector: 'Invite friend button', - } as const; - } + public build() { + return { + strategy: 'accessibility id', + selector: 'Invite friend button', + } as const; + } } export class CloseButton extends LocatorsInterface { - public build(): StrategyExtractionObj { - switch (this.platform) { - case 'android': - return { - strategy: 'accessibility id', - selector: 'Close', - }; - case 'ios': - return { - strategy: 'accessibility id', - selector: 'X', - }; - } + public build(): StrategyExtractionObj { + switch (this.platform) { + case 'android': + return { + strategy: 'accessibility id', + selector: 'Close', + }; + case 'ios': + return { + strategy: 'accessibility id', + selector: 'X', + }; } } +} -// INVITE A FRIEND SECTION +// INVITE A FRIEND SECTION export class AccountIDField extends LocatorsInterface { - public build() { - return { - strategy: 'accessibility id', - selector: 'Account ID', - } as const; - } + public build() { + return { + strategy: 'accessibility id', + selector: 'Account ID', + } as const; + } } export class ShareButton extends LocatorsInterface { - public build() { - return { - strategy: 'accessibility id', - selector: 'Share button', - } as const; - } + public build() { + return { + strategy: 'accessibility id', + selector: 'Share button', + } as const; + } } export class CopyButton extends LocatorsInterface { public build() { - return { - strategy: 'accessibility id', - selector: 'Copy button', - } as const; + return { + strategy: 'accessibility id', + selector: 'Copy button', + } as const; } -} \ No newline at end of file +} diff --git a/run/test/specs/message_requests_accept.spec.ts b/run/test/specs/message_requests_accept.spec.ts index 284b99d1..435c40ce 100644 --- a/run/test/specs/message_requests_accept.spec.ts +++ b/run/test/specs/message_requests_accept.spec.ts @@ -5,7 +5,7 @@ import { newUser } from './utils/create_account'; import { linkedDevice } from './utils/link_device'; import { SupportedPlatformsType, closeApp, openAppThreeDevices } from './utils/open_app'; -bothPlatformsIt("Accept message request", 'high', acceptRequest); +bothPlatformsIt('Accept message request', 'high', acceptRequest); async function acceptRequest(platform: SupportedPlatformsType) { // Check 'accept' button diff --git a/run/test/specs/message_requests_block.spec.ts b/run/test/specs/message_requests_block.spec.ts index 44f749ef..ceea6531 100644 --- a/run/test/specs/message_requests_block.spec.ts +++ b/run/test/specs/message_requests_block.spec.ts @@ -7,7 +7,7 @@ import { newUser } from './utils/create_account'; import { linkedDevice } from './utils/link_device'; import { closeApp, openAppThreeDevices, SupportedPlatformsType } from './utils/open_app'; -bothPlatformsIt("Block message request", 'high', blockedRequest); +bothPlatformsIt('Block message request', 'high', blockedRequest); async function blockedRequest(platform: SupportedPlatformsType) { const { device1, device2, device3 } = await openAppThreeDevices(platform); diff --git a/run/test/specs/message_requests_clear_all.spec.ts b/run/test/specs/message_requests_clear_all.spec.ts index 3105f891..5326b7c3 100644 --- a/run/test/specs/message_requests_clear_all.spec.ts +++ b/run/test/specs/message_requests_clear_all.spec.ts @@ -5,7 +5,7 @@ import { sleepFor } from './utils'; import { newUser } from './utils/create_account'; import { SupportedPlatformsType, closeApp, openAppTwoDevices } from './utils/open_app'; -bothPlatformsIt("Message requests clear all", 'medium', clearAllRequests); +bothPlatformsIt('Message requests clear all', 'medium', clearAllRequests); async function clearAllRequests(platform: SupportedPlatformsType) { const { device1, device2 } = await openAppTwoDevices(platform); diff --git a/run/test/specs/onboarding_pp.spec.ts b/run/test/specs/onboarding_pp.spec.ts index 16bfb7bd..5f03c1c2 100644 --- a/run/test/specs/onboarding_pp.spec.ts +++ b/run/test/specs/onboarding_pp.spec.ts @@ -5,37 +5,40 @@ import { runOnlyOnAndroid, runOnlyOnIOS } from './utils'; import { isChromeFirstTimeOpen } from './utils/chrome_first_time_open'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; -bothPlatformsIt('Onboarding privacy policy', 'high', onboardingPP) +bothPlatformsIt('Onboarding privacy policy', 'high', onboardingPP); async function onboardingPP(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); - const ppURL = 'https://getsession.org/privacy-policy'; - // Tap the text at the bottom of the splash screen to bring up the TOS/PP links modal - await device.clickOnElementAll(new SplashScreenLinks(device)); - // Tap Privacy Policy - await device.clickOnElementAll(new PrivacyPolicyButton(device)); - // Identifying the URL field works differently in Safari and Chrome - if (platform === 'ios') { - // Tap the Safari address bar to reveal the URL - await device.clickOnElementAll(new SafariAddressBar(device)); - } - else { - // Chrome can throw some modals on first open - await isChromeFirstTimeOpen(device); - } - // Retrieve URL - const urlField = await device.waitForTextElementToBePresent(new URLInputField(device)) - const retrievedURL = await device.getTextFromElement(urlField) - // Add https:// to the retrieved URL if the UI doesn't show it (Chrome doesn't, Safari does) - const fullRetrievedURL = retrievedURL.startsWith('https://') ? retrievedURL : `https://${retrievedURL}`; - // Verify that it's the correct URL - if (fullRetrievedURL !== ppURL) { - throw new Error(`The retrieved URL does not match the expected. The retrieved URL is ${fullRetrievedURL}`); - } else { - console.log("The URLs match."); - } - // Close browser and app - await runOnlyOnIOS(platform, () => device.clickOnCoordinates(42,42)); // I don't like this but nothing else works - await runOnlyOnAndroid(platform, () => device.back()); - await closeApp(device); -} \ No newline at end of file + const { device } = await openAppOnPlatformSingleDevice(platform); + const ppURL = 'https://getsession.org/privacy-policy'; + // Tap the text at the bottom of the splash screen to bring up the TOS/PP links modal + await device.clickOnElementAll(new SplashScreenLinks(device)); + // Tap Privacy Policy + await device.clickOnElementAll(new PrivacyPolicyButton(device)); + // Identifying the URL field works differently in Safari and Chrome + if (platform === 'ios') { + // Tap the Safari address bar to reveal the URL + await device.clickOnElementAll(new SafariAddressBar(device)); + } else { + // Chrome can throw some modals on first open + await isChromeFirstTimeOpen(device); + } + // Retrieve URL + const urlField = await device.waitForTextElementToBePresent(new URLInputField(device)); + const retrievedURL = await device.getTextFromElement(urlField); + // Add https:// to the retrieved URL if the UI doesn't show it (Chrome doesn't, Safari does) + const fullRetrievedURL = retrievedURL.startsWith('https://') + ? retrievedURL + : `https://${retrievedURL}`; + // Verify that it's the correct URL + if (fullRetrievedURL !== ppURL) { + throw new Error( + `The retrieved URL does not match the expected. The retrieved URL is ${fullRetrievedURL}` + ); + } else { + console.log('The URLs match.'); + } + // Close browser and app + await runOnlyOnIOS(platform, () => device.clickOnCoordinates(42, 42)); // I don't like this but nothing else works + await runOnlyOnAndroid(platform, () => device.back()); + await closeApp(device); +} diff --git a/run/test/specs/onboarding_tos.spec.ts b/run/test/specs/onboarding_tos.spec.ts index 07c5375a..2a879072 100644 --- a/run/test/specs/onboarding_tos.spec.ts +++ b/run/test/specs/onboarding_tos.spec.ts @@ -5,37 +5,40 @@ import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from import { isChromeFirstTimeOpen } from './utils/chrome_first_time_open'; import { URLInputField, SafariAddressBar } from './locators/browsers'; -bothPlatformsIt('Onboarding terms of service', 'high', onboardingTOS) +bothPlatformsIt('Onboarding terms of service', 'high', onboardingTOS); async function onboardingTOS(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); - const tosURL = 'https://getsession.org/terms-of-service'; - // Tap the text at the bottom of the splash screen to bring up the TOS/PP links modal - await device.clickOnElementAll(new SplashScreenLinks(device)); - // Tap Privacy Policy - await device.clickOnElementAll(new TermsOfServiceButton(device)); - // Identifying the URL field works differently in Safari and Chrome - if (platform === 'ios') { - // Tap the Safari address bar to reveal the URL - await device.clickOnElementAll(new SafariAddressBar(device)); - } - else { - // Chrome can throw some modals on first open - await isChromeFirstTimeOpen(device); - } - // Retrieve URL - const urlField = await device.waitForTextElementToBePresent(new URLInputField(device)) - const retrievedURL = await device.getTextFromElement(urlField) - // Add https:// to the retrieved URL if the UI doesn't show it (Chrome doesn't, Safari does) - const fullRetrievedURL = retrievedURL.startsWith('https://') ? retrievedURL : `https://${retrievedURL}`; - // Verify that it's the correct URL - if (fullRetrievedURL !== tosURL) { - throw new Error(`The retrieved URL does not match the expected. The retrieved URL is ${fullRetrievedURL}`); - } else { - console.log("The URLs match."); - } - // Close browser and app - await runOnlyOnIOS(platform, () => device.clickOnCoordinates(42,42)); // I don't like this but nothing else works - await runOnlyOnAndroid(platform, () => device.back()); - await closeApp(device); -} \ No newline at end of file + const { device } = await openAppOnPlatformSingleDevice(platform); + const tosURL = 'https://getsession.org/terms-of-service'; + // Tap the text at the bottom of the splash screen to bring up the TOS/PP links modal + await device.clickOnElementAll(new SplashScreenLinks(device)); + // Tap Privacy Policy + await device.clickOnElementAll(new TermsOfServiceButton(device)); + // Identifying the URL field works differently in Safari and Chrome + if (platform === 'ios') { + // Tap the Safari address bar to reveal the URL + await device.clickOnElementAll(new SafariAddressBar(device)); + } else { + // Chrome can throw some modals on first open + await isChromeFirstTimeOpen(device); + } + // Retrieve URL + const urlField = await device.waitForTextElementToBePresent(new URLInputField(device)); + const retrievedURL = await device.getTextFromElement(urlField); + // Add https:// to the retrieved URL if the UI doesn't show it (Chrome doesn't, Safari does) + const fullRetrievedURL = retrievedURL.startsWith('https://') + ? retrievedURL + : `https://${retrievedURL}`; + // Verify that it's the correct URL + if (fullRetrievedURL !== tosURL) { + throw new Error( + `The retrieved URL does not match the expected. The retrieved URL is ${fullRetrievedURL}` + ); + } else { + console.log('The URLs match.'); + } + // Close browser and app + await runOnlyOnIOS(platform, () => device.clickOnCoordinates(42, 42)); // I don't like this but nothing else works + await runOnlyOnAndroid(platform, () => device.back()); + await closeApp(device); +} diff --git a/run/test/specs/utils/chrome_first_time_open.ts b/run/test/specs/utils/chrome_first_time_open.ts index faacfdcd..47b13ad4 100644 --- a/run/test/specs/utils/chrome_first_time_open.ts +++ b/run/test/specs/utils/chrome_first_time_open.ts @@ -1,14 +1,18 @@ -import { DeviceWrapper } from "../../../types/DeviceWrapper"; -import { ChromeNotificationsNegativeButton, ChromeUseWithoutAnAccount } from "../locators/browsers"; +import { DeviceWrapper } from '../../../types/DeviceWrapper'; +import { ChromeNotificationsNegativeButton, ChromeUseWithoutAnAccount } from '../locators/browsers'; -// First time open of Chrome triggers an account check and a notifications modal +// First time open of Chrome triggers an account check and a notifications modal export async function isChromeFirstTimeOpen(device: DeviceWrapper) { -const chromeUseWithoutAnAccount = await device.doesElementExist(new ChromeUseWithoutAnAccount(device)) -if (!chromeUseWithoutAnAccount) { - console.log("Chrome opened without an account check, proceeding"); -} else { - console.log("Chrome has been opened for the first time, dismissing account use and notifications"); + const chromeUseWithoutAnAccount = await device.doesElementExist( + new ChromeUseWithoutAnAccount(device) + ); + if (!chromeUseWithoutAnAccount) { + console.log('Chrome opened without an account check, proceeding'); + } else { + console.log( + 'Chrome has been opened for the first time, dismissing account use and notifications' + ); await device.clickOnElementAll(new ChromeUseWithoutAnAccount(device)); await device.clickOnElementAll(new ChromeNotificationsNegativeButton(device)); - } -} \ No newline at end of file + } +} diff --git a/run/test/specs/warning_modal_new_account.spec.ts b/run/test/specs/warning_modal_new_account.spec.ts index 7288debc..7f8e6cb3 100644 --- a/run/test/specs/warning_modal_new_account.spec.ts +++ b/run/test/specs/warning_modal_new_account.spec.ts @@ -1,28 +1,32 @@ -import { bothPlatformsIt } from "../../types/sessionIt"; -import { CreateAccountButton, BackButton, DisplayNameInput, SlowModeRadio, ContinueButton, WarningModalQuitButton } from "./locators/onboarding"; -import { SupportedPlatformsType } from "./utils/open_app"; -import { openAppOnPlatformSingleDevice, closeApp } from "./utils/open_app"; -import { USERNAME } from "../../types/testing"; +import { bothPlatformsIt } from '../../types/sessionIt'; +import { + CreateAccountButton, + BackButton, + DisplayNameInput, + SlowModeRadio, + ContinueButton, + WarningModalQuitButton, +} from './locators/onboarding'; +import { SupportedPlatformsType } from './utils/open_app'; +import { openAppOnPlatformSingleDevice, closeApp } from './utils/open_app'; +import { USERNAME } from '../../types/testing'; -bothPlatformsIt('Warning modal new account', 'medium', warningModalNewAccount) +bothPlatformsIt('Warning modal new account', 'medium', warningModalNewAccount); async function warningModalNewAccount(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); - await device.clickOnElementAll(new CreateAccountButton(device)); - await device.inputText(USERNAME.ALICE, new DisplayNameInput(device)); - await device.clickOnElementAll(new ContinueButton(device)); - // Checking that we're on the Message Notifications screen - await device.doesElementExist(new SlowModeRadio(device)); - // Pressing Back on the Message Notifications screen - await device.clickOnElementAll(new BackButton(device)); - // Verifying that pressing Back from the Message Notifications screen does not bring up a modal but instead shows the Display Name input field - await device.doesElementExist(new DisplayNameInput(device)); - // Pressing Back on the Display Name screen to trigger the Warning modal - await device.clickOnElementAll(new BackButton(device)); - await device.checkModalStrings( - 'warning', - 'onboardingBackAccountCreation' - ) - await device.clickOnElementAll(new WarningModalQuitButton(device)); - await closeApp(device); -} \ No newline at end of file + const { device } = await openAppOnPlatformSingleDevice(platform); + await device.clickOnElementAll(new CreateAccountButton(device)); + await device.inputText(USERNAME.ALICE, new DisplayNameInput(device)); + await device.clickOnElementAll(new ContinueButton(device)); + // Checking that we're on the Message Notifications screen + await device.doesElementExist(new SlowModeRadio(device)); + // Pressing Back on the Message Notifications screen + await device.clickOnElementAll(new BackButton(device)); + // Verifying that pressing Back from the Message Notifications screen does not bring up a modal but instead shows the Display Name input field + await device.doesElementExist(new DisplayNameInput(device)); + // Pressing Back on the Display Name screen to trigger the Warning modal + await device.clickOnElementAll(new BackButton(device)); + await device.checkModalStrings('warning', 'onboardingBackAccountCreation'); + await device.clickOnElementAll(new WarningModalQuitButton(device)); + await closeApp(device); +} diff --git a/run/test/specs/warning_modal_restore_account.spec.ts b/run/test/specs/warning_modal_restore_account.spec.ts index fb783d06..76d0d7fc 100644 --- a/run/test/specs/warning_modal_restore_account.spec.ts +++ b/run/test/specs/warning_modal_restore_account.spec.ts @@ -1,24 +1,29 @@ -import { bothPlatformsIt } from "../../types/sessionIt"; -import { SeedPhraseInput, BackButton, SlowModeRadio, ContinueButton, AccountRestoreButton, WarningModalQuitButton } from "./locators/onboarding"; -import { SupportedPlatformsType } from "./utils/open_app"; -import { openAppOnPlatformSingleDevice, closeApp } from "./utils/open_app"; +import { bothPlatformsIt } from '../../types/sessionIt'; +import { + SeedPhraseInput, + BackButton, + SlowModeRadio, + ContinueButton, + AccountRestoreButton, + WarningModalQuitButton, +} from './locators/onboarding'; +import { SupportedPlatformsType } from './utils/open_app'; +import { openAppOnPlatformSingleDevice, closeApp } from './utils/open_app'; -bothPlatformsIt('Warning modal restore account', 'medium', warningModalRestoreAccount) +bothPlatformsIt('Warning modal restore account', 'medium', warningModalRestoreAccount); async function warningModalRestoreAccount(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); - const seedPhrase = 'eldest fazed hybrid buzzer nasty domestic digit pager unusual purged makeup assorted domestic' - await device.clickOnElementAll(new AccountRestoreButton(device)); - await device.inputText(seedPhrase, new SeedPhraseInput(device)); - await device.clickOnElementAll(new ContinueButton(device)); - // Checking that we're on the Message Notifications screen - await device.doesElementExist(new SlowModeRadio(device).build()); - // Pressing Back on the Message Notifications screen to trigger the Warning modal - await device.clickOnElementAll(new BackButton(device)); - await device.checkModalStrings( - 'warning', - 'onboardingBackLoadAccount' - ) - await device.clickOnElementAll(new WarningModalQuitButton(device)); - await closeApp(device); -} \ No newline at end of file + const { device } = await openAppOnPlatformSingleDevice(platform); + const seedPhrase = + 'eldest fazed hybrid buzzer nasty domestic digit pager unusual purged makeup assorted domestic'; + await device.clickOnElementAll(new AccountRestoreButton(device)); + await device.inputText(seedPhrase, new SeedPhraseInput(device)); + await device.clickOnElementAll(new ContinueButton(device)); + // Checking that we're on the Message Notifications screen + await device.doesElementExist(new SlowModeRadio(device).build()); + // Pressing Back on the Message Notifications screen to trigger the Warning modal + await device.clickOnElementAll(new BackButton(device)); + await device.checkModalStrings('warning', 'onboardingBackLoadAccount'); + await device.clickOnElementAll(new WarningModalQuitButton(device)); + await closeApp(device); +} diff --git a/run/types/DeviceWrapper.ts b/run/types/DeviceWrapper.ts index 7a5ac256..dc02e88d 100644 --- a/run/types/DeviceWrapper.ts +++ b/run/types/DeviceWrapper.ts @@ -308,7 +308,7 @@ export class DeviceWrapper { } await this.click(el.ELEMENT); } -// TODO update this function to handle new locator logic + // TODO update this function to handle new locator logic public async longPress(accessibilityId: AccessibilityId, text?: string) { const el = await this.waitForTextElementToBePresent({ strategy: 'accessibility id', @@ -1829,7 +1829,7 @@ export class DeviceWrapper { `Modal description is incorrect. Expected description: ${expectedDescription}, Actual description: ${formattedDescription}` ); } else { - console.log('Modal description is correct') + console.log('Modal description is correct'); } } diff --git a/run/types/RangeType.ts b/run/types/RangeType.ts index 1d7ab018..56e5f3b0 100644 --- a/run/types/RangeType.ts +++ b/run/types/RangeType.ts @@ -1,7 +1,5 @@ type Enumerate = Acc['length'] extends N ? Acc[number] - : Enumerate - -export type IntRange = Exclude, Enumerate> - + : Enumerate; +export type IntRange = Exclude, Enumerate>; diff --git a/run/types/sessionIt.ts b/run/types/sessionIt.ts index 3dce71a9..8333aceb 100644 --- a/run/types/sessionIt.ts +++ b/run/types/sessionIt.ts @@ -77,7 +77,7 @@ function mobileIt( export function bothPlatformsIt( title: string, - testRisk: TestRisk, + testRisk: TestRisk, testToRun: (platform: SupportedPlatformsType) => Promise, shouldSkip = false ) { diff --git a/run/types/testing.ts b/run/types/testing.ts index 49a2e788..0a051551 100644 --- a/run/types/testing.ts +++ b/run/types/testing.ts @@ -376,8 +376,4 @@ export type Id = | 'network.loki.messenger:id/back_button' | 'Quit'; -export type TestRisk = - | 'high' - | 'medium' - | 'low' - | 'undefined'; \ No newline at end of file +export type TestRisk = 'high' | 'medium' | 'low' | 'undefined'; From 1192668947148f2a3aaae76454c089960f8da8c1 Mon Sep 17 00:00:00 2001 From: Miki-Session Date: Thu, 14 Nov 2024 09:52:55 +1100 Subject: [PATCH 6/6] chore: eslint error --- run/test/specs/utils/sleep_for.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run/test/specs/utils/sleep_for.ts b/run/test/specs/utils/sleep_for.ts index f7372ca2..bf517b2c 100644 --- a/run/test/specs/utils/sleep_for.ts +++ b/run/test/specs/utils/sleep_for.ts @@ -1,6 +1,6 @@ export function sleepFor(ms: number) { return new Promise(resolve => { setTimeout(resolve, ms); - console.log('Sleeping for ' + ms + ' milliseconds'); + console.log(`Sleeping for ${ms} milliseconds`); }); }