mirror of
https://github.com/hcengineering/platform.git
synced 2024-12-22 11:01:54 +03:00
Added Teamspace tests, UI fixes (#6326)
This commit is contained in:
parent
27b04fba7a
commit
e591e073a4
@ -601,7 +601,8 @@ export function createModel (builder: Builder): void {
|
||||
{
|
||||
id: 'properties',
|
||||
label: setting.string.Properties,
|
||||
component: setting.component.SpaceTypePropertiesSectionEditor
|
||||
component: setting.component.SpaceTypePropertiesSectionEditor,
|
||||
withoutContainer: true
|
||||
},
|
||||
{
|
||||
id: 'roles',
|
||||
|
@ -569,7 +569,8 @@ export function createModel (builder: Builder): void {
|
||||
{
|
||||
id: 'properties',
|
||||
label: setting.string.Properties,
|
||||
component: setting.component.SpaceTypePropertiesSectionEditor
|
||||
component: setting.component.SpaceTypePropertiesSectionEditor,
|
||||
withoutContainer: true
|
||||
},
|
||||
{
|
||||
id: 'roles',
|
||||
|
@ -408,7 +408,7 @@
|
||||
<Label label={core.string.AutoJoin} />
|
||||
<span><Label label={core.string.AutoJoinDescr} /></span>
|
||||
</div>
|
||||
<Toggle bind:on={autoJoin} />
|
||||
<Toggle id={'teamspace-autoJoin'} bind:on={autoJoin} />
|
||||
</div>
|
||||
|
||||
{#each roles as role}
|
||||
|
@ -37,12 +37,14 @@
|
||||
IconMoreV,
|
||||
AnySvelteComponent,
|
||||
navigate,
|
||||
getCurrentResolvedLocation
|
||||
getCurrentResolvedLocation,
|
||||
IconWithEmoji
|
||||
} from '@hcengineering/ui'
|
||||
import { createQuery, getClient } from '@hcengineering/presentation'
|
||||
import { showMenu } from '@hcengineering/view-resources'
|
||||
import setting, { SpaceTypeEditor } from '@hcengineering/setting'
|
||||
import { Asset, getResource } from '@hcengineering/platform'
|
||||
import view from '@hcengineering/view'
|
||||
|
||||
import SpaceTypeEditorComponent from './editor/SpaceTypeEditor.svelte'
|
||||
import { clearSettingsStore } from '../../store'
|
||||
@ -59,6 +61,7 @@
|
||||
let selectedSubObjectId: Ref<Doc> | undefined
|
||||
let subItemName: string | undefined
|
||||
let subItemIcon: Asset | undefined
|
||||
let subItemIconColor: number | undefined
|
||||
|
||||
onDestroy(resolvedLocationStore.subscribe(handleLocationChanged))
|
||||
|
||||
@ -109,7 +112,7 @@
|
||||
subEditor = undefined
|
||||
}
|
||||
|
||||
let bcItems: Array<{ title: string, icon?: Asset }> = []
|
||||
let bcItems: Array<{ title: string, icon?: Asset | AnySvelteComponent, iconProps?: any }> = []
|
||||
$: {
|
||||
bcItems = []
|
||||
|
||||
@ -117,7 +120,11 @@
|
||||
bcItems.push({ title: type.name, icon: descriptor?.icon })
|
||||
|
||||
if (selectedSubObjectId) {
|
||||
bcItems.push({ title: subItemName ?? selectedSubObjectId, icon: subItemIcon })
|
||||
bcItems.push({
|
||||
title: subItemName ?? selectedSubObjectId,
|
||||
icon: subItemIcon === view.ids.IconWithEmoji ? IconWithEmoji : subItemIcon,
|
||||
iconProps: { icon: subItemIconColor }
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -193,6 +200,7 @@
|
||||
this={subEditor}
|
||||
bind:name={subItemName}
|
||||
bind:icon={subItemIcon}
|
||||
bind:color={subItemIconColor}
|
||||
readonly={!canEdit}
|
||||
spaceType={type}
|
||||
{descriptor}
|
||||
|
@ -103,6 +103,3 @@
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
</style>
|
||||
|
@ -41,6 +41,7 @@
|
||||
export let objectId: Ref<TaskType>
|
||||
export let name: string | undefined
|
||||
export let icon: Asset | undefined
|
||||
export let color: number | undefined
|
||||
export let readonly: boolean = true
|
||||
|
||||
const client = getClient()
|
||||
@ -59,6 +60,7 @@
|
||||
$: taskType = taskTypes.find((tt) => tt._id === objectId)
|
||||
$: name = taskType?.name
|
||||
$: icon = taskType?.icon
|
||||
$: color = taskType?.color
|
||||
$: descriptor = client.getModel().findAllSync(task.class.TaskTypeDescriptor, { _id: taskType?.descriptor })
|
||||
$: states = (taskType?.statuses.map((p) => $statusStore.byId.get(p)).filter((p) => p !== undefined) as Status[]) ?? []
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { faker } from '@faker-js/faker'
|
||||
import { expect, test } from '@playwright/test'
|
||||
import { ApiEndpoint } from '../API/Api'
|
||||
import { ChannelPage } from '../model/channel-page'
|
||||
@ -8,7 +7,7 @@ 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, generateTestData } from '../utils'
|
||||
import { PlatformURI, generateTestData, getInviteLink, generateUser, createAccount } from '../utils'
|
||||
|
||||
test.describe('channel tests', () => {
|
||||
let leftSideMenuPage: LeftSideMenuPage
|
||||
@ -21,12 +20,7 @@ test.describe('channel tests', () => {
|
||||
|
||||
test.beforeEach(async ({ page, request }) => {
|
||||
data = generateTestData()
|
||||
newUser2 = {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '1234'
|
||||
}
|
||||
newUser2 = generateUser()
|
||||
|
||||
leftSideMenuPage = new LeftSideMenuPage(page)
|
||||
chunterPage = new ChunterPage(page)
|
||||
@ -415,13 +409,9 @@ test.describe('channel tests', () => {
|
||||
await page2.close()
|
||||
})
|
||||
|
||||
test('Checking backlinks in the Chat', async ({ browser, page }) => {
|
||||
await api.createAccount(newUser2.email, newUser2.password, newUser2.firstName, newUser2.lastName)
|
||||
await leftSideMenuPage.openProfileMenu()
|
||||
await leftSideMenuPage.inviteToWorkspace()
|
||||
await leftSideMenuPage.getInviteLink()
|
||||
const linkText = await page.locator('.antiPopup .link').textContent()
|
||||
await leftSideMenuPage.clickOnCloseInvite()
|
||||
test('Checking backlinks in the Chat', async ({ browser, page, request }) => {
|
||||
await createAccount(request, newUser2)
|
||||
const linkText = await getInviteLink(page)
|
||||
const page2 = await browser.newPage()
|
||||
const leftSideMenuPageSecond = new LeftSideMenuPage(page2)
|
||||
const channelPageSecond = new ChannelPage(page2)
|
||||
|
@ -1,8 +1,20 @@
|
||||
import { test } from '@playwright/test'
|
||||
import { generateId, PlatformSetting, PlatformURI } from '../utils'
|
||||
import {
|
||||
generateId,
|
||||
PlatformSetting,
|
||||
PlatformURI,
|
||||
generateUser,
|
||||
createAccount,
|
||||
getInviteLink,
|
||||
createAccountAndWorkspace,
|
||||
generateTestData
|
||||
} from '../utils'
|
||||
import { NewTeamspace } from '../model/documents/types'
|
||||
import { LeftSideMenuPage } from '../model/left-side-menu-page'
|
||||
import { DocumentsPage } from '../model/documents/documents-page'
|
||||
import { SignUpData } from '../model/common-types'
|
||||
import { SignInJoinPage } from '../model/signin-page'
|
||||
import { TestData } from '../chat/types'
|
||||
|
||||
test.use({
|
||||
storageState: PlatformSetting
|
||||
@ -64,4 +76,59 @@ test.describe('Teamspace tests', () => {
|
||||
await documentsPage.moreActionTeamspace(updateEditTeamspace.title, 'Edit teamspace')
|
||||
await documentsPage.checkTeamspace(updateEditTeamspace)
|
||||
})
|
||||
|
||||
test('Auto-join teamspace', async ({ page, request, browser }) => {
|
||||
const testData: TestData = generateTestData()
|
||||
await createAccountAndWorkspace(page, request, testData)
|
||||
const newUser2: SignUpData = generateUser()
|
||||
await createAccount(request, newUser2)
|
||||
|
||||
const autojoinTeamspace: NewTeamspace = {
|
||||
title: `Auto-join Teamspace-${generateId()}`,
|
||||
description: 'Auto-join Teamspace description',
|
||||
private: false,
|
||||
autoJoin: true
|
||||
}
|
||||
await leftSideMenuPage.clickDocuments()
|
||||
await documentsPage.checkTeamspaceNotExist(autojoinTeamspace.title)
|
||||
await documentsPage.createNewTeamspace(autojoinTeamspace)
|
||||
const linkText = await getInviteLink(page)
|
||||
|
||||
const page2 = await browser.newPage()
|
||||
await page2.goto(linkText ?? '')
|
||||
const joinPage: SignInJoinPage = new SignInJoinPage(page2)
|
||||
await joinPage.join(newUser2)
|
||||
const documentsSecondPage: DocumentsPage = new DocumentsPage(page2)
|
||||
await documentsSecondPage.clickDocumentsApp()
|
||||
await documentsSecondPage.checkTeamspaceExist(autojoinTeamspace.title)
|
||||
await page2.close()
|
||||
})
|
||||
|
||||
test('Join teamspace', async ({ page, request, browser }) => {
|
||||
const testData: TestData = generateTestData()
|
||||
await createAccountAndWorkspace(page, request, testData)
|
||||
const newUser2: SignUpData = generateUser()
|
||||
await createAccount(request, newUser2)
|
||||
|
||||
const joinTeamspace: NewTeamspace = {
|
||||
title: `Join Teamspace-${generateId()}`,
|
||||
description: 'Join Teamspace description'
|
||||
}
|
||||
await leftSideMenuPage.clickDocuments()
|
||||
await documentsPage.checkTeamspaceNotExist(joinTeamspace.title)
|
||||
await documentsPage.createNewTeamspace(joinTeamspace)
|
||||
const linkText = await getInviteLink(page)
|
||||
|
||||
const page2 = await browser.newPage()
|
||||
await page2.goto(linkText ?? '')
|
||||
const joinPage: SignInJoinPage = new SignInJoinPage(page2)
|
||||
await joinPage.join(newUser2)
|
||||
const documentsSecondPage: DocumentsPage = new DocumentsPage(page2)
|
||||
await documentsSecondPage.clickDocumentsApp()
|
||||
await documentsSecondPage.checkTeamspaceNotExist(joinTeamspace.title)
|
||||
await documentsSecondPage.clickTeamspaces()
|
||||
await documentsSecondPage.joinTeamspace(joinTeamspace.title)
|
||||
await documentsSecondPage.checkTeamspaceExist(joinTeamspace.title)
|
||||
await page2.close()
|
||||
})
|
||||
})
|
||||
|
@ -23,8 +23,18 @@ export class DocumentsPage extends CommonPage {
|
||||
readonly buttonDocument = (name: string): Locator =>
|
||||
this.page.locator('button.hulyNavItem-container > span[class*="label"]', { hasText: name })
|
||||
|
||||
readonly buttonDocumentsApp = (): Locator => this.page.locator('button[id$="document:string:DocumentApplication"]')
|
||||
readonly divTeamspacesParent = (): Locator =>
|
||||
this.page.locator('div#navGroup-tree-teamspaces').locator('xpath=../button[1]')
|
||||
this.page.locator('button.hulyNavGroup-header', { hasText: 'Teamspaces' })
|
||||
|
||||
readonly buttonTeamspaces = (): Locator =>
|
||||
this.page.locator('button.hulyNavItem-container', { hasText: 'Teamspaces' })
|
||||
|
||||
readonly rowTeamspace = (hasText: string): Locator =>
|
||||
this.page.locator('div.hulyComponent td ', { hasText }).locator('xpath=..')
|
||||
|
||||
readonly buttonJoinTeamspace = (hasText: string): Locator =>
|
||||
this.page.locator('div.hulyComponent td ', { hasText }).locator('xpath=..').locator('button[type="submit"]')
|
||||
|
||||
readonly buttonCreateTeamspace = (): Locator => this.page.locator('button#tree-teamspaces')
|
||||
readonly formNewTeamspace = (): Locator => this.page.locator('form[id="document:string:NewTeamspace"]')
|
||||
@ -36,6 +46,7 @@ export class DocumentsPage extends CommonPage {
|
||||
this.formNewTeamspace().locator('div[id="teamspace-description"] input')
|
||||
|
||||
readonly inputModalNewTeamspacePrivate = (): Locator => this.formNewTeamspace().locator('[id="teamspace-private"]')
|
||||
readonly inputModalNewTeamspaceAutoJoin = (): Locator => this.formNewTeamspace().locator('[id="teamspace-autoJoin"]')
|
||||
readonly buttonModalNewTeamspaceCreate = (): Locator => this.formNewTeamspace().locator('button[type="submit"]')
|
||||
readonly buttonModalEditTeamspaceTitle = (): Locator =>
|
||||
this.formEditTeamspace().locator('div[id="teamspace-title"] input')
|
||||
@ -56,12 +67,15 @@ export class DocumentsPage extends CommonPage {
|
||||
await this.divTeamspacesParent().hover()
|
||||
await this.buttonCreateTeamspace().click()
|
||||
await this.inputModalNewTeamspaceTitle().fill(data.title)
|
||||
if (data.description != null) {
|
||||
if (data?.description !== undefined) {
|
||||
await this.inputModalNewTeamspaceDescription().fill(data.description)
|
||||
}
|
||||
if (data.private != null) {
|
||||
if (data.private === true) {
|
||||
await this.inputModalNewTeamspacePrivate().click()
|
||||
}
|
||||
if (data.autoJoin === true) {
|
||||
await this.inputModalNewTeamspaceAutoJoin().click()
|
||||
}
|
||||
await this.buttonModalNewTeamspaceCreate().click()
|
||||
}
|
||||
|
||||
@ -149,4 +163,17 @@ export class DocumentsPage extends CommonPage {
|
||||
async fillMoveDocumentForm (newSpace: string): Promise<void> {
|
||||
await this.popupMoveDocument.moveToSpace(newSpace)
|
||||
}
|
||||
|
||||
async clickDocumentsApp (): Promise<void> {
|
||||
await this.buttonDocumentsApp().click()
|
||||
}
|
||||
|
||||
async clickTeamspaces (): Promise<void> {
|
||||
await this.buttonTeamspaces().click()
|
||||
}
|
||||
|
||||
async joinTeamspace (name: string): Promise<void> {
|
||||
await expect(this.rowTeamspace(name)).toBeVisible()
|
||||
await this.buttonJoinTeamspace(name).click()
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ export interface NewTeamspace {
|
||||
title: string
|
||||
description?: string
|
||||
private?: boolean
|
||||
autoJoin?: boolean
|
||||
}
|
||||
|
||||
export interface NewDocument {
|
||||
|
@ -21,6 +21,9 @@ export class LoginPage {
|
||||
recoveryLogin = (): Locator => this.page.getByRole('link', { name: 'Log In' })
|
||||
recoverySignUp = (): Locator => this.page.getByRole('link', { name: 'Sign Up' })
|
||||
|
||||
profileButton = (): Locator => this.page.locator('#profile-button')
|
||||
popupItemButton = (hasText: string): Locator => this.page.locator('div.popup button[class*="menu"]', { hasText })
|
||||
|
||||
// ACTIONS
|
||||
async goto (): Promise<void> {
|
||||
await (await this.page.goto(`${PlatformURI}/login/login`))?.finished()
|
||||
@ -50,8 +53,20 @@ export class LoginPage {
|
||||
await this.buttonLogin().click()
|
||||
}
|
||||
|
||||
async openProfileMenu (): Promise<void> {
|
||||
await this.profileButton().click()
|
||||
}
|
||||
|
||||
// ASSERTS
|
||||
|
||||
async checkingNeedReLogin (): Promise<void> {
|
||||
if (await this.profileButton().isVisible()) {
|
||||
await this.openProfileMenu()
|
||||
await this.popupItemButton('Sign out').click()
|
||||
await this.loginWithPassword().waitFor({ state: 'visible', timeout: 15000 })
|
||||
}
|
||||
}
|
||||
|
||||
async checkIfErrorMessageIsShown (): Promise<void> {
|
||||
await expect(this.invalidPasswordMessage()).toContainText('Invalid password')
|
||||
}
|
||||
|
@ -41,13 +41,6 @@ export class TemplatePage extends CommonTrackerPage {
|
||||
saveTemplateButton = (): Locator => this.page.locator('text=Save template')
|
||||
editTemplateButton = (): Locator => this.page.locator('text=Edit template')
|
||||
newSpaceTypeButton = (): Locator => this.page.locator('#new-space-type')
|
||||
spaceTypeButton = (name: string, category?: string): Locator =>
|
||||
this.page.locator('div#navGroup-spaceTypes button.hulyTaskNavLink-container', {
|
||||
hasText: category !== undefined ? `${name} ${category}` : name
|
||||
})
|
||||
|
||||
addTaskTypeButton = (): Locator =>
|
||||
this.page.locator('div.hulyTableAttr-header', { hasText: 'Task types' }).locator('button[data-id="btnAdd"]')
|
||||
|
||||
async createNewTemplate (data: NewIssue): Promise<void> {
|
||||
await this.buttonNewTemplate().click()
|
||||
@ -124,15 +117,6 @@ export class TemplatePage extends CommonTrackerPage {
|
||||
await this.newSpaceTypeButton().click()
|
||||
}
|
||||
|
||||
async selectSpaceType (name: string, category?: string): Promise<void> {
|
||||
await this.spaceTypeButton(name, category).click()
|
||||
}
|
||||
|
||||
async addTaskType (): Promise<void> {
|
||||
console.log('[!!!] ', await this.page.locator('div.hulyTableAttr-header', { hasText: 'Task types' }).isVisible())
|
||||
await this.addTaskTypeButton().click()
|
||||
}
|
||||
|
||||
async createTemplate (templateName: string, templateContent: string): Promise<void> {
|
||||
await this.createTemplateButton().click()
|
||||
await this.newTemplateInput().fill(templateName)
|
||||
|
@ -1,8 +1,13 @@
|
||||
import { Browser, BrowserContext, Locator, Page, expect } from '@playwright/test'
|
||||
import { Browser, BrowserContext, Locator, Page, expect, APIRequestContext } from '@playwright/test'
|
||||
import { allure } from 'allure-playwright'
|
||||
import { faker } from '@faker-js/faker'
|
||||
import { TestData } from './chat/types'
|
||||
import path from 'path'
|
||||
import { LeftSideMenuPage } from './model/left-side-menu-page'
|
||||
import { SignUpData } from './model/common-types'
|
||||
import { ApiEndpoint } from './API/Api'
|
||||
import { SelectWorkspacePage } from './model/select-workspace-page'
|
||||
import { LoginPage } from './model/login-page'
|
||||
|
||||
export const PlatformURI = process.env.PLATFORM_URI as string
|
||||
export const PlatformTransactor = process.env.PLATFORM_TRANSACTOR as string
|
||||
@ -167,3 +172,40 @@ export async function uploadFile (page: Page, fileName: string, fileUploadTestId
|
||||
// Replace with a more reliable condition for determining when the upload is complete, if possible.
|
||||
await page.waitForTimeout(2000)
|
||||
}
|
||||
|
||||
export async function getInviteLink (page: Page): Promise<string | null> {
|
||||
const leftSideMenuPage = new LeftSideMenuPage(page)
|
||||
await leftSideMenuPage.openProfileMenu()
|
||||
await leftSideMenuPage.inviteToWorkspace()
|
||||
await leftSideMenuPage.getInviteLink()
|
||||
const linkText = await page.locator('.antiPopup .link').textContent()
|
||||
expect(linkText).not.toBeNull()
|
||||
await leftSideMenuPage.clickOnCloseInvite()
|
||||
return linkText
|
||||
}
|
||||
|
||||
export function generateUser (): SignUpData {
|
||||
return {
|
||||
firstName: faker.person.firstName(),
|
||||
lastName: faker.person.lastName(),
|
||||
email: faker.internet.email(),
|
||||
password: '1234'
|
||||
}
|
||||
}
|
||||
|
||||
export async function createAccount (request: APIRequestContext, data: SignUpData): Promise<void> {
|
||||
const api: ApiEndpoint = new ApiEndpoint(request)
|
||||
await api.createAccount(data.email, data.password, data.firstName, data.lastName)
|
||||
}
|
||||
|
||||
export async function createAccountAndWorkspace (page: Page, request: APIRequestContext, data: TestData): Promise<void> {
|
||||
const api: ApiEndpoint = new ApiEndpoint(request)
|
||||
await api.createAccount(data.userName, '1234', data.firstName, data.lastName)
|
||||
await api.createWorkspaceWithLogin(data.workspaceName, data.userName, '1234')
|
||||
const loginPage: LoginPage = new LoginPage(page)
|
||||
await loginPage.checkingNeedReLogin()
|
||||
await (await page.goto(`${PlatformURI}`))?.finished()
|
||||
await loginPage.login(data.userName, '1234')
|
||||
const swp = new SelectWorkspacePage(page)
|
||||
await swp.selectWorkspace(data.workspaceName)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user