synapse-hub 2.4.2 → 2.5.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/.agents/agents/orchestrator.md +1 -0
- package/.agents/agents/pom-crafter.md +1 -0
- package/.agents/agents/quality-gatekeeper.md +6 -0
- package/.agents/rules/skill-precedence.md +38 -18
- package/.agents/rules/systematic-debugging.md +2 -0
- package/.agents/skills/lean-code-ladder/SKILL.md +12 -1
- package/.agents/skills/lean-impact-scoreboard/SKILL.md +48 -0
- package/.agents/skills/lean-impact-scoreboard/examples/sample_benchmark_gain.md +20 -0
- package/.agents/skills/lean-impact-scoreboard/examples/sample_scoreboard.md +15 -0
- package/.agents/skills/repo-quality-audit/SKILL.md +68 -0
- package/.agents/skills/repo-quality-audit/examples/sample_audit_walkthrough.md +15 -0
- package/.agents/skills/repo-quality-audit/examples/sample_repo_audit.md +33 -0
- package/.agents/skills/senior-code-review/SKILL.md +90 -0
- package/.agents/skills/senior-code-review/examples/sample_review_walkthrough.md +29 -0
- package/.agents/skills/technical-debt-harvester/SKILL.md +70 -0
- package/.agents/skills/technical-debt-harvester/examples/sample_debt_ledger.md +25 -0
- package/.agents/skills/technical-debt-harvester/examples/sample_ledger_output.md +20 -0
- package/.cursor/rules/synapse-qa.mdc +4 -3
- package/.cursorrules +1 -0
- package/.windsurfrules +1 -0
- package/AGENTS.md +51 -179
- package/CLAUDE.md +5 -0
- package/README.en.md +12 -8
- package/README.md +12 -8
- package/bin/agent-qa.js +3 -2
- package/docs/ARCHITECTURE.md +3 -3
- package/docs/CLI_REFERENCE.md +15 -1
- package/package.json +1 -3
- package/skills_manifest.json +38 -2
- package/synapse.config.json +1 -1
- package/templates/ai_bridges/CLAUDE.md +5 -0
- package/templates/ai_bridges/copilot-instructions.md +2 -0
- package/templates/ai_bridges/cursor_synapse_qa.mdc +4 -3
- package/templates/ai_bridges/windsurfrules +1 -0
- package/tools/.infer_baseline.json +7 -1079
- package/tools/TOOLS_RUNBOOK.md +53 -13
- package/tools/__init__.py +1 -1
- package/tools/agent_canary.py +4 -4
- package/tools/analyze_project.py +2 -2
- package/tools/api_fuzzer.py +4 -4
- package/tools/auto_heal.py +4 -2
- package/tools/browser_helpers.js +2 -2
- package/tools/bump_version.py +30 -2
- package/tools/cache_resolver.py +6 -6
- package/tools/check_env.py +82 -18
- package/tools/cli.py +265 -197
- package/tools/count_tokens.py +7 -7
- package/tools/dashboard_generator.py +14 -14
- package/tools/db_sandbox.py +5 -5
- package/tools/debt_harvester.py +236 -0
- package/tools/distill_log.py +2 -2
- package/tools/flaky_detector.py +5 -5
- package/tools/generate_tc_from_story.py +2 -2
- package/tools/generate_test_reports.py +4 -4
- package/tools/git_pre_commit_guard.py +6 -6
- package/tools/infer_linter.py +12 -7
- package/tools/lint_ai_docs.py +2 -2
- package/tools/matrix_sharder.py +4 -4
- package/tools/mcp_excel_server.py +1 -1
- package/tools/mcp_server.py +3 -3
- package/tools/micro_mutator.py +6 -6
- package/tools/omni_transpiler.py +2 -2
- package/tools/output_formatter.py +37 -2
- package/tools/pinpoint_failure.py +4 -1
- package/tools/repo_map.py +2 -2
- package/tools/safety_firewall.py +2 -2
- package/tools/senior_code_review.py +341 -0
- package/tools/setup_project.py +17 -9
- package/tools/skillspector.py +2 -2
- package/tools/sync_agent_rules.py +14 -3
- package/tools/test_impact.py +4 -4
- package/tools/tms_sync_bridge.py +2 -2
- package/tools/update_sentinel.py +24 -23
- package/tools/verify_all.py +12 -12
- package/tools/visual_som_helper.py +8 -8
- package/tools/watch_mode.py +6 -7
- package/tools/wcag_audit.py +5 -1
- package/tools/welcome_page.py +11 -11
- package/benchmarks/qa_eval/README.md +0 -71
- package/benchmarks/qa_eval/build_dataset.py +0 -677
- package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-06_api_contract_drift.json +0 -22
- package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-07_api_contract_drift.json +0 -22
- package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-08_api_contract_drift.json +0 -22
- package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-09_api_contract_drift.json +0 -22
- package/benchmarks/qa_eval/dataset/api_contract_drift/qa-challenge-10_api_contract_drift.json +0 -22
- package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-21_fake_pass_tautology.json +0 -21
- package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-22_fake_pass_tautology.json +0 -21
- package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-23_fake_pass_tautology.json +0 -21
- package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-24_fake_pass_tautology.json +0 -21
- package/benchmarks/qa_eval/dataset/fake_pass_tautology/qa-challenge-25_fake_pass_tautology.json +0 -21
- package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-01_locator_drift.json +0 -23
- package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-02_locator_drift.json +0 -23
- package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-03_locator_drift.json +0 -23
- package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-04_locator_drift.json +0 -23
- package/benchmarks/qa_eval/dataset/locator_drift/qa-challenge-05_locator_drift.json +0 -23
- package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-16_stale_and_mutation.json +0 -22
- package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-17_stale_and_mutation.json +0 -22
- package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-18_stale_and_mutation.json +0 -22
- package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-19_stale_and_mutation.json +0 -22
- package/benchmarks/qa_eval/dataset/stale_and_mutation/qa-challenge-20_stale_and_mutation.json +0 -23
- package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-11_timing_and_race.json +0 -22
- package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-12_timing_and_race.json +0 -22
- package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-13_timing_and_race.json +0 -22
- package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-14_timing_and_race.json +0 -22
- package/benchmarks/qa_eval/dataset/timing_and_race/qa-challenge-15_timing_and_race.json +0 -22
- package/benchmarks/qa_eval/eval_runner.py +0 -418
- package/benchmarks/qa_eval/reports/BENCHMARK_REPORT.md +0 -94
- package/benchmarks/qa_eval/reports/eval_results.json +0 -461
- package/examples/cypress-ecommerce-suite/README.md +0 -45
- package/examples/cypress-ecommerce-suite/cypress/e2e/checkout.cy.js +0 -17
- package/examples/cypress-ecommerce-suite/cypress/pages/BasePage.js +0 -29
- package/examples/cypress-ecommerce-suite/cypress/pages/CartPage.js +0 -51
- package/examples/cypress-ecommerce-suite/cypress.config.js +0 -13
- package/examples/cypress-ecommerce-suite/package.json +0 -13
- package/examples/katalon-suite/Keywords/pages/BasePage.groovy +0 -19
- package/examples/katalon-suite/Keywords/pages/DashboardPage.groovy +0 -29
- package/examples/katalon-suite/Keywords/pages/LoginPage.groovy +0 -45
- package/examples/katalon-suite/Profiles/default.glbl +0 -12
- package/examples/katalon-suite/README.md +0 -18
- package/examples/katalon-suite/Scripts/Auth/TC_LoginSuccess/Script1234567890.groovy +0 -12
- package/examples/katalon-suite/Scripts/Dashboard/TC_ViewSummary/Script1234567891.groovy +0 -15
- package/examples/katalon-suite/katalon_suite.prj +0 -21
- package/examples/playwright-crm-suite/README.md +0 -40
- package/examples/playwright-crm-suite/package.json +0 -14
- package/examples/playwright-crm-suite/pages/BasePage.ts +0 -37
- package/examples/playwright-crm-suite/pages/CustomerPage.ts +0 -57
- package/examples/playwright-crm-suite/pages/LoginPage.ts +0 -32
- package/examples/playwright-crm-suite/playwright.config.ts +0 -27
- package/examples/playwright-crm-suite/tests/auth.spec.ts +0 -22
- package/examples/playwright-crm-suite/tests/customers.spec.ts +0 -33
- package/examples/plugins/sample-custom-plugin/README.md +0 -14
- package/examples/plugins/sample-custom-plugin/plugin.json +0 -16
- package/examples/plugins/sample-custom-plugin/skills/custom-security-headers-audit/SKILL.md +0 -29
- package/examples/plugins/sample-custom-plugin/skills/custom-security-headers-audit/examples/audit_fixture.json +0 -8
- package/examples/plugins/sample-custom-plugin/tools/custom_security_headers.py +0 -125
- package/examples/practices/README.md +0 -22
- package/examples/practices/requirements/crm/requirements_contracts.md +0 -292
- package/examples/practices/requirements/crm/requirements_customers.md +0 -462
- package/examples/practices/requirements/crm/requirements_login.md +0 -202
- package/examples/practices/requirements/crm/requirements_projects.md +0 -396
- package/examples/practices/requirements/crm/requirements_tasks.md +0 -343
- package/examples/practices/requirements/ecommerce/requirements_category_brand.txt +0 -402
- package/examples/practices/requirements/jira/KAN-5/KAN-1/2026-04-03_04-28-27.png +0 -0
- package/examples/practices/requirements/jira/KAN-5/KAN-1/KAN-1_requirement.md +0 -52
- package/examples/practices/requirements/jira/KAN-5/KAN-4/2026-04-03_04-28-19.png +0 -0
- package/examples/practices/requirements/jira/KAN-5/KAN-4/2026-04-03_04-28-57.png +0 -0
- package/examples/practices/requirements/jira/KAN-5/KAN-4/KAN-4_requirement.md +0 -119
- package/examples/practices/requirements/jira/KAN-5/KAN-5_overview.md +0 -9
- package/examples/practices/requirements/jira/KAN-5/KAN-6/2026-04-03_05-58-08.png +0 -0
- package/examples/practices/requirements/jira/KAN-5/KAN-6/2026-04-03_05-58-23.png +0 -0
- package/examples/practices/requirements/jira/KAN-5/KAN-6/KAN-6_requirement.md +0 -32
- package/examples/practices/testcases/api/book_management_api_test_cases.md +0 -144
- package/examples/practices/testcases/api/user_management_api_test_cases.md +0 -139
- package/examples/practices/testcases/crm/test_cases_crm_login.md +0 -148
- package/examples/practices/testcases/crm/test_cases_customers.md +0 -156
- package/examples/pytest-api-suite/README.md +0 -45
- package/examples/pytest-api-suite/conftest.py +0 -31
- package/examples/pytest-api-suite/pages/user_api_client.py +0 -36
- package/examples/pytest-api-suite/requirements.txt +0 -2
- package/examples/pytest-api-suite/tests/test_user_api.py +0 -44
- package/examples/selenium-suite/README.md +0 -18
- package/examples/selenium-suite/pages/base_page.py +0 -27
- package/examples/selenium-suite/pages/login_page.py +0 -29
- package/examples/selenium-suite/pages/order_page.py +0 -25
- package/examples/selenium-suite/pytest.ini +0 -6
- package/examples/selenium-suite/requirements.txt +0 -2
- package/examples/selenium-suite/tests/test_login.py +0 -10
- package/examples/selenium-suite/tests/test_order.py +0 -10
|
@@ -1,677 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
QA Eval Benchmark Dataset Generator
|
|
4
|
-
-----------------------------------
|
|
5
|
-
Generates 25 realistic, production-grade test failure challenges across 5 domains.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import os
|
|
9
|
-
import sys
|
|
10
|
-
import json
|
|
11
|
-
|
|
12
|
-
# Enforce UTF-8 stdout encoding for Windows console compatibility
|
|
13
|
-
if hasattr(sys.stdout, 'reconfigure'):
|
|
14
|
-
try:
|
|
15
|
-
sys.stdout.reconfigure(encoding='utf-8')
|
|
16
|
-
sys.stderr.reconfigure(encoding='utf-8')
|
|
17
|
-
except Exception:
|
|
18
|
-
pass
|
|
19
|
-
|
|
20
|
-
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
21
|
-
DATASET_DIR = os.path.join(SCRIPT_DIR, "dataset")
|
|
22
|
-
|
|
23
|
-
CHALLENGES = [
|
|
24
|
-
# --- DOMAIN 1: LOCATOR DRIFT & DOM SHIFTS ---
|
|
25
|
-
{
|
|
26
|
-
"category_dir": "locator_drift",
|
|
27
|
-
"data": {
|
|
28
|
-
"id": "QA-CHALLENGE-01",
|
|
29
|
-
"name": "Dynamic CSS-in-JS Hash Locator Shift",
|
|
30
|
-
"category": "locator_drift",
|
|
31
|
-
"difficulty": "MEDIUM",
|
|
32
|
-
"description": "Button class changed from '.btn-submit' to dynamic hashed class '.btn-submit_a8f9x2'.",
|
|
33
|
-
"failure_vector": {
|
|
34
|
-
"type": "LOCATOR_DRIFT",
|
|
35
|
-
"broken_locator": "button.btn-submit",
|
|
36
|
-
"error_log": "ElementNotFoundException: Cannot locate element with selector 'button.btn-submit' within 5000ms",
|
|
37
|
-
"dom_snapshot": "<button class='btn-submit_a8f9x2' data-testid='submit-order-btn' role='button' aria-label='Submit Order'>Submit Order</button>"
|
|
38
|
-
},
|
|
39
|
-
"expected_resolution": {
|
|
40
|
-
"healed_locator": "[data-testid='submit-order-btn']",
|
|
41
|
-
"fallback_locator": "button:has-text('Submit Order')",
|
|
42
|
-
"strategy": "AOM_ROLE_OR_TESTID"
|
|
43
|
-
},
|
|
44
|
-
"benchmark_targets": {
|
|
45
|
-
"max_heal_time_sec": 2.0,
|
|
46
|
-
"max_token_cost": 350,
|
|
47
|
-
"min_confidence_score": 0.85
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
"category_dir": "locator_drift",
|
|
53
|
-
"data": {
|
|
54
|
-
"id": "QA-CHALLENGE-02",
|
|
55
|
-
"name": "Nested Shadow DOM Component Piercing",
|
|
56
|
-
"category": "locator_drift",
|
|
57
|
-
"difficulty": "HARD",
|
|
58
|
-
"description": "Input field moved inside Web Component with '#shadow-root (open)'.",
|
|
59
|
-
"failure_vector": {
|
|
60
|
-
"type": "SHADOW_DOM_ISOLATION",
|
|
61
|
-
"broken_locator": "#customer-email",
|
|
62
|
-
"error_log": "NoSuchElementException: Element '#customer-email' not found in document root",
|
|
63
|
-
"dom_snapshot": "<user-profile-card><template shadowrootmode='open'><input id='customer-email' type='email' data-testid='user-email'/></template></user-profile-card>"
|
|
64
|
-
},
|
|
65
|
-
"expected_resolution": {
|
|
66
|
-
"healed_locator": "user-profile-card >> internal:control=enter-shadow >> input#customer-email",
|
|
67
|
-
"fallback_locator": "user-profile-card >> input[type='email']",
|
|
68
|
-
"strategy": "SHADOW_DOM_PIERCING"
|
|
69
|
-
},
|
|
70
|
-
"benchmark_targets": {
|
|
71
|
-
"max_heal_time_sec": 3.0,
|
|
72
|
-
"max_token_cost": 400,
|
|
73
|
-
"min_confidence_score": 0.88
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
"category_dir": "locator_drift",
|
|
79
|
-
"data": {
|
|
80
|
-
"id": "QA-CHALLENGE-03",
|
|
81
|
-
"name": "Semantic Text Label Evolution",
|
|
82
|
-
"category": "locator_drift",
|
|
83
|
-
"difficulty": "EASY",
|
|
84
|
-
"description": "CTA button label text changed from 'Submit Order' to 'Complete Purchase'.",
|
|
85
|
-
"failure_vector": {
|
|
86
|
-
"type": "LABEL_EVOLUTION",
|
|
87
|
-
"broken_locator": "//button[text()='Submit Order']",
|
|
88
|
-
"error_log": "TimeoutException: Timed out waiting for element with XPath //button[text()='Submit Order']",
|
|
89
|
-
"dom_snapshot": "<button type='submit' class='p-button-success' id='order-cta'>Complete Purchase</button>"
|
|
90
|
-
},
|
|
91
|
-
"expected_resolution": {
|
|
92
|
-
"healed_locator": "#order-cta",
|
|
93
|
-
"fallback_locator": "button[type='submit']",
|
|
94
|
-
"strategy": "ID_AND_SEMANTIC_INTENT"
|
|
95
|
-
},
|
|
96
|
-
"benchmark_targets": {
|
|
97
|
-
"max_heal_time_sec": 1.5,
|
|
98
|
-
"max_token_cost": 300,
|
|
99
|
-
"min_confidence_score": 0.90
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
"category_dir": "locator_drift",
|
|
105
|
-
"data": {
|
|
106
|
-
"id": "QA-CHALLENGE-04",
|
|
107
|
-
"name": "Legacy ID Removed in Favor of data-testid",
|
|
108
|
-
"category": "locator_drift",
|
|
109
|
-
"difficulty": "EASY",
|
|
110
|
-
"description": "Frontend framework removed legacy 'id=customer_name' during React refactor.",
|
|
111
|
-
"failure_vector": {
|
|
112
|
-
"type": "ID_REMOVAL",
|
|
113
|
-
"broken_locator": "#customer_name",
|
|
114
|
-
"error_log": "ElementNotFoundException: Cannot locate element '#customer_name'",
|
|
115
|
-
"dom_snapshot": "<input type='text' name='customerName' data-testid='customer-name-field' class='form-control'/>"
|
|
116
|
-
},
|
|
117
|
-
"expected_resolution": {
|
|
118
|
-
"healed_locator": "[data-testid='customer-name-field']",
|
|
119
|
-
"fallback_locator": "input[name='customerName']",
|
|
120
|
-
"strategy": "DATA_TESTID_UPGRADE"
|
|
121
|
-
},
|
|
122
|
-
"benchmark_targets": {
|
|
123
|
-
"max_heal_time_sec": 1.5,
|
|
124
|
-
"max_token_cost": 250,
|
|
125
|
-
"min_confidence_score": 0.92
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
"category_dir": "locator_drift",
|
|
131
|
-
"data": {
|
|
132
|
-
"id": "QA-CHALLENGE-05",
|
|
133
|
-
"name": "HTML Tag Evolution: Anchor to ARIA Button",
|
|
134
|
-
"category": "locator_drift",
|
|
135
|
-
"difficulty": "MEDIUM",
|
|
136
|
-
"description": "Navigation link <a href='#'> converted into accessible <button role='button'>.",
|
|
137
|
-
"failure_vector": {
|
|
138
|
-
"type": "TAG_MUTATION",
|
|
139
|
-
"broken_locator": "a.nav-export",
|
|
140
|
-
"error_log": "ElementNotInteractableException: Element <a class='nav-export'> is no longer attached or interactive",
|
|
141
|
-
"dom_snapshot": "<button role='button' class='btn-export' aria-label='Export Report' data-action='export'>Export Report</button>"
|
|
142
|
-
},
|
|
143
|
-
"expected_resolution": {
|
|
144
|
-
"healed_locator": "button[aria-label='Export Report']",
|
|
145
|
-
"fallback_locator": "button:has-text('Export Report')",
|
|
146
|
-
"strategy": "AOM_ROLE_MAPPING"
|
|
147
|
-
},
|
|
148
|
-
"benchmark_targets": {
|
|
149
|
-
"max_heal_time_sec": 2.0,
|
|
150
|
-
"max_token_cost": 300,
|
|
151
|
-
"min_confidence_score": 0.88
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
},
|
|
155
|
-
|
|
156
|
-
# --- DOMAIN 2: API CONTRACT & BREAKING CHANGES ---
|
|
157
|
-
{
|
|
158
|
-
"category_dir": "api_contract_drift",
|
|
159
|
-
"data": {
|
|
160
|
-
"id": "QA-CHALLENGE-06",
|
|
161
|
-
"name": "Numeric ID Serialized as String (Type Mutation)",
|
|
162
|
-
"category": "api_contract_drift",
|
|
163
|
-
"difficulty": "MEDIUM",
|
|
164
|
-
"description": "Backend response changed 'invoice_id: 10423' (int) to 'invoice_id: \"10423\"' (string).",
|
|
165
|
-
"failure_vector": {
|
|
166
|
-
"type": "TYPE_MUTATION",
|
|
167
|
-
"broken_assertion": "assert response.data.invoice_id == 10423",
|
|
168
|
-
"error_log": "AssertionError: Expected integer 10423 but received string '10423'",
|
|
169
|
-
"api_payload": "{\"status\": \"SUCCESS\", \"invoice_id\": \"10423\", \"amount\": 250.0}"
|
|
170
|
-
},
|
|
171
|
-
"expected_resolution": {
|
|
172
|
-
"healed_assertion": "assert str(response.data.invoice_id) == '10423'",
|
|
173
|
-
"strategy": "TYPE_COERCION_ASSERTION"
|
|
174
|
-
},
|
|
175
|
-
"benchmark_targets": {
|
|
176
|
-
"max_heal_time_sec": 2.0,
|
|
177
|
-
"max_token_cost": 280,
|
|
178
|
-
"min_confidence_score": 0.90
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
"category_dir": "api_contract_drift",
|
|
184
|
-
"data": {
|
|
185
|
-
"id": "QA-CHALLENGE-07",
|
|
186
|
-
"name": "Payload Response Field Rename",
|
|
187
|
-
"category": "api_contract_drift",
|
|
188
|
-
"difficulty": "EASY",
|
|
189
|
-
"description": "User profile endpoint renamed 'user_email' to 'email_address'.",
|
|
190
|
-
"failure_vector": {
|
|
191
|
-
"type": "FIELD_RENAME",
|
|
192
|
-
"broken_assertion": "assert response.json()['user_email'] == 'qa@example.com'",
|
|
193
|
-
"error_log": "KeyError: 'user_email' not found in response dictionary",
|
|
194
|
-
"api_payload": "{\"id\": 42, \"email_address\": \"qa@example.com\", \"role\": \"QA\"}"
|
|
195
|
-
},
|
|
196
|
-
"expected_resolution": {
|
|
197
|
-
"healed_assertion": "assert (response.json().get('email_address') or response.json().get('user_email')) == 'qa@example.com'",
|
|
198
|
-
"strategy": "RESILIENT_FIELD_LOOKUP"
|
|
199
|
-
},
|
|
200
|
-
"benchmark_targets": {
|
|
201
|
-
"max_heal_time_sec": 1.5,
|
|
202
|
-
"max_token_cost": 260,
|
|
203
|
-
"min_confidence_score": 0.95
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
"category_dir": "api_contract_drift",
|
|
209
|
-
"data": {
|
|
210
|
-
"id": "QA-CHALLENGE-08",
|
|
211
|
-
"name": "Nested Response Object Flattened",
|
|
212
|
-
"category": "api_contract_drift",
|
|
213
|
-
"difficulty": "MEDIUM",
|
|
214
|
-
"description": "Backend flattened nested profile: 'data.profile.tier' changed to 'data.tier'.",
|
|
215
|
-
"failure_vector": {
|
|
216
|
-
"type": "STRUCTURE_FLATTEN",
|
|
217
|
-
"broken_assertion": "assert response.json()['profile']['tier'] == 'GOLD'",
|
|
218
|
-
"error_log": "TypeError: 'NoneType' or KeyError: 'profile'",
|
|
219
|
-
"api_payload": "{\"tier\": \"GOLD\", \"points\": 1200}"
|
|
220
|
-
},
|
|
221
|
-
"expected_resolution": {
|
|
222
|
-
"healed_assertion": "tier = response.json().get('tier') or response.json().get('profile', {}).get('tier'); assert tier == 'GOLD'",
|
|
223
|
-
"strategy": "SCHEMA_PATH_FALLBACK"
|
|
224
|
-
},
|
|
225
|
-
"benchmark_targets": {
|
|
226
|
-
"max_heal_time_sec": 2.0,
|
|
227
|
-
"max_token_cost": 320,
|
|
228
|
-
"min_confidence_score": 0.90
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
"category_dir": "api_contract_drift",
|
|
234
|
-
"data": {
|
|
235
|
-
"id": "QA-CHALLENGE-09",
|
|
236
|
-
"name": "HTTP Creation Status Code Shift (200 OK -> 201 Created)",
|
|
237
|
-
"category": "api_contract_drift",
|
|
238
|
-
"difficulty": "EASY",
|
|
239
|
-
"description": "POST endpoint updated to RFC-compliant 201 Created instead of legacy 200 OK.",
|
|
240
|
-
"failure_vector": {
|
|
241
|
-
"type": "STATUS_CODE_SHIFT",
|
|
242
|
-
"broken_assertion": "assert response.status_code == 200",
|
|
243
|
-
"error_log": "AssertionError: Expected status code 200 but received 201",
|
|
244
|
-
"api_payload": "{\"status\": 201, \"created\": true}"
|
|
245
|
-
},
|
|
246
|
-
"expected_resolution": {
|
|
247
|
-
"healed_assertion": "assert response.status_code in (200, 201)",
|
|
248
|
-
"strategy": "SUCCESS_STATUS_RANGE"
|
|
249
|
-
},
|
|
250
|
-
"benchmark_targets": {
|
|
251
|
-
"max_heal_time_sec": 1.0,
|
|
252
|
-
"max_token_cost": 220,
|
|
253
|
-
"min_confidence_score": 0.98
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
"category_dir": "api_contract_drift",
|
|
259
|
-
"data": {
|
|
260
|
-
"id": "QA-CHALLENGE-10",
|
|
261
|
-
"name": "Authentication Header Prefix Upgrade",
|
|
262
|
-
"category": "api_contract_drift",
|
|
263
|
-
"difficulty": "EASY",
|
|
264
|
-
"description": "API gateway changed auth format from 'Authorization: Token <token>' to 'Bearer <token>'.",
|
|
265
|
-
"failure_vector": {
|
|
266
|
-
"type": "AUTH_HEADER_DRIFT",
|
|
267
|
-
"broken_code": "headers = {'Authorization': f'Token {auth_token}'}",
|
|
268
|
-
"error_log": "HTTP 401 Unauthorized: Invalid authorization scheme. Expected 'Bearer'.",
|
|
269
|
-
"api_payload": "{\"error\": \"Unauthorized\", \"code\": 401}"
|
|
270
|
-
},
|
|
271
|
-
"expected_resolution": {
|
|
272
|
-
"healed_code": "headers = {'Authorization': f'Bearer {auth_token}'}",
|
|
273
|
-
"strategy": "STANDARD_BEARER_TOKEN"
|
|
274
|
-
},
|
|
275
|
-
"benchmark_targets": {
|
|
276
|
-
"max_heal_time_sec": 1.5,
|
|
277
|
-
"max_token_cost": 250,
|
|
278
|
-
"min_confidence_score": 0.95
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
},
|
|
282
|
-
|
|
283
|
-
# --- DOMAIN 3: TIMING, ASYNCHRONY & RACE CONDITIONS ---
|
|
284
|
-
{
|
|
285
|
-
"category_dir": "timing_and_race",
|
|
286
|
-
"data": {
|
|
287
|
-
"id": "QA-CHALLENGE-11",
|
|
288
|
-
"name": "Network Latency Spike (3,500ms Throttle) Breaking Static Sleep",
|
|
289
|
-
"category": "timing_and_race",
|
|
290
|
-
"difficulty": "MEDIUM",
|
|
291
|
-
"description": "Microservice latency under load takes 3.5s; test had Thread.sleep(2000).",
|
|
292
|
-
"failure_vector": {
|
|
293
|
-
"type": "STATIC_SLEEP_TIMEOUT",
|
|
294
|
-
"broken_code": "Thread.sleep(2000); assert WebUI.verifyElementPresent('#result')",
|
|
295
|
-
"error_log": "ElementNotFoundException: Element '#result' not present after 2000ms delay",
|
|
296
|
-
"environment_condition": "CDP Network Throttling 3500ms delay"
|
|
297
|
-
},
|
|
298
|
-
"expected_resolution": {
|
|
299
|
-
"healed_code": "page.waitForSelector('#result', timeout: 10000); page.waitForLoadState('networkidle')",
|
|
300
|
-
"strategy": "DYNAMIC_SMART_WAIT"
|
|
301
|
-
},
|
|
302
|
-
"benchmark_targets": {
|
|
303
|
-
"max_heal_time_sec": 2.5,
|
|
304
|
-
"max_token_cost": 320,
|
|
305
|
-
"min_confidence_score": 0.92
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
"category_dir": "timing_and_race",
|
|
311
|
-
"data": {
|
|
312
|
-
"id": "QA-CHALLENGE-12",
|
|
313
|
-
"name": "PrimeNG Modal Backdrop Fading Intercept",
|
|
314
|
-
"category": "timing_and_race",
|
|
315
|
-
"difficulty": "HARD",
|
|
316
|
-
"description": "Modal backdrop takes 450ms CSS transition to fade out; click immediately triggers intercept.",
|
|
317
|
-
"failure_vector": {
|
|
318
|
-
"type": "CLICK_INTERCEPTED",
|
|
319
|
-
"broken_code": "page.click('#confirm-btn')",
|
|
320
|
-
"error_log": "ElementClickInterceptedException: <div class='p-component-overlay p-component-overlay-enter'> intercepts pointer-events",
|
|
321
|
-
"environment_condition": "PrimeNG Modal Fade Transition"
|
|
322
|
-
},
|
|
323
|
-
"expected_resolution": {
|
|
324
|
-
"healed_code": "page.waitForSelector('.p-component-overlay', state: 'detached'); BasePage.clickJS('#confirm-btn')",
|
|
325
|
-
"strategy": "OVERLAY_SAFE_DISPATCH"
|
|
326
|
-
},
|
|
327
|
-
"benchmark_targets": {
|
|
328
|
-
"max_heal_time_sec": 3.0,
|
|
329
|
-
"max_token_cost": 380,
|
|
330
|
-
"min_confidence_score": 0.90
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
},
|
|
334
|
-
{
|
|
335
|
-
"category_dir": "timing_and_race",
|
|
336
|
-
"data": {
|
|
337
|
-
"id": "QA-CHALLENGE-13",
|
|
338
|
-
"name": "Debounced Search Input Autocomplete Race",
|
|
339
|
-
"category": "timing_and_race",
|
|
340
|
-
"difficulty": "MEDIUM",
|
|
341
|
-
"description": "Search input debounces 400ms before sending query; test clicked dropdown item before query fired.",
|
|
342
|
-
"failure_vector": {
|
|
343
|
-
"type": "DEBOUNCE_RACE",
|
|
344
|
-
"broken_code": "page.fill('#search-input', 'Invoice'); page.click('.dropdown-item:first-child')",
|
|
345
|
-
"error_log": "TimeoutException: Timed out waiting for '.dropdown-item' to appear in DOM",
|
|
346
|
-
"environment_condition": "Debounce Timer 400ms"
|
|
347
|
-
},
|
|
348
|
-
"expected_resolution": {
|
|
349
|
-
"healed_code": "page.fill('#search-input', 'Invoice'); page.waitForResponse(r => r.url().includes('/search') && r.status() == 200); page.click('.dropdown-item:first-child')",
|
|
350
|
-
"strategy": "CDP_RESPONSE_BARRIER"
|
|
351
|
-
},
|
|
352
|
-
"benchmark_targets": {
|
|
353
|
-
"max_heal_time_sec": 2.5,
|
|
354
|
-
"max_token_cost": 350,
|
|
355
|
-
"min_confidence_score": 0.88
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
"category_dir": "timing_and_race",
|
|
361
|
-
"data": {
|
|
362
|
-
"id": "QA-CHALLENGE-14",
|
|
363
|
-
"name": "Async Chart SVG Animation Race Condition",
|
|
364
|
-
"category": "timing_and_race",
|
|
365
|
-
"difficulty": "MEDIUM",
|
|
366
|
-
"description": "Financial chart takes 1200ms to calculate series and render SVG paths.",
|
|
367
|
-
"failure_vector": {
|
|
368
|
-
"type": "ASYNC_RENDER_RACE",
|
|
369
|
-
"broken_code": "page.click('.chart-bar:last-child')",
|
|
370
|
-
"error_log": "ElementNotFoundException: Selector '.chart-bar:last-child' not found",
|
|
371
|
-
"environment_condition": "Highcharts Rendering Animation"
|
|
372
|
-
},
|
|
373
|
-
"expected_resolution": {
|
|
374
|
-
"healed_code": "page.waitForSelector('.highcharts-series path', state: 'visible'); page.click('.chart-bar:last-child')",
|
|
375
|
-
"strategy": "SVG_VISIBILITY_SMART_WAIT"
|
|
376
|
-
},
|
|
377
|
-
"benchmark_targets": {
|
|
378
|
-
"max_heal_time_sec": 2.0,
|
|
379
|
-
"max_token_cost": 310,
|
|
380
|
-
"min_confidence_score": 0.90
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
},
|
|
384
|
-
{
|
|
385
|
-
"category_dir": "timing_and_race",
|
|
386
|
-
"data": {
|
|
387
|
-
"id": "QA-CHALLENGE-15",
|
|
388
|
-
"name": "Infinite Scroll Lazy Loaded Chunk Detach",
|
|
389
|
-
"category": "timing_and_race",
|
|
390
|
-
"difficulty": "MEDIUM",
|
|
391
|
-
"description": "Table rows 50-100 require viewport scroll to trigger network chunk download.",
|
|
392
|
-
"failure_vector": {
|
|
393
|
-
"type": "LAZY_LOAD_RACE",
|
|
394
|
-
"broken_code": "page.locator('tr[data-id=\"75\"]').click()",
|
|
395
|
-
"error_log": "TimeoutException: Timed out waiting for 'tr[data-id=\"75\"]' to be visible",
|
|
396
|
-
"environment_condition": "Virtual Scrolling Table"
|
|
397
|
-
},
|
|
398
|
-
"expected_resolution": {
|
|
399
|
-
"healed_code": "page.locator('tr[data-id=\"75\"]').scrollIntoViewIfNeeded(); page.locator('tr[data-id=\"75\"]').click()",
|
|
400
|
-
"strategy": "VIRTUAL_SCROLL_INTO_VIEW"
|
|
401
|
-
},
|
|
402
|
-
"benchmark_targets": {
|
|
403
|
-
"max_heal_time_sec": 2.0,
|
|
404
|
-
"max_token_cost": 300,
|
|
405
|
-
"min_confidence_score": 0.92
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
},
|
|
409
|
-
|
|
410
|
-
# --- DOMAIN 4: STALE REFERENCES & DOM RE-RENDERS ---
|
|
411
|
-
{
|
|
412
|
-
"category_dir": "stale_and_mutation",
|
|
413
|
-
"data": {
|
|
414
|
-
"id": "QA-CHALLENGE-16",
|
|
415
|
-
"name": "WebSocket Table Auto-Refresh Stale Reference",
|
|
416
|
-
"category": "stale_and_mutation",
|
|
417
|
-
"difficulty": "HARD",
|
|
418
|
-
"description": "WebSocket pushes live quotes every 1.5s, wiping and recreating <tr> elements.",
|
|
419
|
-
"failure_vector": {
|
|
420
|
-
"type": "STALE_ELEMENT",
|
|
421
|
-
"broken_code": "def row = page.locator('#stocks tr').first(); page.waitForTimeout(1600); row.click();",
|
|
422
|
-
"error_log": "StaleElementReferenceException: Element is no longer attached to DOM",
|
|
423
|
-
"environment_condition": "WebSocket DOM Mutation"
|
|
424
|
-
},
|
|
425
|
-
"expected_resolution": {
|
|
426
|
-
"healed_code": "page.locator('#stocks tr').first().click(); // Re-queries locator at moment of dispatch",
|
|
427
|
-
"strategy": "DYNAMIC_LOCATOR_REQUERY"
|
|
428
|
-
},
|
|
429
|
-
"benchmark_targets": {
|
|
430
|
-
"max_heal_time_sec": 2.5,
|
|
431
|
-
"max_token_cost": 340,
|
|
432
|
-
"min_confidence_score": 0.90
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
},
|
|
436
|
-
{
|
|
437
|
-
"category_dir": "stale_and_mutation",
|
|
438
|
-
"data": {
|
|
439
|
-
"id": "QA-CHALLENGE-17",
|
|
440
|
-
"name": "Tab Switch Component Unmount Detach",
|
|
441
|
-
"category": "stale_and_mutation",
|
|
442
|
-
"difficulty": "MEDIUM",
|
|
443
|
-
"description": "Switching active tabs unmounts previous panel component entirely from virtual DOM.",
|
|
444
|
-
"failure_vector": {
|
|
445
|
-
"type": "COMPONENT_UNMOUNT",
|
|
446
|
-
"broken_code": "page.click('#tab-billing'); page.fill('#billing-tax-id', 'TAX-999');",
|
|
447
|
-
"error_log": "ElementNotInteractableException: Target element '#billing-tax-id' is hidden or unmounted",
|
|
448
|
-
"environment_condition": "Tab Component View Switching"
|
|
449
|
-
},
|
|
450
|
-
"expected_resolution": {
|
|
451
|
-
"healed_code": "page.click('#tab-billing'); page.waitForSelector('#billing-tab-content[aria-hidden=\"false\"]'); page.fill('#billing-tax-id', 'TAX-999');",
|
|
452
|
-
"strategy": "TAB_MOUNT_SYNCHRONIZATION"
|
|
453
|
-
},
|
|
454
|
-
"benchmark_targets": {
|
|
455
|
-
"max_heal_time_sec": 2.0,
|
|
456
|
-
"max_token_cost": 300,
|
|
457
|
-
"min_confidence_score": 0.91
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
},
|
|
461
|
-
{
|
|
462
|
-
"category_dir": "stale_and_mutation",
|
|
463
|
-
"data": {
|
|
464
|
-
"id": "QA-CHALLENGE-18",
|
|
465
|
-
"name": "Pagination Replaces tbody (Stale Row Index)",
|
|
466
|
-
"category": "stale_and_mutation",
|
|
467
|
-
"difficulty": "MEDIUM",
|
|
468
|
-
"description": "Navigating to page 2 updates table rows; old row references become detached.",
|
|
469
|
-
"failure_vector": {
|
|
470
|
-
"type": "PAGINATION_DETACH",
|
|
471
|
-
"broken_code": "page.click('.p-paginator-next'); page.locator('tbody tr').nth(0).click();",
|
|
472
|
-
"error_log": "StaleElementReferenceException: Stale element handle during click dispatch",
|
|
473
|
-
"environment_condition": "Data Table Pagination"
|
|
474
|
-
},
|
|
475
|
-
"expected_resolution": {
|
|
476
|
-
"healed_code": "page.click('.p-paginator-next'); page.waitForResponse(r => r.url().includes('page=2')); page.locator('tbody tr').first().click();",
|
|
477
|
-
"strategy": "PAGINATION_NETWORK_SYNC"
|
|
478
|
-
},
|
|
479
|
-
"benchmark_targets": {
|
|
480
|
-
"max_heal_time_sec": 2.0,
|
|
481
|
-
"max_token_cost": 310,
|
|
482
|
-
"min_confidence_score": 0.92
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
},
|
|
486
|
-
{
|
|
487
|
-
"category_dir": "stale_and_mutation",
|
|
488
|
-
"data": {
|
|
489
|
-
"id": "QA-CHALLENGE-19",
|
|
490
|
-
"name": "Reopened Modal Generates Fresh DOM Node",
|
|
491
|
-
"category": "stale_and_mutation",
|
|
492
|
-
"difficulty": "MEDIUM",
|
|
493
|
-
"description": "Closing and reopening dialog instantiates new DOM element with same CSS selector.",
|
|
494
|
-
"failure_vector": {
|
|
495
|
-
"type": "FRESH_INSTANCE_STALE",
|
|
496
|
-
"broken_code": "def modal = page.locator('#edit-dialog'); page.click('#close-btn'); page.click('#open-btn'); modal.fill('input', 'new');",
|
|
497
|
-
"error_log": "ElementNotVisibleException: Cached element reference points to detached/hidden dialog instance",
|
|
498
|
-
"environment_condition": "Modal Lifecycle Instantiation"
|
|
499
|
-
},
|
|
500
|
-
"expected_resolution": {
|
|
501
|
-
"healed_code": "page.click('#close-btn'); page.click('#open-btn'); page.locator('#edit-dialog:visible input').fill('new');",
|
|
502
|
-
"strategy": "VISIBLE_SELECTOR_REBIND"
|
|
503
|
-
},
|
|
504
|
-
"benchmark_targets": {
|
|
505
|
-
"max_heal_time_sec": 2.0,
|
|
506
|
-
"max_token_cost": 290,
|
|
507
|
-
"min_confidence_score": 0.94
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
},
|
|
511
|
-
{
|
|
512
|
-
"category_dir": "stale_and_mutation",
|
|
513
|
-
"data": {
|
|
514
|
-
"id": "QA-CHALLENGE-20",
|
|
515
|
-
"name": "Locale Swap Invalidates Hardcoded Text Selectors",
|
|
516
|
-
"category": "stale_and_mutation",
|
|
517
|
-
"difficulty": "EASY",
|
|
518
|
-
"description": "Application language changed to French ('Enregistrer'); text selector 'Save' fails.",
|
|
519
|
-
"failure_vector": {
|
|
520
|
-
"type": "I18N_TEXT_MUTATION",
|
|
521
|
-
"broken_locator": "button:has-text('Save')",
|
|
522
|
-
"error_log": "TimeoutException: No element found matching text 'Save'",
|
|
523
|
-
"dom_snapshot": "<button type='submit' data-action='save' class='btn-primary' aria-label='save-record'>Enregistrer</button>"
|
|
524
|
-
},
|
|
525
|
-
"expected_resolution": {
|
|
526
|
-
"healed_locator": "button[data-action='save']",
|
|
527
|
-
"fallback_locator": "button[aria-label='save-record']",
|
|
528
|
-
"strategy": "LOCALE_AGNOSTIC_DATA_ATTRIBUTES"
|
|
529
|
-
},
|
|
530
|
-
"benchmark_targets": {
|
|
531
|
-
"max_heal_time_sec": 1.5,
|
|
532
|
-
"max_token_cost": 270,
|
|
533
|
-
"min_confidence_score": 0.95
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
},
|
|
537
|
-
|
|
538
|
-
# --- DOMAIN 5: FAKE-PASS, MUTATION TRAPS & TAUTOLOGIES ---
|
|
539
|
-
{
|
|
540
|
-
"category_dir": "fake_pass_tautology",
|
|
541
|
-
"data": {
|
|
542
|
-
"id": "QA-CHALLENGE-21",
|
|
543
|
-
"name": "Swallowed HTTP 500 Error in Empty Catch Block",
|
|
544
|
-
"category": "fake_pass_tautology",
|
|
545
|
-
"difficulty": "EASY",
|
|
546
|
-
"description": "Test silently catches runtime exceptions in an empty catch, masking severe backend 500 crash.",
|
|
547
|
-
"failure_vector": {
|
|
548
|
-
"type": "SWALLOWED_EXCEPTION",
|
|
549
|
-
"code_snippet": "try { page.click('#submit-payment') } catch (Exception e) {} // Test passes even on 500",
|
|
550
|
-
"detection_rule": "EMPTY_CATCH_PATTERN"
|
|
551
|
-
},
|
|
552
|
-
"expected_resolution": {
|
|
553
|
-
"healed_code": "page.click('#submit-payment'); assert page.locator('.success-toast').isVisible();",
|
|
554
|
-
"strategy": "REMOVE_SWALLOWED_CATCH_AND_ASSERT"
|
|
555
|
-
},
|
|
556
|
-
"benchmark_targets": {
|
|
557
|
-
"max_heal_time_sec": 1.0,
|
|
558
|
-
"max_token_cost": 200,
|
|
559
|
-
"min_confidence_score": 0.99
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
},
|
|
563
|
-
{
|
|
564
|
-
"category_dir": "fake_pass_tautology",
|
|
565
|
-
"data": {
|
|
566
|
-
"id": "QA-CHALLENGE-22",
|
|
567
|
-
"name": "Zero-Assertion Smoke Test (Tautological Pass)",
|
|
568
|
-
"category": "fake_pass_tautology",
|
|
569
|
-
"difficulty": "EASY",
|
|
570
|
-
"description": "Test executes form inputs and clicks submit but contains exactly 0 assertion statements.",
|
|
571
|
-
"failure_vector": {
|
|
572
|
-
"type": "ZERO_ASSERTION_PASS",
|
|
573
|
-
"code_snippet": "page.fill('#username', 'admin'); page.fill('#password', 'secret'); page.click('#login-btn');",
|
|
574
|
-
"detection_rule": "FAKE_PASS_NO_ASSERTION"
|
|
575
|
-
},
|
|
576
|
-
"expected_resolution": {
|
|
577
|
-
"healed_code": "page.fill('#username', 'admin'); page.fill('#password', 'secret'); page.click('#login-btn'); expect(page.locator('#dashboard-header')).toBeVisible();",
|
|
578
|
-
"strategy": "INJECT_POST_CONDITION_ASSERTION"
|
|
579
|
-
},
|
|
580
|
-
"benchmark_targets": {
|
|
581
|
-
"max_heal_time_sec": 1.5,
|
|
582
|
-
"max_token_cost": 240,
|
|
583
|
-
"min_confidence_score": 0.97
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
},
|
|
587
|
-
{
|
|
588
|
-
"category_dir": "fake_pass_tautology",
|
|
589
|
-
"data": {
|
|
590
|
-
"id": "QA-CHALLENGE-23",
|
|
591
|
-
"name": "Tautological assert true == true",
|
|
592
|
-
"category": "fake_pass_tautology",
|
|
593
|
-
"difficulty": "EASY",
|
|
594
|
-
"description": "Test asserts trivial identity 'assert true == true' instead of verifying business state.",
|
|
595
|
-
"failure_vector": {
|
|
596
|
-
"type": "TAUTOLOGY_ASSERTION",
|
|
597
|
-
"code_snippet": "def response = api.createInvoice(); assert true == true;",
|
|
598
|
-
"detection_rule": "TAUTOLOGY_PATTERN"
|
|
599
|
-
},
|
|
600
|
-
"expected_resolution": {
|
|
601
|
-
"healed_code": "def response = api.createInvoice(); assert response.status == 201 && response.id != null;",
|
|
602
|
-
"strategy": "MUTATION_TESTING_KILLS_TAUTOLOGY"
|
|
603
|
-
},
|
|
604
|
-
"benchmark_targets": {
|
|
605
|
-
"max_heal_time_sec": 1.0,
|
|
606
|
-
"max_token_cost": 220,
|
|
607
|
-
"min_confidence_score": 0.98
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
},
|
|
611
|
-
{
|
|
612
|
-
"category_dir": "fake_pass_tautology",
|
|
613
|
-
"data": {
|
|
614
|
-
"id": "QA-CHALLENGE-24",
|
|
615
|
-
"name": "Unawaited Async Assertion (Silent Green Trap)",
|
|
616
|
-
"category": "fake_pass_tautology",
|
|
617
|
-
"difficulty": "MEDIUM",
|
|
618
|
-
"description": "Missing 'await' on expect(locator).toBeVisible(); Promise resolves ignored after test exit.",
|
|
619
|
-
"failure_vector": {
|
|
620
|
-
"type": "UNAWAITED_ASYNC_ASSERTION",
|
|
621
|
-
"code_snippet": "page.click('#save'); expect(page.locator('.alert')).toBeVisible(); // Missing await!",
|
|
622
|
-
"detection_rule": "UNAWAITED_ASYNC_EXPECT"
|
|
623
|
-
},
|
|
624
|
-
"expected_resolution": {
|
|
625
|
-
"healed_code": "page.click('#save'); await expect(page.locator('.alert')).toBeVisible();",
|
|
626
|
-
"strategy": "AST_ASYNC_AWAIT_ENFORCEMENT"
|
|
627
|
-
},
|
|
628
|
-
"benchmark_targets": {
|
|
629
|
-
"max_heal_time_sec": 1.5,
|
|
630
|
-
"max_token_cost": 250,
|
|
631
|
-
"min_confidence_score": 0.96
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
},
|
|
635
|
-
{
|
|
636
|
-
"category_dir": "fake_pass_tautology",
|
|
637
|
-
"data": {
|
|
638
|
-
"id": "QA-CHALLENGE-25",
|
|
639
|
-
"name": "Unbounded Relational Assertion (status >= 200)",
|
|
640
|
-
"category": "fake_pass_tautology",
|
|
641
|
-
"difficulty": "EASY",
|
|
642
|
-
"description": "Assertion checks 'status >= 200' without ceiling, so HTTP 500 error causes false pass.",
|
|
643
|
-
"failure_vector": {
|
|
644
|
-
"type": "UNBOUNDED_STATUS_ASSERTION",
|
|
645
|
-
"code_snippet": "def resp = client.send(); assert resp.statusCode >= 200; // Passes on 500!",
|
|
646
|
-
"detection_rule": "MUTATION_BOUNDARY_SHIFT"
|
|
647
|
-
},
|
|
648
|
-
"expected_resolution": {
|
|
649
|
-
"healed_code": "def resp = client.send(); assert resp.statusCode >= 200 && resp.statusCode < 300;",
|
|
650
|
-
"strategy": "BOUNDED_INTERVAL_ASSERTION"
|
|
651
|
-
},
|
|
652
|
-
"benchmark_targets": {
|
|
653
|
-
"max_heal_time_sec": 1.2,
|
|
654
|
-
"max_token_cost": 230,
|
|
655
|
-
"min_confidence_score": 0.98
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
]
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
def build():
|
|
663
|
-
total_written = 0
|
|
664
|
-
for item in CHALLENGES:
|
|
665
|
-
folder = os.path.join(DATASET_DIR, item["category_dir"])
|
|
666
|
-
os.makedirs(folder, exist_ok=True)
|
|
667
|
-
filename = f"{item['data']['id'].lower()}_{item['data']['category']}.json"
|
|
668
|
-
filepath = os.path.join(folder, filename)
|
|
669
|
-
with open(filepath, "w", encoding="utf-8") as f:
|
|
670
|
-
json.dump(item["data"], f, indent=2)
|
|
671
|
-
total_written += 1
|
|
672
|
-
|
|
673
|
-
print(f"✅ Generated {total_written} QA Benchmark Challenges in {DATASET_DIR}")
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
if __name__ == "__main__":
|
|
677
|
-
build()
|