diff --git a/ts/components/leftpane/overlay/OverlayMessageRequest.tsx b/ts/components/leftpane/overlay/OverlayMessageRequest.tsx index 5d9bd695a..f39a2b21a 100644 --- a/ts/components/leftpane/overlay/OverlayMessageRequest.tsx +++ b/ts/components/leftpane/overlay/OverlayMessageRequest.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React from 'react'; // tslint:disable: no-submodule-imports use-simple-attributes import { useDispatch, useSelector } from 'react-redux'; @@ -6,9 +6,8 @@ import useKey from 'react-use/lib/useKey'; import styled from 'styled-components'; import { declineConversationWithoutConfirm } from '../../../interactions/conversationInteractions'; import { forceSyncConfigurationNowIfNeeded } from '../../../session/utils/sync/syncUtils'; -import { resetConversationExternal } from '../../../state/ducks/conversations'; import { updateConfirmModal } from '../../../state/ducks/modalDialog'; -import { SectionType, resetOverlayMode, showLeftPaneSection } from '../../../state/ducks/section'; +import { resetOverlayMode } from '../../../state/ducks/section'; import { getConversationRequests } from '../../../state/selectors/conversations'; import { useSelectedConversationKey } from '../../../state/selectors/selectedConversation'; import { SessionButton, SessionButtonColor } from '../../basic/SessionButton'; @@ -51,17 +50,6 @@ export const OverlayMessageRequest = () => { const currentlySelectedConvo = useSelectedConversationKey(); const convoRequestCount = useSelector(getConversationRequests).length; const messageRequests = useSelector(getConversationRequests); - - useEffect(() => { - // if no more requests, return to placeholder screen - - if (convoRequestCount === 0) { - dispatch(resetOverlayMode()); - dispatch(showLeftPaneSection(SectionType.Message)); - dispatch(resetConversationExternal()); - } - }, [dispatch, convoRequestCount]); - const buttonText = window.i18n('clearAll'); /** diff --git a/ts/session/onions/onionPath.ts b/ts/session/onions/onionPath.ts index 737398a83..0fb74988b 100644 --- a/ts/session/onions/onionPath.ts +++ b/ts/session/onions/onionPath.ts @@ -497,7 +497,10 @@ async function buildNewOnionPathsWorker() { for (let i = 0; i < maxPath; i += 1) { const path = [guards[i]]; for (let j = 0; j < nodesNeededPerPaths; j += 1) { - const randomWinner = _.sample(otherNodes) as Snode; + const randomWinner = _.sample(otherNodes); + if (!randomWinner) { + throw new Error('randomWinner unset during path building task'); + } otherNodes = otherNodes.filter(n => { return n.pubkey_ed25519 !== randomWinner?.pubkey_ed25519; }); diff --git a/ts/test/automation/call_checks.spec.ts b/ts/test/automation/call_checks.spec.ts index a4c5f6bf2..8285de6ba 100644 --- a/ts/test/automation/call_checks.spec.ts +++ b/ts/test/automation/call_checks.spec.ts @@ -1,12 +1,10 @@ -import { test } from '@playwright/test'; import { sleepFor } from '../../session/utils/Promise'; import { newUser } from './setup/new_user'; -import { openApp } from './setup/open'; import { createContact } from './utilities/create_contact'; import { clickOnMatchingText, clickOnTestIdWithText } from './utilities/utils'; +import { sessionTestTwoWindows } from './setup/sessionTest'; -test('Voice calls', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Voice calls', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); await createContact(windowA, windowB, userA, userB); diff --git a/ts/test/automation/create_user.spec.ts b/ts/test/automation/create_user.spec.ts index 453a56430..e3e884524 100644 --- a/ts/test/automation/create_user.spec.ts +++ b/ts/test/automation/create_user.spec.ts @@ -1,25 +1,13 @@ -import { Page, test } from '@playwright/test'; import { sleepFor } from '../../session/utils/Promise'; -import { beforeAllClean } from './setup/beforeEach'; import { newUser } from './setup/new_user'; -import { openAppAndWait } from './setup/open'; import { clickOnMatchingText, clickOnTestIdWithText, waitForTestIdWithText, } from './utilities/utils'; +import { sessionTestOneWindow } from './setup/sessionTest'; -let window: Page | undefined; -test.beforeEach(beforeAllClean); - -// test.afterEach(async () => { -// if (window) { -// await forceCloseAllWindows([window]); -// } -// }); -test('Create User', async () => { - // Launch Electron app. - window = await openAppAndWait('1'); +sessionTestOneWindow('Create User', async ([window]) => { // // Create User const userA = await newUser(window, 'userA'); // Open profile tab diff --git a/ts/test/automation/delete_account.spec.ts b/ts/test/automation/delete_account.spec.ts index 34feaa031..caee2934e 100644 --- a/ts/test/automation/delete_account.spec.ts +++ b/ts/test/automation/delete_account.spec.ts @@ -10,7 +10,7 @@ import { openApp } from './setup/open'; test.beforeEach(beforeAllClean); test('Delete account from swarm', async () => { - const [windowA, windowB] = await openApp(2); + const [windowA, windowB] = await openApp(2); // not using sessionTest here as we need to close and reopen one of the window const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const testMessage = `${userA.userName} to ${userB.userName}`; const testReply = `${userB.userName} to ${userA.userName}`; @@ -33,7 +33,7 @@ test('Delete account from swarm', async () => { // Wait for window to close and reopen await sleepFor(10000, true); // await windowA.close(); - const restoringWindows = await openApp(1); + const restoringWindows = await openApp(1); // not using sessionTest here as we need to close and reopen one of the window const [restoringWindow] = restoringWindows; // Sign in with deleted account and check that nothing restores await clickOnTestIdWithText(restoringWindow, 'restore-using-recovery', 'Restore your account'); diff --git a/ts/test/automation/disappearing_messages.spec.ts b/ts/test/automation/disappearing_messages.spec.ts index 4044c44b4..80dd16ea5 100644 --- a/ts/test/automation/disappearing_messages.spec.ts +++ b/ts/test/automation/disappearing_messages.spec.ts @@ -1,8 +1,6 @@ -import { test } from '@playwright/test'; import { sleepFor } from '../../session/utils/Promise'; -import { beforeAllClean } from './setup/beforeEach'; import { newUser } from './setup/new_user'; -import { openApp } from './setup/open'; +import { sessionTestTwoWindows } from './setup/sessionTest'; import { sendMessage } from './utilities/message'; import { sendNewMessage } from './utilities/send_message'; import { @@ -13,9 +11,6 @@ import { waitForTestIdWithText, } from './utilities/utils'; -test.beforeEach(beforeAllClean); - -// test.afterEach(() => forceCloseAllWindows(windows)); // tslint:disable: no-console const testMessage = 'Test-Message- (A -> B) '; @@ -23,10 +18,9 @@ const testReply = 'Reply-Test-Message- (B -> A)'; const sentMessage = `${testMessage}${Date.now()}`; const sentReplyMessage = `${testReply} :${Date.now()}`; -test('Disappearing messages', async () => { +sessionTestTwoWindows('Disappearing messages', async ([windowA, windowB]) => { // Open App // Create User - const [windowA, windowB] = await openApp(2); const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); // Create Contact await sendNewMessage(windowA, userB.sessionid, sentMessage); diff --git a/ts/test/automation/group_testing.spec.ts b/ts/test/automation/group_testing.spec.ts index 7b560df12..d0084f0eb 100644 --- a/ts/test/automation/group_testing.spec.ts +++ b/ts/test/automation/group_testing.spec.ts @@ -1,5 +1,6 @@ -import { expect, test } from '@playwright/test'; -import { beforeAllClean } from './setup/beforeEach'; +import { expect } from '@playwright/test'; +import { createGroup } from './setup/create_group'; +import { renameGroup } from './utilities/rename_group'; import { clickOnElement, clickOnMatchingText, @@ -10,22 +11,15 @@ import { waitForMatchingText, waitForTestIdWithText, } from './utilities/utils'; -import { renameGroup } from './utilities/rename_group'; -import { createGroup } from './setup/create_group'; // import { leaveGroup } from './utilities/leave_group'; -import { newUser } from './setup/new_user'; -import { leaveGroup } from './utilities/leave_group'; -import { openApp } from './setup/open'; import { sleepFor } from '../../session/utils/Promise'; +import { newUser } from './setup/new_user'; +import { sessionTestFourWindows, sessionTestThreeWindows } from './setup/sessionTest'; import { createContact } from './utilities/create_contact'; +import { leaveGroup } from './utilities/leave_group'; -test.beforeEach(beforeAllClean); - -// test.afterEach(() => forceCloseAllWindows(windows)); - -test('Create group', async () => { +sessionTestThreeWindows('Create group', async ([windowA, windowB, windowC]) => { // Open Electron - const [windowA, windowB, windowC] = await openApp(3); const [userA, userB, userC] = await Promise.all([ newUser(windowA, 'Alice'), newUser(windowB, 'Bob'), @@ -52,8 +46,7 @@ test('Create group', async () => { ]); }); -test('Add contact to group', async () => { - const [windowA, windowB, windowC, windowD] = await openApp(4); +sessionTestFourWindows('Add contact to group', async ([windowA, windowB, windowC, windowD]) => { const [userA, userB, userC, userD] = await Promise.all([ newUser(windowA, 'Alice'), newUser(windowB, 'Bob'), @@ -94,8 +87,7 @@ test('Add contact to group', async () => { await doesTextIncludeString(windowD, 'control-message', 'You joined the group.'); }); -test('Change group name', async () => { - const [windowA, windowB, windowC] = await openApp(3); +sessionTestThreeWindows('Change group name', async ([windowA, windowB, windowC]) => { const [userA, userB, userC] = await Promise.all([ newUser(windowA, 'Alice'), newUser(windowB, 'Bob'), @@ -130,8 +122,7 @@ test('Change group name', async () => { await clickOnTestIdWithText(windowA, 'back-button-conversation-options'); }); -test('Test mentions', async () => { - const [windowA, windowB, windowC] = await openApp(3); +sessionTestThreeWindows('Test mentions', async ([windowA, windowB, windowC]) => { const [userA, userB, userC] = await Promise.all([ newUser(windowA, 'Alice'), newUser(windowB, 'Bob'), @@ -173,8 +164,7 @@ test('Test mentions', async () => { await waitForTestIdWithText(windowC, 'mentions-popup-row', userB.userName); }); -test('Leave group', async () => { - const [windowA, windowB, windowC] = await openApp(3); +sessionTestThreeWindows('Leave group', async ([windowA, windowB, windowC]) => { const [userA, userB, userC] = await Promise.all([ newUser(windowA, 'Alice'), newUser(windowB, 'Bob'), diff --git a/ts/test/automation/group_upkeep.spec.ts b/ts/test/automation/group_upkeep.spec.ts index 2a77b762a..281904233 100644 --- a/ts/test/automation/group_upkeep.spec.ts +++ b/ts/test/automation/group_upkeep.spec.ts @@ -1,70 +1,63 @@ -import { _electron, test } from '@playwright/test'; -import { beforeAllClean } from './setup/beforeEach'; -import { sendNewMessage } from './utilities/send_message'; -import { logIn } from './setup/log_in'; -import { userA, userB, userC, userD, userE } from './setup/test_user'; -import { openApp } from './setup/open'; +// FIXME enable this test again once we fixed it +// sessionTestFiveWindows( +// 'Group upkeep - should be skipped', +// async ([windowA, windowB, windowC, windowD, windowE]) => { +// await Promise.all([ +// logIn(windowA, userA.recoveryPhrase), +// logIn(windowB, userB.recoveryPhrase), +// logIn(windowC, userC.recoveryPhrase), +// logIn(windowD, userD.recoveryPhrase), +// logIn(windowE, userE.recoveryPhrase), +// ]); +// // Send message from test users to all of it's contacts to maintain contact status -test.beforeEach(beforeAllClean); - -test.skip('Group upkeep', async () => { - const [windowA, windowB, windowC, windowD, windowE] = await openApp(5); - - await Promise.all([ - logIn(windowA, userA.recoveryPhrase), - logIn(windowB, userB.recoveryPhrase), - logIn(windowC, userC.recoveryPhrase), - logIn(windowD, userD.recoveryPhrase), - logIn(windowE, userE.recoveryPhrase), - ]); - // Send message from test users to all of it's contacts to maintain contact status - - // Send message from user A to Whale(TC1) - await sendNewMessage( - windowA, - userB.sessionid, - `${userA.userName} -> ${userB.userName}: ${Date.now()}` - ); - // Send message from Whale to user A - await sendNewMessage( - windowB, - userA.sessionid, - `${userB.userName} -> ${userA.userName} : ${Date.now()}` - ); - // Send message from user A to Dragon(TC2) - await sendNewMessage( - windowA, - userC.sessionid, - `${userA.userName} -> ${userC.userName}: ${Date.now()}` - ); - // Send message from Dragon to user A - await sendNewMessage( - windowC, - userA.sessionid, - `${userC.userName} -> ${userA.userName} : ${Date.now()}` - ); - // Send message from user A to Fish(TC3) - await sendNewMessage( - windowA, - userD.sessionid, - `${userA.userName} -> ${userD.userName}: ${Date.now()}` - ); - // Send message from Fish to user A - await sendNewMessage( - windowD, - userA.sessionid, - `${userD.userName} -> ${userA.userName} : ${Date.now()}` - ); - // Send message from user A to Gopher(TC4) - await sendNewMessage( - windowA, - userE.sessionid, - `${userA.userName} -> ${userD.userName}: ${Date.now()}` - ); - // Send message from Gopher to user A - await sendNewMessage( - windowE, - userA.sessionid, - `${userD.userName} -> ${userA.userName} : ${Date.now()}` - ); -}); +// // Send message from user A to Whale(TC1) +// await sendNewMessage( +// windowA, +// userB.sessionid, +// `${userA.userName} -> ${userB.userName}: ${Date.now()}` +// ); +// // Send message from Whale to user A +// await sendNewMessage( +// windowB, +// userA.sessionid, +// `${userB.userName} -> ${userA.userName} : ${Date.now()}` +// ); +// // Send message from user A to Dragon(TC2) +// await sendNewMessage( +// windowA, +// userC.sessionid, +// `${userA.userName} -> ${userC.userName}: ${Date.now()}` +// ); +// // Send message from Dragon to user A +// await sendNewMessage( +// windowC, +// userA.sessionid, +// `${userC.userName} -> ${userA.userName} : ${Date.now()}` +// ); +// // Send message from user A to Fish(TC3) +// await sendNewMessage( +// windowA, +// userD.sessionid, +// `${userA.userName} -> ${userD.userName}: ${Date.now()}` +// ); +// // Send message from Fish to user A +// await sendNewMessage( +// windowD, +// userA.sessionid, +// `${userD.userName} -> ${userA.userName} : ${Date.now()}` +// ); +// // Send message from user A to Gopher(TC4) +// await sendNewMessage( +// windowA, +// userE.sessionid, +// `${userA.userName} -> ${userD.userName}: ${Date.now()}` +// ); +// // Send message from Gopher to user A +// await sendNewMessage( +// windowE, +// userA.sessionid, +// `${userD.userName} -> ${userA.userName} : ${Date.now()}` +// ); +// } +// ); diff --git a/ts/test/automation/linked_device_group.spec.ts b/ts/test/automation/linked_device_group.spec.ts index b05471000..433cd6e5a 100644 --- a/ts/test/automation/linked_device_group.spec.ts +++ b/ts/test/automation/linked_device_group.spec.ts @@ -3,7 +3,7 @@ import { sleepFor } from '../../session/utils/Promise'; import { beforeAllClean } from './setup/beforeEach'; import { createGroup } from './setup/create_group'; import { newUser } from './setup/new_user'; -import { openApp } from './setup/open'; +import { sessionTestThreeWindows } from './setup/sessionTest'; import { leaveGroup } from './utilities/leave_group'; import { linkedDevice } from './utilities/linked_device'; import { @@ -14,8 +14,7 @@ import { test.beforeEach(beforeAllClean); -test('Check group syncs', async () => { - const [windowA, windowC, windowD] = await openApp(3); +sessionTestThreeWindows('Check group syncs', async ([windowA, windowC, windowD]) => { const [userA, userB, userC] = await Promise.all([ newUser(windowA, 'Alice'), newUser(windowC, 'Bob'), @@ -36,8 +35,7 @@ test('Check group syncs', async () => { await waitForTestIdWithText(windowB, 'module-conversation__user__profile-name', group.userName); }); -test('Check leaving group syncs', async () => { - const [windowA, windowC, windowD] = await openApp(3); +sessionTestThreeWindows('Check leaving group syncs', async ([windowA, windowC, windowD]) => { const [userA, userB, userC] = await Promise.all([ newUser(windowA, 'Alice'), newUser(windowC, 'Bob'), diff --git a/ts/test/automation/linked_device_requests.spec.ts b/ts/test/automation/linked_device_requests.spec.ts index d4983a2bc..c2db549ed 100644 --- a/ts/test/automation/linked_device_requests.spec.ts +++ b/ts/test/automation/linked_device_requests.spec.ts @@ -1,8 +1,5 @@ -import { test } from '@playwright/test'; -import { beforeAllClean } from './setup/beforeEach'; -// import { leaveGroup } from './utilities/leave_group'; import { newUser } from './setup/new_user'; -import { openApp } from './setup/open'; +import { sessionTestTwoWindows } from './setup/sessionTest'; import { linkedDevice } from './utilities/linked_device'; import { sendMessage } from './utilities/message'; import { sendNewMessage } from './utilities/send_message'; @@ -13,10 +10,7 @@ import { waitForTextMessage, } from './utilities/utils'; -test.beforeEach(beforeAllClean); - -test('Accept request syncs', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Accept request syncs', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const [windowC] = await linkedDevice(userB.recoveryPhrase); @@ -41,8 +35,7 @@ test('Accept request syncs', async () => { await waitForTestIdWithText(windowC, 'module-conversation__user__profile-name', userA.userName); }); -test('Decline request syncs', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Decline request syncs', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const [windowC] = await linkedDevice(userB.recoveryPhrase); diff --git a/ts/test/automation/linked_device_user.spec.ts b/ts/test/automation/linked_device_user.spec.ts index 7fb81869b..daa7b9564 100644 --- a/ts/test/automation/linked_device_user.spec.ts +++ b/ts/test/automation/linked_device_user.spec.ts @@ -25,9 +25,9 @@ test.afterEach(() => forceCloseAllWindows(windows)); // tslint:disable: no-console test('Link a device', async () => { - const [windowA] = await openApp(1); + const [windowA] = await openApp(1); // not using sessionTest here as we need to close and reopen one of the window const userA = await newUser(windowA, 'Alice'); - const [windowB] = await linkedDevice(userA.recoveryPhrase); + const [windowB] = await linkedDevice(userA.recoveryPhrase); // not using sessionTest here as we need to close and reopen one of the window await clickOnTestIdWithText(windowA, 'leftpane-primary-avatar'); // Verify Username await waitForTestIdWithText(windowA, 'your-profile-name', userA.userName); @@ -72,9 +72,9 @@ test('Check changed username syncs', async () => { }); test('Check profile picture syncs', async () => { - const [windowA] = await openApp(1); + const [windowA] = await openApp(1); // not using sessionTest here as we need to close and reopen one of the window const userA = await newUser(windowA, 'Alice'); - const [windowB] = await linkedDevice(userA.recoveryPhrase); + const [windowB] = await linkedDevice(userA.recoveryPhrase); // not using sessionTest here as we need to close and reopen one of the window await clickOnTestIdWithText(windowA, 'leftpane-primary-avatar'); // Click on current profile picture await waitForTestIdWithText(windowA, 'copy-button-profile-update', 'Copy'); @@ -97,9 +97,9 @@ test('Check profile picture syncs', async () => { }); test('Check contacts sync', async () => { - const [windowA, windowC] = await openApp(2); + const [windowA, windowC] = await openApp(2); // not using sessionTest here as we need to close and reopen one of the window const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowC, 'Bob')]); - const [windowB] = await linkedDevice(userA.recoveryPhrase); + const [windowB] = await linkedDevice(userA.recoveryPhrase); // not using sessionTest here as we need to close and reopen one of the window // Waiting for linked device to finish loading await waitForLoadingAnimationToFinish(windowB, 'loading-spinner'); await createContact(windowA, windowC, userA, userB); diff --git a/ts/test/automation/message_checks.spec.ts b/ts/test/automation/message_checks.spec.ts index 7e8596e0b..fe254cc32 100644 --- a/ts/test/automation/message_checks.spec.ts +++ b/ts/test/automation/message_checks.spec.ts @@ -1,8 +1,6 @@ -import { test } from '@playwright/test'; import { sleepFor } from '../../session/utils/Promise'; -import { beforeAllClean } from './setup/beforeEach'; import { newUser } from './setup/new_user'; -import { openApp } from './setup/open'; +import { sessionTestTwoWindows } from './setup/sessionTest'; import { createContact } from './utilities/create_contact'; import { sendMessage } from './utilities/message'; import { replyTo } from './utilities/reply_message'; @@ -18,10 +16,7 @@ import { waitForTextMessage, } from './utilities/utils'; -test.beforeEach(beforeAllClean); - -test('Send image and reply test', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Send image and reply test', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const testMessage = `${userA.userName} sending image to ${userB.userName}`; const testReply = `${userB.userName} replying to image from ${userA.userName}`; @@ -41,8 +36,7 @@ test('Send image and reply test', async () => { await replyTo(windowB, testMessage, testReply); }); -test('Send video and reply test', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Send video and reply test', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const testMessage = `${userA.userName} sending video to ${userB.userName}`; const testReply = `${userB.userName} replying to video from ${userA.userName}`; @@ -61,8 +55,7 @@ test('Send video and reply test', async () => { await replyTo(windowB, testMessage, testReply); }); -test('Send document and reply test', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Send document and reply test', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const testMessage = `${userA.userName} sending document to ${userB.userName}`; const testReply = `${userB.userName} replying to document from ${userA.userName}`; @@ -81,8 +74,7 @@ test('Send document and reply test', async () => { await replyTo(windowB, testMessage, testReply); }); -test('Send voice message and reply test', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Send voice message and reply test', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); // const testReply = `${userB.userName} to ${userA.userName}`; await createContact(windowA, windowB, userA, userB); @@ -101,8 +93,7 @@ test('Send voice message and reply test', async () => { await clickOnTestIdWithText(windowB, 'session-confirm-ok-button'); }); -test('Send GIF and reply test', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Send GIF and reply test', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); // const testReply = `${userB.userName} to ${userA.userName}`; await createContact(windowA, windowB, userA, userB); @@ -114,8 +105,7 @@ test('Send GIF and reply test', async () => { await clickOnMatchingText(windowB, 'Click to download media'); }); -test('Send long text and reply test', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Send long text and reply test', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const testReply = `${userB.userName} replying to long text message from ${userA.userName}`; @@ -131,8 +121,7 @@ test('Send long text and reply test', async () => { await replyTo(windowB, longText, testReply); }); -test('Unsend text message', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Unsend text message', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const unsendMessage = 'Testing unsend functionality'; await createContact(windowA, windowB, userA, userB); @@ -147,8 +136,7 @@ test('Unsend text message', async () => { await waitForMatchingText(windowB, 'This message has been deleted'); }); -test('Delete message', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Delete message', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const deletedMessage = 'Testing deletion functionality'; await createContact(windowA, windowB, userA, userB); @@ -164,8 +152,7 @@ test('Delete message', async () => { }); // *************** NEED TO WAIT FOR LINK PREVIEW FIX ************************************************* -// test('Send link and reply test', async () => { -// const [windowA, windowB] = await openApp(2); +// sessionTestTwoWindows('Send link and reply test', async ([windowA, windowB]) => { // const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); // const testMessage = 'https://nerdlegame.com/'; // const testReply = `${userB.userName} replying to link from ${userA.userName}`; diff --git a/ts/test/automation/message_requests.spec.ts b/ts/test/automation/message_requests.spec.ts index 2cc277b59..a9a0cd104 100644 --- a/ts/test/automation/message_requests.spec.ts +++ b/ts/test/automation/message_requests.spec.ts @@ -1,7 +1,6 @@ import { test } from '@playwright/test'; import { beforeAllClean } from './setup/beforeEach'; import { newUser } from './setup/new_user'; -import { openApp } from './setup/open'; import { sendMessage } from './utilities/message'; import { sendNewMessage } from './utilities/send_message'; import { @@ -10,14 +9,14 @@ import { waitForMatchingText, waitForTestIdWithText, } from './utilities/utils'; +import { sessionTestTwoWindows } from './setup/sessionTest'; test.beforeEach(beforeAllClean); // test.afterEach(() => forceCloseAllWindows(windows)); // Open two windows and log into 2 separate accounts test.describe('Message requests', () => { - test('Message requests accept', async () => { - const [windowA, windowB] = await openApp(2); + sessionTestTwoWindows('Message requests accept', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const testMessage = `Sender: ${userA.userName} Receiver: ${userB.userName}`; // send a message to User B from User A @@ -36,8 +35,7 @@ test.describe('Message requests', () => { ); await waitForMatchingText(windowB, 'No pending message requests'); }); - test('Message requests text reply', async () => { - const [windowA, windowB] = await openApp(2); + sessionTestTwoWindows('Message requests text reply', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const testMessage = `Sender: ${userA.userName}, Receiver: ${userB.userName}`; const testReply = `Sender: ${userB.userName}, Receiver: ${userA.userName}`; @@ -57,8 +55,7 @@ test.describe('Message requests', () => { ); await waitForMatchingText(windowB, 'No pending message requests'); }); - test('Message requests decline', async () => { - const [windowA, windowB] = await openApp(2); + sessionTestTwoWindows('Message requests decline', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const testMessage = `Sender: ${userA.userName}, Receiver: ${userB.userName}`; // send a message to User B from User A @@ -72,11 +69,9 @@ test.describe('Message requests', () => { // Confirm decline await clickOnTestIdWithText(windowB, 'session-confirm-ok-button', 'Decline'); // Check config message of message request acceptance - await waitForTestIdWithText(windowB, 'session-toast', 'Blocked'); await waitForMatchingText(windowB, 'No pending message requests'); }); - test('Message requests clear all', async () => { - const [windowA, windowB] = await openApp(2); + sessionTestTwoWindows('Message requests clear all', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const testMessage = `Sender: ${userA.userName}, Receiver: ${userB.userName}`; // send a message to User B from User A diff --git a/ts/test/automation/password.spec.ts b/ts/test/automation/password.spec.ts index 55e6fe160..6aef1a791 100644 --- a/ts/test/automation/password.spec.ts +++ b/ts/test/automation/password.spec.ts @@ -1,8 +1,6 @@ -import { Page, test } from '@playwright/test'; import { sleepFor } from '../../session/utils/Promise'; -import { beforeAllClean } from './setup/beforeEach'; import { newUser } from './setup/new_user'; -import { openAppAndWait } from './setup/open'; +import { sessionTestOneWindow } from './setup/sessionTest'; import { clickOnMatchingText, clickOnTestIdWithText, @@ -10,17 +8,12 @@ import { waitForMatchingText, waitForTestIdWithText, } from './utilities/utils'; -let window: Page | undefined; // tslint:disable: no-console -test.beforeEach(beforeAllClean); - const testPassword = '123456'; const newTestPassword = '789101112'; -test('Set Password', async () => { - // open Electron - window = await openAppAndWait('1'); +sessionTestOneWindow('Set Password', async ([window]) => { // Create user await newUser(window, 'userA'); // Click on settings tab @@ -73,9 +66,8 @@ test('Set Password', async () => { ); }); -test('Wrong password', async () => { +sessionTestOneWindow('Wrong password', async ([window]) => { // Check if incorrect password works - window = await openAppAndWait('1'); // Create user await newUser(window, 'userA'); // Click on settings tab diff --git a/ts/test/automation/setup/new_user.ts b/ts/test/automation/setup/new_user.ts index 026a34cc1..e57cebba1 100644 --- a/ts/test/automation/setup/new_user.ts +++ b/ts/test/automation/setup/new_user.ts @@ -21,30 +21,3 @@ export const newUser = async (window: Page, userName: string): Promise => await window.click('.session-icon-button.small'); return { userName, sessionid, recoveryPhrase }; }; - -// const openAppAndNewUser = async (multi: string): Promise => { -// const window = await openAppAndWait(multi); - -// const userName = `${multi}-user`; -// const loggedIn = await newUser(window, userName); -// return { window, ...loggedIn }; -// }; - -// export async function openAppsAndNewUsers(windowToCreate: number) { -// if (windowToCreate >= multisAvailable.length) { -// throw new Error(`Do you really need ${multisAvailable.length} windows?!`); -// } -// // if windowToCreate = 3, this array will be ABC. If windowToCreate = 5, this array will be ABCDE -// const multisToUse = multisAvailable.slice(0, windowToCreate); -// const loggedInDetails = await Promise.all( -// [...multisToUse].map(async m => { -// return openAppAndNewUser(m); -// }) -// ); - -// const windows = loggedInDetails.map(w => w.window); -// const users = loggedInDetails.map(w => { -// return _.pick(w, ['sessionid', 'recoveryPhrase', 'userName']); -// }); -// return { windows, users }; -// } diff --git a/ts/test/automation/setup/open.ts b/ts/test/automation/setup/open.ts index 756affb89..61f380d63 100644 --- a/ts/test/automation/setup/open.ts +++ b/ts/test/automation/setup/open.ts @@ -32,7 +32,7 @@ export const openElectronAppOnly = async (multi: string) => { return electronApp; }; -export const openAppAndWait = async (multi: string) => { +const openAppAndWait = async (multi: string) => { const electronApp = await openElectronAppOnly(multi); // Get the first window that the app opens, wait if necessary. const window = await electronApp.firstWindow(); diff --git a/ts/test/automation/setup/sessionTest.ts b/ts/test/automation/setup/sessionTest.ts new file mode 100644 index 000000000..afba32320 --- /dev/null +++ b/ts/test/automation/setup/sessionTest.ts @@ -0,0 +1,81 @@ +import { Page, test } from '@playwright/test'; +import { beforeAllClean, forceCloseAllWindows } from './beforeEach'; +import { openApp } from './open'; + +// This is not ideal, most of our test needs to open a specific number of windows and close them once the test is done or failed. +// This file contains a bunch of utility function to use to open those windows and clean them afterwards. +// Note: those function only keep track (and close) the windows they open. If you open a new window or need to close and reopen an existing one, this won't take of it. + +type Tuple = N extends N + ? number extends N + ? T[] + : _TupleOf + : never; +type _TupleOf = R['length'] extends N + ? R + : _TupleOf; + +type CountWindows = 1 | 2 | 3 | 4 | 5; + +async function sessionTest>( + testName: string, + testCallback: (windows: N) => Promise, + count: T +) { + return test(testName, async () => { + beforeAllClean(); + const windows = await openApp(count); + + try { + if (windows.length !== count) { + throw new Error(`openApp should have opened ${count} windows but did not.`); + } + await testCallback(windows as N); + } catch (e) { + throw e; + } finally { + try { + await forceCloseAllWindows(windows); + } catch (e) { + console.error(`forceCloseAllWindows of ${testName} failed with: `, e); + } + } + }); +} + +export async function sessionTestOneWindow( + testName: string, + testCallback: (windows: Tuple) => Promise +) { + return sessionTest(testName, testCallback, 1); +} + +export async function sessionTestTwoWindows( + testName: string, + testCallback: ([windowA, windowB]: [Page, Page]) => Promise +) { + return sessionTest(testName, testCallback, 2); +} + +export async function sessionTestThreeWindows( + testName: string, + testCallback: ([windowA, windowB, windowC]: [Page, Page, Page]) => Promise +) { + return sessionTest(testName, testCallback, 3); +} + +export async function sessionTestFourWindows( + testName: string, + testCallback: ([windowA, windowB, windowC, windowD]: [Page, Page, Page, Page]) => Promise +) { + return sessionTest(testName, testCallback, 4); +} + +export async function sessionTestFiveWindows( + testName: string, + testCallback: ([windowA, windowB, windowC, windowD]: [Page, Page, Page, Page, Page]) => Promise< + void + > +) { + return sessionTest(testName, testCallback, 5); +} diff --git a/ts/test/automation/switching_theme.spec.ts b/ts/test/automation/switching_theme.spec.ts index 6ff483870..5627d9643 100644 --- a/ts/test/automation/switching_theme.spec.ts +++ b/ts/test/automation/switching_theme.spec.ts @@ -1,16 +1,9 @@ -import { expect, test } from '@playwright/test'; -import { beforeAllClean } from './setup/beforeEach'; +import { expect } from '@playwright/test'; import { newUser } from './setup/new_user'; -import { openApp } from './setup/open'; import { clickOnTestIdWithText } from './utilities/utils'; +import { sessionTestOneWindow } from './setup/sessionTest'; -test.beforeEach(beforeAllClean); - -// test.afterEach(() => forceCloseAllWindows(windows)); - -test('Switch themes', async () => { - // Open App - const [windowA] = await openApp(1); +sessionTestOneWindow('Switch themes', async ([windowA]) => { // Create User await newUser(windowA, 'Alice'); // Check light theme colour is correct diff --git a/ts/test/automation/test.spec.ts b/ts/test/automation/test.spec.ts index c501c3ee8..4910014be 100644 --- a/ts/test/automation/test.spec.ts +++ b/ts/test/automation/test.spec.ts @@ -1,11 +1,6 @@ -import { test } from '@playwright/test'; -import { beforeAllClean } from './setup/beforeEach'; -import { openApp } from './setup/open'; import { clickOnMatchingText } from './utilities/utils'; +import { sessionTestOneWindow } from './setup/sessionTest'; -test.beforeEach(beforeAllClean); - -test('Tiny test', async () => { - const [windowA] = await openApp(1); +sessionTestOneWindow('Tiny test', async ([windowA]) => { await clickOnMatchingText(windowA, 'Create Session ID'); }); diff --git a/ts/test/automation/to do b/ts/test/automation/to do deleted file mode 100644 index 8337712ea..000000000 --- a/ts/test/automation/to do +++ /dev/null @@ -1 +0,0 @@ -// diff --git a/ts/test/automation/user_actions.spec.ts b/ts/test/automation/user_actions.spec.ts index babd5d5ca..d26476440 100644 --- a/ts/test/automation/user_actions.spec.ts +++ b/ts/test/automation/user_actions.spec.ts @@ -1,7 +1,7 @@ -import { expect, test } from '@playwright/test'; -import { beforeAllClean } from './setup/beforeEach'; +import { expect } from '@playwright/test'; import { sleepFor } from '../../session/utils/Promise'; import { newUser } from './setup/new_user'; +import { createContact } from './utilities/create_contact'; import { sendNewMessage } from './utilities/send_message'; import { clickOnMatchingText, @@ -11,16 +11,10 @@ import { waitForMatchingText, waitForTestIdWithText, } from './utilities/utils'; -import { openApp } from './setup/open'; -import { createContact } from './utilities/create_contact'; - -test.beforeEach(beforeAllClean); - -// test.afterEach(() => forceCloseAllWindows(windows)); +import { sessionTestOneWindow, sessionTestTwoWindows } from './setup/sessionTest'; // Send message in one to one conversation with new contact -test('Create contact', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Create contact', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const testMessage = `${userA.userName} to ${userB.userName}`; @@ -39,9 +33,8 @@ test('Create contact', async () => { await clickOnTestIdWithText(windowA, 'new-conversation-button'); }); -test('Block user in conversation options', async () => { +sessionTestTwoWindows('Block user in conversation options', async ([windowA, windowB]) => { // Open app and create user - const [windowA, windowB] = await openApp(2); const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const testMessage = `${userA.userName} to ${userB.userName}`; @@ -77,9 +70,8 @@ test('Block user in conversation options', async () => { await waitForMatchingText(windowA, 'No blocked contacts'); }); -test('Block user in conversation list', async () => { +sessionTestTwoWindows('Block user in conversation list', async ([windowA, windowB]) => { // Open app and create user - const [windowA, windowB] = await openApp(2); const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const testMessage = `${userA.userName} to ${userB.userName}`; @@ -119,10 +111,7 @@ test('Block user in conversation list', async () => { await waitForTestIdWithText(windowA, 'session-toast', 'Unblocked'); await waitForMatchingText(windowA, 'No blocked contacts'); }); - -test('Change username', async () => { - // Open App - const [window] = await openApp(1); +sessionTestOneWindow('Change username', async ([window]) => { // Create user const newUsername = 'Tiny bubble'; await newUser(window, 'Alice'); @@ -143,8 +132,7 @@ test('Change username', async () => { await window.click('.session-icon-button.small'); }); -test('Change avatar', async () => { - const [window] = await openApp(1); +sessionTestOneWindow('Change avatar', async ([window]) => { await newUser(window, 'Alice'); // Open profile await clickOnTestIdWithText(window, 'leftpane-primary-avatar'); @@ -168,8 +156,7 @@ test('Change avatar', async () => { expect(screenshot).toMatchSnapshot({ name: 'avatar-updated-blue.jpeg' }); }); -test('Set nickname', async () => { - const [windowA, windowB] = await openApp(2); +sessionTestTwoWindows('Set nickname', async ([windowA, windowB]) => { const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]); const nickname = 'new nickname for Bob'; diff --git a/ts/test/automation/utilities/linked_device.ts b/ts/test/automation/utilities/linked_device.ts index 4af36e8dc..2db8d7165 100644 --- a/ts/test/automation/utilities/linked_device.ts +++ b/ts/test/automation/utilities/linked_device.ts @@ -3,7 +3,7 @@ import { logIn } from '../setup/log_in'; import { openApp } from '../setup/open'; export async function linkedDevice(recoveryPhrase: string) { - const [windowB] = await openApp(1); + const [windowB] = await openApp(1); // not using sessionTest here as we need to close and reopen one of the window await logIn(windowB, recoveryPhrase); diff --git a/ts/test/automation/utilities/utils.ts b/ts/test/automation/utilities/utils.ts index a85805158..93c3ae00c 100644 --- a/ts/test/automation/utilities/utils.ts +++ b/ts/test/automation/utilities/utils.ts @@ -79,8 +79,8 @@ export async function waitForLoadingAnimationToFinish( do { try { loadingAnimation = await waitForElement(window, 'data-testid', `${loader}`, 100); - await sleepFor(100); - console.info('loading-animation was found, waiting for it to be gone'); + await sleepFor(500); + console.info(`${loader} was found, waiting for it to be gone`); } catch (e) { loadingAnimation = undefined; }