testql 1.2.64__tar.gz → 1.2.65__tar.gz

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 (357) hide show
  1. {testql-1.2.64/testql.egg-info → testql-1.2.65}/PKG-INFO +1 -1
  2. {testql-1.2.64 → testql-1.2.65}/pyproject.toml +1 -1
  3. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_api_runner.py +2 -2
  4. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_testtoon_parser.py +59 -5
  5. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/engine.py +8 -1
  6. {testql-1.2.64 → testql-1.2.65/testql.egg-info}/PKG-INFO +1 -1
  7. {testql-1.2.64 → testql-1.2.65}/tests/test_interpreter.py +44 -0
  8. {testql-1.2.64 → testql-1.2.65}/tests/test_ir_runner_captures.py +20 -0
  9. {testql-1.2.64 → testql-1.2.65}/LICENSE +0 -0
  10. {testql-1.2.64 → testql-1.2.65}/README.md +0 -0
  11. {testql-1.2.64 → testql-1.2.65}/setup.cfg +0 -0
  12. {testql-1.2.64 → testql-1.2.65}/testql/__init__.py +0 -0
  13. {testql-1.2.64 → testql-1.2.65}/testql/__main__.py +0 -0
  14. {testql-1.2.64 → testql-1.2.65}/testql/_base_fallback.py +0 -0
  15. {testql-1.2.64 → testql-1.2.65}/testql/adapters/__init__.py +0 -0
  16. {testql-1.2.64 → testql-1.2.65}/testql/adapters/base.py +0 -0
  17. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nl/__init__.py +0 -0
  18. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nl/entity_extractor.py +0 -0
  19. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nl/grammar.py +0 -0
  20. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nl/intent_recognizer.py +0 -0
  21. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nl/lexicon/__init__.py +0 -0
  22. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nl/llm_fallback.py +0 -0
  23. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nl/nl_adapter.py +0 -0
  24. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nlp2dsl/__init__.py +0 -0
  25. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nlp2dsl/client.py +0 -0
  26. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nlp2dsl/live_llm.py +0 -0
  27. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nlp2dsl/llm_provider.py +0 -0
  28. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nlp2dsl/mock_llm.py +0 -0
  29. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nlp2dsl/nlp2dsl_adapter.py +0 -0
  30. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nlp2env/__init__.py +0 -0
  31. {testql-1.2.64 → testql-1.2.65}/testql/adapters/nlp2env/nlp2env_adapter.py +0 -0
  32. {testql-1.2.64 → testql-1.2.65}/testql/adapters/registry.py +0 -0
  33. {testql-1.2.64 → testql-1.2.65}/testql/adapters/scenario_yaml.py +0 -0
  34. {testql-1.2.64 → testql-1.2.65}/testql/adapters/testtoon_adapter.py +0 -0
  35. {testql-1.2.64 → testql-1.2.65}/testql/artifacts/__init__.py +0 -0
  36. {testql-1.2.64 → testql-1.2.65}/testql/artifacts/base.py +0 -0
  37. {testql-1.2.64 → testql-1.2.65}/testql/artifacts/email_checker.py +0 -0
  38. {testql-1.2.64 → testql-1.2.65}/testql/artifacts/file_checker.py +0 -0
  39. {testql-1.2.64 → testql-1.2.65}/testql/artifacts/registry.py +0 -0
  40. {testql-1.2.64 → testql-1.2.65}/testql/assertion_suite.py +0 -0
  41. {testql-1.2.64 → testql-1.2.65}/testql/autoloop_runner.py +0 -0
  42. {testql-1.2.64 → testql-1.2.65}/testql/base.py +0 -0
  43. {testql-1.2.64 → testql-1.2.65}/testql/cli.py +0 -0
  44. {testql-1.2.64 → testql-1.2.65}/testql/commands/__init__.py +0 -0
  45. {testql-1.2.64 → testql-1.2.65}/testql/commands/auto_cmd.py +0 -0
  46. {testql-1.2.64 → testql-1.2.65}/testql/commands/conversation_cmd.py +0 -0
  47. {testql-1.2.64 → testql-1.2.65}/testql/commands/discover_cmd.py +0 -0
  48. {testql-1.2.64 → testql-1.2.65}/testql/commands/echo/__init__.py +0 -0
  49. {testql-1.2.64 → testql-1.2.65}/testql/commands/echo/cli.py +0 -0
  50. {testql-1.2.64 → testql-1.2.65}/testql/commands/echo/context.py +0 -0
  51. {testql-1.2.64 → testql-1.2.65}/testql/commands/echo/formatters/__init__.py +0 -0
  52. {testql-1.2.64 → testql-1.2.65}/testql/commands/echo/formatters/text.py +0 -0
  53. {testql-1.2.64 → testql-1.2.65}/testql/commands/echo/parsers/__init__.py +0 -0
  54. {testql-1.2.64 → testql-1.2.65}/testql/commands/echo/parsers/doql.py +0 -0
  55. {testql-1.2.64 → testql-1.2.65}/testql/commands/echo/parsers/toon.py +0 -0
  56. {testql-1.2.64 → testql-1.2.65}/testql/commands/echo.py +0 -0
  57. {testql-1.2.64 → testql-1.2.65}/testql/commands/echo_helpers.py +0 -0
  58. {testql-1.2.64 → testql-1.2.65}/testql/commands/encoder_routes.py +0 -0
  59. {testql-1.2.64 → testql-1.2.65}/testql/commands/endpoints_cmd.py +0 -0
  60. {testql-1.2.64 → testql-1.2.65}/testql/commands/generate_cmd.py +0 -0
  61. {testql-1.2.64 → testql-1.2.65}/testql/commands/generate_from_page_cmd.py +0 -0
  62. {testql-1.2.64 → testql-1.2.65}/testql/commands/generate_ir_cmd.py +0 -0
  63. {testql-1.2.64 → testql-1.2.65}/testql/commands/generate_topology_cmd.py +0 -0
  64. {testql-1.2.64 → testql-1.2.65}/testql/commands/heal_scenario_cmd.py +0 -0
  65. {testql-1.2.64 → testql-1.2.65}/testql/commands/inspect_cmd.py +0 -0
  66. {testql-1.2.64 → testql-1.2.65}/testql/commands/misc_cmds.py +0 -0
  67. {testql-1.2.64 → testql-1.2.65}/testql/commands/nlp2env_cmd.py +0 -0
  68. {testql-1.2.64 → testql-1.2.65}/testql/commands/run_cmd.py +0 -0
  69. {testql-1.2.64 → testql-1.2.65}/testql/commands/run_ir_cmd.py +0 -0
  70. {testql-1.2.64 → testql-1.2.65}/testql/commands/self_test_cmd.py +0 -0
  71. {testql-1.2.64 → testql-1.2.65}/testql/commands/suite/__init__.py +0 -0
  72. {testql-1.2.64 → testql-1.2.65}/testql/commands/suite/cli.py +0 -0
  73. {testql-1.2.64 → testql-1.2.65}/testql/commands/suite/collection.py +0 -0
  74. {testql-1.2.64 → testql-1.2.65}/testql/commands/suite/execution.py +0 -0
  75. {testql-1.2.64 → testql-1.2.65}/testql/commands/suite/listing.py +0 -0
  76. {testql-1.2.64 → testql-1.2.65}/testql/commands/suite/reports.py +0 -0
  77. {testql-1.2.64 → testql-1.2.65}/testql/commands/suite_cmd.py +0 -0
  78. {testql-1.2.64 → testql-1.2.65}/testql/commands/templates/__init__.py +0 -0
  79. {testql-1.2.64 → testql-1.2.65}/testql/commands/templates/content.py +0 -0
  80. {testql-1.2.64 → testql-1.2.65}/testql/commands/templates/templates.py +0 -0
  81. {testql-1.2.64 → testql-1.2.65}/testql/commands/topology_cmd.py +0 -0
  82. {testql-1.2.64 → testql-1.2.65}/testql/commands/watchdog_cmd.py +0 -0
  83. {testql-1.2.64 → testql-1.2.65}/testql/context/__init__.py +0 -0
  84. {testql-1.2.64 → testql-1.2.65}/testql/context/runtime.py +0 -0
  85. {testql-1.2.64 → testql-1.2.65}/testql/conversation/__init__.py +0 -0
  86. {testql-1.2.64 → testql-1.2.65}/testql/conversation/runner.py +0 -0
  87. {testql-1.2.64 → testql-1.2.65}/testql/data/__init__.py +0 -0
  88. {testql-1.2.64 → testql-1.2.65}/testql/data/verification-request-v1.schema.json +0 -0
  89. {testql-1.2.64 → testql-1.2.65}/testql/data/verification-result-v1.schema.json +0 -0
  90. {testql-1.2.64 → testql-1.2.65}/testql/detectors/__init__.py +0 -0
  91. {testql-1.2.64 → testql-1.2.65}/testql/detectors/base.py +0 -0
  92. {testql-1.2.64 → testql-1.2.65}/testql/detectors/config_detector.py +0 -0
  93. {testql-1.2.64 → testql-1.2.65}/testql/detectors/django_detector.py +0 -0
  94. {testql-1.2.64 → testql-1.2.65}/testql/detectors/express_detector.py +0 -0
  95. {testql-1.2.64 → testql-1.2.65}/testql/detectors/fastapi_detector.py +0 -0
  96. {testql-1.2.64 → testql-1.2.65}/testql/detectors/flask_detector.py +0 -0
  97. {testql-1.2.64 → testql-1.2.65}/testql/detectors/graphql_detector.py +0 -0
  98. {testql-1.2.64 → testql-1.2.65}/testql/detectors/models.py +0 -0
  99. {testql-1.2.64 → testql-1.2.65}/testql/detectors/openapi_detector.py +0 -0
  100. {testql-1.2.64 → testql-1.2.65}/testql/detectors/test_detector.py +0 -0
  101. {testql-1.2.64 → testql-1.2.65}/testql/detectors/unified.py +0 -0
  102. {testql-1.2.64 → testql-1.2.65}/testql/detectors/websocket_detector.py +0 -0
  103. {testql-1.2.64 → testql-1.2.65}/testql/discovery/__init__.py +0 -0
  104. {testql-1.2.64 → testql-1.2.65}/testql/discovery/manifest.py +0 -0
  105. {testql-1.2.64 → testql-1.2.65}/testql/discovery/probes/__init__.py +0 -0
  106. {testql-1.2.64 → testql-1.2.65}/testql/discovery/probes/base.py +0 -0
  107. {testql-1.2.64 → testql-1.2.65}/testql/discovery/probes/browser/__init__.py +0 -0
  108. {testql-1.2.64 → testql-1.2.65}/testql/discovery/probes/browser/playwright_page.py +0 -0
  109. {testql-1.2.64 → testql-1.2.65}/testql/discovery/probes/filesystem/__init__.py +0 -0
  110. {testql-1.2.64 → testql-1.2.65}/testql/discovery/probes/filesystem/api_openapi.py +0 -0
  111. {testql-1.2.64 → testql-1.2.65}/testql/discovery/probes/filesystem/container_compose.py +0 -0
  112. {testql-1.2.64 → testql-1.2.65}/testql/discovery/probes/filesystem/container_dockerfile.py +0 -0
  113. {testql-1.2.64 → testql-1.2.65}/testql/discovery/probes/filesystem/package_node.py +0 -0
  114. {testql-1.2.64 → testql-1.2.65}/testql/discovery/probes/filesystem/package_python.py +0 -0
  115. {testql-1.2.64 → testql-1.2.65}/testql/discovery/probes/network/__init__.py +0 -0
  116. {testql-1.2.64 → testql-1.2.65}/testql/discovery/probes/network/http_endpoint.py +0 -0
  117. {testql-1.2.64 → testql-1.2.65}/testql/discovery/registry.py +0 -0
  118. {testql-1.2.64 → testql-1.2.65}/testql/discovery/source.py +0 -0
  119. {testql-1.2.64 → testql-1.2.65}/testql/doql_parser.py +0 -0
  120. {testql-1.2.64 → testql-1.2.65}/testql/echo_schemas.py +0 -0
  121. {testql-1.2.64 → testql-1.2.65}/testql/endpoint_detector.py +0 -0
  122. {testql-1.2.64 → testql-1.2.65}/testql/export/__init__.py +0 -0
  123. {testql-1.2.64 → testql-1.2.65}/testql/export/scenario_builder.py +0 -0
  124. {testql-1.2.64 → testql-1.2.65}/testql/generator.py +0 -0
  125. {testql-1.2.64 → testql-1.2.65}/testql/generators/__init__.py +0 -0
  126. {testql-1.2.64 → testql-1.2.65}/testql/generators/analyzers.py +0 -0
  127. {testql-1.2.64 → testql-1.2.65}/testql/generators/api_generator.py +0 -0
  128. {testql-1.2.64 → testql-1.2.65}/testql/generators/base.py +0 -0
  129. {testql-1.2.64 → testql-1.2.65}/testql/generators/convenience.py +0 -0
  130. {testql-1.2.64 → testql-1.2.65}/testql/generators/conversation_generator.py +0 -0
  131. {testql-1.2.64 → testql-1.2.65}/testql/generators/generators.py +0 -0
  132. {testql-1.2.64 → testql-1.2.65}/testql/generators/llm/__init__.py +0 -0
  133. {testql-1.2.64 → testql-1.2.65}/testql/generators/llm/coverage_optimizer.py +0 -0
  134. {testql-1.2.64 → testql-1.2.65}/testql/generators/llm/edge_case_generator.py +0 -0
  135. {testql-1.2.64 → testql-1.2.65}/testql/generators/multi.py +0 -0
  136. {testql-1.2.64 → testql-1.2.65}/testql/generators/page_analyzer.py +0 -0
  137. {testql-1.2.64 → testql-1.2.65}/testql/generators/pipeline.py +0 -0
  138. {testql-1.2.64 → testql-1.2.65}/testql/generators/pytest_generator.py +0 -0
  139. {testql-1.2.64 → testql-1.2.65}/testql/generators/scenario_generator.py +0 -0
  140. {testql-1.2.64 → testql-1.2.65}/testql/generators/sources/__init__.py +0 -0
  141. {testql-1.2.64 → testql-1.2.65}/testql/generators/sources/base.py +0 -0
  142. {testql-1.2.64 → testql-1.2.65}/testql/generators/sources/config_source.py +0 -0
  143. {testql-1.2.64 → testql-1.2.65}/testql/generators/sources/conversation.py +0 -0
  144. {testql-1.2.64 → testql-1.2.65}/testql/generators/sources/nl_source.py +0 -0
  145. {testql-1.2.64 → testql-1.2.65}/testql/generators/sources/openapi_source.py +0 -0
  146. {testql-1.2.64 → testql-1.2.65}/testql/generators/sources/oql_models.py +0 -0
  147. {testql-1.2.64 → testql-1.2.65}/testql/generators/sources/oql_parser.py +0 -0
  148. {testql-1.2.64 → testql-1.2.65}/testql/generators/sources/oql_source.py +0 -0
  149. {testql-1.2.64 → testql-1.2.65}/testql/generators/sources/page_source.py +0 -0
  150. {testql-1.2.64 → testql-1.2.65}/testql/generators/sources/pytest_source.py +0 -0
  151. {testql-1.2.64 → testql-1.2.65}/testql/generators/sources/ui_source.py +0 -0
  152. {testql-1.2.64 → testql-1.2.65}/testql/generators/specialized_generator.py +0 -0
  153. {testql-1.2.64 → testql-1.2.65}/testql/generators/targets/__init__.py +0 -0
  154. {testql-1.2.64 → testql-1.2.65}/testql/generators/targets/base.py +0 -0
  155. {testql-1.2.64 → testql-1.2.65}/testql/generators/targets/nl_target.py +0 -0
  156. {testql-1.2.64 → testql-1.2.65}/testql/generators/targets/pytest_target.py +0 -0
  157. {testql-1.2.64 → testql-1.2.65}/testql/generators/targets/testtoon_target.py +0 -0
  158. {testql-1.2.64 → testql-1.2.65}/testql/generators/test_generator.py +0 -0
  159. {testql-1.2.64 → testql-1.2.65}/testql/integrations/planfile_hook.py +0 -0
  160. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/__init__.py +0 -0
  161. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_assertions.py +0 -0
  162. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_context.py +0 -0
  163. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_converter.py +0 -0
  164. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_desktop.py +0 -0
  165. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_dom_scan.py +0 -0
  166. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_encoder.py +0 -0
  167. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_flow.py +0 -0
  168. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_gui.py +0 -0
  169. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_gui_expand.py +0 -0
  170. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_hardware.py +0 -0
  171. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_modbus.py +0 -0
  172. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_node_playwright.py +0 -0
  173. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_node_playwright_bridge.cjs +0 -0
  174. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_parser.py +0 -0
  175. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_shell.py +0 -0
  176. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_unit.py +0 -0
  177. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_validation.py +0 -0
  178. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/_websockets.py +0 -0
  179. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/__init__.py +0 -0
  180. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/core.py +0 -0
  181. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/dispatcher.py +0 -0
  182. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/handlers/__init__.py +0 -0
  183. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/handlers/api.py +0 -0
  184. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/handlers/assertions.py +0 -0
  185. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/handlers/encoder.py +0 -0
  186. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/handlers/flow.py +0 -0
  187. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/handlers/include.py +0 -0
  188. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/handlers/navigate.py +0 -0
  189. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/handlers/record.py +0 -0
  190. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/handlers/select.py +0 -0
  191. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/handlers/unknown.py +0 -0
  192. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/handlers/wait.py +0 -0
  193. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/models.py +0 -0
  194. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/parsers.py +0 -0
  195. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/converter/renderer.py +0 -0
  196. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/dispatcher.py +0 -0
  197. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/dom_scan_formatters.py +0 -0
  198. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/dom_scan_mixin.py +0 -0
  199. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/dom_scan_models.py +0 -0
  200. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/dom_scanner.py +0 -0
  201. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/interpreter.py +0 -0
  202. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/testtoon_models.py +0 -0
  203. {testql-1.2.64 → testql-1.2.65}/testql/interpreter/testtoon_parser.py +0 -0
  204. {testql-1.2.64 → testql-1.2.65}/testql/interpreter.py +0 -0
  205. {testql-1.2.64 → testql-1.2.65}/testql/ir/__init__.py +0 -0
  206. {testql-1.2.64 → testql-1.2.65}/testql/ir/assertions.py +0 -0
  207. {testql-1.2.64 → testql-1.2.65}/testql/ir/captures.py +0 -0
  208. {testql-1.2.64 → testql-1.2.65}/testql/ir/fixtures.py +0 -0
  209. {testql-1.2.64 → testql-1.2.65}/testql/ir/metadata.py +0 -0
  210. {testql-1.2.64 → testql-1.2.65}/testql/ir/plan.py +0 -0
  211. {testql-1.2.64 → testql-1.2.65}/testql/ir/steps.py +0 -0
  212. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/__init__.py +0 -0
  213. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/assertion_eval.py +0 -0
  214. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/context.py +0 -0
  215. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/executors/__init__.py +0 -0
  216. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/executors/api.py +0 -0
  217. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/executors/assert_json.py +0 -0
  218. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/executors/base.py +0 -0
  219. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/executors/encoder.py +0 -0
  220. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/executors/graphql.py +0 -0
  221. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/executors/gui.py +0 -0
  222. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/executors/nl.py +0 -0
  223. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/executors/proto.py +0 -0
  224. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/executors/shell.py +0 -0
  225. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/executors/sql.py +0 -0
  226. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/executors/unit.py +0 -0
  227. {testql-1.2.64 → testql-1.2.65}/testql/ir_runner/interpolation.py +0 -0
  228. {testql-1.2.64 → testql-1.2.65}/testql/mcp/__init__.py +0 -0
  229. {testql-1.2.64 → testql-1.2.65}/testql/mcp/server.py +0 -0
  230. {testql-1.2.64 → testql-1.2.65}/testql/meta/__init__.py +0 -0
  231. {testql-1.2.64 → testql-1.2.65}/testql/meta/confidence_scorer.py +0 -0
  232. {testql-1.2.64 → testql-1.2.65}/testql/meta/coverage_analyzer.py +0 -0
  233. {testql-1.2.64 → testql-1.2.65}/testql/meta/mutator.py +0 -0
  234. {testql-1.2.64 → testql-1.2.65}/testql/meta/self_test.py +0 -0
  235. {testql-1.2.64 → testql-1.2.65}/testql/nlp2env/__init__.py +0 -0
  236. {testql-1.2.64 → testql-1.2.65}/testql/nlp2env/llm.py +0 -0
  237. {testql-1.2.64 → testql-1.2.65}/testql/nlp2env/mcp_client.py +0 -0
  238. {testql-1.2.64 → testql-1.2.65}/testql/nlp2env/runner.py +0 -0
  239. {testql-1.2.64 → testql-1.2.65}/testql/nlp2env/scenarios.py +0 -0
  240. {testql-1.2.64 → testql-1.2.65}/testql/openapi_generator.py +0 -0
  241. {testql-1.2.64 → testql-1.2.65}/testql/pipeline.py +0 -0
  242. {testql-1.2.64 → testql-1.2.65}/testql/proto_schema/__init__.py +0 -0
  243. {testql-1.2.64 → testql-1.2.65}/testql/proto_schema/descriptor_loader.py +0 -0
  244. {testql-1.2.64 → testql-1.2.65}/testql/proto_schema/message_validator.py +0 -0
  245. {testql-1.2.64 → testql-1.2.65}/testql/report_generator.py +0 -0
  246. {testql-1.2.64 → testql-1.2.65}/testql/reporters/__init__.py +0 -0
  247. {testql-1.2.64 → testql-1.2.65}/testql/reporters/console.py +0 -0
  248. {testql-1.2.64 → testql-1.2.65}/testql/reporters/json_reporter.py +0 -0
  249. {testql-1.2.64 → testql-1.2.65}/testql/reporters/junit.py +0 -0
  250. {testql-1.2.64 → testql-1.2.65}/testql/results/__init__.py +0 -0
  251. {testql-1.2.64 → testql-1.2.65}/testql/results/analyzer.py +0 -0
  252. {testql-1.2.64 → testql-1.2.65}/testql/results/artifacts.py +0 -0
  253. {testql-1.2.64 → testql-1.2.65}/testql/results/models.py +0 -0
  254. {testql-1.2.64 → testql-1.2.65}/testql/results/serializers.py +0 -0
  255. {testql-1.2.64 → testql-1.2.65}/testql/runner.py +0 -0
  256. {testql-1.2.64 → testql-1.2.65}/testql/runners/__init__.py +0 -0
  257. {testql-1.2.64 → testql-1.2.65}/testql/sql_schema/__init__.py +0 -0
  258. {testql-1.2.64 → testql-1.2.65}/testql/sql_schema/ddl_parser.py +0 -0
  259. {testql-1.2.64 → testql-1.2.65}/testql/sql_schema/dialect_resolver.py +0 -0
  260. {testql-1.2.64 → testql-1.2.65}/testql/sumd_generator.py +0 -0
  261. {testql-1.2.64 → testql-1.2.65}/testql/sumd_parser.py +0 -0
  262. {testql-1.2.64 → testql-1.2.65}/testql/toon_parser.py +0 -0
  263. {testql-1.2.64 → testql-1.2.65}/testql/topology/__init__.py +0 -0
  264. {testql-1.2.64 → testql-1.2.65}/testql/topology/builder.py +0 -0
  265. {testql-1.2.64 → testql-1.2.65}/testql/topology/generator.py +0 -0
  266. {testql-1.2.64 → testql-1.2.65}/testql/topology/models.py +0 -0
  267. {testql-1.2.64 → testql-1.2.65}/testql/topology/serializers.py +0 -0
  268. {testql-1.2.64 → testql-1.2.65}/testql/topology/sitemap.py +0 -0
  269. {testql-1.2.64 → testql-1.2.65}/testql/verification.py +0 -0
  270. {testql-1.2.64 → testql-1.2.65}/testql.egg-info/SOURCES.txt +0 -0
  271. {testql-1.2.64 → testql-1.2.65}/testql.egg-info/dependency_links.txt +0 -0
  272. {testql-1.2.64 → testql-1.2.65}/testql.egg-info/entry_points.txt +0 -0
  273. {testql-1.2.64 → testql-1.2.65}/testql.egg-info/requires.txt +0 -0
  274. {testql-1.2.64 → testql-1.2.65}/testql.egg-info/top_level.txt +0 -0
  275. {testql-1.2.64 → testql-1.2.65}/tests/test_adapter_capture_syntax.py +0 -0
  276. {testql-1.2.64 → testql-1.2.65}/tests/test_adapters_base.py +0 -0
  277. {testql-1.2.64 → testql-1.2.65}/tests/test_api_handler.py +0 -0
  278. {testql-1.2.64 → testql-1.2.65}/tests/test_assertion_suite.py +0 -0
  279. {testql-1.2.64 → testql-1.2.65}/tests/test_browser_discovery.py +0 -0
  280. {testql-1.2.64 → testql-1.2.65}/tests/test_cc_refactor_helpers.py +0 -0
  281. {testql-1.2.64 → testql-1.2.65}/tests/test_cli.py +0 -0
  282. {testql-1.2.64 → testql-1.2.65}/tests/test_cli_no_block.py +0 -0
  283. {testql-1.2.64 → testql-1.2.65}/tests/test_conversation_live_llm.py +0 -0
  284. {testql-1.2.64 → testql-1.2.65}/tests/test_conversation_nlp2dsl.py +0 -0
  285. {testql-1.2.64 → testql-1.2.65}/tests/test_converter.py +0 -0
  286. {testql-1.2.64 → testql-1.2.65}/tests/test_converter_handlers.py +0 -0
  287. {testql-1.2.64 → testql-1.2.65}/tests/test_desktop_assert_elements.py +0 -0
  288. {testql-1.2.64 → testql-1.2.65}/tests/test_desktop_execution.py +0 -0
  289. {testql-1.2.64 → testql-1.2.65}/tests/test_detectors.py +0 -0
  290. {testql-1.2.64 → testql-1.2.65}/tests/test_discovery.py +0 -0
  291. {testql-1.2.64 → testql-1.2.65}/tests/test_dispatcher.py +0 -0
  292. {testql-1.2.64 → testql-1.2.65}/tests/test_doql_parser_sumd_gen.py +0 -0
  293. {testql-1.2.64 → testql-1.2.65}/tests/test_echo.py +0 -0
  294. {testql-1.2.64 → testql-1.2.65}/tests/test_echo_doql_parser.py +0 -0
  295. {testql-1.2.64 → testql-1.2.65}/tests/test_echo_schemas_helpers.py +0 -0
  296. {testql-1.2.64 → testql-1.2.65}/tests/test_encoder_routes.py +0 -0
  297. {testql-1.2.64 → testql-1.2.65}/tests/test_environment_regressions.py +0 -0
  298. {testql-1.2.64 → testql-1.2.65}/tests/test_generate_cmd.py +0 -0
  299. {testql-1.2.64 → testql-1.2.65}/tests/test_generate_from_page_cli.py +0 -0
  300. {testql-1.2.64 → testql-1.2.65}/tests/test_generate_ir_cli.py +0 -0
  301. {testql-1.2.64 → testql-1.2.65}/tests/test_generators.py +0 -0
  302. {testql-1.2.64 → testql-1.2.65}/tests/test_gui_execution.py +0 -0
  303. {testql-1.2.64 → testql-1.2.65}/tests/test_ir.py +0 -0
  304. {testql-1.2.64 → testql-1.2.65}/tests/test_ir_captures.py +0 -0
  305. {testql-1.2.64 → testql-1.2.65}/tests/test_ir_runner_assertion_eval.py +0 -0
  306. {testql-1.2.64 → testql-1.2.65}/tests/test_ir_runner_engine.py +0 -0
  307. {testql-1.2.64 → testql-1.2.65}/tests/test_ir_runner_executors.py +0 -0
  308. {testql-1.2.64 → testql-1.2.65}/tests/test_ir_runner_interpolation.py +0 -0
  309. {testql-1.2.64 → testql-1.2.65}/tests/test_mcp_autoloop.py +0 -0
  310. {testql-1.2.64 → testql-1.2.65}/tests/test_meta_confidence.py +0 -0
  311. {testql-1.2.64 → testql-1.2.65}/tests/test_meta_coverage.py +0 -0
  312. {testql-1.2.64 → testql-1.2.65}/tests/test_meta_mutator.py +0 -0
  313. {testql-1.2.64 → testql-1.2.65}/tests/test_meta_self_test.py +0 -0
  314. {testql-1.2.64 → testql-1.2.65}/tests/test_misc_cmds.py +0 -0
  315. {testql-1.2.64 → testql-1.2.65}/tests/test_modbus_commands.py +0 -0
  316. {testql-1.2.64 → testql-1.2.65}/tests/test_navigate_json_path.py +0 -0
  317. {testql-1.2.64 → testql-1.2.65}/tests/test_network_discovery.py +0 -0
  318. {testql-1.2.64 → testql-1.2.65}/tests/test_nl_adapter.py +0 -0
  319. {testql-1.2.64 → testql-1.2.65}/tests/test_nl_entity_extractor.py +0 -0
  320. {testql-1.2.64 → testql-1.2.65}/tests/test_nl_grammar.py +0 -0
  321. {testql-1.2.64 → testql-1.2.65}/tests/test_nl_intent_recognizer.py +0 -0
  322. {testql-1.2.64 → testql-1.2.65}/tests/test_nl_scenarios_e2e.py +0 -0
  323. {testql-1.2.64 → testql-1.2.65}/tests/test_nlp2env_adapter.py +0 -0
  324. {testql-1.2.64 → testql-1.2.65}/tests/test_node_playwright_fallback.py +0 -0
  325. {testql-1.2.64 → testql-1.2.65}/tests/test_openapi_generator.py +0 -0
  326. {testql-1.2.64 → testql-1.2.65}/tests/test_page_analyzer.py +0 -0
  327. {testql-1.2.64 → testql-1.2.65}/tests/test_pipeline.py +0 -0
  328. {testql-1.2.64 → testql-1.2.65}/tests/test_plugin_registry.py +0 -0
  329. {testql-1.2.64 → testql-1.2.65}/tests/test_proto_descriptor_loader.py +0 -0
  330. {testql-1.2.64 → testql-1.2.65}/tests/test_proto_graphql_scenarios_e2e.py +0 -0
  331. {testql-1.2.64 → testql-1.2.65}/tests/test_proto_message_validator.py +0 -0
  332. {testql-1.2.64 → testql-1.2.65}/tests/test_report_generator.py +0 -0
  333. {testql-1.2.64 → testql-1.2.65}/tests/test_reporters.py +0 -0
  334. {testql-1.2.64 → testql-1.2.65}/tests/test_results.py +0 -0
  335. {testql-1.2.64 → testql-1.2.65}/tests/test_run_cmd.py +0 -0
  336. {testql-1.2.64 → testql-1.2.65}/tests/test_run_ir_cli.py +0 -0
  337. {testql-1.2.64 → testql-1.2.65}/tests/test_runner.py +0 -0
  338. {testql-1.2.64 → testql-1.2.65}/tests/test_runtime_context.py +0 -0
  339. {testql-1.2.64 → testql-1.2.65}/tests/test_scenario_yaml_adapter.py +0 -0
  340. {testql-1.2.64 → testql-1.2.65}/tests/test_shell_execution.py +0 -0
  341. {testql-1.2.64 → testql-1.2.65}/tests/test_smoke_decisions.py +0 -0
  342. {testql-1.2.64 → testql-1.2.65}/tests/test_sources.py +0 -0
  343. {testql-1.2.64 → testql-1.2.65}/tests/test_sql_ddl_parser.py +0 -0
  344. {testql-1.2.64 → testql-1.2.65}/tests/test_sql_dialect_resolver.py +0 -0
  345. {testql-1.2.64 → testql-1.2.65}/tests/test_suite_cmd_helpers.py +0 -0
  346. {testql-1.2.64 → testql-1.2.65}/tests/test_suite_execution.py +0 -0
  347. {testql-1.2.64 → testql-1.2.65}/tests/test_suite_listing.py +0 -0
  348. {testql-1.2.64 → testql-1.2.65}/tests/test_sumd_parser.py +0 -0
  349. {testql-1.2.64 → testql-1.2.65}/tests/test_targets.py +0 -0
  350. {testql-1.2.64 → testql-1.2.65}/tests/test_test_generator.py +0 -0
  351. {testql-1.2.64 → testql-1.2.65}/tests/test_testtoon_adapter.py +0 -0
  352. {testql-1.2.64 → testql-1.2.65}/tests/test_toon_parser.py +0 -0
  353. {testql-1.2.64 → testql-1.2.65}/tests/test_topology.py +0 -0
  354. {testql-1.2.64 → testql-1.2.65}/tests/test_topology_generator.py +0 -0
  355. {testql-1.2.64 → testql-1.2.65}/tests/test_unit_execution.py +0 -0
  356. {testql-1.2.64 → testql-1.2.65}/tests/test_validation.py +0 -0
  357. {testql-1.2.64 → testql-1.2.65}/tests/test_verification_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: testql
