mirror of
https://github.com/hcengineering/platform.git
synced 2025-06-08 00:37:42 +00:00
feat(tests): TESTS-43 added the Create an issue with all params test (#3905)
Signed-off-by: Alex Velichko <nestor_007@mail.ru>
This commit is contained in:
parent
e158788f4e
commit
46ffacc46a
@ -3,7 +3,7 @@ import { Page } from '@playwright/test'
|
||||
export class CommonPage {
|
||||
async selectMenuItem (page: Page, name: string): Promise<void> {
|
||||
if (name !== 'first') {
|
||||
await page.locator('div.selectPopup input').fill(name)
|
||||
await page.locator('div.selectPopup input').fill(name.split(' ')[0])
|
||||
}
|
||||
await page.locator('div.selectPopup div.list-item:first-child').click()
|
||||
}
|
||||
@ -37,4 +37,19 @@ export class CommonPage {
|
||||
async pressYesDeletePopup (page: Page): Promise<void> {
|
||||
await page.locator('form[id="view:string:DeleteObject"] button.primary').click()
|
||||
}
|
||||
|
||||
async addNewTagPopup (page: Page, title: string, description: string): Promise<void> {
|
||||
await page.locator('div.popup form[id="tags:string:AddTag"] input[placeholder$="title"]').fill(title)
|
||||
await page
|
||||
.locator('div.popup form[id="tags:string:AddTag"] input[placeholder="Please type description here"]')
|
||||
.fill(description)
|
||||
await page.locator('div.popup form[id="tags:string:AddTag"] button[type="submit"]').click()
|
||||
}
|
||||
|
||||
async selectAssignee (page: Page, name: string): Promise<void> {
|
||||
if (name !== 'first') {
|
||||
await page.locator('div.selectPopup input').fill(name.split(' ')[0])
|
||||
}
|
||||
await page.locator('div.selectPopup div.list-item').click()
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,12 @@ export class LeftSideMenuPage {
|
||||
readonly page: Page
|
||||
readonly buttonChunter: Locator
|
||||
readonly buttonContacts: Locator
|
||||
readonly buttonTracker: Locator
|
||||
|
||||
constructor (page: Page) {
|
||||
this.page = page
|
||||
this.buttonChunter = page.locator('button[id$="ApplicationLabelChunter"]')
|
||||
this.buttonContacts = page.locator('button[id$="Contacts"]')
|
||||
this.buttonTracker = page.locator('button[id$="TrackerApplication"]')
|
||||
}
|
||||
}
|
||||
|
@ -59,14 +59,6 @@ export class CommonRecruitingPage extends CommonPage {
|
||||
await page.locator('div.popup form[id="recruit:string:CreateReviewParams"] button[type="submit"]').click()
|
||||
}
|
||||
|
||||
async addNewTagPopup (page: Page, title: string, description: string): Promise<void> {
|
||||
await page.locator('div.popup form[id="tags:string:AddTag"] input[placeholder$="title"]').fill(title)
|
||||
await page
|
||||
.locator('div.popup form[id="tags:string:AddTag"] input[placeholder="Please type description here"]')
|
||||
.fill(description)
|
||||
await page.locator('div.popup form[id="tags:string:AddTag"] button[type="submit"]').click()
|
||||
}
|
||||
|
||||
async deleteEntity (): Promise<void> {
|
||||
await this.buttonMoreActions.click()
|
||||
await this.buttonDelete.click()
|
||||
|
11
tests/sanity/tests/model/tracker/common-tracker-page.ts
Normal file
11
tests/sanity/tests/model/tracker/common-tracker-page.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Page } from '@playwright/test'
|
||||
import { CommonPage } from '../common-page'
|
||||
|
||||
export class CommonTrackerPage extends CommonPage {
|
||||
readonly page: Page
|
||||
|
||||
constructor (page: Page) {
|
||||
super()
|
||||
this.page = page
|
||||
}
|
||||
}
|
56
tests/sanity/tests/model/tracker/issues-details-page.ts
Normal file
56
tests/sanity/tests/model/tracker/issues-details-page.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import { expect, type Locator, type Page } from '@playwright/test'
|
||||
import { CommonTrackerPage } from './common-tracker-page'
|
||||
import { NewIssue } from './types'
|
||||
|
||||
export class IssuesDetailsPage extends CommonTrackerPage {
|
||||
readonly page: Page
|
||||
readonly inputTitle: Locator
|
||||
readonly inputDescription: Locator
|
||||
readonly textStatus: Locator
|
||||
readonly textPriority: Locator
|
||||
readonly textAssignee: Locator
|
||||
readonly textLabels: Locator
|
||||
readonly textComponent: Locator
|
||||
readonly textMilestone: Locator
|
||||
readonly textEstimation: Locator
|
||||
|
||||
constructor (page: Page) {
|
||||
super(page)
|
||||
this.page = page
|
||||
this.inputTitle = page.locator('div.popupPanel-body input[type="text"]')
|
||||
this.inputDescription = page.locator('div.popupPanel-body div.textInput p')
|
||||
this.textStatus = page.locator('//span[text()="Status"]/../button[1]//span')
|
||||
this.textPriority = page.locator('//span[text()="Status"]/../button[2]//span')
|
||||
this.textAssignee = page.locator('(//span[text()="Assignee"]/../div/button)[2]')
|
||||
this.textLabels = page.locator('div.step-container div.listitems-container')
|
||||
this.textComponent = page.locator('(//span[text()="Component"]/../div/div/button)[2]')
|
||||
this.textMilestone = page.locator('(//span[text()="Milestone"]/../div/div/button)[3]')
|
||||
this.textEstimation = page.locator('(//span[text()="Estimation"]/../div/button)[4]')
|
||||
}
|
||||
|
||||
async checkIssueDescription (data: NewIssue): Promise<void> {
|
||||
await expect(this.inputTitle).toHaveValue(data.title)
|
||||
await expect(this.inputDescription).toHaveText(data.description)
|
||||
if (data.status != null) {
|
||||
await expect(this.textStatus).toHaveText(data.status)
|
||||
}
|
||||
if (data.priority != null) {
|
||||
await expect(this.textPriority).toHaveText(data.priority)
|
||||
}
|
||||
if (data.assignee != null) {
|
||||
await expect(this.textAssignee).toHaveText(data.assignee)
|
||||
}
|
||||
if (data.labels != null) {
|
||||
await expect(this.textLabels).toHaveText(data.labels)
|
||||
}
|
||||
if (data.component != null) {
|
||||
await expect(this.textComponent).toHaveText(data.component)
|
||||
}
|
||||
if (data.milestone != null) {
|
||||
await expect(this.textMilestone).toHaveText(data.milestone)
|
||||
}
|
||||
if (data.estimation != null) {
|
||||
await expect(this.textEstimation).toHaveText(data.estimation)
|
||||
}
|
||||
}
|
||||
}
|
126
tests/sanity/tests/model/tracker/issues-page.ts
Normal file
126
tests/sanity/tests/model/tracker/issues-page.ts
Normal file
@ -0,0 +1,126 @@
|
||||
import { expect, type Locator, type Page } from '@playwright/test'
|
||||
import { NewIssue } from './types'
|
||||
import path from 'path'
|
||||
import { CommonTrackerPage } from './common-tracker-page'
|
||||
|
||||
export class IssuesPage extends CommonTrackerPage {
|
||||
readonly page: Page
|
||||
readonly pageHeader: Locator
|
||||
readonly buttonCreateNewIssue: Locator
|
||||
readonly inputPopupCreateNewIssueTitle: Locator
|
||||
readonly inputPopupCreateNewIssueDescription: Locator
|
||||
readonly buttonPopupCreateNewIssueStatus: Locator
|
||||
readonly buttonPopupCreateNewIssuePriority: Locator
|
||||
readonly buttonPopupCreateNewIssueAssignee: Locator
|
||||
readonly buttonPopupCreateNewIssueLabels: Locator
|
||||
readonly buttonPopupCreateNewIssueComponent: Locator
|
||||
readonly buttonPopupCreateNewIssueEstimation: Locator
|
||||
readonly buttonPopupCreateNewIssueMilestone: Locator
|
||||
readonly buttonPopupCreateNewIssueDuedate: Locator
|
||||
readonly buttonDatePopupToday: Locator
|
||||
readonly inputPopupCreateNewIssueFile: Locator
|
||||
readonly textPopupCreateNewIssueFile: Locator
|
||||
readonly buttonCreateIssue: Locator
|
||||
readonly inputSearch: Locator
|
||||
|
||||
constructor (page: Page) {
|
||||
super(page)
|
||||
this.page = page
|
||||
this.pageHeader = page.locator('span[class*="header"]', { hasText: 'Issues' })
|
||||
this.buttonCreateNewIssue = page.locator('button > span', { hasText: 'New issue' })
|
||||
this.inputPopupCreateNewIssueTitle = page.locator('form[id="tracker:string:NewIssue"] input[type="text"]')
|
||||
this.inputPopupCreateNewIssueDescription = page.locator('form[id="tracker:string:NewIssue"] div.tiptap')
|
||||
this.buttonPopupCreateNewIssueStatus = page.locator('form[id="tracker:string:NewIssue"] div#status-editor button')
|
||||
this.buttonPopupCreateNewIssuePriority = page.locator(
|
||||
'form[id="tracker:string:NewIssue"] div#priority-editor button'
|
||||
)
|
||||
this.buttonPopupCreateNewIssueAssignee = page.locator(
|
||||
'form[id="tracker:string:NewIssue"] div#assignee-editor button'
|
||||
)
|
||||
this.buttonPopupCreateNewIssueLabels = page.locator('form[id="tracker:string:NewIssue"] button span', {
|
||||
hasText: 'Labels'
|
||||
})
|
||||
this.buttonPopupCreateNewIssueComponent = page.locator(
|
||||
'form[id="tracker:string:NewIssue"] button span[title="No component"]'
|
||||
)
|
||||
this.buttonPopupCreateNewIssueEstimation = page.locator(
|
||||
'form[id="tracker:string:NewIssue"] div#estimation-editor button'
|
||||
)
|
||||
this.buttonPopupCreateNewIssueMilestone = page.locator(
|
||||
'form[id="tracker:string:NewIssue"] div#milestone-editor button'
|
||||
)
|
||||
this.buttonPopupCreateNewIssueDuedate = page.locator('form[id="tracker:string:NewIssue"] div#duedate-editor button')
|
||||
this.buttonDatePopupToday = page.locator('div.popup div.today')
|
||||
this.inputPopupCreateNewIssueFile = page.locator('form[id="tracker:string:NewIssue"] input[type="file"]')
|
||||
this.textPopupCreateNewIssueFile = page.locator('div[class*="attachments"] > div[class*="attachment"]')
|
||||
this.buttonCreateIssue = page.locator('button > span', { hasText: 'Create issue' })
|
||||
this.inputSearch = page.locator('input[placeholder="Search"]')
|
||||
}
|
||||
|
||||
async createNewIssue (data: NewIssue): Promise<void> {
|
||||
await this.buttonCreateNewIssue.click()
|
||||
|
||||
await this.inputPopupCreateNewIssueTitle.fill(data.title)
|
||||
await this.inputPopupCreateNewIssueDescription.fill(data.description)
|
||||
if (data.status != null) {
|
||||
await this.buttonPopupCreateNewIssueStatus.click()
|
||||
await this.selectFromDropdown(this.page, data.status)
|
||||
}
|
||||
if (data.priority != null) {
|
||||
await this.buttonPopupCreateNewIssuePriority.click()
|
||||
await this.selectMenuItem(this.page, data.priority)
|
||||
}
|
||||
if (data.assignee != null) {
|
||||
await this.buttonPopupCreateNewIssueAssignee.click()
|
||||
await this.selectAssignee(this.page, data.assignee)
|
||||
}
|
||||
if (data.labels != null && data.createLabel != null) {
|
||||
await this.buttonPopupCreateNewIssueLabels.click()
|
||||
if (data.createLabel) {
|
||||
await this.pressCreateButtonSelectPopup(this.page)
|
||||
await this.addNewTagPopup(this.page, data.labels, 'Tag from createNewIssue')
|
||||
}
|
||||
await this.checkFromDropdown(this.page, data.labels)
|
||||
await this.inputPopupCreateNewIssueTitle.click({ force: true })
|
||||
}
|
||||
if (data.component != null) {
|
||||
await this.buttonPopupCreateNewIssueComponent.click()
|
||||
await this.selectMenuItem(this.page, data.component)
|
||||
}
|
||||
if (data.estimation != null) {
|
||||
await this.buttonPopupCreateNewIssueEstimation.click({ delay: 100 })
|
||||
await this.fillToSelectPopup(this.page, data.estimation)
|
||||
}
|
||||
if (data.milestone != null) {
|
||||
await this.buttonPopupCreateNewIssueMilestone.click()
|
||||
await this.selectMenuItem(this.page, data.milestone)
|
||||
}
|
||||
if (data.duedate != null) {
|
||||
await this.buttonPopupCreateNewIssueDuedate.click()
|
||||
if (data.duedate === 'today') {
|
||||
await this.buttonDatePopupToday.click()
|
||||
} else {
|
||||
await this.fillToSelectPopup(this.page, data.duedate)
|
||||
}
|
||||
}
|
||||
if (data.filePath != null) {
|
||||
await this.inputPopupCreateNewIssueFile.setInputFiles(path.join(__dirname, `../../files/${data.filePath}`))
|
||||
await expect(await this.textPopupCreateNewIssueFile.filter({ hasText: data.filePath })).toBeVisible()
|
||||
}
|
||||
|
||||
await this.buttonCreateIssue.click()
|
||||
}
|
||||
|
||||
async searchIssueByName (issueName: string): Promise<void> {
|
||||
await this.inputSearch.fill(issueName)
|
||||
await this.page.waitForTimeout(3000)
|
||||
}
|
||||
|
||||
async openIssueByName (issueName: string): Promise<void> {
|
||||
await this.page.locator('a', { hasText: issueName }).click()
|
||||
}
|
||||
|
||||
async checkIssueNotExist (issueName: string): Promise<void> {
|
||||
await expect(this.page.locator('tr', { hasText: issueName })).toHaveCount(0)
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
import { type Locator, type Page } from '@playwright/test'
|
||||
|
||||
export class TrackerNavigationMenuPage {
|
||||
readonly page: Page
|
||||
readonly buttonIssues: Locator
|
||||
|
||||
constructor (page: Page) {
|
||||
this.page = page
|
||||
this.buttonIssues = page.locator('a span', { hasText: 'Issues' })
|
||||
}
|
||||
}
|
14
tests/sanity/tests/model/tracker/types.ts
Normal file
14
tests/sanity/tests/model/tracker/types.ts
Normal file
@ -0,0 +1,14 @@
|
||||
export interface NewIssue {
|
||||
title: string
|
||||
description: string
|
||||
status?: string
|
||||
priority?: string
|
||||
assignee?: string
|
||||
createLabel?: boolean
|
||||
labels?: string
|
||||
component?: string
|
||||
estimation?: string
|
||||
milestone?: string
|
||||
duedate?: string
|
||||
filePath?: string
|
||||
}
|
48
tests/sanity/tests/tracker/issues.spec.ts
Normal file
48
tests/sanity/tests/tracker/issues.spec.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { test } from '@playwright/test'
|
||||
import { generateId, PlatformSetting, PlatformURI } from '../utils'
|
||||
import { LeftSideMenuPage } from '../model/left-side-menu-page'
|
||||
import { IssuesPage } from '../model/tracker/issues-page'
|
||||
import { IssuesDetailsPage } from '../model/tracker/issues-details-page'
|
||||
import { NewIssue } from '../model/tracker/types'
|
||||
|
||||
test.use({
|
||||
storageState: PlatformSetting
|
||||
})
|
||||
|
||||
test.describe('tracker issue tests', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await (await page.goto(`${PlatformURI}/workbench/sanity-ws`))?.finished()
|
||||
})
|
||||
|
||||
test('Create an issue with all parameters and attachments', async ({ page }) => {
|
||||
const newIssue: NewIssue = {
|
||||
title: `Issue with all parameters and attachments-${generateId()}`,
|
||||
description: 'Created issue with all parameters and attachments description',
|
||||
status: 'In Progress',
|
||||
priority: 'Urgent',
|
||||
assignee: 'Appleseed John',
|
||||
createLabel: true,
|
||||
labels: `CREATE-ISSUE-${generateId()}`,
|
||||
component: 'No component',
|
||||
estimation: '2',
|
||||
milestone: 'No Milestone',
|
||||
duedate: 'today',
|
||||
filePath: 'cat.jpeg'
|
||||
}
|
||||
|
||||
const leftSideMenuPage = new LeftSideMenuPage(page)
|
||||
await leftSideMenuPage.buttonTracker.click()
|
||||
|
||||
const issuesPage = new IssuesPage(page)
|
||||
await issuesPage.createNewIssue(newIssue)
|
||||
await issuesPage.searchIssueByName(newIssue.title)
|
||||
await issuesPage.openIssueByName(newIssue.title)
|
||||
|
||||
const issuesDetailsPage = new IssuesDetailsPage(page)
|
||||
await issuesDetailsPage.checkIssueDescription({
|
||||
...newIssue,
|
||||
milestone: 'Milestone',
|
||||
estimation: '2h'
|
||||
})
|
||||
})
|
||||
})
|
@ -13,7 +13,7 @@ import {
|
||||
setViewOrder,
|
||||
ViewletSelectors
|
||||
} from './tracker.utils'
|
||||
import { fillSearch, generateId, PlatformSetting } from './utils'
|
||||
import { fillSearch, generateId, PlatformSetting } from '../utils'
|
||||
test.use({
|
||||
storageState: PlatformSetting
|
||||
})
|
@ -1,5 +1,5 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { PlatformSetting, PlatformURI } from './utils'
|
||||
import { PlatformSetting, PlatformURI } from '../utils'
|
||||
test.use({
|
||||
storageState: PlatformSetting
|
||||
})
|
@ -1,6 +1,6 @@
|
||||
import { expect, test } from '@playwright/test'
|
||||
import { navigate } from './tracker.utils'
|
||||
import { generateId, PlatformSetting, PlatformURI, fillSearch } from './utils'
|
||||
import { generateId, PlatformSetting, PlatformURI, fillSearch } from '../utils'
|
||||
|
||||
test.use({
|
||||
storageState: PlatformSetting
|
@ -8,9 +8,10 @@ import {
|
||||
createIssue,
|
||||
fillIssueForm,
|
||||
navigate,
|
||||
openIssue
|
||||
openIssue,
|
||||
toTime
|
||||
} from './tracker.utils'
|
||||
import { PlatformSetting, fillSearch, generateId } from './utils'
|
||||
import { PlatformSetting, fillSearch, generateId } from '../utils'
|
||||
test.use({
|
||||
storageState: PlatformSetting
|
||||
})
|
||||
@ -127,18 +128,6 @@ test('my-issues', async ({ page }) => {
|
||||
await expect(page.locator('.antiPanel-component')).not.toContainText(name)
|
||||
})
|
||||
|
||||
function floorFractionDigits (n: number | string, amount: number): number {
|
||||
return Number(Number(n).toFixed(amount))
|
||||
}
|
||||
|
||||
function toTime (value: number): string {
|
||||
if (value > 0 && value < 8) {
|
||||
return `${floorFractionDigits(value, 2)}h`
|
||||
} else {
|
||||
return `${floorFractionDigits(value / 8, 3)}d`
|
||||
}
|
||||
}
|
||||
|
||||
test('report-time-from-issue-card', async ({ page }) => {
|
||||
await navigate(page)
|
||||
const assignee = 'Chen Rosamund'
|
||||
@ -168,7 +157,7 @@ test('report-time-from-issue-card', async ({ page }) => {
|
||||
await page.click('button:has-text("Create")')
|
||||
await page.click('#card-close')
|
||||
|
||||
await expect(page.locator('#ReportedTimeEditor')).toContainText(toTime(time))
|
||||
await expect(page.locator('#ReportedTimeEditor')).toContainText(await toTime(time))
|
||||
}
|
||||
})
|
||||
|
||||
@ -245,7 +234,7 @@ test('report-time-from-main-view', async ({ page }) => {
|
||||
await page.click('button:has-text("Create")')
|
||||
await page.click('#card-close')
|
||||
|
||||
await expect(page.locator('.estimation-container >> span').first()).toContainText(toTime(count))
|
||||
await expect(page.locator('.estimation-container >> span').first()).toContainText(await toTime(count))
|
||||
}
|
||||
})
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { expect, Page } from '@playwright/test'
|
||||
import { PlatformURI } from './utils'
|
||||
import { PlatformURI } from '../utils'
|
||||
|
||||
export interface IssueProps {
|
||||
name: string
|
||||
@ -203,3 +203,15 @@ export async function openIssue (page: Page, name: string): Promise<void> {
|
||||
timeout: 15000
|
||||
})
|
||||
}
|
||||
|
||||
export async function floorFractionDigits (n: number | string, amount: number): Promise<number> {
|
||||
return Number(Number(n).toFixed(amount))
|
||||
}
|
||||
|
||||
export async function toTime (value: number): Promise<string> {
|
||||
if (value > 0 && value < 8) {
|
||||
return `${await floorFractionDigits(value, 2)}h`
|
||||
} else {
|
||||
return `${await floorFractionDigits(value / 8, 3)}d`
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user