From 1798ae4d2ef8708b7de30710f8fdbabd00d93572 Mon Sep 17 00:00:00 2001 From: JasminMus <167111741+JasminMus@users.noreply.github.com> Date: Wed, 15 May 2024 17:43:18 +0200 Subject: [PATCH] Add API Workflow and chat tests (#5594) Signed-off-by: Jasmin --- tests/sanity/.env | 1 + tests/sanity/tests/API/Api.ts | 61 +++++++++++ tests/sanity/tests/channel.spec.ts | 31 ------ tests/sanity/tests/chat/chat.spec.ts | 127 +++++++++++++++++++++++ tests/sanity/tests/chat/types.ts | 7 ++ tests/sanity/tests/model/channel-page.ts | 45 +++++++- tests/sanity/tests/utils.ts | 13 +++ 7 files changed, 252 insertions(+), 33 deletions(-) create mode 100644 tests/sanity/tests/API/Api.ts delete mode 100644 tests/sanity/tests/channel.spec.ts create mode 100644 tests/sanity/tests/chat/chat.spec.ts create mode 100644 tests/sanity/tests/chat/types.ts diff --git a/tests/sanity/.env b/tests/sanity/.env index e5b4e957a9..646ea5afaf 100644 --- a/tests/sanity/.env +++ b/tests/sanity/.env @@ -3,5 +3,6 @@ PLATFORM_TRANSACTOR='ws://localhost:3334' PLATFORM_USER='user1' PLATFORM_USER_SECOND='user2' PLATFORM_TOKEN='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InVzZXIxIiwid29ya3NwYWNlIjoic2FuaXR5LXdzIn0.hfUCqePHO-WNps2by4B-CYGKIpDpLG0WVCUUtU-SVI4' +ACCOUNT_URL='http://localhost:3003/' SETTING=storage.json SETTING_SECOND=storageSecond.json diff --git a/tests/sanity/tests/API/Api.ts b/tests/sanity/tests/API/Api.ts new file mode 100644 index 0000000000..c868a8e1ad --- /dev/null +++ b/tests/sanity/tests/API/Api.ts @@ -0,0 +1,61 @@ +import { APIRequestContext } from '@playwright/test' +import { PlatformURI, AccountUrl } from '../utils' + +export class ApiEndpoint { + private readonly request: APIRequestContext + + constructor (request: APIRequestContext) { + this.request = request + } + + private getDefaultHeaders (token: string = ''): Record { + const headers: Record = { + 'Content-Type': 'application/json', + Origin: PlatformURI, + Referer: PlatformURI + } + if (token !== '') { + headers.Authorization = `Bearer ${token}` + } + return headers + } + + private async loginAndGetToken (username: string, password: string): Promise { + const loginUrl = AccountUrl + const loginPayload = { + method: 'login', + params: [username, password] + } + const headers = { + 'Content-Type': 'application/json', + Origin: PlatformURI, + Referer: PlatformURI + } + const response = await this.request.post(loginUrl, { data: loginPayload, headers }) + const token = (await response.json()).result.token + return token + } + + async createWorkspaceWithLogin (workspaceName: string, username: string, password: string): Promise { + const token = await this.loginAndGetToken(username, password) + const url = AccountUrl + const payload = { + method: 'createWorkspace', + params: [workspaceName] + } + const headers = this.getDefaultHeaders(token) + const response = await this.request.post(url, { data: payload, headers }) + return await response.json() + } + + async createAccount (username: string, password: string, firstName: string, lastName: string): Promise { + const url = AccountUrl + const payload = { + method: 'createAccount', + params: [username, password, firstName, lastName] + } + const headers = this.getDefaultHeaders() + const response = await this.request.post(url, { data: payload, headers }) + return await response.json() + } +} diff --git a/tests/sanity/tests/channel.spec.ts b/tests/sanity/tests/channel.spec.ts deleted file mode 100644 index cc1a25c996..0000000000 --- a/tests/sanity/tests/channel.spec.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { test } from '@playwright/test' -import { generateId, PlatformSetting, PlatformURI } from './utils' -import { LeftSideMenuPage } from './model/left-side-menu-page' -import { ChunterPage } from './model/chunter-page' -import { ChannelPage } from './model/channel-page' - -test.use({ - storageState: PlatformSetting -}) - -test.describe('channel tests', () => { - let leftSideMenuPage: LeftSideMenuPage - let chunterPage: ChunterPage - let channelPage: ChannelPage - test.beforeEach(async ({ page }) => { - leftSideMenuPage = new LeftSideMenuPage(page) - chunterPage = new ChunterPage(page) - channelPage = new ChannelPage(page) - await (await page.goto(`${PlatformURI}/workbench/sanity-ws`))?.finished() - }) - - test('create new private channel tests', async () => { - await leftSideMenuPage.clickChunter() - await chunterPage.clickChannelBrowser() - await chunterPage.clickNewChannelHeader() - const channel = 'channel-' + generateId() - await chunterPage.createPrivateChannel(channel, true) - await channelPage.sendMessage('Test message') - await channelPage.checkMessageExist('Test message') - }) -}) diff --git a/tests/sanity/tests/chat/chat.spec.ts b/tests/sanity/tests/chat/chat.spec.ts new file mode 100644 index 0000000000..09cc1e9245 --- /dev/null +++ b/tests/sanity/tests/chat/chat.spec.ts @@ -0,0 +1,127 @@ +import { test } from '@playwright/test' +import { PlatformURI, generateTestData } from '../utils' +import { LeftSideMenuPage } from '../model/left-side-menu-page' +import { ChunterPage } from '../model/chunter-page' +import { ChannelPage } from '../model/channel-page' +import { ApiEndpoint } from '../API/Api' +import { LoginPage } from '../model/login-page' +import { SignUpData } from '../model/common-types' +import { faker } from '@faker-js/faker' +import { SignInJoinPage } from '../model/signin-page' + +test.describe('channel tests', () => { + let leftSideMenuPage: LeftSideMenuPage + let chunterPage: ChunterPage + let channelPage: ChannelPage + let loginPage: LoginPage + let api: ApiEndpoint + let newUser2: SignUpData + let data: { workspaceName: string, userName: string, firstName: string, lastName: string, channelName: string } + + test.beforeEach(async ({ page, request }) => { + data = generateTestData() + newUser2 = { + firstName: faker.person.firstName(), + lastName: faker.person.lastName(), + email: faker.internet.email(), + password: '1234' + } + + leftSideMenuPage = new LeftSideMenuPage(page) + chunterPage = new ChunterPage(page) + channelPage = new ChannelPage(page) + loginPage = new LoginPage(page) + api = new ApiEndpoint(request) + await api.createAccount(data.userName, '1234', data.firstName, data.lastName) + await api.createWorkspaceWithLogin(data.workspaceName, data.userName, '1234') + await (await page.goto(`${PlatformURI}/workbench/${data.workspaceName}`))?.finished() + await loginPage.login(data.userName, '1234') + }) + + test('create new private channel and check if the messages stays on it', async ({ browser, page }) => { + await leftSideMenuPage.clickChunter() + await chunterPage.clickChannelBrowser() + await chunterPage.clickNewChannelHeader() + await chunterPage.createPrivateChannel(data.channelName, true) + await channelPage.checkIfChannelDefaultExist(true, data.channelName) + await channelPage.sendMessage('Test message') + await channelPage.checkMessageExist('Test message', true) + await channelPage.clickChannel('general') + await channelPage.checkMessageExist('Test message', false) + await channelPage.clickChannel(data.channelName) + await channelPage.checkMessageExist('Test message', true) + await page.reload() + await channelPage.checkMessageExist('Test message', true) + }) + + test('create new public channel and check if the messages stays on it', async ({ browser, page }) => { + await leftSideMenuPage.clickChunter() + await chunterPage.clickChannelBrowser() + await chunterPage.clickNewChannelHeader() + await chunterPage.createPrivateChannel(data.channelName, false) + await channelPage.checkIfChannelDefaultExist(true, data.channelName) + await channelPage.sendMessage('Test message') + await channelPage.checkMessageExist('Test message', true) + await channelPage.clickChannel('general') + await channelPage.checkMessageExist('Test message', false) + await channelPage.clickChannel(data.channelName) + await channelPage.checkMessageExist('Test message', true) + await page.reload() + await channelPage.checkMessageExist('Test message', true) + }) + + test('create new private channel tests and check if the new user have access to it', async ({ browser, page }) => { + await leftSideMenuPage.clickChunter() + await chunterPage.clickChannelBrowser() + await chunterPage.clickNewChannelHeader() + await chunterPage.createPrivateChannel(data.channelName, true) + await channelPage.checkIfChannelDefaultExist(true, data.channelName) + await channelPage.sendMessage('Test message') + await channelPage.checkMessageExist('Test message', true) + await leftSideMenuPage.openProfileMenu() + await leftSideMenuPage.inviteToWorkspace() + await leftSideMenuPage.getInviteLink() + + const linkText = await page.locator('.antiPopup .link').textContent() + const page2 = await browser.newPage() + const leftSideMenuPageSecond = new LeftSideMenuPage(page2) + const channelPageSecond = new ChannelPage(page2) + await api.createAccount(newUser2.email, newUser2.password, newUser2.firstName, newUser2.lastName) + await page2.goto(linkText ?? '') + const joinPage = new SignInJoinPage(page2) + await joinPage.join(newUser2) + await leftSideMenuPageSecond.clickChunter() + await channelPageSecond.checkIfChannelDefaultExist(false, data.channelName) + await channelPageSecond.clickChannelTab() + await channelPageSecond.checkIfChannelTableExist(data.channelName, false) + }) + + test('create new public channel tests and check if the new user have access to it by default', async ({ + browser, + page + }) => { + await leftSideMenuPage.clickChunter() + await chunterPage.clickChannelBrowser() + await chunterPage.clickNewChannelHeader() + await chunterPage.createPrivateChannel(data.channelName, false) + await channelPage.checkIfChannelDefaultExist(true, data.channelName) + await channelPage.sendMessage('Test message') + await channelPage.checkMessageExist('Test message', true) + await leftSideMenuPage.openProfileMenu() + await leftSideMenuPage.inviteToWorkspace() + await leftSideMenuPage.getInviteLink() + + const linkText = await page.locator('.antiPopup .link').textContent() + const page2 = await browser.newPage() + const leftSideMenuPageSecond = new LeftSideMenuPage(page2) + const channelPageSecond = new ChannelPage(page2) + await api.createAccount(newUser2.email, newUser2.password, newUser2.firstName, newUser2.lastName) + await page2.goto(linkText ?? '') + const joinPage = new SignInJoinPage(page2) + await joinPage.join(newUser2) + await leftSideMenuPageSecond.clickChunter() + await channelPageSecond.checkIfChannelDefaultExist(false, data.channelName) + await channelPageSecond.clickChannelTab() + await channelPageSecond.checkIfChannelTableExist(data.channelName, true) + }) +}) diff --git a/tests/sanity/tests/chat/types.ts b/tests/sanity/tests/chat/types.ts new file mode 100644 index 0000000000..f0d4cd37a2 --- /dev/null +++ b/tests/sanity/tests/chat/types.ts @@ -0,0 +1,7 @@ +export interface TestData { + workspaceName: string + userName: string + firstName: string + lastName: string + channelName: string +} diff --git a/tests/sanity/tests/model/channel-page.ts b/tests/sanity/tests/model/channel-page.ts index 8677c11938..1908417eb5 100644 --- a/tests/sanity/tests/model/channel-page.ts +++ b/tests/sanity/tests/model/channel-page.ts @@ -10,13 +10,54 @@ export class ChannelPage { readonly inputMessage = (): Locator => this.page.locator('div[class~="text-editor-view"]') readonly buttonSendMessage = (): Locator => this.page.locator('g#Send') readonly textMessage = (): Locator => this.page.getByText('Test message') + readonly channelName = (channel: string): Locator => this.page.getByText('general random').getByText(channel) + readonly channelTab = (): Locator => this.page.getByRole('link', { name: 'Channels' }).getByRole('button') + readonly channelTable = (): Locator => this.page.locator('[class="antiTable metaColumn highlightRows"]') + readonly channel = (channel: string): Locator => this.page.getByRole('button', { name: channel }) async sendMessage (message: string): Promise { await this.inputMessage().fill(message) await this.buttonSendMessage().click() } - async checkMessageExist (message: string): Promise { - await expect(this.textMessage().filter({ hasText: message })).toBeVisible() + async clickChannel (channel: string): Promise { + await this.channel(channel).click() + } + + async checkMessageExist (message: string, messageExists: boolean): Promise { + if (messageExists) { + await expect(this.textMessage().filter({ hasText: message })).toBeVisible() + } else { + await expect(this.textMessage().filter({ hasText: message })).toBeHidden() + } + } + + async clickChannelTab (): Promise { + await this.channelTab().click() + } + + async checkIfChannelDefaultExist (shouldExist: boolean, channel: string): Promise { + if (shouldExist) { + await expect(this.channelName(channel)).toBeVisible() + } else { + await expect(this.channelName(channel)).toBeHidden() + } + } + + async checkIfChannelTableExist (channel: string, publicChannel: boolean): Promise { + if (publicChannel) { + await expect(this.channelTable()).toBeVisible() + await expect(this.channelTable()).toContainText(channel) + } else { + await expect(this.channelTable()).not.toContainText(channel) + } + } + + async checkIfMessageExist (messageExists: boolean): Promise { + if (messageExists) { + await expect(this.textMessage()).toBeVisible() + } else { + await expect(this.textMessage()).toBeHidden() + } } } diff --git a/tests/sanity/tests/utils.ts b/tests/sanity/tests/utils.ts index f7dc65c1b5..6f05355697 100644 --- a/tests/sanity/tests/utils.ts +++ b/tests/sanity/tests/utils.ts @@ -1,5 +1,7 @@ import { Browser, BrowserContext, Locator, Page, expect } from '@playwright/test' import { allure } from 'allure-playwright' +import { faker } from '@faker-js/faker' +import { TestData } from './chat/types' export const PlatformURI = process.env.PLATFORM_URI as string export const PlatformTransactor = process.env.PLATFORM_TRANSACTOR as string @@ -8,6 +10,17 @@ export const PlatformUserSecond = process.env.PLATFORM_USER_SECOND as string export const PlatformSetting = process.env.SETTING as string export const PlatformSettingSecond = process.env.SETTING_SECOND as string export const DefaultWorkspace = 'SanityTest' +export const AccountUrl = process.env.ACCOUNT_URL as string + +export function generateTestData (): TestData { + return { + workspaceName: faker.lorem.word(), + userName: faker.internet.userName(), + firstName: faker.person.firstName(), + lastName: faker.person.lastName(), + channelName: faker.lorem.word() + } +} function toHex (value: number, chars: number): string { const result = value.toString(16)