3
- Version: 1.2.64
3
+ Version: 1.2.65
4
4
  Summary: TestQL — Multi-DSL Test Platform: TestTOON / NL / SQL / Proto / GraphQL adapters with Unified IR, generator engine, and meta-testing
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: <3.14,>=3.11
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "testql"
7
- version = "1.2.64"
7
+ version = "1.2.65"
8
8
  description = "TestQL — Multi-DSL Test Platform: TestTOON / NL / SQL / Proto / GraphQL adapters with Unified IR, generator engine, and meta-testing"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11,<3.14"
@@ -72,7 +72,7 @@ class ApiRunnerMixin:
72
72
  continue
73
73
  # Re-raise non-retryable errors
74
74
  raise
75
- except Exception as e:
75
+ except Exception:
76
76
  # Non-retryable errors
77
77
  raise
78
78
 
@@ -128,7 +128,7 @@ class ApiRunnerMixin:
128
128
  return
129
129
 
130
130
  method = parts[0].upper()
131
- url = parts[1].strip("\"'")
131
+ url = self.vars.interpolate(parts[1].strip("\"'"))
132
132
  body_str = parts[2] if len(parts) > 2 else ""
133
133
 
134
134
  if url.startswith("/"):
@@ -19,9 +19,6 @@ import json
19
19
 
