Add API Workflow and chat tests (#5594)

Signed-off-by: Jasmin <jasmin@hardcoreeng.com>
This commit is contained in:
JasminMus 2024-05-15 17:43:18 +02:00 committed by GitHub
parent 167ad3378b
commit 1798ae4d2e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 252 additions and 33 deletions

View File

@ -3,5 +3,6 @@ PLATFORM_TRANSACTOR='ws://localhost:3334'
PLATFORM_USER='user1' PLATFORM_USER='user1'
PLATFORM_USER_SECOND='user2' PLATFORM_USER_SECOND='user2'
PLATFORM_TOKEN='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InVzZXIxIiwid29ya3NwYWNlIjoic2FuaXR5LXdzIn0.hfUCqePHO-WNps2by4B-CYGKIpDpLG0WVCUUtU-SVI4' PLATFORM_TOKEN='eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6InVzZXIxIiwid29ya3NwYWNlIjoic2FuaXR5LXdzIn0.hfUCqePHO-WNps2by4B-CYGKIpDpLG0WVCUUtU-SVI4'
ACCOUNT_URL='http://localhost:3003/'
SETTING=storage.json SETTING=storage.json
SETTING_SECOND=storageSecond.json SETTING_SECOND=storageSecond.json

View File

@ -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<string, string> {
const headers: Record<string, string> = {
'Content-Type': 'application/json',
Origin: PlatformURI,
Referer: PlatformURI
}
if (token !== '') {
headers.Authorization = `Bearer ${token}`
}
return headers
}
private async loginAndGetToken (username: string, password: string): Promise<string> {
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<any> {
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<any> {
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()
}
}

View File

@ -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')
})
})

View File

@ -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)
})
})

View File

@ -0,0 +1,7 @@
export interface TestData {
workspaceName: string
userName: string
firstName: string
lastName: string
channelName: string
}

View File

@ -10,13 +10,54 @@ export class ChannelPage {
readonly inputMessage = (): Locator => this.page.locator('div[class~="text-editor-view"]') readonly inputMessage = (): Locator => this.page.locator('div[class~="text-editor-view"]')
readonly buttonSendMessage = (): Locator => this.page.locator('g#Send') readonly buttonSendMessage = (): Locator => this.page.locator('g#Send')
readonly textMessage = (): Locator => this.page.getByText('Test message') 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<void> { async sendMessage (message: string): Promise<void> {
await this.inputMessage().fill(message) await this.inputMessage().fill(message)
await this.buttonSendMessage().click() await this.buttonSendMessage().click()
} }
async checkMessageExist (message: string): Promise<void> { async clickChannel (channel: string): Promise<void> {
await expect(this.textMessage().filter({ hasText: message })).toBeVisible() await this.channel(channel).click()
}
async checkMessageExist (message: string, messageExists: boolean): Promise<void> {
if (messageExists) {
await expect(this.textMessage().filter({ hasText: message })).toBeVisible()
} else {
await expect(this.textMessage().filter({ hasText: message })).toBeHidden()
}
}
async clickChannelTab (): Promise<void> {
await this.channelTab().click()
}
async checkIfChannelDefaultExist (shouldExist: boolean, channel: string): Promise<void> {
if (shouldExist) {
await expect(this.channelName(channel)).toBeVisible()
} else {
await expect(this.channelName(channel)).toBeHidden()
}
}
async checkIfChannelTableExist (channel: string, publicChannel: boolean): Promise<void> {
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<void> {
if (messageExists) {
await expect(this.textMessage()).toBeVisible()
} else {
await expect(this.textMessage()).toBeHidden()
}
} }
} }

View File

@ -1,5 +1,7 @@
import { Browser, BrowserContext, Locator, Page, expect } from '@playwright/test' import { Browser, BrowserContext, Locator, Page, expect } from '@playwright/test'
import { allure } from 'allure-playwright' 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 PlatformURI = process.env.PLATFORM_URI as string
export const PlatformTransactor = process.env.PLATFORM_TRANSACTOR 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 PlatformSetting = process.env.SETTING as string
export const PlatformSettingSecond = process.env.SETTING_SECOND as string export const PlatformSettingSecond = process.env.SETTING_SECOND as string
export const DefaultWorkspace = 'SanityTest' 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 { function toHex (value: number, chars: number): string {
const result = value.toString(16) const result = value.toString(16)