@kkeve/suite 0.0.17 → 0.0.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kkeve/suite",
3
- "version": "0.0.17",
3
+ "version": "0.0.18",
4
4
  "description": "AI-powered full-stack test agent CLI - static analysis, unit test, component test, E2E test, execute, evaluate, and report",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -406,23 +406,68 @@ function readReportData(resultDir) {
406
406
 
407
407
  /**
408
408
  * 目标地址解析:优先使用用例 OPEN_PAGE 中的真实业务地址。
409
- * 只有 DSL 里的地址是本机占位地址,或 DSL 没有可用地址时,才使用
410
- * 调度入参 / 环境映射,避免 env=rc 覆盖用例明确声明的目标站点。
409
+ * 只有 DSL 里的地址是本机占位地址,或 DSL 没有可用地址时,才使用调度入参。
410
+ * 不做任何环境映射兜底——用例指定什么页面就访问什么页面,不私自替换为平台域名。
411
+ *
412
+ * 支持三种 OPEN_PAGE value 格式:
413
+ * 1. 字符串:直接用
414
+ * 2. { url } / { value }:取对应字段
415
+ * 3. { type: 'VARIABLE', value: varId, variable: [{key,value}] }:
416
+ * 从 variableList 查出对应环境的 URL,再应用 step.variable 改写
411
417
  */
412
418
  function deriveTargetUrl(input, cases) {
419
+ const env = String(input?.env || 'test');
413
420
  for (const item of cases) {
421
+ const variableList = Array.isArray(item.variableList) ? item.variableList : [];
414
422
  for (const raw of Array.isArray(item?.dslList) ? item.dslList : []) {
415
423
  const step = normalizeStep(raw);
416
424
  if (String(step?.operation || '') !== 'OPEN_PAGE') continue;
417
425
  const value = step.value;
418
- const candidate = typeof value === 'string'
419
- ? value
420
- : value?.url || value?.value || '';
421
- const candidateUrl = String(candidate || '').trim();
422
- if (!/^https?:\/\//i.test(candidateUrl)) continue;
423
- if (isLocalPlaceholderUrl(candidateUrl)) {
424
- continue;
426
+ let candidateUrl = '';
427
+ if (typeof value === 'string') {
428
+ candidateUrl = value.trim();
429
+ } else if (value && typeof value === 'object') {
430
+ if (value.type === 'VARIABLE' && variableList.length) {
431
+ // 变量库引用:按 id 查找变量行,取对应环境列
432
+ const varId = value.value;
433
+ const row = variableList.find((r) => String(r.id) === String(varId));
434
+ if (row) {
435
+ const cols = [env, 'test', 'online', 'rc', 'pre'];
436
+ const isUrl = (x) => typeof x === 'string' && /^https?:\/\//i.test(x.trim());
437
+ const isPlaceholder = (x) => /^(1|0|true|false)$/i.test(String(x ?? '').trim());
438
+ let base = '';
439
+ for (const c of cols) { if (isUrl(row[c])) { base = row[c]; break; } }
440
+ if (!base) {
441
+ for (const c of cols) {
442
+ const v = row[c];
443
+ if (typeof v === 'string' && v.trim() && !isPlaceholder(v)) { base = v; break; }
444
+ }
445
+ }
446
+ if (base) {
447
+ // 应用 step.variable 改写(与 buildVariableUrl 同逻辑)
448
+ const kv = new Map();
449
+ for (const item of row.variable || []) {
450
+ if (item && item.key !== undefined) kv.set(String(item.key), String(item.value ?? ''));
451
+ }
452
+ for (const item of value.variable || []) {
453
+ if (item && item.key !== undefined) kv.set(String(item.key), String(item.value ?? ''));
454
+ }
455
+ let url = String(base).replace(/\$\{([^}]+)}/g, (m, k) => kv.has(k) ? kv.get(k) : m);
456
+ for (const [k, v] of kv) {
457
+ if (!v || !/^[A-Za-z_][A-Za-z0-9_-]*$/.test(k)) continue;
458
+ const re = new RegExp(`([?&])${k}=[^&#]*`);
459
+ if (re.test(url)) url = url.replace(re, `$1${k}=${v}`);
460
+ else url += (url.includes('?') ? '&' : '?') + `${k}=${v}`;
461
+ }
462
+ candidateUrl = url.trim();
463
+ }
464
+ }
465
+ } else {
466
+ candidateUrl = String(value?.url || value?.value || '').trim();
467
+ }
425
468
  }
469
+ if (!/^https?:\/\//i.test(candidateUrl)) continue;
470
+ if (isLocalPlaceholderUrl(candidateUrl)) continue;
426
471
  return candidateUrl;
427
472
  }
428
473
  }
@@ -431,8 +476,8 @@ function deriveTargetUrl(input, cases) {
431
476
  if (/^https?:\/\//i.test(explicit)) {
432
477
  return explicit;
433
478
  }
434
- const envTarget = resolveEnvTargetUrl(input?.env);
435
- if (envTarget) return envTarget;
479
+ // 无法从用例和调度参数中取到有效地址,不做环境映射兜底,返回空串。
480
+ // cypress.config 中 baseUrl 留空时 Cypress 不会自行 visit,避免访问到平台自身域名。
436
481
  return '';
437
482
  }
438
483
 
@@ -445,17 +490,6 @@ function isLocalPlaceholderUrl(value) {
445
490
  }
446
491
  }
447
492
 
448
- function resolveEnvTargetUrl(env) {
449
- const normalized = String(env || '').trim().toLowerCase();
450
- return {
451
- online: 'https://keve.corp.kuaishou.com',
452
- pre: 'https://keve.corp.kuaishou.com',
453
- rc: 'https://rc-eve.corp.kuaishou.com',
454
- test: 'http://127.0.0.1:8080',
455
- local: 'http://127.0.0.1:8080',
456
- }[normalized] || '';
457
- }
458
-
459
493
  /**
460
494
  * 把 DSL 中指向本机的 OPEN_PAGE 地址投影为真实执行目标地址。
461
495
  *
@@ -600,7 +634,6 @@ function buildExecEnv({ input, taskDir, round, engine }) {
600
634
  export {
601
635
  deriveTargetUrl,
602
636
  isLocalPlaceholderUrl,
603
- resolveEnvTargetUrl,
604
637
  rewriteOpenPageTargets,
605
638
  };
606
639