wavexis 2.2.4__tar.gz → 2.2.5__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 (213) hide show
  1. {wavexis-2.2.4 → wavexis-2.2.5}/CHANGELOG.md +12 -0
  2. {wavexis-2.2.4 → wavexis-2.2.5}/PKG-INFO +1 -1
  3. {wavexis-2.2.4 → wavexis-2.2.5}/pyproject.toml +1 -1
  4. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/__init__.py +1 -1
  5. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_shared.py +15 -5
  6. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/exceptions.py +28 -3
  7. {wavexis-2.2.4 → wavexis-2.2.5}/.dockerignore +0 -0
  8. {wavexis-2.2.4 → wavexis-2.2.5}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  9. {wavexis-2.2.4 → wavexis-2.2.5}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  10. {wavexis-2.2.4 → wavexis-2.2.5}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  11. {wavexis-2.2.4 → wavexis-2.2.5}/.github/workflows/ci.yml +0 -0
  12. {wavexis-2.2.4 → wavexis-2.2.5}/.github/workflows/docs.yml +0 -0
  13. {wavexis-2.2.4 → wavexis-2.2.5}/.github/workflows/release.yml +0 -0
  14. {wavexis-2.2.4 → wavexis-2.2.5}/.gitignore +0 -0
  15. {wavexis-2.2.4 → wavexis-2.2.5}/CODE_OF_CONDUCT.md +0 -0
  16. {wavexis-2.2.4 → wavexis-2.2.5}/CONTRIBUTING.md +0 -0
  17. {wavexis-2.2.4 → wavexis-2.2.5}/Dockerfile +0 -0
  18. {wavexis-2.2.4 → wavexis-2.2.5}/LICENSE +0 -0
  19. {wavexis-2.2.4 → wavexis-2.2.5}/README.md +0 -0
  20. {wavexis-2.2.4 → wavexis-2.2.5}/SECURITY.md +0 -0
  21. {wavexis-2.2.4 → wavexis-2.2.5}/docs/api/actions.md +0 -0
  22. {wavexis-2.2.4 → wavexis-2.2.5}/docs/api/backends.md +0 -0
  23. {wavexis-2.2.4 → wavexis-2.2.5}/docs/api/cli.md +0 -0
  24. {wavexis-2.2.4 → wavexis-2.2.5}/docs/api/config.md +0 -0
  25. {wavexis-2.2.4 → wavexis-2.2.5}/docs/api/exceptions.md +0 -0
  26. {wavexis-2.2.4 → wavexis-2.2.5}/docs/api/multi.md +0 -0
  27. {wavexis-2.2.4 → wavexis-2.2.5}/docs/api/plugins.md +0 -0
  28. {wavexis-2.2.4 → wavexis-2.2.5}/docs/api/serve.md +0 -0
  29. {wavexis-2.2.4 → wavexis-2.2.5}/docs/cookbook/auth.md +0 -0
  30. {wavexis-2.2.4 → wavexis-2.2.5}/docs/cookbook/ci-cd.md +0 -0
  31. {wavexis-2.2.4 → wavexis-2.2.5}/docs/cookbook/css.md +0 -0
  32. {wavexis-2.2.4 → wavexis-2.2.5}/docs/cookbook/debug.md +0 -0
  33. {wavexis-2.2.4 → wavexis-2.2.5}/docs/cookbook/record-replay.md +0 -0
  34. {wavexis-2.2.4 → wavexis-2.2.5}/docs/cookbook/scraping.md +0 -0
  35. {wavexis-2.2.4 → wavexis-2.2.5}/docs/cookbook/screenshots.md +0 -0
  36. {wavexis-2.2.4 → wavexis-2.2.5}/docs/cookbook/serve-mode.md +0 -0
  37. {wavexis-2.2.4 → wavexis-2.2.5}/docs/guide/assert.md +0 -0
  38. {wavexis-2.2.4 → wavexis-2.2.5}/docs/guide/backends.md +0 -0
  39. {wavexis-2.2.4 → wavexis-2.2.5}/docs/guide/commands.md +0 -0
  40. {wavexis-2.2.4 → wavexis-2.2.5}/docs/guide/init.md +0 -0
  41. {wavexis-2.2.4 → wavexis-2.2.5}/docs/guide/installation.md +0 -0
  42. {wavexis-2.2.4 → wavexis-2.2.5}/docs/guide/multi.md +0 -0
  43. {wavexis-2.2.4 → wavexis-2.2.5}/docs/guide/perf.md +0 -0
  44. {wavexis-2.2.4 → wavexis-2.2.5}/docs/guide/plugins.md +0 -0
  45. {wavexis-2.2.4 → wavexis-2.2.5}/docs/guide/quickstart.md +0 -0
  46. {wavexis-2.2.4 → wavexis-2.2.5}/docs/guide/raw.md +0 -0
  47. {wavexis-2.2.4 → wavexis-2.2.5}/docs/guide/repl.md +0 -0
  48. {wavexis-2.2.4 → wavexis-2.2.5}/docs/guide/troubleshooting.md +0 -0
  49. {wavexis-2.2.4 → wavexis-2.2.5}/docs/index.md +0 -0
  50. {wavexis-2.2.4 → wavexis-2.2.5}/mkdocs.yml +0 -0
  51. {wavexis-2.2.4 → wavexis-2.2.5}/stubs/bidiwave/__init__.pyi +0 -0
  52. {wavexis-2.2.4 → wavexis-2.2.5}/stubs/cdpwave/__init__.pyi +0 -0
  53. {wavexis-2.2.4 → wavexis-2.2.5}/tests/__init__.py +0 -0
  54. {wavexis-2.2.4 → wavexis-2.2.5}/tests/conftest.py +0 -0
  55. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/__init__.py +0 -0
  56. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_a11y.py +0 -0
  57. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_animation.py +0 -0
  58. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_backend_selection.py +0 -0
  59. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_browser.py +0 -0
  60. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_console.py +0 -0
  61. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_css.py +0 -0
  62. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_debug.py +0 -0
  63. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_dialog.py +0 -0
  64. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_dom.py +0 -0
  65. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_dom_snapshot.py +0 -0
  66. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_emulation.py +0 -0
  67. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_emulation_advanced.py +0 -0
  68. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_eval.py +0 -0
  69. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_har.py +0 -0
  70. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_input.py +0 -0
  71. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_media.py +0 -0
  72. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_multi.py +0 -0
  73. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_navigate.py +0 -0
  74. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_network.py +0 -0
  75. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_network_advanced.py +0 -0
  76. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_overlay.py +0 -0
  77. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_pdf.py +0 -0
  78. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_perf.py +0 -0
  79. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_permissions.py +0 -0
  80. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_raw.py +0 -0
  81. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_record.py +0 -0
  82. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_scrape.py +0 -0
  83. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_screenshot.py +0 -0
  84. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_security.py +0 -0
  85. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_serve.py +0 -0
  86. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_service_worker.py +0 -0
  87. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_storage.py +0 -0
  88. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_tabs.py +0 -0
  89. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_webaudio.py +0 -0
  90. {wavexis-2.2.4 → wavexis-2.2.5}/tests/integration/test_webauthn.py +0 -0
  91. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/__init__.py +0 -0
  92. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_abstract_backend_phase5.py +0 -0
  93. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_actions.py +0 -0
  94. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_actions_phase5.py +0 -0
  95. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_animation_action.py +0 -0
  96. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_assert_multi.py +0 -0
  97. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_auth.py +0 -0
  98. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_backend_manager.py +0 -0
  99. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_bidi_backend.py +0 -0
  100. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_bidi_phase5.py +0 -0
  101. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_bluetooth_action.py +0 -0
  102. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_cast_action.py +0 -0
  103. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_cleanup.py +0 -0
  104. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_cli_phase5.py +0 -0
  105. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_config.py +0 -0
  106. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_config_phase5.py +0 -0
  107. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_cookies_headers_actions.py +0 -0
  108. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_css_action.py +0 -0
  109. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_debug_action.py +0 -0
  110. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_dom_snapshot_action.py +0 -0
  111. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_download_screencast.py +0 -0
  112. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_emulation_action.py +0 -0
  113. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_error_handling.py +0 -0
  114. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_exceptions.py +0 -0
  115. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_format_record.py +0 -0
  116. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_global_options.py +0 -0
  117. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_init.py +0 -0
  118. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_input_action.py +0 -0
  119. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_interactions_crawl.py +0 -0
  120. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_manager.py +0 -0
  121. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_media_action.py +0 -0
  122. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_multi.py +0 -0
  123. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_multi_improvements.py +0 -0
  124. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_new_features.py +0 -0
  125. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_output.py +0 -0
  126. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_overlay_action.py +0 -0
  127. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_perf_action.py +0 -0
  128. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_perf_console.py +0 -0
  129. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_plugins.py +0 -0
  130. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_raw.py +0 -0
  131. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_record.py +0 -0
  132. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_repl.py +0 -0
  133. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_serve.py +0 -0
  134. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_service_worker_action.py +0 -0
  135. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_storage_action.py +0 -0
  136. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_webaudio_action.py +0 -0
  137. {wavexis-2.2.4 → wavexis-2.2.5}/tests/unit/test_webauthn_action.py +0 -0
  138. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/__main__.py +0 -0
  139. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/__init__.py +0 -0
  140. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/accessibility.py +0 -0
  141. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/animation.py +0 -0
  142. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/base.py +0 -0
  143. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/bluetooth.py +0 -0
  144. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/browser.py +0 -0
  145. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/cast.py +0 -0
  146. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/console.py +0 -0
  147. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/cookies.py +0 -0
  148. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/crawl.py +0 -0
  149. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/css.py +0 -0
  150. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/debug.py +0 -0
  151. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/dialog.py +0 -0
  152. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/dom.py +0 -0
  153. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/dom_snapshot.py +0 -0
  154. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/download.py +0 -0
  155. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/emulation.py +0 -0
  156. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/eval.py +0 -0
  157. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/extract.py +0 -0
  158. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/form.py +0 -0
  159. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/har.py +0 -0
  160. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/headers.py +0 -0
  161. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/input.py +0 -0
  162. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/lighthouse.py +0 -0
  163. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/media.py +0 -0
  164. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/multi.py +0 -0
  165. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/navigate.py +0 -0
  166. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/network.py +0 -0
  167. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/overlay.py +0 -0
  168. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/pdf.py +0 -0
  169. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/performance.py +0 -0
  170. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/permissions.py +0 -0
  171. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/record.py +0 -0
  172. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/scrape.py +0 -0
  173. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/screencast.py +0 -0
  174. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/screenshot.py +0 -0
  175. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/security.py +0 -0
  176. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/service_worker.py +0 -0
  177. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/session.py +0 -0
  178. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/storage.py +0 -0
  179. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/tabs.py +0 -0
  180. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/wait.py +0 -0
  181. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/webaudio.py +0 -0
  182. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/webauthn.py +0 -0
  183. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/actions/websocket.py +0 -0
  184. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/auth.py +0 -0
  185. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/backend/__init__.py +0 -0
  186. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/backend/base.py +0 -0
  187. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/backend/bidi.py +0 -0
  188. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/backend/cdp.py +0 -0
  189. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/backend/manager.py +0 -0
  190. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cleanup.py +0 -0
  191. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/__init__.py +0 -0
  192. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_advanced.py +0 -0
  193. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_capture.py +0 -0
  194. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_config.py +0 -0
  195. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_debug.py +0 -0
  196. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_emulation.py +0 -0
  197. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_experimental.py +0 -0
  198. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_input.py +0 -0
  199. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_navigation.py +0 -0
  200. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_network.py +0 -0
  201. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_perf.py +0 -0
  202. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_serve.py +0 -0
  203. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_session.py +0 -0
  204. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/_workflow.py +0 -0
  205. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/cli/app.py +0 -0
  206. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/config.py +0 -0
  207. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/init.py +0 -0
  208. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/multi.py +0 -0
  209. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/output.py +0 -0
  210. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/plugins.py +0 -0
  211. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/record.py +0 -0
  212. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/repl.py +0 -0
  213. {wavexis-2.2.4 → wavexis-2.2.5}/wavexis/serve.py +0 -0
@@ -2,6 +2,18 @@
2
2
 
3
3
  All notable changes to wavexis are documented in this file.
4
4
 
5
+ ## v2.2.5 — 2026-07-07
6
+
7
+ ### Improved
8
+
9
+ - Error messages now include actionable hints for common failures
10
+ - `ElementNotFoundError` suggests `wavexis dom` and `wavexis screenshot` for debugging
11
+ - `WaitTimeoutError` suggests increasing `--timeout` and alternative wait strategies
12
+ - `NavigationError` suggests checking URL, `--timeout`, and `--proxy`
13
+ - `SessionNotInitializedError` suggests `--headed` and checking Chromium installation
14
+ - `BackendNotAvailableError` shows install commands for both backends
15
+ - `MultiConfigError` suggests `--dry-run` to validate config
16
+
5
17
  ## v2.2.4 — 2026-07-07
6
18
 
7
19
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wavexis
3
- Version: 2.2.4
3
+ Version: 2.2.5
4
4
  Summary: Browser automation CLI — wraps cdpwave and bidiwave, no Node.js, no Chromium download
5
5
  Project-URL: Homepage, https://github.com/MathiasPaulenko/wavexis
6
6
  Project-URL: Repository, https://github.com/MathiasPaulenko/wavexis
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "wavexis"
7
- version = "2.2.4"
7
+ version = "2.2.5"
8
8
  description = "Browser automation CLI — wraps cdpwave and bidiwave, no Node.js, no Chromium download"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -1,3 +1,3 @@
