blaze-performance-tester 3.1.62 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -196,6 +196,93 @@ function loadBaselineData(filePath) {
196
196
  }
197
197
  return null;
198
198
  }
199
+ async function generateScenarioTS(prompt) {
200
+ const apiKey = process.env.GEMINI_API_KEY;
201
+ if (!apiKey) {
202
+ throw new Error("\u274C Environment variable GEMINI_API_KEY is missing. AI scenario generation aborted.");
203
+ }
204
+ console.log("\u{1F9E0} Translating natural language requirements into TypeScript via Gemini 2.5 Flash...");
205
+ const systemInstruction = `
206
+ You are an expert Performance & Systems Reliability Engineer specializing in QuickJS-compatible virtual user load testing scripts for the Blaze framework.
207
+ Your task is to convert a natural language description into a clean, valid TypeScript simulation script.
208
+
209
+ The script must adhere to this exact structural import pattern:
210
+ \`\`\`typescript
211
+ import { VirtualUser } from '../src/core/vu';
212
+
213
+ export async function runScenario(vu: VirtualUser) {
214
+ // Setup headers
215
+ // Execute multi-step operations (e.g., fetching a login, parsing tokens, making subsequent requests)
216
+ // Manage dynamic value extraction (e.g., const token = response.json().token) and pass variables forward
217
+ // Include standard loops (e.g., for-loops) or timeouts as requested
218
+ }
219
+ \`\`\`
220
+
221
+ Rules:
222
+ 1. Return ONLY executable, valid TypeScript script.
223
+ 2. Cleanly extract dynamic payload fields or tokens and assign them to downstream headers.
224
+ 3. Keep logic performance-optimized and sandbox-compatible.
225
+ 4. Do NOT wrap code blocks in backticks like \`\`\`typescript. Start directly with the TypeScript imports and export block. Do not include markdown or text commentary.
226
+ `;
227
+ try {
228
+ const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${apiKey}`, {
229
+ method: "POST",
230
+ headers: { "Content-Type": "application/json" },
231
+ body: JSON.stringify({
232
+ contents: [{ parts: [{ text: `Generate a Virtual User script for this scenario: ${prompt}` }] }],
233
+ generationConfig: {
234
+ temperature: 0.1,
235
+ maxOutputTokens: 65536
236
+ },
237
+ systemInstruction: {
238
+ parts: [{ text: systemInstruction }]
239
+ }
240
+ })
241
+ });
242
+ const data = await response.json();
243
+ if (data?.error) {
244
+ throw new Error(`Google API Error ${data.error.code}: ${data.error.message}`);
245
+ }
246
+ const candidateText = data?.candidates?.[0]?.content?.parts?.[0]?.text;
247
+ if (!candidateText) {
248
+ throw new Error(`Malformed API layout or empty response body.`);
249
+ }
250
+ return candidateText.replace(/```typescript/g, "").replace(/```javascript/g, "").replace(/```/g, "").trim();
251
+ } catch (error) {
252
+ throw new Error(`Failed to generate script via Gemini: ${error.message || error}`);
253
+ }
254
+ }
255
+ async function handleScenarioGeneration(config) {
256
+ const targetDir = path.resolve(__dirname, "./tests");
257
+ const tsFilePath = path.join(targetDir, "generated_scenario.ts");
258
+ const jsFilePath = path.join(targetDir, "generated_scenario.js");
259
+ try {
260
+ if (!fs.existsSync(targetDir)) {
261
+ fs.mkdirSync(targetDir, { recursive: true });
262
+ }
263
+ const tsCode = await generateScenarioTS(config.scenarioPrompt);
264
+ fs.writeFileSync(tsFilePath, tsCode, "utf-8");
265
+ console.log(`\u{1F4BE} Successfully generated scenario script saved to: ${tsFilePath}`);
266
+ console.log("\u2699\uFE0F Transpiling generated scenario to JavaScript for native QuickJS sandbox validation...");
267
+ let compiledSuccessfully = false;
268
+ try {
269
+ const { execSync } = require2("child_process");
270
+ execSync(`npx tsc "${tsFilePath}" --target es2020 --module commonjs --allowJs --skipLibCheck`, { stdio: "ignore" });
271
+ compiledSuccessfully = true;
272
+ } catch (e) {
273
+ console.warn("\u26A0\uFE0F TypeScript compiler (tsc) was not found or timed out. Falling back to clean JS copy conversion...");
274
+ }
275
+ if (!compiledSuccessfully) {
276
+ const cleanJs = tsCode.replace(/: VirtualUser/g, "").replace(/import {[^}]+} from .*/g, "").replace(/export async/g, "async");
277
+ fs.writeFileSync(jsFilePath, cleanJs, "utf-8");
278
+ }
279
+ console.log(`\u2705 Sandbox compilation resolved. Active test file: ${jsFilePath}`);
280
+ config.targetScript = jsFilePath;
281
+ } catch (error) {
282
+ console.error(`\u274C Scenario generation flow aborted: ${error.message || error}`);
283
+ process.exit(1);
284
+ }
285
+ }
199
286
  async function generateGeminiRCA(history, finalSummary, errorLogs) {
200
287
  const apiKey = process.env.GEMINI_API_KEY;
201
288
  if (!apiKey) {
@@ -232,7 +319,7 @@ Paragraph 3 - ARCHITECTURAL SIZING RECOMMENDATIONS: Give concrete, infrastructur
232
319
  CRITICAL: Return ONLY plain paragraph text. Do not use markdown headers (###). If you use bold text, use standard HTML <strong> tags. Wrap lines cleanly.
233
320
  `;
234
321
  try {
235
- const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${apiKey}`, {
322
+ const response = await fetch(`[https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=$](https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=$){apiKey}`, {
236
323
  method: "POST",
237
324
  headers: { "Content-Type": "application/json" },
238
325
  body: JSON.stringify({
@@ -269,13 +356,13 @@ async function executeTestPipeline(config) {
269
356
  const transactionalScenario = [
270
357
  {
271
358
  name: "Fetch Target Anti-Forgery Nonce",
272
- url: "https://httpbin.org/json",
359
+ url: "[https://httpbin.org/json](https://httpbin.org/json)",
273
360
  method: "GET",
274
361
  body: null
275
362
  },
276
363
  {
277
364
  name: "Perform Contextual Post Action",
278
- url: "https://httpbin.org/post?verification=${csrf_token}",
365
+ url: "[https://httpbin.org/post?verification=$](https://httpbin.org/post?verification=$){csrf_token}",
279
366
  method: "POST",
280
367
  body: JSON.stringify({
281
368
  data: "performance_payload",
@@ -300,6 +387,9 @@ async function main() {
300
387
  return;
301
388
  }
302
389
  const config = parseArguments(args);
390
+ if (config.scenarioPrompt) {
391
+ await handleScenarioGeneration(config);
392
+ }
303
393
  if (config.isCorrelate) {
304
394
  await executeTestPipeline(config);
305
395
  }
@@ -310,6 +400,12 @@ async function main() {
310
400
  }
311
401
  }
312
402
  function parseArguments(args) {
403
+ const scenarioIdx = args.indexOf("--generate-scenario");
404
+ let scenarioPrompt = null;
405
+ if (scenarioIdx !== -1) {
406
+ scenarioPrompt = args[scenarioIdx + 1];
407
+ args.splice(scenarioIdx, 2);
408
+ }
313
409
  const targetScript = path.resolve(args[0] || ".");
314
410
  const isAgentic = args.includes("--agentic");
315
411
  const isCorrelate = args.includes("--correlate");
@@ -363,6 +459,7 @@ function parseArguments(args) {
363
459
  }
364
460
  return {
365
461
  targetScript,
462
+ scenarioPrompt,
366
463
  isAgentic,
367
464
  isCorrelate,
368
465
  isSeo,
@@ -966,7 +1063,7 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
966
1063
  const htmlContent = `<!DOCTYPE html><html lang="en"><head>
967
1064
  <meta charset="UTF-8">
968
1065
  <title>Blaze Core Performance Report</title>
969
- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
1066
+ <script src="[https://cdn.jsdelivr.net/npm/chart.js](https://cdn.jsdelivr.net/npm/chart.js)"></script>
970
1067
  <style>
971
1068
  body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #0b111e; color: #f8fafc; margin: 0; padding: 2rem; }
972
1069
  .container { max-width: 1300px; margin: 0 auto; }
@@ -1459,6 +1556,14 @@ function exportHtmlDashboard(history, config, verdictReason, semanticReport, res
1459
1556
  function printUsage() {
1460
1557
  console.log(`Blaze Core Performance Test CLI Engine
1461
1558
  Options:
1462
- --threads <count> | --duration <seconds> | --baseline <json_file> | --output <html_file>`);
1559
+ --generate-scenario <prompt> Generates a virtual user script from a natural language prompt
1560
+ --threads <count> Number of concurrent threads (default: 10)
1561
+ --duration <seconds> Duration of stress testing in seconds (default: 10)
1562
+ --ramp-up <seconds> Ramp-up speed
1563
+ --ramp-down <seconds> Ramp-down speed
1564
+ --agentic Enable Intelligent Autonomous Agentic Stress Test
1565
+ --correlate Launch dynamic transaction parameter mapping pipeline
1566
+ --baseline <json_file> Input baseline JSON benchmark reference
1567
+ --output <html_file> Target path for exported standalone dashboard`);
1463
1568
  }
1464
1569
  main().catch(console.error);
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blaze-performance-tester",
3
- "version": "3.1.62",
3
+ "version": "3.2.0",
4
4
  "description": "A high-performance, multi-threaded load testing engine built with Rust and QuickJS.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",