blaze-performance-tester 3.2.46 → 3.2.47

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.
Files changed (2) hide show
  1. package/dist/cli.js +70 -3
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -16335,6 +16335,8 @@ var i18n = {
16335
16335
  volume: "\u{1F4CA} Throughput Velocity & Workload Volume",
16336
16336
  concurrency: "\u{1F504} Active Concurrency (VUs) vs. TTF Trend & AI Load Forecast",
16337
16337
  status: "\u{1F369} HTTP Status Code Proportions",
16338
+ verbs: "\u{1F369} HTTP Verb Distribution",
16339
+ // Added HTTP Verb chart title
16338
16340
  scatter: "\u{1F4C8} Time-to-First-Byte Scatter Plot"
16339
16341
  },
16340
16342
  telemetry: {
@@ -16387,6 +16389,8 @@ var i18n = {
16387
16389
  volume: "\u{1F4CA} Velocidad de Rendimiento y Carga de Trabajo",
16388
16390
  concurrency: "\u{1F504} Concurrencia (VUs) vs Tendencia TTF",
16389
16391
  status: "\u{1F369} Proporciones de C\xF3digos HTTP",
16392
+ verbs: "\u{1F369} Distribuci\xF3n de Verbos HTTP",
16393
+ // Added HTTP Verb chart title
16390
16394
  scatter: "\u{1F4C8} Gr\xE1fico de Dispersi\xF3n de Tiempo de Respuesta"
16391
16395
  },
16392
16396
  telemetry: {
@@ -16439,6 +16443,8 @@ var i18n = {
16439
16443
  volume: "\u{1F4CA} \u0633\u0631\u0639\u0629 \u0627\u0644\u0625\u0646\u062A\u0627\u062C\u064A\u0629 \u0648\u062D\u062C\u0645 \u0639\u0628\u0621 \u0627\u0644\u0639\u0645\u0644",
16440
16444
  concurrency: "\u{1F504} \u0627\u0644\u062A\u0632\u0627\u0645\u0646 \u0627\u0644\u0646\u0634\u0637 (VUs) \u0645\u0642\u0627\u0628\u0644 \u0627\u062A\u062C\u0627\u0647 TTF \u0648\u062A\u0648\u0642\u0639\u0627\u062A \u0627\u0644\u062D\u0645\u0644",
16441
16445
  status: "\u{1F369} \u0646\u0633\u0628 \u0631\u0645\u0648\u0632 \u062D\u0627\u0644\u0629 HTTP",
16446
+ verbs: "\u{1F369} \u062A\u0648\u0632\u064A\u0639 \u0623\u0641\u0639\u0627\u0644 HTTP",
16447
+ // Added HTTP Verb chart title
16442
16448
  scatter: "\u{1F4C8} \u0645\u062E\u0637\u0637 \u0627\u0644\u062A\u0634\u062A\u062A \u0644\u0644\u0648\u0642\u062A \u0644\u0623\u0648\u0644 \u0628\u0627\u064A\u062A"
16443
16449
  },
16444
16450
  telemetry: {
@@ -16488,6 +16494,8 @@ var i18n = {
16488
16494
  volume: "\u{1F4CA} \u0925\u094D\u0930\u0942\u092A\u0941\u091F \u0935\u0947\u0917 \u0914\u0930 \u0935\u0930\u094D\u0915\u0932\u094B\u0921 \u0935\u0949\u0932\u094D\u092F\u0942\u092E",
16489
16495
  concurrency: "\u{1F504} \u0938\u0915\u094D\u0930\u093F\u092F \u0938\u092E\u0935\u0930\u094D\u0924\u0940 (VUs) \u092C\u0928\u093E\u092E TTF \u091F\u094D\u0930\u0947\u0902\u0921",
16490
16496
  status: "\u{1F369} HTTP \u0938\u094D\u091F\u0947\u091F\u0938 \u0915\u094B\u0921 \u0905\u0928\u0941\u092A\u093E\u0924",
16497
+ verbs: "\u{1F369} HTTP \u0935\u0930\u094D\u092C \u0935\u093F\u0924\u0930\u0923",
16498
+ // Added HTTP Verb chart title
16491
16499
  scatter: "\u{1F4C8} \u091F\u093E\u0907\u092E-\u091F\u0942-\u092B\u0930\u094D\u0938\u094D\u091F-\u092C\u093E\u0907\u091F \u0938\u094D\u0915\u0948\u091F\u0930 \u092A\u094D\u0932\u0949\u091F"
16492
16500
  },
16493
16501
  telemetry: {
@@ -16537,6 +16545,8 @@ var i18n = {
16537
16545
  volume: "\u{1F4CA} \u0B9A\u0BC6\u0BAF\u0BB2\u0BCD\u0BA4\u0BBF\u0BB1\u0BA9\u0BCD \u0BB5\u0BC7\u0B95\u0BAE\u0BCD \u0BAE\u0BB1\u0BCD\u0BB1\u0BC1\u0BAE\u0BCD \u0BAA\u0BA3\u0BBF\u0B9A\u0BCD\u0B9A\u0BC1\u0BAE\u0BC8",
16538
16546
  concurrency: "\u{1F504} \u0B9A\u0BC6\u0BAF\u0BB2\u0BBF\u0BB2\u0BCD \u0B89\u0BB3\u0BCD\u0BB3 \u0B87\u0BA3\u0BC8\u0BAA\u0BCD\u0BAA\u0BC1\u0B95\u0BB3\u0BCD (VUs) \u0BAE\u0BB1\u0BCD\u0BB1\u0BC1\u0BAE\u0BCD TTF \u0BAA\u0BCB\u0B95\u0BCD\u0B95\u0BC1",
16539
16547
  status: "\u{1F369} HTTP \u0BA8\u0BBF\u0BB2\u0BC8 \u0B95\u0BC1\u0BB1\u0BBF\u0BAF\u0BC0\u0B9F\u0BC1 \u0BB5\u0BBF\u0B95\u0BBF\u0BA4\u0B99\u0BCD\u0B95\u0BB3\u0BCD",
16548
+ verbs: "\u{1F369} HTTP \u0BB5\u0BBF\u0BA9\u0BC8 \u0BB5\u0BBF\u0BA8\u0BBF\u0BAF\u0BCB\u0B95\u0BAE\u0BCD",
16549
+ // Added HTTP Verb chart title
16540
16550
  scatter: "\u{1F4C8} TTFB \u0B9A\u0BBF\u0BA4\u0BB1\u0BB2\u0BCD \u0BB5\u0BB0\u0BC8\u0BAA\u0B9F\u0BAE\u0BCD"
16541
16551
  },
16542
16552
  telemetry: {
@@ -16586,6 +16596,8 @@ var i18n = {
16586
16596
  volume: "\u{1F4CA} \u0DB4\u0DCA\u200D\u0DBB\u0DC0\u0DCF\u0DC4 \u0DC0\u0DDA\u0D9C\u0DBA \u0DC3\u0DC4 \u0DC0\u0DD0\u0DA9 \u0DB6\u0DBB",
16587
16597
  concurrency: "\u{1F504} \u0DC3\u0D9A\u0DCA\u200D\u0DBB\u0DD3\u0DBA \u0DC3\u0DB8\u0D9C\u0DCF\u0DB8\u0DD3\u0DAD\u0DCA\u0DC0\u0DBA (VUs) \u0DC3\u0DC4 TTF \u0DB4\u0DCA\u200D\u0DBB\u0DC0\u0DAB\u0DAD\u0DCF\u0DC0",
16588
16598
  status: "\u{1F369} HTTP \u0DAD\u0DAD\u0DCA\u0DC0 \u0D9A\u0DDA\u0DAD \u0D85\u0DB1\u0DD4\u0DB4\u0DCF\u0DAD",
16599
+ verbs: "\u{1F369} HTTP \u0D9A\u0DCA\u200D\u0DBB\u0DD2\u0DBA\u0DCF \u0DB4\u0DAF \u0DC0\u0DCA\u200D\u0DBA\u0DCF\u0DB4\u0DCA\u0DAD\u0DD2\u0DBA",
16600
+ // Added HTTP Verb chart title
16589
16601
  scatter: "\u{1F4C8} TTFB \u0DC3\u0DCA\u0D9A\u0DD0\u0DA7\u0DBB\u0DCA \u0DB4\u0DCA\u0DBD\u0DDC\u0DA7\u0DCA"
16590
16602
  },
16591
16603
  telemetry: {
@@ -17079,6 +17091,7 @@ async function runIntelligentAgenticStressTest(config) {
17079
17091
  let total1xx = 0, total2xx = 0, total3xx = 0, total4xx = 0, total5xx = 0;
17080
17092
  let totalRequestsAccumulator = 0;
17081
17093
  const globalCodeCounts = { 400: 0, 401: 0, 403: 0, 404: 0, 429: 0, 500: 0, 502: 0, 503: 0, 504: 0 };
17094
+ const globalMethodCounts = { GET: 0, POST: 0, PUT: 0, DELETE: 0, PATCH: 0 };
17082
17095
  const globalMetricsAccumulator = { dns: [], tcp: [], tls: [], ttfb: [], latencies: [], bandwidths: [] };
17083
17096
  let currentThreads = Math.min(config.maxThreads, Math.max(5, Math.floor(config.maxThreads * 0.2)));
17084
17097
  const baseStep = config.stepSize;
@@ -17102,6 +17115,9 @@ async function runIntelligentAgenticStressTest(config) {
17102
17115
  targetCodes.forEach((code) => {
17103
17116
  globalCodeCounts[code] += metrics.codeCounts[code] || 0;
17104
17117
  });
17118
+ ["GET", "POST", "PUT", "DELETE", "PATCH"].forEach((m) => {
17119
+ globalMethodCounts[m] += metrics.methodCounts[m] || 0;
17120
+ });
17105
17121
  globalMetricsAccumulator.dns.push(metrics.avgDnsMs);
17106
17122
  globalMetricsAccumulator.tcp.push(metrics.avgTcpMs);
17107
17123
  globalMetricsAccumulator.tls.push(metrics.avgTlsMs);
@@ -17198,7 +17214,7 @@ async function runIntelligentAgenticStressTest(config) {
17198
17214
  breakdownRates[code] = totalRequestsAccumulator === 0 ? 0 : globalCodeCounts[code] / totalRequestsAccumulator * 100;
17199
17215
  });
17200
17216
  const baselineData = loadBaselineData(config.baselinePath);
17201
- exportHtmlDashboard(history, config, verdictReason, semanticReport, { total1xx, total2xx, total3xx, total4xx, total5xx, breakdownRates }, finalSummaryCards, lastRawRequests, geminiAnalysisHtml, wittyBriefingText, baselineData);
17217
+ exportHtmlDashboard(history, config, verdictReason, semanticReport, { total1xx, total2xx, total3xx, total4xx, total5xx, breakdownRates, methodCounts: globalMethodCounts }, finalSummaryCards, lastRawRequests, geminiAnalysisHtml, wittyBriefingText, baselineData);
17202
17218
  }
17203
17219
  async function runStandardStressTest(config) {
17204
17220
  console.log(`\u{1F3CB}\uFE0F Running Standard Stress Test [Threads: ${config.threads} | Duration: ${config.durationSec}s | RampUp: ${config.rampUpSec}s | RampDown: ${config.rampDownSec}s]`);
@@ -17267,7 +17283,8 @@ async function runStandardStressTest(config) {
17267
17283
  total3xx: metrics.c3xx,
17268
17284
  total4xx: metrics.c4xx,
17269
17285
  total5xx: metrics.c5xx,
17270
- breakdownRates
17286
+ breakdownRates,
17287
+ methodCounts: metrics.methodCounts
17271
17288
  }, finalSummaryCards, rawRequests, geminiAnalysisHtml, wittyBriefingText, baselineData);
17272
17289
  }
17273
17290
  function getFallbackClusterLogs() {
@@ -17294,6 +17311,7 @@ function generateSimulationData(threads, durationSec, maxAllowedLatencyMs, rampU
17294
17311
  const targetThresholdBreak = Math.max(5, Math.floor(maxAllowedLatencyMs * 0.05));
17295
17312
  const errorPool = getFallbackClusterLogs();
17296
17313
  const deviceProfilesList = ["Mobile Safari", "Desktop Chrome", "Desktop Firefox", "Edge Corporate"];
17314
+ const simulatedMethodPool = ["GET", "GET", "GET", "GET", "POST", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"];
17297
17315
  for (let i2 = 0; i2 < totalRequests; i2++) {
17298
17316
  const offsetMs = Math.random() * totalTestMs;
17299
17317
  const loadFactor = getLoadMultiplier(offsetMs, rampUpMs, steadyMs, rampDownMs);
@@ -17314,6 +17332,7 @@ function generateSimulationData(threads, durationSec, maxAllowedLatencyMs, rampU
17314
17332
  else if (deviceProfile === "Edge Corporate")
17315
17333
  deviceMultiplier = 1.05;
17316
17334
  const baseLatency = (25 + Math.random() * 35) * stressFactor * deviceMultiplier;
17335
+ const requestMethod = simulatedMethodPool[Math.floor(Math.random() * simulatedMethodPool.length)];
17317
17336
  let errorMessage;
17318
17337
  let statusCode = 200;
17319
17338
  if (isError) {
@@ -17328,6 +17347,7 @@ function generateSimulationData(threads, durationSec, maxAllowedLatencyMs, rampU
17328
17347
  tcpTimeMs: 4 + Math.random() * 1.5,
17329
17348
  tlsTimeMs: 6 + Math.random() * 1.8,
17330
17349
  statusCode,
17350
+ method: requestMethod,
17331
17351
  errorMessage,
17332
17352
  deviceProfile
17333
17353
  });
@@ -17346,6 +17366,7 @@ function processMetricsTelemetry(requests, durationSec) {
17346
17366
  const avgTtfbMs = avgDnsMs + avgTcpMs + avgTlsMs + avgLatencyMs * 0.3;
17347
17367
  let c1xx = 0, c2xx = 0, c3xx = 0, c4xx = 0, c5xx = 0;
17348
17368
  const codeCounts = { 400: 0, 401: 0, 403: 0, 404: 0, 429: 0, 500: 502, 503: 0, 504: 0 };
17369
+ const methodCounts = { GET: 0, POST: 0, PUT: 0, DELETE: 0, PATCH: 0 };
17349
17370
  [400, 401, 403, 404, 429, 500, 502, 503, 504].forEach((c3) => codeCounts[c3] = 0);
17350
17371
  requests.forEach((r) => {
17351
17372
  if (r.statusCode >= 100 && r.statusCode < 200)
@@ -17361,6 +17382,12 @@ function processMetricsTelemetry(requests, durationSec) {
17361
17382
  if (r.statusCode in codeCounts) {
17362
17383
  codeCounts[r.statusCode]++;
17363
17384
  }
17385
+ const mappedVerb = r.method ? r.method.toUpperCase() : "GET";
17386
+ if (methodCounts[mappedVerb] !== void 0) {
17387
+ methodCounts[mappedVerb]++;
17388
+ } else {
17389
+ methodCounts["GET"]++;
17390
+ }
17364
17391
  });
17365
17392
  const errorCount = c4xx + c5xx;
17366
17393
  const errorRate = totalRequests === 0 ? 0 : errorCount / totalRequests;
@@ -17387,7 +17414,8 @@ function processMetricsTelemetry(requests, durationSec) {
17387
17414
  avgTlsMs,
17388
17415
  avgTtfbMs,
17389
17416
  bandwidthMb,
17390
- codeCounts
17417
+ codeCounts,
17418
+ methodCounts
17391
17419
  };
17392
17420
  }
17393
17421
  function printMatrixDashboard(m, threads) {
@@ -17416,6 +17444,7 @@ function generateFinalAgentReport(history, score) {
17416
17444
  function exportHtmlDashboard(history, config, verdictReason, semanticReport, responseMatrix, cards, rawRequests = [], geminiAnalysisHtml = "", wittyBriefingText = "", baselineData = null) {
17417
17445
  const dict = i18n[config.locale] || i18n["en-US"];
17418
17446
  const dir = dict.rtl ? "rtl" : "ltr";
17447
+ const chartTitleVerbs = dict.charts.verbs || "\u{1F369} HTTP Verb Distribution";
17419
17448
  const formatter = new Intl.DateTimeFormat(config.locale || "en-US", {
17420
17449
  year: "numeric",
17421
17450
  month: "long",
@@ -17911,6 +17940,14 @@ ${formattedTicketLogs}
17911
17940
  </div>
17912
17941
  </div>
17913
17942
 
17943
+ <!-- \u{1F369} HTTP Verb Distribution Donut Addition -->
17944
+ <div class="graph-card">
17945
+ <div class="graph-title">${chartTitleVerbs}</div>
17946
+ <div style="height: 280px; position: relative;">
17947
+ <canvas id="verbDonutChart"></canvas>
17948
+ </div>
17949
+ </div>
17950
+
17914
17951
  <div class="graph-card">
17915
17952
  <div class="graph-title">${dict.charts.scatter}</div>
17916
17953
  <div style="height: 280px; position: relative;">
@@ -18142,6 +18179,36 @@ ${formattedTicketLogs}
18142
18179
  }
18143
18180
  });
18144
18181
 
18182
+ // HTTP Verbs Matrix Chart implementation
18183
+ const methodCountsData = ${JSON.stringify([
18184
+ responseMatrix.methodCounts?.GET || 0,
18185
+ responseMatrix.methodCounts?.POST || 0,
18186
+ responseMatrix.methodCounts?.PUT || 0,
18187
+ responseMatrix.methodCounts?.DELETE || 0,
18188
+ responseMatrix.methodCounts?.PATCH || 0
18189
+ ])};
18190
+
18191
+ new Chart(document.getElementById('verbDonutChart'), {
18192
+ type: 'doughnut',
18193
+ data: {
18194
+ labels: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
18195
+ datasets: [{
18196
+ data: methodCountsData,
18197
+ backgroundColor: ['#38bdf8', '#4ade80', '#facc15', '#f87171', '#c084fc'],
18198
+ borderWidth: 1,
18199
+ borderColor: '#1e293b'
18200
+ }]
18201
+ },
18202
+ options: {
18203
+ responsive: true,
18204
+ maintainAspectRatio: false,
18205
+ plugins: {
18206
+ legend: { position: 'top', labels: { color: '#94a3b8', font: { size: 11 } } },
18207
+ cutout: '65%'
18208
+ }
18209
+ }
18210
+ });
18211
+
18145
18212
  // Render User-Agent Device Splitting Donut Charts dynamically
18146
18213
  ${deviceMetrics.map((dm, idx) => `
18147
18214
  new Chart(document.getElementById('deviceDonutChart_${idx}'), {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "blaze-performance-tester",
3
- "version": "3.2.46",
3
+ "version": "3.2.47",
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",