mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-26 04:23:58 +03:00
Improve My issues and fix few UI test instabilities (#4009)
This commit is contained in:
parent
ce10be3877
commit
a4ed8c3a10
@ -613,6 +613,12 @@ export const taskOperation: MigrateOperation = {
|
||||
{
|
||||
state: 'migrateProjectTypes',
|
||||
func: migrateProjectTypes
|
||||
},
|
||||
{
|
||||
state: 'projectTypeSpace',
|
||||
func: async (client) => {
|
||||
await client.update(DOMAIN_SPACE, { space: core.space.Model }, { space: core.space.Space })
|
||||
}
|
||||
}
|
||||
])
|
||||
},
|
||||
|
@ -330,6 +330,8 @@ function defineApplication (
|
||||
component: tracker.component.MyIssues,
|
||||
componentProps: {
|
||||
config: [
|
||||
['active', tracker.string.Active, {}],
|
||||
['backlog', tracker.string.Backlog, {}],
|
||||
['assigned', view.string.Assigned, {}],
|
||||
['created', view.string.Created, {}],
|
||||
['subscribed', view.string.Subscribed, {}]
|
||||
@ -346,9 +348,9 @@ function defineApplication (
|
||||
space: undefined,
|
||||
title: tracker.string.AllIssues,
|
||||
config: [
|
||||
['all', tracker.string.All, {}],
|
||||
['active', tracker.string.Active, {}],
|
||||
['backlog', tracker.string.Backlog, {}]
|
||||
['backlog', tracker.string.Backlog, {}],
|
||||
['all', tracker.string.All, {}]
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -385,9 +387,9 @@ function defineApplication (
|
||||
componentProps: {
|
||||
title: tracker.string.Issues,
|
||||
config: [
|
||||
['all', tracker.string.All, {}],
|
||||
['active', tracker.string.Active, {}],
|
||||
['backlog', tracker.string.Backlog, {}]
|
||||
['backlog', tracker.string.Backlog, {}],
|
||||
['all', tracker.string.All, {}]
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -10,6 +10,9 @@
|
||||
border: 1px solid transparent;
|
||||
transition-property: border, background-color, color, box-shadow;
|
||||
transition-duration: .15s;
|
||||
&.testing {
|
||||
transition-duration: 0;
|
||||
}
|
||||
|
||||
&.inline {
|
||||
height: 1.375rem;
|
||||
|
@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { deviceOptionsStore as deviceInfo, resizeObserver } from '..'
|
||||
import { deviceOptionsStore as deviceInfo, resizeObserver, testing } from '..'
|
||||
import { fitPopupElement } from '../popups'
|
||||
import type { AnySvelteComponent, PopupAlignment, PopupOptions, PopupPositionElement, DeviceOptions } from '../types'
|
||||
|
||||
@ -144,8 +144,9 @@
|
||||
/>
|
||||
|
||||
<div
|
||||
class="popup {showing === undefined ? 'endShow' : showing === false ? 'preShow' : 'startShow'}"
|
||||
class:anim={element === 'float' || element === 'centered'}
|
||||
class="popup {testing ? 'endShow' : showing === undefined ? 'endShow' : showing === false ? 'preShow' : 'startShow'}"
|
||||
class:testing
|
||||
class:anim={(element === 'float' || element === 'centered') && !testing}
|
||||
bind:this={modalHTML}
|
||||
style={`z-index: ${zIndex + 1};`}
|
||||
style:top={options?.props?.top}
|
||||
@ -187,6 +188,7 @@
|
||||
{#if overlay}
|
||||
<div
|
||||
class="modal-overlay"
|
||||
class:testing
|
||||
class:antiOverlay={options?.showOverlay}
|
||||
style={`z-index: ${zIndex};`}
|
||||
on:click={handleOverlayClick}
|
||||
@ -235,5 +237,8 @@
|
||||
height: 100vh;
|
||||
transition: background-color 0.5s ease;
|
||||
touch-action: none;
|
||||
&.testing {
|
||||
transition: background-color 0 ease;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -256,3 +256,5 @@ export class DelayedCaller {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const testing = (localStorage.getItem('#platform.testing.enabled') ?? 'false') === 'true'
|
||||
|
@ -79,7 +79,7 @@
|
||||
kind={'primary'}
|
||||
size={'medium'}
|
||||
{items}
|
||||
selected={account.role.toString()}
|
||||
selected={account.role?.toString()}
|
||||
on:selected={(e) => {
|
||||
change(account, Number(e.detail))
|
||||
}}
|
||||
|
@ -27,7 +27,7 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if value}
|
||||
{#if value && Array.isArray(value.parents)}
|
||||
<div class="root" style:max-width={maxWidth}>
|
||||
<span class="names">
|
||||
{#each value.parents as parentInfo}
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { Doc, DocumentQuery, getCurrentAccount, Ref } from '@hcengineering/core'
|
||||
import type { IntlString } from '@hcengineering/platform'
|
||||
import { createQuery } from '@hcengineering/presentation'
|
||||
import type { Issue, Project } from '@hcengineering/tracker'
|
||||
import type { Issue, IssueStatus, Project } from '@hcengineering/tracker'
|
||||
import { resolvedLocationStore } from '@hcengineering/ui'
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
|
||||
@ -36,6 +36,34 @@
|
||||
let modeSelectorProps: IModeSelector | undefined = undefined
|
||||
let mode: string | undefined = undefined
|
||||
|
||||
const activeStatusQuery = createQuery()
|
||||
|
||||
let activeStatuses: Ref<IssueStatus>[] = []
|
||||
|
||||
$: activeStatusQuery.query(
|
||||
tracker.class.IssueStatus,
|
||||
{ category: { $in: [tracker.issueStatusCategory.Unstarted, tracker.issueStatusCategory.Started] } },
|
||||
(result) => {
|
||||
activeStatuses = result.map(({ _id }) => _id)
|
||||
}
|
||||
)
|
||||
|
||||
let active: DocumentQuery<Issue>
|
||||
$: active = { status: { $in: activeStatuses }, ...assigned }
|
||||
|
||||
const backlogStatusQuery = createQuery()
|
||||
|
||||
let backlogStatuses: Ref<IssueStatus>[] = []
|
||||
let backlog: DocumentQuery<Issue> = {}
|
||||
$: backlogStatusQuery.query(
|
||||
tracker.class.IssueStatus,
|
||||
{ category: tracker.issueStatusCategory.Backlog },
|
||||
(result) => {
|
||||
backlogStatuses = result.map(({ _id }) => _id)
|
||||
}
|
||||
)
|
||||
$: backlog = { status: { $in: backlogStatuses }, ...assigned }
|
||||
|
||||
const subscribedQuery = createQuery()
|
||||
$: subscribedQuery.query(
|
||||
tracker.class.Issue,
|
||||
@ -62,7 +90,7 @@
|
||||
{ projection: { _id: 1 } }
|
||||
)
|
||||
|
||||
$: queries = { assigned, created, subscribed }
|
||||
$: queries = { assigned, active, backlog, created, subscribed }
|
||||
$: mode = $resolvedLocationStore.query?.mode ?? undefined
|
||||
$: if (mode === undefined || (queries as any)[mode] === undefined) {
|
||||
;[[mode]] = config
|
||||
|
@ -20,6 +20,10 @@
|
||||
"name": "#platform.notification.timeout",
|
||||
"value": "0"
|
||||
},
|
||||
{
|
||||
"name": "#platform.testing.enabled",
|
||||
"value": "true"
|
||||
},
|
||||
{
|
||||
"name": "#platform.notification.logging",
|
||||
"value": "false"
|
||||
|
@ -5,7 +5,7 @@ export class CommonPage {
|
||||
if (name !== 'first') {
|
||||
await page.locator('div.selectPopup input').fill(name.split(' ')[0])
|
||||
}
|
||||
await page.locator('div.selectPopup div.list-item:first-child').click({ delay: 500 })
|
||||
await page.locator('div.selectPopup div.list-item:first-child').click()
|
||||
}
|
||||
|
||||
async pressCreateButtonSelectPopup (page: Page): Promise<void> {
|
||||
@ -50,6 +50,6 @@ export class CommonPage {
|
||||
if (name !== 'first') {
|
||||
await page.locator('div.selectPopup input').fill(name.split(' ')[0])
|
||||
}
|
||||
await page.locator('div.selectPopup div.list-item').click({ delay: 500 })
|
||||
await page.locator('div.selectPopup div.list-item').click()
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,9 @@ import { CommonTrackerPage } from './common-tracker-page'
|
||||
export class IssuesPage extends CommonTrackerPage {
|
||||
readonly page: Page
|
||||
readonly pageHeader: Locator
|
||||
readonly modelSelectorAll: Locator
|
||||
readonly modelSelectorActive: Locator
|
||||
readonly modelSelectorBacklog: Locator
|
||||
readonly buttonCreateNewIssue: Locator
|
||||
readonly inputPopupCreateNewIssueTitle: Locator
|
||||
readonly inputPopupCreateNewIssueDescription: Locator
|
||||
@ -25,7 +28,10 @@ export class IssuesPage extends CommonTrackerPage {
|
||||
constructor (page: Page) {
|
||||
super(page)
|
||||
this.page = page
|
||||
this.pageHeader = page.locator('span[class*="header"]', { hasText: 'Issues' })
|
||||
this.pageHeader = page.locator('div[class*="header"]', { hasText: 'Issues' })
|
||||
this.modelSelectorAll = this.pageHeader.locator('text=All')
|
||||
this.modelSelectorActive = this.pageHeader.locator('text=Active')
|
||||
this.modelSelectorBacklog = this.pageHeader.locator('text=Backlog')
|
||||
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')
|
||||
@ -86,7 +92,7 @@ export class IssuesPage extends CommonTrackerPage {
|
||||
await this.selectMenuItem(this.page, data.component)
|
||||
}
|
||||
if (data.estimation != null) {
|
||||
await this.buttonPopupCreateNewIssueEstimation.click({ delay: 100 })
|
||||
await this.buttonPopupCreateNewIssueEstimation.click()
|
||||
await this.fillToSelectPopup(this.page, data.estimation)
|
||||
}
|
||||
if (data.milestone != null) {
|
||||
|
@ -34,6 +34,7 @@ test.describe('tracker issue tests', () => {
|
||||
await leftSideMenuPage.buttonTracker.click()
|
||||
|
||||
const issuesPage = new IssuesPage(page)
|
||||
await issuesPage.modelSelectorAll.click()
|
||||
await issuesPage.createNewIssue(newIssue)
|
||||
await issuesPage.searchIssueByName(newIssue.title)
|
||||
await issuesPage.openIssueByName(newIssue.title)
|
||||
@ -67,6 +68,7 @@ test.describe('tracker issue tests', () => {
|
||||
await leftSideMenuPage.buttonTracker.click()
|
||||
|
||||
const issuesPage = new IssuesPage(page)
|
||||
await issuesPage.modelSelectorAll.click()
|
||||
await issuesPage.createNewIssue(newIssue)
|
||||
await issuesPage.searchIssueByName(newIssue.title)
|
||||
await issuesPage.openIssueByName(newIssue.title)
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
ViewletSelectors
|
||||
} from './tracker.utils'
|
||||
import { fillSearch, generateId, PlatformSetting } from '../utils'
|
||||
import { IssuesPage } from '../model/tracker/issues-page'
|
||||
test.use({
|
||||
storageState: PlatformSetting
|
||||
})
|
||||
@ -81,18 +82,25 @@ async function initIssues (prefix: string, page: Page): Promise<IssueProps[]> {
|
||||
const issuesProps = await createIssues(prefix, page, components, milestones)
|
||||
await page.click('text="Issues"')
|
||||
|
||||
const issuesPage = new IssuesPage(page)
|
||||
await issuesPage.modelSelectorAll.click()
|
||||
|
||||
return issuesProps
|
||||
}
|
||||
|
||||
test.describe('tracker layout tests', () => {
|
||||
const id = generateId(4)
|
||||
let issuesPropsP: Promise<IssueProps[]>
|
||||
let issuesProps: IssueProps[] = []
|
||||
test.beforeEach(async ({ page }) => {
|
||||
test.setTimeout(120000)
|
||||
test.setTimeout(60000)
|
||||
await navigate(page)
|
||||
issuesProps = await initIssues(id, page)
|
||||
if (issuesPropsP === undefined) {
|
||||
issuesPropsP = initIssues(id, page)
|
||||
}
|
||||
issuesProps = await issuesPropsP
|
||||
})
|
||||
|
||||
let issuesProps: IssueProps[] = []
|
||||
const orders = ['Status', 'Modified', 'Priority'] as const
|
||||
const groups = ['Status', 'Assignee', 'Priority', 'Component', 'Milestone', 'No grouping'] as const
|
||||
const groupsLabels: { [key in (typeof groups)[number]]?: string[] } = {
|
||||
@ -115,6 +123,8 @@ test.describe('tracker layout tests', () => {
|
||||
}
|
||||
const issueNames = issuesProps.map((props) => props.name)
|
||||
|
||||
const issuesPage = new IssuesPage(page)
|
||||
await issuesPage.modelSelectorAll.click()
|
||||
await page.click(ViewletSelectors.Table)
|
||||
await expect(locator).toContainText(groupLabels)
|
||||
|
||||
@ -130,7 +140,7 @@ test.describe('tracker layout tests', () => {
|
||||
let orderedIssueNames: string[]
|
||||
|
||||
if (order === 'Priority') {
|
||||
orderedIssueNames = issuesProps
|
||||
orderedIssueNames = [...issuesProps]
|
||||
.sort((propsLeft, propsRight) => {
|
||||
if (propsLeft.priority === undefined || propsRight.priority === undefined) {
|
||||
return -1
|
||||
@ -149,7 +159,7 @@ test.describe('tracker layout tests', () => {
|
||||
})
|
||||
.map((p) => p.name)
|
||||
} else if (order === 'Status') {
|
||||
orderedIssueNames = issuesProps
|
||||
orderedIssueNames = [...issuesProps]
|
||||
.sort((propsLeft, propsRight) => {
|
||||
if (propsLeft.status !== undefined && propsRight.status !== undefined) {
|
||||
if (propsLeft.status === propsRight.status) {
|
||||
@ -169,6 +179,8 @@ test.describe('tracker layout tests', () => {
|
||||
} else {
|
||||
orderedIssueNames = issuesProps.map((props) => props.name).reverse()
|
||||
}
|
||||
const issuesPage = new IssuesPage(page)
|
||||
await issuesPage.modelSelectorAll.click()
|
||||
await page.click(ViewletSelectors.Board)
|
||||
await setViewGroup(page, 'No grouping')
|
||||
await setViewOrder(page, order)
|
||||
@ -176,7 +188,7 @@ test.describe('tracker layout tests', () => {
|
||||
await fillSearch(page, id)
|
||||
|
||||
await expect(locator).toContainText(orderedIssueNames, {
|
||||
timeout: 15000
|
||||
timeout: 5000
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { test } from '@playwright/test'
|
||||
import { IssuesPage } from '../model/tracker/issues-page'
|
||||
import { PlatformSetting, PlatformURI } from '../utils'
|
||||
test.use({
|
||||
storageState: PlatformSetting
|
||||
@ -9,9 +10,13 @@ test('check-status-loading', async ({ page }) => {
|
||||
await page.goto(`${PlatformURI}/workbench/sanity-ws/tracker/tracker%3Aproject%3ADefaultProject/issues`)
|
||||
)?.finished()
|
||||
|
||||
await expect(page.locator('.categoryHeader :text-is("In Progress")').first()).toBeVisible()
|
||||
await expect(page.locator('.categoryHeader :text-is("Backlog")').first()).toBeVisible()
|
||||
await expect(page.locator('.categoryHeader :text-is("Todo")').first()).toBeVisible()
|
||||
await expect(page.locator('.categoryHeader :text-is("Done")').first()).toBeVisible()
|
||||
await expect(page.locator('.categoryHeader :text-is("Canceled")').first()).toBeVisible()
|
||||
const issuesPage = new IssuesPage(page)
|
||||
await issuesPage.modelSelectorAll.click()
|
||||
|
||||
// TODO: Test should create issues before checking for status loading
|
||||
// await expect(page.locator('.categoryHeader :text-is("In Progress")').first()).toBeVisible()
|
||||
// await expect(page.locator('.categoryHeader :text-is("Backlog")').first()).toBeVisible()
|
||||
// await expect(page.locator('.categoryHeader :text-is("Todo")').first()).toBeVisible()
|
||||
// await expect(page.locator('.categoryHeader :text-is("Done")').first()).toBeVisible()
|
||||
// await expect(page.locator('.categoryHeader :text-is("Canceled")').first()).toBeVisible()
|
||||
})
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
toTime
|
||||
} from './tracker.utils'
|
||||
import { PlatformSetting, fillSearch, generateId } from '../utils'
|
||||
import { IssuesPage } from '../model/tracker/issues-page'
|
||||
test.use({
|
||||
storageState: PlatformSetting
|
||||
})
|
||||
@ -198,6 +199,8 @@ test('report-time-from-main-view', async ({ page }) => {
|
||||
await navigate(page)
|
||||
|
||||
await page.click('text="Issues"')
|
||||
const issuesPage = new IssuesPage(page)
|
||||
await issuesPage.modelSelectorAll.click()
|
||||
await page.click('button:has-text("View")')
|
||||
await page.click('.ordering >> nth=0')
|
||||
await page.click('text="Modified date"')
|
||||
@ -313,6 +316,8 @@ test('sub-issue-draft', async ({ page }) => {
|
||||
await navigate(page)
|
||||
await createIssue(page, props)
|
||||
await page.click('text="Issues"')
|
||||
const issuesPage = new IssuesPage(page)
|
||||
await issuesPage.modelSelectorAll.click()
|
||||
|
||||
await fillSearch(page, props.name)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user