ragger 1.21.1__tar.gz → 1.41.0__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 (186) hide show
  1. ragger-1.41.0/.github/workflows/build_and_tests.yml +133 -0
  2. {ragger-1.21.1 → ragger-1.41.0}/.github/workflows/codeql-analysis.yml +9 -7
  3. {ragger-1.21.1 → ragger-1.41.0}/.github/workflows/documentation.yml +5 -0
  4. {ragger-1.21.1 → ragger-1.41.0}/.github/workflows/fast-checks.yml +7 -2
  5. {ragger-1.21.1 → ragger-1.41.0}/.gitignore +1 -1
  6. {ragger-1.21.1 → ragger-1.41.0}/CHANGELOG.md +223 -0
  7. {ragger-1.21.1/src/ragger.egg-info → ragger-1.41.0}/PKG-INFO +17 -13
  8. {ragger-1.21.1 → ragger-1.41.0}/README.md +4 -4
  9. {ragger-1.21.1 → ragger-1.41.0}/doc/index.rst +1 -2
  10. {ragger-1.21.1 → ragger-1.41.0}/doc/rationale.rst +1 -1
  11. {ragger-1.21.1 → ragger-1.41.0}/doc/source.rst +3 -0
  12. {ragger-1.21.1 → ragger-1.41.0}/doc/tutorial_conftest.rst +3 -0
  13. {ragger-1.21.1 → ragger-1.41.0}/doc/tutorial_screen.rst +4 -4
  14. ragger-1.41.0/ledger_app.toml +5 -0
  15. {ragger-1.21.1 → ragger-1.41.0}/pyproject.toml +12 -8
  16. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/__init__.py +0 -4
  17. ragger-1.41.0/src/ragger/__version__.py +34 -0
  18. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/backend/interface.py +52 -19
  19. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/backend/ledgercomm.py +8 -8
  20. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/backend/ledgerwallet.py +8 -8
  21. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/backend/physical_backend.py +33 -11
  22. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/backend/speculos.py +48 -14
  23. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/backend/stub.py +6 -2
  24. ragger-1.41.0/src/ragger/conftest/base_conftest.py +458 -0
  25. ragger-1.41.0/src/ragger/conftest/configuration.py +68 -0
  26. ragger-1.41.0/src/ragger/error.py +175 -0
  27. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/firmware/__init__.py +2 -2
  28. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/firmware/structs.py +29 -14
  29. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/firmware/touch/element.py +7 -6
  30. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/firmware/touch/layouts.py +0 -12
  31. ragger-1.41.0/src/ragger/firmware/touch/positions.py +938 -0
  32. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/firmware/touch/screen.py +8 -8
  33. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/__init__.py +1 -1
  34. ragger-1.41.0/src/ragger/gui/assets/swipe_left_action.png +0 -0
  35. ragger-1.41.0/src/ragger/gui/assets/swipe_right_action.png +0 -0
  36. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/interface.py +80 -23
  37. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/process.py +20 -7
  38. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/logger.py +24 -7
  39. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/navigator/instruction.py +1 -0
  40. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/navigator/nano_navigator.py +5 -5
  41. ragger-1.41.0/src/ragger/navigator/navigation_scenario.py +194 -0
  42. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/navigator/navigator.py +35 -24
  43. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/navigator/touch_navigator.py +7 -6
  44. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/utils/misc.py +16 -1
  45. {ragger-1.21.1 → ragger-1.41.0/src/ragger.egg-info}/PKG-INFO +17 -13
  46. {ragger-1.21.1 → ragger-1.41.0}/src/ragger.egg-info/SOURCES.txt +8 -0
  47. {ragger-1.21.1 → ragger-1.41.0}/src/ragger.egg-info/requires.txt +7 -5
  48. {ragger-1.21.1 → ragger-1.41.0}/tests/functional/backend/test_speculos.py +3 -3
  49. {ragger-1.21.1 → ragger-1.41.0}/tests/functional/navigator/test_navigator.py +5 -5
  50. {ragger-1.21.1 → ragger-1.41.0}/tests/functional/test_boilerplate.py +12 -13
  51. ragger-1.41.0/tests/snapshots/apex_p/waiting_screen/00000.png +0 -0
  52. ragger-1.41.0/tests/snapshots/apex_p/waiting_screen/00001.png +0 -0
  53. ragger-1.41.0/tests/snapshots/apex_p/waiting_screen/00002.png +0 -0
  54. ragger-1.41.0/tests/snapshots/apex_p/waiting_screen/00003.png +0 -0
  55. ragger-1.41.0/tests/snapshots/apex_p/waiting_screen/00004.png +0 -0
  56. ragger-1.41.0/tests/snapshots/flex/waiting_screen/00000.png +0 -0
  57. ragger-1.41.0/tests/snapshots/flex/waiting_screen/00001.png +0 -0
  58. ragger-1.41.0/tests/snapshots/flex/waiting_screen/00002.png +0 -0
  59. ragger-1.41.0/tests/snapshots/flex/waiting_screen/00003.png +0 -0
  60. ragger-1.41.0/tests/snapshots/flex/waiting_screen/00004.png +0 -0
  61. ragger-1.41.0/tests/snapshots/stax/waiting_screen/00001.png +0 -0
  62. ragger-1.41.0/tests/snapshots/stax/waiting_screen/00002.png +0 -0
  63. ragger-1.41.0/tests/snapshots/stax/waiting_screen/00003.png +0 -0
  64. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/backend/test_interface.py +10 -7
  65. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/backend/test_ledgercomm.py +3 -3
  66. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/backend/test_ledgerwallet.py +2 -3
  67. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/backend/test_physical_backend.py +8 -8
  68. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/backend/test_speculos.py +13 -10
  69. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/conftests/test_base_conftest.py +41 -45
  70. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/firmware/touch/test_element.py +4 -4
  71. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/firmware/touch/test_screen_FullScreen.py +26 -26
  72. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/firmware/touch/test_screen_MetaScreen.py +4 -4
  73. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/navigator/test_nano_navigator.py +4 -4
  74. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/navigator/test_navigation_scenario.py +4 -4
  75. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/navigator/test_navigator.py +12 -12
  76. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/navigator/test_touch_navigator.py +4 -4
  77. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/utils/test_misc.py +7 -21
  78. ragger-1.21.1/.github/workflows/build_and_tests.yml +0 -139
  79. ragger-1.21.1/src/ragger/__version__.py +0 -16
  80. ragger-1.21.1/src/ragger/conftest/base_conftest.py +0 -276
  81. ragger-1.21.1/src/ragger/conftest/configuration.py +0 -51
  82. ragger-1.21.1/src/ragger/error.py +0 -38
  83. ragger-1.21.1/src/ragger/firmware/touch/positions.py +0 -510
  84. ragger-1.21.1/src/ragger/navigator/navigation_scenario.py +0 -114
  85. ragger-1.21.1/tests/snapshots/flex/waiting_screen/00000.png +0 -0
  86. ragger-1.21.1/tests/snapshots/flex/waiting_screen/00001.png +0 -0
  87. ragger-1.21.1/tests/snapshots/flex/waiting_screen/00002.png +0 -0
  88. ragger-1.21.1/tests/snapshots/flex/waiting_screen/00003.png +0 -0
  89. ragger-1.21.1/tests/snapshots/flex/waiting_screen/00004.png +0 -0
  90. ragger-1.21.1/tests/snapshots/stax/waiting_screen/00001.png +0 -0
  91. ragger-1.21.1/tests/snapshots/stax/waiting_screen/00002.png +0 -0
  92. ragger-1.21.1/tests/snapshots/stax/waiting_screen/00003.png +0 -0
  93. {ragger-1.21.1 → ragger-1.41.0}/.codeql-config.yaml +0 -0
  94. {ragger-1.21.1 → ragger-1.41.0}/.gitattributes +0 -0
  95. {ragger-1.21.1 → ragger-1.41.0}/.github/workflows/force-rebase.yml +0 -0
  96. {ragger-1.21.1 → ragger-1.41.0}/LICENSE +0 -0
  97. {ragger-1.21.1 → ragger-1.41.0}/MANIFEST.in +0 -0
  98. {ragger-1.21.1 → ragger-1.41.0}/doc/Makefile +0 -0
  99. {ragger-1.21.1 → ragger-1.41.0}/doc/_static/layout.css +0 -0
  100. {ragger-1.21.1 → ragger-1.41.0}/doc/_templates/layout.html +0 -0
  101. {ragger-1.21.1 → ragger-1.41.0}/doc/architecture.rst +0 -0
  102. {ragger-1.21.1 → ragger-1.41.0}/doc/conf.py +0 -0
  103. {ragger-1.21.1 → ragger-1.41.0}/doc/faq.rst +0 -0
  104. {ragger-1.21.1 → ragger-1.41.0}/doc/glossary.rst +0 -0
  105. {ragger-1.21.1 → ragger-1.41.0}/doc/images/navigate.draw +0 -0
  106. {ragger-1.21.1 → ragger-1.41.0}/doc/images/navigate.svg +0 -0
  107. {ragger-1.21.1 → ragger-1.41.0}/doc/images/ragger.png +0 -0
  108. {ragger-1.21.1 → ragger-1.41.0}/doc/images/stax_infos.png +0 -0
  109. {ragger-1.21.1 → ragger-1.41.0}/doc/images/stax_welcome.png +0 -0
  110. {ragger-1.21.1 → ragger-1.41.0}/doc/images/usage.draw +0 -0
  111. {ragger-1.21.1 → ragger-1.41.0}/doc/images/usage.svg +0 -0
  112. {ragger-1.21.1 → ragger-1.41.0}/doc/installation.rst +0 -0
  113. {ragger-1.21.1 → ragger-1.41.0}/doc/tutorial.rst +0 -0
  114. {ragger-1.21.1 → ragger-1.41.0}/doc/tutorial_installation.rst +0 -0
  115. {ragger-1.21.1 → ragger-1.41.0}/setup.cfg +0 -0
  116. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/backend/__init__.py +0 -0
  117. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/bip/__init__.py +0 -0
  118. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/bip/path.py +0 -0
  119. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/bip/seed.py +0 -0
  120. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/conftest/__init__.py +0 -0
  121. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/firmware/touch/__init__.py +0 -0
  122. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/firmware/touch/use_cases.py +0 -0
  123. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/assets/nanos_body.png +0 -0
  124. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/assets/nanos_leftbutton.png +0 -0
  125. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/assets/nanos_rightbutton.png +0 -0
  126. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/assets/nanosp_body.png +0 -0
  127. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/assets/nanosp_leftbutton.png +0 -0
  128. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/assets/nanosp_rightbutton.png +0 -0
  129. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/assets/nanox_body.png +0 -0
  130. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/assets/nanox_leftbutton.png +0 -0
  131. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/assets/nanox_rightbutton.png +0 -0
  132. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/assets/stax_body.png +0 -0
  133. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/gui/assets/touch_action.png +0 -0
  134. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/navigator/__init__.py +0 -0
  135. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/py.typed +0 -0
  136. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/utils/__init__.py +0 -0
  137. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/utils/packing.py +0 -0
  138. {ragger-1.21.1 → ragger-1.41.0}/src/ragger/utils/structs.py +0 -0
  139. {ragger-1.21.1 → ragger-1.41.0}/src/ragger.egg-info/dependency_links.txt +0 -0
  140. {ragger-1.21.1 → ragger-1.41.0}/src/ragger.egg-info/top_level.txt +0 -0
  141. {ragger-1.21.1 → ragger-1.41.0}/template/.dispatch_to_your_test_folder +0 -0
  142. {ragger-1.21.1 → ragger-1.41.0}/template/conftest.py +0 -0
  143. {ragger-1.21.1 → ragger-1.41.0}/template/usage.md +0 -0
  144. {ragger-1.21.1 → ragger-1.41.0}/tests/__init__.py +0 -0
  145. {ragger-1.21.1 → ragger-1.41.0}/tests/functional/__init__.py +0 -0
  146. {ragger-1.21.1 → ragger-1.41.0}/tests/functional/backend/__init__.py +0 -0
  147. {ragger-1.21.1 → ragger-1.41.0}/tests/functional/conftest.py +0 -0
  148. {ragger-1.21.1 → ragger-1.41.0}/tests/functional/navigator/__init__.py +0 -0
  149. {ragger-1.21.1 → ragger-1.41.0}/tests/pytest.ini +0 -0
  150. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/generic/00000.png +0 -0
  151. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/generic/00001.png +0 -0
  152. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/generic/00002.png +0 -0
  153. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/generic/00003.png +0 -0
  154. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/generic/00004.png +0 -0
  155. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_and_compare/00000.png +0 -0
  156. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_and_compare/00001.png +0 -0
  157. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_and_compare/00002.png +0 -0
  158. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_and_compare/00003.png +0 -0
  159. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_and_compare/00004.png +0 -0
  160. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_and_compare/00005.png +0 -0
  161. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_and_compare/00006.png +0 -0
  162. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_and_compare/00007.png +0 -0
  163. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_and_compare_no_golden/00000.png +0 -0
  164. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_and_compare_wrong_golden/00000.png +0 -0
  165. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_and_compare_wrong_golden/00001.png +0 -0
  166. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_until_text_and_compare/00000.png +0 -0
  167. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_until_text_and_compare/00001.png +0 -0
  168. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_until_text_and_compare/00002.png +0 -0
  169. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/nanos/test_navigate_until_text_and_compare/00003.png +0 -0
  170. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/stax/waiting_screen/00000.png +0 -0
  171. {ragger-1.21.1 → ragger-1.41.0}/tests/snapshots/stax/waiting_screen/00004.png +0 -0
  172. {ragger-1.21.1 → ragger-1.41.0}/tests/stubs.py +0 -0
  173. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/__init__.py +0 -0
  174. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/backend/__init__.py +0 -0
  175. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/backend/test_stub.py +0 -0
  176. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/bip/test_path.py +0 -0
  177. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/bip/test_seed.py +0 -0
  178. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/conftests/__init__.py +0 -0
  179. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/firmware/test_structs_Firmware.py +0 -0
  180. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/helpers.py +0 -0
  181. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/navigator/__init__.py +0 -0
  182. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/test_error_ApplicationError.py +0 -0
  183. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/utils/__init__.py +0 -0
  184. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/utils/test_packing.py +0 -0
  185. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/utils/test_path.py +0 -0
  186. {ragger-1.21.1 → ragger-1.41.0}/tests/unit/utils/test_structs.py +0 -0
