From a4ed8c3a10b4793d09514cafebe5cc78dbb4c788 Mon Sep 17 00:00:00 2001 From: Andrey Sobolev Date: Sat, 18 Nov 2023 15:20:19 +0700 Subject: [PATCH] Improve My issues and fix few UI test instabilities (#4009) --- models/task/src/migration.ts | 6 ++++ models/tracker/src/index.ts | 10 +++--- packages/theme/styles/button.scss | 3 ++ .../ui/src/components/PopupInstance.svelte | 11 +++++-- packages/ui/src/utils.ts | 2 ++ .../src/components/Owners.svelte | 2 +- .../issues/ParentNamesPresenter.svelte | 2 +- .../src/components/myissues/MyIssues.svelte | 32 +++++++++++++++++-- tests/sanity/storage-dev.json | 4 +++ tests/sanity/tests/model/common-page.ts | 4 +-- .../sanity/tests/model/tracker/issues-page.ts | 10 ++++-- tests/sanity/tests/tracker/issues.spec.ts | 2 ++ .../tests/tracker/tracker.layout.spec.ts | 24 ++++++++++---- .../tests/tracker/tracker.loading.spec.ts | 17 ++++++---- tests/sanity/tests/tracker/tracker.spec.ts | 5 +++ 15 files changed, 107 insertions(+), 27 deletions(-) diff --git a/models/task/src/migration.ts b/models/task/src/migration.ts index 281d3a873e..044dd504d1 100644 --- a/models/task/src/migration.ts +++ b/models/task/src/migration.ts @@ -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 }) + } } ]) }, diff --git a/models/tracker/src/index.ts b/models/tracker/src/index.ts index 737d6207b5..48bcf354ba 100644 --- a/models/tracker/src/index.ts +++ b/models/tracker/src/index.ts @@ -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, {}] ] } }, diff --git a/packages/theme/styles/button.scss b/packages/theme/styles/button.scss index 80a23ee1ea..2f4249155d 100644 --- a/packages/theme/styles/button.scss +++ b/packages/theme/styles/button.scss @@ -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; diff --git a/packages/ui/src/components/PopupInstance.svelte b/packages/ui/src/components/PopupInstance.svelte index e28c0326fd..1303c1cdf2 100644 --- a/packages/ui/src/components/PopupInstance.svelte +++ b/packages/ui/src/components/PopupInstance.svelte @@ -14,7 +14,7 @@ // limitations under the License. --> -{#if value} +{#if value && Array.isArray(value.parents)}
{#each value.parents as parentInfo} diff --git a/plugins/tracker-resources/src/components/myissues/MyIssues.svelte b/plugins/tracker-resources/src/components/myissues/MyIssues.svelte index f3412ccad9..0e34d6fcac 100644 --- a/plugins/tracker-resources/src/components/myissues/MyIssues.svelte +++ b/plugins/tracker-resources/src/components/myissues/MyIssues.svelte @@ -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[] = [] + + $: activeStatusQuery.query( + tracker.class.IssueStatus, + { category: { $in: [tracker.issueStatusCategory.Unstarted, tracker.issueStatusCategory.Started] } }, + (result) => { + activeStatuses = result.map(({ _id }) => _id) + } + ) + + let active: DocumentQuery + $: active = { status: { $in: activeStatuses }, ...assigned } + + const backlogStatusQuery = createQuery() + + let backlogStatuses: Ref[] = [] + let backlog: DocumentQuery = {} + $: 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 diff --git a/tests/sanity/storage-dev.json b/tests/sanity/storage-dev.json index 0965baea79..49064f83de 100644 --- a/tests/sanity/storage-dev.json +++ b/tests/sanity/storage-dev.json @@ -20,6 +20,10 @@ "name": "#platform.notification.timeout", "value": "0" }, + { + "name": "#platform.testing.enabled", + "value": "true" + }, { "name": "#platform.notification.logging", "value": "false" diff --git a/tests/sanity/tests/model/common-page.ts b/tests/sanity/tests/model/common-page.ts index 7c3fbc5f17..f732f76d30 100644 --- a/tests/sanity/tests/model/common-page.ts +++ b/tests/sanity/tests/model/common-page.ts @@ -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 { @@ -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() } } diff --git a/tests/sanity/tests/model/tracker/issues-page.ts b/tests/sanity/tests/model/tracker/issues-page.ts index 00e3a24300..7480e052f3 100644 --- a/tests/sanity/tests/model/tracker/issues-page.ts +++ b/tests/sanity/tests/model/tracker/issues-page.ts @@ -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) { diff --git a/tests/sanity/tests/tracker/issues.spec.ts b/tests/sanity/tests/tracker/issues.spec.ts index 97543c1167..8cf92146a6 100644 --- a/tests/sanity/tests/tracker/issues.spec.ts +++ b/tests/sanity/tests/tracker/issues.spec.ts @@ -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) diff --git a/tests/sanity/tests/tracker/tracker.layout.spec.ts b/tests/sanity/tests/tracker/tracker.layout.spec.ts index 9ca6a4fc2a..2f39f30a2d 100644 --- a/tests/sanity/tests/tracker/tracker.layout.spec.ts +++ b/tests/sanity/tests/tracker/tracker.layout.spec.ts @@ -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 { 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 + 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 }) }) } diff --git a/tests/sanity/tests/tracker/tracker.loading.spec.ts b/tests/sanity/tests/tracker/tracker.loading.spec.ts index 0767412dbf..af9fde6cc3 100644 --- a/tests/sanity/tests/tracker/tracker.loading.spec.ts +++ b/tests/sanity/tests/tracker/tracker.loading.spec.ts @@ -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() }) diff --git a/tests/sanity/tests/tracker/tracker.spec.ts b/tests/sanity/tests/tracker/tracker.spec.ts index ec6f2f76e0..5a966b14c9 100644 --- a/tests/sanity/tests/tracker/tracker.spec.ts +++ b/tests/sanity/tests/tracker/tracker.spec.ts @@ -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)