Skip to content
5 changes: 5 additions & 0 deletions tests/automation/constants/community.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
export const testCommunityLink =
'https://chat.lokinet.dev/testing-all-the-things?public_key=1d7e7f92b1ed3643855c98ecac02fc7274033a3467653f047d6e433540c03f17';
export const testCommunityName = 'Testing All The Things!';

export type DefaultCommunity =
| 'Lokinet Updates'
| 'Session Network Updates'
| 'Session Updates';
119 changes: 46 additions & 73 deletions tests/automation/group_testing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
typeIntoInput,
waitForMatchingText,
waitForTestIdWithText,
waitForTextMessage,
} from './utilities/utils';

// Note: Note using the group fixture here as we want to test it thoroughly
Expand Down Expand Up @@ -167,87 +168,59 @@ test_group_Alice_1W_Bob_1W_Charlie_1W(
charlieWindow1,
groupCreated,
}) => {
// in windowA we should be able to mentions bob and userC
const members = [
{ user: alice, window: aliceWindow1, others: [bob, charlie] },
{ user: bob, window: bobWindow1, others: [alice, charlie] },
{ user: charlie, window: charlieWindow1, others: [alice, bob] },
];

await clickOnWithText(
aliceWindow1,
HomeScreen.conversationItemName,
groupCreated.userName,
);
await typeIntoInput(aliceWindow1, 'message-input-text-area', '@');
// does 'message-input-text-area' have aria-expanded: true when @ is typed into input
await waitForTestIdWithText(aliceWindow1, 'mentions-popup-row');
await waitForTestIdWithText(
aliceWindow1,
'mentions-popup-row',
bob.userName,
);
await waitForTestIdWithText(
aliceWindow1,
'mentions-popup-row',
charlie.userName,
);
// ALice tags Bob
await clickOnWithText(
aliceWindow1,
Conversation.mentionsPopup,
bob.userName,
// All users open group conversation
await Promise.all(
members.map((m) =>
clickOnWithText(
m.window,
HomeScreen.conversationItemName,
groupCreated.userName,
),
),
);
await waitForMatchingText(bobWindow1, 'You');

// in windowB we should be able to mentions alice and charlie
await clickOnWithText(
bobWindow1,
HomeScreen.conversationItemName,
groupCreated.userName,
);
await typeIntoInput(bobWindow1, 'message-input-text-area', '@');
// does 'message-input-text-area' have aria-expanded: true when @ is typed into input
await waitForTestIdWithText(bobWindow1, 'mentions-popup-row');
await waitForTestIdWithText(
bobWindow1,
'mentions-popup-row',
alice.userName,
);
await waitForTestIdWithText(
bobWindow1,
'mentions-popup-row',
charlie.userName,
);
// Bob tags Charlie
await clickOnWithText(
bobWindow1,
Conversation.mentionsPopup,
charlie.userName,
// All users type @ to open mentions
await Promise.all(
members.map((m) =>
typeIntoInput(m.window, 'message-input-text-area', '@'),
),
);
await waitForMatchingText(charlieWindow1, 'You');

// in charlieWindow1 we should be able to mentions alice and userB
await clickOnWithText(
charlieWindow1,
HomeScreen.conversationItemName,
groupCreated.userName,
);
await typeIntoInput(charlieWindow1, 'message-input-text-area', '@');
// does 'message-input-text-area' have aria-expanded: true when @ is typed into input
await waitForTestIdWithText(charlieWindow1, 'mentions-popup-row');
await waitForTestIdWithText(
charlieWindow1,
'mentions-popup-row',
alice.userName,
// All users check mentions dropdown shows "You" + other members
await Promise.all(
members.flatMap((m) =>
['You', ...m.others.map((o) => o.userName)].map((name) =>
waitForTestIdWithText(m.window, 'mentions-container-row', name),
),
),
);
await waitForTestIdWithText(
charlieWindow1,
'mentions-popup-row',
bob.userName,

// All users click on next member (Alice→Bob, Bob→Charlie, Charlie→Alice) and send
await Promise.all(
members.map(async (m, i) => {
await clickOnWithText(
m.window,
Conversation.mentionsItem,
members[(i + 1) % members.length].user.userName,
);
await clickOn(m.window, Conversation.sendMessageButton);
}),
);
// Charlie tags Alice
await clickOnWithText(
charlieWindow1,
Conversation.mentionsPopup,
alice.userName,

// All users should see all mentions ("You" for their own tag, names for others)
await Promise.all(
members.flatMap((m) =>
['You', ...m.others.map((o) => o.userName)].map((text) =>
waitForTextMessage(m.window, text),
),
),
);
await waitForMatchingText(aliceWindow1, 'You');
},
);

Expand Down
4 changes: 2 additions & 2 deletions tests/automation/linked_device_user.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,10 @@ test_Alice_2W(
);

test_Alice_2W(
'Profile picture syncs',
'Avatar syncs',
async ({ aliceWindow1, aliceWindow2 }, testInfo) => {
await clickOn(aliceWindow1, LeftPane.profileButton);
// Click on current profile picture
// Click on current avatar
await clickOn(aliceWindow1, Settings.displayName);
await clickOn(aliceWindow1, Settings.imageUploadSection);
await clickOn(aliceWindow1, Settings.imageUploadClick);
Expand Down
3 changes: 2 additions & 1 deletion tests/automation/locators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ export class Conversation extends Locator {
);
static readonly endCallButton = this.testId('end-call');
static readonly endVoiceMessageButton = this.testId('end-voice-message');
static readonly mentionsPopup = this.testId('mentions-popup-row');
static readonly mentionsContainer = this.testId('mentions-container'); // This is also the locator for emojis
static readonly mentionsItem = this.testId('mentions-container-row'); // This is also the locator for emojis
static readonly messageContent = this.testId('message-content');

static readonly messageInput = this.testId('message-input-text-area');
Expand Down
82 changes: 82 additions & 0 deletions tests/automation/message_checks.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { newUser } from './setup/new_user';
import {
sessionTestTwoWindows,
test_Alice_1W,
test_Alice_1W_Bob_1W,
} from './setup/sessionTest';
import { createContact } from './utilities/create_contact';
Expand All @@ -32,6 +33,7 @@ import {
clickOnMatchingText,
clickOnTextMessage,
clickOnWithText,
hasElementPoppedUpThatShouldnt,
hasTextMessageBeenDeleted,
measureSendingTime,
typeIntoInput,
Expand Down Expand Up @@ -394,3 +396,83 @@ messageLengthTestCases.forEach((testCase) => {
},
);
});

test_Alice_1W(
'Emoji container does not show for links',
async ({ aliceWindow1, alice }) => {
await clickOn(aliceWindow1, HomeScreen.plusButton);
await clickOn(aliceWindow1, HomeScreen.newMessageOption);
await typeIntoInput(
aliceWindow1,
HomeScreen.newMessageAccountIDInput.selector,
alice.accountid,
true,
);
await clickOn(aliceWindow1, HomeScreen.newMessageNextButton);
await typeIntoInput(aliceWindow1, Conversation.messageInput.selector, ':a');
await waitForTestIdWithText(
aliceWindow1,
Conversation.mentionsContainer.selector,
);
await waitForTestIdWithText(
aliceWindow1,
Conversation.mentionsItem.selector,
':a:',
);
await typeIntoInput(
aliceWindow1,
Conversation.messageInput.selector,
'https:/',
);
await hasElementPoppedUpThatShouldnt(
aliceWindow1,
Conversation.mentionsContainer.strategy,
Conversation.mentionsContainer.selector,
);
await typeIntoInput(
aliceWindow1,
Conversation.messageInput.selector,
'check this out https:/',
);
await hasElementPoppedUpThatShouldnt(
aliceWindow1,
Conversation.mentionsContainer.strategy,
Conversation.mentionsContainer.selector,
);
},
);

test_Alice_1W(
'Emoji container closes when clicking away',
async ({ aliceWindow1, alice }) => {
await clickOn(aliceWindow1, HomeScreen.plusButton);
await clickOn(aliceWindow1, HomeScreen.newMessageOption);
await typeIntoInput(
aliceWindow1,
HomeScreen.newMessageAccountIDInput.selector,
alice.accountid,
true,
);
await clickOn(aliceWindow1, HomeScreen.newMessageNextButton);
await typeIntoInput(
aliceWindow1,
Conversation.messageInput.selector,
'hey check this out :a',
);
await waitForTestIdWithText(
aliceWindow1,
Conversation.mentionsContainer.selector,
);
await waitForTestIdWithText(
aliceWindow1,
Conversation.mentionsItem.selector,
':a:',
);
await clickOn(aliceWindow1, Conversation.messageInput);
await hasElementPoppedUpThatShouldnt(
aliceWindow1,
Conversation.mentionsContainer.strategy,
Conversation.mentionsContainer.selector,
);
},
);
89 changes: 89 additions & 0 deletions tests/automation/recovery_phrase_banner.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import type { Page } from '@playwright/test';

import { sleepFor } from '../promise_utils';
import { Global, HomeScreen, Settings } from './locators';
import { test_Alice_1W } from './setup/sessionTest';
import {
joinDefaultCommunity,
leaveCommunity,
} from './utilities/join_community';
import { linkedDevice } from './utilities/linked_device';
import {
clickOn,
hasElementPoppedUpThatShouldnt,
waitForTestIdWithText,
} from './utilities/utils';

async function bannerShouldNotAppear(window: Page) {
await waitForTestIdWithText(window, HomeScreen.plusButton.selector);
await hasElementPoppedUpThatShouldnt(
window,
HomeScreen.revealRecoveryPhraseButton.strategy,
HomeScreen.revealRecoveryPhraseButton.selector,
);
console.log('On home screen, banner did not appear');
}

async function bannerShouldAppear(window: Page) {
await waitForTestIdWithText(window, HomeScreen.plusButton.selector);
await waitForTestIdWithText(
window,
HomeScreen.revealRecoveryPhraseButton.selector,
);
console.log('On home screen, banner is visible');
}

test_Alice_1W(
'Recovery password banner appears after >2 conversations',
async ({ aliceWindow1 }) => {
await bannerShouldNotAppear(aliceWindow1);
await joinDefaultCommunity(aliceWindow1, 'Lokinet Updates');
await bannerShouldNotAppear(aliceWindow1);
await joinDefaultCommunity(aliceWindow1, 'Session Network Updates');
await bannerShouldNotAppear(aliceWindow1);
await joinDefaultCommunity(aliceWindow1, 'Session Updates');
await bannerShouldAppear(aliceWindow1);
},
);

test_Alice_1W(
'Recovery password banner 2 windows',
async ({ aliceWindow1, alice }) => {
await joinDefaultCommunity(aliceWindow1, 'Lokinet Updates');
await joinDefaultCommunity(aliceWindow1, 'Session Network Updates');
await joinDefaultCommunity(aliceWindow1, 'Session Updates');
const aliceWindow2 = await linkedDevice(alice.recoveryPassword);
await sleepFor(2_000);
await bannerShouldNotAppear(aliceWindow2);
},
);

test_Alice_1W(
'Recovery password banner persists when conversation count drops below 3',
async ({ aliceWindow1 }) => {
await joinDefaultCommunity(aliceWindow1, 'Lokinet Updates');
await joinDefaultCommunity(aliceWindow1, 'Session Network Updates');
await joinDefaultCommunity(aliceWindow1, 'Session Updates');
await bannerShouldAppear(aliceWindow1);

await leaveCommunity(aliceWindow1, 'Lokinet Updates');
await bannerShouldAppear(aliceWindow1);
},
);

test_Alice_1W(
'Recovery password banner disappears after being opened',
async ({ aliceWindow1 }) => {
await joinDefaultCommunity(aliceWindow1, 'Lokinet Updates');
await joinDefaultCommunity(aliceWindow1, 'Session Network Updates');
await joinDefaultCommunity(aliceWindow1, 'Session Updates');
await bannerShouldAppear(aliceWindow1);
await clickOn(aliceWindow1, HomeScreen.revealRecoveryPhraseButton);
await waitForTestIdWithText(
aliceWindow1,
Settings.recoveryPasswordContainer.selector,
);
await clickOn(aliceWindow1, Global.modalCloseButton);
await bannerShouldNotAppear(aliceWindow1);
},
);
3 changes: 2 additions & 1 deletion tests/automation/setup/open.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ function mockNetworkPageNodeCount(networkPageNodeCount?: number) {
const openElectronAppOnly = async (multi: string, context?: TestContext) => {
process.env.MULTI = `${multi}`;
// using a v4 uuid, as timestamps to the ms are sometimes the same (when a bunch of workers are started)
const uniqueId = v4();
const fullUniqueId = v4();
const uniqueId = fullUniqueId.slice(0, 8);
process.env.NODE_APP_INSTANCE = `${MULTI_PREFIX}-devprod-${uniqueId}-${process.env.MULTI}`;
process.env.NODE_ENV = NODE_ENV;

Expand Down
3 changes: 2 additions & 1 deletion tests/automation/types/testing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ export type DataTestId =
| 'loading-spinner'
| 'manage-members-menu-option'
| 'market-cap-amount'
| 'mentions-popup-row'
| 'mentions-container-row'
| 'mentions-container'
| 'message-content'
| 'message-input-text-area'
| 'message-request-banner'
Expand Down
2 changes: 1 addition & 1 deletion tests/automation/user_actions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ test_Alice_1W_no_network(
async ({ aliceWindow1 }, testInfo) => {
// Open profile
await clickOn(aliceWindow1, LeftPane.profileButton);
// Click on current profile picture
// Click on current avatar
await clickOn(aliceWindow1, Settings.displayName);

await clickOn(aliceWindow1, Settings.imageUploadSection);
Expand Down
Loading
Loading