@@ -0,0 +1,133 @@
1
+ name: Build, test and deploy Ragger
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ push:
6
+ tags:
7
+ - '*'
8
+ branches:
9
+ - master
10
+ - develop
11
+ pull_request:
12
+ branches:
13
+ - master
14
+ - develop
15
+
16
+ # Cancel previous runs on this reference
17
+ concurrency:
18
+ group: ${{ github.workflow }}-${{ github.ref }}
19
+ cancel-in-progress: true
20
+
21
+ jobs:
22
+
23
+ build_boilerplate_application:
24
+ name: Build boilerplate application using the reusable workflow
25
+ uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_build.yml@v1
26
+ with:
27
+ app_repository: LedgerHQ/app-boilerplate
28
+ app_branch_name: master
29
+ upload_app_binaries_artifact: boilerplate_binaries
30
+
31
+ build_boilerplate_application_nanos:
32
+ name: Build boilerplate application for Nanos S using the reusable workflow
33
+ uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_build.yml@v1
34
+ with:
35
+ app_repository: LedgerHQ/app-boilerplate
36
+ app_branch_name: nanos_baseline
37
+ upload_app_binaries_artifact: boilerplate_binaries_nanos
38
+
39
+ prepare_matrix:
40
+ name: Prepare matrix from TOML file
41
+ runs-on: ubuntu-latest
42
+ outputs:
43
+ devices: ${{ steps.get_devices.outputs.devices }}
44
+ env:
45
+ APP_MANIFEST: "ledger_app.toml"
46
+
47
+ steps:
48
+ - name: Clone
49
+ uses: actions/checkout@v4
50
+ - name: Install ledgered
51
+ run: pip install ledgered
52
+ - name: Get devices from TOML
53
+ id: get_devices
54
+ run: |
55
+ # get device list as a single line json formatted value
56
+ compatible_devices="$(ledger-manifest --output-devices "${APP_MANIFEST}" -j | jq -rc '.devices')"
57
+
58
+ echo "devices=${compatible_devices}" | sed 's/+/p/' >> "${GITHUB_OUTPUT}"
59
+
60
+ build_install_test:
61
+ name: Install and test the library
62
+ needs: [prepare_matrix, build_boilerplate_application, build_boilerplate_application_nanos]
63
+ runs-on: ubuntu-latest
64
+ strategy:
65
+ fail-fast: false
66
+ matrix:
67
+ python_version: ['3.9', '3.10', '3.11', '3.12', '3.13']
68
+ device: ${{ fromJson(needs.prepare_matrix.outputs.devices) }}
69
+
70
+ steps:
71
+ - name: Clone
72
+ uses: actions/checkout@v4
73
+ with:
74
+ fetch-depth: 0
75
+
76
+ - name: Setup Python version
77
+ uses: actions/setup-python@v5
78
+ with:
79
+ python-version: ${{ matrix.python_version }}
80
+
81
+ - name: Speculos dependencies
82
+ run: sudo apt-get update && sudo apt-get install -y qemu-user-static tesseract-ocr libtesseract-dev python3-pyqt6
83
+
84
+ - name: Build & install
85
+ run: |
86
+ pip install -U .[tests,all_backends]
87
+ pip install -U "click>=8"
88
+
89
+ - name: Install speculos for Nanos
90
+ if: ${{ matrix.device == 'nanos' }}
91
+ run: |
92
+ pip install -U speculos==v0.25.5
93
+
94
+ - name: Download app binaries
95
+ if: ${{ matrix.device != 'nanos' }}
96
+ uses: actions/download-artifact@v4
97
+ with:
98
+ name: boilerplate_binaries
99
+ path: ./build/
100
+
101
+ - name: Download app binaries for Nano S
102
+ if: ${{ matrix.device == 'nanos' }}
103
+ uses: actions/download-artifact@v4
104
+ with:
105
+ name: boilerplate_binaries_nanos
106
+ path: ./build/
107
+
108
+ - name: Check the downloaded files
109
+ run: tree .
110
+
111
+ - name: Run unit tests and generate coverage
112
+ run: pytest -v --tb=short tests/unit --cov ragger --cov-report xml
113
+
114
+ - name: Run functional tests and generate coverage
115
+ run: pytest -v --tb=short tests/functional --cov ragger --cov-report xml --cov-append --device ${{ matrix.device }}
116
+
117
+ - name: Upload to codecov.io
118
+ uses: codecov/codecov-action@v5
119
+ env:
120
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
121
+ with:
122
+ name: codecov-ragger
123
+ flags: ${{ matrix.device }}-py${{ matrix.python_version }}
124
+
125
+ package_and_deploy:
126
+ name: Build and deploy the Ragger Python package
127
+ needs: [build_install_test]
128
+ uses: LedgerHQ/ledger-app-workflows/.github/workflows/reusable_pypi_deployment.yml@v1
129
+ with:
130
+ package_name: ragger
131
+ publish: ${{ startsWith(github.ref, 'refs/tags/') }}
132
+ secrets:
133
+ pypi_token: ${{ secrets.PYPI_PUBLIC_API_TOKEN }}
@@ -12,6 +12,11 @@ on:
12
12
  - develop
