canary-test-cli 5.15.0 → 6.0.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.
Files changed (79) hide show
  1. package/agent/frameworks/registry.json +655 -0
  2. package/bin/canary.js +20 -15
  3. package/dist/doctor-manifest.d.ts +94 -0
  4. package/dist/doctor.d.ts +67 -0
  5. package/dist/engine/analysis/cli.js +270 -0
  6. package/dist/engine/analysis/engine.js +146 -0
  7. package/dist/engine/analysis/reports.js +0 -0
  8. package/dist/engine/analysis/rows.js +9 -0
  9. package/dist/engine/cli-commands.js +618 -0
  10. package/dist/engine/cli-common.js +60 -0
  11. package/dist/engine/cli.core.js +208 -0
  12. package/dist/engine/cli.js +31 -0
  13. package/dist/engine/company-knowledge-cli.js +201 -0
  14. package/dist/engine/core/ci-env.js +33 -0
  15. package/dist/engine/core/classifier.js +192 -0
  16. package/dist/engine/core/company-knowledge.js +765 -0
  17. package/dist/engine/core/config-validation.js +74 -0
  18. package/dist/engine/core/detection.js +48 -0
  19. package/dist/engine/core/domain-scanner.js +212 -0
  20. package/dist/engine/core/environment-detect.js +410 -0
  21. package/dist/engine/core/executor.js +181 -0
  22. package/dist/engine/core/feedback.js +93 -0
  23. package/dist/engine/core/fixture-scanner.js +173 -0
  24. package/dist/engine/core/framework-registry.js +123 -0
  25. package/dist/engine/core/mcp-validator.js +218 -0
  26. package/dist/engine/core/metadata-scanner.js +147 -0
  27. package/dist/engine/core/migrator.js +1112 -0
  28. package/dist/engine/core/overlays.js +176 -0
  29. package/dist/engine/core/pattern-healer.js +147 -0
  30. package/dist/engine/core/pattern-matcher.js +255 -0
  31. package/dist/engine/core/quality-scorer.js +213 -0
  32. package/dist/engine/core/recommender.js +152 -0
  33. package/dist/engine/core/reporter.js +211 -0
  34. package/dist/engine/core/scaffolder.js +236 -0
  35. package/dist/engine/core/skill-registry.js +522 -0
  36. package/dist/engine/core/static-linter.js +237 -0
  37. package/dist/engine/core/ticket-updater.js +639 -0
  38. package/dist/engine/core/workflow-discovery.js +693 -0
  39. package/dist/engine/guardian/agent-tier.js +338 -0
  40. package/dist/engine/guardian/analysis-emit.js +201 -0
  41. package/dist/engine/guardian/cli.js +787 -0
  42. package/dist/engine/guardian/coverage.js +1055 -0
  43. package/dist/engine/guardian/delta-emitter.js +46 -0
  44. package/dist/engine/guardian/diff-extractor.js +257 -0
  45. package/dist/engine/guardian/hard-gate.js +373 -0
  46. package/dist/engine/guardian/impact-mapper.js +121 -0
  47. package/dist/engine/guardian/pr-check.js +975 -0
  48. package/dist/engine/guardian/pr-comment.js +200 -0
  49. package/dist/engine/guardian/summary-emitter.js +94 -0
  50. package/dist/engine/guardian/tier.js +58 -0
  51. package/dist/engine/history/cli.js +303 -0
  52. package/dist/engine/history/detector.js +68 -0
  53. package/dist/engine/history/ndjson-store.js +177 -0
  54. package/dist/engine/history/record.js +14 -0
  55. package/dist/engine/history/schema.js +59 -0
  56. package/dist/engine/history/store.js +47 -0
  57. package/dist/engine/history/supabase-store.js +113 -0
  58. package/dist/engine/main-deps.js +105 -0
  59. package/dist/engine/mcp-server.js +647 -0
  60. package/dist/engine/package.json +4 -0
  61. package/dist/engine/skills-cli.js +181 -0
  62. package/dist/engine/ui/banner.js +50 -0
  63. package/dist/engine/util/coalesce.js +12 -0
  64. package/dist/engine/util/round.js +43 -0
  65. package/dist/engine/workflow-cli.js +242 -0
  66. package/dist/engine-checks.d.ts +49 -0
  67. package/dist/overlay-commands.d.ts +81 -0
  68. package/dist/overlay-conflicts.d.ts +33 -0
  69. package/dist/overlay-lint.d.ts +19 -0
  70. package/dist/overlays-registry.d.ts +74 -0
  71. package/dist/reporters/testtracker.d.ts +89 -0
  72. package/dist/reporters/testtracker.js +195 -0
  73. package/dist/router.d.ts +12 -0
  74. package/dist/router.js +4 -4
  75. package/dist/skill-requirements.d.ts +57 -0
  76. package/dist/source-spec.d.ts +20 -0
  77. package/package.json +30 -6
  78. package/bin/canary +0 -0
  79. package/scripts/install.js +0 -104
