diff --git a/tests/sanity/tests/chat/chat.spec.ts b/tests/sanity/tests/chat/chat.spec.ts index e3d85cd777..08db15f311 100644 --- a/tests/sanity/tests/chat/chat.spec.ts +++ b/tests/sanity/tests/chat/chat.spec.ts @@ -6,10 +6,16 @@ import { SignUpData } from '../model/common-types' import { LeftSideMenuPage } from '../model/left-side-menu-page' import { LoginPage } from '../model/login-page' import { SelectWorkspacePage } from '../model/select-workspace-page' -import { SignInJoinPage } from '../model/signin-page' -import { PlatformURI, createAccount, generateTestData, generateUser, getInviteLink, getSecondPage } from '../utils' +import { + PlatformURI, + generateTestData, + getInviteLink, + generateUser, + createAccount, + getSecondPageByInvite +} from '../utils' -test.describe('channel tests', () => { +test.describe('Channel tests', () => { let leftSideMenuPage: LeftSideMenuPage let chunterPage: ChunterPage let channelPage: ChannelPage @@ -33,10 +39,9 @@ test.describe('channel tests', () => { await loginPage.login(data.userName, '1234') const swp = new SelectWorkspacePage(page) await swp.selectWorkspace(data.workspaceName) - // await (await page.goto(`${PlatformURI}/workbench/${data.workspaceName}`))?.finished() }) - test('create new private channel and check if the messages stays on it', async ({ browser, page }) => { + 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() @@ -52,7 +57,7 @@ test.describe('channel tests', () => { await channelPage.checkMessageExist('Test message', true, 'Test message') }) - test('create new public channel and check if the messages stays on it', async ({ browser, page }) => { + 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() @@ -68,7 +73,7 @@ test.describe('channel tests', () => { await channelPage.checkMessageExist('Test message', true, 'Test message') }) - test('create new private channel tests and check if the new user have access to it', async ({ browser, page }) => { + 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() @@ -76,27 +81,22 @@ test.describe('channel tests', () => { await channelPage.checkIfChannelDefaultExist(true, data.channelName) await channelPage.sendMessage('Test message') await channelPage.checkMessageExist('Test message', true, 'Test message') - await leftSideMenuPage.openProfileMenu() - await leftSideMenuPage.inviteToWorkspace() - await leftSideMenuPage.getInviteLink() - const linkText = await page.locator('.antiPopup .link').textContent() - using _page = await getSecondPage(browser) - const page2 = _page.page + const linkText = await getInviteLink(page) + await api.createAccount(newUser2.email, newUser2.password, newUser2.firstName, newUser2.lastName) + using _page2 = await getSecondPageByInvite(browser, linkText, newUser2) + const page2 = _page2.page 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 ({ + test('Create new public channel tests and check if the new user have access to it by default', async ({ browser, page }) => { @@ -107,27 +107,21 @@ test.describe('channel tests', () => { await channelPage.checkIfChannelDefaultExist(true, data.channelName) await channelPage.sendMessage('Test message') await channelPage.checkMessageExist('Test message', true, 'Test message') - await leftSideMenuPage.openProfileMenu() - await leftSideMenuPage.inviteToWorkspace() - await leftSideMenuPage.getInviteLink() - const linkText = await page.locator('.antiPopup .link').textContent() - using _page = await getSecondPage(browser) - const page2 = _page.page + const linkText = await getInviteLink(page) + await api.createAccount(newUser2.email, newUser2.password, newUser2.firstName, newUser2.lastName) + using _page2 = await getSecondPageByInvite(browser, linkText, newUser2) + const page2 = _page2.page 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) }) - test('create new private channel and test if the user can exchange the messages', async ({ browser, page }) => { + test('Create new private channel and test if the user can exchange the messages', async ({ browser, page }) => { await leftSideMenuPage.clickChunter() await chunterPage.clickChannelBrowser() await chunterPage.clickNewChannelHeader() @@ -135,21 +129,15 @@ test.describe('channel tests', () => { await channelPage.checkIfChannelDefaultExist(true, data.channelName) await channelPage.sendMessage('Test message') await channelPage.checkMessageExist('Test message', true, 'Test message') - await leftSideMenuPage.openProfileMenu() - await leftSideMenuPage.inviteToWorkspace() - await leftSideMenuPage.getInviteLink() - const linkText = await page.locator('.antiPopup .link').textContent() - using _page = await getSecondPage(browser) - const page2 = _page.page + const linkText = await getInviteLink(page) + await api.createAccount(newUser2.email, newUser2.password, newUser2.firstName, newUser2.lastName) + using _page2 = await getSecondPageByInvite(browser, linkText, newUser2) + const page2 = _page2.page const leftSideMenuPageSecond = new LeftSideMenuPage(page2) const channelPageSecond = new ChannelPage(page2) - await leftSideMenuPage.clickOnCloseInvite() - 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() @@ -164,7 +152,7 @@ test.describe('channel tests', () => { await channelPage.checkMessageExist('My dream is to fly', true, 'My dream is to fly') }) - test('create new private channel add user to it', async ({ browser, page }) => { + test('Create new private channel add user to it', async ({ browser, page }) => { await leftSideMenuPage.clickChunter() await chunterPage.clickChannelBrowser() await chunterPage.clickNewChannelHeader() @@ -172,21 +160,15 @@ test.describe('channel tests', () => { await channelPage.checkIfChannelDefaultExist(true, data.channelName) await channelPage.sendMessage('Test message') await channelPage.checkMessageExist('Test message', true, 'Test message') - await leftSideMenuPage.openProfileMenu() - await leftSideMenuPage.inviteToWorkspace() - await leftSideMenuPage.getInviteLink() - const linkText = await page.locator('.antiPopup .link').textContent() - using _page = await getSecondPage(browser) - const page2 = _page.page + const linkText = await getInviteLink(page) + await api.createAccount(newUser2.email, newUser2.password, newUser2.firstName, newUser2.lastName) + using _page2 = await getSecondPageByInvite(browser, linkText, newUser2) + const page2 = _page2.page const leftSideMenuPageSecond = new LeftSideMenuPage(page2) const channelPageSecond = new ChannelPage(page2) - await leftSideMenuPage.clickOnCloseInvite() - 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 channelPage.clickChannelTab() await channelPage.clickOnUser(data.lastName + ' ' + data.firstName) @@ -204,27 +186,21 @@ test.describe('channel tests', () => { await channelPage.checkMessageExist('One two', true, 'One two') }) - test('go to general channel add user to it', async ({ browser, page }) => { + test('Go to general channel add user to it', async ({ browser, page }) => { await leftSideMenuPage.clickChunter() await channelPage.clickChannel('general') await channelPage.sendMessage('Test message') await channelPage.checkMessageExist('Test message', true, 'Test message') - await leftSideMenuPage.openProfileMenu() - await leftSideMenuPage.inviteToWorkspace() - await leftSideMenuPage.getInviteLink() - const linkText = await page.locator('.antiPopup .link').textContent() - using _page = await getSecondPage(browser) - const page2 = _page.page + const linkText = await getInviteLink(page) + await api.createAccount(newUser2.email, newUser2.password, newUser2.firstName, newUser2.lastName) + using _page2 = await getSecondPageByInvite(browser, linkText, newUser2) + const page2 = _page2.page const leftSideMenuPageSecond = new LeftSideMenuPage(page2) const channelPageSecond = new ChannelPage(page2) - await leftSideMenuPage.clickOnCloseInvite() - 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.clickChannel('general') await channelPageSecond.checkMessageExist('Test message', true, 'Test message') @@ -236,27 +212,21 @@ test.describe('channel tests', () => { await channelPage.checkMessageExist('One two', true, 'One two') }) - test('go to random channel add user to it', async ({ browser, page }) => { + test('Go to random channel add user to it', async ({ browser, page }) => { await leftSideMenuPage.clickChunter() await channelPage.clickChannel('random') await channelPage.sendMessage('Test message') await channelPage.checkMessageExist('Test message', true, 'Test message') - await leftSideMenuPage.openProfileMenu() - await leftSideMenuPage.inviteToWorkspace() - await leftSideMenuPage.getInviteLink() - const linkText = await page.locator('.antiPopup .link').textContent() - using _page = await getSecondPage(browser) - const page2 = _page.page + const linkText = await getInviteLink(page) + await api.createAccount(newUser2.email, newUser2.password, newUser2.firstName, newUser2.lastName) + using _page2 = await getSecondPageByInvite(browser, linkText, newUser2) + const page2 = _page2.page const leftSideMenuPageSecond = new LeftSideMenuPage(page2) const channelPageSecond = new ChannelPage(page2) - await leftSideMenuPage.clickOnCloseInvite() - 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.clickChannel('random') await channelPageSecond.checkMessageExist('Test message', true, 'Test message') @@ -268,7 +238,7 @@ test.describe('channel tests', () => { await channelPage.checkMessageExist('One two', true, 'One two') }) - test('check if user can add emoji', async () => { + test('Check if user can add emoji', async () => { await leftSideMenuPage.clickChunter() await channelPage.clickChannel('random') await channelPage.sendMessage('Test message') @@ -277,7 +247,7 @@ test.describe('channel tests', () => { await channelPage.checkIfEmojiIsAdded('😤') }) - test('check if user can save message', async () => { + test('Check if user can save message', async () => { await leftSideMenuPage.clickChunter() await channelPage.clickChannel('random') await channelPage.sendMessage('Test message') @@ -287,7 +257,7 @@ test.describe('channel tests', () => { await channelPage.checkIfMessageExist(true, 'Test message') }) - test('check if user can pin message', async () => { + test('Check if user can pin message', async () => { await leftSideMenuPage.clickChunter() await channelPage.clickChannel('random') await channelPage.sendMessage('Test message') @@ -297,7 +267,7 @@ test.describe('channel tests', () => { await channelPage.checkIfMessageExist(true, 'Reply message') }) - test('check if user can edit message', async ({ page }) => { + test('Check if user can edit message', async ({ page }) => { await leftSideMenuPage.clickChunter() await channelPage.clickChannel('random') await channelPage.sendMessage('Test message') @@ -311,7 +281,7 @@ test.describe('channel tests', () => { await channelPage.checkIfMessageExist(true, 'Test message edited message 1') }) - test('check if user can copy message', async ({ page }) => { + test('Check if user can copy message', async ({ page }) => { const baseURL = process.env.PLATFORM_URI ?? 'http://localhost:8083' const expectedUrl = `${baseURL}/workbench/${data.workspaceName}/chunter/chunter:space:Random|chunter:class:Channel?message=` await leftSideMenuPage.clickChunter() @@ -325,7 +295,7 @@ test.describe('channel tests', () => { expect(clipboardContent).toContain(expectedUrl) }) - test('check if user can delete messages', async ({ page }) => { + test('Check if user can delete messages', async ({ page }) => { await leftSideMenuPage.clickChunter() await channelPage.clickChannel('random') await channelPage.sendMessage('Test message') @@ -367,26 +337,18 @@ test.describe('channel tests', () => { }) test('Check if the user can be added through preview tab', async ({ browser, page }) => { - await leftSideMenuPage.openProfileMenu() - await leftSideMenuPage.inviteToWorkspace() - await leftSideMenuPage.getInviteLink() + const linkText = await getInviteLink(page) + await api.createAccount(newUser2.email, newUser2.password, newUser2.firstName, newUser2.lastName) + using _page2 = await getSecondPageByInvite(browser, linkText, newUser2) + const page2 = _page2.page - const linkText = await page.locator('.antiPopup .link').textContent() - using _page = await getSecondPage(browser) - const page2 = _page.page const leftSideMenuPageSecond = new LeftSideMenuPage(page2) const channelPageSecond = new ChannelPage(page2) - await leftSideMenuPage.clickOnCloseInvite() - 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.clickChannel('general') await channelPageSecond.clickOnOpenChannelDetails() await channelPageSecond.checkIfUserIsAdded(data.lastName + ' ' + data.firstName, false) - await page2.close() }) test('Check if we can create new public channel tests and check if the new user have can be added through preview', async ({ @@ -398,17 +360,14 @@ test.describe('channel tests', () => { await chunterPage.clickNewChannelHeader() await chunterPage.createPrivateChannel(data.channelName, false) await channelPage.checkIfChannelDefaultExist(true, data.channelName) - await leftSideMenuPage.openProfileMenu() - await leftSideMenuPage.inviteToWorkspace() - await leftSideMenuPage.getInviteLink() - const linkText = await page.locator('.antiPopup .link').textContent() - await leftSideMenuPage.clickOnCloseInvite() - using _page = await getSecondPage(browser) - const page2 = _page.page + + const linkText = await getInviteLink(page) await api.createAccount(newUser2.email, newUser2.password, newUser2.firstName, newUser2.lastName) - await page2.goto(linkText ?? '') - const joinPage = new SignInJoinPage(page2) - await joinPage.join(newUser2) + using _page2 = await getSecondPageByInvite(browser, linkText, newUser2) + const page2 = _page2.page + const leftSideMenuPageSecond = new LeftSideMenuPage(page2) + await leftSideMenuPageSecond.clickChunter() + await leftSideMenuPage.clickChunter() await channelPage.clickChannel('general') await channelPage.clickChannel(data.channelName) @@ -419,13 +378,11 @@ test.describe('channel tests', () => { test('Checking backlinks in the Chat', async ({ browser, page, request }) => { await createAccount(request, newUser2) const linkText = await getInviteLink(page) - using _page = await getSecondPage(browser) - const page2 = _page.page + using _page2 = await getSecondPageByInvite(browser, linkText, newUser2) + const page2 = _page2.page + const leftSideMenuPageSecond = new LeftSideMenuPage(page2) const channelPageSecond = new ChannelPage(page2) - await page2.goto(linkText ?? '') - const joinPage = new SignInJoinPage(page2) - await joinPage.join(newUser2) await leftSideMenuPageSecond.clickChunter() await leftSideMenuPage.clickChunter() @@ -437,4 +394,129 @@ test.describe('channel tests', () => { await channelPageSecond.clickChannel('general') await channelPageSecond.checkMessageExist(`@${mentionName}`, true, `@${mentionName}`) }) + + test('User can star and unstar a channel', async () => { + await test.step('Prepare channel', async () => { + await leftSideMenuPage.clickChunter() + await chunterPage.clickChannelBrowser() + await chunterPage.clickNewChannelHeader() + await chunterPage.createPrivateChannel(data.channelName, false) + await channelPage.checkIfChannelDefaultExist(true, data.channelName) + }) + + await test.step('Star channel', async () => { + await leftSideMenuPage.clickChunter() + await channelPage.makeActionWithChannelInMenu(data.channelName, 'Star channel') + await channelPage.checkChannelStarred(true, data.channelName) + await channelPage.checkIfChannelDefaultExist(false, data.channelName) + }) + + await test.step('Unstar channel', async () => { + await leftSideMenuPage.clickChunter() + await channelPage.makeActionWithChannelInMenu(data.channelName, 'Unstar channel') + await channelPage.checkChannelStarred(false, data.channelName) + await channelPage.checkIfChannelDefaultExist(true, data.channelName) + }) + }) + + test('User can leave and join a channel', async () => { + await test.step('Prepare channel', async () => { + await leftSideMenuPage.clickChunter() + await chunterPage.clickChannelBrowser() + await chunterPage.clickNewChannelHeader() + await chunterPage.createPrivateChannel(data.channelName, false) + await channelPage.checkIfChannelDefaultExist(true, data.channelName) + + await leftSideMenuPage.clickChunter() + await channelPage.clickChooseChannel(data.channelName) + await channelPage.sendMessage('Test message') + }) + + await test.step('Leave channel #1', async () => { + await channelPage.makeActionWithChannelInMenu(data.channelName, 'Leave channel') + }) + + await test.step('Join channel from a leaved channel page', async () => { + await channelPage.checkIfChannelDefaultExist(true, data.channelName) + await channelPage.clickJoinChannelButton() + await channelPage.checkIfChannelDefaultExist(true, data.channelName) + }) + + await test.step('Leave channel #2', async () => { + await channelPage.makeActionWithChannelInMenu(data.channelName, 'Leave channel') + }) + + await test.step('Open another channel and then check that leaved channel is removed from left menu', async () => { + await channelPage.clickChooseChannel('random') + await channelPage.checkIfChannelDefaultExist(false, data.channelName) + }) + + await test.step('Join channel from a channels table', async () => { + await channelPage.clickChannelTab() + await channelPage.checkIfChannelTableExist(data.channelName, true) + await channelPage.clickJoinChannelButton() + await channelPage.checkIfChannelDefaultExist(true, data.channelName) + await channelPage.clickChooseChannel(data.channelName) + await channelPage.checkMessageExist('Test message', true, 'Test message') + }) + }) + + test('User can filter channels in table', async () => { + await test.step('Prepare channel', async () => { + await leftSideMenuPage.clickChunter() + await chunterPage.clickChannelBrowser() + await chunterPage.clickNewChannelHeader() + await chunterPage.createPrivateChannel(data.channelName, false) + await channelPage.checkIfChannelDefaultExist(true, data.channelName) + + await leftSideMenuPage.clickChunter() + await channelPage.clickChannelTab() + }) + + await test.step('Test filtering by name', async () => { + await channelPage.selectFilter('Name', data.channelName) + await channelPage.checkFilter('Name', 'contains', data.channelName) + await channelPage.checkIfChannelTableExist(data.channelName, true) + await channelPage.checkIfChannelTableExist('general', false) + }) + + await test.step('Clear Filters', async () => { + await channelPage.buttonClearFilters().click() + await channelPage.checkIfChannelTableExist('general', true) + }) + }) + + test('User can search channel in table', async () => { + await test.step('Prepare channel', async () => { + await leftSideMenuPage.clickChunter() + await chunterPage.clickChannelBrowser() + await chunterPage.clickNewChannelHeader() + await chunterPage.createPrivateChannel(data.channelName, false) + await channelPage.checkIfChannelDefaultExist(true, data.channelName) + + await leftSideMenuPage.clickChunter() + await channelPage.clickChannelTab() + }) + + await test.step('Search channel by first 3 char and find nothing', async () => { + await channelPage.searchChannel(data.channelName.slice(0, 3)) + await channelPage.page.keyboard.press('Enter') + await channelPage.checkIfChannelTableExist(data.channelName, false) + await channelPage.checkIfChannelTableExist('general', false) + }) + + await test.step('Search channel by fillName and find channel', async () => { + await channelPage.searchChannel(data.channelName) + await channelPage.page.keyboard.press('Enter') + await channelPage.checkIfChannelTableExist(data.channelName, true) + await channelPage.checkIfChannelTableExist('general', false) + }) + + await test.step('Clear search and show all channels', async () => { + await channelPage.searchChannel('') + await channelPage.page.keyboard.press('Enter') + await channelPage.checkIfChannelTableExist(data.channelName, true) + await channelPage.checkIfChannelTableExist('general', true) + }) + }) }) diff --git a/tests/sanity/tests/chat/direct-chat.spec.ts b/tests/sanity/tests/chat/direct-chat.spec.ts new file mode 100644 index 0000000000..8c23154200 --- /dev/null +++ b/tests/sanity/tests/chat/direct-chat.spec.ts @@ -0,0 +1,85 @@ +import { expect, test } from '@playwright/test' +import { ApiEndpoint } from '../API/Api' +import { ChannelPage } from '../model/channel-page' +import { ChunterPage } from '../model/chunter-page' +import { SignUpData } from '../model/common-types' +import { LeftSideMenuPage } from '../model/left-side-menu-page' +import { LoginPage } from '../model/login-page' +import { SelectWorkspacePage } from '../model/select-workspace-page' +import { + PlatformURI, + generateTestData, + getInviteLink, + generateUser, + createAccount, + getSecondPageByInvite +} from '../utils' + +test.describe('Check direct messages channels', () => { + 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 = generateUser() + + 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}`))?.finished() + await loginPage.login(data.userName, '1234') + const swp = new SelectWorkspacePage(page) + await swp.selectWorkspace(data.workspaceName) + }) + + test('User can create/close/reacreate direct chat with employee', async ({ request, page, browser }) => { + const linkText = await getInviteLink(page) + await createAccount(request, newUser2) + using _page2 = await getSecondPageByInvite(browser, linkText, newUser2) + const page2 = _page2.page + const channelPageSecond = new ChannelPage(page2) + const leftSideMenuPageSecond = new LeftSideMenuPage(page2) + await leftSideMenuPageSecond.clickChunter() + + await test.step('Create a direct chat', async () => { + await leftSideMenuPage.clickChunter() + await chunterPage.createDirectChat(newUser2) + }) + + await test.step('Exchange messages in the direct chat', async () => { + await channelPage.clickChooseChannel(`${newUser2.lastName} ${newUser2.firstName}`) + await channelPage.sendMessage('Test direct question') + + await channelPageSecond.clickChooseChannel(`${data.lastName} ${data.firstName}`) + await channelPageSecond.checkMessageExist('Test direct question', true, 'Test direct question') + await channelPageSecond.sendMessage('Test direct answer') + + await channelPage.checkMessageExist('Test direct answer', true, 'Test direct answer') + }) + + await test.step('Close conversation', async () => { + await leftSideMenuPage.clickChunter() + await channelPage.makeActionWithChannelInMenu(`${newUser2.lastName} ${newUser2.firstName}`, 'Close conversation') + await expect(chunterPage.directMessagesButtonInLeftMenu()).toBeHidden() + }) + + await test.step('Recreate a direct chat and see if messages are kept', async () => { + await page.reload() + await leftSideMenuPage.clickChunter() + await channelPage.clickChooseChannel('general') + + await chunterPage.createDirectChat(newUser2) + await channelPage.clickChooseChannel(`${newUser2.lastName} ${newUser2.firstName}`) + await channelPage.checkMessageExist('Test direct answer', true, 'Test direct answer') + }) + }) +}) diff --git a/tests/sanity/tests/chat/dynamic-issues-chats.spec.ts b/tests/sanity/tests/chat/dynamic-issues-chats.spec.ts new file mode 100644 index 0000000000..b6bb17e58d --- /dev/null +++ b/tests/sanity/tests/chat/dynamic-issues-chats.spec.ts @@ -0,0 +1,106 @@ +import { test } from '@playwright/test' +import { ApiEndpoint } from '../API/Api' +import { ChannelPage } from '../model/channel-page' +import { SignUpData } from '../model/common-types' +import { LeftSideMenuPage } from '../model/left-side-menu-page' +import { LoginPage } from '../model/login-page' +import { SelectWorkspacePage } from '../model/select-workspace-page' +import { + PlatformURI, + generateTestData, + generateUser, + getInviteLink, + createAccount, + generateId, + getSecondPageByInvite +} from '../utils' +import { IssuesDetailsPage } from '../model/tracker/issues-details-page' +import { NewIssue } from '../model/tracker/types' +import { prepareNewIssueWithOpenStep } from '../tracker/common-steps' +import { LinkedChannelTypes } from '../model/types' + +test.describe('Dynamic issues chats', () => { + let leftSideMenuPage: LeftSideMenuPage + 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 = generateUser() + + leftSideMenuPage = new LeftSideMenuPage(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}`))?.finished() + await loginPage.login(data.userName, '1234') + const swp = new SelectWorkspacePage(page) + await swp.selectWorkspace(data.workspaceName) + }) + + test('User can create issue for himself and see linked chat', async ({ page, browser, request }) => { + await leftSideMenuPage.clickTracker() + + const newIssue: NewIssue = { + title: `Issue to test dynamic chat-${generateId()}`, + description: 'Created issue with all parameters and attachments description', + status: 'ToDo', + priority: 'High', + assignee: `${data.lastName} ${data.firstName}` + } + + await test.step('User 1 creates Issue for himself', async () => { + await prepareNewIssueWithOpenStep(page, newIssue) + }) + + await test.step('User 1 has issue and linked chat', async () => { + await leftSideMenuPage.clickChunter() + await channelPage.checkLinkedChannelIsExist(newIssue.title, LinkedChannelTypes.Issue) + }) + }) + + test('User can see chat for assigned issue from other user', async ({ page, browser, request }) => { + const linkText = await getInviteLink(page) + await createAccount(request, newUser2) + using _page2 = await getSecondPageByInvite(browser, linkText, newUser2) + const page2 = _page2.page + + const channelPageSecond = new ChannelPage(page2) + const leftSideMenuPageSecond = new LeftSideMenuPage(page2) + await leftSideMenuPageSecond.clickChunter() + + const newIssue: NewIssue = { + title: `Issue to test dynamic chat-${generateId()}`, + description: 'Created issue for employee with all parameters and attachments description', + status: 'ToDo', + priority: 'High', + assignee: `${newUser2.lastName} ${newUser2.firstName}` + } + + await test.step('User 1 creates an issue and assign it to User 2', async () => { + await prepareNewIssueWithOpenStep(page, newIssue) + }) + + await test.step('User 2 has issue and linked chat', async () => { + await leftSideMenuPageSecond.clickChunter() + await channelPageSecond.checkLinkedChannelIsExist(newIssue.title, LinkedChannelTypes.Issue) + }) + + await test.step('User 1 adds comment and User 2 sees it in chat', async () => { + const commentText = `Comment to show in chat-${generateId()}` + const issuesDetailsPage = new IssuesDetailsPage(page) + await issuesDetailsPage.waitDetailsOpened(newIssue.title) + await issuesDetailsPage.addComment(commentText) + await issuesDetailsPage.checkCommentExist(commentText) + + await channelPageSecond.clickChooseChannel(newIssue.title) + await channelPageSecond.checkMessageExist(commentText, true, commentText) + }) + }) +}) diff --git a/tests/sanity/tests/chat/dynamic-recruting-chats.spec.ts b/tests/sanity/tests/chat/dynamic-recruting-chats.spec.ts new file mode 100644 index 0000000000..d8ccb29580 --- /dev/null +++ b/tests/sanity/tests/chat/dynamic-recruting-chats.spec.ts @@ -0,0 +1,80 @@ +import { test } from '@playwright/test' +import { ApiEndpoint } from '../API/Api' +import { ChannelPage } from '../model/channel-page' +import { LeftSideMenuPage } from '../model/left-side-menu-page' +import { LoginPage } from '../model/login-page' +import { SelectWorkspacePage } from '../model/select-workspace-page' +import { PlatformURI, generateTestData, generateId } from '../utils' +import { LinkedChannelTypes } from '../model/types' +import { VacanciesPage } from '../model/recruiting/vacancies-page' +import { TalentsPage } from '../model/recruiting/talents-page' +import { TalentName } from '../model/recruiting/types' + +test.describe('Dynamic reqruting chats', () => { + let leftSideMenuPage: LeftSideMenuPage + let channelPage: ChannelPage + let vacanciesPage: VacanciesPage + let talentsPage: TalentsPage + let loginPage: LoginPage + let api: ApiEndpoint + let data: { workspaceName: string, userName: string, firstName: string, lastName: string, channelName: string } + + test.beforeEach(async ({ page, request }) => { + data = generateTestData() + + leftSideMenuPage = new LeftSideMenuPage(page) + channelPage = new ChannelPage(page) + vacanciesPage = new VacanciesPage(page) + talentsPage = new TalentsPage(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}`))?.finished() + await loginPage.login(data.userName, '1234') + const swp = new SelectWorkspacePage(page) + await swp.selectWorkspace(data.workspaceName) + }) + + test('User can work with a vacancy/talent/aplications and see linked chat', async () => { + await leftSideMenuPage.clickRecruiting() + const newVacancyTitle = `Vacancy ${generateId()}` + let talentName: TalentName + + await test.step('Create vacancy', async () => { + await vacanciesPage.createVacancy(newVacancyTitle) + }) + + await test.step('User has linked vacancy chat', async () => { + await leftSideMenuPage.clickChunter() + await channelPage.checkLinkedChannelIsExist(newVacancyTitle, LinkedChannelTypes.Vacancy) + }) + + await test.step('Prepare a talent', async () => { + await leftSideMenuPage.clickRecruiting() + await talentsPage.clickTalentsTab() + talentName = await talentsPage.createNewTalent() + await talentsPage.openTalentByTalentName(talentName) + }) + + await test.step('Create application', async () => { + await talentsPage.clickAddApplication() + await talentsPage.selectSpace() + await talentsPage.searchAndSelectVacancy(newVacancyTitle) + await talentsPage.waitForHRInterviewVisible() + await talentsPage.createApplication() + await talentsPage.clickVacancyApplication(newVacancyTitle) + await talentsPage.assignRecruiter() + await talentsPage.selectRecruterToAssignByName(`${data.lastName} ${data.firstName}`) + }) + + await test.step('User has linked application chat', async () => { + await leftSideMenuPage.clickChunter() + await channelPage.checkLinkedChannelIsExist( + `${talentName.lastName} ${talentName.firstName}`, + LinkedChannelTypes.Application + ) + }) + }) +}) diff --git a/tests/sanity/tests/documents/documents-content.spec.ts b/tests/sanity/tests/documents/documents-content.spec.ts index 71271d0e46..bff9023129 100644 --- a/tests/sanity/tests/documents/documents-content.spec.ts +++ b/tests/sanity/tests/documents/documents-content.spec.ts @@ -50,26 +50,27 @@ test.describe('Content in the Documents tests', () => { } testData = generateTestData() - newUser2 = generateUser() await createAccountAndWorkspace(page, request, testData) - await createAccount(request, newUser2) - const linkText = await getInviteLink(page) await leftSideMenuPage.clickDocuments() await documentsPage.checkTeamspaceNotExist(testTeamspace.title) await documentsPage.createNewTeamspace(testTeamspace) - secondPage = await getSecondPageByInvite(browser, linkText, newUser2) - - leftSideMenuSecondPage = new LeftSideMenuPage(secondPage) - documentsSecondPage = new DocumentsPage(secondPage) - documentContentSecondPage = new DocumentContentPage(secondPage) await documentsPage.clickOnButtonCreateDocument() await documentsPage.createDocument(testDocument) await documentsPage.openDocument(testDocument.title) await documentContentPage.checkDocumentTitle(testDocument.title) }) - test('ToDos in the Document', async () => { + test('ToDos in the Document', async ({ page, request, browser }) => { + newUser2 = generateUser() + await createAccount(request, newUser2) + const linkText = await getInviteLink(page) + using _secondPage = await getSecondPageByInvite(browser, linkText, newUser2) + secondPage = _secondPage.page + leftSideMenuSecondPage = new LeftSideMenuPage(secondPage) + documentsSecondPage = new DocumentsPage(secondPage) + documentContentSecondPage = new DocumentContentPage(secondPage) + const contents: string[] = ['work', 'meet up'] let content: string = '' @@ -98,12 +99,20 @@ test.describe('Content in the Documents tests', () => { await planningPage.checkInSchedule(contents[1]) await planningPage.markDoneInToDos(contents[0]) await planningPage.markDoneInToDos(contents[1]) - await secondPage.close() for (const line of contents) await documentContentPage.checkToDo(line, true) }) - test('Table in the Document', async ({ page }) => { + test('Table in the Document', async ({ page, browser, request }) => { + newUser2 = generateUser() + await createAccount(request, newUser2) + const linkText = await getInviteLink(page) + using _secondPage = await getSecondPageByInvite(browser, linkText, newUser2) + secondPage = _secondPage.page + leftSideMenuSecondPage = new LeftSideMenuPage(secondPage) + documentsSecondPage = new DocumentsPage(secondPage) + documentContentSecondPage = new DocumentContentPage(secondPage) + await documentContentPage.inputContentParapraph().click() await documentContentPage.leftMenu().click() await documentContentPage.menuPopupItemButton('Table').click() @@ -138,6 +147,5 @@ test.describe('Content in the Documents tests', () => { await documentContentSecondPage.proseTableCell(1, 1).dblclick() await documentContentSecondPage.proseTableCell(1, 1).fill('Center') await expect(documentContentPage.proseTableCell(1, 1)).toContainText('Center', { timeout: 5000 }) - await secondPage.close() }) }) diff --git a/tests/sanity/tests/model/channel-page.ts b/tests/sanity/tests/model/channel-page.ts index 62e1a7ebd7..36df33e231 100644 --- a/tests/sanity/tests/model/channel-page.ts +++ b/tests/sanity/tests/model/channel-page.ts @@ -1,5 +1,6 @@ import { expect, type Locator, type Page } from '@playwright/test' import { CommonPage } from './common-page' +import { LinkedChannelTypes } from './types' export class ChannelPage extends CommonPage { readonly page: Page @@ -73,6 +74,23 @@ export class ChannelPage extends CommonPage { private readonly addMemberPreview = (): Locator => this.page.getByRole('button', { name: 'Add members' }) private readonly addButtonPreview = (): Locator => this.page.getByRole('button', { name: 'Add', exact: true }) + readonly inputSearchIcon = (): Locator => this.page.locator('.searchInput-icon') + readonly inputSearchChannel = (): Locator => this.page.locator('.hulyHeader-container').getByPlaceholder('Search') + + readonly channelContainers = (): Locator => this.page.locator('.hulyNavItem-container') + + readonly starredChannelContainers = (): Locator => + this.page.locator('#navGroup-starred').locator('.hulyNavItem-container') + + readonly issueChannelContainers = (): Locator => + this.page.locator('#navGroup-tracker\\:class\\:Issue').locator('.hulyNavItem-container') + + readonly vacancyChannelContainers = (): Locator => + this.page.locator('#navGroup-recruit\\:class\\:Vacancy').locator('.hulyNavItem-container') + + readonly applicationChannelContainers = (): Locator => + this.page.locator('#navGroup-recruit\\:class\\:Applicant').locator('.hulyNavItem-container') + async sendMessage (message: string): Promise { await this.inputMessage().fill(message) await this.buttonSendMessage().click() @@ -218,6 +236,17 @@ export class ChannelPage extends CommonPage { await this.joinChannelButton().click() } + async getChannelsGroupLocatorByType (channelType: LinkedChannelTypes, channelName: string): Promise { + const mapTypesToLocator = { + [LinkedChannelTypes.Issue]: this.issueChannelContainers(), + [LinkedChannelTypes.Vacancy]: this.vacancyChannelContainers(), + [LinkedChannelTypes.Application]: this.applicationChannelContainers() + } as const + + const groupLocator: Locator = mapTypesToLocator[channelType] ?? this.issueChannelContainers() + return groupLocator.filter({ has: this.page.locator(`span:has-text("${channelName}")`) }) + } + async checkIfChannelDefaultExist (shouldExist: boolean, channel: string): Promise { if (shouldExist) { await expect(this.channelName(channel)).toBeVisible() @@ -260,4 +289,31 @@ export class ChannelPage extends CommonPage { await expect(this.channel(channel).nth(1)).toBeVisible() await expect(this.channel(channel).nth(2)).toBeVisible() } + + async makeActionWithChannelInMenu (channelName: string, action: string): Promise { + await this.channelContainers().filter({ hasText: channelName }).hover() + await this.channelContainers().filter({ hasText: channelName }).locator('.hulyNavItem-actions').click() + await this.selectFromDropdown(this.page, action) + } + + async checkChannelStarred (shouldExist: boolean, channelName: string): Promise { + if (shouldExist) { + await expect(this.starredChannelContainers().filter({ hasText: channelName })).toHaveCount(1) + } else { + await expect(this.starredChannelContainers().filter({ hasText: channelName })).toHaveCount(0) + } + } + + async searchChannel (channelName: string): Promise { + await this.inputSearchIcon().click() + await this.inputSearchChannel().fill(channelName) + } + + async checkLinkedChannelIsExist (channelName: string, linkedChannelType: LinkedChannelTypes): Promise { + await expect(await this.getChannelsGroupLocatorByType(linkedChannelType, channelName)).toHaveCount(1) + } + + async openLinkedChannelIsExist (channelName: string, linkedChannelType: LinkedChannelTypes): Promise { + await (await this.getChannelsGroupLocatorByType(linkedChannelType, channelName)).click() + } } diff --git a/tests/sanity/tests/model/chunter-page.ts b/tests/sanity/tests/model/chunter-page.ts index c5875590a1..2b443f5b3b 100644 --- a/tests/sanity/tests/model/chunter-page.ts +++ b/tests/sanity/tests/model/chunter-page.ts @@ -1,4 +1,5 @@ -import { type Locator, type Page } from '@playwright/test' +import { expect, type Locator, type Page } from '@playwright/test' +import { SignUpData } from './common-types' export class ChunterPage { readonly page: Page @@ -9,12 +10,21 @@ export class ChunterPage { readonly buttonChannelBrowser = (): Locator => this.page.locator('.hulyNavPanel-header > button.type-button-icon') readonly buttonNewChannelHeader = (): Locator => this.page.getByRole('button', { name: 'New channel' }) + readonly buttonNewDirectChatHeader = (): Locator => this.page.getByRole('button', { name: 'New direct chat' }) readonly inputNewChannelName = (): Locator => this.page.getByPlaceholder('New channel') readonly inputDescription = (): Locator => this.page.getByPlaceholder('Description (optional)') readonly checkboxMakePublic = (): Locator => this.page.getByRole('button', { name: 'Public' }) readonly checkboxMakePrivate = (): Locator => this.page.getByRole('button', { name: 'Private' }) readonly buttonCreateChannel = (): Locator => this.page.getByRole('button', { name: 'Create' }) readonly buttonOpenChannel = (): Locator => this.page.locator('div.antiNav-element__dropbox span.an-element__label') + readonly inputNewDirectChatEmployee = (): Locator => this.page.locator('.popup input[placeholder="Search..."]') + readonly rowEmployeeInNewDirectChatModal = (): Locator => this.page.locator('.popup .users button.row') + readonly buttonNewDirectChatModalNext = (): Locator => this.page.locator('.hulyModal-footer button:has-text("Next")') + readonly buttonNewDirectChatModalCreate = (): Locator => + this.page.locator('.hulyModal-footer button:has-text("Create")') + + readonly directMessagesButtonInLeftMenu = (): Locator => + this.page.locator('.hulyNavGroup-header:has-text("Direct messages")') // ACTIONS @@ -26,6 +36,10 @@ export class ChunterPage { await this.buttonNewChannelHeader().click() } + async clickNewDirectChatHeader (): Promise { + await this.buttonNewDirectChatHeader().click() + } + async createPrivateChannel (channelName: string, privateChannel: boolean): Promise { await this.inputNewChannelName().fill(channelName) if (privateChannel) { @@ -38,4 +52,16 @@ export class ChunterPage { async openChannel (channelName: string): Promise { await this.buttonOpenChannel().filter({ hasText: channelName }).click() } + + async createDirectChat ({ firstName, lastName }: SignUpData): Promise { + await this.clickChannelBrowser() + await this.clickNewDirectChatHeader() + await this.inputNewDirectChatEmployee().fill(`${lastName}`) + await this.rowEmployeeInNewDirectChatModal() + .filter({ hasText: `${lastName} ${firstName}` }) + .click() + await this.buttonNewDirectChatModalNext().click() + await this.buttonNewDirectChatModalCreate().click() + await expect(this.directMessagesButtonInLeftMenu()).toBeVisible() + } } diff --git a/tests/sanity/tests/model/common-page.ts b/tests/sanity/tests/model/common-page.ts index 0f6083b9b0..f04db77642 100644 --- a/tests/sanity/tests/model/common-page.ts +++ b/tests/sanity/tests/model/common-page.ts @@ -18,6 +18,8 @@ export class CommonPage { popupSpanLabel = (point: string): Locator => this.page.locator('div[class$="opup"] span[class*="label"]', { hasText: point }) + readonly inputSearchIcon = (): Locator => this.page.locator('.searchInput-icon') + selectPopupSpanLines = (item: string): Locator => this.page.locator('div.selectPopup span[class^="lines"]', { hasText: item }) @@ -49,6 +51,7 @@ export class CommonPage { buttonFilter = (): Locator => this.page.getByRole('button', { name: 'Filter' }) inputFilterTitle = (): Locator => this.page.locator('div.selectPopup input[placeholder="Title"]') + inputFilterName = (): Locator => this.page.locator('div.selectPopup input[placeholder="Name"]') inputSearch = (): Locator => this.page.locator('div.selectPopup input[placeholder="Search..."]') buttonFilterApply = (): Locator => this.page.locator('div.selectPopup button[type="button"]', { hasText: 'Apply' }) buttonClearFilters = (): Locator => this.page.locator('button > span', { hasText: 'Clear filters' }) @@ -213,6 +216,10 @@ export class CommonPage { await this.inputFilterTitle().fill(filterSecondLevel) await this.buttonFilterApply().click() break + case 'Name': + await this.inputFilterName().fill(filterSecondLevel) + await this.buttonFilterApply().click() + break case 'Labels': await this.selectFromDropdown(this.page, filterSecondLevel) break diff --git a/tests/sanity/tests/model/common-types.ts b/tests/sanity/tests/model/common-types.ts index 13e7d21b2e..20674b9bc1 100644 --- a/tests/sanity/tests/model/common-types.ts +++ b/tests/sanity/tests/model/common-types.ts @@ -4,3 +4,10 @@ export interface SignUpData { email: string password: string } + +export interface SignUpWithWorkspaceData { + firstName: string + lastName: string + email: string + password: string +} diff --git a/tests/sanity/tests/model/recruiting/talents-page.ts b/tests/sanity/tests/model/recruiting/talents-page.ts index f9f00b8a18..e7ec6eac33 100644 --- a/tests/sanity/tests/model/recruiting/talents-page.ts +++ b/tests/sanity/tests/model/recruiting/talents-page.ts @@ -22,7 +22,6 @@ export class TalentsPage extends CommonRecruitingPage { textVacancyMatchingScore = (): Locator => this.page.locator('form[id="recruit:string:VacancyMatching"] table > tbody > tr > td:nth-child(2)') - inputSearchIcon = (): Locator => this.page.locator('.searchInput-icon') inputSearchTalent = (): Locator => this.page.getByPlaceholder('Search') andreyTalet = (): Locator => this.page.locator('text=P. Andrey') @@ -35,6 +34,9 @@ export class TalentsPage extends CommonRecruitingPage { createButton = (): Locator => this.page.locator('button:has-text("Create")') assignedRecruiterButton = (): Locator => this.page.locator('button:has-text("Assigned recruiter")') chenRosamundButton = (): Locator => this.page.locator('button:has-text("Chen Rosamund")') + recruterSelectItemButton = (name: string): Locator => + this.page.locator(`button.menu-item.withList:has-text("${name}")`) + vacancyApplicatio = (vacancyId: string): Locator => this.page.locator(`tr:has-text("${vacancyId}") >> text=APP-`) recruitApplicationButton = (): Locator => this.page.locator('[id="app-recruit\\:string\\:RecruitApplication"]') @@ -104,6 +106,10 @@ export class TalentsPage extends CommonRecruitingPage { await this.chenRosamundButton().click() } + async selectRecruterToAssignByName (recruterName: string): Promise { + await this.recruterSelectItemButton(recruterName).click() + } + async clickOnAndreyTalet (): Promise { await this.andreyTalet().click() } diff --git a/tests/sanity/tests/model/types.ts b/tests/sanity/tests/model/types.ts index 10f00f124f..dcc1b8a25b 100644 --- a/tests/sanity/tests/model/types.ts +++ b/tests/sanity/tests/model/types.ts @@ -21,3 +21,9 @@ export enum TaskTypes { Subtask = 'Sub-task', TaskAndSubtask = 'Task & Sub-task' } + +export enum LinkedChannelTypes { + Issue = 'Issue', + Vacancy = 'Vacancy', + Application = 'Application' +} diff --git a/tests/sanity/tests/utils.ts b/tests/sanity/tests/utils.ts index 8c414d09ba..eb591c7e80 100644 --- a/tests/sanity/tests/utils.ts +++ b/tests/sanity/tests/utils.ts @@ -127,12 +127,25 @@ export async function getSecondPageByInvite ( browser: Browser, linkText: string | null, newUser: SignUpData -): Promise { - const page = await browser.newPage() - await page.goto(linkText ?? '') - const joinPage: SignInJoinPage = new SignInJoinPage(page) +): Promise<{ page: Page, context: BrowserContext } & Disposable> { + const userSecondContext = await browser.newContext({ storageState: PlatformSettingSecond }) + const newPage = await userSecondContext.newPage() + await newPage.goto(linkText ?? '') + const joinPage: SignInJoinPage = new SignInJoinPage(newPage) await joinPage.join(newUser) - return page + + return { + page: newPage, + context: userSecondContext, + [Symbol.dispose]: () => { + void newPage + .close() + .finally(() => { + void userSecondContext.close().catch(() => {}) + }) + .catch(() => {}) + } + } } export function expectToContainsOrdered (val: Locator, text: string[], timeout?: number): Promise {