prix-r9 2.0.2 → 2.0.3

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/README.md CHANGED
@@ -9,6 +9,7 @@ CLI para pruebas de carga HTTP/REST con ramp-up, multipart y escenarios encadena
9
9
  - Permite escenarios encadenados dentro de una misma iteracion usando `steps`.
10
10
  - Extrae valores del response JSON y los reutiliza en los siguientes steps.
11
11
  - Soporta escenarios simples de un solo request y escenarios encadenados por steps.
12
+ - Permite usar `insecureHttps: true` para endpoints HTTPS locales con certificados autofirmados.
12
13
  - Genera `reporte.txt` con metricas generales del escenario y metricas por step.
13
14
 
14
15
  ## Instalacion
@@ -73,6 +74,37 @@ Este formato sigue funcionando sin cambios:
73
74
 
74
75
  Este formato representa un escenario de endpoint unico.
75
76
 
77
+ ## HTTPS local con certificados no confiables
78
+
79
+ Si necesitas probar un endpoint local como `https://localhost:64847/...` con certificado autofirmado o no confiable, puedes activar:
80
+
81
+ ```json
82
+ {
83
+ "url": "https://localhost:64847/mdl37/api/Reports/GetReportAlliedBusinessByCompany",
84
+ "method": "POST",
85
+ "rate": 1,
86
+ "duration": 1,
87
+ "insecureHttps": true,
88
+ "headers": {
89
+ "Content-Type": "application/json"
90
+ },
91
+ "body": {
92
+ "StartDate": "2026-03-01",
93
+ "EndDate": "2026-03-17"
94
+ }
95
+ }
96
+ ```
97
+
98
+ Cuando `insecureHttps` es `true`, Prix-R9 usa un `https.Agent` con `rejectUnauthorized: false`.
99
+
100
+ Importante:
101
+ - usalo solo en ambientes locales o de desarrollo
102
+ - no lo uses en QA formal, staging productivo o produccion
103
+ - con esto ya no necesitas ejecutar `NODE_TLS_REJECT_UNAUTHORIZED=0`
104
+ - la herramienta muestra una advertencia en consola cuando esta opcion esta activa
105
+
106
+ En escenarios con `steps`, `insecureHttps` se puede declarar a nivel del escenario y aplica a todos los steps.
107
+
76
108
  ## Formato recomendado para escenarios encadenados
77
109
 
78
110
  La forma mas simple es usar `steps` con el mismo formato que genera `prix-r9-curl`, sin obligarte a anidar `request`.
@@ -133,6 +165,7 @@ Tambien se acepta la forma anidada con `request`, pero la forma directa suele se
133
165
  - `extract` guarda valores del response JSON para los steps siguientes.
134
166
  - Si un step falla por HTTP, red o extraccion, la iteracion termina y los steps restantes quedan omitidos por cascade.
135
167
  - En escenarios multi-step, el rate representa iteraciones por segundo.
168
+ - Si `insecureHttps` no esta presente o es `false`, el comportamiento TLS queda igual que antes.
136
169
 
137
170
  ## Extraccion de valores
138
171
 
@@ -200,9 +233,4 @@ Al finalizar, el CLI imprime un resumen y guarda `reporte.txt` con:
200
233
  prix-r9 --prompt
