diff --git a/eslint.config.mjs b/eslint.config.mjs index c8f00ce5..de67e03a 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,11 +1,17 @@ import eslint from '@eslint/js'; -import tseslint from 'typescript-eslint'; +import perfectionist from 'eslint-plugin-perfectionist'; import globals from 'globals'; +import tseslint from 'typescript-eslint'; export default tseslint.config( { files: ['**/*.{ts,tsx,cts,mts,js,cjs,mjs}'], }, + { + plugins: { + perfectionist, + }, + }, { ignores: [ '**/node_modules/**', @@ -51,6 +57,8 @@ export default tseslint.config( caughtErrorsIgnorePattern: '^_', }, ], + 'perfectionist/sort-imports': 'error', + 'perfectionist/sort-named-imports': 'error', }, } ); diff --git a/package.json b/package.json index 0870da60..99d8f022 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "allure-commandline": "^2.34.0", "allure-playwright": "^3.2.2", "eslint": "^9.14.0", + "eslint-plugin-perfectionist": "^4.15.0", "fs-extra": "^11.3.0", "gh-pages": "^6.3.0", "globals": "^15.12.0", @@ -40,6 +41,7 @@ "looks-same": "^9.0.1", "png-js": "^1.0.0", "prettier": "^3.3.3", + "sharp": "^0.34.2", "sinon": "^19.0.2", "ts-node": "^10.9.1", "typescript": "^5.6.3", diff --git a/playwright.config.ts b/playwright.config.ts index bd20cea9..f760a7b1 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -2,12 +2,13 @@ import dotenv from 'dotenv'; dotenv.config(); import { defineConfig, ReporterDescription } from '@playwright/test'; + +import { allureResultsDir } from './run/constants/allure'; import { getRepeatEachCount, getRetriesCount, getWorkersCount, } from './run/test/specs/utils/binaries'; -import { allureResultsDir } from './run/constants/allure'; // NOTE: without this, the wrong source map is loaded and the stacktraces are all wrong // eslint-disable-next-line @typescript-eslint/no-require-imports diff --git a/run/test/specs/app_disguise_icons.spec.ts b/run/test/specs/app_disguise_icons.spec.ts index 296d1c2b..54fff403 100644 --- a/run/test/specs/app_disguise_icons.spec.ts +++ b/run/test/specs/app_disguise_icons.spec.ts @@ -1,12 +1,13 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; -import { SupportedPlatformsType, closeApp, openAppOnPlatformSingleDevice } from './utils/open_app'; -import { newUser } from './utils/create_account'; import { USERNAME } from '../../types/testing'; import { AppearanceMenuItem, SelectAppIcon, UserSettings } from './locators/settings'; -import { verifyElementScreenshot } from './utils/verify_screenshots'; -import { AppDisguisePageScreenshot } from './utils/screenshot_paths'; import { sleepFor } from './utils'; -import type { TestInfo } from '@playwright/test'; +import { newUser } from './utils/create_account'; +import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; +import { AppDisguisePageScreenshot } from './utils/screenshot_paths'; +import { verifyElementScreenshot } from './utils/verify_screenshots'; bothPlatformsIt({ title: 'App disguise icons', @@ -16,7 +17,7 @@ bothPlatformsIt({ }); async function appDisguiseIcons(platform: SupportedPlatformsType, testInfo: TestInfo) { - const { device } = await openAppOnPlatformSingleDevice(platform); + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); await newUser(device, USERNAME.ALICE); await device.clickOnElementAll(new UserSettings(device)); // Must scroll down to reveal the Appearance menu item diff --git a/run/test/specs/app_disguise_set.spec.ts b/run/test/specs/app_disguise_set.spec.ts index 275763f8..77a75a5e 100644 --- a/run/test/specs/app_disguise_set.spec.ts +++ b/run/test/specs/app_disguise_set.spec.ts @@ -1,7 +1,9 @@ +import type { TestInfo } from '@playwright/test'; + +import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { androidIt } from '../../types/sessionIt'; -import { SupportedPlatformsType, openAppOnPlatformSingleDevice } from './utils/open_app'; -import { newUser } from './utils/create_account'; import { USERNAME } from '../../types/testing'; +import { DisguisedApp } from './locators/external'; import { AppDisguiseMeetingIcon, AppearanceMenuItem, @@ -9,12 +11,12 @@ import { SelectAppIcon, UserSettings, } from './locators/settings'; -import { DisguisedApp } from './locators/external'; import { sleepFor } from './utils'; -import { runScriptAndLog } from './utils/utilities'; import { getAdbFullPath } from './utils/binaries'; +import { newUser } from './utils/create_account'; +import { openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; import { closeApp } from './utils/open_app'; -import { englishStrippedStr } from '../../localizer/englishStrippedStr'; +import { runScriptAndLog } from './utils/utilities'; // iOS implementation blocked by SES-3809 androidIt({ @@ -24,8 +26,8 @@ androidIt({ testCb: appDisguiseSetIcon, }); -async function appDisguiseSetIcon(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function appDisguiseSetIcon(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); await newUser(device, USERNAME.ALICE); await device.clickOnElementAll(new UserSettings(device)); // Must scroll down to reveal the Appearance menu item diff --git a/run/test/specs/check_avatar_color.spec.ts b/run/test/specs/check_avatar_color.spec.ts index 8a419097..f12f3d13 100644 --- a/run/test/specs/check_avatar_color.spec.ts +++ b/run/test/specs/check_avatar_color.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; -import { isSameColor } from './utils/check_colour'; -import { UserSettings } from './locators/settings'; import { ConversationSettings } from './locators/conversation'; -import { open_Alice1_Bob1_friends } from './state_builder'; import { ConversationItem } from './locators/home'; +import { UserSettings } from './locators/settings'; +import { open_Alice1_Bob1_friends } from './state_builder'; +import { isSameColor } from './utils/check_colour'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Avatar color', @@ -20,24 +22,25 @@ bothPlatformsItSeparate({ }, }); -async function avatarColor(platform: SupportedPlatformsType) { +async function avatarColor(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: false, + testInfo, }); // Get Alice's avatar color on device 1 (Settings screen avatar) and turn it into a hex value await alice1.clickOnElementAll(new UserSettings(alice1)); const alice1PixelColor = await alice1.getElementPixelColor(new UserSettings(alice1)); - console.log(alice1PixelColor); + alice1.log(alice1PixelColor); // Get Alice's avatar color on device 2 and turn it into a hex value // Open the conversation with Alice on Bob's device await bob1.clickOnElementAll(new ConversationItem(bob1, alice.userName)); const bob1PixelColor = await bob1.getElementPixelColor(new ConversationSettings(bob1)); - console.log(bob1PixelColor); + bob1.log(bob1PixelColor); // Color matching devices 1 and 2 const colorMatch = isSameColor(alice1PixelColor, bob1PixelColor); if (!colorMatch) { diff --git a/run/test/specs/community_tests_image.spec.ts b/run/test/specs/community_tests_image.spec.ts index 3b2c6edf..fa48b144 100644 --- a/run/test/specs/community_tests_image.spec.ts +++ b/run/test/specs/community_tests_image.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + import { testCommunityLink, testCommunityName } from '../../constants/community'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { open_Alice1_Bob1_friends } from './state_builder'; import { newUser } from './utils/create_account'; import { joinCommunity } from './utils/join_community'; -import { SupportedPlatformsType, closeApp, openAppTwoDevices } from './utils/open_app'; +import { closeApp, openAppTwoDevices, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send image to community', @@ -23,13 +25,14 @@ bothPlatformsItSeparate({ // Tests skipped due to both platforms having unique issues, have made a ticket // to investigate further https://optf.atlassian.net/browse/QA-486 -async function sendImageCommunityiOS(platform: SupportedPlatformsType) { +async function sendImageCommunityiOS(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: false, + testInfo, }); const testMessage = 'Testing sending images to communities'; const testImageMessage = `Image message + ${new Date().getTime()} - ${platform}`; @@ -43,8 +46,8 @@ async function sendImageCommunityiOS(platform: SupportedPlatformsType) { await closeApp(alice1, bob1); } -async function sendImageCommunityAndroid(platform: SupportedPlatformsType) { - const { device1: alice1, device2: bob1 } = await openAppTwoDevices(platform); +async function sendImageCommunityAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device1: alice1, device2: bob1 } = await openAppTwoDevices(platform, testInfo); const time = await alice1.getTimeFromDevice(platform); const testMessage = `Testing sending images to communities + ${time} - ${platform}`; // Create user A and user B diff --git a/run/test/specs/community_tests_join.spec.ts b/run/test/specs/community_tests_join.spec.ts index feb50fe7..b4cdf6e5 100644 --- a/run/test/specs/community_tests_join.spec.ts +++ b/run/test/specs/community_tests_join.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + import { testCommunityLink, testCommunityName } from '../../constants/community'; import { bothPlatformsIt } from '../../types/sessionIt'; import { ConversationItem } from './locators/home'; import { open_Alice2 } from './state_builder'; import { sleepFor } from './utils'; import { joinCommunity } from './utils/join_community'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Join community test', @@ -13,10 +15,10 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function joinCommunityTest(platform: SupportedPlatformsType) { +async function joinCommunityTest(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, alice2 }, - } = await open_Alice2({ platform }); + } = await open_Alice2({ platform, testInfo }); const testMessage = `Test message + ${new Date().getTime()}`; await joinCommunity(alice1, testCommunityLink, testCommunityName); diff --git a/run/test/specs/disappear_after_read.spec.ts b/run/test/specs/disappear_after_read.spec.ts index 3c996c4b..256e5515 100644 --- a/run/test/specs/disappear_after_read.spec.ts +++ b/run/test/specs/disappear_after_read.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { DISAPPEARING_TIMES, DisappearModes } from '../../types/testing'; import { open_Alice1_Bob1_friends } from './state_builder'; @@ -13,12 +15,13 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function disappearAfterRead(platform: SupportedPlatformsType) { +async function disappearAfterRead(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice, bob }, } = await open_Alice1_Bob1_friends({ platform, + testInfo, focusFriendsConvo: true, }); diff --git a/run/test/specs/disappear_after_send.spec.ts b/run/test/specs/disappear_after_send.spec.ts index 62a70b27..91437f1f 100644 --- a/run/test/specs/disappear_after_send.spec.ts +++ b/run/test/specs/disappear_after_send.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { DisappearActions, DISAPPEARING_TIMES, DisappearModes } from '../../types/testing'; +import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils'; import { checkDisappearingControlMessage } from './utils/disappearing_control_messages'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; import { setDisappearingMessage } from './utils/set_disappearing_messages'; -import { open_Alice1_Bob1_friends } from './state_builder'; bothPlatformsIt({ title: 'Disappear after send', @@ -13,15 +15,15 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function disappearAfterSend(platform: SupportedPlatformsType) { +async function disappearAfterSend(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice, bob }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); - const mode: DisappearModes = 'send'; const testMessage = `Checking disappear after ${mode} is working`; const controlMode: DisappearActions = 'sent'; diff --git a/run/test/specs/disappear_after_send_groups.spec.ts b/run/test/specs/disappear_after_send_groups.spec.ts index a27c229e..8cfb2d32 100644 --- a/run/test/specs/disappear_after_send_groups.spec.ts +++ b/run/test/specs/disappear_after_send_groups.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { DisappearActions, DISAPPEARING_TIMES } from '../../types/testing'; @@ -13,7 +15,7 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function disappearAfterSendGroups(platform: SupportedPlatformsType) { +async function disappearAfterSendGroups(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Disappear after send test'; const testMessage = 'Testing disappear after sent in groups'; const controlMode: DisappearActions = 'sent'; @@ -25,6 +27,7 @@ async function disappearAfterSendGroups(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['Group', `Disappear after send option`, time]); diff --git a/run/test/specs/disappear_after_send_note_to_self.spec.ts b/run/test/specs/disappear_after_send_note_to_self.spec.ts index 6610873f..b3713c1b 100644 --- a/run/test/specs/disappear_after_send_note_to_self.spec.ts +++ b/run/test/specs/disappear_after_send_note_to_self.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { DisappearActions, DISAPPEARING_TIMES, USERNAME } from '../../types/testing'; import { PlusButton } from './locators/home'; @@ -14,8 +16,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -async function disappearAfterSendNoteToSelf(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function disappearAfterSendNoteToSelf(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); const testMessage = `Testing disappearing messages in Note to Self`; const alice = await newUser(device, USERNAME.ALICE); const controlMode: DisappearActions = 'sent'; diff --git a/run/test/specs/disappear_after_send_off_1o1.spec.ts b/run/test/specs/disappear_after_send_off_1o1.spec.ts index f9eb356b..9235887c 100644 --- a/run/test/specs/disappear_after_send_off_1o1.spec.ts +++ b/run/test/specs/disappear_after_send_off_1o1.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { DisappearActions, DISAPPEARING_TIMES, DisappearModes } from '../../types/testing'; @@ -22,11 +24,11 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function disappearAfterSendOff1o1(platform: SupportedPlatformsType) { +async function disappearAfterSendOff1o1(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, alice2, bob1 }, prebuilt: { alice, bob }, - } = await open_Alice2_Bob1_friends({ platform, focusFriendsConvo: true }); + } = await open_Alice2_Bob1_friends({ platform, focusFriendsConvo: true, testInfo }); const mode: DisappearModes = 'send'; const controlMode: DisappearActions = 'sent'; diff --git a/run/test/specs/disappearing_call.spec.ts b/run/test/specs/disappearing_call.spec.ts index 86620fc2..68739923 100644 --- a/run/test/specs/disappearing_call.spec.ts +++ b/run/test/specs/disappearing_call.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { DISAPPEARING_TIMES } from '../../types/testing'; import { CallButton } from './locators/conversation'; import { ContinueButton } from './locators/global'; import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; import { setDisappearingMessage } from './utils/set_disappearing_messages'; bothPlatformsItSeparate({ @@ -24,13 +26,14 @@ bothPlatformsItSeparate({ const time = DISAPPEARING_TIMES.THIRTY_SECONDS; const timerType = 'Disappear after send option'; -async function disappearingCallMessage1o1Ios(platform: SupportedPlatformsType) { +async function disappearingCallMessage1o1Ios(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice, bob }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['1:1', timerType, time], bob1); await alice1.clickOnElementAll(new CallButton(alice1)); @@ -89,7 +92,10 @@ async function disappearingCallMessage1o1Ios(platform: SupportedPlatformsType) { await closeApp(alice1, bob1); } -async function disappearingCallMessage1o1Android(platform: SupportedPlatformsType) { +async function disappearingCallMessage1o1Android( + platform: SupportedPlatformsType, + testInfo: TestInfo +) { const time = DISAPPEARING_TIMES.THIRTY_SECONDS; const { devices: { alice1, bob1 }, @@ -97,6 +103,7 @@ async function disappearingCallMessage1o1Android(platform: SupportedPlatformsTyp } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['1:1', timerType, time], bob1); await alice1.clickOnElementAll(new CallButton(alice1)); diff --git a/run/test/specs/disappearing_community_invite.spec.ts b/run/test/specs/disappearing_community_invite.spec.ts index bb32c592..5c16d04d 100644 --- a/run/test/specs/disappearing_community_invite.spec.ts +++ b/run/test/specs/disappearing_community_invite.spec.ts @@ -1,14 +1,16 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { DISAPPEARING_TIMES } from '../../types/testing'; +import { testCommunityLink, testCommunityName } from './../../constants/community'; import { InviteContactsMenuItem } from './locators'; +import { ConversationSettings } from './locators/conversation'; +import { GroupMember } from './locators/groups'; +import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils'; import { joinCommunity } from './utils/join_community'; import { closeApp, SupportedPlatformsType } from './utils/open_app'; import { setDisappearingMessage } from './utils/set_disappearing_messages'; -import { testCommunityLink, testCommunityName } from './../../constants/community'; -import { ConversationSettings } from './locators/conversation'; -import { open_Alice1_Bob1_friends } from './state_builder'; -import { GroupMember } from './locators/groups'; bothPlatformsItSeparate({ title: 'Disappearing community invite message 1:1', @@ -27,13 +29,17 @@ bothPlatformsItSeparate({ const time = DISAPPEARING_TIMES.THIRTY_SECONDS; const timerType = 'Disappear after send option'; -async function disappearingCommunityInviteMessageIos(platform: SupportedPlatformsType) { +async function disappearingCommunityInviteMessageIos( + platform: SupportedPlatformsType, + testInfo: TestInfo +) { const { devices: { alice1, bob1 }, prebuilt: { bob }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['1:1', timerType, time], bob1); // await alice1.navigateBack(); @@ -72,13 +78,17 @@ async function disappearingCommunityInviteMessageIos(platform: SupportedPlatform await closeApp(alice1, bob1); } -async function disappearingCommunityInviteMessageAndroid(platform: SupportedPlatformsType) { +async function disappearingCommunityInviteMessageAndroid( + platform: SupportedPlatformsType, + testInfo: TestInfo +) { const { devices: { alice1, bob1 }, prebuilt: { bob }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['1:1', timerType, time], bob1); diff --git a/run/test/specs/disappearing_gif.spec.ts b/run/test/specs/disappearing_gif.spec.ts index a9cb055c..8bb99150 100644 --- a/run/test/specs/disappearing_gif.spec.ts +++ b/run/test/specs/disappearing_gif.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { DISAPPEARING_TIMES, USERNAME } from '../../types/testing'; import { open_Alice1_Bob1_friends } from './state_builder'; @@ -22,13 +24,14 @@ const time = DISAPPEARING_TIMES.ONE_MINUTE; const timerType = 'Disappear after send option'; const testMessage = "Testing disappearing messages for GIF's"; -async function disappearingGifMessage1o1Ios(platform: SupportedPlatformsType) { +async function disappearingGifMessage1o1Ios(platform: SupportedPlatformsType, testInfo: TestInfo) { const testMessage = "Testing disappearing messages for GIF's"; const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['1:1', timerType, time], bob1); // Click on attachments button @@ -54,12 +57,16 @@ async function disappearingGifMessage1o1Ios(platform: SupportedPlatformsType) { await closeApp(alice1, bob1); } -async function disappearingGifMessage1o1Android(platform: SupportedPlatformsType) { +async function disappearingGifMessage1o1Android( + platform: SupportedPlatformsType, + testInfo: TestInfo +) { const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['1:1', timerType, time], bob1); // Wait for control messages to disappear before sending image diff --git a/run/test/specs/disappearing_image.spec.ts b/run/test/specs/disappearing_image.spec.ts index 34e6f3ba..074ab212 100644 --- a/run/test/specs/disappearing_image.spec.ts +++ b/run/test/specs/disappearing_image.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { DISAPPEARING_TIMES, USERNAME } from '../../types/testing'; import { open_Alice1_Bob1_friends } from './state_builder'; @@ -16,12 +18,13 @@ const time = DISAPPEARING_TIMES.THIRTY_SECONDS; const timerType = 'Disappear after send option'; const testMessage = 'Testing disappearing messages for images'; -async function disappearingImageMessage1o1(platform: SupportedPlatformsType) { +async function disappearingImageMessage1o1(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['1:1', timerType, time], bob1); await sleepFor(500); diff --git a/run/test/specs/disappearing_link.spec.ts b/run/test/specs/disappearing_link.spec.ts index 0cef35ef..451ad876 100644 --- a/run/test/specs/disappearing_link.spec.ts +++ b/run/test/specs/disappearing_link.spec.ts @@ -1,12 +1,14 @@ +import type { TestInfo } from '@playwright/test'; + +import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { DISAPPEARING_TIMES } from '../../types/testing'; import { LinkPreview } from './locators'; +import { OutgoingMessageStatusSent } from './locators/conversation'; import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; import { setDisappearingMessage } from './utils/set_disappearing_messages'; -import { OutgoingMessageStatusSent } from './locators/conversation'; -import { englishStrippedStr } from '../../localizer/englishStrippedStr'; bothPlatformsItSeparate({ title: 'Disappearing link message 1:1', @@ -24,12 +26,13 @@ const time = DISAPPEARING_TIMES.THIRTY_SECONDS; const timerType = 'Disappear after read option'; const testLink = `https://getsession.org/`; -async function disappearingLinkMessage1o1Ios(platform: SupportedPlatformsType) { +async function disappearingLinkMessage1o1Ios(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['1:1', timerType, time], bob1); // Send a link @@ -82,12 +85,16 @@ async function disappearingLinkMessage1o1Ios(platform: SupportedPlatformsType) { await closeApp(alice1, bob1); } -async function disappearingLinkMessage1o1Android(platform: SupportedPlatformsType) { +async function disappearingLinkMessage1o1Android( + platform: SupportedPlatformsType, + testInfo: TestInfo +) { const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['1:1', timerType, time], bob1); // Send a link diff --git a/run/test/specs/disappearing_video.spec.ts b/run/test/specs/disappearing_video.spec.ts index 741d241d..1c8d8d72 100644 --- a/run/test/specs/disappearing_video.spec.ts +++ b/run/test/specs/disappearing_video.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { DISAPPEARING_TIMES, USERNAME } from '../../types/testing'; import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; import { setDisappearingMessage } from './utils/set_disappearing_messages'; bothPlatformsIt({ @@ -16,12 +18,13 @@ const time = DISAPPEARING_TIMES.THIRTY_SECONDS; const timerType = 'Disappear after send option'; const testMessage = 'Testing disappearing messages for videos'; -async function disappearingVideoMessage1o1(platform: SupportedPlatformsType) { +async function disappearingVideoMessage1o1(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['1:1', timerType, time], bob1); await alice1.onIOS().sendVideoiOS(testMessage); diff --git a/run/test/specs/disappearing_voice.spec.ts b/run/test/specs/disappearing_voice.spec.ts index 9bdd840c..d4ba3460 100644 --- a/run/test/specs/disappearing_voice.spec.ts +++ b/run/test/specs/disappearing_voice.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { DISAPPEARING_TIMES, USERNAME } from '../../types/testing'; import { open_Alice1_Bob1_friends } from './state_builder'; @@ -20,12 +22,16 @@ bothPlatformsItSeparate({ const time = DISAPPEARING_TIMES.THIRTY_SECONDS; const timerType = 'Disappear after send option'; -async function disappearingVoiceMessage1o1Ios(platform: SupportedPlatformsType) { +async function disappearingVoiceMessage1o1Ios( + platform: SupportedPlatformsType, + testInfo: TestInfo +) { const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['1:1', timerType, time], bob1); await alice1.sendVoiceMessage(); @@ -50,12 +56,16 @@ async function disappearingVoiceMessage1o1Ios(platform: SupportedPlatformsType) await closeApp(alice1, bob1); } -async function disappearingVoiceMessage1o1Android(platform: SupportedPlatformsType) { +async function disappearingVoiceMessage1o1Android( + platform: SupportedPlatformsType, + testInfo: TestInfo +) { const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['1:1', timerType, time], bob1); await alice1.sendVoiceMessage(); diff --git a/run/test/specs/donate.spec.ts b/run/test/specs/donate.spec.ts index f4aed0d2..7d0d8c62 100644 --- a/run/test/specs/donate.spec.ts +++ b/run/test/specs/donate.spec.ts @@ -1,13 +1,15 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { SafariAddressBar, URLInputField } from './locators/browsers'; +import { OpenLinkButton } from './locators/network_page'; import { DonationsMenuItem, UserSettings } from './locators/settings'; -import { handleChromeFirstTimeOpen } from './utils/handle_first_open'; import { newUser } from './utils/create_account'; +import { handleChromeFirstTimeOpen } from './utils/handle_first_open'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; import { assertUrlIsReachable, ensureHttpsURL } from './utils/utilities'; -import { OpenLinkButton } from './locators/network_page'; bothPlatformsIt({ title: 'Donate linkout', @@ -16,10 +18,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -// TODO add in screenshot verification - -async function donateLinkout(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function donateLinkout(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); const linkURL = 'https://session.foundation/donate#app'; await newUser(device, USERNAME.ALICE); await device.clickOnElementAll(new UserSettings(device)); diff --git a/run/test/specs/group_disappearing_messages_gif.spec.ts b/run/test/specs/group_disappearing_messages_gif.spec.ts index 786b56cd..3add6390 100644 --- a/run/test/specs/group_disappearing_messages_gif.spec.ts +++ b/run/test/specs/group_disappearing_messages_gif.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { DISAPPEARING_TIMES } from '../../types/testing'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; import { setDisappearingMessage } from './utils/set_disappearing_messages'; bothPlatformsIt({ @@ -15,7 +17,7 @@ bothPlatformsIt({ const time = DISAPPEARING_TIMES.THIRTY_SECONDS; const timerType = 'Disappear after send option'; -async function disappearingGifMessageGroup(platform: SupportedPlatformsType) { +async function disappearingGifMessageGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Disappear after sent test'; const testMessage = "Testing disappearing messages for GIF's"; const { @@ -24,6 +26,7 @@ async function disappearingGifMessageGroup(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['Group', timerType, time]); // Click on attachments button diff --git a/run/test/specs/group_disappearing_messages_image.spec.ts b/run/test/specs/group_disappearing_messages_image.spec.ts index 8a95e43b..82f63d8d 100644 --- a/run/test/specs/group_disappearing_messages_image.spec.ts +++ b/run/test/specs/group_disappearing_messages_image.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { DISAPPEARING_TIMES } from '../../types/testing'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; import { setDisappearingMessage } from './utils/set_disappearing_messages'; bothPlatformsIt({ @@ -12,7 +14,7 @@ bothPlatformsIt({ testCb: disappearingImageMessageGroup, }); -async function disappearingImageMessageGroup(platform: SupportedPlatformsType) { +async function disappearingImageMessageGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { const testMessage = 'Testing disappearing messages for images'; const testGroupName = 'Testing disappearing messages'; const time = DISAPPEARING_TIMES.THIRTY_SECONDS; @@ -23,6 +25,7 @@ async function disappearingImageMessageGroup(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['Group', timerType, time]); diff --git a/run/test/specs/group_disappearing_messages_link.spec.ts b/run/test/specs/group_disappearing_messages_link.spec.ts index 31f9944e..8f89c1ce 100644 --- a/run/test/specs/group_disappearing_messages_link.spec.ts +++ b/run/test/specs/group_disappearing_messages_link.spec.ts @@ -1,12 +1,14 @@ +import type { TestInfo } from '@playwright/test'; + +import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { DISAPPEARING_TIMES } from '../../types/testing'; import { LinkPreview, LinkPreviewMessage } from './locators'; +import { OutgoingMessageStatusSent } from './locators/conversation'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; import { sleepFor } from './utils'; import { closeApp, SupportedPlatformsType } from './utils/open_app'; import { setDisappearingMessage } from './utils/set_disappearing_messages'; -import { OutgoingMessageStatusSent } from './locators/conversation'; -import { englishStrippedStr } from '../../localizer/englishStrippedStr'; bothPlatformsIt({ title: 'Disappearing link to group', @@ -17,7 +19,7 @@ bothPlatformsIt({ const timerType = 'Disappear after send option'; const time = DISAPPEARING_TIMES.THIRTY_SECONDS; -async function disappearingLinkMessageGroup(platform: SupportedPlatformsType) { +async function disappearingLinkMessageGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Testing disappearing messages'; const testLink = `https://getsession.org/`; const { @@ -26,6 +28,7 @@ async function disappearingLinkMessageGroup(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['Group', timerType, time]); diff --git a/run/test/specs/group_disappearing_messages_members.spec.ts b/run/test/specs/group_disappearing_messages_members.spec.ts index 16202494..bea43ed7 100644 --- a/run/test/specs/group_disappearing_messages_members.spec.ts +++ b/run/test/specs/group_disappearing_messages_members.spec.ts @@ -1,5 +1,6 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; import { DISAPPEARING_TIMES } from '../../types/testing'; import { ConversationSettings } from './locators/conversation'; import { @@ -8,6 +9,7 @@ import { SetDisappearMessagesButton, } from './locators/disappearing_messages'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Group member disappearing messages', @@ -16,7 +18,10 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function membersCantSetDisappearingMessages(platform: SupportedPlatformsType) { +async function membersCantSetDisappearingMessages( + platform: SupportedPlatformsType, + testInfo: TestInfo +) { const testGroupName = 'Testing disappearing messages'; const { devices: { alice1, bob1, charlie1 }, @@ -24,6 +29,7 @@ async function membersCantSetDisappearingMessages(platform: SupportedPlatformsTy platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); // Member B navigates to DM settings diff --git a/run/test/specs/group_disappearing_messages_video.spec.ts b/run/test/specs/group_disappearing_messages_video.spec.ts index dc286805..dab702c2 100644 --- a/run/test/specs/group_disappearing_messages_video.spec.ts +++ b/run/test/specs/group_disappearing_messages_video.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { DISAPPEARING_TIMES } from '../../types/testing'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; import { setDisappearingMessage } from './utils/set_disappearing_messages'; bothPlatformsIt({ @@ -15,7 +17,7 @@ bothPlatformsIt({ const time = DISAPPEARING_TIMES.THIRTY_SECONDS; const timerType = 'Disappear after send option'; -async function disappearingVideoMessageGroup(platform: SupportedPlatformsType) { +async function disappearingVideoMessageGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { const testMessage = 'Testing disappearing messages for videos'; const testGroupName = 'Testing disappearing messages'; const { @@ -24,6 +26,7 @@ async function disappearingVideoMessageGroup(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['Group', timerType, time]); await alice1.onIOS().sendVideoiOS(testMessage); diff --git a/run/test/specs/group_disappearing_messages_voice.spec.ts b/run/test/specs/group_disappearing_messages_voice.spec.ts index 6f3c5f83..c5d57f8d 100644 --- a/run/test/specs/group_disappearing_messages_voice.spec.ts +++ b/run/test/specs/group_disappearing_messages_voice.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { DISAPPEARING_TIMES, GROUPNAME } from '../../types/testing'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; import { setDisappearingMessage } from './utils/set_disappearing_messages'; bothPlatformsIt({ @@ -12,7 +14,7 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function disappearingVoiceMessageGroup(platform: SupportedPlatformsType) { +async function disappearingVoiceMessageGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName: GROUPNAME = 'Testing voice'; const time = DISAPPEARING_TIMES.THIRTY_SECONDS; const timerType = 'Disappear after send option'; @@ -22,6 +24,7 @@ async function disappearingVoiceMessageGroup(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); await setDisappearingMessage(platform, alice1, ['Group', timerType, time]); await alice1.sendVoiceMessage(); diff --git a/run/test/specs/group_message_delete.spec.ts b/run/test/specs/group_message_delete.spec.ts index eed2d457..c4fff303 100644 --- a/run/test/specs/group_message_delete.spec.ts +++ b/run/test/specs/group_message_delete.spec.ts @@ -1,9 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { DeleteMessageConfirmationModal, DeleteMessageLocally } from './locators'; import { DeletedMessage } from './locators/conversation'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Delete message in group', @@ -12,7 +14,7 @@ bothPlatformsIt({ testCb: deleteMessageGroup, }); -async function deleteMessageGroup(platform: SupportedPlatformsType) { +async function deleteMessageGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const { devices: { alice1, bob1, charlie1 }, @@ -20,6 +22,7 @@ async function deleteMessageGroup(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); const sentMessage = await alice1.sendMessage('Checking local delete functionality'); await Promise.all([ diff --git a/run/test/specs/group_message_document.spec.ts b/run/test/specs/group_message_document.spec.ts index c4a3cc84..5f046e52 100644 --- a/run/test/specs/group_message_document.spec.ts +++ b/run/test/specs/group_message_document.spec.ts @@ -1,7 +1,9 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send document to group', @@ -15,7 +17,7 @@ bothPlatformsItSeparate({ }, }); -async function sendDocumentGroupiOS(platform: SupportedPlatformsType) { +async function sendDocumentGroupiOS(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const { devices: { alice1, bob1, charlie1 }, @@ -24,6 +26,7 @@ async function sendDocumentGroupiOS(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); const testMessage = 'Testing-document-1'; const replyMessage = `Replying to document from ${alice.userName}`; @@ -52,7 +55,7 @@ async function sendDocumentGroupiOS(platform: SupportedPlatformsType) { await closeApp(alice1, bob1, charlie1); } -async function sendDocumentGroupAndroid(platform: SupportedPlatformsType) { +async function sendDocumentGroupAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const { devices: { alice1, bob1, charlie1 }, @@ -61,6 +64,7 @@ async function sendDocumentGroupAndroid(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); const replyMessage = `Replying to document from ${alice.userName} in ${testGroupName}`; diff --git a/run/test/specs/group_message_gif.spec.ts b/run/test/specs/group_message_gif.spec.ts index 31e5c96e..ff92eb61 100644 --- a/run/test/specs/group_message_gif.spec.ts +++ b/run/test/specs/group_message_gif.spec.ts @@ -1,7 +1,9 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send GIF to group', @@ -15,7 +17,7 @@ bothPlatformsItSeparate({ }, }); -async function sendGifGroupiOS(platform: SupportedPlatformsType) { +async function sendGifGroupiOS(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const { @@ -25,6 +27,7 @@ async function sendGifGroupiOS(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo: testInfo, }); const testMessage = 'Testing-GIF-1'; @@ -59,7 +62,7 @@ async function sendGifGroupiOS(platform: SupportedPlatformsType) { await closeApp(alice1, bob1, charlie1); } -async function sendGifGroupAndroid(platform: SupportedPlatformsType) { +async function sendGifGroupAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const { @@ -69,6 +72,7 @@ async function sendGifGroupAndroid(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo: testInfo, }); const testMessage = 'Testing-GIF-1'; const replyMessage = `Replying to GIF from ${alice.userName}`; diff --git a/run/test/specs/group_message_image.spec.ts b/run/test/specs/group_message_image.spec.ts index 3b889093..14cd14d7 100644 --- a/run/test/specs/group_message_image.spec.ts +++ b/run/test/specs/group_message_image.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; +import { OutgoingMessageStatusSent } from './locators/conversation'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; -import { OutgoingMessageStatusSent } from './locators/conversation'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send image to group', @@ -16,7 +18,7 @@ bothPlatformsItSeparate({ }, }); -async function sendImageGroupiOS(platform: SupportedPlatformsType) { +async function sendImageGroupiOS(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const testMessage = 'Sending image to group'; @@ -27,6 +29,7 @@ async function sendImageGroupiOS(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); await alice1.sendImage(testMessage); await alice1.waitForTextElementToBePresent({ @@ -66,7 +69,7 @@ async function sendImageGroupiOS(platform: SupportedPlatformsType) { await closeApp(alice1, bob1, charlie1); } -async function sendImageGroupAndroid(platform: SupportedPlatformsType) { +async function sendImageGroupAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const testMessage = 'Testing image sending to groups'; @@ -77,6 +80,7 @@ async function sendImageGroupAndroid(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); const replyMessage = `Replying to image from ${alice.userName}`; await alice1.sendImage(testMessage); diff --git a/run/test/specs/group_message_link_preview.spec.ts b/run/test/specs/group_message_link_preview.spec.ts index 3e496df2..68225d9d 100644 --- a/run/test/specs/group_message_link_preview.spec.ts +++ b/run/test/specs/group_message_link_preview.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + +import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { LinkPreview, LinkPreviewMessage } from './locators'; +import { OutgoingMessageStatusSent } from './locators/conversation'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; -import { OutgoingMessageStatusSent } from './locators/conversation'; -import { englishStrippedStr } from '../../localizer/englishStrippedStr'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send link to group', @@ -18,7 +20,7 @@ bothPlatformsItSeparate({ }, }); -async function sendLinkGroupiOS(platform: SupportedPlatformsType) { +async function sendLinkGroupiOS(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const testLink = `https://getsession.org/`; @@ -29,6 +31,7 @@ async function sendLinkGroupiOS(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); const replyMessage = `Replying to link from ${alice.userName} in group ${testGroupName}`; // Create contact between User A and User B @@ -82,7 +85,7 @@ async function sendLinkGroupiOS(platform: SupportedPlatformsType) { await closeApp(alice1, bob1, charlie1); } -async function sendLinkGroupAndroid(platform: SupportedPlatformsType) { +async function sendLinkGroupAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const { @@ -92,6 +95,7 @@ async function sendLinkGroupAndroid(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); const testLink = `https://getsession.org/`; // Send a link diff --git a/run/test/specs/group_message_long_text.spec.ts b/run/test/specs/group_message_long_text.spec.ts index 3cce2d27..d7584fde 100644 --- a/run/test/specs/group_message_long_text.spec.ts +++ b/run/test/specs/group_message_long_text.spec.ts @@ -1,9 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { longText } from '../../constants'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; -import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; import { OutgoingMessageStatusSent } from './locators/conversation'; import { ConversationItem } from './locators/home'; +import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send long message to group', @@ -17,7 +19,7 @@ bothPlatformsItSeparate({ }, }); -async function sendLongMessageGroupiOS(platform: SupportedPlatformsType) { +async function sendLongMessageGroupiOS(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; // Sending a long text message @@ -28,6 +30,7 @@ async function sendLongMessageGroupiOS(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); await alice1.sendMessage(longText); await bob1.waitForTextElementToBePresent({ @@ -55,7 +58,7 @@ async function sendLongMessageGroupiOS(platform: SupportedPlatformsType) { await closeApp(alice1, bob1, charlie1); } -async function sendLongMessageGroupAndroid(platform: SupportedPlatformsType) { +async function sendLongMessageGroupAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const { @@ -65,6 +68,7 @@ async function sendLongMessageGroupAndroid(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); // Sending a long text message diff --git a/run/test/specs/group_message_unsend.spec.ts b/run/test/specs/group_message_unsend.spec.ts index 72515ca8..fb742003 100644 --- a/run/test/specs/group_message_unsend.spec.ts +++ b/run/test/specs/group_message_unsend.spec.ts @@ -1,9 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { DeleteMessageConfirmationModal, DeleteMessageForEveryone } from './locators'; import { DeletedMessage } from './locators/conversation'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Unsend message in group', @@ -12,7 +14,7 @@ bothPlatformsIt({ testCb: unsendMessageGroup, }); -async function unsendMessageGroup(platform: SupportedPlatformsType) { +async function unsendMessageGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const { @@ -21,6 +23,7 @@ async function unsendMessageGroup(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); const sentMessage = await alice1.sendMessage('Checking unsend functionality'); await Promise.all([ diff --git a/run/test/specs/group_message_video.spec.ts b/run/test/specs/group_message_video.spec.ts index b7700fdf..7c285199 100644 --- a/run/test/specs/group_message_video.spec.ts +++ b/run/test/specs/group_message_video.spec.ts @@ -1,6 +1,8 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send video to group', @@ -14,7 +16,7 @@ bothPlatformsItSeparate({ }, }); -async function sendVideoGroupiOS(platform: SupportedPlatformsType) { +async function sendVideoGroupiOS(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const { @@ -24,6 +26,7 @@ async function sendVideoGroupiOS(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); const testMessage = 'Testing-video-1'; const replyMessage = `Replying to video from ${alice.userName} in ${testGroupName}`; @@ -61,7 +64,7 @@ async function sendVideoGroupiOS(platform: SupportedPlatformsType) { await closeApp(alice1, bob1, charlie1); } -async function sendVideoGroupAndroid(platform: SupportedPlatformsType) { +async function sendVideoGroupAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { // Test sending a video // open devices const testGroupName = 'Message checks for groups'; @@ -73,6 +76,7 @@ async function sendVideoGroupAndroid(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); const replyMessage = `Replying to video from ${alice.userName} in ${testGroupName}`; // Click on attachments button diff --git a/run/test/specs/group_message_voice.spec.ts b/run/test/specs/group_message_voice.spec.ts index dbfd743d..9c7d342b 100644 --- a/run/test/specs/group_message_voice.spec.ts +++ b/run/test/specs/group_message_voice.spec.ts @@ -1,6 +1,8 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send voice message to group', @@ -14,7 +16,7 @@ bothPlatformsItSeparate({ }, }); -async function sendVoiceMessageGroupiOS(platform: SupportedPlatformsType) { +async function sendVoiceMessageGroupiOS(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Message checks for groups'; const { devices: { alice1, bob1, charlie1 }, @@ -23,6 +25,7 @@ async function sendVoiceMessageGroupiOS(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); const replyMessage = `Replying to voice message from ${alice.userName} in ${testGroupName}`; await alice1.sendVoiceMessage(); @@ -50,7 +53,7 @@ async function sendVoiceMessageGroupiOS(platform: SupportedPlatformsType) { await closeApp(alice1, bob1, charlie1); } -async function sendVoiceMessageGroupAndroid(platform: SupportedPlatformsType) { +async function sendVoiceMessageGroupAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { // open devices const testGroupName = 'Message checks for groups'; const { @@ -60,6 +63,7 @@ async function sendVoiceMessageGroupAndroid(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); const replyMessage = `Replying to voice message from ${alice.userName} in ${testGroupName}`; // Select voice message button to activate recording state diff --git a/run/test/specs/group_tests_add_contact.spec.ts b/run/test/specs/group_tests_add_contact.spec.ts index 6c4cd9ca..ddf444e8 100644 --- a/run/test/specs/group_tests_add_contact.spec.ts +++ b/run/test/specs/group_tests_add_contact.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; @@ -10,7 +12,7 @@ import { open_Alice1_Bob1_Charlie1_Unknown1 } from './state_builder'; import { sleepFor } from './utils'; import { newUser } from './utils/create_account'; import { newContact } from './utils/create_contact'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Add contact to group', @@ -18,7 +20,7 @@ bothPlatformsIt({ testCb: addContactToGroup, countOfDevicesNeeded: 4, }); -async function addContactToGroup(platform: SupportedPlatformsType) { +async function addContactToGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Group to test adding contact'; const { devices: { alice1, bob1, charlie1, unknown1 }, @@ -27,6 +29,7 @@ async function addContactToGroup(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo: testInfo, }); const userD = await newUser(unknown1, USERNAME.DRACULA); await alice1.navigateBack(); diff --git a/run/test/specs/group_tests_change_group_name.spec.ts b/run/test/specs/group_tests_change_group_name.spec.ts index f79fbe58..d505178c 100644 --- a/run/test/specs/group_tests_change_group_name.spec.ts +++ b/run/test/specs/group_tests_change_group_name.spec.ts @@ -1,14 +1,16 @@ +import type { TestInfo } from '@playwright/test'; + +import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; +import { ConversationSettings } from './locators/conversation'; import { - UpdateGroupInformation, EditGroupNameInput, SaveGroupNameChangeButton, + UpdateGroupInformation, } from './locators/groups'; -import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; -import { ConversationSettings } from './locators/conversation'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; -import { englishStrippedStr } from '../../localizer/englishStrippedStr'; +import { sleepFor } from './utils'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Change group name', @@ -22,7 +24,7 @@ bothPlatformsItSeparate({ }, }); -async function changeGroupNameIos(platform: SupportedPlatformsType) { +async function changeGroupNameIos(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Test group'; const newGroupName = 'Changed group name'; @@ -32,6 +34,7 @@ async function changeGroupNameIos(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); // Click on settings or three dots await alice1.clickOnElementAll(new ConversationSettings(alice1)); @@ -51,7 +54,7 @@ async function changeGroupNameIos(platform: SupportedPlatformsType) { }); const attr = await alice1.getAttribute('value', saveButton.ELEMENT); if (attr !== 'enabled') { - console.log('Save button disabled - no text input'); + alice1.log('Save button disabled - no text input'); } else { throw new Error('Save button should be disabled'); } @@ -69,7 +72,7 @@ async function changeGroupNameIos(platform: SupportedPlatformsType) { await closeApp(alice1, bob1, charlie1); } -async function changeGroupNameAndroid(platform: SupportedPlatformsType) { +async function changeGroupNameAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Test group'; const newGroupName = 'Changed group name'; @@ -79,6 +82,7 @@ async function changeGroupNameAndroid(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); // Click on settings or three dots await alice1.clickOnElementAll(new ConversationSettings(alice1)); diff --git a/run/test/specs/group_tests_create_group.spec.ts b/run/test/specs/group_tests_create_group.spec.ts index e9da2704..b2158f3f 100644 --- a/run/test/specs/group_tests_create_group.spec.ts +++ b/run/test/specs/group_tests_create_group.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { newUser } from './utils/create_account'; import { createGroup } from './utils/create_group'; -import { SupportedPlatformsType, closeApp, openAppThreeDevices } from './utils/open_app'; +import { closeApp, openAppThreeDevices, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Create group', @@ -11,9 +13,9 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function groupCreation(platform: SupportedPlatformsType) { +async function groupCreation(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Test group'; - const { device1, device2, device3 } = await openAppThreeDevices(platform); + const { device1, device2, device3 } = await openAppThreeDevices(platform, testInfo); // Create users A, B and C const [alice, bob, charlie] = await Promise.all([ newUser(device1, USERNAME.ALICE), diff --git a/run/test/specs/group_tests_create_group_banner.spec.ts b/run/test/specs/group_tests_create_group_banner.spec.ts index 596ce244..628ec78e 100644 --- a/run/test/specs/group_tests_create_group_banner.spec.ts +++ b/run/test/specs/group_tests_create_group_banner.spec.ts @@ -1,9 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; +import { LatestReleaseBanner } from './locators/groups'; import { PlusButton } from './locators/home'; import { CreateGroupOption } from './locators/start_conversation'; -import { closeApp, SupportedPlatformsType } from './utils/open_app'; -import { LatestReleaseBanner } from './locators/groups'; import { open_Alice1_Bob1_friends } from './state_builder'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Create group banner', @@ -11,12 +13,13 @@ bothPlatformsIt({ testCb: createGroupBanner, countOfDevicesNeeded: 2, }); -async function createGroupBanner(platform: SupportedPlatformsType) { +async function createGroupBanner(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); await alice1.navigateBack(); // Open the Create Group screen from home diff --git a/run/test/specs/group_tests_edit_group_banner.spec.ts b/run/test/specs/group_tests_edit_group_banner.spec.ts index cd11d5e5..91ff01bf 100644 --- a/run/test/specs/group_tests_edit_group_banner.spec.ts +++ b/run/test/specs/group_tests_edit_group_banner.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; -import { closeApp, SupportedPlatformsType } from './utils/open_app'; import { ConversationSettings } from './locators/conversation'; import { LatestReleaseBanner, ManageMembersMenuItem } from './locators/groups'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Edit group banner', @@ -11,7 +13,7 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function editGroupBanner(platform: SupportedPlatformsType) { +async function editGroupBanner(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Test group'; const { @@ -20,6 +22,7 @@ async function editGroupBanner(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); // Navigate to Edit Group screen await alice1.clickOnElementAll(new ConversationSettings(alice1)); diff --git a/run/test/specs/group_tests_invite_contact_banner.spec.ts b/run/test/specs/group_tests_invite_contact_banner.spec.ts index 6a0d485e..c852975b 100644 --- a/run/test/specs/group_tests_invite_contact_banner.spec.ts +++ b/run/test/specs/group_tests_invite_contact_banner.spec.ts @@ -1,9 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; -import { closeApp, SupportedPlatformsType } from './utils/open_app'; -import { ConversationSettings } from './locators/conversation'; import { InviteContactsButton } from './locators'; +import { ConversationSettings } from './locators/conversation'; import { LatestReleaseBanner, ManageMembersMenuItem } from './locators/groups'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Invite contacts banner', @@ -12,7 +14,7 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function inviteContactGroupBanner(platform: SupportedPlatformsType) { +async function inviteContactGroupBanner(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Test group'; const { @@ -21,6 +23,7 @@ async function inviteContactGroupBanner(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); // Navigate to Invite Contacts screen await alice1.clickOnElementAll(new ConversationSettings(alice1)); diff --git a/run/test/specs/group_tests_kick_member.spec.ts b/run/test/specs/group_tests_kick_member.spec.ts index 5bc52c7a..d26b0b34 100644 --- a/run/test/specs/group_tests_kick_member.spec.ts +++ b/run/test/specs/group_tests_kick_member.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; @@ -19,7 +21,7 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function kickMember(platform: SupportedPlatformsType) { +async function kickMember(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Kick member'; const { @@ -28,6 +30,7 @@ async function kickMember(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); await alice1.clickOnElementAll(new ConversationSettings(alice1)); await alice1.clickOnElementAll(new ManageMembersMenuItem(alice1)); diff --git a/run/test/specs/group_tests_leave_group.spec.ts b/run/test/specs/group_tests_leave_group.spec.ts index 2f2cb895..3dde5bd0 100644 --- a/run/test/specs/group_tests_leave_group.spec.ts +++ b/run/test/specs/group_tests_leave_group.spec.ts @@ -1,11 +1,13 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { ConversationSettings } from './locators/conversation'; -import { LeaveGroupMenuItem, LeaveGroupConfirm } from './locators/groups'; +import { LeaveGroupConfirm, LeaveGroupMenuItem } from './locators/groups'; import { ConversationItem } from './locators/home'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; import { sleepFor } from './utils/index'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Leave group', @@ -14,7 +16,7 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function leaveGroup(platform: SupportedPlatformsType) { +async function leaveGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Leave group'; const { @@ -24,6 +26,7 @@ async function leaveGroup(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); await charlie1.clickOnElementAll(new ConversationSettings(charlie1)); await sleepFor(1000); diff --git a/run/test/specs/group_tests_mentions.spec.ts b/run/test/specs/group_tests_mentions.spec.ts index 79b7e109..7abf2e39 100644 --- a/run/test/specs/group_tests_mentions.spec.ts +++ b/run/test/specs/group_tests_mentions.spec.ts @@ -1,6 +1,8 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { open_Alice1_Bob1_Charlie1_friends_group } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Mentions for groups', @@ -9,7 +11,7 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function mentionsForGroups(platform: SupportedPlatformsType) { +async function mentionsForGroups(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Mentions test group'; const { devices: { alice1, bob1, charlie1 }, @@ -18,6 +20,7 @@ async function mentionsForGroups(platform: SupportedPlatformsType) { platform, groupName: testGroupName, focusGroupConvo: true, + testInfo, }); await alice1.mentionContact(platform, bob); 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 bc2269b2..d855b7bd 100644 --- a/run/test/specs/input_validations/onboarding_incorrect_seed.spec.ts +++ b/run/test/specs/input_validations/onboarding_incorrect_seed.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../../types/sessionIt'; +import { ContinueButton } from '../locators/global'; import { AccountRestoreButton, ErrorMessage, SeedPhraseInput } from '../locators/onboarding'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from '../utils/open_app'; -import { ContinueButton } from '../locators/global'; bothPlatformsIt({ title: 'Onboarding incorrect seed', @@ -11,8 +13,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -async function onboardingIncorrectSeed(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function onboardingIncorrectSeed(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); await device.clickOnElementAll(new AccountRestoreButton(device)); // the word 'zork' is not on the mnemonic word list which triggers the expected error const incorrectSeed = 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 2976e358..0242f93c 100644 --- a/run/test/specs/input_validations/onboarding_long_name.spec.ts +++ b/run/test/specs/input_validations/onboarding_long_name.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../../types/sessionIt'; +import { ContinueButton } from '../locators/global'; import { CreateAccountButton, DisplayNameInput, ErrorMessage } from '../locators/onboarding'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from '../utils/open_app'; -import { ContinueButton } from '../locators/global'; bothPlatformsIt({ title: 'Onboarding long name', @@ -11,8 +13,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -async function onboardingLongName(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function onboardingLongName(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); // 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'; 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 99829314..e7acd93d 100644 --- a/run/test/specs/input_validations/onboarding_no_name.spec.ts +++ b/run/test/specs/input_validations/onboarding_no_name.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../../types/sessionIt'; +import { ContinueButton } from '../locators/global'; import { CreateAccountButton, DisplayNameInput, ErrorMessage } from '../locators/onboarding'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from '../utils/open_app'; -import { ContinueButton } from '../locators/global'; bothPlatformsIt({ title: 'Onboarding no name', @@ -11,8 +13,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -async function onboardingNoName(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function onboardingNoName(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); await device.clickOnElementAll(new CreateAccountButton(device)); // the expected error is 'Please enter a display name' which is represented by the following localized string const expectedError = englishStrippedStr('displayNameErrorDescription').toString(); 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 f2a6c145..f4a59cd0 100644 --- a/run/test/specs/input_validations/onboarding_no_seed.spec.ts +++ b/run/test/specs/input_validations/onboarding_no_seed.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../../types/sessionIt'; +import { ContinueButton } from '../locators/global'; import { AccountRestoreButton, ErrorMessage, SeedPhraseInput } from '../locators/onboarding'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from '../utils/open_app'; -import { ContinueButton } from '../locators/global'; bothPlatformsIt({ title: 'Onboarding no seed', @@ -11,8 +13,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -async function onboardingNoSeed(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function onboardingNoSeed(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); await device.clickOnElementAll(new AccountRestoreButton(device)); const emptySeed = ''; // the expected error is 'Recovery Password not long enough' which is represented by the following localized string 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 d883634a..36b1ed78 100644 --- a/run/test/specs/input_validations/onboarding_wrong_seed.spec.ts +++ b/run/test/specs/input_validations/onboarding_wrong_seed.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../../types/sessionIt'; +import { ContinueButton } from '../locators/global'; import { AccountRestoreButton, ErrorMessage, SeedPhraseInput } from '../locators/onboarding'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from '../utils/open_app'; -import { ContinueButton } from '../locators/global'; bothPlatformsIt({ title: 'Onboarding wrong seed', @@ -11,8 +13,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -async function onboardingIncorrectSeed(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function onboardingIncorrectSeed(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); // 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'; diff --git a/run/test/specs/invite_a_friend_share.spec.ts b/run/test/specs/invite_a_friend_share.spec.ts index b05bc9a1..a40a0147 100644 --- a/run/test/specs/invite_a_friend_share.spec.ts +++ b/run/test/specs/invite_a_friend_share.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + +import { IOS_XPATHS } from '../../constants'; import { bothPlatformsIt } from '../../types/sessionIt'; -import { newUser } from './utils/create_account'; -import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; import { USERNAME } from '../../types/testing'; import { PlusButton } from './locators/home'; import { AccountIDField, InviteAFriendOption, ShareButton } from './locators/start_conversation'; -import { IOS_XPATHS } from '../../constants'; +import { newUser } from './utils/create_account'; +import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Invite a friend', @@ -13,8 +15,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -async function inviteAFriend(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function inviteAFriend(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); let messageElement; // This is a const so that the user.accountID can be used later on const user = await newUser(device, USERNAME.ALICE); @@ -41,7 +43,7 @@ async function inviteAFriend(platform: SupportedPlatformsType) { // 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"); + device.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}` diff --git a/run/test/specs/landing_page_new_account.spec.ts b/run/test/specs/landing_page_new_account.spec.ts index 36edcf9f..cb990497 100644 --- a/run/test/specs/landing_page_new_account.spec.ts +++ b/run/test/specs/landing_page_new_account.spec.ts @@ -1,10 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; +import { USERNAME } from '../../types/testing'; import { newUser } from './utils/create_account'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; -import { USERNAME } from '../../types/testing'; -import { verifyElementScreenshot } from './utils/verify_screenshots'; import { EmptyLandingPageScreenshot } from './utils/screenshot_paths'; -import type { TestInfo } from '@playwright/test'; +import { verifyElementScreenshot } from './utils/verify_screenshots'; bothPlatformsIt({ title: 'Landing page new account', @@ -12,8 +13,9 @@ bothPlatformsIt({ testCb: landingPageNewAccount, countOfDevicesNeeded: 1, }); + async function landingPageNewAccount(platform: SupportedPlatformsType, testInfo: TestInfo) { - const { device } = await openAppOnPlatformSingleDevice(platform); + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); await newUser(device, USERNAME.ALICE); // Verify that the party popper is shown on the landing page await verifyElementScreenshot( diff --git a/run/test/specs/landing_page_restore_account.spec.ts b/run/test/specs/landing_page_restore_account.spec.ts index e3188a19..70f36b63 100644 --- a/run/test/specs/landing_page_restore_account.spec.ts +++ b/run/test/specs/landing_page_restore_account.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + +import { USERNAME } from '@session-foundation/qa-seeder'; + import { bothPlatformsIt } from '../../types/sessionIt'; +import { linkedDevice } from './utils/link_device'; import { closeApp, openAppTwoDevices, SupportedPlatformsType } from './utils/open_app'; -import { verifyElementScreenshot } from './utils/verify_screenshots'; import { EmptyLandingPageScreenshot } from './utils/screenshot_paths'; -import { USERNAME } from '@session-foundation/qa-seeder'; -import { linkedDevice } from './utils/link_device'; -import type { TestInfo } from '@playwright/test'; +import { verifyElementScreenshot } from './utils/verify_screenshots'; bothPlatformsIt({ title: 'Landing page restore account', @@ -15,7 +17,7 @@ bothPlatformsIt({ async function landingPageRestoreAccount(platform: SupportedPlatformsType, testInfo: TestInfo) { // Creating a linked device is used as a shortcut to restore an account - const { device1: alice1, device2: alice2 } = await openAppTwoDevices(platform); + const { device1: alice1, device2: alice2 } = await openAppTwoDevices(platform, testInfo); await linkedDevice(alice1, alice2, USERNAME.ALICE); // Verify that the Session logo is shown on the landing page await verifyElementScreenshot( diff --git a/run/test/specs/linked_device.spec.ts b/run/test/specs/linked_device.spec.ts index 0f82b3f9..0d548e8a 100644 --- a/run/test/specs/linked_device.spec.ts +++ b/run/test/specs/linked_device.spec.ts @@ -1,9 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + import { USERNAME } from '@session-foundation/qa-seeder'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { UsernameSettings } from './locators'; import { UserSettings } from './locators/settings'; import { linkedDevice } from './utils/link_device'; -import { SupportedPlatformsType, closeApp, openAppTwoDevices } from './utils/open_app'; +import { closeApp, openAppTwoDevices, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Link device', @@ -12,9 +15,9 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function linkDevice(platform: SupportedPlatformsType) { +async function linkDevice(platform: SupportedPlatformsType, testInfo: TestInfo) { // Open server and two devices - const { device1: alice1, device2: alice2 } = await openAppTwoDevices(platform); + const { device1: alice1, device2: alice2 } = await openAppTwoDevices(platform, testInfo); // link device const alice = await linkedDevice(alice1, alice2, USERNAME.ALICE); // Check that 'Youre almost finished' reminder doesn't pop up on alice2 diff --git a/run/test/specs/linked_device_avatar_color.spec.ts b/run/test/specs/linked_device_avatar_color.spec.ts index 349475ed..cb8136b2 100644 --- a/run/test/specs/linked_device_avatar_color.spec.ts +++ b/run/test/specs/linked_device_avatar_color.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; -import { isSameColor } from './utils/check_colour'; import { UserSettings } from './locators/settings'; import { open_Alice2 } from './state_builder'; +import { isSameColor } from './utils/check_colour'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Avatar color linked device', @@ -10,11 +12,11 @@ bothPlatformsIt({ testCb: avatarColorLinkedDevice, countOfDevicesNeeded: 2, }); -async function avatarColorLinkedDevice(platform: SupportedPlatformsType) { +async function avatarColorLinkedDevice(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, alice2 }, prebuilt: { alice }, - } = await open_Alice2({ platform }); + } = await open_Alice2({ platform, testInfo }); // Get Alice's avatar color on device 1 (Home Screen avatar) and turn it into a hex value const alice1PixelColor = await alice1.getElementPixelColor(new UserSettings(alice1)); diff --git a/run/test/specs/linked_device_block_user.spec.ts b/run/test/specs/linked_device_block_user.spec.ts index aaa779cb..9c1cb1ef 100644 --- a/run/test/specs/linked_device_block_user.spec.ts +++ b/run/test/specs/linked_device_block_user.spec.ts @@ -1,7 +1,9 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { BlockedContactsSettings, BlockUser, BlockUserConfirmationModal } from './locators'; -import { ConversationSettings, BlockedBanner } from './locators/conversation'; +import { BlockedBanner, ConversationSettings } from './locators/conversation'; import { ConversationItem } from './locators/home'; import { ConversationsMenuItem, UserSettings } from './locators/settings'; import { open_Alice2_Bob1_friends } from './state_builder'; @@ -15,13 +17,15 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function blockUserInConversationOptions(platform: SupportedPlatformsType) { +async function blockUserInConversationOptions( + platform: SupportedPlatformsType, + testInfo: TestInfo +) { const { devices: { alice1, alice2, bob1 }, prebuilt: { bob }, - } = await open_Alice2_Bob1_friends({ platform, focusFriendsConvo: true }); + } = await open_Alice2_Bob1_friends({ platform, focusFriendsConvo: true, testInfo }); // Block contact - await alice1.clickOnElementAll(new ConversationSettings(alice1)); // Select Block option await sleepFor(500); @@ -43,9 +47,9 @@ async function blockUserInConversationOptions(platform: SupportedPlatformsType) // Check linked device for blocked status (if shown on alice1) await alice2.onAndroid().clickOnElementAll(new ConversationItem(alice2, bob.userName)); await alice2.onAndroid().waitForTextElementToBePresent(new BlockedBanner(alice2)); - console.info(`${bob.userName}` + ' has been blocked'); + alice2.info(`${bob.userName}` + ' has been blocked'); } else { - console.info('Blocked banner not found'); + alice2.info('Blocked banner not found'); } // Check settings for blocked user await Promise.all([alice1.navigateBack(), alice2.onAndroid().navigateBack()]); diff --git a/run/test/specs/linked_device_change_username.spec.ts b/run/test/specs/linked_device_change_username.spec.ts index c5a1c057..eb8ee325 100644 --- a/run/test/specs/linked_device_change_username.spec.ts +++ b/run/test/specs/linked_device_change_username.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { TickButton, UsernameInput, UsernameSettings } from './locators'; import { SaveNameChangeButton, UserSettings } from './locators/settings'; import { open_Alice2 } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Change username linked device', @@ -18,11 +20,11 @@ bothPlatformsItSeparate({ }, }); -async function changeUsernameLinkediOS(platform: SupportedPlatformsType) { +async function changeUsernameLinkediOS(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, alice2 }, prebuilt: { alice }, - } = await open_Alice2({ platform }); + } = await open_Alice2({ platform, testInfo }); const newUsername = 'Alice in chains'; // click on settings/profile avatar @@ -67,11 +69,11 @@ async function changeUsernameLinkediOS(platform: SupportedPlatformsType) { await closeApp(alice1, alice2); } -async function changeUsernameLinkedAndroid(platform: SupportedPlatformsType) { +async function changeUsernameLinkedAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, alice2 }, prebuilt: { alice }, - } = await open_Alice2({ platform }); + } = await open_Alice2({ platform, testInfo }); const newUsername = 'Alice in chains'; // click on settings/profile avatar @@ -111,7 +113,7 @@ async function changeUsernameLinkedAndroid(platform: SupportedPlatformsType) { currentLinkedUsername = await alice2.getTextFromElement(linkedUsernameEl); } while (currentLinkedUsername === alice.userName && currentWait < maxWait); { - console.log('Username not changed yet'); + alice2.log('Username not changed yet'); } await closeApp(alice1, alice2); } diff --git a/run/test/specs/linked_device_create_group.spec.ts b/run/test/specs/linked_device_create_group.spec.ts index 71cca47f..88eb0ac8 100644 --- a/run/test/specs/linked_device_create_group.spec.ts +++ b/run/test/specs/linked_device_create_group.spec.ts @@ -1,18 +1,20 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { ConversationHeaderName, ConversationSettings } from './locators/conversation'; import { EditGroupNameInput, - UpdateGroupInformation, SaveGroupNameChangeButton, + UpdateGroupInformation, } from './locators/groups'; import { ConversationItem } from './locators/home'; import { sleepFor } from './utils'; import { newUser } from './utils/create_account'; import { createGroup } from './utils/create_group'; import { linkedDevice } from './utils/link_device'; -import { SupportedPlatformsType, closeApp, openAppFourDevices } from './utils/open_app'; +import { closeApp, openAppFourDevices, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Create group and change name syncs', @@ -26,8 +28,8 @@ bothPlatformsItSeparate({ }, }); -async function linkedGroupiOS(platform: SupportedPlatformsType) { - const { device1, device2, device3, device4 } = await openAppFourDevices(platform); +async function linkedGroupiOS(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device1, device2, device3, device4 } = await openAppFourDevices(platform, testInfo); const alice = await linkedDevice(device1, device2, USERNAME.ALICE); const [bob, charlie] = await Promise.all([ newUser(device3, USERNAME.BOB), @@ -79,10 +81,10 @@ async function linkedGroupiOS(platform: SupportedPlatformsType) { await closeApp(device1, device2, device3, device4); } -async function linkedGroupAndroid(platform: SupportedPlatformsType) { +async function linkedGroupAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Test group'; const newGroupName = 'Changed group name'; - const { device1, device2, device3, device4 } = await openAppFourDevices(platform); + const { device1, device2, device3, device4 } = await openAppFourDevices(platform, testInfo); // Create users A, B and C const alice = await linkedDevice(device1, device2, USERNAME.ALICE); const [bob, charlie] = await Promise.all([ diff --git a/run/test/specs/linked_device_delete_message.spec.ts b/run/test/specs/linked_device_delete_message.spec.ts index 557f63d3..bba53474 100644 --- a/run/test/specs/linked_device_delete_message.spec.ts +++ b/run/test/specs/linked_device_delete_message.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { DeleteMessageConfirmationModal } from './locators'; import { DeletedMessage } from './locators/conversation'; import { ConversationItem } from './locators/home'; import { open_Alice2_Bob1_friends } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Delete message linked device', @@ -12,11 +14,11 @@ bothPlatformsIt({ testCb: deletedMessageLinkedDevice, countOfDevicesNeeded: 3, }); -async function deletedMessageLinkedDevice(platform: SupportedPlatformsType) { +async function deletedMessageLinkedDevice(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1, alice2 }, prebuilt: { bob }, - } = await open_Alice2_Bob1_friends({ platform, focusFriendsConvo: true }); + } = await open_Alice2_Bob1_friends({ platform, focusFriendsConvo: true, testInfo }); const testMessage = 'Howdy'; // Send message from user a to user b diff --git a/run/test/specs/linked_device_hide_note_to_self.spec.ts b/run/test/specs/linked_device_hide_note_to_self.spec.ts index 6da2cc11..0d039e9d 100644 --- a/run/test/specs/linked_device_hide_note_to_self.spec.ts +++ b/run/test/specs/linked_device_hide_note_to_self.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { EmptyConversation, Hide } from './locators/conversation'; @@ -20,10 +22,10 @@ bothPlatformsItSeparate({ }, }); -async function hideNoteToSelf(platform: SupportedPlatformsType) { +async function hideNoteToSelf(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, alice2 }, - } = await open_Alice2({ platform }); + } = await open_Alice2({ platform, testInfo }); const noteToSelf = englishStrippedStr('noteToSelf').toString(); await alice1.clickOnElementAll(new SearchButton(alice1)); diff --git a/run/test/specs/linked_device_profile_picture_syncs.spec.ts b/run/test/specs/linked_device_profile_picture_syncs.spec.ts index 7db7a686..8d46208c 100644 --- a/run/test/specs/linked_device_profile_picture_syncs.spec.ts +++ b/run/test/specs/linked_device_profile_picture_syncs.spec.ts @@ -1,9 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { UserSettings } from './locators/settings'; import { open_Alice2 } from './state_builder'; import { runOnlyOnAndroid, sleepFor } from './utils'; import { parseDataImage } from './utils/check_colour'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Avatar restored', @@ -12,10 +14,10 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function avatarRestored(platform: SupportedPlatformsType) { +async function avatarRestored(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, alice2 }, - } = await open_Alice2({ platform }); + } = await open_Alice2({ platform, testInfo }); let expectedPixelHexColour: string; if (platform === 'android') { @@ -38,11 +40,11 @@ async function avatarRestored(platform: SupportedPlatformsType) { const base64 = await alice1.getElementScreenshot(profilePicture.ELEMENT); const actualPixelColor = await parseDataImage(base64); if (actualPixelColor === expectedPixelHexColour) { - console.log('alice1: Colour is correct'); + alice1.log('Colour is correct'); } else { - throw new Error(`alice1: Colour isn't ${expectedPixelHexColour}, it is: ` + actualPixelColor); + throw new Error(`Colour isn't ${expectedPixelHexColour}, it is: ` + actualPixelColor); } - console.log('Now checking avatar on linked device'); + alice2.log('Now checking avatar on linked device'); // Check avatar on device 2 await sleepFor(5000); await alice2.closeScreen(); @@ -55,7 +57,7 @@ async function avatarRestored(platform: SupportedPlatformsType) { `alice1: Colour isn't ${expectedPixelHexColour}, it is: ` + actualPixelColorLinked ); } - console.log('Device 2: Colour is correct on linked device'); + alice2.log('Colour is correct on linked device'); await closeApp(alice1, alice2); } diff --git a/run/test/specs/linked_device_restore_group.spec.ts b/run/test/specs/linked_device_restore_group.spec.ts index d0ed0344..59028e1d 100644 --- a/run/test/specs/linked_device_restore_group.spec.ts +++ b/run/test/specs/linked_device_restore_group.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { ConversationHeaderName } from './locators/conversation'; @@ -13,9 +15,9 @@ bothPlatformsIt({ testCb: restoreGroup, countOfDevicesNeeded: 4, }); -async function restoreGroup(platform: SupportedPlatformsType) { +async function restoreGroup(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Restore group'; - const { device1, device2, device3, device4 } = await openAppFourDevices(platform); + const { device1, device2, device3, device4 } = await openAppFourDevices(platform, testInfo); const [alice, bob, charlie] = await Promise.all([ newUser(device1, USERNAME.ALICE), newUser(device2, USERNAME.BOB), diff --git a/run/test/specs/linked_device_unsend_message.spec.ts b/run/test/specs/linked_device_unsend_message.spec.ts index 9e6d281e..cf57d807 100644 --- a/run/test/specs/linked_device_unsend_message.spec.ts +++ b/run/test/specs/linked_device_unsend_message.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { DeleteMessageConfirmationModal, DeleteMessageForEveryone } from './locators'; import { DeletedMessage } from './locators/conversation'; import { ConversationItem } from './locators/home'; import { open_Alice2_Bob1_friends } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Unsent message syncs', @@ -13,11 +15,11 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function unSendMessageLinkedDevice(platform: SupportedPlatformsType) { +async function unSendMessageLinkedDevice(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, alice2, bob1 }, prebuilt: { bob }, - } = await open_Alice2_Bob1_friends({ platform, focusFriendsConvo: true }); + } = await open_Alice2_Bob1_friends({ platform, focusFriendsConvo: true, testInfo }); // Send message from user a to user b const sentMessage = await alice1.sendMessage('Howdy'); diff --git a/run/test/specs/linked_group_leave.spec.ts b/run/test/specs/linked_group_leave.spec.ts index c8556a7f..19a38550 100644 --- a/run/test/specs/linked_group_leave.spec.ts +++ b/run/test/specs/linked_group_leave.spec.ts @@ -1,13 +1,15 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { ConversationSettings } from './locators/conversation'; +import { LeaveGroupConfirm, LeaveGroupMenuItem } from './locators/groups'; import { sleepFor } from './utils'; import { newUser } from './utils/create_account'; import { createGroup } from './utils/create_group'; import { linkedDevice } from './utils/link_device'; -import { SupportedPlatformsType, closeApp, openAppFourDevices } from './utils/open_app'; -import { LeaveGroupMenuItem, LeaveGroupConfirm } from './locators/groups'; +import { closeApp, openAppFourDevices, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Leave group linked device', @@ -16,9 +18,9 @@ bothPlatformsIt({ countOfDevicesNeeded: 4, }); -async function leaveGroupLinkedDevice(platform: SupportedPlatformsType) { +async function leaveGroupLinkedDevice(platform: SupportedPlatformsType, testInfo: TestInfo) { const testGroupName = 'Leave group linked device'; - const { device1, device2, device3, device4 } = await openAppFourDevices(platform); + const { device1, device2, device3, device4 } = await openAppFourDevices(platform, testInfo); const charlie = await linkedDevice(device3, device4, USERNAME.CHARLIE); // Create users A, B and C const [alice, bob] = await Promise.all([ diff --git a/run/test/specs/locators/groups.ts b/run/test/specs/locators/groups.ts index 255f61a0..e5123c25 100644 --- a/run/test/specs/locators/groups.ts +++ b/run/test/specs/locators/groups.ts @@ -1,9 +1,10 @@ +import type { UserNameType } from '@session-foundation/qa-seeder'; + import { LocatorsInterface } from '.'; import { englishStrippedStr } from '../../../localizer/englishStrippedStr'; +import { DeviceWrapper } from '../../../types/DeviceWrapper'; import { StrategyExtractionObj } from '../../../types/testing'; -import type { UserNameType } from '@session-foundation/qa-seeder'; import { GROUPNAME } from '../../../types/testing'; -import { DeviceWrapper } from '../../../types/DeviceWrapper'; export class GroupNameInput extends LocatorsInterface { public build(): StrategyExtractionObj { diff --git a/run/test/specs/locators/home.ts b/run/test/specs/locators/home.ts index 0bbd1c49..9ae82c3a 100644 --- a/run/test/specs/locators/home.ts +++ b/run/test/specs/locators/home.ts @@ -1,4 +1,5 @@ import type { DeviceWrapper } from '../../../types/DeviceWrapper'; + import { StrategyExtractionObj } from '../../../types/testing'; import { LocatorsInterface } from './index'; diff --git a/run/test/specs/message_check_performance.spec.ts b/run/test/specs/message_check_performance.spec.ts index bc2886d3..e9a3bd61 100644 --- a/run/test/specs/message_check_performance.spec.ts +++ b/run/test/specs/message_check_performance.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { open_Alice1_Bob1_friends } from './state_builder'; import { SupportedPlatformsType } from './utils/open_app'; @@ -9,12 +11,13 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function checkPerformance(platform: SupportedPlatformsType) { +async function checkPerformance(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const timesArray: Array = []; diff --git a/run/test/specs/message_community_invitation.spec.ts b/run/test/specs/message_community_invitation.spec.ts index 8f6acb6b..6dab93da 100644 --- a/run/test/specs/message_community_invitation.spec.ts +++ b/run/test/specs/message_community_invitation.spec.ts @@ -1,14 +1,16 @@ +import type { TestInfo } from '@playwright/test'; + +import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; -import { InviteContactsMenuItem } from './locators'; -import { sleepFor } from './utils'; -import { joinCommunity } from './utils/join_community'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; import { testCommunityLink, testCommunityName } from './../../constants/community'; +import { InviteContactsMenuItem } from './locators'; import { ConversationSettings } from './locators/conversation'; -import { open_Alice1_Bob1_friends } from './state_builder'; -import { englishStrippedStr } from '../../localizer/englishStrippedStr'; -import { ConversationItem } from './locators/home'; import { GroupMember } from './locators/groups'; +import { ConversationItem } from './locators/home'; +import { open_Alice1_Bob1_friends } from './state_builder'; +import { sleepFor } from './utils'; +import { joinCommunity } from './utils/join_community'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send community invitation', @@ -22,13 +24,14 @@ bothPlatformsItSeparate({ }, }); -async function sendCommunityInvitationIos(platform: SupportedPlatformsType) { +async function sendCommunityInvitationIos(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { bob }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); // Join community on device 1 // Click on plus button @@ -68,13 +71,17 @@ async function sendCommunityInvitationIos(platform: SupportedPlatformsType) { await closeApp(alice1, bob1); } -async function sendCommunityInviteMessageAndroid(platform: SupportedPlatformsType) { +async function sendCommunityInviteMessageAndroid( + platform: SupportedPlatformsType, + testInfo: TestInfo +) { const { devices: { alice1, bob1 }, prebuilt: { bob }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); // Join community await sleepFor(100); diff --git a/run/test/specs/message_deletion.spec.ts b/run/test/specs/message_deletion.spec.ts index f2f3667d..f25df4c0 100644 --- a/run/test/specs/message_deletion.spec.ts +++ b/run/test/specs/message_deletion.spec.ts @@ -1,9 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { DeleteMessageConfirmationModal, DeleteMessageLocally } from './locators'; import { DeletedMessage } from './locators/conversation'; import { open_Alice1_Bob1_friends } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Delete message locally', @@ -11,12 +13,13 @@ bothPlatformsIt({ testCb: deleteMessage, countOfDevicesNeeded: 2, }); -async function deleteMessage(platform: SupportedPlatformsType) { +async function deleteMessage(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); // send message from User A to User B const sentMessage = await alice1.sendMessage('Checking local deletetion functionality'); diff --git a/run/test/specs/message_document.spec.ts b/run/test/specs/message_document.spec.ts index af3b9406..60c7b093 100644 --- a/run/test/specs/message_document.spec.ts +++ b/run/test/specs/message_document.spec.ts @@ -1,6 +1,8 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { open_Alice1_Bob1_friends } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Send document 1:1', @@ -8,13 +10,14 @@ bothPlatformsIt({ testCb: sendDocument, countOfDevicesNeeded: 2, }); -async function sendDocument(platform: SupportedPlatformsType) { +async function sendDocument(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const testMessage = 'Testing-document-1'; const replyMessage = `Replying to document from ${alice.userName}`; diff --git a/run/test/specs/message_gif.spec.ts b/run/test/specs/message_gif.spec.ts index a0dda752..6ede1faf 100644 --- a/run/test/specs/message_gif.spec.ts +++ b/run/test/specs/message_gif.spec.ts @@ -1,7 +1,9 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send GIF 1:1', @@ -15,13 +17,14 @@ bothPlatformsItSeparate({ }, }); -async function sendGifIos(platform: SupportedPlatformsType) { +async function sendGifIos(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const testMessage = 'Testing-GIF-1'; await alice1.sendGIF(testMessage); @@ -41,7 +44,7 @@ async function sendGifIos(platform: SupportedPlatformsType) { await closeApp(alice1, bob1); } -async function sendGifAndroid(platform: SupportedPlatformsType) { +async function sendGifAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { // Test sending a video // open devices and server const { @@ -50,6 +53,7 @@ async function sendGifAndroid(platform: SupportedPlatformsType) { } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const testMessage = 'Test message with GIF'; diff --git a/run/test/specs/message_image.spec.ts b/run/test/specs/message_image.spec.ts index 1db9c8be..89cad18c 100644 --- a/run/test/specs/message_image.spec.ts +++ b/run/test/specs/message_image.spec.ts @@ -1,6 +1,8 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { open_Alice1_Bob1_friends } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Send image 1:1', @@ -9,13 +11,14 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function sendImage(platform: SupportedPlatformsType) { +async function sendImage(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const testMessage = 'Sending image from Alice to Bob'; diff --git a/run/test/specs/message_link_preview.spec.ts b/run/test/specs/message_link_preview.spec.ts index d533c80c..71e54aff 100644 --- a/run/test/specs/message_link_preview.spec.ts +++ b/run/test/specs/message_link_preview.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + +import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { LinkPreview, LinkPreviewMessage } from './locators'; +import { OutgoingMessageStatusSent } from './locators/conversation'; import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; -import { OutgoingMessageStatusSent } from './locators/conversation'; -import { englishStrippedStr } from '../../localizer/englishStrippedStr'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send link 1:1', @@ -18,13 +20,14 @@ bothPlatformsItSeparate({ }, }); -async function sendLinkIos(platform: SupportedPlatformsType) { +async function sendLinkIos(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const testLink = `https://getsession.org/`; @@ -71,12 +74,13 @@ async function sendLinkIos(platform: SupportedPlatformsType) { await closeApp(alice1, bob1); } -async function sendLinkAndroid(platform: SupportedPlatformsType) { +async function sendLinkAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const testLink = `https://getsession.org/`; diff --git a/run/test/specs/message_long_text.spec.ts b/run/test/specs/message_long_text.spec.ts index c91545e1..a86772ba 100644 --- a/run/test/specs/message_long_text.spec.ts +++ b/run/test/specs/message_long_text.spec.ts @@ -1,9 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { longText } from '../../constants'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; +import { ConversationItem } from './locators/home'; import { open_Alice1_Bob1_friends } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; import { sleepFor } from './utils'; -import { ConversationItem } from './locators/home'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send long message 1:1', @@ -17,7 +19,7 @@ bothPlatformsItSeparate({ }, }); -async function sendLongMessageIos(platform: SupportedPlatformsType) { +async function sendLongMessageIos(platform: SupportedPlatformsType, testInfo: TestInfo) { // Sending a long text message // Open device and server const { @@ -26,6 +28,7 @@ async function sendLongMessageIos(platform: SupportedPlatformsType) { } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); // Send a long message from User A to User B await alice1.sendMessage(longText); @@ -40,7 +43,7 @@ async function sendLongMessageIos(platform: SupportedPlatformsType) { await closeApp(alice1, bob1); } -async function sendLongMessageAndroid(platform: SupportedPlatformsType) { +async function sendLongMessageAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { // Sending a long text message // Open device and server const { @@ -49,6 +52,7 @@ async function sendLongMessageAndroid(platform: SupportedPlatformsType) { } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); // Send a long message from User A to User B await alice1.sendMessage(longText); diff --git a/run/test/specs/message_requests_accept.spec.ts b/run/test/specs/message_requests_accept.spec.ts index cd24b4fc..24a75a0e 100644 --- a/run/test/specs/message_requests_accept.spec.ts +++ b/run/test/specs/message_requests_accept.spec.ts @@ -1,9 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { newUser } from './utils/create_account'; import { linkedDevice } from './utils/link_device'; -import { SupportedPlatformsType, closeApp, openAppThreeDevices } from './utils/open_app'; +import { closeApp, openAppThreeDevices, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Accept message request', @@ -12,10 +14,10 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function acceptRequest(platform: SupportedPlatformsType) { +async function acceptRequest(platform: SupportedPlatformsType, testInfo: TestInfo) { // Check 'accept' button // Open app - const { device1, device2, device3 } = await openAppThreeDevices(platform); + const { device1, device2, device3 } = await openAppThreeDevices(platform, testInfo); // Create two users const alice = await newUser(device1, USERNAME.ALICE); const bob = await linkedDevice(device2, device3, USERNAME.BOB); diff --git a/run/test/specs/message_requests_accept_text_reply.spec.ts b/run/test/specs/message_requests_accept_text_reply.spec.ts index da4a0c68..973c6a66 100644 --- a/run/test/specs/message_requests_accept_text_reply.spec.ts +++ b/run/test/specs/message_requests_accept_text_reply.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; @@ -5,7 +7,7 @@ import { MessageInput } from './locators/conversation'; import { PlusButton } from './locators/home'; import { EnterAccountID, NewMessageOption, NextButton } from './locators/start_conversation'; import { newUser } from './utils/create_account'; -import { SupportedPlatformsType, closeApp, openAppTwoDevices } from './utils/open_app'; +import { closeApp, openAppTwoDevices, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Accept message request with text', @@ -14,9 +16,9 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function acceptRequestWithText(platform: SupportedPlatformsType) { +async function acceptRequestWithText(platform: SupportedPlatformsType, testInfo: TestInfo) { // Check accept request by sending text message - const { device1, device2 } = await openAppTwoDevices(platform); + const { device1, device2 } = await openAppTwoDevices(platform, testInfo); // Create two users const [alice, bob] = await Promise.all([ newUser(device1, USERNAME.ALICE), diff --git a/run/test/specs/message_requests_block.spec.ts b/run/test/specs/message_requests_block.spec.ts index edc0e6ae..a04cbe52 100644 --- a/run/test/specs/message_requests_block.spec.ts +++ b/run/test/specs/message_requests_block.spec.ts @@ -1,6 +1,8 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; -import { USERNAME, type AccessibilityId } from '../../types/testing'; +import { type AccessibilityId, USERNAME } from '../../types/testing'; import { BlockedContactsSettings } from './locators'; import { PlusButton } from './locators/home'; import { ConversationsMenuItem, UserSettings } from './locators/settings'; @@ -16,8 +18,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function blockedRequest(platform: SupportedPlatformsType) { - const { device1, device2, device3 } = await openAppThreeDevices(platform); +async function blockedRequest(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device1, device2, device3 } = await openAppThreeDevices(platform, testInfo); const alice = await newUser(device1, USERNAME.ALICE); const bob = await linkedDevice(device2, device3, USERNAME.BOB); diff --git a/run/test/specs/message_requests_clear_all.spec.ts b/run/test/specs/message_requests_clear_all.spec.ts index 7547f481..d36c7eb3 100644 --- a/run/test/specs/message_requests_clear_all.spec.ts +++ b/run/test/specs/message_requests_clear_all.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; -import { USERNAME, type AccessibilityId } from '../../types/testing'; +import { type AccessibilityId, USERNAME } from '../../types/testing'; import { newUser } from './utils/create_account'; -import { SupportedPlatformsType, closeApp, openAppTwoDevices } from './utils/open_app'; +import { closeApp, openAppTwoDevices, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Message requests clear all', @@ -11,8 +13,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function clearAllRequests(platform: SupportedPlatformsType) { - const { device1, device2 } = await openAppTwoDevices(platform); +async function clearAllRequests(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device1, device2 } = await openAppTwoDevices(platform, testInfo); const [alice, bob] = await Promise.all([ newUser(device1, USERNAME.ALICE), newUser(device2, USERNAME.BOB), diff --git a/run/test/specs/message_requests_decline.spec.ts b/run/test/specs/message_requests_decline.spec.ts index 3c7d4a27..9f9f0e24 100644 --- a/run/test/specs/message_requests_decline.spec.ts +++ b/run/test/specs/message_requests_decline.spec.ts @@ -1,12 +1,14 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; -import { USERNAME, type AccessibilityId } from '../../types/testing'; +import { type AccessibilityId, USERNAME } from '../../types/testing'; import { DeclineMessageRequestButton, DeleteMesssageRequestConfirmation } from './locators'; import { PlusButton } from './locators/home'; import { sleepFor } from './utils'; import { newUser } from './utils/create_account'; import { linkedDevice } from './utils/link_device'; -import { SupportedPlatformsType, closeApp, openAppThreeDevices } from './utils/open_app'; +import { closeApp, openAppThreeDevices, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Delete message request in conversation', @@ -15,9 +17,9 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function declineRequest(platform: SupportedPlatformsType) { +async function declineRequest(platform: SupportedPlatformsType, testInfo: TestInfo) { // Check 'decline' button - const { device1, device2, device3 } = await openAppThreeDevices(platform); + const { device1, device2, device3 } = await openAppThreeDevices(platform, testInfo); // Create two users const alice = await newUser(device1, USERNAME.ALICE); const bob = await linkedDevice(device2, device3, USERNAME.BOB); diff --git a/run/test/specs/message_requests_delete.spec.ts b/run/test/specs/message_requests_delete.spec.ts index 17531fbb..bed4511a 100644 --- a/run/test/specs/message_requests_delete.spec.ts +++ b/run/test/specs/message_requests_delete.spec.ts @@ -1,9 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; -import { USERNAME, type AccessibilityId } from '../../types/testing'; +import { type AccessibilityId, USERNAME } from '../../types/testing'; import { DeleteMessageRequestButton, DeleteMesssageRequestConfirmation } from './locators'; import { newUser } from './utils/create_account'; -import { SupportedPlatformsType, closeApp, openAppTwoDevices } from './utils/open_app'; +import { closeApp, openAppTwoDevices, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Delete message request in list', @@ -12,8 +14,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function deleteRequest(platform: SupportedPlatformsType) { - const { device1, device2 } = await openAppTwoDevices(platform); +async function deleteRequest(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device1, device2 } = await openAppTwoDevices(platform, testInfo); const [alice, bob] = await Promise.all([ newUser(device1, USERNAME.ALICE), newUser(device2, USERNAME.BOB), diff --git a/run/test/specs/message_unsend.spec.ts b/run/test/specs/message_unsend.spec.ts index 641a4af4..bd52940d 100644 --- a/run/test/specs/message_unsend.spec.ts +++ b/run/test/specs/message_unsend.spec.ts @@ -1,9 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { DeleteMessageConfirmationModal, DeleteMessageForEveryone } from './locators'; import { DeletedMessage } from './locators/conversation'; import { open_Alice1_Bob1_friends } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Unsend message', @@ -12,12 +14,13 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function unsendMessage(platform: SupportedPlatformsType) { +async function unsendMessage(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const testMessage = 'Checking unsend functionality'; diff --git a/run/test/specs/message_video.spec.ts b/run/test/specs/message_video.spec.ts index f24a8dbc..90920707 100644 --- a/run/test/specs/message_video.spec.ts +++ b/run/test/specs/message_video.spec.ts @@ -1,7 +1,9 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Send video 1:1', @@ -15,7 +17,7 @@ bothPlatformsItSeparate({ }, }); -async function sendVideoIos(platform: SupportedPlatformsType) { +async function sendVideoIos(platform: SupportedPlatformsType, testInfo: TestInfo) { // Test sending a video // open devices const { @@ -24,6 +26,7 @@ async function sendVideoIos(platform: SupportedPlatformsType) { } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const testMessage = 'Testing-video-1'; @@ -49,7 +52,7 @@ async function sendVideoIos(platform: SupportedPlatformsType) { await closeApp(alice1, bob1); } -async function sendVideoAndroid(platform: SupportedPlatformsType) { +async function sendVideoAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { // Test sending a video // open devices const { @@ -58,6 +61,7 @@ async function sendVideoAndroid(platform: SupportedPlatformsType) { } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const replyMessage = `Replying to video from ${alice.userName}`; // Send video diff --git a/run/test/specs/message_voice.spec.ts b/run/test/specs/message_voice.spec.ts index 93e209d0..9e9412a1 100644 --- a/run/test/specs/message_voice.spec.ts +++ b/run/test/specs/message_voice.spec.ts @@ -1,7 +1,9 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Send voice message 1:1', @@ -10,13 +12,14 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function sendVoiceMessage(platform: SupportedPlatformsType) { +async function sendVoiceMessage(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const replyMessage = `Replying to voice message from ${alice.userName}`; // Select voice message button to activate recording state diff --git a/run/test/specs/network_page_link_network.spec.ts b/run/test/specs/network_page_link_network.spec.ts index 1d605c47..1799877d 100644 --- a/run/test/specs/network_page_link_network.spec.ts +++ b/run/test/specs/network_page_link_network.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; @@ -8,8 +10,8 @@ import { SessionNetworkMenuItem, } from './locators/network_page'; import { UserSettings } from './locators/settings'; -import { handleChromeFirstTimeOpen } from './utils/handle_first_open'; import { newUser } from './utils/create_account'; +import { handleChromeFirstTimeOpen } from './utils/handle_first_open'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; import { assertUrlIsReachable, ensureHttpsURL } from './utils/utilities'; @@ -20,8 +22,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -async function networkPageLearnMore(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function networkPageLearnMore(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); const linkURL = 'https://docs.getsession.org/session-network'; await newUser(device, USERNAME.ALICE); await device.clickOnElementAll(new UserSettings(device)); @@ -49,7 +51,7 @@ async function networkPageLearnMore(platform: SupportedPlatformsType) { `The retrieved URL does not match the expected. The retrieved URL is ${fullRetrievedURL}` ); } else { - console.log('The URLs match.'); + device.log('The URLs match.'); } await assertUrlIsReachable(linkURL); // Close browser and app diff --git a/run/test/specs/network_page_link_staking.spec.ts b/run/test/specs/network_page_link_staking.spec.ts index 05386f2a..4d3dfebb 100644 --- a/run/test/specs/network_page_link_staking.spec.ts +++ b/run/test/specs/network_page_link_staking.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; @@ -8,8 +10,8 @@ import { SessionNetworkMenuItem, } from './locators/network_page'; import { UserSettings } from './locators/settings'; -import { handleChromeFirstTimeOpen } from './utils/handle_first_open'; import { newUser } from './utils/create_account'; +import { handleChromeFirstTimeOpen } from './utils/handle_first_open'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; import { assertUrlIsReachable, ensureHttpsURL } from './utils/utilities'; @@ -20,8 +22,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -async function networkPageLearnMore(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function networkPageLearnMore(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); const linkURL = 'https://docs.getsession.org/session-network/staking'; await newUser(device, USERNAME.ALICE); await device.clickOnElementAll(new UserSettings(device)); @@ -50,7 +52,7 @@ async function networkPageLearnMore(platform: SupportedPlatformsType) { `The retrieved URL does not match the expected. The retrieved URL is ${fullRetrievedURL}` ); } else { - console.log('The URLs match.'); + device.log('The URLs match.'); } await assertUrlIsReachable(linkURL); // Close browser and app diff --git a/run/test/specs/network_page_refresh_page.spec.ts b/run/test/specs/network_page_refresh_page.spec.ts index 792aadd0..1d5c6ee4 100644 --- a/run/test/specs/network_page_refresh_page.spec.ts +++ b/run/test/specs/network_page_refresh_page.spec.ts @@ -1,9 +1,11 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { LastUpdatedTimeStamp, SessionNetworkMenuItem } from './locators/network_page'; import { UserSettings } from './locators/settings'; import { newUser } from './utils/create_account'; -import { SupportedPlatformsType, openAppOnPlatformSingleDevice } from './utils/open_app'; +import { openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Refresh network page', @@ -12,8 +14,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -async function refreshNetworkPage(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function refreshNetworkPage(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); const lastUpdatedExpected = 'Last updated 0m ago'; await newUser(device, USERNAME.ALICE); diff --git a/run/test/specs/onboarding_pp.spec.ts b/run/test/specs/onboarding_pp.spec.ts index 4c802acf..ba819281 100644 --- a/run/test/specs/onboarding_pp.spec.ts +++ b/run/test/specs/onboarding_pp.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { SafariAddressBar, URLInputField } from './locators/browsers'; import { PrivacyPolicyButton, SplashScreenLinks } from './locators/onboarding'; @@ -12,8 +14,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -async function onboardingPP(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function onboardingPP(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); 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)); diff --git a/run/test/specs/onboarding_tos.spec.ts b/run/test/specs/onboarding_tos.spec.ts index cb188cca..37ba4601 100644 --- a/run/test/specs/onboarding_tos.spec.ts +++ b/run/test/specs/onboarding_tos.spec.ts @@ -1,8 +1,10 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; -import { TermsOfServiceButton, SplashScreenLinks } from './locators/onboarding'; -import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; +import { SafariAddressBar, URLInputField } from './locators/browsers'; +import { SplashScreenLinks, TermsOfServiceButton } from './locators/onboarding'; import { handleChromeFirstTimeOpen } from './utils/handle_first_open'; -import { URLInputField, SafariAddressBar } from './locators/browsers'; +import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; import { assertUrlIsReachable, ensureHttpsURL } from './utils/utilities'; bothPlatformsIt({ @@ -11,8 +13,8 @@ bothPlatformsIt({ testCb: onboardingTOS, countOfDevicesNeeded: 1, }); -async function onboardingTOS(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function onboardingTOS(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); 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)); diff --git a/run/test/specs/state_builder/index.ts b/run/test/specs/state_builder/index.ts index 1d33553f..5c13a99f 100644 --- a/run/test/specs/state_builder/index.ts +++ b/run/test/specs/state_builder/index.ts @@ -1,13 +1,17 @@ +import type { TestInfo } from '@playwright/test'; + import { buildStateForTest, type PrebuiltStateKey, type StateUser, type WithGroupStateKey, } from '@session-foundation/qa-seeder'; + +import type { DeviceWrapper } from '../../../types/DeviceWrapper'; + +import { ConversationItem } from '../locators/home'; import { openAppMultipleDevices, type SupportedPlatformsType } from '../utils/open_app'; import { restoreAccountNoFallback } from '../utils/restore_account'; -import { ConversationItem } from '../locators/home'; -import type { DeviceWrapper } from '../../../types/DeviceWrapper'; const networkToTarget = 'mainnet'; @@ -81,13 +85,15 @@ async function openAppsWithState m.seedPhrase); await linkDevices(result.devices, seedPhrases); @@ -113,7 +123,6 @@ export async function open_Alice1_Bob1_friends({ const bob = result.prebuilt.users[1]; const alice1 = result.devices[0]; const bob1 = result.devices[1]; - const formattedDevices = { alice1, bob1, @@ -141,9 +150,11 @@ export async function open_Alice1_Bob1_Charlie1_friends_group({ platform, groupName, focusGroupConvo, + testInfo, }: WithPlatform & WithFocusGroupConvo & { groupName: string; + testInfo: TestInfo; }) { const stateToBuildKey = '3friendsInGroup'; const appsToOpen = 3; @@ -152,7 +163,12 @@ export async function open_Alice1_Bob1_Charlie1_friends_group({ appsToOpen, stateToBuildKey, groupName, + testInfo, }); + result.devices[0].setDeviceIdentity('alice1'); + result.devices[1].setDeviceIdentity('bob1'); + result.devices[2].setDeviceIdentity('charlie1'); + const seedPhrases = result.prebuilt.users.map(m => m.seedPhrase); await linkDevices(result.devices, seedPhrases); @@ -197,9 +213,11 @@ export async function open_Alice1_Bob1_Charlie1_Unknown1({ platform, groupName, focusGroupConvo = true, + testInfo, }: WithPlatform & WithFocusGroupConvo & { groupName: string; + testInfo: TestInfo; }) { const stateToBuildKey = '3friendsInGroup'; const appsToOpen = 4; @@ -208,8 +226,12 @@ export async function open_Alice1_Bob1_Charlie1_Unknown1({ appsToOpen, stateToBuildKey, groupName, + testInfo, }); - + result.devices[0].setDeviceIdentity('alice1'); + result.devices[1].setDeviceIdentity('bob1'); + result.devices[2].setDeviceIdentity('charlie1'); + result.devices[3].setDeviceIdentity('unknown1'); // this device will be linked later const seedPhrases = result.prebuilt.users.map(m => m.seedPhrase); await linkDevices(result.devices.slice(0, -1), seedPhrases); @@ -247,7 +269,7 @@ export async function open_Alice1_Bob1_Charlie1_Unknown1({ }; } -export async function open_Alice2({ platform }: WithPlatform) { +export async function open_Alice2({ platform, testInfo }: WithPlatform & { testInfo: TestInfo }) { const prebuiltStateKey = '1user'; const appsToOpen = 2; const result = await openAppsWithState({ @@ -255,7 +277,10 @@ export async function open_Alice2({ platform }: WithPlatform) { appsToOpen, stateToBuildKey: prebuiltStateKey, groupName: undefined, + testInfo, }); + result.devices[0].setDeviceIdentity('alice1'); + result.devices[1].setDeviceIdentity('alice2'); // we want the first user to have the first 2 devices linked const alice = result.prebuilt.users[0]; const alice1 = result.devices[0]; @@ -281,14 +306,20 @@ export async function open_Alice2({ platform }: WithPlatform) { /** * Open 2 devices, one for Alice, one for Bob, but they are not friends */ -export async function open_Alice1_bob1_notfriends({ platform }: WithPlatform) { +export async function open_Alice1_bob1_notfriends({ + platform, + testInfo, +}: WithPlatform & { testInfo: TestInfo }) { const appsToOpen = 2; const result = await openAppsWithState({ platform, appsToOpen, stateToBuildKey: '2users', groupName: undefined, + testInfo, }); + result.devices[0].setDeviceIdentity('alice1'); + result.devices[1].setDeviceIdentity('bob1'); const alice = result.prebuilt.users[0]; const bob = result.prebuilt.users[1]; @@ -315,7 +346,8 @@ export async function open_Alice1_bob1_notfriends({ platform }: WithPlatform) { export async function open_Alice2_Bob1_friends({ platform, focusFriendsConvo, -}: WithPlatform & WithFocusFriendsConvo) { + testInfo, +}: WithPlatform & WithFocusFriendsConvo & { testInfo: TestInfo }) { const prebuiltStateKey = '2friends'; const appsToOpen = 3; const result = await openAppsWithState({ @@ -323,7 +355,11 @@ export async function open_Alice2_Bob1_friends({ appsToOpen, stateToBuildKey: prebuiltStateKey, groupName: undefined, + testInfo, }); + result.devices[0].setDeviceIdentity('alice1'); + result.devices[1].setDeviceIdentity('alice2'); + result.devices[2].setDeviceIdentity('bob1'); const alice = result.prebuilt.users[0]; const bob = result.prebuilt.users[1]; // we want the first user to have the first 2 devices linked diff --git a/run/test/specs/user_actions_block_conversation_list.spec.ts b/run/test/specs/user_actions_block_conversation_list.spec.ts index df362006..8136f4ca 100644 --- a/run/test/specs/user_actions_block_conversation_list.spec.ts +++ b/run/test/specs/user_actions_block_conversation_list.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { androidIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; @@ -5,7 +7,7 @@ import { BlockedContactsSettings, BlockUserConfirmationModal } from './locators' import { LongPressBlockOption } from './locators/home'; import { ConversationsMenuItem, UserSettings } from './locators/settings'; import { open_Alice1_Bob1_friends } from './state_builder'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; // Block option no longer available on iOS in conversation list androidIt({ @@ -15,13 +17,14 @@ androidIt({ countOfDevicesNeeded: 2, }); -async function blockUserInConversationList(platform: SupportedPlatformsType) { +async function blockUserInConversationList(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { bob }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); // Navigate back to conversation list await alice1.navigateBack(); diff --git a/run/test/specs/user_actions_block_conversation_options.spec.ts b/run/test/specs/user_actions_block_conversation_options.spec.ts index da40b025..3b004248 100644 --- a/run/test/specs/user_actions_block_conversation_options.spec.ts +++ b/run/test/specs/user_actions_block_conversation_options.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { @@ -6,7 +8,7 @@ import { BlockUserConfirmationModal, ExitUserProfile, } from './locators'; -import { ConversationSettings, BlockedBanner } from './locators/conversation'; +import { BlockedBanner, ConversationSettings } from './locators/conversation'; import { ConversationsMenuItem, UserSettings } from './locators/settings'; import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils'; @@ -19,13 +21,17 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function blockUserInConversationOptions(platform: SupportedPlatformsType) { +async function blockUserInConversationOptions( + platform: SupportedPlatformsType, + testInfo: TestInfo +) { const { devices: { alice1, bob1 }, prebuilt: { bob }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const blockedMessage = 'Blocked message'; diff --git a/run/test/specs/user_actions_change_profile_picture.spec.ts b/run/test/specs/user_actions_change_profile_picture.spec.ts index 2aa001c6..94e9fbde 100644 --- a/run/test/specs/user_actions_change_profile_picture.spec.ts +++ b/run/test/specs/user_actions_change_profile_picture.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { UserSettings } from './locators/settings'; import { sleepFor } from './utils'; import { parseDataImage } from './utils/check_colour'; import { newUser } from './utils/create_account'; -import { SupportedPlatformsType, closeApp, openAppOnPlatformSingleDevice } from './utils/open_app'; +import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Change profile picture', @@ -18,8 +20,8 @@ bothPlatformsItSeparate({ }, }); -async function changeProfilePictureiOS(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function changeProfilePictureiOS(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); const pixelHexColour = '04cbfe'; // Create new user await newUser(device, USERNAME.ALICE); @@ -30,17 +32,17 @@ async function changeProfilePictureiOS(platform: SupportedPlatformsType) { const el = await device.waitForTextElementToBePresent(new UserSettings(device)); const base64 = await device.getElementScreenshot(el.ELEMENT); const pixelColor = await parseDataImage(base64); - console.log('RGB Value of pixel is:', pixelColor); + device.log('RGB Value of pixel is:', pixelColor); if (pixelColor === pixelHexColour) { - console.log('Colour is correct'); + device.log('Colour is correct'); } else { - console.log("Colour isn't 04cbfe, it is: ", pixelColor); + device.log("Colour isn't 04cbfe, it is: ", pixelColor); } await closeApp(device); } -async function changeProfilePictureAndroid(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function changeProfilePictureAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); let expectedPixelHexColour: string; if (platform === 'android') { expectedPixelHexColour = 'cbfeff'; @@ -58,9 +60,9 @@ async function changeProfilePictureAndroid(platform: SupportedPlatformsType) { await sleepFor(10000); const base64 = await device.getElementScreenshot(el.ELEMENT); const actualPixelColor = await parseDataImage(base64); - console.log('Hex value of pixel is:', actualPixelColor); + device.log('Hex value of pixel is:', actualPixelColor); if (actualPixelColor === expectedPixelHexColour) { - console.log('Colour is correct'); + device.log('Colour is correct'); } else { throw new Error(`Colour isn't ${expectedPixelHexColour}, it is: ` + actualPixelColor); } diff --git a/run/test/specs/user_actions_change_username.spec.ts b/run/test/specs/user_actions_change_username.spec.ts index baa6d9c6..006316fc 100644 --- a/run/test/specs/user_actions_change_username.spec.ts +++ b/run/test/specs/user_actions_change_username.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; @@ -5,7 +7,7 @@ import { TickButton, UsernameInput, UsernameSettings } from './locators'; import { SaveNameChangeButton, UserSettings } from './locators/settings'; import { sleepFor } from './utils'; import { newUser } from './utils/create_account'; -import { SupportedPlatformsType, closeApp, openAppOnPlatformSingleDevice } from './utils/open_app'; +import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Change username', @@ -19,8 +21,8 @@ bothPlatformsItSeparate({ }, }); -async function changeUsernameiOS(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function changeUsernameiOS(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); const alice = await newUser(device, USERNAME.ALICE); const newUsername = 'Alice in chains'; // click on settings/profile avatar @@ -42,9 +44,9 @@ async function changeUsernameiOS(platform: SupportedPlatformsType) { selector: 'Username', }); const changedUsername = await device.getTextFromElement(username); - console.log('Changed username', changedUsername); + device.log('Changed username', changedUsername); if (changedUsername === newUsername) { - console.log('Username change successful'); + device.log('Username change successful'); } if (changedUsername === alice.userName) { throw new Error('Username change unsuccessful'); @@ -53,8 +55,8 @@ async function changeUsernameiOS(platform: SupportedPlatformsType) { await closeApp(device); } -async function changeUsernameAndroid(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function changeUsernameAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); const alice = await newUser(device, USERNAME.ALICE); const newUsername = 'Alice in chains'; // click on settings/profile avatar @@ -72,9 +74,9 @@ async function changeUsernameAndroid(platform: SupportedPlatformsType) { text: newUsername, }); const changedUsername = await device.getTextFromElement(username); - console.log('Changed username', changedUsername); + device.log('Changed username', changedUsername); if (changedUsername === newUsername) { - console.log('Username change successful'); + device.log('Username change successful'); } if (changedUsername === alice.userName) { throw new Error('Username change unsuccessful'); diff --git a/run/test/specs/user_actions_create_contact.spec.ts b/run/test/specs/user_actions_create_contact.spec.ts index 8baba1af..3dfebc59 100644 --- a/run/test/specs/user_actions_create_contact.spec.ts +++ b/run/test/specs/user_actions_create_contact.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { newUser } from './utils/create_account'; import { retryMsgSentForBanner } from './utils/create_contact'; import { linkedDevice } from './utils/link_device'; -import { SupportedPlatformsType, closeApp, openAppThreeDevices } from './utils/open_app'; +import { closeApp, openAppThreeDevices, SupportedPlatformsType } from './utils/open_app'; import { runOnlyOnIOS } from './utils/run_on'; import { sleepFor } from './utils/sleep_for'; @@ -15,8 +17,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function createContact(platform: SupportedPlatformsType) { - const { device1, device2, device3 } = await openAppThreeDevices(platform); +async function createContact(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device1, device2, device3 } = await openAppThreeDevices(platform, testInfo); const Alice = await linkedDevice(device1, device3, USERNAME.ALICE); const Bob = await newUser(device2, USERNAME.BOB); diff --git a/run/test/specs/user_actions_create_user.spec.ts b/run/test/specs/user_actions_create_user.spec.ts index 4d1c91c2..24e119dd 100644 --- a/run/test/specs/user_actions_create_user.spec.ts +++ b/run/test/specs/user_actions_create_user.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { newUser } from './utils/create_account'; @@ -10,8 +12,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 1, }); -async function createUser(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function createUser(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); await newUser(device, USERNAME.ALICE); // Should verify session ID and recovery phrase are what was originally created await closeApp(device); diff --git a/run/test/specs/user_actions_delete_conversation.spec.ts b/run/test/specs/user_actions_delete_conversation.spec.ts index 683caf57..bd38c7a7 100644 --- a/run/test/specs/user_actions_delete_conversation.spec.ts +++ b/run/test/specs/user_actions_delete_conversation.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; @@ -12,11 +14,11 @@ bothPlatformsIt({ countOfDevicesNeeded: 3, }); -async function deleteConversation(platform: SupportedPlatformsType) { +async function deleteConversation(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, alice2 }, prebuilt: { bob }, - } = await open_Alice2_Bob1_friends({ platform, focusFriendsConvo: false }); + } = await open_Alice2_Bob1_friends({ platform, focusFriendsConvo: false, testInfo }); // Check contact has loaded on linked device // await alice1.navigateBack(); diff --git a/run/test/specs/user_actions_hide_note_to_self.spec.ts b/run/test/specs/user_actions_hide_note_to_self.spec.ts index f6ba9c68..b08939e2 100644 --- a/run/test/specs/user_actions_hide_note_to_self.spec.ts +++ b/run/test/specs/user_actions_hide_note_to_self.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; @@ -21,9 +23,9 @@ bothPlatformsItSeparate({ }, }); -async function hideNoteToSelf(platform: SupportedPlatformsType) { +async function hideNoteToSelf(platform: SupportedPlatformsType, testInfo: TestInfo) { const noteToSelf = englishStrippedStr('noteToSelf').toString(); - const { device } = await openAppOnPlatformSingleDevice(platform); + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); await newUser(device, USERNAME.ALICE); await device.clickOnElementAll(new SearchButton(device)); await device.clickOnElementAll(new NoteToSelfOption(device)); diff --git a/run/test/specs/user_actions_hide_recovery_password.spec.ts b/run/test/specs/user_actions_hide_recovery_password.spec.ts index fc5731c1..3a8ac103 100644 --- a/run/test/specs/user_actions_hide_recovery_password.spec.ts +++ b/run/test/specs/user_actions_hide_recovery_password.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; @@ -18,8 +20,8 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function hideRecoveryPassword(platform: SupportedPlatformsType) { - const { device1, device2 } = await openAppTwoDevices(platform); +async function hideRecoveryPassword(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device1, device2 } = await openAppTwoDevices(platform, testInfo); await linkedDevice(device1, device2, USERNAME.ALICE); await device1.clickOnElementAll(new UserSettings(device1)); await device1.scrollDown(); diff --git a/run/test/specs/user_actions_read_status.spec.ts b/run/test/specs/user_actions_read_status.spec.ts index 63895a3f..c08062e6 100644 --- a/run/test/specs/user_actions_read_status.spec.ts +++ b/run/test/specs/user_actions_read_status.spec.ts @@ -1,7 +1,9 @@ +import type { TestInfo } from '@playwright/test'; + import { bothPlatformsIt } from '../../types/sessionIt'; import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils/index'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsIt({ title: 'Read status', @@ -10,13 +12,14 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function readStatus(platform: SupportedPlatformsType) { +async function readStatus(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice, bob }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const testMessage = 'Testing read status'; // Go to settings to turn on read status diff --git a/run/test/specs/user_actions_set_nickname.spec.ts b/run/test/specs/user_actions_set_nickname.spec.ts index 0c2e7a52..3a517527 100644 --- a/run/test/specs/user_actions_set_nickname.spec.ts +++ b/run/test/specs/user_actions_set_nickname.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; @@ -6,7 +8,7 @@ import { ConversationHeaderName, ConversationSettings } from './locators/convers import { SaveNameChangeButton } from './locators/settings'; import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; bothPlatformsItSeparate({ title: 'Set nickname', @@ -20,13 +22,14 @@ bothPlatformsItSeparate({ }, }); -async function setNicknameIos(platform: SupportedPlatformsType) { +async function setNicknameIos(platform: SupportedPlatformsType, testInfo: TestInfo) { const nickName = 'New nickname'; const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); // Click on settings/more info await alice1.clickOnElementAll(new ConversationSettings(alice1)); @@ -61,13 +64,14 @@ async function setNicknameIos(platform: SupportedPlatformsType) { await closeApp(alice1, bob1); } -async function setNicknameAndroid(platform: SupportedPlatformsType) { +async function setNicknameAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { bob }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const nickName = 'New nickname'; // Go back to conversation list diff --git a/run/test/specs/user_actions_share_to_session.spec.ts b/run/test/specs/user_actions_share_to_session.spec.ts index 68fcc40a..c1f1b290 100644 --- a/run/test/specs/user_actions_share_to_session.spec.ts +++ b/run/test/specs/user_actions_share_to_session.spec.ts @@ -1,12 +1,14 @@ +import type { TestInfo } from '@playwright/test'; + +import { testImage } from '../../constants/testfiles'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; import { ImageName, MediaMessageInput, SendMediaButton, ShareExtensionIcon } from './locators'; import { PhotoLibrary } from './locators/external'; import { open_Alice1_Bob1_friends } from './state_builder'; import { sleepFor } from './utils'; -import { SupportedPlatformsType } from './utils/open_app'; -import { testImage } from '../../constants/testfiles'; import { handlePhotosFirstTimeOpen } from './utils/handle_first_open'; +import { SupportedPlatformsType } from './utils/open_app'; // TODO investigate why the Android Photos app throws an unexpected error when sharing bothPlatformsItSeparate({ @@ -22,12 +24,13 @@ bothPlatformsItSeparate({ countOfDevicesNeeded: 2, }); -async function shareToSession(platform: SupportedPlatformsType) { +async function shareToSession(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const testMessage = 'Testing sharing an image through photo gallery to Session'; diff --git a/run/test/specs/user_actions_unblock_user.spec.ts b/run/test/specs/user_actions_unblock_user.spec.ts index a03902f5..61b6853a 100644 --- a/run/test/specs/user_actions_unblock_user.spec.ts +++ b/run/test/specs/user_actions_unblock_user.spec.ts @@ -1,3 +1,5 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsIt } from '../../types/sessionIt'; import { BlockUser, BlockUserConfirmationModal } from './locators'; @@ -12,13 +14,14 @@ bothPlatformsIt({ countOfDevicesNeeded: 2, }); -async function unblockUser(platform: SupportedPlatformsType) { +async function unblockUser(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice, bob }, } = await open_Alice1_Bob1_friends({ platform, focusFriendsConvo: true, + testInfo, }); const blockedMessage = `Blocked message from ${bob.userName} to ${alice.userName}`; await alice1.clickOnElementAll(new ConversationSettings(alice1)); @@ -35,9 +38,9 @@ async function unblockUser(platform: SupportedPlatformsType) { maxWait: 5000, }); if (blockedStatus) { - console.info(`${bob.userName} has been blocked`); + alice1.info(`${bob.userName} has been blocked`); } else { - console.info('Blocked banner not found'); + alice1.info('Blocked banner not found'); } // Send message from Blocked User await bob1.sendMessage(blockedMessage); diff --git a/run/test/specs/utils/allure/allureHelpers.ts b/run/test/specs/utils/allure/allureHelpers.ts index 84e7a9b7..ef63979b 100644 --- a/run/test/specs/utils/allure/allureHelpers.ts +++ b/run/test/specs/utils/allure/allureHelpers.ts @@ -1,9 +1,10 @@ +import { execSync } from 'child_process'; import fs from 'fs-extra'; import path from 'path'; -import { execSync } from 'child_process'; + import { - allureResultsDir, allureCurrentReportDir, + allureResultsDir, GH_PAGES_BASE_URL, } from '../../../../constants/allure'; import { SupportedPlatformsType } from '../open_app'; diff --git a/run/test/specs/utils/allure/closeRun.ts b/run/test/specs/utils/allure/closeRun.ts index dba572aa..8052c0cf 100644 --- a/run/test/specs/utils/allure/closeRun.ts +++ b/run/test/specs/utils/allure/closeRun.ts @@ -1,5 +1,6 @@ -import fs from 'fs-extra'; import { exec } from 'child_process'; +import fs from 'fs-extra'; + import { allureCurrentReportDir, allureResultsDir } from '../../../../constants/allure'; import { getReportContextFromEnv, diff --git a/run/test/specs/utils/allure/publishReport.ts b/run/test/specs/utils/allure/publishReport.ts index 5b82f367..99d966ab 100644 --- a/run/test/specs/utils/allure/publishReport.ts +++ b/run/test/specs/utils/allure/publishReport.ts @@ -1,7 +1,8 @@ import fs from 'fs-extra'; +import ghpages from 'gh-pages'; import path from 'path'; + import { allureCurrentReportDir } from '../../../../constants/allure'; -import ghpages from 'gh-pages'; import { getReportContextFromEnv, patchStylesCss, writeMetadataJson } from './allureHelpers'; // Bail out early if not on CI diff --git a/run/test/specs/utils/capabilities_android.ts b/run/test/specs/utils/capabilities_android.ts index 588bf0d4..504383ce 100644 --- a/run/test/specs/utils/capabilities_android.ts +++ b/run/test/specs/utils/capabilities_android.ts @@ -5,8 +5,9 @@ import { } from '@wdio/types/build/Capabilities'; import dotenv from 'dotenv'; import { isString } from 'lodash'; -import { CapabilitiesIndexType } from './capabilities_ios'; + import { getAndroidApk } from './binaries'; +import { CapabilitiesIndexType } from './capabilities_ios'; dotenv.config(); // Access the environment variable diff --git a/run/test/specs/utils/capabilities_ios.ts b/run/test/specs/utils/capabilities_ios.ts index f35b740d..5d835f95 100644 --- a/run/test/specs/utils/capabilities_ios.ts +++ b/run/test/specs/utils/capabilities_ios.ts @@ -1,6 +1,7 @@ import { AppiumXCUITestCapabilities } from '@wdio/types/build/Capabilities'; import { W3CCapabilities } from '@wdio/types/build/Capabilities'; import dotenv from 'dotenv'; + import { IntRange } from '../../../types/RangeType'; dotenv.config(); const iosPathPrefix = process.env.IOS_APP_PATH_PREFIX; diff --git a/run/test/specs/utils/check_colour.ts b/run/test/specs/utils/check_colour.ts index 6609608d..77d1c722 100644 --- a/run/test/specs/utils/check_colour.ts +++ b/run/test/specs/utils/check_colour.ts @@ -1,5 +1,6 @@ -import PNG from 'png-js'; import { colors } from 'looks-same'; +import PNG from 'png-js'; + import { hexToRgbObject } from './utilities'; export async function parseDataImage(base64: string) { @@ -20,9 +21,7 @@ export async function parseDataImage(base64: string) { }); const middlePx = px.buffer.slice(pxDataStart, pxDataEnd); - // console.info("middlePx RGB: ", Buffer.from(middlePx).toString("hex")); const pixelColor = Buffer.from(middlePx).toString('hex'); - // console.info("Middle x:", middleX, "middleY:", middleY, "width:", width); return pixelColor; } diff --git a/run/test/specs/utils/click_by_coordinates.ts b/run/test/specs/utils/click_by_coordinates.ts index 8074d914..bbe2b94a 100644 --- a/run/test/specs/utils/click_by_coordinates.ts +++ b/run/test/specs/utils/click_by_coordinates.ts @@ -6,5 +6,5 @@ export const clickOnCoordinates = async (device: DeviceWrapper, coordinates: Coo const { x, y } = coordinates; await sleepFor(1000); await device.pressCoordinates(x, y); - console.log(`Tapped coordinates ${x}, ${y}`); + device.log(`Tapped coordinates ${x}, ${y}`); }; diff --git a/run/test/specs/utils/copy_file_to_simulator.ts b/run/test/specs/utils/copy_file_to_simulator.ts index a49b0153..8d2eb80a 100644 --- a/run/test/specs/utils/copy_file_to_simulator.ts +++ b/run/test/specs/utils/copy_file_to_simulator.ts @@ -1,6 +1,7 @@ +import { execSync } from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; -import { execSync } from 'child_process'; + import { DeviceWrapper } from '../../../types/DeviceWrapper'; const TARGET_GROUP_ID = 'group.com.apple.FileProvider.LocalStorage'; @@ -52,7 +53,7 @@ export function copyFileToSimulator(device: DeviceWrapper, fileName: string): vo ); if (fs.existsSync(destinationPath)) { - console.log(`File already exists in simulator: ${destinationPath}`); + device.log(`File already exists in simulator: ${destinationPath}`); return; } if (!fs.existsSync(sourcePath)) { @@ -60,5 +61,5 @@ export function copyFileToSimulator(device: DeviceWrapper, fileName: string): vo } fs.mkdirSync(downloadsPath, { recursive: true }); fs.copyFileSync(sourcePath, destinationPath); - console.log(`Copied ${fileName} to simulator Downloads at: ${downloadsPath}`); + device.log(`Copied ${fileName} to simulator Downloads at: ${downloadsPath}`); } diff --git a/run/test/specs/utils/create_account.ts b/run/test/specs/utils/create_account.ts index 15fa9c1e..8d4536a7 100644 --- a/run/test/specs/utils/create_account.ts +++ b/run/test/specs/utils/create_account.ts @@ -1,14 +1,16 @@ import type { UserNameType } from '@session-foundation/qa-seeder'; + import { sleepFor } from '.'; import { DeviceWrapper } from '../../../types/DeviceWrapper'; import { User } from '../../../types/testing'; -import { RecoveryPhraseContainer, RevealRecoveryPhraseButton } from '../locators/settings'; +import { ContinueButton } from '../locators/global'; import { CreateAccountButton, DisplayNameInput, SlowModeRadio } from '../locators/onboarding'; +import { RecoveryPhraseContainer, RevealRecoveryPhraseButton } from '../locators/settings'; import { UserSettings } from '../locators/settings'; -import { ContinueButton } from '../locators/global'; import { CopyButton } from '../locators/start_conversation'; export const newUser = async (device: DeviceWrapper, userName: UserNameType): Promise => { + device.setDeviceIdentity(`${userName.toLowerCase()}1`); // Click create session ID await device.clickOnElementAll(new CreateAccountButton(device)); // Input username @@ -21,10 +23,10 @@ export const newUser = async (device: DeviceWrapper, userName: UserNameType): Pr // Select Continue to save notification settings await device.clickOnElementAll(new ContinueButton(device)); // TODO need to retry check every 1s for 5s - console.warn('about to look for Allow permission in 5s'); + device.warn('about to look for Allow permission in 5s'); await sleepFor(5000); await device.checkPermissions('Allow'); - console.warn('looked for Allow permission'); + device.warn('looked for Allow permission'); await sleepFor(1000); // Click on 'continue' button to open recovery phrase modal await device.waitForTextElementToBePresent(new RevealRecoveryPhraseButton(device)); @@ -36,7 +38,7 @@ export const newUser = async (device: DeviceWrapper, userName: UserNameType): Pr await device.onAndroid().clickOnElementAll(new CopyButton(device)); // Save recovery phrase as variable const recoveryPhrase = await device.getTextFromElement(recoveryPhraseContainer); - console.log(`${userName}s recovery phrase is "${recoveryPhrase}"`); + device.log(`${userName}s recovery phrase is "${recoveryPhrase}"`); // Exit Modal await device.navigateBack(false); await device.clickOnElementAll(new UserSettings(device)); diff --git a/run/test/specs/utils/create_contact.ts b/run/test/specs/utils/create_contact.ts index 4eadd23a..0a24f972 100644 --- a/run/test/specs/utils/create_contact.ts +++ b/run/test/specs/utils/create_contact.ts @@ -55,11 +55,11 @@ export const retryMsgSentForBanner = async ( messageRequest = element !== null; if (!messageRequest) { - console.log(`Retrying message request`); + device1.log(`Retrying message request`); await device1.sendMessage('Retry'); await sleepFor(5000); } else { - console.log('Found message request: No need for retry'); + device2.log('Found message request: No need for retry'); } } diff --git a/run/test/specs/utils/disappearing_control_messages.ts b/run/test/specs/utils/disappearing_control_messages.ts index 9e6405ce..d28c75e4 100644 --- a/run/test/specs/utils/disappearing_control_messages.ts +++ b/run/test/specs/utils/disappearing_control_messages.ts @@ -1,8 +1,9 @@ import type { UserNameType } from '@session-foundation/qa-seeder'; + +import { englishStrippedStr } from '../../../localizer/englishStrippedStr'; import { DeviceWrapper } from '../../../types/DeviceWrapper'; import { DisappearActions, DISAPPEARING_TIMES } from '../../../types/testing'; import { SupportedPlatformsType } from './open_app'; -import { englishStrippedStr } from '../../../localizer/englishStrippedStr'; export const checkDisappearingControlMessage = async ( platform: SupportedPlatformsType, diff --git a/run/test/specs/utils/handle_first_open.ts b/run/test/specs/utils/handle_first_open.ts index 72cdbdd3..d3fe8199 100644 --- a/run/test/specs/utils/handle_first_open.ts +++ b/run/test/specs/utils/handle_first_open.ts @@ -8,9 +8,9 @@ export async function handleChromeFirstTimeOpen(device: DeviceWrapper) { new ChromeUseWithoutAnAccount(device) ); if (!chromeUseWithoutAnAccount) { - console.log('Chrome opened without an account check, proceeding'); + device.log('Chrome opened without an account check, proceeding'); } else { - console.log( + device.log( 'Chrome has been opened for the first time, dismissing account use and notifications' ); await device.clickOnElementAll(new ChromeUseWithoutAnAccount(device)); @@ -22,9 +22,9 @@ export async function handleChromeFirstTimeOpen(device: DeviceWrapper) { export async function handlePhotosFirstTimeOpen(device: DeviceWrapper) { const continueButton = await device.doesElementExist(new iOSPhotosContinuebutton(device)); if (!continueButton) { - console.log(`Photos app opened without a "What's New" screen, proceeding`); + device.log(`Photos app opened without a "What's New" screen, proceeding`); } else { - console.log(`Photos app has been opened for the first time, dismissing modals`); + device.log(`Photos app has been opened for the first time, dismissing modals`); await device.clickOnElementAll(new iOSPhotosContinuebutton(device)); await device.clickOnByAccessibilityID('Don’t Allow'); } diff --git a/run/test/specs/utils/index.ts b/run/test/specs/utils/index.ts index 8d45bcb6..cbc92334 100644 --- a/run/test/specs/utils/index.ts +++ b/run/test/specs/utils/index.ts @@ -1,8 +1,7 @@ -import { sleepFor } from './sleep_for'; -import { saveSessionIdIos, getAccountId } from './get_account_id'; -import { runOnlyOnIOS, runOnlyOnAndroid } from './run_on'; - import { clickOnCoordinates } from './click_by_coordinates'; +import { getAccountId, saveSessionIdIos } from './get_account_id'; +import { runOnlyOnAndroid, runOnlyOnIOS } from './run_on'; +import { sleepFor } from './sleep_for'; export { sleepFor, diff --git a/run/test/specs/utils/link_device.ts b/run/test/specs/utils/link_device.ts index f3dbf232..b269988d 100644 --- a/run/test/specs/utils/link_device.ts +++ b/run/test/specs/utils/link_device.ts @@ -1,15 +1,16 @@ +import type { UserNameType } from '@session-foundation/qa-seeder'; + import { sleepFor } from '.'; -import { newUser } from './create_account'; +import { DeviceWrapper } from '../../../types/DeviceWrapper'; +import { ContinueButton } from '../locators/global'; +import { PlusButton } from '../locators/home'; import { AccountRestoreButton, DisplayNameInput, SeedPhraseInput, SlowModeRadio, } from '../locators/onboarding'; -import { DeviceWrapper } from '../../../types/DeviceWrapper'; -import type { UserNameType } from '@session-foundation/qa-seeder'; -import { ContinueButton } from '../locators/global'; -import { PlusButton } from '../locators/home'; +import { newUser } from './create_account'; export const linkedDevice = async ( device1: DeviceWrapper, @@ -18,6 +19,7 @@ export const linkedDevice = async ( ) => { const user = await newUser(device1, userName); // Log in with recovery seed on device 2 + device2.setDeviceIdentity(`${userName.toLowerCase()}2`); await device2.clickOnElementAll(new AccountRestoreButton(device2)); // Enter recovery phrase into input box @@ -40,7 +42,7 @@ export const linkedDevice = async ( await device2.inputText(userName, new DisplayNameInput(device2)); await device2.clickOnElementAll(new ContinueButton(device2)); } else { - console.info('Display name found: Loading account'); + device2.info('Display name found: Loading account'); } // Wait for permissions modal to pop up await sleepFor(500); @@ -48,7 +50,7 @@ export const linkedDevice = async ( // Check that button was clicked await device2.waitForTextElementToBePresent(new PlusButton(device2)); - console.info('Device 2 linked'); + device2.info('Device linked'); return user; }; diff --git a/run/test/specs/utils/logger.ts b/run/test/specs/utils/logger.ts deleted file mode 100644 index 03a094f5..00000000 --- a/run/test/specs/utils/logger.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { forEach } from 'lodash'; - -// {test1: ["line1", "line2", ], test2: ["line1"]} -const buffer: Record> = {}; - -export function pushToBuffer(testName: string, strToPush: string) { - if (!buffer[testName]) { - buffer[testName] = []; - } - buffer[testName].push(strToPush); -} - -export function clearBufferOfTest(testName: string) { - delete buffer[testName]; -} - -export function printBufferAndClear(testName: string) { - if (buffer[testName]) { - forEach(buffer[testName], line => console.log(line)); - } - - clearBufferOfTest(testName); -} diff --git a/run/test/specs/utils/open_app.ts b/run/test/specs/utils/open_app.ts index 3fabfbdd..31646a5a 100644 --- a/run/test/specs/utils/open_app.ts +++ b/run/test/specs/utils/open_app.ts @@ -1,15 +1,11 @@ -import { getAndroidCapabilities, getAndroidUdid } from './capabilities_android'; -import { CapabilitiesIndexType, capabilityIsValid, getIosCapabilities } from './capabilities_ios'; -import { isCI, runScriptAndLog } from './utilities'; +import type { TestInfo } from '@playwright/test'; -import { XCUITestDriverOpts } from 'appium-xcuitest-driver/build/lib/driver'; import AndroidUiautomator2Driver from 'appium-uiautomator2-driver'; - +import { XCUITestDriverOpts } from 'appium-xcuitest-driver/build/lib/driver'; import { DriverOpts } from 'appium/build/lib/appium'; import { compact } from 'lodash'; + import { DeviceWrapper } from '../../../types/DeviceWrapper'; -import { cleanPermissions } from './permissions'; -import { sleepFor } from './sleep_for'; import { getAdbFullPath, getAndroidSystemImageToUse, @@ -17,6 +13,12 @@ import { getEmulatorFullPath, getSdkManagerFullPath, } from './binaries'; +import { getAndroidCapabilities, getAndroidUdid } from './capabilities_android'; +import { CapabilitiesIndexType, capabilityIsValid, getIosCapabilities } from './capabilities_ios'; +import { cleanPermissions } from './permissions'; +import { registerDevicesForTest } from './screenshot_helper'; +import { sleepFor } from './sleep_for'; +import { isCI, runScriptAndLog } from './utilities'; const APPIUM_PORT = 4728; @@ -28,7 +30,8 @@ export type SupportedPlatformsType = 'android' | 'ios'; export const openAppMultipleDevices = async ( platform: SupportedPlatformsType, - numberOfDevices: number + numberOfDevices: number, + testInfo: TestInfo ): Promise => { // Create an array of promises for each device const devicePromises = Array.from({ length: numberOfDevices }, (_, index) => @@ -39,7 +42,11 @@ export const openAppMultipleDevices = async ( const apps = await Promise.all(devicePromises); // Map the result to return only the device objects - return apps.map(app => app.device); + const devices = apps.map(app => app.device); + + registerDevicesForTest(testInfo, devices, platform); + + return devices; }; const openAppOnPlatform = async ( @@ -53,15 +60,21 @@ const openAppOnPlatform = async ( }; export const openAppOnPlatformSingleDevice = async ( - platform: SupportedPlatformsType + platform: SupportedPlatformsType, + testInfo: TestInfo ): Promise<{ device: DeviceWrapper; }> => { - return openAppOnPlatform(platform, 0); + const result = await openAppOnPlatform(platform, 0); + + registerDevicesForTest(testInfo, [result.device], platform); + + return result; }; export const openAppTwoDevices = async ( - platform: SupportedPlatformsType + platform: SupportedPlatformsType, + testInfo: TestInfo ): Promise<{ device1: DeviceWrapper; device2: DeviceWrapper; @@ -71,11 +84,16 @@ export const openAppTwoDevices = async ( openAppOnPlatform(platform, 1), ]); - return { device1: app1.device, device2: app2.device }; + const result = { device1: app1.device, device2: app2.device }; + + registerDevicesForTest(testInfo, Object.values(result), platform); + + return result; }; export const openAppThreeDevices = async ( - platform: SupportedPlatformsType + platform: SupportedPlatformsType, + testInfo: TestInfo ): Promise<{ device1: DeviceWrapper; device2: DeviceWrapper; @@ -87,15 +105,20 @@ export const openAppThreeDevices = async ( openAppOnPlatform(platform, 2), ]); - return { + const result = { device1: app1.device, device2: app2.device, device3: app3.device, }; + + registerDevicesForTest(testInfo, Object.values(result), platform); + + return result; }; export const openAppFourDevices = async ( - platform: SupportedPlatformsType + platform: SupportedPlatformsType, + testInfo: TestInfo ): Promise<{ device1: DeviceWrapper; device2: DeviceWrapper; @@ -109,12 +132,16 @@ export const openAppFourDevices = async ( openAppOnPlatform(platform, 3), ]); - return { + const result = { device1: app1.device, device2: app2.device, device3: app3.device, device4: app4.device, }; + + registerDevicesForTest(testInfo, Object.values(result), platform); + + return result; }; async function createAndroidEmulator(emulatorName: string) { diff --git a/run/test/specs/utils/permissions.ts b/run/test/specs/utils/permissions.ts index 2aeca25a..8f70cada 100644 --- a/run/test/specs/utils/permissions.ts +++ b/run/test/specs/utils/permissions.ts @@ -1,5 +1,6 @@ import { W3CCapabilities } from '@wdio/types/build/Capabilities'; import { XCUITestDriver, XCUITestDriverOpts } from 'appium-xcuitest-driver/build/lib/driver'; + import { DeviceWrapper } from '../../../types/DeviceWrapper'; import { runScriptAndLog } from './utilities'; diff --git a/run/test/specs/utils/restore_account.ts b/run/test/specs/utils/restore_account.ts index 48401eb2..a8f3ffc4 100644 --- a/run/test/specs/utils/restore_account.ts +++ b/run/test/specs/utils/restore_account.ts @@ -1,10 +1,11 @@ +import test from '@playwright/test'; + import { sleepFor } from '.'; import { DeviceWrapper } from '../../../types/DeviceWrapper'; import { User } from '../../../types/testing'; -import { AccountRestoreButton, SeedPhraseInput, SlowModeRadio } from '../locators/onboarding'; import { ContinueButton } from '../../specs/locators/global'; import { PlusButton } from '../locators/home'; -import test from '@playwright/test'; +import { AccountRestoreButton, SeedPhraseInput, SlowModeRadio } from '../locators/onboarding'; export const restoreAccount = async (device: DeviceWrapper, user: User) => { await device.clickOnElementAll(new AccountRestoreButton(device)); @@ -31,7 +32,7 @@ export const restoreAccount = async (device: DeviceWrapper, user: User) => { }); await device.clickOnElementAll(new ContinueButton(device)); } else { - console.info('Display name found: Loading account'); + device.info('Display name found: Loading account'); } // Wait for permissions modal to pop up await sleepFor(500); @@ -71,7 +72,7 @@ export const restoreAccountNoFallback = async (device: DeviceWrapper, recoveryPh if (displayName) { throw new Error('Account not found'); } - console.info('Display name found: Loading account'); + device.info('Display name found: Loading account'); // Wait for permissions modal to pop up await sleepFor(500); diff --git a/run/test/specs/utils/screenshot_helper.ts b/run/test/specs/utils/screenshot_helper.ts new file mode 100644 index 00000000..a9c057ae --- /dev/null +++ b/run/test/specs/utils/screenshot_helper.ts @@ -0,0 +1,211 @@ +import type { TestInfo } from '@playwright/test'; + +import * as fs from 'fs'; +import * as path from 'path'; +import sharp from 'sharp'; + +import { DeviceWrapper } from '../../../types/DeviceWrapper'; +import { SupportedPlatformsType } from './open_app'; + +// Screenshot context type +type ScreenshotContext = { + devices: DeviceWrapper[]; + testInfo: TestInfo; + platform: SupportedPlatformsType; +}; + +// Global registry to track devices for screenshot capture +const deviceRegistry = new Map(); + +// Register devices for a test +export function registerDevicesForTest( + testInfo: TestInfo, + devices: DeviceWrapper[], + platform: SupportedPlatformsType +) { + const testId = `${testInfo.testId}-${testInfo.parallelIndex}-${testInfo.repeatEachIndex}`; + // Throw if deviceRegistry already has an entry for this test + // Could indicate that previous test did not unregister properly + if (deviceRegistry.has(testId)) { + throw new Error(`Device registry already contains entry for test "${testInfo.title}"`); + } + + deviceRegistry.set(testId, { devices, testInfo, platform }); +} + +// Unregister devices after test +export function unregisterDevicesForTest(testInfo: TestInfo) { + const testId = `${testInfo.testId}-${testInfo.parallelIndex}-${testInfo.repeatEachIndex}`; + deviceRegistry.delete(testId); +} +// Add device labels to screenshots (e.g. "Device: alice1") +async function addDeviceLabel(screenshot: Buffer, device: DeviceWrapper): Promise { + const { width } = await sharp(screenshot).metadata(); + const deviceName = device.getDeviceIdentity(); + + // Create semi-transparent label overlay + const labelHeight = 60; + const fontSize = 28; + const label = Buffer.from(` + + + + Device: ${deviceName} + + + `); + + // Composite label over screenshot + return sharp(screenshot) + .composite([ + { + input: label, + top: 0, + left: 0, + blend: 'over', + }, + ]) + .png() + .toBuffer(); +} + +async function createComposite(screenshots: Buffer[]): Promise { + if (screenshots.length === 0) { + throw new Error('No screenshots provided'); + } + + if (screenshots.length === 1) { + return screenshots[0]; + } + + if (screenshots.length > 4) { + throw new Error( + `Screenshot composition not supported for ${screenshots.length} devices. Maximum supported is 4.` + ); + } + + // Get dimensions from first screenshot + const { width, height } = await sharp(screenshots[0]).metadata(); + const gap = 2; + + // Calculate grid layout + const cols = 2; + const rows = Math.ceil(screenshots.length / cols); + + // Calculate canvas size + const canvasWidth = width * cols + gap * (cols - 1); + const canvasHeight = height * rows + gap * (rows - 1); + + // Create base canvas with white background + const canvas = sharp({ + create: { + width: canvasWidth, + height: canvasHeight, + channels: 4, + background: { r: 255, g: 255, b: 255, alpha: 1 }, + }, + }); + + // Calculate positions and create composite array + const composites = screenshots.map((screenshot, index) => { + const col = index % cols; + const row = Math.floor(index / cols); + const x = col * (width + gap); + const y = row * (height + gap); + + return { + input: screenshot, + left: x, + top: y, + }; + }); + + // Apply all screenshots to canvas + return canvas.composite(composites).png().toBuffer(); +} + +// Main screenshot capture function +export async function captureScreenshotsOnFailure(testInfo: TestInfo): Promise { + const testId = `${testInfo.testId}-${testInfo.parallelIndex}-${testInfo.repeatEachIndex}`; + const context = deviceRegistry.get(testId); + + if (!context || context.devices.length === 0) { + console.log('No devices registered for screenshot capture'); + return; + } + + console.log(`Test failed, capturing screenshots from ${context.devices.length} device(s)...`); + + // Collect screenshots + const screenshots: Buffer[] = []; + + for (let i = 0; i < context.devices.length; i++) { + const device = context.devices[i]; + try { + const screenshotBase64 = await device.getScreenshot(); + if (!screenshotBase64) continue; + + const rawScreenshot = Buffer.from(screenshotBase64, 'base64'); + + // Add label to each screenshot + const labeledScreenshot = await addDeviceLabel(rawScreenshot, device); + screenshots.push(labeledScreenshot); + + console.log(`Captured and labeled screenshot from device ${device.getDeviceIdentity()}`); + } catch (error) { + console.error( + `Failed to capture screenshot from device ${device.getDeviceIdentity()}:`, + error + ); + } + } + + if (screenshots.length === 0) { + console.log('No screenshots captured'); + return; + } + + try { + const finalImage = await createComposite(screenshots); + + // Strip everything after @ for a clean filename + const testDesc = testInfo.title.split('@')[0].trim().toLowerCase(); + const cleanName = testDesc.replace(/[:\s]+/g, '-').replace(/-+/g, '-'); + const retry = testInfo.retry > 0 ? `-retry${testInfo.retry}` : ''; + const fileName = `${cleanName}${retry}.png`; + + // Ensure output directory exists + await fs.promises.mkdir(testInfo.outputDir, { recursive: true }); + + // Save locally + const screenshotPath = path.join(testInfo.outputDir, fileName); + await fs.promises.writeFile(screenshotPath, finalImage); + console.log(`Screenshot saved: ${screenshotPath}`); + + // Attach to report + const attachmentName = + screenshots.length === 1 + ? 'Test Failure Screenshot' + : `Test Failure - ${screenshots.length} Devices`; + + await testInfo.attach(attachmentName, { + body: finalImage, + contentType: 'image/png', + }); + } catch (error) { + console.error('Failed to create screenshot:', error); + // Fallback: attach individual screenshots + for (let i = 0; i < screenshots.length; i++) { + await testInfo.attach(`Device ${i + 1}`, { + body: screenshots[i], + contentType: 'image/png', + }); + } + } +} diff --git a/run/test/specs/utils/screenshot_paths.ts b/run/test/specs/utils/screenshot_paths.ts index 8ea2c27e..f03aaed6 100644 --- a/run/test/specs/utils/screenshot_paths.ts +++ b/run/test/specs/utils/screenshot_paths.ts @@ -1,8 +1,9 @@ import path from 'path'; -import { EmptyLandingPage } from '../locators/home'; -import { SupportedPlatformsType } from './open_app'; + import { PageName } from '../../../types/testing'; +import { EmptyLandingPage } from '../locators/home'; import { AppDisguisePage } from '../locators/settings'; +import { SupportedPlatformsType } from './open_app'; // Extends locator classes with baseline screenshot paths for visual regression testing // If a locator appears in multiple states, a state argument must be provided to screenshotFileName() diff --git a/run/test/specs/utils/utilities.ts b/run/test/specs/utils/utilities.ts index ce0d1ecf..b89a2464 100644 --- a/run/test/specs/utils/utilities.ts +++ b/run/test/specs/utils/utilities.ts @@ -1,12 +1,13 @@ +import { exec as execNotPromised } from 'child_process'; +import * as fs from 'fs'; import { pick } from 'lodash'; -import * as util from 'util'; -import sharp from 'sharp'; import path from 'path'; -import * as fs from 'fs'; +import sharp from 'sharp'; +import * as util from 'util'; import { v4 as uuidv4 } from 'uuid'; -import { Suffix } from '../../../types/testing'; -import { exec as execNotPromised } from 'child_process'; + import { DeviceWrapper } from '../../../types/DeviceWrapper'; +import { Suffix } from '../../../types/testing'; const exec = util.promisify(execNotPromised); export async function runScriptAndLog(toRun: string, verbose = false): Promise { diff --git a/run/test/specs/utils/verify_screenshots.ts b/run/test/specs/utils/verify_screenshots.ts index 8a169616..70c45862 100644 --- a/run/test/specs/utils/verify_screenshots.ts +++ b/run/test/specs/utils/verify_screenshots.ts @@ -1,14 +1,15 @@ +import { TestInfo } from '@playwright/test'; import * as fs from 'fs'; import looksSame from 'looks-same'; import * as path from 'path'; import { v4 as uuidv4 } from 'uuid'; + import { DeviceWrapper } from '../../../types/DeviceWrapper'; import { PageName } from '../../../types/testing'; import { LocatorsInterfaceScreenshot } from '../locators'; import { SupportedPlatformsType } from './open_app'; import { BrowserPageScreenshot } from './screenshot_paths'; import { cropScreenshot, getDiffDirectory, saveImage } from './utilities'; -import { TestInfo } from '@playwright/test'; type Attachment = { name: string; diff --git a/run/test/specs/voice_calls.spec.ts b/run/test/specs/voice_calls.spec.ts index 99bb2a97..bc484609 100644 --- a/run/test/specs/voice_calls.spec.ts +++ b/run/test/specs/voice_calls.spec.ts @@ -1,10 +1,12 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { bothPlatformsItSeparate } from '../../types/sessionIt'; import { ExitUserProfile } from './locators'; import { CallButton, NotificationSettings, NotificationSwitch } from './locators/conversation'; import { open_Alice1_bob1_notfriends } from './state_builder'; import { sleepFor } from './utils/index'; -import { SupportedPlatformsType, closeApp } from './utils/open_app'; +import { closeApp, SupportedPlatformsType } from './utils/open_app'; // skipping tests because they are unreliable on virtual devices, see QA-478 bothPlatformsItSeparate({ @@ -21,11 +23,11 @@ bothPlatformsItSeparate({ }, }); -async function voiceCallIos(platform: SupportedPlatformsType) { +async function voiceCallIos(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice, bob }, - } = await open_Alice1_bob1_notfriends({ platform }); + } = await open_Alice1_bob1_notfriends({ platform, testInfo }); await alice1.sendNewMessage({ accountID: bob.sessionId }, 'Testing calls'); // Look for phone icon (shouldnt be there) @@ -144,11 +146,11 @@ async function voiceCallIos(platform: SupportedPlatformsType) { await closeApp(alice1, bob1); } -async function voiceCallAndroid(platform: SupportedPlatformsType) { +async function voiceCallAndroid(platform: SupportedPlatformsType, testInfo: TestInfo) { const { devices: { alice1, bob1 }, prebuilt: { alice, bob }, - } = await open_Alice1_bob1_notfriends({ platform }); + } = await open_Alice1_bob1_notfriends({ platform, testInfo }); await alice1.sendNewMessage({ accountID: bob.sessionId }, 'Testing calls'); // Look for phone icon (should not be there) diff --git a/run/test/specs/warning_modal_new_account.spec.ts b/run/test/specs/warning_modal_new_account.spec.ts index 966b3ab0..0ce4d1db 100644 --- a/run/test/specs/warning_modal_new_account.spec.ts +++ b/run/test/specs/warning_modal_new_account.spec.ts @@ -1,6 +1,9 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { androidIt } from '../../types/sessionIt'; import { USERNAME } from '../../types/testing'; +import { ContinueButton } from '../specs/locators/global'; import { BackButton, CreateAccountButton, @@ -9,7 +12,6 @@ import { WarningModalQuitButton, } from './locators/onboarding'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; -import { ContinueButton } from '../specs/locators/global'; // These modals no longer exist in groups rebuild for iOS androidIt({ @@ -19,8 +21,8 @@ androidIt({ countOfDevicesNeeded: 1, }); -async function warningModalNewAccount(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function warningModalNewAccount(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); await device.clickOnElementAll(new CreateAccountButton(device)); await device.inputText(USERNAME.ALICE, new DisplayNameInput(device)); await device.clickOnElementAll(new ContinueButton(device)); diff --git a/run/test/specs/warning_modal_restore_account.spec.ts b/run/test/specs/warning_modal_restore_account.spec.ts index fa46a96a..74cd948a 100644 --- a/run/test/specs/warning_modal_restore_account.spec.ts +++ b/run/test/specs/warning_modal_restore_account.spec.ts @@ -1,5 +1,8 @@ +import type { TestInfo } from '@playwright/test'; + import { englishStrippedStr } from '../../localizer/englishStrippedStr'; import { androidIt } from '../../types/sessionIt'; +import { ContinueButton } from '../specs/locators/global'; import { AccountRestoreButton, BackButton, @@ -8,7 +11,6 @@ import { WarningModalQuitButton, } from './locators/onboarding'; import { closeApp, openAppOnPlatformSingleDevice, SupportedPlatformsType } from './utils/open_app'; -import { ContinueButton } from '../specs/locators/global'; // These modals no longer exist in groups rebuild for iOS androidIt({ title: 'Warning modal on restore account', @@ -17,8 +19,8 @@ androidIt({ countOfDevicesNeeded: 1, }); -async function warningModalRestoreAccount(platform: SupportedPlatformsType) { - const { device } = await openAppOnPlatformSingleDevice(platform); +async function warningModalRestoreAccount(platform: SupportedPlatformsType, testInfo: TestInfo) { + const { device } = await openAppOnPlatformSingleDevice(platform, testInfo); const seedPhrase = 'eldest fazed hybrid buzzer nasty domestic digit pager unusual purged makeup assorted domestic'; await device.clickOnElementAll(new AccountRestoreButton(device)); diff --git a/run/types/DeviceWrapper.ts b/run/types/DeviceWrapper.ts index 6ecc2e20..02fd3b41 100644 --- a/run/types/DeviceWrapper.ts +++ b/run/types/DeviceWrapper.ts @@ -1,8 +1,13 @@ +import { getImageOccurrence } from '@appium/opencv'; import { W3CCapabilities } from '@wdio/types/build/Capabilities'; import { AndroidUiautomator2Driver } from 'appium-uiautomator2-driver'; import { XCUITestDriver } from 'appium-xcuitest-driver/build/lib/driver'; +import fs from 'fs/promises'; import { isArray, isEmpty } from 'lodash'; +import * as path from 'path'; +import sharp from 'sharp'; import * as sinon from 'sinon'; + import { ChangeProfilePictureButton, DownloadMediaButton, @@ -13,6 +18,13 @@ import { ReadReceiptsButton, SendMediaButton, } from '../../run/test/specs/locators'; +import { + profilePicture, + testFile, + testImage, + testVideo, + testVideoThumbnail, +} from '../constants/testfiles'; import { englishStrippedStr } from '../localizer/englishStrippedStr'; import { AttachmentsButton, @@ -20,6 +32,7 @@ import { OutgoingMessageStatusSent, } from '../test/specs/locators/conversation'; import { ModalDescription, ModalHeading } from '../test/specs/locators/global'; +import { PlusButton } from '../test/specs/locators/home'; import { LoadingAnimation } from '../test/specs/locators/onboarding'; import { PrivacyMenuItem, @@ -34,6 +47,7 @@ import { import { clickOnCoordinates, sleepFor } from '../test/specs/utils'; import { getAdbFullPath } from '../test/specs/utils/binaries'; import { parseDataImage } from '../test/specs/utils/check_colour'; +import { copyFileToSimulator } from '../test/specs/utils/copy_file_to_simulator'; import { SupportedPlatformsType } from '../test/specs/utils/open_app'; import { isDeviceAndroid, isDeviceIOS, runScriptAndLog } from '../test/specs/utils/utilities'; import { @@ -47,19 +61,6 @@ import { User, XPath, } from './testing'; -import { PlusButton } from '../test/specs/locators/home'; -import { - testFile, - testImage, - testVideo, - profilePicture, - testVideoThumbnail, -} from '../constants/testfiles'; -import * as path from 'path'; -import fs from 'fs/promises'; -import { getImageOccurrence } from '@appium/opencv'; -import { copyFileToSimulator } from '../test/specs/utils/copy_file_to_simulator'; -import sharp from 'sharp'; export type Coordinates = { x: number; @@ -74,10 +75,42 @@ type AppiumNextElementType = { ELEMENT: string }; export class DeviceWrapper { private readonly device: AndroidUiautomator2Driver | XCUITestDriver; public readonly udid: string; + private deviceIdentity: string = ''; constructor(device: AndroidUiautomator2Driver | XCUITestDriver, udid: string) { this.device = device; this.udid = udid; + // Set temporary identity immediately + this.deviceIdentity = `device-${udid.slice(-4)}`; + } + + // LOGGING METHODS + public log(...args: unknown[]): void { + console.log(`[${this.deviceIdentity}]`, ...args); + } + + public info(...args: unknown[]): void { + console.info(`[${this.deviceIdentity}]`, ...args); + } + + public warn(...args: unknown[]): void { + console.warn(`[${this.deviceIdentity}]`, ...args); + } + + public error(...args: unknown[]): void { + console.error(`[${this.deviceIdentity}]`, ...args); + } + + // DEVICE IDENTITY METHODS + public setDeviceIdentity(identity: string): void { + const oldIdentity = this.deviceIdentity; + this.deviceIdentity = identity; + this.log(`Device identity changed from ${oldIdentity} to ${identity}`); + } + + // Get device identity for labels and logging + public getDeviceIdentity(): string { + return this.deviceIdentity; } public onIOS() { @@ -217,7 +250,7 @@ export class DeviceWrapper { } public async pushFile(path: string, data: string): Promise { - console.log('Did file get pushed', path); + this.log('Did file get pushed', path); await this.toShared().pushFile(path, data); } @@ -334,7 +367,7 @@ export class DeviceWrapper { await this.click(el.ELEMENT); } catch (error: unknown) { if (error instanceof Error && error.name === 'StaleElementReferenceError') { - console.log('Element is stale, refinding element and attempting second click'); + this.log('Element is stale, refinding element and attempting second click'); await this.waitForTextElementToBePresent({ strategy: 'accessibility id', selector: accessibilityId, @@ -398,7 +431,7 @@ export class DeviceWrapper { public async clickOnCoordinates(xCoOrdinates: number, yCoOrdinates: number) { await this.pressCoordinates(xCoOrdinates, yCoOrdinates); - console.log(`Tapped coordinates ${xCoOrdinates}, ${yCoOrdinates}`); + this.log(`Tapped coordinates ${xCoOrdinates}, ${yCoOrdinates}`); } public async tapOnElement(accessibilityId: AccessibilityId) { @@ -448,7 +481,7 @@ export class DeviceWrapper { }); if (longPressSuccess) { - console.log('LongClick successful'); + this.log('LongClick successful'); success = true; // Exit the loop if successful } else { throw new Error(`longPress on message: ${textToLookFor} unsuccessful`); @@ -460,7 +493,7 @@ export class DeviceWrapper { `Longpress on message: ${textToLookFor} unsuccessful after ${maxRetries} attempts, ${(error as Error).toString()}` ); } - console.log(`Longpress attempt ${attempt} failed. Retrying...`); + this.log(`Longpress attempt ${attempt} failed. Retrying...`); await sleepFor(1000); } } @@ -495,13 +528,13 @@ export class DeviceWrapper { }); if (longPressSuccess) { - console.log('LongClick successful'); + this.log('LongClick successful'); success = true; // Exit the loop if successful } else { throw new Error(`longPress on conversation list: ${userName} unsuccessful`); } } catch (error) { - console.log(`Longpress attempt ${attempt} failed. Retrying...`); + this.log(`Longpress attempt ${attempt} failed. Retrying...`); attempt++; await sleepFor(1000); if (attempt >= maxRetries) { @@ -574,7 +607,7 @@ export class DeviceWrapper { }); success = true; } catch (error: any) { - console.info(`Retrying long press and select all, attempt ${retries + 1}`); + this.info(`Retrying long press and select all, attempt ${retries + 1}`); } } else { await this.longClick(el, 2000); @@ -588,7 +621,7 @@ export class DeviceWrapper { await this.clear(el.ELEMENT); - console.info(`Text has been cleared `); + this.info(`Text has been cleared `); return; } @@ -686,9 +719,9 @@ export class DeviceWrapper { if (elements && elements.length) { const matching = await this.findAsync(elements, async e => { const text = await this.getTextFromElement(e); - // console.info(`text ${text} looking for ${textToLookFor}`); + // this.info(`text ${text} looking for ${textToLookFor}`); if (text.toLowerCase().includes(textToLookFor.toLowerCase())) { - console.info(`Text found to include ${textToLookFor}`); + this.info(`Text found to include ${textToLookFor}`); } return Boolean(text && text.toLowerCase() === textToLookFor.toLowerCase()); }); @@ -756,7 +789,7 @@ export class DeviceWrapper { // Find all candidate elements matching the locator const elements = await this.findElements(locator.strategy, locator.selector); - console.info( + this.info( `[matchAndTapImage] Found ${elements.length} elements for ${locator.strategy} "${locator.selector}"` ); @@ -771,7 +804,7 @@ export class DeviceWrapper { // Iterate over each candidate element for (const [i, el] of elements.entries()) { - console.info(`[matchAndTapImage] Processing element ${i + 1}/${elements.length}`); + this.info(`[matchAndTapImage] Processing element ${i + 1}/${elements.length}`); // Take a screenshot of the element const base64 = await this.getElementScreenshot(el.ELEMENT); @@ -804,7 +837,7 @@ export class DeviceWrapper { const { rect: matchRect, score } = await getImageOccurrence(elementBuffer, resizedRef, { threshold, }); - console.info(`[matchAndTapImage] Match score for element ${i + 1}: ${score.toFixed(4)}`); + this.info(`[matchAndTapImage] Match score for element ${i + 1}: ${score.toFixed(4)}`); /** * Matching is done on a resized reference image to account for device pixel density. @@ -836,7 +869,7 @@ export class DeviceWrapper { // If earlyMatch is enabled and the score is high enough, tap immediately if (earlyMatch && score >= earlyMatchThreshold) { - console.info( + this.info( `[matchAndTapImage] Tapping first match with ${(score * 100).toFixed(2)}% confidence` ); await clickOnCoordinates(this, center); @@ -845,13 +878,11 @@ export class DeviceWrapper { // Otherwise, keep track of the best match so far if (!bestMatch || score > bestMatch.score) { bestMatch = { center, score }; - console.info( - `[matchAndTapImage] New best match: ${(score * 100).toFixed(2)}% confidence` - ); + this.info(`[matchAndTapImage] New best match: ${(score * 100).toFixed(2)}% confidence`); } } catch (err) { // If matching fails for this element, log and continue to the next - console.warn( + this.warn( `[matchAndTapImage] Matching failed for element ${i + 1}:`, err instanceof Error ? err.message : err ); @@ -864,7 +895,7 @@ export class DeviceWrapper { ); } // Tap the best match found - console.info( + this.info( `[matchAndTapImage] Tapping best match with ${(bestMatch.score * 100).toFixed(2)}% confidence` ); await clickOnCoordinates(this, bestMatch.center); @@ -892,17 +923,15 @@ export class DeviceWrapper { const els = await this.findElements(locator.strategy, locator.selector); element = await this.findMatchingTextInElementArray(els, text); if (element) { - console.log( - `${locator.strategy}: ${locator.selector} with matching text "${text}" found` - ); + this.log(`${locator.strategy}: ${locator.selector} with matching text "${text}" found`); } else { - console.log( + this.log( `Couldn't find "${text}" with matching ${locator.strategy}: ${locator.selector}` ); } } } catch (e: any) { - console.info(`doesElementExist failed with ${locator.strategy} ${locator.selector}`); + this.info(`doesElementExist failed with ${locator.strategy} ${locator.selector}`); } // Break immediately if we found the element if (element) { @@ -911,10 +940,10 @@ export class DeviceWrapper { // Check for timeout before sleeping if (Date.now() >= beforeStart + maxWaitMSec) { - console.log(locator.selector, "doesn't exist, time expired"); + this.log(locator.selector, "doesn't exist, time expired"); break; } else { - console.log(locator.selector, "Doesn't exist but retrying"); + this.log(locator.selector, "Doesn't exist but retrying"); } // Sleep before trying again @@ -941,20 +970,20 @@ export class DeviceWrapper { // Note: we need a `maxWait` here to make sure we don't wait for an element that we expect is deleted for too long element = await this.waitForTextElementToBePresent({ ...locator, maxWait }); await sleepFor(100); - console.log(`Element has been found, waiting for deletion`); + this.log(`Element has been found, waiting for deletion`); } catch (e: any) { element = undefined; - console.log(`Element has been deleted, great success`); + this.log(`Element has been deleted, great success`); } } else { try { // Note: we need a `maxWait` here to make sure we don't wait for an element that we expect is deleted for too long element = await this.waitForTextElementToBePresent({ ...locator, maxWait }); await sleepFor(100); - console.log(`Text element has been found, waiting for deletion`); + this.log(`Text element has been found, waiting for deletion`); } catch (e) { element = undefined; - console.log(`Text element has been deleted, great success`); + this.log(`Text element has been deleted, great success`); } } } while (Date.now() - start <= maxWait && element); @@ -974,7 +1003,7 @@ export class DeviceWrapper { throw e; } } - console.log(accessibilityId, ': ', text, 'is not visible, congratulations'); + this.log(accessibilityId, ': ', text, 'is not visible, congratulations'); } // WAIT FOR FUNCTIONS @@ -996,15 +1025,15 @@ export class DeviceWrapper { try { const waitingForStr = `Waiting for "${locator.strategy}" and "${locator.selector}" to be present`; if (text) { - console.log(`${waitingForStr} with "${text}"`); + this.log(`${waitingForStr} with "${text}"`); const els = await this.findElements(locator.strategy, locator.selector); el = await this.findMatchingTextInElementArray(els, text); } else { - console.log(waitingForStr); + this.log(waitingForStr); el = await this.findElement(locator.strategy, locator.selector); } } catch (e: any) { - console.info( + this.info( `waitForTextElementToBePresent threw: "${locator.strategy}": "${locator.selector}` ); } @@ -1021,9 +1050,9 @@ export class DeviceWrapper { } if (el) { if (text) { - console.log(`'${locator.selector}' and '${text}' has been found`); + this.log(`'${locator.selector}' and '${text}' has been found`); } else { - console.log(`'${locator.selector}' has been found`); + this.log(`'${locator.selector}' has been found`); } } } @@ -1041,24 +1070,24 @@ export class DeviceWrapper { const textWithQuotes = `"${text}"`; while (el === null) { try { - console.log(`Waiting for control message to be present with "${textWithQuotes}"`); + this.log(`Waiting for control message to be present with "${textWithQuotes}"`); const els = await this.findElements('accessibility id', 'Control message'); el = await this.findMatchingTextInElementArray(els, text); } catch (e: any) { - console.info('waitForControlMessageToBePresent threw: ', e.message); + this.info('waitForControlMessageToBePresent threw: ', e.message); } if (!el) { await sleepFor(waitPerLoop); } currentWait += waitPerLoop; if (currentWait >= maxWaitMSec) { - console.log('Waited too long'); + this.log('Waited too long'); throw new Error( `Waited for too long (${maxWaitMSec}ms) looking for Control message "${textWithQuotes}"` ); } } - console.log(`Control message "${textWithQuotes}" has been found`); + this.log(`Control message "${textWithQuotes}" has been found`); return el; } @@ -1072,24 +1101,24 @@ export class DeviceWrapper { const waitPerLoop = 100; while (el === null) { try { - console.log(`Waiting for control message to be present with ${text}`); + this.log(`Waiting for control message to be present with ${text}`); const els = await this.findElements('accessibility id', 'Control message'); el = await this.findMatchingTextInElementArray(els, text); } catch (e) { - console.info('disappearingControlMessage threw: ', e); + this.info('disappearingControlMessage threw: ', e); } if (!el) { await sleepFor(waitPerLoop); } currentWait += waitPerLoop; if (currentWait >= maxWaitMSec) { - console.log('Waited too long'); + this.log('Waited too long'); throw new Error( `Waited for too long (${maxWaitMSec}ms) looking for Control message ${text}` ); } } - console.log(`Control message ${text} has been found`); + this.log(`Control message ${text} has been found`); return el; } @@ -1106,15 +1135,15 @@ export class DeviceWrapper { if (loadingAnimation) { await sleepFor(100); - console.info('Loading animation was found, waiting for it to be gone'); + this.info('Loading animation was found, waiting for it to be gone'); } } catch (e: any) { - console.log('Loading animation not found'); + this.log('Loading animation not found'); loadingAnimation = null; } } while (loadingAnimation); - console.info('Loading animation has finished'); + this.info('Loading animation has finished'); } public async waitForLoadingOnboarding() { @@ -1128,15 +1157,15 @@ export class DeviceWrapper { if (loadingAnimation) { await sleepFor(500); - console.info('Loading animation was found, waiting for it to be gone'); + this.info('Loading animation was found, waiting for it to be gone'); } } catch (e: any) { - console.log('Loading animation not found'); + this.log('Loading animation not found'); loadingAnimation = null; } } while (loadingAnimation); - console.info('Loading animation has finished'); + this.info('Loading animation has finished'); } // UTILITY FUNCTIONS @@ -1224,9 +1253,9 @@ export class DeviceWrapper { selector: 'Conversation list item', text: receiver.userName, }); - console.log(`${sender.userName} + " sent message to ${receiver.userName}`); + this.log(`${sender.userName} + " sent message to ${receiver.userName}`); await this.sendMessage(message); - console.log(`Message received by ${receiver.userName} from ${sender.userName}`); + this.log(`Message received by ${receiver.userName} from ${sender.userName}`); return message; } @@ -1260,7 +1289,7 @@ export class DeviceWrapper { const timeEnd = Date.now(); const timeMs = timeEnd - timeStart; - console.log(`Message ${messageNumber}: ${timeMs}`); + this.log(`Message ${messageNumber}: ${timeMs}`); return timeMs; } @@ -1271,7 +1300,7 @@ export class DeviceWrapper { let el: null | AppiumNextElementType = null; const locator = args instanceof LocatorsInterface ? args.build() : args; - console.log('Locator being used:', locator); + this.log('Locator being used:', locator); el = await this.waitForTextElementToBePresent({ ...locator }); if (!el) { @@ -1296,7 +1325,7 @@ export class DeviceWrapper { }); const attr = await this.getAttribute('value', radioButton.ELEMENT); if (attr === 'selected') { - console.log('Great success - default time is correct'); + this.log('Great success - default time is correct'); } else { throw new Error('Dammit - default time was not correct'); } @@ -1309,7 +1338,7 @@ export class DeviceWrapper { if (!attr) { throw new Error('Dammit - default time was not correct'); } - console.log('Great success - default time is correct'); + this.log('Great success - default time is correct'); } } @@ -1629,7 +1658,7 @@ export class DeviceWrapper { }); if (longPressSuccess) { - console.log('LongClick successful'); // Exit the loop if successful + this.log('LongClick successful'); // Exit the loop if successful } else { throw new Error(`longPress on voice message unsuccessful`); } @@ -1640,7 +1669,7 @@ export class DeviceWrapper { `Longpress on on voice message unsuccessful after ${maxRetries} attempts, ${error as string}` ); } - console.log(`Longpress attempt ${attempt} failed. Retrying...`); + this.log(`Longpress attempt ${attempt} failed. Retrying...`); await sleepFor(1000); } } else if (this.isIOS()) { @@ -1685,9 +1714,9 @@ export class DeviceWrapper { try { const time = await this.getDeviceTime(platform); timeString = time.toString(); - console.log(`Device time: ${timeString}`); + this.log(`Device time: ${timeString}`); } catch (e) { - console.log(`Couldn't get time from device`); + this.log(`Couldn't get time from device`); } return timeString; } @@ -1701,7 +1730,7 @@ export class DeviceWrapper { }); return Boolean(spaceBar); } - console.log(`Not an iOS device: shouldn't use this function`); + this.log(`Not an iOS device: shouldn't use this function`); } public async mentionContact(platform: SupportedPlatformsType, contact: Pick) { @@ -1753,7 +1782,7 @@ export class DeviceWrapper { }); const loc = await this.getElementRect(el.ELEMENT); - console.log(loc); + this.log(loc); if (!loc) { throw new Error('did not find element rectangle'); @@ -1764,7 +1793,7 @@ export class DeviceWrapper { 1000 ); - console.info('Swiped left on ', selector); + this.info('Swiped left on ', selector); } public async swipeRightAny(selector: AccessibilityId) { const el = await this.waitForTextElementToBePresent({ @@ -1773,7 +1802,7 @@ export class DeviceWrapper { }); const loc = await this.getElementRect(el.ELEMENT); - console.log(loc); + this.log(loc); if (!loc) { throw new Error('did not find element rectangle'); @@ -1784,13 +1813,13 @@ export class DeviceWrapper { 500 ); - console.info('Swiped right on ', selector); + this.info('Swiped right on ', selector); } public async swipeLeft(accessibilityId: AccessibilityId, text: string) { const el = await this.findMatchingTextAndAccessibilityId(accessibilityId, text); const loc = await this.getElementRect(el.ELEMENT); - console.log(loc); + this.log(loc); if (!loc) { throw new Error('did not find element rectangle'); @@ -1801,7 +1830,7 @@ export class DeviceWrapper { 1000 ); - console.info('Swiped left on ', el); + this.info('Swiped left on ', el); // let some time for swipe action to happen and UI to update } @@ -1830,7 +1859,7 @@ export class DeviceWrapper { selector: 'network.loki.messenger:id/scrollToBottomButton', }); } else { - console.info('Scroll button not visible'); + this.info('Scroll button not visible'); } } else { await this.clickOnElementAll({ @@ -1962,7 +1991,7 @@ export class DeviceWrapper { await this.clickOnByAccessibilityID(selector); } } catch (e) { - console.info('iosPermissions doesElementExist failed with: ', e); + this.info('iosPermissions doesElementExist failed with: ', e); // Ignore any exceptions during the action } @@ -2003,14 +2032,14 @@ export class DeviceWrapper { ...args, maxWait: 500, }); - console.info('iosPermissions', iosPermissions); + this.info('iosPermissions', iosPermissions); if (iosPermissions) { await this.clickOnElementAll({ ...args, maxWait }); } else { - console.info('No iosPermissions', iosPermissions); + this.info('No iosPermissions', iosPermissions); } } catch (e) { - console.info('FAILED WITH', e); + this.info('FAILED WITH', e); // Ignore any exceptions during the action } @@ -2059,7 +2088,7 @@ export class DeviceWrapper { const elHeading = await this.findWithFallback(headingPrimary, headingFallback); const actualHeading = removeNewLines(await this.getTextFromElement(elHeading)); if (expectedHeading === actualHeading) { - console.log('Modal heading is correct'); + this.log('Modal heading is correct'); } else { throw new Error( `Modal heading is incorrect.\nExpected: ${expectedHeading}\nActual: ${actualHeading}` @@ -2069,7 +2098,7 @@ export class DeviceWrapper { const elDescription = await this.findWithFallback(descPrimary, descFallback); const actualDescription = removeNewLines(await this.getTextFromElement(elDescription)); if (expectedDescription === actualDescription) { - console.log('Modal description is correct'); + this.log('Modal description is correct'); } else { throw new Error( `Modal description is incorrect.\nExpected: ${expectedDescription}\nActual: ${actualDescription}` diff --git a/run/types/sessionIt.ts b/run/types/sessionIt.ts index 25b8ade8..5c0d8cb3 100644 --- a/run/types/sessionIt.ts +++ b/run/types/sessionIt.ts @@ -1,10 +1,17 @@ -/* eslint-disable no-empty-pattern */ +// run/types/sessionIt.ts - Clean version matching original pattern import { test, type TestInfo } from '@playwright/test'; +import { omit } from 'lodash'; + +import type { AppCountPerTest } from '../test/specs/state_builder'; + import { SupportedPlatformsType } from '../test/specs/utils/open_app'; +import { + captureScreenshotsOnFailure, + unregisterDevicesForTest, +} from '../test/specs/utils/screenshot_helper'; import { TestRisk } from './testing'; -import type { AppCountPerTest } from '../test/specs/state_builder'; -import { omit } from 'lodash'; +// Test wrapper configuration type MobileItArgs = { platform: SupportedPlatformsType; countOfDevicesNeeded: AppCountPerTest; @@ -31,23 +38,56 @@ function mobileIt({ countOfDevicesNeeded, }: MobileItArgs) { const testName = `${title} @${platform} @${risk ?? 'default'}-risk @${countOfDevicesNeeded}-devices`; + if (shouldSkip) { test.skip(testName, () => { console.info(`\n\n==========> Skipping "${testName}"\n\n`); }); - } else { - test(testName, async ({}, testInfo) => { - console.info(`\n\n==========> Running "${testName}"\n\n`); - await testCb(platform, testInfo); - }); + return; } + + // eslint-disable-next-line no-empty-pattern + test(testName, async ({}, testInfo) => { + console.info(`\n\n==========> Running "${testName}"\n\n`); + + let testFailed = false; + + try { + await testCb(platform, testInfo); + } catch (error) { + testFailed = true; // Playwright hasn't updated testInfo.status yet, so track failure manually + throw error; + } finally { + // NOTE: This finally block runs for thrown errors but NOT for: + // - Test timeouts (Playwright kills execution before finally) + // - Interrupts/Ctrl+C (Process terminated before finally) + // If timeout screenshots become important, consider using test fixtures + // or racing against a custom timeout promise + try { + // Check for test failure - either our flag or Playwright's status + if ( + testFailed || + testInfo.errors.length > 0 || + testInfo.status === 'failed' || + testInfo.status === 'timedOut' + ) { + await captureScreenshotsOnFailure(testInfo); + } + } catch (screenshotError) { + console.error('Failed to capture screenshot:', screenshotError); + } + + try { + unregisterDevicesForTest(testInfo); + } catch (cleanupError) { + console.error('Failed to unregister devices:', cleanupError); + } + } + }); } export function bothPlatformsIt(args: Omit) { - // Define test for Android mobileIt({ platform: 'android', ...args }); - - // Define test for iOS mobileIt({ platform: 'ios', ...args }); } @@ -57,9 +97,6 @@ export function bothPlatformsItSeparate( android: Pick; } ) { - // Define test for Android mobileIt({ platform: 'android', ...omit(args, ['ios', 'android']), ...args.android }); - - // Define test for iOS mobileIt({ platform: 'ios', ...omit(args, ['ios', 'android']), ...args.ios }); } diff --git a/run/types/testing.ts b/run/types/testing.ts index 8e5dae0b..f1f42f70 100644 --- a/run/types/testing.ts +++ b/run/types/testing.ts @@ -1,6 +1,6 @@ -import { DeviceWrapper } from './DeviceWrapper'; +import { USERNAME as usernameFromSeeder, UserNameType } from '@session-foundation/qa-seeder'; -import { UserNameType, USERNAME as usernameFromSeeder } from '@session-foundation/qa-seeder'; +import { DeviceWrapper } from './DeviceWrapper'; export type User = { userName: UserNameType; diff --git a/scripts/start_ios.ts b/scripts/start_ios.ts index 5bb603d5..edfbd891 100644 --- a/scripts/start_ios.ts +++ b/scripts/start_ios.ts @@ -1,4 +1,5 @@ import { execSync, spawnSync } from 'child_process'; + import { getChunkedSimulators, isSimulatorBooted } from './ios_shared'; import { sleepSync } from './shared'; diff --git a/scripts/stop_ios.ts b/scripts/stop_ios.ts index a2f837e6..1827c6ef 100644 --- a/scripts/stop_ios.ts +++ b/scripts/stop_ios.ts @@ -1,4 +1,5 @@ import { execSync } from 'child_process'; + import { isAnySimulatorBooted } from './ios_shared'; function stopSimulatorsFromEnvIOS() { diff --git a/yarn.lock b/yarn.lock index 51f22b53..90f0cac6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1164,6 +1164,19 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/project-service@npm:8.35.1": + version: 8.35.1 + resolution: "@typescript-eslint/project-service@npm:8.35.1" + dependencies: + "@typescript-eslint/tsconfig-utils": "npm:^8.35.1" + "@typescript-eslint/types": "npm:^8.35.1" + debug: "npm:^4.3.4" + peerDependencies: + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/f8e88d773d7e9f193a05b4daeca1e7571fa0059b36ffad291fc6d83c9df94fbe38c935e076ae29e755bcb6008c4ee5c1073ebb2077258c5c0b53c76a23eb3c16 + languageName: node + linkType: hard + "@typescript-eslint/scope-manager@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/scope-manager@npm:5.62.0" @@ -1184,6 +1197,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:8.35.1": + version: 8.35.1 + resolution: "@typescript-eslint/scope-manager@npm:8.35.1" + dependencies: + "@typescript-eslint/types": "npm:8.35.1" + "@typescript-eslint/visitor-keys": "npm:8.35.1" + checksum: 10c0/ddfa0b81f47402874efcdd8e0857142600d90fc4e827243ed0fd058731e77e4beb8f5a60425117d1d4146d84437f538cf303f7bfebbd0f02733b202aa30a8393 + languageName: node + linkType: hard + "@typescript-eslint/tsconfig-utils@npm:8.34.1, @typescript-eslint/tsconfig-utils@npm:^8.34.1": version: 8.34.1 resolution: "@typescript-eslint/tsconfig-utils@npm:8.34.1" @@ -1193,6 +1216,15 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/tsconfig-utils@npm:8.35.1, @typescript-eslint/tsconfig-utils@npm:^8.35.1": + version: 8.35.1 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.35.1" + peerDependencies: + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/a11b53e05fbc59eff3f95619847fb7222d8b2aa613e602524c9b700be3ce0d48bcf5e5932869df4658f514bd2cdc87c857d484472af3f3f3adf88b6e7e1c26f3 + languageName: node + linkType: hard + "@typescript-eslint/type-utils@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/type-utils@npm:5.62.0" @@ -1239,6 +1271,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:8.35.1, @typescript-eslint/types@npm:^8.35.1": + version: 8.35.1 + resolution: "@typescript-eslint/types@npm:8.35.1" + checksum: 10c0/136dd1c7a39685baa398406423a97a4b6a66e6aed7cbd6ae698a89b0fde92c76f1415294bec612791d67d7917fda280caa65b9d761e2744e8143506d1f417fb2 + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/typescript-estree@npm:5.62.0" @@ -1277,6 +1316,26 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:8.35.1": + version: 8.35.1 + resolution: "@typescript-eslint/typescript-estree@npm:8.35.1" + dependencies: + "@typescript-eslint/project-service": "npm:8.35.1" + "@typescript-eslint/tsconfig-utils": "npm:8.35.1" + "@typescript-eslint/types": "npm:8.35.1" + "@typescript-eslint/visitor-keys": "npm:8.35.1" + debug: "npm:^4.3.4" + fast-glob: "npm:^3.3.2" + is-glob: "npm:^4.0.3" + minimatch: "npm:^9.0.4" + semver: "npm:^7.6.0" + ts-api-utils: "npm:^2.1.0" + peerDependencies: + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/6ef093cf9d7a54a323b3d112c78309b2c24c0f94e2c5b61401db9390eb7ffa3ab1da066c497907d58f0bba6986984ac73a478febd91f0bf11598108cc49f6e02 + languageName: node + linkType: hard + "@typescript-eslint/utils@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/utils@npm:5.62.0" @@ -1310,6 +1369,21 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/utils@npm:^8.34.1": + version: 8.35.1 + resolution: "@typescript-eslint/utils@npm:8.35.1" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.7.0" + "@typescript-eslint/scope-manager": "npm:8.35.1" + "@typescript-eslint/types": "npm:8.35.1" + "@typescript-eslint/typescript-estree": "npm:8.35.1" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: ">=4.8.4 <5.9.0" + checksum: 10c0/1fa4877caae48961d160b88fc974bb7bfe355ca2f8f6915987427354ca23621698041678adab5964caf9ad62c17b349110136890688f13b10ab1aaad74ae63d9 + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:5.62.0": version: 5.62.0 resolution: "@typescript-eslint/visitor-keys@npm:5.62.0" @@ -1330,6 +1404,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:8.35.1": + version: 8.35.1 + resolution: "@typescript-eslint/visitor-keys@npm:8.35.1" + dependencies: + "@typescript-eslint/types": "npm:8.35.1" + eslint-visitor-keys: "npm:^4.2.1" + checksum: 10c0/55b9eb15842a5d5dca11375e436340c731e01b07190c741d2656330f3e4d88b59e1bf3d677681dd091460be2b6e5f2c42e92faea36f947d25382ead5e8118108 + languageName: node + linkType: hard + "@wdio/config@npm:8.40.6": version: 8.40.6 resolution: "@wdio/config@npm:8.40.6" @@ -3268,6 +3352,19 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-perfectionist@npm:^4.15.0": + version: 4.15.0 + resolution: "eslint-plugin-perfectionist@npm:4.15.0" + dependencies: + "@typescript-eslint/types": "npm:^8.34.1" + "@typescript-eslint/utils": "npm:^8.34.1" + natural-orderby: "npm:^5.0.0" + peerDependencies: + eslint: ">=8.45.0" + checksum: 10c0/e6fd86a083be063580bde3947e885b6f3a18b8c47a77874a64d0e22a54e6bafcb356bcc5f0c00634ea7ee1c8744757b3e6f2dc478f01e4874090ffc1aea9efa6 + languageName: node + linkType: hard + "eslint-scope@npm:^5.1.1": version: 5.1.1 resolution: "eslint-scope@npm:5.1.1" @@ -5436,6 +5533,13 @@ __metadata: languageName: node linkType: hard +"natural-orderby@npm:^5.0.0": + version: 5.0.0 + resolution: "natural-orderby@npm:5.0.0" + checksum: 10c0/d4e8b3bf16636eedc0c99a4cd551cd371732dd8c9766f19c8e153946553d82c12527eab182b8e79d640681aa6cb718273b53662ccf88127d4726307b6e645b2b + languageName: node + linkType: hard + "ncp@npm:2.0.0, ncp@npm:~2.0.0": version: 2.0.0 resolution: "ncp@npm:2.0.0" @@ -6631,6 +6735,7 @@ __metadata: appium-xcuitest-driver: "npm:^7.26.0" dotenv: "npm:^16.4.5" eslint: "npm:^9.14.0" + eslint-plugin-perfectionist: "npm:^4.15.0" fs-extra: "npm:^11.3.0" gh-pages: "npm:^6.3.0" globals: "npm:^15.12.0" @@ -6638,6 +6743,7 @@ __metadata: looks-same: "npm:^9.0.1" png-js: "npm:^1.0.0" prettier: "npm:^3.3.3" + sharp: "npm:^0.34.2" sinon: "npm:^19.0.2" ts-node: "npm:^10.9.1" typescript: "npm:^5.6.3"