@@ -0,0 +1,655 @@
1
+ {
2
+ "frameworks": [
3
+ {
4
+ "name": "playwright",
5
+ "display_name": "Playwright",
6
+ "category": "e2e_ui",
7
+ "categories": ["e2e_ui", "api"],
8
+ "languages": ["typescript", "javascript"],
9
+ "file_extensions": ["spec.ts", "spec.js", "test.ts", "test.js"],
10
+ "execution_command": "npx --yes playwright test {file}",
11
+ "ci_flags": ["--reporter=list"],
12
+ "ecosystems": ["react", "vue", "angular", "node"],
13
+ "status": "preferred",
14
+ "maturity": "high",
15
+ "community_size": "large",
16
+ "recommended_for": [
17
+ "end-to-end testing",
18
+ "cross-browser testing",
19
+ "modern frontend applications"
20
+ ],
21
+ "strengths": [
22
+ "Reliable auto-waiting",
23
+ "Strong TypeScript support",
24
+ "Modern testing architecture",
25
+ "Fast execution"
26
+ ],
27
+ "avoid_when": ["legacy selenium-only environments"]
28
+ },
29
+ {
30
+ "name": "vitest",
31
+ "display_name": "Vitest",
32
+ "category": "frontend_unit",
33
+ "languages": ["typescript", "javascript"],
34
+ "file_extensions": ["test.ts", "test.js", "spec.ts", "spec.js"],
35
+ "execution_command": "npx --yes vitest run {file}",
36
+ "ci_flags": ["--reporter=verbose"],
37
+ "ecosystems": ["vite", "react", "vue"],
38
+ "status": "preferred",
39
+ "maturity": "high",
40
+ "community_size": "large",
41
+ "recommended_for": [
42
+ "frontend unit testing",
43
+ "component testing",
44
+ "modern vite ecosystems"
45
+ ],
46
+ "strengths": [
47
+ "Fast execution",
48
+ "Modern developer experience",
49
+ "Vite-native integration"
50
+ ],
51
+ "avoid_when": ["legacy jest-only environments"]
52
+ },
53
+ {
54
+ "name": "pytest",
55
+ "display_name": "pytest",
56
+ "category": "api",
57
+ "languages": ["python"],
58
+ "file_extensions": ["py"],
59
+ "file_patterns": ["test_*.py", "*_test.py"],
60
+ "execution_command": "pytest {file}",
61
+ "ci_flags": ["--tb=short", "-p", "no:cacheprovider"],
62
+ "ecosystems": ["python"],
63
+ "status": "preferred",
64
+ "maturity": "very_high",
65
+ "community_size": "massive",
66
+ "recommended_for": [
67
+ "python backend testing",
68
+ "api testing",
69
+ "integration testing"
70
+ ],
71
+ "strengths": [
72
+ "Extremely mature ecosystem",
73
+ "Powerful fixtures",
74
+ "Excellent plugin ecosystem"
75
+ ],
76
+ "avoid_when": []
77
+ },
78
+ {
79
+ "name": "schemathesis",
80
+ "display_name": "Schemathesis",
81
+ "category": "api",
82
+ "categories": ["api", "contract"],
83
+ "languages": ["python"],
84
+ "file_extensions": ["py"],
85
+ "file_patterns": ["test_*.py", "*_test.py"],
86
+ "execution_command": "schemathesis run {file}",
87
+ "ci_flags": ["--checks", "all", "--max-response-time", "2000"],
88
+ "ecosystems": ["python", "openapi", "rest"],
89
+ "status": "supported",
90
+ "license": "MIT",
91
+ "maturity": "high",
92
+ "community_size": "medium",
93
+ "recommended_for": [
94
+ "property-based API testing",
95
+ "OpenAPI fuzz testing",
96
+ "finding schema/implementation drift"
97
+ ],
98
+ "strengths": [
99
+ "Automatically generates test cases from OpenAPI schemas",
100
+ "Finds coercion bugs and undocumented responses hand-written tests miss",
101
+ "Zero test code required — point at an OpenAPI URL",
102
+ "MIT licensed, no API key, no external service"
103
+ ],
104
+ "avoid_when": [
105
+ "No OpenAPI/Swagger spec available",
106
+ "API has destructive side-effects not safe to trigger randomly (use --dry-run or filter operations)"
107
+ ]
108
+ },
109
+ {
110
+ "name": "k6",
111
+ "display_name": "k6",
112
+ "category": "performance",
113
+ "languages": ["javascript"],
114
+ "file_extensions": ["js"],
115
+ "file_patterns": ["load.js", "*.load.js"],
116
+ "execution_command": "k6 run {file}",
117
+ "ci_flags": [],
118
+ "ecosystems": ["api", "backend", "microservices"],
119
+ "status": "preferred",
120
+ "maturity": "high",
121
+ "community_size": "large",
122
+ "recommended_for": [
123
+ "performance testing",
124
+ "load testing",
125
+ "api stress testing"
126
+ ],
127
+ "strengths": [
128
+ "Developer-friendly scripting",
129
+ "Strong CI/CD integration",
130
+ "Modern architecture"
131
+ ],
132
+ "avoid_when": []
133
+ },
134
+ {
135
+ "name": "axe-core",
136
+ "display_name": "axe-core",
137
+ "category": "accessibility",
138
+ "languages": ["typescript", "javascript"],
139
+ "file_extensions": ["spec.ts", "spec.js"],
140
+ "execution_command": "npx --yes playwright test {file}",
141
+ "ecosystems": ["playwright", "react", "vue", "angular"],
142
+ "status": "supported",
143
+ "maturity": "high",
144
+ "community_size": "large",
145
+ "recommended_for": [
146
+ "accessibility audits (WCAG)",
147
+ "a11y regression checks in existing E2E suites"
148
+ ],
149
+ "strengths": [
150
+ "Pairs with an existing Playwright suite via @axe-core/playwright",
151
+ "Maps findings to WCAG success criteria",
152
+ "No separate runner to maintain"
153
+ ],
154
+ "avoid_when": ["projects with no browser-driven test layer"]
155
+ },
156
+ {
157
+ "name": "zap",
158
+ "display_name": "OWASP ZAP",
159
+ "category": "security",
160
+ "languages": ["any"],
161
+ "execution_command": "zap-baseline.py -t {target}",
162
+ "ecosystems": ["web", "api"],
163
+ "status": "supported",
164
+ "maturity": "high",
165
+ "community_size": "large",
166
+ "recommended_for": [
167
+ "dynamic application security testing (DAST)",
168
+ "baseline vulnerability scans in CI"
169
+ ],
170
+ "strengths": [
171
+ "Mature OWASP-backed scanner",
172
+ "Scriptable baseline scan for CI gating",
173
+ "Active + passive scan modes"
174
+ ],
175
+ "avoid_when": [
176
+ "static-only analysis needs (use static_analysis category instead)"
177
+ ]
178
+ },
179
+ {
180
+ "name": "backstopjs",
181
+ "display_name": "BackstopJS",
182
+ "category": "visual",
183
+ "languages": ["javascript", "typescript"],
184
+ "file_extensions": ["js", "json"],
185
+ "execution_command": "npx --yes backstop test",
186
+ "ecosystems": ["web"],
187
+ "status": "supported",
188
+ "maturity": "medium",
189
+ "community_size": "medium",
190
+ "recommended_for": [
191
+ "visual regression testing",
192
+ "pixel-diff snapshots across viewports"
193
+ ],
194
+ "strengths": [
195
+ "Dedicated visual-diff workflow",
196
+ "Configurable viewports and scenarios"
197
+ ],
198
+ "avoid_when": ["teams already using Playwright snapshots inline with E2E"]
199
+ },
200
+ {
201
+ "name": "pact",
202
+ "display_name": "Pact",
203
+ "category": "contract",
204
+ "languages": ["typescript", "javascript", "python", "java"],
205
+ "execution_command": "npx --yes pact verify",
206
+ "ecosystems": ["microservices", "api"],
207
+ "status": "supported",
208
+ "maturity": "high",
209
+ "community_size": "large",
210
+ "recommended_for": [
211
+ "consumer-driven contract testing between services",
212
+ "preventing integration drift across teams"
213
+ ],
214
+ "strengths": [
215
+ "Consumer-driven contracts",
216
+ "Broker for sharing pacts across teams",
217
+ "Polyglot language support"
218
+ ],
219
+ "avoid_when": ["single-team monolith with no cross-service contracts"]
220
+ },
221
+ {
222
+ "name": "chaos-toolkit",
223
+ "display_name": "Chaos Toolkit",
224
+ "category": "chaos",
225
+ "languages": ["python"],
226
+ "file_extensions": ["json", "yaml"],
227
+ "execution_command": "chaos run {file}",
228
+ "ecosystems": ["kubernetes", "cloud", "microservices"],
229
+ "status": "supported",
230
+ "maturity": "medium",
231
+ "community_size": "medium",
232
+ "recommended_for": [
233
+ "chaos engineering experiments",
234
+ "resilience and fault-injection testing"
235
+ ],
236
+ "strengths": [
237
+ "Declarative experiment definitions",
238
+ "Extensible driver ecosystem (k8s, cloud providers)"
239
+ ],
240
+ "avoid_when": ["systems without redundancy to absorb induced failures"]
241
+ },
242
+ {
243
+ "name": "sdv",
244
+ "display_name": "SDV (Synthetic Data Vault)",
245
+ "category": "synthetic_data",
246
+ "languages": ["python"],
247
+ "execution_command": "python -m pytest {file}",
248
+ "ecosystems": ["python", "data"],
249
+ "status": "preferred",
250
+ "license": "BSL-1.1",
251
+ "license_note": "Business Source License — source-available, not OSI open-source. Internal test-data generation is generally within permitted use, but BSL carries a production-use restriction. Downstream adopters must review BSL against their own business/procurement rules before relying on it; fall back to Faker if BSL is unacceptable.",
252
+ "maturity": "high",
253
+ "community_size": "medium",
254
+ "recommended_for": [
255
+ "statistically faithful synthetic datasets",
256
+ "schema-aware multi-table data preserving distributions and correlations"
257
+ ],
258
+ "strengths": [
259
+ "Learns real-data distributions and cross-column relationships",
260
+ "Relational / multi-table synthesis",
261
+ "Higher fidelity than field-level fakers"
262
+ ],
263
+ "avoid_when": [
264
+ "BSL is unacceptable under the adopter's license policy (use Faker)"
265
+ ]
266
+ },
267
+ {
268
+ "name": "faker",
269
+ "display_name": "Faker",
270
+ "category": "synthetic_data",
271
+ "languages": ["python", "javascript", "typescript"],
272
+ "execution_command": "python -m pytest {file}",
273
+ "ecosystems": ["any"],
274
+ "status": "supported",
275
+ "maturity": "very_high",
276
+ "community_size": "massive",
277
+ "recommended_for": [
278
+ "generating realistic synthetic test data",
279
+ "seeding fixtures without production data"
280
+ ],
281
+ "strengths": [
282
+ "Permissive MIT license",
283
+ "Huge provider catalog",
284
+ "Python and JS implementations"
285
+ ],
286
+ "avoid_when": [
287
+ "statistically faithful, distribution-matching datasets are required (prefer SDV, subject to its BSL review)"
288
+ ]
289
+ },
290
+ {
291
+ "name": "opentelemetry",
292
+ "display_name": "OpenTelemetry",
293
+ "category": "observability",
294
+ "languages": ["any"],
295
+ "ecosystems": ["distributed-systems", "microservices"],
296
+ "status": "supported",
297
+ "maturity": "high",
298
+ "community_size": "large",
299
+ "recommended_for": [
300
+ "instrumentation and telemetry assertions",
301
+ "validating traces/metrics/logs emitted under test"
302
+ ],
303
+ "strengths": [
304
+ "Vendor-neutral standard",
305
+ "Traces, metrics, and logs in one SDK"
306
+ ],
307
+ "avoid_when": [
308
+ "simple apps with no distributed call graph (Stage 2 routes this, issue #129)"
309
+ ]
310
+ },
311
+ {
312
+ "name": "maestro",
313
+ "display_name": "Maestro",
314
+ "category": "mobile",
315
+ "languages": ["yaml"],
316
+ "file_extensions": ["yaml", "yml"],
317
+ "execution_command": "maestro test {file}",
318
+ "ecosystems": ["android", "ios", "react-native", "flutter"],
319
+ "status": "supported",
320
+ "maturity": "medium",
321
+ "community_size": "medium",
322
+ "recommended_for": [
323
+ "mobile UI flow testing (Android/iOS)",
324
+ "cross-platform mobile smoke tests"
325
+ ],
326
+ "strengths": [
327
+ "Simple YAML flow syntax",
328
+ "Built-in flakiness tolerance",
329
+ "Single tool across Android and iOS"
330
+ ],
331
+ "avoid_when": [
332
+ "deep native-instrumentation needs (consider Appium/Espresso)"
333
+ ]
334
+ },
335
+ {
336
+ "name": "locust",
337
+ "display_name": "Locust",
338
+ "category": "load",
339
+ "languages": ["python"],
340
+ "file_extensions": ["py"],
341
+ "file_patterns": ["locustfile.py", "*_locust.py"],
342
+ "execution_command": "locust -f {file} --headless",
343
+ "ecosystems": ["api", "web", "backend"],
344
+ "status": "supported",
345
+ "maturity": "high",
346
+ "community_size": "large",
347
+ "recommended_for": [
348
+ "Python-defined load scenarios",
349
+ "soak and spike testing with concurrent users"
350
+ ],
351
+ "strengths": [
352
+ "Load scenarios as plain Python",
353
+ "Distributed mode for high concurrency",
354
+ "Live web UI for run monitoring"
355
+ ],
356
+ "avoid_when": [
357
+ "teams standardized on k6 for performance (overlapping concern)"
358
+ ]
359
+ },
360
+ {
361
+ "name": "stryker",
362
+ "display_name": "Stryker Mutator",
363
+ "category": "mutation",
364
+ "languages": ["typescript", "javascript"],
365
+ "file_extensions": ["js", "ts"],
366
+ "execution_command": "npx --yes stryker run",
367
+ "ecosystems": ["node", "react", "vue"],
368
+ "status": "supported",
369
+ "maturity": "high",
370
+ "community_size": "medium",
371
+ "recommended_for": [
372
+ "mutation testing to measure test-suite effectiveness",
373
+ "finding assertions that never actually fail"
374
+ ],
375
+ "strengths": [
376
+ "Reveals weak/ineffective tests",
377
+ "Integrates with Jest/Vitest/Mocha"
378
+ ],
379
+ "avoid_when": [
380
+ "suites too slow to tolerate the mutation runtime multiplier"
381
+ ]
382
+ },
383
+ {
384
+ "name": "semgrep",
385
+ "display_name": "Semgrep",
386
+ "category": "static_analysis",
387
+ "languages": ["any"],
388
+ "file_extensions": ["yaml", "yml"],
389
+ "execution_command": "semgrep --config auto {target}",
390
+ "ecosystems": ["any"],
391
+ "status": "supported",
392
+ "maturity": "high",
393
+ "community_size": "large",
394
+ "recommended_for": [
395
+ "static analysis and custom lint rules",
396
+ "catching anti-patterns and code smells pre-merge"
397
+ ],
398
+ "strengths": [
399
+ "Pattern rules across many languages",
400
+ "Fast, CI-friendly, custom-rule authoring"
401
+ ],
402
+ "avoid_when": ["runtime/dynamic behavior is what needs verifying"]
403
+ },
404
+ {
405
+ "name": "testcontainers",
406
+ "display_name": "Testcontainers",
407
+ "category": "integration",
408
+ "languages": ["python", "typescript", "javascript", "java", "go"],
409
+ "execution_command": "pytest {file}",
410
+ "ecosystems": ["docker", "microservices", "backend"],
411
+ "status": "supported",
412
+ "maturity": "high",
413
+ "community_size": "large",
414
+ "recommended_for": [
415
+ "integration tests against real dependencies (DBs, brokers) in Docker",
416
+ "replacing brittle mocks with disposable real services"
417
+ ],
418
+ "strengths": [
419
+ "Real dependencies in ephemeral containers",
420
+ "Polyglot bindings",
421
+ "Deterministic teardown"
422
+ ],
423
+ "avoid_when": ["CI without a Docker daemon available"]
424
+ },
425
+ {
426
+ "name": "tosca",
427
+ "display_name": "Tricentis Tosca",
428
+ "category": "e2e_ui",
429
+ "languages": ["any"],
430
+ "ecosystems": ["enterprise", "sap", "web"],
431
+ "status": "commercial",
432
+ "license": "commercial",
433
+ "license_gate": "CANARY_LICENSE_TRICENTIS",
434
+ "maturity": "high",
435
+ "community_size": "medium",
436
+ "recommended_for": [
437
+ "model-based / codeless E2E in orgs that already license Tricentis"
438
+ ],
439
+ "strengths": [
440
+ "Codeless model-based authoring",
441
+ "Broad enterprise app coverage"
442
+ ],
443
+ "avoid_when": [
444
+ "no active Tricentis license — prefer the OSS default (Playwright)"
445
+ ]
446
+ },
447
+ {
448
+ "name": "neoload",
449
+ "display_name": "Tricentis NeoLoad",
450
+ "category": "performance",
451
+ "languages": ["any"],
452
+ "ecosystems": ["enterprise", "api", "web"],
453
+ "status": "commercial",
454
+ "license": "commercial",
455
+ "license_gate": "CANARY_LICENSE_TRICENTIS",
456
+ "maturity": "high",
457
+ "community_size": "medium",
458
+ "recommended_for": [
459
+ "enterprise load testing in orgs that already license Tricentis"
460
+ ],
461
+ "strengths": [
462
+ "Enterprise protocol coverage",
463
+ "Integrated with Tricentis suite"
464
+ ],
465
+ "avoid_when": [
466
+ "no active Tricentis license — prefer the OSS default (k6)"
467
+ ]
468
+ },
469
+ {
470
+ "name": "lambdatest",
471
+ "display_name": "LambdaTest",
472
+ "category": "e2e_ui",
473
+ "languages": ["any"],
474
+ "ecosystems": ["cloud", "cross-browser"],
475
+ "status": "commercial",
476
+ "license": "commercial-org",
477
+ "license_gate": "CANARY_SCOPE",
478
+ "maturity": "high",
479
+ "community_size": "large",
480
+ "recommended_for": [
481
+ "cloud cross-browser grids for orgs holding a LambdaTest license"
482
+ ],
483
+ "strengths": [
484
+ "Large device/browser cloud",
485
+ "Parallel cross-browser runs"
486
+ ],
487
+ "avoid_when": [
488
+ "no org license scope set — prefer the OSS default (Playwright)"
489
+ ]
490
+ },
491
+ {
492
+ "name": "mutmut",
493
+ "display_name": "mutmut",
494
+ "category": "mutation",
495
+ "languages": ["python"],
496
+ "file_extensions": ["py"],
497
+ "file_patterns": ["test_*.py", "*_test.py"],
498
+ "execution_command": "mutmut run",
499
+ "ci_flags": [],
500
+ "ecosystems": ["python", "pytest"],
501
+ "status": "supported",
502
+ "license": "BSD-3-Clause",
503
+ "maturity": "high",
504
+ "community_size": "medium",
505
+ "recommended_for": [
506
+ "mutation testing for Python suites",
507
+ "measuring whether pytest assertions actually catch regressions"
508
+ ],
509
+ "strengths": [
510
+ "The de-facto Python mutation runner (closes the Python-mutation routing gap Stryker cannot serve)",
511
+ "Reads pytest configuration — no separate test harness",
512
+ "Reveals assertions that never fail"
513
+ ],
514
+ "avoid_when": [
515
+ "suites too slow to tolerate the mutation runtime multiplier",
516
+ "TypeScript/JavaScript projects (use Stryker)"
517
+ ]
518
+ },
519
+ {
520
+ "name": "wdio",
521
+ "display_name": "Appium + WebdriverIO",
522
+ "category": "mobile",
523
+ "languages": ["typescript", "javascript"],
524
+ "file_extensions": ["spec.ts", "spec.js"],
525
+ "execution_command": "npx --yes wdio run wdio.conf.ts --spec {file}",
526
+ "ci_flags": [],
527
+ "ecosystems": ["android", "ios", "react-native", "appium"],
528
+ "status": "supported",
529
+ "license": "MIT",
530
+ "maturity": "high",
531
+ "community_size": "large",
532
+ "recommended_for": [
533
+ "deep native-instrumentation mobile testing (Android/iOS) via Appium",
534
+ "cross-platform mobile suites needing real element interaction"
535
+ ],
536
+ "strengths": [
537
+ "Full Appium capability access (native selectors, gestures, contexts)",
538
+ "Mature WebdriverIO runner with rich reporter/service ecosystem",
539
+ "TypeScript-first authoring; `canary init wdio` scaffolds wdio.conf plus a capabilities stub"
540
+ ],
541
+ "avoid_when": [
542
+ "simple UI-flow smoke tests where Maestro's YAML flows are enough"
543
+ ]
544
+ },
545
+ {
546
+ "name": "hurl",
547
+ "display_name": "Hurl",
548
+ "category": "api",
549
+ "categories": ["api"],
550
+ "languages": ["hurl"],
551
+ "file_extensions": ["hurl"],
552
+ "file_patterns": ["*.hurl"],
553
+ "execution_command": "hurl --test {file}",
554
+ "ci_flags": ["--report-junit", "hurl-report.xml"],
555
+ "ecosystems": ["api", "rest", "http"],
556
+ "status": "supported",
557
+ "license": "Apache-2.0",
558
+ "maturity": "high",
559
+ "community_size": "medium",
560
+ "recommended_for": [
561
+ "single-file plain-text HTTP API tests",
562
+ "API checks for less-technical personas — no programming language required"
563
+ ],
564
+ "strengths": [
565
+ "One `.hurl` file per test fits the one-file execution model exactly",
566
+ "Human-readable HTTP DSL with assertions and captures",
567
+ "Fast native runner, no runtime dependency to install per project"
568
+ ],
569
+ "avoid_when": [
570
+ "complex programmatic setup/teardown is needed (use pytest or Playwright request)"
571
+ ]
572
+ },
573
+ {
574
+ "name": "fast-check",
575
+ "display_name": "fast-check",
576
+ "category": "property",
577
+ "languages": ["typescript", "javascript"],
578
+ "file_extensions": ["test.ts", "test.js", "spec.ts", "spec.js"],
579
+ "execution_command": "npx --yes vitest run {file}",
580
+ "ci_flags": ["--reporter=verbose"],
581
+ "ecosystems": ["node", "vitest", "jest"],
582
+ "status": "preferred",
583
+ "license": "MIT",
584
+ "maturity": "high",
585
+ "community_size": "large",
586
+ "recommended_for": [
587
+ "property-based / invariant testing in TypeScript and JavaScript",
588
+ "finding edge cases hand-written examples miss via generated inputs"
589
+ ],
590
+ "strengths": [
591
+ "Piggybacks the existing host runner (Vitest/Jest) — no new runner",
592
+ "Shrinking reports the minimal failing case",
593
+ "Rich arbitraries for structured input generation"
594
+ ],
595
+ "avoid_when": [
596
+ "behavior has no expressible invariant (example-based tests fit better)"
597
+ ]
598
+ },
599
+ {
600
+ "name": "hypothesis",
601
+ "display_name": "Hypothesis",
602
+ "category": "property",
603
+ "languages": ["python"],
604
+ "file_extensions": ["py"],
605
+ "file_patterns": ["test_*.py", "*_test.py"],
606
+ "execution_command": "pytest {file}",
607
+ "ci_flags": ["--tb=short", "-p", "no:cacheprovider"],
608
+ "ecosystems": ["python", "pytest"],
609
+ "status": "supported",
610
+ "license": "MPL-2.0",
611
+ "maturity": "very_high",
612
+ "community_size": "large",
613
+ "recommended_for": [
614
+ "property-based / invariant testing in Python",
615
+ "generative edge-case discovery over pytest suites"
616
+ ],
617
+ "strengths": [
618
+ "Runs inside pytest as the host runner — no new harness",
619
+ "Automatic shrinking to a minimal failing example",
620
+ "Strategy library for composing input generators"
621
+ ],
622
+ "avoid_when": [
623
+ "behavior has no expressible invariant (example-based tests fit better)"
624
+ ]
625
+ },
626
+ {
627
+ "name": "promptfoo",
628
+ "display_name": "promptfoo",
629
+ "category": "llm_eval",
630
+ "languages": ["yaml"],
631
+ "file_extensions": ["yaml", "yml"],
632
+ "file_patterns": ["promptfooconfig.yaml", "*.promptfoo.yaml"],
633
+ "execution_command": "npx --yes promptfoo eval -c {file}",
634
+ "ci_flags": ["--no-progress-bar"],
635
+ "ecosystems": ["llm", "prompts"],
636
+ "status": "supported",
637
+ "license": "MIT",
638
+ "maturity": "high",
639
+ "community_size": "medium",
640
+ "recommended_for": [
641
+ "LLM-behavior regression testing across prompts and model versions",
642
+ "assertion-based eval of prompt outputs (quality, format, safety)"
643
+ ],
644
+ "strengths": [
645
+ "Declarative YAML eval config — versioned alongside prompts",
646
+ "Model-agnostic assertions with side-by-side comparison",
647
+ "CI-friendly pass/fail gating on eval thresholds"
648
+ ],
649
+ "avoid_when": [
650
+ "no LLM under test (this is not a general functional-testing tool)"
651
+ ],
652
+ "provider_access_note": "Route provider access through the agent-plugin path — never embed raw API keys in the eval config or CI."
653
+ }
654
+ ]
655
+ }