From f8990446de9fa97670d3869bc4f84f01b49a8eb7 Mon Sep 17 00:00:00 2001 From: Vadym Hrechukha Date: Wed, 3 Dec 2025 18:51:04 +0200 Subject: [PATCH 1/3] HP-2826: Fix failing manager-model-export.spec.ts:4:1 in pw-hiqdev-stock CI due timeout problem --- tests/playwright/page/Index.ts | 52 +++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/tests/playwright/page/Index.ts b/tests/playwright/page/Index.ts index 23a99505..1101f433 100644 --- a/tests/playwright/page/Index.ts +++ b/tests/playwright/page/Index.ts @@ -2,6 +2,7 @@ import { expect, Page } from "@playwright/test"; import * as fs from "fs"; import AdvancedSearch from "@hipanel-core/helper/AdvancedSearch"; import { Alert, BulkActions, ColumnFilters } from "@hipanel-core/shared/ui/components"; +import {Download} from "@playwright/test"; export default class Index { advancedSearch: AdvancedSearch; @@ -212,30 +213,55 @@ export default class Index { } } - private async checkDownloadByLinkName(linkName: string) { - const linkLocator = this.page.locator(`a:has-text("${linkName}")`); + private async checkDownloadByLinkName(linkName: string): Promise { + const download = await this.triggerDownloadByLinkName(linkName); + const downloadPath = this.buildDownloadPath(download); - await linkLocator.highlight(); + await this.saveDownload(download, downloadPath); + + this.assertFileWasDownloaded(downloadPath); + this.assertFileIsNotEmpty(downloadPath, download); + } + + private async triggerDownloadByLinkName(linkName: string) { + const link = this.page.locator(`a:has-text("${linkName}")`); + await link.highlight(); const [download] = await Promise.all([ this.page.waitForEvent("download"), - linkLocator.click(), + link.click(), ]); - const downloadPath = `runtime/${download.suggestedFilename()}`; - await download.saveAs(downloadPath); + return download; + } - const fileExissts = fs.existsSync(downloadPath); - const stats = fs.statSync(downloadPath); + private buildDownloadPath(download: Download): string { + return `runtime/${download.suggestedFilename()}`; + } - const path = await download.path(); + private async saveDownload(download: Download, filePath: string): Promise { + await download.saveAs(filePath); - console.log("Temporary path:", path); + console.log("Temporary download path:", await download.path()); + } + + private assertFileWasDownloaded(filePath: string): void { + const isFileDownloaded = fs.existsSync(filePath); + + expect( + isFileDownloaded, + `Expected downloaded file to exist at: ${filePath}` + ).toBeTruthy(); + } - expect(fileExissts, `File not found at path: ${downloadPath}`).toBeTruthy(); + private assertFileIsNotEmpty(filePath: string, download: Download): void { + const stats = fs.statSync(filePath); - console.log(`File ${path}: ${stats.size} bytes`); + console.log(`Saved file ${filePath}: ${stats.size} bytes`); - expect(stats.size).toBeGreaterThan(0); + expect( + stats.size, + `Downloaded file "${download.suggestedFilename()}" is empty` + ).toBeGreaterThan(0); } } From 59d49de986d866d47b459d2c4cc90fccc17b7336 Mon Sep 17 00:00:00 2001 From: Vadym Hrechukha Date: Thu, 4 Dec 2025 04:05:04 +0200 Subject: [PATCH 2/3] HP-2826: modified code responsible for checking downloaded file to ensure it will work stable. --- tests/playwright/page/Index.ts | 44 ++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/tests/playwright/page/Index.ts b/tests/playwright/page/Index.ts index 1101f433..c5b21199 100644 --- a/tests/playwright/page/Index.ts +++ b/tests/playwright/page/Index.ts @@ -219,8 +219,7 @@ export default class Index { await this.saveDownload(download, downloadPath); - this.assertFileWasDownloaded(downloadPath); - this.assertFileIsNotEmpty(downloadPath, download); + await this.waitForFile(downloadPath); } private async triggerDownloadByLinkName(linkName: string) { @@ -245,23 +244,38 @@ export default class Index { console.log("Temporary download path:", await download.path()); } - private assertFileWasDownloaded(filePath: string): void { - const isFileDownloaded = fs.existsSync(filePath); + private async waitForFile(filePath: string, timeoutMs = 5000): Promise { + const pollingIntervalMs = 100; + const deadline = Date.now() + timeoutMs; - expect( - isFileDownloaded, - `Expected downloaded file to exist at: ${filePath}` - ).toBeTruthy(); + while (Date.now() < deadline) { + if (this.isFileReady(filePath)) { + return; + } + + console.log(`Waiting for file to be ready: ${filePath}`); + await this.delay(pollingIntervalMs); + } + + throw new Error(`Timed out waiting for file: ${filePath}`); } - private assertFileIsNotEmpty(filePath: string, download: Download): void { - const stats = fs.statSync(filePath); + private isFileReady(filePath: string): boolean { + if (!fs.existsSync(filePath)) { + return false; + } + + const { size } = fs.statSync(filePath); - console.log(`Saved file ${filePath}: ${stats.size} bytes`); + if (size > 0) { + console.log(`Downloaded file ready: ${filePath} (${size} bytes)`); + return true; + } + + return false; + } - expect( - stats.size, - `Downloaded file "${download.suggestedFilename()}" is empty` - ).toBeGreaterThan(0); + private delay(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); } } From 1abf7275d034c5450d4c1cb14f96511684d29fb6 Mon Sep 17 00:00:00 2001 From: Vadym Hrechukha Date: Thu, 4 Dec 2025 05:18:48 +0200 Subject: [PATCH 3/3] HP-2826: Trying to fix timeout issue --- tests/playwright/page/Index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/playwright/page/Index.ts b/tests/playwright/page/Index.ts index c5b21199..786820c0 100644 --- a/tests/playwright/page/Index.ts +++ b/tests/playwright/page/Index.ts @@ -223,13 +223,13 @@ export default class Index { } private async triggerDownloadByLinkName(linkName: string) { + const downloadPromise = this.page.waitForEvent('download'); + const link = this.page.locator(`a:has-text("${linkName}")`); await link.highlight(); + await link.click(); - const [download] = await Promise.all([ - this.page.waitForEvent("download"), - link.click(), - ]); + const download = await downloadPromise; return download; }