13
13
  schedule:
14
14
  - cron: '35 0 * * 5'
15
+ # Cancel previous runs on this reference
16
+ concurrency:
17
+ group: ${{ github.workflow }}-${{ github.ref }}
18
+ cancel-in-progress: true
19
+
15
20
 
16
21
  jobs:
17
22
  analyze:
@@ -22,16 +27,13 @@ jobs:
22
27
  contents: read
23
28
  security-events: write
24
29
 
25
- strategy:
26
- fail-fast: false
27
-
28
30
  steps:
29
31
  - name: Checkout repository
30
32
  uses: actions/checkout@v4
31
33
 
32
34
  # Initializes the CodeQL tools for scanning.
33
35
  - name: Initialize CodeQL
34
- uses: github/codeql-action/init@v2
36
+ uses: github/codeql-action/init@v3
35
37
  with:
36
38
  languages: "python"
37
39
  # If you wish to specify custom queries, you can do so here or in a config file.
@@ -40,10 +42,10 @@ jobs:
40
42
  # queries: ./path/to/local/query, your-org/your-repo/queries@main
41
43
  queries: +security-and-quality
42
44
 
43
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
45
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
44
46
  # If this step fails, then you should remove it and run the build manually (see below)
45
47
  - name: Autobuild
46
- uses: github/codeql-action/autobuild@v2
48
+ uses: github/codeql-action/autobuild@v3
47
49
 