20
20
  from ._gui_expand import expand_gui_row
21
21
  from ._parser import OqlLine, OqlScript
22
- from .testtoon_models import ToonSection, ToonScript
23
- from .testtoon_parser import parse_testtoon
24
-
25
22
  # Backward compatibility: re-export classes that were moved
26
23
  from .testtoon_models import ToonSection, ToonScript # noqa: F401
27
24
  from .testtoon_parser import parse_testtoon # noqa: F401
@@ -110,9 +107,38 @@ def _append_api_asserts(row: dict, lines: list[OqlLine], line_num: int) -> int:
110
107
  return line_num
111
108
 
112
109
 
113
- def _expand_api(section: ToonSection, lines: list[OqlLine], line_num: int) -> int:
110
+ def _append_api_captures(
111
+ row: dict,
112
+ api_step: int,
113
+ capture_rows: list[dict],
114
+ lines: list[OqlLine],
115
+ line_num: int,
116
+ ) -> int:
117
+ """Append captures assigned to an API row by its 1-based index or name."""
118
+ step_name = str(row.get('name', '')).strip()
119
+ for capture in capture_rows:
120
+ target = str(capture.get('step', '')).strip()
121
+ if target != str(api_step) and (not step_name or target != step_name):
122
+ continue
123
+ var_name = str(capture.get('var', '')).strip()
124
+ from_path = str(capture.get('from', '')).strip()
125
+ if not var_name or not from_path:
126
+ continue
127
+ args = f'{var_name} FROM "{from_path}"'
128
+ line_num = _append_raw_command(lines, line_num, 'CAPTURE', args)
129
+ return line_num
130
+
131
+
132
+ def _expand_api(
133
+ section: ToonSection,
134
+ lines: list[OqlLine],
135
+ line_num: int,
136
+ *,
137
+ capture_rows: list[dict] | None = None,
138
+ step_offset: int = 0,
139
+ ) -> int:
114
140
  """Expand API section → API + ASSERT_STATUS commands."""
115
- for row in section.rows:
141
+ for row_index, row in enumerate(section.rows, 1):
116
142
  method = row.get('method', 'GET')
117
143
  endpoint = row.get('endpoint', '/')
118
144
  body = row.get('body')
@@ -127,6 +153,13 @@ def _expand_api(section: ToonSection, lines: list[OqlLine], line_num: int) -> in
127
153
  raw = f'API {method} "{endpoint}"{body_str}'
128
154
  lines.append(OqlLine(number=line_num, command='API', args=f'{method} "{endpoint}"{body_str}', raw=raw))
129
155
  line_num = _append_api_asserts(row, lines, line_num + 1)
156
+ line_num = _append_api_captures(
157
+ row,
158
+ step_offset + row_index,
159
+ capture_rows or [],
160
+ lines,
161
+ line_num,
162
+ )
130
163
  return line_num
131
164
 
132
165
 
@@ -649,8 +682,29 @@ def testtoon_to_oql(text: str, filename: str = "<string>") -> OqlScript:
649
682
  toon = parse_testtoon(text, filename)
650
683
  lines: list[OqlLine] = []
651
684
  line_num = 1
685
+ api_step_count = 0
686
+ capture_rows = [
687
+ row
688
+ for section in toon.sections
689
+ if section.type == 'CAPTURE'
690
+ for row in section.rows
691
+ ]
652
692
 
653
693
  for section in toon.sections:
694
+ if section.type == 'CAPTURE':
695
+ # Captures must run while the referenced API response is still the
696
+ # current response, so API expansion interleaves them above.
697
+ continue
698
+ if section.type == 'API':
699
+ line_num = _expand_api(
700
+ section,
701
+ lines,
702
+ line_num,
703
+ capture_rows=capture_rows,
704
+ step_offset=api_step_count,
705
+ )
706
+ api_step_count += len(section.rows)
707
+ continue
654
708
  expander = _SECTION_EXPANDERS.get(section.type, _expand_generic)
655
709
  line_num = expander(section, lines, line_num)
656
710
 
@@ -49,7 +49,14 @@ def _apply_captures(step, result: StepResult, ctx: ExecutionContext) -> None:
49
49
  return
50
50
  payload = (result.details or {}).get("payload", {})
51
51
  for capture in captures:
52
- value = navigate(payload, capture.from_path)
52
+ # API capture paths are relative to the response body (`response.data.id`
53
+ # is normalized to `data.id`). Other executors expose their result fields
54
+ # directly. Fall back to the full envelope so API status/header captures
55
+ # remain possible.
56
+ capture_root = payload.get("data", {}) if getattr(step, "kind", "") == "api" else payload
57
+ value = navigate(capture_root, capture.from_path)
58
+ if value is None and capture_root is not payload:
59
+ value = navigate(payload, capture.from_path)
53
60
  if value is None:
54
61
  ctx.warnings.append(
55
62
  f"capture {capture.var_name!r} from {capture.from_path!r}: path not found"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: testql
3
- Version: 1.2.64
3
+ Version: 1.2.65
4
4
  Summary: TestQL — Multi-DSL Test Platform: TestTOON / NL / SQL / Proto / GraphQL adapters with Unified IR, generator engine, and meta-testing
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: <3.14,>=3.11
@@ -103,6 +103,34 @@ class TestTestTOONExpansion:
103
103
  assert script.lines[3].command == "ASSERT_STATUS"
104
104
  assert "201" in script.lines[3].args
105
105
 
106
+ def test_capture_is_interleaved_after_referenced_api_step(self):
107
+ source = (
108
+ "API[2]{method, endpoint, status}:\n"
109
+ " POST, /devices, 201\n"
110
+ " GET, /devices/${device_id}, 200\n"
111
+ "CAPTURE[1]{step, var, from}:\n"
112
+ " 1, device_id, data.id\n"
113
+ )
114
+
115
+ script = _testtoon_to_oql(source, "test.testql.toon.yaml")
116
+
117
+ assert [line.command for line in script.lines] == [
118
+ "API", "ASSERT_STATUS", "CAPTURE", "API", "ASSERT_STATUS",
119
+ ]
120
+ assert script.lines[2].args == 'device_id FROM "data.id"'
121
+
122
+ def test_capture_can_reference_named_api_step(self):
123
+ source = (
124
+ "API[1]{method, endpoint, status, name}:\n"
125
+ " POST, /devices, 201, createDevice\n"
126
+ "CAPTURE[1]{step, var, from}:\n"
127
+ " createDevice, device_id, data.id\n"
128
+ )
129
+
130
+ script = _testtoon_to_oql(source, "test.testql.toon.yaml")
131
+
132
+ assert script.lines[-1].command == "CAPTURE"
133
+
106
134
  def test_encoder_expansion(self):
107
135
  source = (
108
136
  "ENCODER[2]{action, target, value, wait_ms}:\n"
@@ -227,6 +255,22 @@ class TestOqlInterpreter:
227
255
  assert result.ok
228
256
  assert result.passed >= 1
229
257
 
258
+ def test_api_interpolates_captured_variable_in_url(self, monkeypatch):
259
+ requested_urls = []
260
+
261
+ def fake_request(_self, _method, url, _body):
262
+ requested_urls.append(url)
263
+ return 200, {"ok": True}, {}
264
+
265
+ monkeypatch.setattr(OqlInterpreter, "_do_http_request_with_retry", fake_request)
266
+ interp = OqlInterpreter(quiet=True, api_url="http://localhost:8101")
267
+ interp.vars.set("device_id", "dev-7")
268
+
269
+ result = interp.run('API GET "/devices/${device_id}"', "test.tql")
270
+
271
+ assert result.ok
272
+ assert requested_urls == ["http://localhost:8101/devices/dev-7"]
273
+
230
274
  def test_set_get(self):
231
275
  source = 'SET foo "bar"\nGET foo'
232
276
  interp = OqlInterpreter(dry_run=True, quiet=True)
@@ -77,6 +77,26 @@ class TestShellCaptures:
77
77
  assert "hello" in runner.ctx.vars.get("out")
78
78
 
79
79
 
80
+ class TestApiCaptures:
81
+ def test_capture_is_relative_to_response_body(self, monkeypatch):
82
+ from testql.ir_runner.executors import api
83
+
84
+ monkeypatch.setattr(api, "_do_request", lambda *args: (201, {"data": {"id": "sc-1"}}))
85
+ plan = _plan(
86
+ ApiStep(
87
+ method="POST",
88
+ path="/api/v3/scenarios",
89
+ captures=[Capture(var_name="scenario_id", from_path="data.id")],
90
+ )
91
+ )
92
+ runner = IRRunner()
93
+
94
+ result = runner.run(plan)
95
+
96
+ assert result.ok
97
+ assert runner.ctx.vars.get("scenario_id") == "sc-1"
98
+
99
+
80
100
  # ── Missing path → warning, not failure ─────────────────────────────────────
81
101
 
82
102
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes