| @@ -35,6 +35,10 @@ interface JsonResponse { | |||||
| } | } | ||||
| const suffix = (runId.replace(/[^A-Za-z0-9]/g, '').slice(-8) || 'MANUAL').toUpperCase() | const suffix = (runId.replace(/[^A-Za-z0-9]/g, '').slice(-8) || 'MANUAL').toUpperCase() | ||||
| const TOOL_ICON_PNG = Buffer.from( | |||||
| 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=', | |||||
| 'base64', | |||||
| ) | |||||
| const asRecord = (value: unknown): JsonRecord => value && typeof value === 'object' && !Array.isArray(value) | const asRecord = (value: unknown): JsonRecord => value && typeof value === 'object' && !Array.isArray(value) | ||||
| ? value as JsonRecord | ? value as JsonRecord | ||||
| @@ -477,6 +481,7 @@ test.describe('原型运营页面真实交互生命周期', () => { | |||||
| const editedName = `${name}-修订` | const editedName = `${name}-修订` | ||||
| const safePath = `/ape2e/${suffix.toLowerCase()}` | const safePath = `/ape2e/${suffix.toLowerCase()}` | ||||
| let resourceId = '' | let resourceId = '' | ||||
| let iconFileId = '' | |||||
| let primaryError: unknown | let primaryError: unknown | ||||
| await cleanupBySuffix(request, headers, 'tools', activities, cleanupErrors) | await cleanupBySuffix(request, headers, 'tools', activities, cleanupErrors) | ||||
| @@ -489,6 +494,7 @@ test.describe('原型运营页面真实交互生命周期', () => { | |||||
| let dialog = visibleDialog(page) | let dialog = visibleDialog(page) | ||||
| await fillFormItem(dialog, '工具名称', name) | await fillFormItem(dialog, '工具名称', name) | ||||
| await fillFormItem(dialog, '用途说明', '装备维修工单与作业进度协同入口。') | await fillFormItem(dialog, '用途说明', '装备维修工单与作业进度协同入口。') | ||||
| await dialog.getByRole('radio', { name: '工单台账' }).click() | |||||
| await dialog.getByText('高级接入参数(技术人员)').first().click() | await dialog.getByText('高级接入参数(技术人员)').first().click() | ||||
| await fillFormItem(dialog, '原始工具地址', 'http://127.0.0.1:8001') | await fillFormItem(dialog, '原始工具地址', 'http://127.0.0.1:8001') | ||||
| await fillFormItem(dialog, '入口路径', safePath) | await fillFormItem(dialog, '入口路径', safePath) | ||||
| @@ -507,6 +513,8 @@ test.describe('原型运营页面真实交互生命周期', () => { | |||||
| expect(created).not.toBeNull() | expect(created).not.toBeNull() | ||||
| resourceId = String(created?.id ?? '') | resourceId = String(created?.id ?? '') | ||||
| expect(created?.domain).toBe('https://example.com') | expect(created?.domain).toBe('https://example.com') | ||||
| expect(created?.icon).toBe('clipboard') | |||||
| await expect(card.locator('[data-icon="clipboard"]')).toBeVisible() | |||||
| activities.push({ module, action: '页面创建安全 HTTPS 工具', result: 'PASS', resourceId }) | activities.push({ module, action: '页面创建安全 HTTPS 工具', result: 'PASS', resourceId }) | ||||
| await captureScreenshot(page, testInfo, '09-tool-safe-url-created') | await captureScreenshot(page, testInfo, '09-tool-safe-url-created') | ||||
| @@ -514,13 +522,28 @@ test.describe('原型运营页面真实交互生命周期', () => { | |||||
| dialog = visibleDialog(page) | dialog = visibleDialog(page) | ||||
| await fillFormItem(dialog, '工具名称', editedName) | await fillFormItem(dialog, '工具名称', editedName) | ||||
| await fillFormItem(dialog, '用途说明', '装备维修工单、审批与进度协同入口(已修订)。') | await fillFormItem(dialog, '用途说明', '装备维修工单、审批与进度协同入口(已修订)。') | ||||
| await dialog.getByRole('radio', { name: '数据图表' }).click() | |||||
| await dialog.getByRole('radio', { name: '上传图片' }).click() | |||||
| await dialog.locator('.custom-icon-editor input[type="file"]').setInputFiles({ | |||||
| name: `tool-icon-${suffix}.png`, | |||||
| mimeType: 'image/png', | |||||
| buffer: TOOL_ICON_PNG, | |||||
| }) | |||||
| await expect(dialog.locator('.custom-icon-preview img')).toBeVisible() | |||||
| await dialog.getByRole('button', { name: '保存工具' }).click() | await dialog.getByRole('button', { name: '保存工具' }).click() | ||||
| await expectSuccessMessage(page, '工具配置已更新') | await expectSuccessMessage(page, '工具配置已更新') | ||||
| await page.reload() | await page.reload() | ||||
| await filterByKeyword(page, '搜索工具名称、分类或用途', editedName) | await filterByKeyword(page, '搜索工具名称、分类或用途', editedName) | ||||
| await page.locator('.tool-toolbar').getByRole('button', { name: '搜索' }).click() | |||||
| card = await cardByText(page, editedName) | card = await cardByText(page, editedName) | ||||
| await expect(card).toContainText('已修订') | await expect(card).toContainText('已修订') | ||||
| activities.push({ module, action: '页面编辑并刷新验证持久化', result: 'PASS', resourceId }) | |||||
| await expect(card.locator('[data-icon="chart"]')).toBeVisible() | |||||
| await expect(card.locator('.tool-card-icon img')).toBeVisible() | |||||
| const edited = await findResource(request, headers, 'tools', editedName, (item) => item.name === editedName) | |||||
| iconFileId = String(edited?.iconFileId ?? '') | |||||
| expect(iconFileId).not.toBe('') | |||||
| expect(String(edited?.iconUrl ?? '')).toMatch(/^\/api\/v1\/files\/.+\/content\?expires=/) | |||||
| activities.push({ module, action: '页面上传自定义图片图标并刷新验证持久化', result: 'PASS', resourceId }) | |||||
| const popupPromise = page.waitForEvent('popup') | const popupPromise = page.waitForEvent('popup') | ||||
| await card.getByRole('button', { name: '打开工具' }).click() | await card.getByRole('button', { name: '打开工具' }).click() | ||||
| @@ -544,7 +567,7 @@ test.describe('原型运营页面真实交互生命周期', () => { | |||||
| const statusSelect = page.locator('.toolbar .el-select').last() | const statusSelect = page.locator('.toolbar .el-select').last() | ||||
| await statusSelect.click() | await statusSelect.click() | ||||
| await page.locator('.el-select-dropdown:visible .el-select-dropdown__item').filter({ hasText: conditionLabel }).click() | await page.locator('.el-select-dropdown:visible .el-select-dropdown__item').filter({ hasText: conditionLabel }).click() | ||||
| await page.waitForTimeout(350) | |||||
| await page.locator('.tool-toolbar').getByRole('button', { name: '搜索' }).click() | |||||
| card = await cardByText(page, editedName) | card = await cardByText(page, editedName) | ||||
| activities.push({ | activities.push({ | ||||
| module, | module, | ||||
| @@ -559,6 +582,7 @@ test.describe('原型运营页面真实交互生命周期', () => { | |||||
| await expectSuccessMessage(page, '工具入口已停用') | await expectSuccessMessage(page, '工具入口已停用') | ||||
| await page.reload() | await page.reload() | ||||
| await filterByKeyword(page, '搜索工具名称、分类或用途', editedName) | await filterByKeyword(page, '搜索工具名称、分类或用途', editedName) | ||||
| await page.locator('.tool-toolbar').getByRole('button', { name: '搜索' }).click() | |||||
| card = await cardByText(page, editedName) | card = await cardByText(page, editedName) | ||||
| await expect(card).toHaveClass(/disabled/) | await expect(card).toHaveClass(/disabled/) | ||||
| activities.push({ module, action: '页面停用并刷新验证', result: 'PASS', resourceId }) | activities.push({ module, action: '页面停用并刷新验证', result: 'PASS', resourceId }) | ||||
| @@ -568,6 +592,9 @@ test.describe('原型运营页面真实交互生命周期', () => { | |||||
| await expectSuccessMessage(page, '工具已删除') | await expectSuccessMessage(page, '工具已删除') | ||||
| activities.push({ module, action: '页面删除工具', result: 'PASS', resourceId }) | activities.push({ module, action: '页面删除工具', result: 'PASS', resourceId }) | ||||
| resourceId = '' | resourceId = '' | ||||
| const retiredIcon = await request.get(`/api/v1/files/${encodeURIComponent(iconFileId)}`, { headers }) | |||||
| expect(retiredIcon.status(), '删除工具后未被共享的自定义图标应一并回收').toBe(404) | |||||
| iconFileId = '' | |||||
| } catch (error) { | } catch (error) { | ||||
| primaryError = error | primaryError = error | ||||
| activities.push({ module, action: '页面生命周期', result: 'FAIL', detail: error instanceof Error ? error.message : String(error) }) | activities.push({ module, action: '页面生命周期', result: 'FAIL', detail: error instanceof Error ? error.message : String(error) }) | ||||