201
234
  ```
202
235
 
203
- Copia `promptInforme.txt` al directorio actual. El template ya esta orientado a analizar escenarios multi-step y distinguir entre metricas por iteracion y metricas por step.
204
-
205
-
206
-
207
-
208
-
236
+ Copia `promptInforme.txt` al directorio actual. El template ya esta orientado a analizar escenarios multi-step y distinguir entre metricas por iteracion y metricas por step.
package/import-curl.js CHANGED
@@ -5,7 +5,7 @@ const { program } = require('commander');
5
5
  const { toJsonString } = require('curlconverter');
6
6
 
7
7
  program
8
- .version('2.0.2')
8
+ .version('2.0.3')
9
9
  .description('Importador de cURL a config JSON base para pruebas de carga')
10
10
  .requiredOption('-i, --input <path>', 'Archivo de texto (.txt) que contiene el comando cURL crudo')
11
11
  .requiredOption('-o, --output <path>', 'Ruta de destino para el config JSON de la prueba (ej: casos/az/nuevo-endpoint.json)')
@@ -116,3 +116,4 @@ try {
116
116
 
117
117
 
118
118
 
119
+
package/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  const axios = require('axios');
3
+ const https = require('https');
3
4
  const fs = require('fs');
4
5
  const path = require('path');
5
6
  const FormData = require('form-data');
@@ -12,7 +13,7 @@ const BODY_METHODS = new Set(['POST', 'PUT', 'PATCH']);
12
13
  const PLACEHOLDER_PATTERN = /\{\{([^{}]+)\}\}/g;
13
14
 
14
15
  program
15
- .version('2.0.2')
16
+ .version('2.0.3')
16
17
  .description('Herramienta Avanzada HTTP/REST (Ramp-up y Datos Dinámicos)')
17
18
  .option('-c, --config <path>', 'Ruta a un archivo JSON con toda la configuración')
18
19
  .option('--prompt', 'Copia el template promptInforme.txt al directorio actual')
@@ -70,6 +71,7 @@ function normalizeStep(step, index, fallbackRequest) {
70
71
  body: sourceStep.body,
71
72
  file: sourceStep.file,
72
73
  filekey: sourceStep.filekey,
74
+ insecureHttps: sourceStep.insecureHttps,
73
75
  };
74
76
 
75
77
  return {
@@ -81,6 +83,7 @@ function normalizeStep(step, index, fallbackRequest) {
81
83
  body: request.body,
82
84
  file: request.file,
83
85
  filekey: request.filekey || 'file',
86
+ insecureHttps: request.insecureHttps,
84
87
  },
85
88
  extract: isPlainObject(sourceStep.extract) ? sourceStep.extract : {},
86
89
  };
@@ -101,10 +104,16 @@ function normalizeConfig(options) {
101
104
  targetRate: options.targetRate,
102
105
  rampUpTime: options.rampUpTime,
103
106
  duration: options.duration || 10,
107
+ insecureHttps: options.insecureHttps,
104
108
  };
105
109
  }
106
110
 
107
111
  function validateScenarioConfig(currentScenario) {
112
+ if (currentScenario.insecureHttps !== undefined && typeof currentScenario.insecureHttps !== 'boolean') {
113
+ console.error('Error: "insecureHttps" debe ser true o false.');
114
+ process.exit(1);
115
+ }
116
+
108
117
  if (!Array.isArray(currentScenario.steps) || currentScenario.steps.length === 0) {
109
118
  console.error('Error: Debes proporcionar al menos un step en "steps" o un request legacy con "url" y "method".');
110
119
  process.exit(1);
@@ -123,6 +132,11 @@ function validateScenarioConfig(currentScenario) {
123
132
  process.exit(1);
124
133
  }
125
134
 
135
+ if (request.insecureHttps !== undefined && typeof request.insecureHttps !== 'boolean') {
136
+ console.error(`Error: "insecureHttps" del step "${step.name}" debe ser true o false.`);
137
+ process.exit(1);
138
+ }
139
+
126
140
  if (request.file && !containsPlaceholders(request.file)) {
127
141
  const resolvedFile = path.isAbsolute(request.file)
128
142
  ? request.file
@@ -152,6 +166,8 @@ const startRate = isRampUp ? (scenario.startRate || 1) : (scenario.rate || 10);
152
166
  const targetRate = isRampUp ? scenario.targetRate : (scenario.rate || 10);
153
167
  const rampUpTime = isRampUp ? scenario.rampUpTime : 0;
154
168
  const duration = scenario.duration;
169
+ const insecureHttpsAgent = new https.Agent({ rejectUnauthorized: false });
170
+ const usesInsecureHttps = scenario.insecureHttps === true || scenario.steps.some((step) => step.request.insecureHttps === true);
155
171
 
156
172
  function calculateRate(second) {
157
173
  if (!isRampUp) return startRate;
@@ -382,6 +398,8 @@ function buildRequestConfig(step, context) {
382
398
  const resolvedFile = renderValue(step.request.file, context);
383
399
  const resolvedFileKey = renderValue(step.request.filekey || 'file', context);
384
400
 
401
+ const effectiveInsecureHttps = step.request.insecureHttps !== undefined ? step.request.insecureHttps : scenario.insecureHttps;
402
+
385
403
  const reqConfig = {
386
404
  method: step.request.method,
387
405
  url: resolvedUrl,
@@ -390,6 +408,10 @@ function buildRequestConfig(step, context) {
390
408
  timeout: 60000,
391
409
  };
392
410
 
411
+ if (effectiveInsecureHttps && typeof resolvedUrl === 'string' && resolvedUrl.startsWith('https://')) {
412
+ reqConfig.httpsAgent = insecureHttpsAgent;
413
+ }
414
+
393
415
  if (resolvedFile && BODY_METHODS.has(step.request.method)) {
394
416
  const finalFilePath = resolveFilePath(resolvedFile);
395
417
  if (!fs.existsSync(finalFilePath)) {
@@ -507,6 +529,10 @@ async function runTest() {
507
529
  metrics.scenario.configHeader.push(`Step ${index + 1}: ${step.name} [${step.request.method}] ${step.request.url}`);
508
530
  });
509
531
 
532
+ if (usesInsecureHttps) {
533
+ metrics.scenario.configHeader.push('HTTPS inseguro: habilitado (rejectUnauthorized=false)');
534
+ }
535
+
510
536
  if (isRampUp) {
511
537
  metrics.scenario.configHeader.push(`Ramp-up: De ${startRate} a ${targetRate} iter/s en ${rampUpTime}s`);
512
538
  metrics.scenario.configHeader.push(`Duración total: ${duration} segundos`);
@@ -523,6 +549,10 @@ async function runTest() {
523
549
  console.log(` ${index + 1}. ${step.name} [${step.request.method}] ${step.request.url}`);
524
550
  });
525
551
 
552
+ if (usesInsecureHttps) {
553
+ console.warn('⚠️ insecureHttps=true: se deshabilitó la validación TLS. Úsalo solo en localhost/dev con certificados autofirmados.');
554
+ }
555
+
526
556
  if (isRampUp) {
527
557
  console.log(`Ramp-up: De ${startRate} a ${targetRate} iter/s en ${rampUpTime}s`);
528
558
  console.log(`Mantenido en ${targetRate} iter/s hasta alcanzar los ${duration}s de prueba.`);
@@ -723,3 +753,4 @@ runTest()
723
753
 
724
754
 
725
755
 
756
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prix-r9",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "description": "CLI para pruebas de carga HTTP/REST con ramp-up, multipart y escenarios encadenados por steps.",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -47,6 +47,4 @@
47
47
  "form-data": "^4.0.5",
48
48
  "uuid": "^13.0.0"
49
49
  }
50
- }
51
-
52
-
50
+ }