import { test, expect } from '@playwright/test'; import { login } from './helpers/auth'; import * as path from 'path'; import * as fs from 'fs'; /** * 庫存模組端到端測試 */ test.describe('庫存管理 - 調撥單匯入', () => { // 登入 + 導航 + 匯入全流程需要較長時間 test.use({ actionTimeout: 15000 }); test.beforeEach(async ({ page }) => { await login(page); }); test('應能成功匯入調撥單明細', async ({ page }) => { // 整體測試逾時設定為 60 秒 test.setTimeout(60000); // 1. 前往調撥單列表 await page.goto('/inventory/transfer-orders'); await expect(page.getByText('庫存調撥管理')).toBeVisible(); // 2. 等待表格載入並尋找特定的 E2E 測試單據 await page.waitForSelector('table tbody tr'); const draftRow = page.locator('tr:has-text("TRF-E2E-FINAL")').first(); const hasDraft = await draftRow.count() > 0; if (hasDraft) { // 點擊 "編輯" 按鈕 await draftRow.locator('button[title="編輯"], a:has-text("編輯")').first().click(); } else { throw new Error('測試環境中找不到單號為 TRF-E2E-FINAL 的調撥單。'); } // 3. 驗證已進入詳情頁 (標題包含調撥單單號) await expect(page.getByRole('heading', { name: /調撥單: TRF-/ })).toBeVisible({ timeout: 15000 }); // 4. 開啟匯入對話框 const importBtn = page.getByRole('button', { name: /匯入 Excel|匯入/ }); await expect(importBtn).toBeVisible(); await importBtn.click(); await expect(page.getByText('匯入調撥明細')).toBeVisible(); // 5. 準備測試檔案 (CSV 格式) const csvPath = path.join('/tmp', 'transfer_import_test.csv'); // 欄位名稱必須與後端匹配,商品代碼使用 P2 (紅糖) const csvContent = "商品代碼,數量,批號,備註\nP2,10,BATCH001,E2E Test Import\n"; fs.writeFileSync(csvPath, csvContent); // 6. 執行上傳 await page.setInputFiles('input[type="file"]', csvPath); // 7. 點擊開始匯入 await page.getByRole('button', { name: '開始匯入' }).click(); // 8. 等待頁面更新 (Inertia reload) await page.waitForTimeout(3000); // 9. 驗證詳情頁表格是否出現匯入的資料 // 注意:「E2E Test Import」是 input 的 value,不是靜態文字,hasText 無法匹配 input value // 因此先找包含 P2 文字的行(P2 是靜態 text),再驗證備註 input 的值 const p2Row = page.locator('table tbody tr').filter({ hasText: 'P2' }).first(); await expect(p2Row).toBeVisible({ timeout: 15000 }); // 驗證備註欄位的 input value 包含測試標記 // 快照中備註欄位的 role 是 textbox,placeholder 是 "備註..." const remarkInput = p2Row.getByRole('textbox', { name: '備註...' }); await expect(remarkInput).toHaveValue('E2E Test Import'); // 截圖留存 if (!fs.existsSync('e2e/screenshots')) fs.mkdirSync('e2e/screenshots', { recursive: true }); await page.screenshot({ path: 'e2e/screenshots/inventory-transfer-import-success.png', fullPage: true }); // 清理臨時檔案 if (fs.existsSync(csvPath)) fs.unlinkSync(csvPath); }); });