48
50
  # ℹ️ Command-line programs to run using the OS shell.
49
51
  # 📚 https://git.io/JvXDl
@@ -57,6 +59,6 @@ jobs:
57
59
  # make release
58
60
 
59
61
  - name: Perform CodeQL Analysis
60
- uses: github/codeql-action/analyze@v2
62
+ uses: github/codeql-action/analyze@v3
61
63
  with:
62
64
  config-file: .codeql-config.yaml
@@ -11,6 +11,11 @@ on:
11
11
  branches:
12
12
  - develop
13
13
  - master
14
+ # Cancel previous runs on this reference
15
+ concurrency:
16
+ group: ${{ github.workflow }}-${{ github.ref }}
17
+ cancel-in-progress: true
18
+
14
19
 
15
20
  jobs:
16
21
  generate:
@@ -7,6 +7,11 @@ on:
7
7
  - develop
8
8
  - master
9
9
  pull_request:
10
+ # Cancel previous runs on this reference
11
+ concurrency:
12
+ group: ${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
10
15
 
11
16
  jobs:
12
17
  lint:
@@ -59,8 +64,8 @@ jobs:
59
64
  - name: Clone
60
65
  uses: actions/checkout@v4
61
66
  - name: Check misspellings
62
- uses: codespell-project/actions-codespell@v1
67
+ uses: codespell-project/actions-codespell@v2
63
68
  with:
64
69
  builtin: clear,rare
65
70
  check_filenames: true
66
- ignore_words_list: assertIn,
71
+ ignore_words_list: assertIn,crate,
@@ -6,9 +6,9 @@ coverage.xml
6
6
  build/
7
7
  dist/
8
8
  __version__.py
9
+ .python-version
9
10
 
10
11
  tests/snapshots-tmp/
11
- ledger_app.toml
12
12
 
13
13
  # doc
14
14
  doc/images/*generated*
@@ -5,6 +5,229 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.41.0] - 2025-12-09
9
+
10
+ ### Added
11
+
12
+ - Class `StatusWords` with default Status Words values, as defined in the SDK
13
+
14
+ ## [1.40.4] - 2025-11-20
15
+
16
+ ### Fixed
17
+
18
+ - Fix navigation in functions `xxx_with_warning` with multiple warning screens for Nano on NBGL
19
+
20
+ ## [1.40.3] - 2025-11-06
21
+
22
+ ### Fixed
23
+
24
+ - Add new parameter in `navigation_scenario` functions `xxx_with_warning` to specify the number of warning screens
25
+
26
+ ## [1.40.2] - 2025-09-09
27
+
28
+ ### Fixed
29
+
30
+ - Fix APEX keyboards positions
31
+
32
+ ## [1.40.1] - 2025-09-03
33
+
34
+ ### Fixed
35
+
36
+ - Fix APEX BUTTON_LOWER_LEFT coordinates
37
+
38
+ ## [1.40.0] - 2025-08-01
39
+
40
+ ### Added
41
+
42
+ - Add two new devices: Apex_p and Apex_m
43
+
44
+ ## [1.39.0] - 2025-07-22
45
+
46
+ ### Added
47
+
48
+ - Align libraries loading for swap standalone tests with library loading for eth plugin tests
49
+
50
+ ## [1.38.0] - 2025-07-16
51
+
52
+ ### Changed
53
+
54
+ - `log_apdu_file` option allows to set the filename pattern when executing multiple tests
55
+
56
+ ### Fixed
57
+
58
+ - yield true on async to notify the action has been completed (physical backends)
59
+
60
+ ## [1.37.1] - 2025-05-16
61
+
62
+ ### Fixed
63
+
64
+ - minor bug fixes on the PhysicalDevice navigation flow
65
+ - OCR enhancements on physical backend to detect words
66
+
67
+ ### Added
68
+ - Key presses shortcuts (y/n) to navigate through the ragger GUI with a physical backend
69
+
70
+ ## [1.37.0] - 2025-05-16
71
+
72
+ ### Changed
73
+
74
+ - `exchange_async_raw` on the speculos backend can yield if the apdu has a response or not as a boolean
75
+
76
+ ## [1.36.1] - 2025-06-16
77
+
78
+ ### Fixed
79
+
80
+ - Added toml as a dependency (requided in utils/misc.py)
81
+
82
+ ## [1.36.0] - 2025-05-30
83
+
84
+ ### Changed
85
+
86
+ - Enable to use both MAIN_APP_DIR and SIDELOADED_APPS options (required to perform Swap tests)
87
+
88
+
89
+ ## [1.35.0] - 2025-05-14
90
+
91
+ ### Changed
92
+
93
+ - Using `ledgered` Devices instead of local `Firmware` / `FIRMWARES`.
94
+ Basically `ledgered.device.DeviceType` replaces the `ragger.firmware.Firmware` enum, and
95
+ `ledgered.device.Devices` replaces `FIRMWARES`.
96
+ - `ragger.firmware.Firmware` is now a proxy to `ledgered` types and prints deprecation messages.
97
+
98
+ ## [1.34.0] - 2025-04-28
99
+
100
+ ### Changed
101
+
102
+ - Use pytest builtin --log-level instead of custom --Verbose
103
+
104
+ ### Fixed
105
+
106
+ - Fix scenario navigation regular expression matching partial words
107
+
108
+ ## [1.33.0] - 2025-04-23
109
+
110
+ ### Added
111
+
112
+ - conftest: `--no-nav` option to completely disable the navigation during the tests.
113
+ - Retrieve `sdk_graphics` from elf file
114
+ - Add new functions `review_xxx_with_warning` to include the warning screen acknowledge
115
+ - Adapt `NavigationScenarioData` for Nano using NBGL
116
+
117
+ ## [1.32.1] - 2025-04-04
118
+
119
+ ### Fixed
120
+
121
+ - Reviews navigation on touchable devices (Flex, Stax) no longer 'taps', but 'swipes'
122
+
123
+ ## [1.32.0] - 2025-03-31
124
+
125
+ ### Changed
126
+
127
+ - Upgrade PyQt5 to PyQt6
128
+
129
+ ## [1.31.1] - 2025-03-26
130
+
131
+ ### Fixed
132
+
133
+ - Add missing method to physical device interface
134
+
135
+ ## [1.31.0] - 2025-03-26
136
+
137
+ ### Changed
138
+
139
+ - Reactivate logs like "Saving screenshot to image" (which were removed in v1.29.0)
140
+
141
+ ## [1.30.0] - 2025-03-21
142
+
143
+ ### Added
144
+
145
+ - Added support for Python 3.13
146
+
147
+ ## [1.29.0] - 2025-03-06
148
+
149
+ ### Changed
150
+
151
+ - Use `--Verbose` option to increase `pytest` verbosity. It adds log timestamps, some test-specific
152
+ logs, and the verbose option is forwarded to Speculos.
153
+
154
+ ## [1.28.0] - 2025-03-05
155
+
156
+ ### Added
157
+
158
+ - Added --pki_prod option that can be forwarded to Speculos upon usage
159
+
160
+ ## [1.27.1] - 2025-02-26
161
+
162
+ ### Fixed
163
+
164
+ - Fixed backend being instantiated even when the test needs a different setup
165
+
166
+ ## [1.27.0] - 2025-02-21
167
+
168
+ ### Added
169
+
170
+ - Added support for different test setup
171
+
172
+ ## [1.26.0] - 2025-02-06
173
+
174
+ ### Added
175
+
176
+ - Added support for Python 3.12
177
+ - SWIPE support for physical backend
178
+
179
+ ### Removed
180
+
181
+ - Drop support for Python 3.8
182
+
183
+ ### Fixed
184
+
185
+ - `_actionhint` element location (covered previously by the snapshot image)
186
+ - Physical backend -specific imports (`PIL`, `tesseract`) are postponed to avoid raising when using
187
+ Speculos only
188
+
189
+ ## [1.25.0] - 2024-12-20
190
+
191
+ ### Added
192
+ - navigator: `Navigator.navigate_until_text_and_compare` and `Navigator.navigate_until_text` now
193
+ accept a `snap_start_idx` argument, like `Navigator.navigate_and_compare`.
194
+
195
+ ## [1.24.0] - 2024-10-03
196
+
197
+ ### Added
198
+ - conftest: Added 'all_eink' option for the `--device` argument to target Stax + Flex
199
+ - conftest: Added a autouse fixture to skip unsupported devices
200
+
201
+ ### Fixed
202
+
203
+ - firmware/stax: Choice List positions were no longer correct compared to latest NBGL evolutions
204
+
205
+ ## [1.23.0] - 2024-07-25
206
+
207
+ ### Changed
208
+
209
+ - Rust app: get target directory from cargo metadata (workspace compatible)
210
+
211
+ ## [1.22.1] - 2024-07-23
212
+
213
+ ### Fixed
214
+
215
+ - firmware/flex: Wrong keyboard position
216
+
217
+ ## [1.22.0] - 2024-07-22
218
+
219
+ ### Added
220
+
221
+ - firmware/flex: Added the suggestion buttons positions (used with keyboard)
222
+
223
+ ### Changed
224
+
225
+ - firmware/stax: Updated the suggestion buttons positions (used with keyboard)
226
+
227
+ ### Fixed
228
+
229
+ - firmware/flex: Wrong keyboard position
230
+
8
231
  ## [1.21.1] - 2024-07-16
9
232
 
10
233
  ### Fixed
@@ -1,24 +1,26 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: ragger
3
- Version: 1.21.1
3
+ Version: 1.41.0
4
4
  Summary: Testing framework using Speculos and LedgerComm as backends
5
5
  Author-email: Ledger <hello@ledger.fr>
6
6
  Project-URL: Homepage, https://github.com/LedgerHQ/ragger
7
7
  Project-URL: Bug Tracker, https://github.com/LedgerHQ/ragger/issues
8
8
  Classifier: Programming Language :: Python :: 3
9
- Classifier: Programming Language :: Python :: 3.8
10
9
  Classifier: Programming Language :: Python :: 3.9
11
10
  Classifier: Programming Language :: Python :: 3.10
12
11
  Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
13
14
  Classifier: License :: OSI Approved :: Apache Software License
14
15
  Classifier: Operating System :: POSIX :: Linux
15
16
  Classifier: Operating System :: MacOS :: MacOS X
16
- Requires-Python: >=3.8
17
+ Requires-Python: >=3.9
17
18
  Description-Content-Type: text/markdown
18
19
  License-File: LICENSE
19
20
  Requires-Dist: bip_utils>=2.4.0
20
21
  Requires-Dist: py-sr25519-bindings<0.3.0,>=0.2.0
21
- Requires-Dist: ledgered>=0.6.3
22
+ Requires-Dist: ledgered>=0.10.1
23
+ Requires-Dist: toml
22
24
  Provides-Extra: tests
23
25
  Requires-Dist: pytest; extra == "tests"
24
26
  Requires-Dist: pytest-cov; extra == "tests"
@@ -30,7 +32,6 @@ Requires-Dist: flake8-pyproject; extra == "checkers"
30
32
  Requires-Dist: mypy; extra == "checkers"
31
33
  Requires-Dist: types-toml; extra == "checkers"
32
34
  Requires-Dist: bandit; extra == "checkers"
33
- Requires-Dist: pyqt5-stubs; extra == "checkers"
34
35
  Provides-Extra: doc
35
36
  Requires-Dist: pylint; extra == "doc"
36
37
  Requires-Dist: sphinx; extra == "doc"
@@ -40,21 +41,24 @@ Requires-Dist: sphinx-copybutton; extra == "doc"
40
41
  Requires-Dist: Jinja2>=3.0; extra == "doc"
41
42
  Requires-Dist: docutils==0.16; extra == "doc"
42
43
  Provides-Extra: speculos
43
- Requires-Dist: speculos>=0.9.1; extra == "speculos"
44
+ Requires-Dist: speculos>=0.13.1; extra == "speculos"
44
45
  Requires-Dist: mnemonic; extra == "speculos"
45
46
  Provides-Extra: ledgercomm
46
47
  Requires-Dist: ledgercomm>=1.2.1; extra == "ledgercomm"
47
48
  Requires-Dist: ledgercomm[hid]>=1.2.1; extra == "ledgercomm"
48
- Requires-Dist: pyqt5; extra == "ledgercomm"
49
+ Requires-Dist: pyqt6; extra == "ledgercomm"
49
50
  Requires-Dist: pytesseract; extra == "ledgercomm"
51
+ Requires-Dist: pillow; extra == "ledgercomm"
50
52
  Provides-Extra: ledgerwallet
51
53
  Requires-Dist: ledgerwallet>=0.4.0; extra == "ledgerwallet"
52
- Requires-Dist: pyqt5; extra == "ledgerwallet"
54
+ Requires-Dist: pyqt6; extra == "ledgerwallet"
53
55
  Requires-Dist: pytesseract; extra == "ledgerwallet"
56
+ Requires-Dist: pillow; extra == "ledgerwallet"
54
57
  Provides-Extra: all-backends
55
58
  Requires-Dist: ragger[speculos]; extra == "all-backends"
56
59
  Requires-Dist: ragger[ledgercomm]; extra == "all-backends"
57
60
  Requires-Dist: ragger[ledgerwallet]; extra == "all-backends"
61
+ Dynamic: license-file
58
62
 
59
63
  # Ragger
60
64
 
@@ -66,16 +70,16 @@ Requires-Dist: ragger[ledgerwallet]; extra == "all-backends"
66
70
  This library aims at reducing the cost of running code on both Speculos emulator
67
71
  or on a real device.
68
72
 
69
- It mainly consists on an interface which is implemented by three backends:
73
+ It mainly consists of an interface which is implemented by three backends:
70
74
 
71
75
  - an emulator-only backend, `SpeculosBackend`, which uses
72
76
  [`SpeculosClient`](https://github.com/LedgerHQ/speculos/blob/master/speculos/client.py)
73
- to run an app on a Speculos emulator. With this backend, APDU can be send directly,
77
+ to run an app on a Speculos emulator. With this backend, APDU can be sent directly,
74
78
  without having to connect a device, start a docker or anything.
75
79
 
76
80
  - two physical backends (although technically they are agnostic, but the
77
81
  `SpeculosClient` is superior with an emulator), `LedgerCommBackend` and
78
- `LedgewWalletbackend`, which use respectively the
82
+ `LedgerWalletBackend`, which use respectively the
79
83
  [`LedgerComm` library](https://github.com/LedgerHQ/ledgercomm) or the
80
84
  [`LedgerWallet` library](https://github.com/LedgerHQ/ledgerctl/) to discuss
81
85
  with a physical device. In these cases, the physical device must be started,
@@ -125,7 +129,7 @@ different backends and that allow to interact with a device (either a real devic
125
129
 
126
130
  * `send`: send a formatted APDU.
127
131
  * `send_raw`: send a raw APDU.
128
- * `receive`: receive a response ADPU.
132
+ * `receive`: receive a response APDU.
129
133
  * `exchange`: send a formatted APDU and wait for a response (synchronous).
130
134
  * `exchange_raw`: send a raw APDU and wait for a response (synchronous).
131
135
  * `exchange_async`: send a formatted APDU and give back the control to the caller (asynchronous).
@@ -8,16 +8,16 @@
8
8
  This library aims at reducing the cost of running code on both Speculos emulator
9
9
  or on a real device.
10
10
 
11
- It mainly consists on an interface which is implemented by three backends:
11
+ It mainly consists of an interface which is implemented by three backends:
12
12
 
13
13
  - an emulator-only backend, `SpeculosBackend`, which uses
14
14
  [`SpeculosClient`](https://github.com/LedgerHQ/speculos/blob/master/speculos/client.py)
15
- to run an app on a Speculos emulator. With this backend, APDU can be send directly,
15
+ to run an app on a Speculos emulator. With this backend, APDU can be sent directly,
16
16
  without having to connect a device, start a docker or anything.
17
17
 
18
18
  - two physical backends (although technically they are agnostic, but the
19
19
  `SpeculosClient` is superior with an emulator), `LedgerCommBackend` and
20
- `LedgewWalletbackend`, which use respectively the
20
+ `LedgerWalletBackend`, which use respectively the
21
21
  [`LedgerComm` library](https://github.com/LedgerHQ/ledgercomm) or the
22
22
  [`LedgerWallet` library](https://github.com/LedgerHQ/ledgerctl/) to discuss
23
23
  with a physical device. In these cases, the physical device must be started,
@@ -67,7 +67,7 @@ different backends and that allow to interact with a device (either a real devic
67
67
 
68
68
  * `send`: send a formatted APDU.
69
69
  * `send_raw`: send a raw APDU.
70
- * `receive`: receive a response ADPU.
70
+ * `receive`: receive a response APDU.
71
71
  * `exchange`: send a formatted APDU and wait for a response (synchronous).
72
72
  * `exchange_raw`: send a raw APDU and wait for a response (synchronous).
73
73
  * `exchange_async`: send a formatted APDU and give back the control to the caller (asynchronous).
@@ -2,8 +2,7 @@ The Ragger framework
2
2
  ====================
3
3
 
4
4
  ``Ragger`` is a Python framework which aims at simplifying the test and overall
5
- automatic manipulation of applications running on Ledger devices: NanoS, NanoS+,
6
- NanoX, Stax and Flex.
5
+ automatic manipulation of applications running on Ledger devices.
7
6
 
8
7
  It is composed of a tiny wrapper around other Ledger's libraries which abstract
9
8
  and/or provide access to Ledger's cold wallet, and higher-level classes allowing
@@ -103,7 +103,7 @@ Dealing with UI and user interaction is never simple. Nano devices has only two
103
103
  user physical inputs, through the two buttons, which already allows some
104
104
  elaborate combinations that could be challenging to test automatically.
105
105
 
106
- With the touchable screens of Stax or Flex devices, the number of possibilities
106
+ With the touchable screens devices, the number of possibilities
107
107
  drastically increases.
108
108
 
109
109
  ``Ragger`` embeds tools allowing to ease the development and the maintenance of
@@ -74,6 +74,9 @@ should expect. This is declared with this class:
74
74
 
75
75
  .. autoattribute:: FLEX
76
76
 
77
+ .. autoattribute:: APEX_P
78
+
79
+ .. autoattribute:: APEX_M
77
80
 
78
81
  ``ragger.firmware.touch``
79
82
  ++++++++++++++++++++++++
@@ -429,6 +429,9 @@ Running the tests on specific device is automatically integrated with the
429
429
  - ``--device nanox``,
430
430
  - ``--device nanosp``,
431
431
  - ``--device stax``,
432
+ - ``--device flex``,
433
+ - ``--device apex_p``,
434
+ - ``--device apex_m``,
432
435
  - ``--device all``.
433
436
 
434
437
  This last option can only work with the :class:`SpeculosBackend
@@ -1,6 +1,6 @@
1
1
  .. _tutorial_screen:
2
2
 
3
- Complex UI management - Flex / Stax
3
+ Complex UI management - touchable screen devices
4
4
  ===================================
5
5
 
6
6
  Interacting programmatically with an application tends to be a non-trivial
@@ -16,7 +16,7 @@ specifically about the UI, we saw :ref:`previously
16
16
  to cope with simple physical interactions (like on the Nano devices: only two
17
17
  buttons). But what to do with more complex interfaces?
18
18
 
19
- In particular, interacting with the touch screen devices (Stax or Flex) can be
19
+ In particular, interacting with the touch screen devices can be
20
20
  bothersome. It is hard to track of button positions, pages layouts and such.
21
21
 
22
22
  Study case
@@ -66,7 +66,7 @@ to change some button position, or if higher-level graphic objects (such as
66
66
  the "info" button to the top left -, all this code becomes deprecated.
67
67
 
68
68
 
69
- That's why ``Ragger`` mimics the Flex/Stax SDK graphics library and provides
69
+ That's why ``Ragger`` mimics the SDK graphics library and provides
70
70
  :term:`Layout` and :term:`Use Case` (:term:`Page` will also come soon) classes
71
71
  that keep track of every interactive screen elements and expose meaningful
72
72
  methods to interact with them.
@@ -131,7 +131,7 @@ way than if positions were still necessary:
131
131
  First of all, the buttons may be at the same place, but they don't carry the
132
132
  same purpose, and it is a good idea to reflect that on the code.
133
133
 
134
- Second, if in a future version the Flex/Stax design changes and one of these
134
+ Second, if in a future version the devices design changes and one of these
135
135
  button moves somewhere else on the screen's footer, **the layouts will be
136
136
  updated accordingly** in ``Ragger``, and the ``CancelFooter`` or ``ExitFooter``
137
137
  will still be valid, hence all code using this class remains valid too.
@@ -0,0 +1,5 @@
1
+ # Fake boilerplate application manifest for ragger tests
2
+ [app]
3
+ build_directory = "./"
4
+ sdk = "C"
5
+ devices = ["nanos", "nanos+", "nanox", "stax", "flex", "apex_p"]