diff --git a/dist.zip b/dist.zip new file mode 100644 index 0000000..9fc9acd Binary files /dev/null and b/dist.zip differ diff --git a/release/dify-batch-tester-release-2026-04-20.tar.gz b/release/dify-batch-tester-release-2026-04-20.tar.gz new file mode 100644 index 0000000..313fd66 Binary files /dev/null and b/release/dify-batch-tester-release-2026-04-20.tar.gz differ diff --git a/release/dify-batch-tester-release-2026-04-29.tar.gz b/release/dify-batch-tester-release-2026-04-29.tar.gz new file mode 100644 index 0000000..45b622a Binary files /dev/null and b/release/dify-batch-tester-release-2026-04-29.tar.gz differ diff --git a/src/App.tsx b/src/App.tsx index f77c5df..60709b8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -38,6 +38,26 @@ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Di import { DifyInput, TestCase, DifyConfig, AppMode, NodeTraceStep, NodeStatus, TestResult } from './types'; +const createId = () => { + if (globalThis.crypto?.randomUUID) { + return globalThis.crypto.randomUUID(); + } + + if (globalThis.crypto?.getRandomValues) { + const bytes = new Uint8Array(16); + globalThis.crypto.getRandomValues(bytes); + bytes[6] = (bytes[6] & 0x0f) | 0x40; + bytes[8] = (bytes[8] & 0x3f) | 0x80; + + return Array.from(bytes, (byte, index) => { + const hex = byte.toString(16).padStart(2, '0'); + return [4, 6, 8, 10].includes(index) ? `-${hex}` : hex; + }).join(''); + } + + return `id-${Date.now()}-${Math.random().toString(36).slice(2)}`; +}; + // Parse a Dify SSE stream (workflow/advanced-chat) into a TestResult. // Emits live updates via onUpdate after each meaningful event so the UI // can reflect node-level progress as it arrives. @@ -202,7 +222,7 @@ export default function App() { const [testCases, setTestCases] = useState([]); const [isExecuting, setIsExecuting] = useState(false); const [isStopping, setIsStopping] = useState(false); - const [captureTrace, setCaptureTrace] = useState(false); + const [captureTrace, setCaptureTrace] = useState(true); const [traceDialogResult, setTraceDialogResult] = useState(null); const [difyConfig, setDifyConfig] = useState({ apiKey: '', @@ -256,7 +276,7 @@ export default function App() { if (response.status === 404) { setInputs([]); setTestCases([{ - id: crypto.randomUUID(), + id: createId(), inputs: {}, times: 1, status: 'idle', @@ -365,7 +385,7 @@ export default function App() { }); return { - id: crypto.randomUUID(), + id: createId(), inputs: testCaseInputs, query: difyConfig.appMode === 'chat' ? (row['query'] || row['Query'] || '') : undefined, times: parseInt(row['times'] || row['Times'] || '1') || 1, @@ -389,7 +409,7 @@ export default function App() { const addTestCase = () => { const newCase: TestCase = { - id: crypto.randomUUID(), + id: createId(), inputs: {}, query: difyConfig.appMode === 'chat' ? '' : undefined, times: 1, @@ -1145,7 +1165,7 @@ export default function App() {