Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions test/e2e_tests/pageManager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {CreatGuestLinkModal} from './webapp/modals/createGuestLink.modal';
import {DataShareConsentModal} from './webapp/modals/dataShareConsent.modal';
import {DeleteAccountModal} from './webapp/modals/deleteAccount.modal';
import {DetailViewModal} from './webapp/modals/detailView.modal';
import {ErrorModal} from './webapp/modals/error.modal';
import {ExportBackupModal} from './webapp/modals/exportBackup.modal';
import {importBackupModal} from './webapp/modals/importBackup.modal';
import {LeaveConversationModal} from './webapp/modals/leaveConversation.modal';
Expand All @@ -63,6 +64,7 @@ import {HistoryExportPage} from './webapp/pages/historyExport.page';
import {HistoryImportPage} from './webapp/pages/historyImport.page';
import {HistoryInfoPage} from './webapp/pages/infoHistory.page';
import {LoginPage} from './webapp/pages/login.page';
import {OptionsPage} from './webapp/pages/options.page';
import {OutgoingConnectionPage} from './webapp/pages/outgoingConnection.page';
import {ParticipantDetails} from './webapp/pages/participantDetails.page';
import {RegisterSuccessPage} from './webapp/pages/registerSuccess.page';
Expand Down Expand Up @@ -161,6 +163,7 @@ export class PageManager {
connectRequest: () => this.getOrCreate('webapp.pages.connectRequest', () => new ConnectRequestPage(this.page)),
calling: () => this.getOrCreate('webapp.pages.calling', () => new CallingPage(this.page)),
settings: () => this.getOrCreate('webapp.pages.settings', () => new SettingsPage(this.page)),
options: () => this.getOrCreate('webapp.pages.options', () => new OptionsPage(this.page)),
audioVideoSettings: () =>
this.getOrCreate('webapp.pages.audioVideoSettings', () => new AudioVideoSettingsPage(this.page)),
outgoingConnection: () =>
Expand All @@ -182,6 +185,7 @@ export class PageManager {
setUsername: () => this.getOrCreate('webapp.pages.setUsername', () => new SetUsernamePage(this.page)),
},
modals: {
errorModal: () => this.getOrCreate('webapp.modals.errorModal', () => new ErrorModal(this.page)),
dataShareConsent: () =>
this.getOrCreate('webapp.modals.dataShareConsent', () => new DataShareConsentModal(this.page)),
appLock: () => this.getOrCreate('webapp.modals.appLock', () => new AppLockModal(this.page)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,29 @@ import {Page, Locator} from '@playwright/test';
import {selectByDataAttribute} from 'test/e2e_tests/utils/selector.util';

export class ConversationSidebar {
readonly pageLoadingTimeout = 60_000;
readonly page: Page;

readonly personalStatusLabel: Locator;
readonly personalStatusName: Locator;
readonly personalUserName: Locator;
readonly preferencesButton: Locator;
readonly allConverationsButton: Locator;
readonly connectButton: Locator;
readonly archiveButton: Locator;
readonly manageTeamButton: Locator;
readonly sidebar: Locator;

constructor(page: Page) {
this.page = page;

this.personalStatusLabel = page.getByTestId('status-availability');
this.personalStatusName = page.locator(`${selectByDataAttribute('status-name')}`);
this.personalUserName = page.locator(`${selectByDataAttribute('user-handle')}`);
this.preferencesButton = page.locator(`${selectByDataAttribute('go-preferences')}`);
this.allConverationsButton = page.locator(`${selectByDataAttribute('go-recent-view')}`);
this.connectButton = page.locator(`button${selectByDataAttribute('go-people')}`);
this.archiveButton = page.locator(selectByDataAttribute('go-archive'));
this.manageTeamButton = page.locator(selectByDataAttribute('go-team-management'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I doesn't make sense to have both getByTestId and selectByDataAttribute because they both locate elements by data-uie-name.

this.sidebar = page.locator(`.conversations-sidebar-items`);
}

Expand All @@ -65,7 +69,7 @@ export class ConversationSidebar {
}

async isPageLoaded() {
await this.preferencesButton.waitFor({state: 'visible'});
await this.preferencesButton.waitFor({state: 'visible', timeout: this.pageLoadingTimeout});
}

async clickArchive() {
Expand Down
8 changes: 4 additions & 4 deletions test/e2e_tests/pageManager/webapp/modals/base.modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ export abstract class BaseModal {
constructor(page: Page, modalLocator: string) {
this.page = page;
this.modal = page.locator(modalLocator);
this.modalTitle = this.modal.locator("[data-uie-name='status-modal-title']");
this.modalText = this.modal.locator("[data-uie-name='status-modal-text']");
this.actionButton = this.modal.locator("[data-uie-name='do-action']");
this.cancelButton = this.modal.locator("[data-uie-name='do-secondary']");
this.modalTitle = this.modal.getByTestId('status-modal-title');
this.modalText = this.modal.getByTestId('status-modal-text');
this.actionButton = this.modal.getByTestId('do-action');
this.cancelButton = this.modal.getByTestId('do-secondary');
}

async isModalPresent() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class DataShareConsentModal {
}

async isModalPresent() {
return this.modal.isVisible();
return this.modalTitle.isVisible();
}

async getModalTitle() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,12 @@
*
*/

import {addCreatedTeam, addCreatedUser} from './tearDown.util';
import {inviteMembers} from './userActions';
import {Page} from '@playwright/test';

import {ApiManagerE2E} from '../backend/apiManager.e2e';
import {User} from '../data/user';
import {BaseModal} from './base.modal';

/**
* add an team with one owner and 2 member
*/
export const setupBasicTestScenario = async (api: ApiManagerE2E, member: User[], owner: User, teamName: string) => {
const user = await api.createTeamOwner(owner, teamName);
// register credentials for cleanup later
addCreatedTeam(user, user.teamId);
await inviteMembers(member, user, api);

for (const [, user] of member.entries()) {
addCreatedUser(user);
export class ErrorModal extends BaseModal {
constructor(page: Page) {
super(page, "[data-uie-name='primary-modals-container']");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it doesn't make much sense since a lot of modals we have utilise the same [data-uie-name='primary-modals-container']. We either need to distinguish modals with some other means or add unique identifiers. @e-maad what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @iskvortsov, we should add unique identifiers.

}
return user;
};
}
16 changes: 16 additions & 0 deletions test/e2e_tests/pageManager/webapp/pages/account.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ export class AccountPage {
readonly restoreBackupButton: Locator;
readonly logoutButton: Locator;
readonly emailDisplay: Locator;
readonly nameDisplay: Locator;
readonly domainDisplay: Locator;
readonly usernameDisplay: Locator;
readonly editEmailButton: Locator;
readonly editDisplayNameButton: Locator;
readonly emailInput: Locator;
readonly displayNameInput: Locator;
readonly resetPasswordButton: Locator;
readonly receiveNewsletterCheckbox: Locator;
readonly typingIndicator: Locator;
Expand All @@ -49,8 +54,13 @@ export class AccountPage {
this.restoreBackupButton = page.locator("[data-uie-name='do-backup-import']+button");
this.logoutButton = page.locator(selectByDataAttribute('do-logout'));
this.editEmailButton = page.locator(selectByDataAttribute('go-edit-email'));
this.editDisplayNameButton = page.locator(selectByDataAttribute('go-edit-email'));
this.emailInput = page.locator(selectByDataAttribute('enter-email-input'));
this.displayNameInput = page.locator(selectByDataAttribute('enter-displayname-input'));
this.emailDisplay = page.locator(selectByDataAttribute('email-display'));
this.nameDisplay = page.locator(selectByDataAttribute('displayname-display'));
this.domainDisplay = page.locator(selectByDataAttribute('item-enriched-value'));
this.usernameDisplay = page.locator(selectByDataAttribute('username-display'));
this.resetPasswordButton = page.locator(selectByDataAttribute('do-reset-password'));
this.receiveNewsletterCheckbox = page.locator("[data-uie-name='status-preference-marketing']+label");
this.typingIndicator = page.locator("[data-uie-name='status-preference-typing-indicator']+label");
Expand Down Expand Up @@ -111,4 +121,10 @@ export class AccountPage {
await this.emailInput.fill(newEmail);
await this.emailInput.press('Enter');
}

async changeName(newName: string) {
await this.editDisplayNameButton.click();
await this.displayNameInput.fill(newName);
await this.displayNameInput.press('Enter');
}
}
12 changes: 12 additions & 0 deletions test/e2e_tests/pageManager/webapp/pages/conversation.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export class ConversationPage {
readonly conversationInfoButton: Locator;
readonly pingButton: Locator;
readonly messages: Locator;
readonly messageItems: Locator;
readonly filesTab: Locator;
readonly isTypingIndicator: Locator;

Expand Down Expand Up @@ -79,6 +80,7 @@ export class ConversationPage {
this.callButton = page.locator(selectByDataAttribute('do-call'));
this.conversationInfoButton = page.locator(selectByDataAttribute('do-open-info'));
this.pingButton = page.locator(selectByDataAttribute('do-ping'));
this.messageItems = page.locator(selectByDataAttribute('item-message'));
this.messages = page.locator(
`${selectByDataAttribute('item-message')} ${selectByClass('message-body')}:not(:has(p${selectByClass('text-foreground')})):has(${selectByClass('text')})`,
);
Expand Down Expand Up @@ -192,6 +194,11 @@ export class ConversationPage {
return await locator.screenshot();
}

async reactOnMessage(message: Locator) {
await message.hover();
await message.getByRole('group').getByRole('button').first().click();
}

async clickImage(user: User) {
const locator = this.getImageLocator(user);

Expand Down Expand Up @@ -349,4 +356,9 @@ export class ConversationPage {
async sendPing() {
await this.pingButton.click();
}

async getCurrentFocusedToolTip(message: Locator) {
await message.getByTestId('emoji-pill').first().hover();
return this.page.locator('[data-testid="tooltip-content"]');
}
}
4 changes: 2 additions & 2 deletions test/e2e_tests/pageManager/webapp/pages/infoHistory.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ import {selectByDataAttribute} from 'test/e2e_tests/utils/selector.util';

export class HistoryInfoPage {
readonly page: Page;
private readonly continueButton: Locator;
readonly continueButton: Locator;

constructor(page: Page) {
this.page = page;
this.continueButton = this.page.locator(selectByDataAttribute('do-history-confirm'));
}
async isButtonVisible() {
try {
await this.continueButton.waitFor({state: 'visible', timeout: 10000});
await this.continueButton.waitFor({state: 'visible'});
return true;
} catch (err) {
return false;
Expand Down
44 changes: 44 additions & 0 deletions test/e2e_tests/pageManager/webapp/pages/options.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Wire
* Copyright (C) 2025 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
*/

import {Page, Locator} from '@playwright/test';

import {selectByDataAttribute} from 'test/e2e_tests/utils/selector.util';

export class OptionsPage {
readonly checkboxSoundAlertsAll: Locator;
readonly checkboxSoundAlertsSome: Locator;
readonly checkboxSoundAlertsNone: Locator;

constructor(page: Page) {
this.checkboxSoundAlertsAll = page.locator(selectByDataAttribute('preferences-options-audio-all'));
this.checkboxSoundAlertsSome = page.locator(selectByDataAttribute('preferences-options-audio-some'));
this.checkboxSoundAlertsNone = page.locator(selectByDataAttribute('preferences-options-audio-none'));
}

async checkSoundAll() {
await this.checkboxSoundAlertsAll.check();
}
async checkSoundSome() {
await this.checkboxSoundAlertsSome.check();
}
async checkSoundNone() {
await this.checkboxSoundAlertsNone.check();
}
}
6 changes: 6 additions & 0 deletions test/e2e_tests/pageManager/webapp/pages/settings.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ export class SettingsPage {

readonly audioVideoSettingsButton: Locator;
readonly accountButton: Locator;
readonly optionsButton: Locator;

constructor(page: Page) {
this.page = page;
this.audioVideoSettingsButton = page.locator("[data-uie-name='go-audio-video']");
this.accountButton = page.locator("[data-uie-name='go-account']");
this.optionsButton = page.locator("[data-uie-name='go-options']");
}

async clickAudioVideoSettingsButton() {
Expand All @@ -38,4 +40,8 @@ export class SettingsPage {
async clickAccountButton() {
await this.accountButton.click();
}

async clickOptionsButton() {
await this.optionsButton.click();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import {getUser, User} from 'test/e2e_tests/data/user';
import {setupBasicTestScenario} from 'test/e2e_tests/utils/setup.utli';
import {bootstrapTeamForTesting} from 'test/e2e_tests/utils/setup.util';
import {tearDownAll} from 'test/e2e_tests/utils/tearDown.util';
import {loginUser} from 'test/e2e_tests/utils/userActions';

Expand All @@ -31,7 +31,7 @@ test.describe('f2a for teams', () => {
const member1 = getUser();

test.beforeAll(async ({api}) => {
const user = await setupBasicTestScenario(api, [member1], owner, teamName);
const user = await bootstrapTeamForTesting(api, [member1], owner, teamName);
owner = {...owner, ...user};

await api.brig.unlockSndFactorPasswordChallenge(owner.teamId);
Expand Down
4 changes: 2 additions & 2 deletions test/e2e_tests/specs/Accessibility/Accessibility.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import {getUser} from 'test/e2e_tests/data/user';
import {PageManager} from 'test/e2e_tests/pageManager';
import {setupBasicTestScenario} from 'test/e2e_tests/utils/setup.util';
import {bootstrapTeamForTesting} from 'test/e2e_tests/utils/setup.util';
import {tearDownAll} from 'test/e2e_tests/utils/tearDown.util';
import {createGroup, loginUser} from 'test/e2e_tests/utils/userActions';

Expand All @@ -38,7 +38,7 @@ test.describe('Accessibility', () => {
const loginTimeOut = 60_000;

test.beforeAll(async ({api}) => {
const user = await setupBasicTestScenario(api, members, owner, teamName);
const user = await bootstrapTeamForTesting(api, members, owner, teamName);
owner = {...owner, ...user};
});

Expand Down
Loading
Loading