Skip to content
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
d127d61
chore: adding e2e tests for federation (WIP)
Sep 25, 2022
335d2b6
Merge branch 'develop' into chore/federation-e2e-tests
Oct 20, 2022
5885e29
style: fix lint
Oct 20, 2022
860ad94
Merge branch 'develop' into chore/federation-e2e-tests
Oct 21, 2022
539151d
test: adding basic structure + known tests cases specs
Oct 22, 2022
f4b9467
test: adding first test case + configuration
Oct 27, 2022
367eaf5
test: adding more tests cases + config tweaks
Oct 27, 2022
c3a142d
test: finishing test for public channels
Oct 28, 2022
15c48b5
test: tests for private groups
Oct 28, 2022
7f0df58
chore: ignoring federation tests
Oct 28, 2022
7ca91b5
test: tests for DM (WIP)
Oct 29, 2022
20425e8
test: dm tests (WIP)
Oct 29, 2022
ec4c419
test: removing useless var
Oct 29, 2022
b7a7371
test: removing after each
Oct 29, 2022
596bc8d
test: fix lint
Oct 29, 2022
54745a9
test: dm tests tweaks
Oct 29, 2022
0284cc9
test: owner rights for channel
Oct 30, 2022
bd04ad9
test: visual elements for rooms
Oct 30, 2022
b056907
test: tests from remove users/leave from room
Nov 6, 2022
dfbf385
Merge branch 'develop' into chore/federation-e2e-tests
Nov 7, 2022
ae4aec9
test: ensure the removed from channel sys message shows up in public …
Nov 7, 2022
f9e9a3f
chore: trying to fix build
Nov 7, 2022
978bec2
refactor: clean up the code a little bit
Nov 7, 2022
df71e6e
Merge branch 'develop' into chore/federation-e2e-tests
Nov 7, 2022
173e6e5
style: fix lint
Nov 7, 2022
d57ef00
refactor: move to another folder
Nov 7, 2022
da06d80
fix: fix paths
Nov 7, 2022
301d37e
test: e2e tests for messaging
Nov 11, 2022
27fcce0
test: finishing tests
Nov 11, 2022
871449b
chore: disable eslint rule for files
Nov 11, 2022
f592947
test: final tweaks
Nov 11, 2022
1747df0
test: unskip test
Nov 11, 2022
371d5aa
fix: addressing this problem in another PR
Nov 16, 2022
df50f51
Merge branch 'develop' into chore/federation-e2e-tests
Nov 16, 2022
8784b61
Merge branch 'chore/federation-e2e-tests' into chore/federation-e2e-t…
Nov 16, 2022
f758455
test: small tweaks
Nov 16, 2022
12c3a12
Merge branch 'chore/federation-e2e-tests-messages' of github.com:Rock…
Nov 16, 2022
b190ba5
test: more test cases + unskipping some tests
Nov 18, 2022
7168c53
test: several tweaks
Nov 22, 2022
b1d662f
chore: fix lint
Nov 22, 2022
975bd6d
test: unskip test
Nov 23, 2022
c0f5b61
test: final tweaks
Nov 25, 2022
5fcd83f
chore: fix lint
Nov 28, 2022
d9e2181
test: small tweaks
Nov 28, 2022
227619b
test: unskipping tests
Nov 30, 2022
975e541
Merge branch 'develop' into chore/federation-e2e-tests
Nov 30, 2022
de26cbe
Merge branch 'chore/federation-e2e-tests' into chore/federation-e2e-t…
Nov 30, 2022
51ea9f1
test: adding tests cases for CE forbidden actions
Dec 3, 2022
7587628
Merge branch 'develop' into chore/federation-e2e-tests
Dec 14, 2022
9c1d960
Merge branch 'chore/federation-e2e-tests' into chore/federation-e2e-t…
Dec 14, 2022
53f27be
test: removing only
Dec 15, 2022
5ff05a2
Merge branch 'chore/federation-e2e-tests-messages' of github.com:Rock…
Dec 15, 2022
0230798
Merge branch 'develop' into chore/federation-e2e-tests
Dec 24, 2022
dcdd149
Merge branch 'develop' into chore/federation-e2e-tests
Jan 3, 2023
3cc72af
Merge branch 'develop' into chore/federation-e2e-tests
Jan 5, 2023
0fed84e
Merge branch 'chore/federation-e2e-tests' into chore/federation-e2e-t…
Jan 5, 2023
49d0dd6
test: adapt to the new message composer
Jan 5, 2023
310ac6c
test: remove and replace waitForTimeout wherever possible
Jan 5, 2023
9bb5668
Merge branch 'develop' into chore/federation-e2e-tests
Jan 16, 2023
1893d44
Merge branch 'chore/federation-e2e-tests' into chore/federation-e2e-t…
Jan 16, 2023
b1ee1e0
Merge branch 'feat/federation-feat-2' into chore/federation-e2e-tests
Jan 25, 2023
238f51a
Merge branch 'chore/federation-e2e-tests' into chore/federation-e2e-t…
Jan 25, 2023
6aa62e0
Merge branch 'feat/federation-feat-2' into chore/federation-e2e-tests…
Feb 1, 2023
bac250f
test: fix stuff from merge
Feb 1, 2023
0e41031
Merge branch 'chore/federation-e2e-tests-messages' of github.com:Rock…
Feb 1, 2023
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
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ const UserAutoCompleteMultipleFederated = ({
}}
renderOptions={AutocompleteOptions}
options={options.concat(Object.entries(selectedCache)).map(([, item]) => [item.username, item.name || item.username])}
data-qa='create-channel-users-autocomplete'
/>
</OptionsContext.Provider>
);
Expand Down
1 change: 1 addition & 0 deletions apps/meteor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"deploy": "npm run build && pm2 startOrRestart pm2.json",
"coverage": "nyc -r html mocha --config ./.mocharc.js",
"test:e2e": "playwright test",
"test:e2e:federation": "playwright test --config=playwright-federation.config.ts",
"test:e2e:nyc": "nyc report --reporter=text-summary --reporter=lcov",
"testapi": "mocha --config ./.mocharc.api.js",
"testunit": "npm run .testunit:definition && npm run .testunit:client && npm run .testunit:server",
Expand Down
24 changes: 24 additions & 0 deletions apps/meteor/playwright-federation.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { PlaywrightTestConfig } from '@playwright/test';

export default {
globalSetup: require.resolve('./tests/e2e/federation/config/global-setup.ts'),
use: {
headless: true,
ignoreHTTPSErrors: true,
trace: 'retain-on-failure',
screenshot: 'only-on-failure',
channel: 'chrome',
launchOptions: {
// force GPU hardware acceleration
// (even in headless mode)
args: ['--use-gl=egl', '--use-fake-ui-for-media-stream'],
},
permissions: ['microphone', 'camera'],
},
outputDir: 'tests/e2e/.playwright',
reporter: 'list',
testDir: 'tests/e2e/federation',
workers: 1,
retries: 2,
timeout: 60 * 2000,
} as PlaywrightTestConfig;
1 change: 1 addition & 0 deletions apps/meteor/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default {
],
],
testDir: 'tests/e2e',
testIgnore: 'tests/e2e/federation/**',
workers: 1,
retries: process.env.CI ? 2 : undefined,
timeout: 60 * 1000,
Expand Down
12 changes: 12 additions & 0 deletions apps/meteor/tests/e2e/federation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# E2E Testing with playwright

## Running tests

```sh
$ RC_SERVER_1=http://localhost:3000 RC_SERVER_1_ADMIN_USER=test RC_SERVER_1_ADMIN_PASSWORD=test RC_SERVER_1_MATRIX_SERVER_NAME=my.matrix.server \
RC_SERVER_2=http://localhost:3000 RC_SERVER_2_ADMIN_USER=test2 RC_SERVER_2_ADMIN_PASSWORD=test RC_SERVER_2_MATRIX_SERVER_NAME=my2.matrix.server \
yarn run test:e2e:federation
```

## Important
Make sure to increase the rate limiter for the user register api under Admin => Rate Limiter => Feature limiting. This is necessary since we are registering new users programatically.
13 changes: 13 additions & 0 deletions apps/meteor/tests/e2e/federation/config/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const RC_SERVER_1 = {
url: process.env.RC_SERVER_1 ?? 'http://localhost:3000',
username: process.env.RC_SERVER_1_ADMIN_USER ?? '',
password: process.env.RC_SERVER_1_ADMIN_PASSWORD ?? '',
matrixServerName: process.env.RC_SERVER_1_MATRIX_SERVER_NAME ?? '',
};

export const RC_SERVER_2 = {
url: process.env.RC_SERVER_2 ?? 'http://localhost:3000',
username: process.env.RC_SERVER_2_ADMIN_USER ?? '',
password: process.env.RC_SERVER_2_ADMIN_PASSWORD ?? '',
matrixServerName: process.env.RC_SERVER_2_MATRIX_SERVER_NAME ?? '',
};
20 changes: 20 additions & 0 deletions apps/meteor/tests/e2e/federation/config/global-setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { chromium } from '@playwright/test';

export default async function (): Promise<void> {
const browser = await chromium.launch();

const requiredEnvVars = [
'RC_SERVER_1',
'RC_SERVER_2',
'RC_SERVER_1_ADMIN_USER',
'RC_SERVER_1_ADMIN_PASSWORD',
'RC_SERVER_2_ADMIN_USER',
'RC_SERVER_2_ADMIN_PASSWORD',
];

if (requiredEnvVars.some((envVar) => !process.env[envVar])) {
throw new Error(`Missing required environment variables: ${requiredEnvVars.filter((envVar) => !process.env[envVar]).join(', ')}`);
}

await browser.close();
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
78 changes: 78 additions & 0 deletions apps/meteor/tests/e2e/federation/page-objects/account-profile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import type { Locator, Page } from '@playwright/test';

import { FederationAccountSidenav } from './fragments/account-sidenav';

export class FederationAccountProfile {
private readonly page: Page;

readonly sidenav: FederationAccountSidenav;

constructor(page: Page) {
this.page = page;
this.sidenav = new FederationAccountSidenav(page);
}

get inputName(): Locator {
return this.page.locator('//label[contains(text(), "Name")]/..//input');
}

get inputAvatarLink(): Locator {
return this.page.locator('[data-qa-id="UserAvatarEditorLink"]');
}

get btnSetAvatarLink(): Locator {
return this.page.locator('[data-qa-id="UserAvatarEditorSetAvatarLink"]');
}

get inputUsername(): Locator {
return this.page.locator('//label[contains(text(), "Username")]/..//input');
}

get btnSubmit(): Locator {
return this.page.locator('[data-qa="AccountProfilePageSaveButton"]');
}

get avatarFileInput(): Locator {
return this.page.locator('.avatar-file-input');
}

get emailTextInput(): Locator {
return this.page.locator('//label[contains(text(), "Email")]/..//input');
}

get btnClose(): Locator {
return this.page.locator('button >> i.rcx-icon--name-cross.rcx-icon');
}

get inputToken(): Locator {
return this.page.locator('[data-qa="PersonalTokenField"]');
}

get tokensTableEmpty(): Locator {
return this.page.locator('//div[contains(text(), "No results found")]');
}

get btnTokensAdd(): Locator {
return this.page.locator('//button[contains(text(), "Add")]');
}

get tokenAddedModal(): Locator {
return this.page.locator("//div[text()='Personal Access Token successfully generated']");
}

tokenInTable(name: string): Locator {
return this.page.locator(`tr[qa-token-name="${name}"]`);
}

get btnRegenerateTokenModal(): Locator {
return this.page.locator('//button[contains(text(), "Regenerate token")]');
}

get btnRemoveTokenModal(): Locator {
return this.page.locator('//button[contains(text(), "Remove")]');
}

get inputImageFile(): Locator {
return this.page.locator('input[type=file]');
}
}
26 changes: 26 additions & 0 deletions apps/meteor/tests/e2e/federation/page-objects/admin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Locator, Page } from '@playwright/test';

import { FederationAdminFlextab } from './fragments/admin-flextab';

export class FederationAdmin {
private readonly page: Page;

readonly tabs: FederationAdminFlextab;

constructor(page: Page) {
this.page = page;
this.tabs = new FederationAdminFlextab(page);
}

get inputSearchRooms(): Locator {
return this.page.locator('input[placeholder ="Search Rooms"]');
}

get inputSearchUsers(): Locator {
return this.page.locator('input[placeholder="Search Users"]');
}

get inputSearchSettings(): Locator {
return this.page.locator('input[type=search]');
}
}
64 changes: 64 additions & 0 deletions apps/meteor/tests/e2e/federation/page-objects/channel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import type { Locator, Page } from '@playwright/test';

import { FederationHomeContent } from './fragments/home-content';
import { FederationHomeFlextab } from './fragments/home-flextab';
import { FederationSidenav } from './fragments/home-sidenav';

export class FederationChannel {
private readonly page: Page;

readonly content: FederationHomeContent;

readonly sidenav: FederationSidenav;

readonly tabs: FederationHomeFlextab;

constructor(page: Page) {
this.page = page;
this.content = new FederationHomeContent(page);
this.sidenav = new FederationSidenav(page);
this.tabs = new FederationHomeFlextab(page);
}

get toastSuccess(): Locator {
return this.page.locator('.rcx-toastbar.rcx-toastbar--success');
}

get btnVerticalBarClose(): Locator {
return this.page.locator('[data-qa="VerticalBarActionClose"]');
}

async createPublicChannelAndInviteUsersUsingCreationModal(channelName: string, usernamesToInvite: string[]) {
await this.sidenav.openNewByLabel('Channel');
await this.sidenav.checkboxPrivateChannel.click();
await this.sidenav.checkboxFederatedChannel.click();
await this.sidenav.inputChannelName.type(channelName);
for await (const username of usernamesToInvite) {
await this.sidenav.inviteUserToChannel(username);
}

await this.sidenav.btnCreateChannel.click();
}

async createPrivateGroupAndInviteUsersUsingCreationModal(channelName: string, usernamesToInvite: string[]) {
await this.sidenav.openNewByLabel('Channel');
await this.sidenav.checkboxFederatedChannel.click();
await this.sidenav.inputChannelName.type(channelName);
for await (const username of usernamesToInvite) {
await this.sidenav.inviteUserToChannel(username);
}

await this.sidenav.btnCreateChannel.click();
}

async createDirectMessagesUsingModal(usernamesToInvite: string[]) {
await this.sidenav.openNewByLabel('Direct Messages');
for await (const username of usernamesToInvite) {
await this.sidenav.inviteUserToDM(username);
}
await this.page
.locator('//*[@id="modal-root"]//*[contains(@class, "rcx-modal__title") and contains(text(), "Direct Messages")]')
.click();
await this.sidenav.btnCreateChannel.click();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Locator, Page } from '@playwright/test';

export class FederationAccountSidenav {
private readonly page: Page;

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

get linkTokens(): Locator {
return this.page.locator('.flex-nav [href="/account/tokens"]');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { Locator, Page } from '@playwright/test';

export class FederationAdminFlextabUsers {
private readonly page: Page;

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

get btnNew(): Locator {
return this.page.locator('//button[text()="New"]');
}

get btnEdit(): Locator {
return this.page.locator('//button[text()="Edit"]');
}

get btnSave(): Locator {
return this.page.locator('//button[text()="Save"]');
}

get inputName(): Locator {
return this.page.locator('//label[text()="Name"]/following-sibling::span//input');
}

get inputUserName(): Locator {
return this.page.locator('//label[text()="Username"]/following-sibling::span//input');
}

get inputEmail(): Locator {
return this.page.locator('//label[text()="Email"]/following-sibling::span//input').first();
}

get inputPassword(): Locator {
return this.page.locator('//label[text()="Password"]/following-sibling::span//input');
}

get checkboxVerified(): Locator {
return this.page.locator('//label[text()="Email"]/following-sibling::span//input/following-sibling::i');
}

async addRole(role: string): Promise<void> {
await this.page.locator('//label[text()="Roles"]/following-sibling::span//input').click();
await this.page.locator(`li[value=${role}]`).click();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { Page } from '@playwright/test';

import { FederationAdminFlextabUsers } from './admin-flextab-users';

export class FederationAdminFlextab {
readonly users: FederationAdminFlextabUsers;

constructor(page: Page) {
this.users = new FederationAdminFlextabUsers(page);
}
}
Loading