Chore: Test/improve reliability (#26724)

pull/26748/head^2
souzaramon 3 years ago committed by GitHub
parent bf915717db
commit 8ebefd8a69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      apps/meteor/ee/client/views/admin/engagementDashboard/EngagementDashboardPage.tsx
  2. 14
      apps/meteor/tests/e2e/administration.spec.ts
  3. 22
      apps/meteor/tests/e2e/apps.spec.ts
  4. 9
      apps/meteor/tests/e2e/engagement-dashboard.spec.ts
  5. 11
      apps/meteor/tests/e2e/messaging.spec.ts
  6. 61
      apps/meteor/tests/e2e/omnichannel-currentChats.spec.ts
  7. 10
      apps/meteor/tests/e2e/omnichannel-livechat.spec.ts
  8. 13
      apps/meteor/tests/e2e/page-objects/across-page.ts
  9. 4
      apps/meteor/tests/e2e/page-objects/admin.ts
  10. 29
      apps/meteor/tests/e2e/page-objects/fragments/admin-sidenav.ts
  11. 5
      apps/meteor/tests/e2e/page-objects/fragments/home-sidenav.ts
  12. 1
      apps/meteor/tests/e2e/page-objects/fragments/index.ts
  13. 4
      apps/meteor/tests/e2e/page-objects/home-channel.ts
  14. 1
      apps/meteor/tests/e2e/page-objects/index.ts
  15. 37
      apps/meteor/tests/e2e/settings-account-profile.spec.ts
  16. 5
      apps/meteor/tests/e2e/utils/apps/apps-data.ts
  17. 12
      apps/meteor/tests/e2e/utils/apps/cleanup-app.ts
  18. 3
      apps/meteor/tests/e2e/utils/apps/index.ts
  19. 11
      apps/meteor/tests/e2e/utils/apps/install-test-app.ts
  20. 11
      apps/meteor/tests/e2e/utils/apps/remove-app.ts
  21. 15
      apps/meteor/tests/e2e/utils/create-aux-context.ts
  22. 2
      apps/meteor/tests/e2e/utils/index.ts

@ -32,7 +32,7 @@ const EngagementDashboardPage = ({ tab = 'users', onSelectTab }: EngagementDashb
);
return (
<Page backgroundColor='neutral-100' data-qa='EngagementDashboardPage'>
<Page backgroundColor='neutral-100'>
<Page.Header title={t('Engagement_Dashboard')}>
<Select options={timezoneOptions} value={timezoneId} onChange={handleTimezoneChange} />
</Page.Header>

@ -10,13 +10,11 @@ test.describe.parallel('administration', () => {
test.beforeEach(async ({ page }) => {
poAdmin = new Admin(page);
await page.goto('/admin');
});
test.describe('Info', () => {
test.beforeEach(async () => {
await poAdmin.sidenav.linkInfo.click();
test.beforeEach(async ({ page }) => {
await page.goto('/admin/info');
});
test('expect download info as JSON', async ({ page }) => {
@ -27,8 +25,8 @@ test.describe.parallel('administration', () => {
});
test.describe('Users', () => {
test.beforeEach(async () => {
await poAdmin.sidenav.linkUsers.click();
test.beforeEach(async ({ page }) => {
await page.goto('/admin/users');
});
test('expect find "user1" user', async ({ page }) => {
@ -50,8 +48,8 @@ test.describe.parallel('administration', () => {
});
test.describe('Rooms', () => {
test.beforeEach(async () => {
await poAdmin.sidenav.linkRooms.click();
test.beforeEach(async ({ page }) => {
await page.goto('/admin/rooms');
});
test('expect find "general" channel', async ({ page }) => {

@ -1,22 +1,26 @@
import { expect, test } from './utils/test';
import { HomeChannel, AcrossPage } from './page-objects';
import { installTestApp, cleanupTesterApp } from './utils';
import { HomeChannel } from './page-objects';
const APP_TESTER = {
id: '',
url: 'https://github.com/RocketChat/Apps.RocketChat.Tester/blob/master/dist/appsrocketchattester_0.0.5.zip?raw=true',
};
test.use({ storageState: 'user1-session.json' });
test.describe.parallel('Apps', () => {
let poHomeChannel: HomeChannel;
let acrossPage: AcrossPage;
test.beforeAll(async ({ api }) => {
await api.post('/settings/Apps_Framework_enabled', { value: true });
await api.post('/settings/Apps_Framework_Development_Mode', { value: true });
await installTestApp(api);
const { app } = await (await api.post('/api/apps', { url: APP_TESTER.url }, '')).json();
APP_TESTER.id = app.id;
});
test.beforeEach(async ({ page }) => {
poHomeChannel = new HomeChannel(page);
acrossPage = new AcrossPage(page);
await page.goto('/home');
await poHomeChannel.sidenav.openChat('general');
@ -24,17 +28,17 @@ test.describe.parallel('Apps', () => {
test('expect allow user open app contextualbar', async () => {
await poHomeChannel.content.dispatchSlashCommand('/contextualbar');
await expect(acrossPage.btnVerticalBarClose).toBeVisible();
await expect(poHomeChannel.btnVerticalBarClose).toBeVisible();
});
test('expect app contextualbar to be closed', async () => {
await poHomeChannel.content.dispatchSlashCommand('/contextualbar');
await acrossPage.btnVerticalBarClose.click();
await expect(acrossPage.btnVerticalBarClose).toBeHidden();
await poHomeChannel.btnVerticalBarClose.click();
await expect(poHomeChannel.btnVerticalBarClose).toBeHidden();
});
test.afterAll(async ({ api }) => {
await cleanupTesterApp(api);
await api.delete(`/api/apps/${APP_TESTER.id}`);
await api.post('/settings/Apps_Framework_enabled', { value: false });
await api.post('/settings/Apps_Framework_Development_Mode', { value: false });
});

@ -1,5 +1,4 @@
import { test, expect } from './utils/test';
import { Admin } from './page-objects';
import { IS_EE } from './config/constants';
test.skip(!IS_EE, 'Engagemente Dashboard > Enterprise Only');
@ -7,16 +6,10 @@ test.skip(!IS_EE, 'Engagemente Dashboard > Enterprise Only');
test.use({ storageState: 'admin-session.json' });
test.describe('engagement-dashboard', () => {
let poAdmin: Admin;
test.describe.parallel('expect to trigger fallback error component', () => {
test.beforeEach(async ({ page }) => {
poAdmin = new Admin(page);
await page.goto('/admin');
await page.goto('/admin/engagement-dashboard');
await page.route('**/api/v1/engagement-dashboard/**', (route) => route.abort());
await poAdmin.sidenav.linkEngagementDashboard.click();
await expect(page.locator('[data-qa="EngagementDashboardPage"]')).toBeVisible();
});
test('expect to show 4 fallback errors components inside widget at Users Tab', async ({ page }) => {

@ -1,6 +1,15 @@
import type { Browser, Page } from '@playwright/test';
import { expect, test } from './utils/test';
import { HomeChannel } from './page-objects';
import { createTargetChannel, createAuxContext } from './utils';
import { createTargetChannel } from './utils';
const createAuxContext = async (browser: Browser, storageState: string): Promise<{ page: Page; poHomeChannel: HomeChannel }> => {
const page = await browser.newPage({ storageState });
const poHomeChannel = new HomeChannel(page);
await page.goto('/');
return { page, poHomeChannel };
};
test.use({ storageState: 'user1-session.json' });

@ -9,72 +9,87 @@ test.describe.serial('Current Chats', () => {
test.beforeEach(async ({ page }) => {
pageOmnichannelCurrentChats = new OmnichannelCurrentChats(page);
await page.goto('/omnichannel');
await pageOmnichannelCurrentChats.sidenav.linkCurrentChats.click();
await page.goto('/omnichannel/current');
});
test.describe('Render Fields', () => {
test('expect show guest Field', async () => {
test.describe('Render Fields', async () => {
await test.step('expect show guest Field', async () => {
await expect(pageOmnichannelCurrentChats.guestField).toBeVisible();
});
test('expect show servedBy Field', async () => {
await test.step('expect show servedBy Field', async () => {
await expect(pageOmnichannelCurrentChats.servedByField).toBeVisible();
});
test('expect show status Field', async () => {
await test.step('expect show status Field', async () => {
await expect(pageOmnichannelCurrentChats.statusField).toBeVisible();
});
test('expect show from Field', async () => {
await test.step('expect show from Field', async () => {
await expect(pageOmnichannelCurrentChats.fromField).toBeVisible();
});
test('expect show to Field', async () => {
await test.step('expect show to Field', async () => {
await expect(pageOmnichannelCurrentChats.toField).toBeVisible();
});
test('expect show department Field', async () => {
await test.step('expect show department Field', async () => {
await expect(pageOmnichannelCurrentChats.departmentField).toBeVisible();
});
test('expect show form options button', async () => {
await test.step('expect show form options button', async () => {
await expect(pageOmnichannelCurrentChats.formOptions).toBeVisible();
});
});
test.describe('Render Options', () => {
test.describe('Render Options', async () => {
test.beforeEach(async () => {
await pageOmnichannelCurrentChats.doOpenOptions();
});
test('expect show form options button', async () => {
await test.step('expect show form options button', async () => {
await expect(pageOmnichannelCurrentChats.formOptions).toBeVisible();
});
test('expect show clear filters option', async () => {
await test.step('expect show clear filters option', async () => {
await expect(pageOmnichannelCurrentChats.clearFiltersOption).toBeVisible();
});
test('expect show removeAllClosed option', async () => {
await test.step('expect show removeAllClosed option', async () => {
await expect(pageOmnichannelCurrentChats.removeAllClosedOption).toBeVisible();
});
test('expect not to show custom fields option', async () => {
await test.step('expect not to show custom fields option', async () => {
await expect(pageOmnichannelCurrentChats.customFieldsOption).not.toBeVisible();
});
});
test.describe('Render Table', () => {
test('expect show table', async () => {
test.describe('Render Table', async () => {
await test.step('expect show table', async () => {
await expect(pageOmnichannelCurrentChats.table).toBeVisible();
});
test('expect show name header', async () => {
await test.step('expect show name header', async () => {
await expect(pageOmnichannelCurrentChats.tableHeaderName).toBeVisible();
});
test('expect show department header', async () => {
await test.step('expect show department header', async () => {
await expect(pageOmnichannelCurrentChats.tableHeaderDepartment).toBeVisible();
});
test('expect show servedBy header', async () => {
await test.step('expect show servedBy header', async () => {
await expect(pageOmnichannelCurrentChats.tableHeaderServedBy).toBeVisible();
});
test('expect show startedAt header', async () => {
await test.step('expect show startedAt header', async () => {
await expect(pageOmnichannelCurrentChats.tableHeaderStartedAt).toBeVisible();
});
test('expect show lastMessage header', async () => {
await test.step('expect show lastMessage header', async () => {
await expect(pageOmnichannelCurrentChats.tableHeaderLastMessage).toBeVisible();
});
test('expect show form status header', async () => {
await test.step('expect show form status header', async () => {
await expect(pageOmnichannelCurrentChats.tableHeaderStatus).toBeVisible();
});
});

@ -1,9 +1,15 @@
import { faker } from '@faker-js/faker';
import type { Page } from '@playwright/test';
import type { Browser, Page } from '@playwright/test';
import { test, expect } from './utils/test';
import { HomeChannel, OmnichannelLiveChat } from './page-objects';
import { createAuxContext } from './utils';
const createAuxContext = async (browser: Browser, storageState: string): Promise<{ page: Page; poHomeChannel: HomeChannel }> => {
const page = await browser.newPage({ storageState });
const poHomeChannel = new HomeChannel(page);
await page.goto('/');
return { page, poHomeChannel };
};
const newUser = {
name: faker.name.firstName(),

@ -1,13 +0,0 @@
import type { Locator, Page } from '@playwright/test';
export class AcrossPage {
private readonly page: Page;
constructor(page: Page) {
this.page = page;
}
get btnVerticalBarClose(): Locator {
return this.page.locator('[data-qa="VerticalBarActionClose"]');
}
}

@ -1,18 +1,14 @@
import type { Locator, Page } from '@playwright/test';
import { AdminSidenav } from './fragments';
import { AdminFlextab } from './fragments/admin-flextab';
export class Admin {
private readonly page: Page;
readonly sidenav: AdminSidenav;
readonly tabs: AdminFlextab;
constructor(page: Page) {
this.page = page;
this.sidenav = new AdminSidenav(page);
this.tabs = new AdminFlextab(page);
}

@ -1,29 +0,0 @@
import type { Locator, Page } from '@playwright/test';
export class AdminSidenav {
private readonly page: Page;
constructor(page: Page) {
this.page = page;
}
get linkInfo(): Locator {
return this.page.locator('.flex-nav [href="/admin/info"]');
}
get linkUsers(): Locator {
return this.page.locator('.flex-nav [href="/admin/users"]');
}
get linkRooms(): Locator {
return this.page.locator('.flex-nav [href="/admin/rooms"]');
}
get linkSettings(): Locator {
return this.page.locator('.flex-nav [href="/admin/settings"]');
}
get linkEngagementDashboard(): Locator {
return this.page.locator('.flex-nav [href="/admin/engagement-dashboard"]');
}
}

@ -31,11 +31,6 @@ export class HomeSidenav {
await this.page.locator('//*[contains(@class, "rcx-option__content") and contains(text(), "Logout")]').click();
}
async goToMyAccount(): Promise<void> {
await this.page.locator('[data-qa="sidebar-avatar-button"]').click();
await this.page.locator('//li[@class="rcx-option"]//div[contains(text(), "My Account")]').click();
}
async switchStatus(status: 'offline' | 'online'): Promise<void> {
await this.page.locator('[data-qa="sidebar-avatar-button"]').click();
await this.page.locator(`//li[@class="rcx-option"]//div[contains(text(), "${status}")]`).click();

@ -1,4 +1,3 @@
export * from './admin-sidenav';
export * from './home-content';
export * from './home-flextab';
export * from './home-sidenav';

@ -21,4 +21,8 @@ export class HomeChannel {
get toastSuccess(): Locator {
return this.page.locator('.rcx-toastbar.rcx-toastbar--success');
}
get btnVerticalBarClose(): Locator {
return this.page.locator('[data-qa="VerticalBarActionClose"]');
}
}

@ -1,5 +1,4 @@
export * from './account-profile';
export * from './across-page';
export * from './admin';
export * from './auth';
export * from './home-channel';

@ -19,11 +19,11 @@ test.describe.serial('settings-account-profile', () => {
});
// FIXME: solve test intermitencies
test.skip('expect update profile with new name/username', async () => {
test.skip('expect update profile with new name/username', async ({ page }) => {
const newName = faker.name.findName();
const newUsername = faker.internet.userName(newName);
await poHomeChannel.sidenav.goToMyAccount();
await page.goto('/account/profile');
await poAccountProfile.inputName.fill(newName);
await poAccountProfile.inputUsername.fill(newUsername);
await poAccountProfile.btnSubmit.click();
@ -39,55 +39,56 @@ test.describe.serial('settings-account-profile', () => {
await expect(poHomeChannel.tabs.userInfoUsername).toHaveText(newUsername);
});
test.describe('Personal Access Tokens', () => {
test.beforeEach(async () => {
await poHomeChannel.sidenav.goToMyAccount();
await poAccountProfile.sidenav.linkTokens.click();
});
test('Personal Access Tokens', async ({ page }) => {
await page.goto('/account/tokens');
test('expect show empty personal access tokens table', async () => {
await test.step('expect show empty personal access tokens table', async () => {
await expect(poAccountProfile.tokensTableEmpty).toBeVisible();
await expect(poAccountProfile.inputToken).toBeVisible();
});
test('expect show new personal token', async () => {
await test.step('expect show new personal token', async () => {
await poAccountProfile.inputToken.type(token);
await poAccountProfile.btnTokensAdd.click();
await expect(poAccountProfile.tokenAddedModal).toBeVisible();
await page.locator('button:has-text("Ok")').click();
});
test('expect not allow add new personal token with same name', async ({ page }) => {
await test.step('expect not allow add new personal token with same name', async () => {
await poAccountProfile.inputToken.type(token);
await poAccountProfile.btnTokensAdd.click();
await expect(page.locator('.rcx-toastbar.rcx-toastbar--error')).toBeVisible();
});
test('expect regenerate personal token', async () => {
await test.step('expect regenerate personal token', async () => {
await poAccountProfile.tokenInTable(token).locator('button >> nth=0').click();
await poAccountProfile.btnRegenerateTokenModal.click();
await expect(poAccountProfile.tokenAddedModal).toBeVisible();
await page.locator('button:has-text("Ok")').click();
});
test('expect delete personal token', async ({ page }) => {
await test.step('expect delete personal token', async () => {
await poAccountProfile.tokenInTable(token).locator('button >> nth=1').click();
await poAccountProfile.btnRemoveTokenModal.click();
await expect(page.locator('.rcx-toastbar.rcx-toastbar--success')).toBeVisible();
});
});
test.describe('Change avatar', () => {
test.beforeEach(async () => {
await poHomeChannel.sidenav.goToMyAccount();
});
test('change avatar', async ({ page }) => {
await page.goto('/account/profile');
test('expect change avatar image by upload', async ({ page }) => {
await test.step('expect change avatar image by upload', async () => {
await poAccountProfile.inputImageFile.setInputFiles('./tests/e2e/fixtures/files/test-image.jpeg');
await poAccountProfile.btnSubmit.click();
await expect(page.locator('.rcx-toastbar.rcx-toastbar--success').first()).toBeVisible();
});
test('expect set image from url', async ({ page }) => {
await test.step('expect to close toastbar', async () => {
await page.locator('.rcx-toastbar.rcx-toastbar--success').first().click();
});
await test.step('expect set image from url', async () => {
await poAccountProfile.inputAvatarLink.fill('https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50');
await poAccountProfile.btnSetAvatarLink.click();

@ -1,5 +0,0 @@
export const APP_URL = 'https://github.com/RocketChat/Apps.RocketChat.Tester/blob/master/dist/appsrocketchattester_0.0.5.zip?raw=true';
export const APP_ID = 'bc4dd4a1-bf9b-408e-83a4-aba7eba0bf02';
export const APP_NAME = 'Apps.RocketChat.Tester';
export const APP_USERNAME = 'appsrocketchattester.bot';
export const appsEndpoint = (path = '') => `/api/apps${path}`;

@ -1,12 +0,0 @@
import { APP_ID } from './apps-data';
import type { BaseTest } from '../test';
import { removeAppById } from './remove-app';
/**
* cleanupApp:
* - This helper remove the tester app from the workspace
*/
export const cleanupTesterApp = async (api: BaseTest['api']) => {
await removeAppById(api, APP_ID);
};

@ -1,3 +0,0 @@
export * from './install-test-app';
export * from './remove-app';
export * from './cleanup-app';

@ -1,11 +0,0 @@
import type { BaseTest } from '../test';
import { appsEndpoint, APP_URL } from './apps-data';
/**
* installTestApp:
* - Usefull to test apps functionalities
*/
export async function installTestApp(api: BaseTest['api']): Promise<void> {
await api.post(appsEndpoint(), { url: APP_URL }, '');
}

@ -1,11 +0,0 @@
import type { BaseTest } from '../test';
import { appsEndpoint } from './apps-data';
/**
* removeAppById:
* - This helper remove the desirable app from the workspace
*/
export const removeAppById = async (api: BaseTest['api'], id: string) => {
await api.delete(appsEndpoint(`/${id}`));
};

@ -1,15 +0,0 @@
import type { Browser, Page } from '@playwright/test';
import { HomeChannel } from '../page-objects';
/**
* createAuxContext:
* - Usefull to create a aux context for test will need many contexts
*/
export const createAuxContext = async (browser: Browser, storageState: string): Promise<{ page: Page; poHomeChannel: HomeChannel }> => {
const page = await browser.newPage({ storageState });
const poHomeChannel = new HomeChannel(page);
await page.goto('/');
return { page, poHomeChannel };
};

@ -1,3 +1 @@
export * from './create-target-channel';
export * from './create-aux-context';
export * from './apps';

Loading…
Cancel
Save