1
1
  """wavexis — CLI de automatización de navegador."""
2
2
 
3
- __version__ = "2.2.4"
3
+ __version__ = "2.2.5"
@@ -21,6 +21,7 @@ from wavexis.exceptions import (
21
21
  ElementNotFoundError,
22
22
  MultiConfigError,
23
23
  NavigationError,
24
+ SessionNotInitializedError,
24
25
  WaitTimeoutError,
25
26
  WavexisError,
26
27
  )
@@ -39,6 +40,7 @@ __all__ = [
39
40
  "MultiConfigError",
40
41
  "NavigationError",
41
42
  "Output",
43
+ "SessionNotInitializedError",
42
44
  "WaitTimeoutError",
43
45
  "WavexisError",
44
46
  "_browser_options",
@@ -209,20 +211,28 @@ def _handle_error(e: Exception) -> None:
209
211
  """
210
212
  if isinstance(e, BackendNotAvailableError):
211
213
  Output.error(
212
- "No backend available. Install cdpwave: pip install wavexis[cdp]"
214
+ "No backend available.\n"
215
+ "Hint: Install cdpwave with `pip install wavexis[cdp]`, "
216
+ "or bidiwave with `pip install wavexis[bidi]`."
213
217
  )
214
218
  raise typer.Exit(EXIT_BACKEND_ERROR) from e
219
+ if isinstance(e, SessionNotInitializedError):
220
+ Output.error(str(e))
221
+ raise typer.Exit(EXIT_BROWSER_ERROR) from e
215
222
  if isinstance(e, NavigationError):
216
- Output.error(f"Navigation failed: {e}")
223
+ Output.error(str(e))
217
224
  raise typer.Exit(EXIT_BROWSER_ERROR) from e
218
225
  if isinstance(e, WaitTimeoutError):
219
- Output.error(f"Timeout waiting: {e}")
226
+ Output.error(str(e))
220
227
  raise typer.Exit(EXIT_BROWSER_ERROR) from e
221
228
  if isinstance(e, ElementNotFoundError):
222
- Output.error(f"Element not found: {e}")
229
+ Output.error(str(e))
223
230
  raise typer.Exit(EXIT_BROWSER_ERROR) from e
224
231
  if isinstance(e, MultiConfigError):
225
- Output.error(f"Invalid multi config: {e}")
232
+ Output.error(
233
+ f"Invalid multi config: {e}\n"
234
+ "Hint: Run `wavexis multi <config> --dry-run` to validate the config."
235
+ )
226
236
  raise typer.Exit(EXIT_CONFIG_ERROR) from e
227
237
  if isinstance(e, WavexisError):
228
238
  Output.error(str(e))
@@ -41,6 +41,21 @@ class BackendNotSupportedError(WavexisError):
41
41
  class SessionNotInitializedError(WavexisError):
42
42
  """Raised when a backend method is called before launch()."""
43
43
 
44
+ def __init__(self, msg: str | None = None) -> None:
45
+ """Initialize the error.
46
+
47
+ Args:
48
+ msg: Optional custom message.
49
+ """
50
+ if msg:
51
+ super().__init__(msg)
52
+ else:
53
+ super().__init__(
54
+ "Browser session not initialized. Call launch() first.\n"
55
+ "Hint: This usually means the browser failed to start. "
56
+ "Try --headed to see the browser window, or check if Chromium is installed."
57
+ )
58
+
44
59
 
45
60
  class NavigationError(WavexisError):
46
61
  """Raised when navigation fails or times out."""
@@ -52,7 +67,11 @@ class NavigationError(WavexisError):
52
67
  url: The URL that failed to navigate to.
53
68
  reason: The failure reason.
54
69
  """
55
- super().__init__(f"Navigation to '{url}' failed: {reason}")
70
+ super().__init__(
71
+ f"Navigation to '{url}' failed: {reason}\n"
72
+ f"Hint: Check the URL is reachable, try --timeout 60000, "
73
+ f"or use --proxy if behind a firewall."
74
+ )
56
75
 
57
76
 
58
77
  class WaitTimeoutError(WavexisError):
@@ -66,7 +85,9 @@ class WaitTimeoutError(WavexisError):
66
85
  timeout_ms: The timeout duration in milliseconds.
67
86
  """
68
87
  super().__init__(
69
- f"Wait strategy '{strategy}' timed out after {timeout_ms}ms"
88
+ f"Wait strategy '{strategy}' timed out after {timeout_ms}ms\n"
89
+ f"Hint: Increase timeout with --timeout {max(timeout_ms * 2, 60000)}, "
90
+ f"or use a different wait strategy (load, domcontentloaded, networkidle)."
70
91
  )
71
92
 
72
93
 
@@ -79,7 +100,11 @@ class ElementNotFoundError(WavexisError):
79
100
  Args:
80
101
  selector: The CSS selector that matched no elements.
81
102
  """
82
- super().__init__(f"No element found matching selector: {selector}")
103
+ super().__init__(
104
+ f"No element found matching selector: {selector}\n"
105
+ f"Hint: Verify the selector with `wavexis dom --selector '{selector}'`, "
106
+ f"or use `wavexis screenshot` to inspect the page visually."
107
+ )
83
108
 
84
109
 
85
110
  class ActionError(WavexisError):
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
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
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
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
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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes