Adding tests set nickname, call checks, change profile picture on linked device and unsend message check. Adding into data-testids for aforementioned tests and cleaning up typings

pull/2786/head
Emily 2 years ago
parent eeb6cfb435
commit 9e3a569fac

@ -4,6 +4,7 @@ export interface FlexProps {
children?: any;
className?: string;
container?: boolean;
dataTestId?: string;
/****** Container Props ********/
flexDirection?: 'row' | 'column';
justifyContent?:

@ -283,6 +283,7 @@ export const HangUpButton = ({ isFullScreen }: { isFullScreen: boolean }) => {
borderRadius="50%"
onClick={handleEndCall}
margin="10px"
dataTestId="end-call"
/>
</StyledCallActionButton>
);

@ -255,6 +255,7 @@ const CallButton = () => {
onClick={() => {
void callRecipient(selectedConvoKey, canCall);
}}
dataTestId="call-button"
/>
);
};

@ -67,6 +67,7 @@ export const SessionNicknameDialog = (props: Props) => {
onKeyUp={e => {
void onNicknameInput(_.cloneDeep(e));
}}
data-testid="nickname-input"
/>
<div className="session-modal__button-group">
@ -74,6 +75,7 @@ export const SessionNicknameDialog = (props: Props) => {
text={window.i18n('ok')}
buttonType={SessionButtonType.Simple}
onClick={saveNickname}
dataTestId="confirm-nickname"
/>
<SessionButton
text={window.i18n('cancel')}

@ -86,6 +86,7 @@ const SessionIconButtonInner = React.forwardRef<HTMLDivElement, SProps>((props,
backgroundColor={backgroundColor}
borderRadius={borderRadius}
iconPadding={iconPadding}
data-testid={dataTestId}
/>
{Boolean(notificationCount) && <SessionNotificationCount count={notificationCount} />}
</StyledSessionIconButton>

@ -208,6 +208,7 @@ export const SignInTab = () => {
pointerEvents: 'all',
backgroundColor: 'var(--background-primary-color)',
}}
dataTestId="three-dot-loading-animation"
>
<SessionSpinner loading={true} />
</Flex>

@ -74,7 +74,7 @@ export const SettingsCategoryPermissions = (props: { hasPassword: boolean | null
title={window.i18n('callMediaPermissionsTitle')}
description={window.i18n('callMediaPermissionsDescription')}
active={Boolean(window.getCallMediaPermissions())}
data-dataTestId="enable-calls"
dataTestId="enable-calls"
/>
<SessionToggleWithDescription
onClickToggle={async () => {

@ -0,0 +1,27 @@
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';
test('Voice calls', async () => {
const [windowA, windowB] = await openApp(2);
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]);
await createContact(windowA, windowB, userA, userB);
await clickOnTestIdWithText(windowA, 'call-button');
await clickOnTestIdWithText(windowA, 'session-toast');
await clickOnTestIdWithText(windowA, 'enable-calls');
await clickOnTestIdWithText(windowA, 'session-confirm-ok-button');
await clickOnTestIdWithText(windowA, 'message-section');
await clickOnTestIdWithText(windowA, 'module-conversation__user__profile-name', userB.userName);
await clickOnTestIdWithText(windowA, 'call-button');
// Enable calls in window B
await clickOnTestIdWithText(windowB, 'session-toast');
await clickOnTestIdWithText(windowB, 'enable-calls');
await clickOnTestIdWithText(windowB, 'session-confirm-ok-button');
await clickOnMatchingText(windowB, 'Accept');
await sleepFor(5000);
await clickOnTestIdWithText(windowA, 'end-call');
});

@ -1,8 +1,10 @@
import { expect, test } from '@playwright/test';
import { beforeAllClean } from './setup/beforeEach';
import {
clickOnElement,
clickOnMatchingText,
clickOnTestIdWithText,
doesTextIncludeString,
typeIntoInput,
waitForControlMessageWithText,
waitForMatchingText,
@ -15,6 +17,7 @@ import { newUser } from './setup/new_user';
import { leaveGroup } from './utilities/leave_group';
import { openApp } from './setup/open';
import { sleepFor } from '../../session/utils/Promise';
import { createContact } from './utilities/create_contact';
test.beforeEach(beforeAllClean);
@ -28,8 +31,8 @@ test('Create group', async () => {
newUser(windowB, 'Bob'),
newUser(windowC, 'Chloe'),
]);
const testGroupName = 'Tiny Bubble Gang';
await createGroup(testGroupName, userA, windowA, userB, windowB, userC, windowC);
await createGroup('Tiny Bubble Gang', userA, windowA, userB, windowB, userC, windowC);
// Check config messages in all windows
await sleepFor(1000);
// await waitForTestIdWithText(windowA, 'control-message');
@ -49,6 +52,48 @@ test('Create group', async () => {
]);
});
test('Add contact to group', async () => {
const [windowA, windowB, windowC, windowD] = await openApp(4);
const [userA, userB, userC, userD] = await Promise.all([
newUser(windowA, 'Alice'),
newUser(windowB, 'Bob'),
newUser(windowC, 'Chloe'),
newUser(windowD, 'Dracula'),
]);
const testGroup = await createGroup(
'Tiny Bubble Gang',
userA,
windowA,
userB,
windowB,
userC,
windowC
);
// Check config messages in all windows
await sleepFor(1000);
await createContact(windowA, windowD, userA, userD);
await clickOnTestIdWithText(
windowA,
'module-conversation__user__profile-name',
testGroup.userName
);
await clickOnElement(windowA, 'data-testid', 'conversation-options-avatar');
await clickOnElement(windowA, 'data-testid', 'add-user-button');
// Waiting for animation of right panel to appear
await sleepFor(1000);
await clickOnMatchingText(windowA, userD.userName);
await clickOnMatchingText(windowA, 'OK');
await waitForControlMessageWithText(windowA, `"${userD.userName}" joined the group.`);
await waitForControlMessageWithText(windowB, `${userD.sessionid} joined the group.`);
await waitForControlMessageWithText(windowC, `${userD.sessionid} joined the group.`);
await clickOnTestIdWithText(
windowD,
'module-conversation__user__profile-name',
testGroup.userName
);
await doesTextIncludeString(windowD, 'control-message', 'You joined the group.');
});
test('Change group name', async () => {
const [windowA, windowB, windowC] = await openApp(3);
const [userA, userB, userC] = await Promise.all([
@ -56,9 +101,16 @@ test('Change group name', async () => {
newUser(windowB, 'Bob'),
newUser(windowC, 'Chloe'),
]);
const testGroupName = 'Tiny Bubble Gang';
const newGroupName = 'Otter lovers';
const group = await createGroup(testGroupName, userA, windowA, userB, windowB, userC, windowC);
const group = await createGroup(
'Tiny Bubble Gang',
userA,
windowA,
userB,
windowB,
userC,
windowC
);
// Change the name of the group and check that it syncs to all devices (config messages)
// Click on already created group
// Check that renaming a group is working
@ -85,8 +137,15 @@ test('Test mentions', async () => {
newUser(windowB, 'Bob'),
newUser(windowC, 'Chloe'),
]);
const testGroupName = 'Tiny Bubble Gang';
const group = await createGroup(testGroupName, userA, windowA, userB, windowB, userC, windowC);
const group = await createGroup(
'Tiny Bubble Gang',
userA,
windowA,
userB,
windowB,
userC,
windowC
);
// in windowA we should be able to mentions userB and userC
@ -121,8 +180,7 @@ test('Leave group', async () => {
newUser(windowB, 'Bob'),
newUser(windowC, 'Chloe'),
]);
const testGroupName = 'Tiny Bubble Gang';
await createGroup(testGroupName, userA, windowA, userB, windowB, userC, windowC);
await createGroup('Tiny Bubble Gang', userA, windowA, userB, windowB, userC, windowC);
await leaveGroup(windowC);
});

@ -0,0 +1,70 @@
import { test } from '@playwright/test';
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 { leaveGroup } from './utilities/leave_group';
import { linkedDevice } from './utilities/linked_device';
import {
clickOnTestIdWithText,
waitForControlMessageWithText,
waitForTestIdWithText,
} from './utilities/utils';
test.beforeEach(beforeAllClean);
test('Check group syncs', async () => {
const [windowA, windowC, windowD] = await openApp(3);
const [userA, userB, userC] = await Promise.all([
newUser(windowA, 'Alice'),
newUser(windowC, 'Bob'),
newUser(windowD, 'Chloe'),
]);
const [windowB] = await linkedDevice(userA.recoveryPhrase);
const group = await createGroup(
'Tiny Bubble Gang',
userA,
windowA,
userB,
windowC,
userC,
windowD
);
// Check group conversation is in conversation list
await waitForTestIdWithText(windowB, 'module-conversation__user__profile-name', group.userName);
});
test('Check leaving group syncs', async () => {
const [windowA, windowC, windowD] = await openApp(3);
const [userA, userB, userC] = await Promise.all([
newUser(windowA, 'Alice'),
newUser(windowC, 'Bob'),
newUser(windowD, 'Chloe'),
]);
const [windowB] = await linkedDevice(userA.recoveryPhrase);
const group = await createGroup(
'Tiny Bubble Gang',
userA,
windowA,
userB,
windowC,
userC,
windowD
);
// Check group conversation is in conversation list
await waitForTestIdWithText(windowB, 'module-conversation__user__profile-name', group.userName);
// User C to leave group
await leaveGroup(windowD);
// Check for user A
await sleepFor(1000);
await clickOnTestIdWithText(windowA, 'module-conversation__user__profile-name', group.userName);
await waitForControlMessageWithText(windowA, `"${userC.userName}" has left the group.`);
// Check for linked device (userA)
await clickOnTestIdWithText(windowB, 'module-conversation__user__profile-name', group.userName);
await waitForControlMessageWithText(windowB, `"${userC.userName}" has left the group.`);
// Check for user B
await waitForControlMessageWithText(windowC, `"${userC.userName}" has left the group.`);
});

@ -0,0 +1,62 @@
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 { linkedDevice } from './utilities/linked_device';
import { sendMessage } from './utilities/message';
import { sendNewMessage } from './utilities/send_message';
import {
clickOnTestIdWithText,
waitForMatchingText,
waitForTestIdWithText,
waitForTextMessage,
} from './utilities/utils';
test.beforeEach(beforeAllClean);
test('Accept request syncs', async () => {
const [windowA, windowB] = await openApp(2);
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]);
const [windowC] = await linkedDevice(userB.recoveryPhrase);
const testMessage = `${userA.userName} sending message request to ${userB.userName}`;
const testReply = `${userB.userName} accepting message request from ${userA.userName}`;
await sendNewMessage(windowA, userB.sessionid, testMessage);
// Accept request in windowB
await clickOnTestIdWithText(windowB, 'message-request-banner');
await clickOnTestIdWithText(windowC, 'message-request-banner');
await clickOnTestIdWithText(windowB, 'module-conversation__user__profile-name', userA.userName);
await clickOnTestIdWithText(windowB, 'accept-message-request');
await waitForTestIdWithText(
windowB,
'control-message',
`You have accepted ${userA.userName}'s message request`
);
await waitForMatchingText(windowB, 'No pending message requests');
await waitForMatchingText(windowC, 'No pending message requests');
await sendMessage(windowB, testReply);
await waitForTextMessage(windowA, testReply);
await clickOnTestIdWithText(windowC, 'new-conversation-button');
await waitForTestIdWithText(windowC, 'module-conversation__user__profile-name', userA.userName);
});
test('Decline request syncs', async () => {
const [windowA, windowB] = await openApp(2);
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]);
const [windowC] = await linkedDevice(userB.recoveryPhrase);
const testMessage = `${userA.userName} sending message request to ${userB.userName}`;
await sendNewMessage(windowA, userB.sessionid, testMessage);
// Accept request in windowB
await clickOnTestIdWithText(windowB, 'message-request-banner');
await clickOnTestIdWithText(windowB, 'module-conversation__user__profile-name', userA.userName);
await clickOnTestIdWithText(windowC, 'message-request-banner');
await waitForTestIdWithText(windowC, 'module-conversation__user__profile-name', userA.userName);
await clickOnTestIdWithText(windowB, 'decline-message-request');
await clickOnTestIdWithText(windowB, 'session-confirm-ok-button', 'Decline');
await waitForTestIdWithText(windowB, 'session-toast', 'Blocked');
await waitForMatchingText(windowB, 'No pending message requests');
await waitForMatchingText(windowC, 'No pending message requests');
});

@ -1,9 +1,22 @@
import { _electron, Page, test } from '@playwright/test';
import { expect, Page, test } from '@playwright/test';
import { sleepFor } from '../../session/utils/Promise';
import { beforeAllClean, forceCloseAllWindows } from './setup/beforeEach';
import { newUser } from './setup/new_user';
import { openApp } from './setup/open';
import { createContact } from './utilities/create_contact';
import { linkedDevice } from './utilities/linked_device';
import { clickOnTestIdWithText, typeIntoInput, waitForTestIdWithText } from './utilities/utils';
import { sendMessage } from './utilities/message';
import {
clickOnElement,
clickOnMatchingText,
clickOnTestIdWithText,
hasTextElementBeenDeleted,
typeIntoInput,
waitForLoadingAnimationToFinish,
waitForMatchingText,
waitForTestIdWithText,
waitForTextMessage,
} from './utilities/utils';
const windows: Array<Page> = [];
test.beforeEach(beforeAllClean);
@ -15,7 +28,6 @@ test('Link a device', async () => {
const [windowA] = await openApp(1);
const userA = await newUser(windowA, 'Alice');
const [windowB] = await linkedDevice(userA.recoveryPhrase);
const newUsername = 'Tiny bubble';
await clickOnTestIdWithText(windowA, 'leftpane-primary-avatar');
// Verify Username
await waitForTestIdWithText(windowA, 'your-profile-name', userA.userName);
@ -28,7 +40,7 @@ test('Link a device', async () => {
try {
const elemShouldNotBeFound = windowB.locator('[data-testid=reveal-recovery-phrase]');
if (elemShouldNotBeFound) {
console.error('Element not found');
console.error('Continue to save recovery phrase not found, excellent news');
throw new Error(errorDesc);
}
} catch (e) {
@ -37,18 +49,130 @@ test('Link a device', async () => {
throw e;
}
}
});
test('Check changed username syncs', async () => {
const [windowA] = await openApp(1);
const userA = await newUser(windowA, 'Alice');
const [windowB] = await linkedDevice(userA.recoveryPhrase);
const newUsername = 'Tiny bubble';
await clickOnTestIdWithText(windowA, 'leftpane-primary-avatar');
// Click on pencil icon
await clickOnTestIdWithText(windowA, 'edit-profile-icon');
// Replace old username with new username
await typeIntoInput(windowA, 'profile-name-input', newUsername);
// Press enter to confirm change
await windowA.keyboard.press('Enter');
await clickOnElement(windowA, 'data-testid', 'save-button-profile-update');
// Wait for loading animation
// Check username change in window B2
// Check username change in window B
// Click on profile settings in window B
await clickOnTestIdWithText(windowB, 'leftpane-primary-avatar');
// Verify username has changed to new username
await waitForTestIdWithText(windowB, 'your-profile-name', newUsername);
// Check message is deleting on both devices
});
test('Check profile picture syncs', async () => {
const [windowA] = await openApp(1);
const userA = await newUser(windowA, 'Alice');
const [windowB] = await linkedDevice(userA.recoveryPhrase);
await clickOnTestIdWithText(windowA, 'leftpane-primary-avatar');
// Click on current profile picture
await waitForTestIdWithText(windowA, 'copy-button-profile-update', 'Copy');
await clickOnTestIdWithText(windowA, 'image-upload-section');
await clickOnTestIdWithText(windowA, 'save-button-profile-update');
await waitForTestIdWithText(windowA, 'loading-spinner');
await waitForTestIdWithText(windowA, 'copy-button-profile-update', 'Copy');
await clickOnTestIdWithText(windowA, 'modal-close-button');
await sleepFor(500);
const leftpaneAvatarContainer = await waitForTestIdWithText(windowB, 'leftpane-primary-avatar');
await sleepFor(500);
const screenshot = await leftpaneAvatarContainer.screenshot({
type: 'jpeg',
// path: 'avatar-updated-blue',
});
expect(screenshot).toMatchSnapshot({ name: 'avatar-updated-blue.jpeg' });
});
test('Check contacts sync', async () => {
const [windowA, windowC] = await openApp(2);
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowC, 'Bob')]);
const [windowB] = await linkedDevice(userA.recoveryPhrase);
// Waiting for linked device to finish loading
await waitForLoadingAnimationToFinish(windowB, 'loading-spinner');
await createContact(windowA, windowC, userA, userB);
// Check linked device (windowB)
await waitForTestIdWithText(windowB, 'module-conversation__user__profile-name', userB.userName);
console.info('Contacts correctly synced');
});
test('Check deleted message syncs', async () => {
const [windowA, windowC] = await openApp(2);
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowC, 'Bob')]);
const [windowB] = await linkedDevice(userA.recoveryPhrase);
const deletedMessage = 'Testing deletion functionality for linked device';
await waitForLoadingAnimationToFinish(windowB, 'loading-spinner');
await createContact(windowA, windowC, userA, userB);
await sendMessage(windowA, deletedMessage);
// Navigate to conversation on linked device and check for message from user A to user B
await clickOnTestIdWithText(windowB, 'module-conversation__user__profile-name', userB.userName);
await waitForTextMessage(windowB, deletedMessage);
await waitForTextMessage(windowC, deletedMessage);
await clickOnTestIdWithText(windowA, 'control-message', deletedMessage, true);
await clickOnMatchingText(windowA, 'Delete just for me');
await clickOnMatchingText(windowA, 'Delete');
await waitForTestIdWithText(windowA, 'session-toast', 'Deleted');
await hasTextElementBeenDeleted(windowA, deletedMessage, 1000);
// Check linked device for deleted message
// Waiting for message to be removed
await sleepFor(5000);
await hasTextElementBeenDeleted(windowB, deletedMessage, 1000);
// Still should exist for user B
await waitForMatchingText(windowC, deletedMessage);
});
test('Check unsent message syncs', async () => {
const [windowA, windowC] = await openApp(2);
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowC, 'Bob')]);
const [windowB] = await linkedDevice(userA.recoveryPhrase);
const unsentMessage = 'Testing unsending functionality for linked device';
await waitForLoadingAnimationToFinish(windowB, 'loading-spinner');
await createContact(windowA, windowC, userA, userB);
await sendMessage(windowA, unsentMessage);
// Navigate to conversation on linked device and check for message from user A to user B
await clickOnTestIdWithText(windowB, 'module-conversation__user__profile-name', userB.userName);
await waitForTextMessage(windowB, unsentMessage);
await waitForTextMessage(windowC, unsentMessage);
await clickOnTestIdWithText(windowA, 'control-message', unsentMessage, true);
await clickOnMatchingText(windowA, 'Delete for everyone');
await clickOnElement(windowA, 'data-testid', 'session-confirm-ok-button');
await waitForTestIdWithText(windowA, 'session-toast', 'Deleted');
await hasTextElementBeenDeleted(windowA, unsentMessage, 1000);
await waitForMatchingText(windowC, 'This message has been deleted');
// Check linked device for deleted message
await hasTextElementBeenDeleted(windowB, unsentMessage, 1000);
});
// test('Check blocked user syncs', async () => {
// const [windowA, windowC] = await openApp(2);
// const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowC, 'Bob')]);
// const [windowB] = await linkedDevice(userA.recoveryPhrase);
// const testMessage = 'Testing blocking functionality for linked device';
// await waitForLoadingAnimationToFinish(windowB, 'loading-spinner');
// await createContact(windowA, windowC, userA, userB);
// await sendMessage(windowA, testMessage);
// // Navigate to conversation on linked device and check for message from user A to user B
// await clickOnTestIdWithText(windowB, 'module-conversation__user__profile-name', userB.userName);
// await clickOnElement(windowA, 'data-testid', 'three-dots-conversation-options');
// await clickOnMatchingText(windowA, 'Block');
// await waitForTestIdWithText(windowA, 'session-toast', 'Blocked');
// await waitForMatchingText(windowA, 'Unblock this contact to send a message.');
// // Check linked device for blocked contact in settings screen
// await clickOnTestIdWithText(windowB, 'settings-section');
// await clickOnTestIdWithText(windowB, 'conversations-settings-menu-item');
// await clickOnTestIdWithText(windowB, 'reveal-blocked-user-settings');
// // Check if user B is in blocked contact list
// await waitForMatchingText(windowB, userB.userName);
// });

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

@ -4,12 +4,18 @@ import { beforeAllClean } from './setup/beforeEach';
import { newUser } from './setup/new_user';
import { openApp } from './setup/open';
import { createContact } from './utilities/create_contact';
import { sendMessage } from './utilities/message';
import { replyTo } from './utilities/reply_message';
import {
clickOnElement,
clickOnMatchingText,
clickOnTestIdWithText,
hasTextElementBeenDeleted,
typeIntoInput,
waitForLoadingAnimationToFinish,
waitForMatchingText,
waitForTestIdWithText,
waitForTextMessage,
} from './utilities/utils';
test.beforeEach(beforeAllClean);
@ -28,7 +34,7 @@ test('Send image and reply test', async () => {
await sleepFor(1000);
await clickOnMatchingText(windowB, 'Click to download media');
await clickOnTestIdWithText(windowB, 'session-confirm-ok-button');
await waitForLoadingAnimationToFinish(windowB);
await waitForLoadingAnimationToFinish(windowB, 'loading-animation');
// Waiting for image to change from loading state to loaded (takes a second)
await sleepFor(1000);
@ -49,7 +55,7 @@ test('Send video and reply test', async () => {
await sleepFor(1000);
await clickOnMatchingText(windowB, 'Click to download media');
await clickOnTestIdWithText(windowB, 'session-confirm-ok-button');
await waitForLoadingAnimationToFinish(windowB);
await waitForLoadingAnimationToFinish(windowB, 'loading-animation');
// Waiting for videoto change from loading state to loaded (takes a second)
await sleepFor(1000);
await replyTo(windowB, testMessage, testReply);
@ -69,9 +75,9 @@ test('Send document and reply test', async () => {
await sleepFor(1000);
await clickOnMatchingText(windowB, 'Click to download media');
await clickOnTestIdWithText(windowB, 'session-confirm-ok-button');
await waitForLoadingAnimationToFinish(windowB);
// Waiting for videoto change from loading state to loaded (takes a second)
await sleepFor(1000);
await waitForLoadingAnimationToFinish(windowB, 'loading-animation');
// Waiting for video to change from loading state to loaded (takes a second)
await sleepFor(500);
await replyTo(windowB, testMessage, testReply);
});
@ -125,22 +131,50 @@ test('Send long text and reply test', async () => {
await replyTo(windowB, longText, testReply);
});
test('Send link and reply test', async () => {
test('Unsend text message', async () => {
const [windowA, windowB] = await openApp(2);
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}`;
const unsendMessage = 'Testing unsend functionality';
await createContact(windowA, windowB, userA, userB);
await typeIntoInput(windowA, 'message-input-text-area', testMessage);
await sleepFor(5000);
await clickOnTestIdWithText(windowA, 'send-message-button');
await sendMessage(windowA, unsendMessage);
await waitForTextMessage(windowB, unsendMessage);
await clickOnTestIdWithText(windowA, 'control-message', unsendMessage, true);
await clickOnMatchingText(windowA, 'Delete for everyone');
await clickOnElement(windowA, 'data-testid', 'session-confirm-ok-button');
await waitForTestIdWithText(windowA, 'session-toast', 'Deleted');
await sleepFor(1000);
await replyTo(windowB, testMessage, testReply);
await waitForMatchingText(windowB, 'This message has been deleted');
});
test('Delete message', async () => {
const [windowA, windowB] = await openApp(2);
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]);
const deletedMessage = 'Testing deletion functionality';
await createContact(windowA, windowB, userA, userB);
await sendMessage(windowA, deletedMessage);
await waitForTextMessage(windowB, deletedMessage);
await clickOnTestIdWithText(windowA, 'control-message', deletedMessage, true);
await clickOnMatchingText(windowA, 'Delete just for me');
await clickOnMatchingText(windowA, 'Delete');
await waitForTestIdWithText(windowA, 'session-toast', 'Deleted');
await hasTextElementBeenDeleted(windowA, deletedMessage, 1000);
// Still should exist in window B
await waitForMatchingText(windowB, deletedMessage);
});
// Send link
// Send long text
// Unsend
// Delete message
// *************** NEED TO WAIT FOR LINK PREVIEW FIX *************************************************
// test('Send link and reply test', async () => {
// const [windowA, windowB] = await openApp(2);
// 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}`;
// await createContact(windowA, windowB, userA, userB);
// await typeIntoInput(windowA, 'message-input-text-area', testMessage);
// await sleepFor(5000);
// await clickOnTestIdWithText(windowA, 'send-message-button');
// await sleepFor(1000);
// await replyTo(windowB, testMessage, testReply);
// });

@ -1,6 +1,6 @@
import { _electron, Page, test } from '@playwright/test';
import { Page, test } from '@playwright/test';
import { sleepFor } from '../../session/utils/Promise';
import { beforeAllClean, forceCloseAllWindows } from './setup/beforeEach';
import { beforeAllClean } from './setup/beforeEach';
import { newUser } from './setup/new_user';
import { openAppAndWait } from './setup/open';
import {
@ -14,121 +14,113 @@ let window: Page | undefined;
test.beforeEach(beforeAllClean);
test.afterEach(async () => {
if (window) {
await forceCloseAllWindows([window]);
}
});
const testPassword = '123456';
const newTestPassword = '789101112';
test.describe('Password checks', () => {
test('Set Password', async () => {
// open Electron
window = await openAppAndWait('1');
// Create user
await newUser(window, 'userA');
// Click on settings tab
await clickOnTestIdWithText(window, 'settings-section');
// Click on privacy
await clickOnTestIdWithText(window, 'privacy-settings-menu-item');
// Click set password
await clickOnTestIdWithText(window, 'set-password-button');
// Enter password
await typeIntoInput(window, 'password-input', testPassword);
// Confirm password
await typeIntoInput(window, 'password-input-confirm', testPassword);
// Click Done
await clickOnMatchingText(window, 'Done');
// Check toast notification
await waitForTestIdWithText(
window,
'session-toast',
'Your password has been set. Please keep it safe.'
);
// Click on settings tab
await sleepFor(300);
await clickOnTestIdWithText(window, 'settings-section');
// Type password into input field
test('Set Password', async () => {
// open Electron
window = await openAppAndWait('1');
// Create user
await newUser(window, 'userA');
// Click on settings tab
await clickOnTestIdWithText(window, 'settings-section');
// Click on privacy
await clickOnTestIdWithText(window, 'privacy-settings-menu-item');
// Click set password
await clickOnTestIdWithText(window, 'set-password-button');
// Enter password
await typeIntoInput(window, 'password-input', testPassword);
// Confirm password
await typeIntoInput(window, 'password-input-confirm', testPassword);
// Click Done
await clickOnMatchingText(window, 'Done');
// Check toast notification
await waitForTestIdWithText(
window,
'session-toast',
'Your password has been set. Please keep it safe.'
);
// Click on settings tab
await sleepFor(300);
await clickOnTestIdWithText(window, 'settings-section');
// Type password into input field
await typeIntoInput(window, 'password-input', testPassword);
await typeIntoInput(window, 'password-input', testPassword);
// Click Done
await clickOnMatchingText(window, 'Done');
await clickOnTestIdWithText(window, 'settings-section');
// Click Done
await clickOnMatchingText(window, 'Done');
await clickOnTestIdWithText(window, 'settings-section');
// Change password
await clickOnTestIdWithText(window, 'change-password-settings-button', 'Change Password');
// Change password
await clickOnTestIdWithText(window, 'change-password-settings-button', 'Change Password');
console.warn('clicked Change Password');
// Enter old password
await typeIntoInput(window, 'password-input', testPassword);
// Enter new password
await typeIntoInput(window, 'password-input-confirm', newTestPassword);
await window.keyboard.press('Tab');
// Confirm new password
await typeIntoInput(window, 'password-input-reconfirm', newTestPassword);
// Press enter on keyboard
await window.keyboard.press('Enter');
// Check toast notification for 'changed password'
await waitForTestIdWithText(
window,
'session-toast',
'Your password has been changed. Please keep it safe.'
);
});
test('Wrong password', async () => {
// Check if incorrect password works
window = await openAppAndWait('1');
// Create user
await newUser(window, 'userA');
// Click on settings tab
await clickOnTestIdWithText(window, 'settings-section');
// Click on privacy
await clickOnMatchingText(window, 'Privacy');
// Click set password
await clickOnMatchingText(window, 'Set Password');
// Enter password
await typeIntoInput(window, 'password-input', testPassword);
// Confirm password
await typeIntoInput(window, 'password-input-confirm', testPassword);
// Click Done
await window.keyboard.press('Enter');
// // Click on settings tab
await sleepFor(100);
await clickOnTestIdWithText(window, 'settings-section');
console.warn('clicked Change Password');
// Enter old password
await typeIntoInput(window, 'password-input', testPassword);
// Enter new password
await typeIntoInput(window, 'password-input-confirm', newTestPassword);
await window.keyboard.press('Tab');
// Confirm new password
await typeIntoInput(window, 'password-input-reconfirm', newTestPassword);
// Press enter on keyboard
await window.keyboard.press('Enter');
// Check toast notification for 'changed password'
await waitForTestIdWithText(
window,
'session-toast',
'Your password has been changed. Please keep it safe.'
);
});
test('Wrong password', async () => {
// Check if incorrect password works
window = await openAppAndWait('1');
// Create user
await newUser(window, 'userA');
// Click on settings tab
await clickOnTestIdWithText(window, 'settings-section');
// Click on privacy
await clickOnMatchingText(window, 'Privacy');
// Click set password
await clickOnMatchingText(window, 'Set Password');
// Enter password
await typeIntoInput(window, 'password-input', testPassword);
// Confirm password
await typeIntoInput(window, 'password-input-confirm', testPassword);
// Click Done
await window.keyboard.press('Enter');
// // Click on settings tab
await sleepFor(100);
await clickOnTestIdWithText(window, 'settings-section');
// Type password into input field
await sleepFor(100);
await typeIntoInput(window, 'password-input', testPassword);
// Click Done
await clickOnMatchingText(window, 'Done');
await sleepFor(100);
await window.mouse.click(0, 0);
await clickOnTestIdWithText(window, 'message-section');
await sleepFor(100);
// Type password into input field
await sleepFor(100);
await typeIntoInput(window, 'password-input', testPassword);
// Click Done
await clickOnMatchingText(window, 'Done');
await sleepFor(100);
await window.mouse.click(0, 0);
await clickOnTestIdWithText(window, 'message-section');
await sleepFor(100);
// // Click on settings tab
await sleepFor(1000);
await clickOnTestIdWithText(window, 'settings-section');
// // Try with incorrect password
await typeIntoInput(window, 'password-input', '000000');
// Confirm
await clickOnMatchingText(window, 'Done');
// // invalid password banner showing?
await waitForMatchingText(window, 'Invalid password');
// // Empty password
// // Navigate away from settings tab
await window.mouse.click(0, 0);
await sleepFor(100);
await clickOnTestIdWithText(window, 'message-section');
await sleepFor(100);
// // Click on settings tab
await clickOnTestIdWithText(window, 'settings-section');
// // No password entered
await clickOnMatchingText(window, 'Done');
// // Banner should ask for password to be entered
await waitForMatchingText(window, 'Enter password');
});
// // Click on settings tab
await sleepFor(1000);
await clickOnTestIdWithText(window, 'settings-section');
// // Try with incorrect password
await typeIntoInput(window, 'password-input', '000000');
// Confirm
await clickOnMatchingText(window, 'Done');
// // invalid password banner showing?
await waitForMatchingText(window, 'Invalid password');
// // Empty password
// // Navigate away from settings tab
await window.mouse.click(0, 0);
await sleepFor(100);
await clickOnTestIdWithText(window, 'message-section');
await sleepFor(100);
// // Click on settings tab
await clickOnTestIdWithText(window, 'settings-section');
// // No password entered
await clickOnMatchingText(window, 'Done');
// // Banner should ask for password to be entered
await waitForMatchingText(window, 'Enter password');
});

@ -1,10 +1,20 @@
import { _electron, Page } from '@playwright/test';
import { clickOnTestIdWithText, typeIntoInput } from '../utilities/utils';
import { Page } from '@playwright/test';
import {
clickOnTestIdWithText,
hasElementPoppedUpThatShouldnt,
typeIntoInput,
waitForLoadingAnimationToFinish,
} from '../utilities/utils';
export async function logIn(window: Page, recoveryPhrase: string) {
await clickOnTestIdWithText(window, 'link-device');
await typeIntoInput(window, 'recovery-phrase-input', recoveryPhrase);
await clickOnTestIdWithText(window, 'continue-session-button');
return { window };
await waitForLoadingAnimationToFinish(window, 'loading-spinner', 5000);
await hasElementPoppedUpThatShouldnt(
window,
'data-testid',
'session-toast',
'Could not find your display name. Please Sign In by Restoring Your Account instead.'
);
}

@ -12,3 +12,5 @@ export type Group = {
};
export type Strategy = 'data-testid' | 'class' | ':has-text';
export type loaderType = 'loading-animation' | 'loading-spinner';

@ -1,38 +0,0 @@
import { test } from '@playwright/test';
import { beforeAllClean } from './setup/beforeEach';
import { newUser } from './setup/new_user';
import { openApp } from './setup/open';
import { sendNewMessage } from './utilities/send_message';
import {
clickOnMatchingText,
clickOnTestIdWithText,
waitForMatchingText,
waitForTestIdWithText,
} from './utilities/utils';
const testMessage = 'A -> B: ';
const testReply = 'B -> A: ';
test.beforeEach(beforeAllClean);
// test.afterEach(() => forceCloseAllWindows(windows));
test('Unsend message', async () => {
// Open App
const [windowA, windowB] = await openApp(2);
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]);
// Send message between two users
await sendNewMessage(windowA, userB.sessionid, `${testMessage}${Date.now()}`);
await sendNewMessage(windowB, userA.sessionid, `${testReply}${Date.now()}`);
// Unsend message from User A to User B
// Right click on message
await windowA.click('.module-message.module-message--outgoing', { button: 'right' });
// Select delete for everyone
await clickOnMatchingText(windowA, 'Delete for everyone');
// Select delete for everyone confirmation
await clickOnTestIdWithText(windowA, 'session-confirm-ok-button', 'Delete for everyone');
// Check that toast notification opens and says 'deleted'
await waitForTestIdWithText(windowA, 'session-toast', 'Deleted');
// Check that message is deleted in receivers window
await waitForMatchingText(windowB, 'This message has been deleted');
});

@ -7,10 +7,12 @@ import {
clickOnMatchingText,
clickOnTestIdWithText,
typeIntoInput,
typeIntoInputSlow,
waitForMatchingText,
waitForTestIdWithText,
} from './utilities/utils';
import { openApp } from './setup/open';
import { createContact } from './utilities/create_contact';
test.beforeEach(beforeAllClean);
@ -75,6 +77,49 @@ test('Block user in conversation options', async () => {
await waitForMatchingText(windowA, 'No blocked contacts');
});
test('Block user in conversation list', async () => {
// 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}`;
const testReply = `${userB.userName} to ${userA.userName}`;
// Create contact and send new message
await sendNewMessage(windowA, userB.sessionid, `${testMessage} Time: '${Date.now()}'`);
await sendNewMessage(windowB, userA.sessionid, `${testReply} Time: '${Date.now()}'`);
// Check to see if User B is a contact
await clickOnTestIdWithText(windowA, 'new-conversation-button');
await waitForTestIdWithText(windowA, 'module-conversation__user__profile-name', userB.userName);
//Click on three dots menu
await clickOnTestIdWithText(windowA, 'message-section');
await clickOnTestIdWithText(
windowA,
'module-conversation__user__profile-name',
userB.userName,
true
);
// Select block
await clickOnMatchingText(windowA, 'Block');
// Verify toast notification 'blocked'
await waitForTestIdWithText(windowA, 'session-toast', 'Blocked');
// Verify the user was moved to the blocked contact list
// Click on settings tab
await clickOnTestIdWithText(windowA, 'settings-section');
// click on settings section 'conversation'
await clickOnTestIdWithText(windowA, 'conversations-settings-menu-item');
// Navigate to blocked users tab'
await clickOnTestIdWithText(windowA, 'reveal-blocked-user-settings');
// select the contact to unblock by clicking on it by name
await clickOnMatchingText(windowA, userB.userName);
// Unblock user by clicking on unblock
await clickOnTestIdWithText(windowA, 'unblock-button-settings-screen');
// Verify toast notification says unblocked
await waitForTestIdWithText(windowA, 'session-toast', 'Unblocked');
await waitForMatchingText(windowA, 'No blocked contacts');
});
test('Change username', async () => {
// Open App
const [window] = await openApp(1);
@ -122,3 +167,31 @@ test('Change avatar', async () => {
});
expect(screenshot).toMatchSnapshot({ name: 'avatar-updated-blue.jpeg' });
});
test('Set nickname', async () => {
const [windowA, windowB] = await openApp(2);
const [userA, userB] = await Promise.all([newUser(windowA, 'Alice'), newUser(windowB, 'Bob')]);
const nickname = 'new nickname for Bob';
await createContact(windowA, windowB, userA, userB);
await sleepFor(100);
await clickOnTestIdWithText(windowA, 'three-dots-conversation-options');
await clickOnMatchingText(windowA, 'Change Nickname');
await sleepFor(1000);
await typeIntoInputSlow(windowA, 'nickname-input', nickname);
await sleepFor(100);
await clickOnTestIdWithText(windowA, 'confirm-nickname', 'OK');
const headerUsername = await waitForTestIdWithText(windowA, 'header-conversation-name');
const headerUsernameText = await headerUsername.innerText();
console.warn('Innertext ', headerUsernameText);
expect(headerUsernameText).toBe(nickname);
// Check conversation list name also
const conversationListUsernameText = await waitForTestIdWithText(
windowA,
'module-conversation__user__profile-name'
);
const conversationListUsername = await conversationListUsernameText.innerText();
expect(conversationListUsername).toBe(nickname);
});

@ -7,9 +7,9 @@ export const createContact = async (windowA: Page, windowB: Page, userA: User, u
const testMessage = `${userA.userName} to ${userB.userName}`;
const testReply = `${userB.userName} to ${userA.userName}`;
// User A sends message to User B
await sendNewMessage(windowA, userB.sessionid, `${testMessage}`);
await sendNewMessage(windowA, userB.sessionid, testMessage);
// User B sends message to User B to USER A
await sendNewMessage(windowB, userA.sessionid, `${testReply}`);
await sendNewMessage(windowB, userA.sessionid, testReply);
await clickOnTestIdWithText(windowA, 'new-conversation-button');
await windowA.waitForTimeout(2000);

@ -1,7 +1,7 @@
import { ElementHandle } from '@playwright/test';
import { Page } from 'playwright-core';
import { sleepFor } from '../../../session/utils/Promise';
import { Strategy } from '../types/testing';
import { loaderType, Strategy } from '../types/testing';
// tslint:disable: no-console
// WAIT FOR FUNCTIONS
@ -37,7 +37,7 @@ export async function waitForElement(
}
export async function waitForTextMessage(window: Page, text: string, maxWait?: number) {
let builtSelector = `:has-text("${text}")`;
let builtSelector = `css=[data-testid=control-message]:has-text("${text}")`;
if (text) {
// " => \\\"
/* prettier-ignore */
@ -49,6 +49,7 @@ export async function waitForTextMessage(window: Page, text: string, maxWait?: n
// console.warn('Text is tiny bubble: ', escapedText);
}
const el = await window.waitForSelector(builtSelector, { timeout: maxWait });
console.info(`Text message found. Text: , ${text}`);
return el;
}
@ -56,31 +57,36 @@ export async function waitForControlMessageWithText(window: Page, text: string)
return waitForTestIdWithText(window, 'control-message', text);
}
export async function waitForMatchingText(window: Page, text: string) {
export async function waitForMatchingText(window: Page, text: string, maxWait?: number) {
const builtSelector = `css=:has-text("${text}")`;
const maxTimeout = maxWait ?? 55000;
console.info(`waitForMatchingText: ${text}`);
await window.waitForSelector(builtSelector, { timeout: 55000 });
await window.waitForSelector(builtSelector, { timeout: maxTimeout });
console.info(`got matchingText: ${text}`);
}
export async function waitForLoadingAnimationToFinish(window: Page) {
export async function waitForLoadingAnimationToFinish(
window: Page,
loader: loaderType,
maxWait?: number
) {
let loadingAnimation: ElementHandle<SVGElement | HTMLElement> | undefined;
await waitForElement(window, 'data-testid', 'loading-animation');
await waitForElement(window, 'data-testid', `${loader}`, maxWait);
do {
try {
loadingAnimation = await waitForElement(window, 'data-testid', 'loading-animation', 100);
loadingAnimation = await waitForElement(window, 'data-testid', `${loader}`, 100);
await sleepFor(100);
console.info('loading-animation was found, waiting for it to be gone');
} catch (e) {
loadingAnimation = undefined;
}
} while (loadingAnimation);
console.info('Loading animation has finished');
}
console.info('Loading animation has finished');
// ACTIONS
@ -124,5 +130,72 @@ export function getMessageTextContentNow() {
export async function typeIntoInput(window: Page, dataTestId: string, text: string) {
console.info(`typeIntoInput testId: ${dataTestId} : "${text}"`);
const builtSelector = `css=[data-testid=${dataTestId}]`;
return window.type(builtSelector, text);
return window.fill(builtSelector, text);
}
export async function typeIntoInputSlow(window: Page, dataTestId: string, text: string) {
console.info(`typeIntoInput testId: ${dataTestId} : "${text}"`);
const builtSelector = `css=[data-testid=${dataTestId}]`;
await window.waitForSelector(builtSelector);
return window.type(builtSelector, text, { delay: 100 });
}
export async function hasTextElementBeenDeleted(window: Page, text: string, maxWait?: number) {
const fakeError = `Matching text: ${text} has been found... oops`;
try {
await waitForMatchingText(window, text, maxWait);
throw new Error(fakeError);
} catch (e) {
if (e.message === fakeError) {
throw e;
}
}
console.info('Element has not been found, congratulations', text);
}
export async function doesTextIncludeString(window: Page, dataTestId: string, text: string) {
const element = await waitForTestIdWithText(window, dataTestId);
const el = await element.innerText();
const builtSelector = el.includes(text);
if (builtSelector) {
console.info('Text found:', text);
} else {
throw new Error(`Text not found: , ${text}`);
}
}
export async function hasElementBeenDeleted(
window: Page,
strategy: Strategy,
selector: string,
maxWait?: number
) {
const fakeError = `Element ${selector} has been found... oops`;
try {
await waitForElement(window, strategy, selector, maxWait);
throw new Error(fakeError);
} catch (e) {
if (e.message === fakeError) {
throw e;
}
}
console.info(`${selector} has not been found, congrats`);
}
export async function hasElementPoppedUpThatShouldnt(
window: Page,
strategy: Strategy,
selector: string,
text?: string
) {
const builtSelector = !text
? `css=[${strategy}=${selector}]`
: `css=[${strategy}=${selector}]:has-text("${text.replace(/"/g, '\\"')}")`;
const fakeError = `Found ${selector}, oops..`;
const elVisible = await window.isVisible(builtSelector);
if (elVisible === true) {
throw new Error(fakeError);
}
}

Loading…
Cancel
Save