ragger 1.39.0__tar.gz → 1.40.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 (166) hide show
  1. {ragger-1.39.0 → ragger-1.40.0}/CHANGELOG.md +7 -0
  2. {ragger-1.39.0/src/ragger.egg-info → ragger-1.40.0}/PKG-INFO +1 -1
  3. {ragger-1.39.0 → ragger-1.40.0}/doc/index.rst +1 -2
  4. {ragger-1.39.0 → ragger-1.40.0}/doc/rationale.rst +1 -1
  5. {ragger-1.39.0 → ragger-1.40.0}/doc/source.rst +3 -0
  6. {ragger-1.39.0 → ragger-1.40.0}/doc/tutorial_conftest.rst +3 -0
  7. {ragger-1.39.0 → ragger-1.40.0}/doc/tutorial_screen.rst +4 -4
  8. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/__version__.py +16 -3
  9. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/firmware/structs.py +2 -0
  10. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/firmware/touch/layouts.py +0 -12
  11. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/firmware/touch/positions.py +151 -15
  12. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/interface.py +10 -2
  13. {ragger-1.39.0 → ragger-1.40.0/src/ragger.egg-info}/PKG-INFO +1 -1
  14. {ragger-1.39.0 → ragger-1.40.0}/.codeql-config.yaml +0 -0
  15. {ragger-1.39.0 → ragger-1.40.0}/.gitattributes +0 -0
  16. {ragger-1.39.0 → ragger-1.40.0}/.github/workflows/build_and_tests.yml +0 -0
  17. {ragger-1.39.0 → ragger-1.40.0}/.github/workflows/codeql-analysis.yml +0 -0
  18. {ragger-1.39.0 → ragger-1.40.0}/.github/workflows/documentation.yml +0 -0
  19. {ragger-1.39.0 → ragger-1.40.0}/.github/workflows/fast-checks.yml +0 -0
  20. {ragger-1.39.0 → ragger-1.40.0}/.github/workflows/force-rebase.yml +0 -0
  21. {ragger-1.39.0 → ragger-1.40.0}/.gitignore +0 -0
  22. {ragger-1.39.0 → ragger-1.40.0}/LICENSE +0 -0
  23. {ragger-1.39.0 → ragger-1.40.0}/MANIFEST.in +0 -0
  24. {ragger-1.39.0 → ragger-1.40.0}/README.md +0 -0
  25. {ragger-1.39.0 → ragger-1.40.0}/doc/Makefile +0 -0
  26. {ragger-1.39.0 → ragger-1.40.0}/doc/_static/layout.css +0 -0
  27. {ragger-1.39.0 → ragger-1.40.0}/doc/_templates/layout.html +0 -0
  28. {ragger-1.39.0 → ragger-1.40.0}/doc/architecture.rst +0 -0
  29. {ragger-1.39.0 → ragger-1.40.0}/doc/conf.py +0 -0
  30. {ragger-1.39.0 → ragger-1.40.0}/doc/faq.rst +0 -0
  31. {ragger-1.39.0 → ragger-1.40.0}/doc/glossary.rst +0 -0
  32. {ragger-1.39.0 → ragger-1.40.0}/doc/images/navigate.draw +0 -0
  33. {ragger-1.39.0 → ragger-1.40.0}/doc/images/navigate.svg +0 -0
  34. {ragger-1.39.0 → ragger-1.40.0}/doc/images/ragger.png +0 -0
  35. {ragger-1.39.0 → ragger-1.40.0}/doc/images/stax_infos.png +0 -0
  36. {ragger-1.39.0 → ragger-1.40.0}/doc/images/stax_welcome.png +0 -0
  37. {ragger-1.39.0 → ragger-1.40.0}/doc/images/usage.draw +0 -0
  38. {ragger-1.39.0 → ragger-1.40.0}/doc/images/usage.svg +0 -0
  39. {ragger-1.39.0 → ragger-1.40.0}/doc/installation.rst +0 -0
  40. {ragger-1.39.0 → ragger-1.40.0}/doc/tutorial.rst +0 -0
  41. {ragger-1.39.0 → ragger-1.40.0}/doc/tutorial_installation.rst +0 -0
  42. {ragger-1.39.0 → ragger-1.40.0}/ledger_app.toml +0 -0
  43. {ragger-1.39.0 → ragger-1.40.0}/pyproject.toml +0 -0
  44. {ragger-1.39.0 → ragger-1.40.0}/setup.cfg +0 -0
  45. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/__init__.py +0 -0
  46. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/backend/__init__.py +0 -0
  47. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/backend/interface.py +0 -0
  48. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/backend/ledgercomm.py +0 -0
  49. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/backend/ledgerwallet.py +0 -0
  50. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/backend/physical_backend.py +0 -0
  51. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/backend/speculos.py +0 -0
  52. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/backend/stub.py +0 -0
  53. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/bip/__init__.py +0 -0
  54. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/bip/path.py +0 -0
  55. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/bip/seed.py +0 -0
  56. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/conftest/__init__.py +0 -0
  57. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/conftest/base_conftest.py +0 -0
  58. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/conftest/configuration.py +0 -0
  59. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/error.py +0 -0
  60. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/firmware/__init__.py +0 -0
  61. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/firmware/touch/__init__.py +0 -0
  62. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/firmware/touch/element.py +0 -0
  63. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/firmware/touch/screen.py +0 -0
  64. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/firmware/touch/use_cases.py +0 -0
  65. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/__init__.py +0 -0
  66. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/nanos_body.png +0 -0
  67. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/nanos_leftbutton.png +0 -0
  68. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/nanos_rightbutton.png +0 -0
  69. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/nanosp_body.png +0 -0
  70. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/nanosp_leftbutton.png +0 -0
  71. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/nanosp_rightbutton.png +0 -0
  72. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/nanox_body.png +0 -0
  73. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/nanox_leftbutton.png +0 -0
  74. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/nanox_rightbutton.png +0 -0
  75. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/stax_body.png +0 -0
  76. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/swipe_left_action.png +0 -0
  77. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/swipe_right_action.png +0 -0
  78. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/assets/touch_action.png +0 -0
  79. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/gui/process.py +0 -0
  80. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/logger.py +0 -0
  81. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/navigator/__init__.py +0 -0
  82. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/navigator/instruction.py +0 -0
  83. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/navigator/nano_navigator.py +0 -0
  84. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/navigator/navigation_scenario.py +0 -0
  85. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/navigator/navigator.py +0 -0
  86. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/navigator/touch_navigator.py +0 -0
  87. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/py.typed +0 -0
  88. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/utils/__init__.py +0 -0
  89. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/utils/misc.py +0 -0
  90. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/utils/packing.py +0 -0
  91. {ragger-1.39.0 → ragger-1.40.0}/src/ragger/utils/structs.py +0 -0
  92. {ragger-1.39.0 → ragger-1.40.0}/src/ragger.egg-info/SOURCES.txt +0 -0
  93. {ragger-1.39.0 → ragger-1.40.0}/src/ragger.egg-info/dependency_links.txt +0 -0
  94. {ragger-1.39.0 → ragger-1.40.0}/src/ragger.egg-info/requires.txt +0 -0
  95. {ragger-1.39.0 → ragger-1.40.0}/src/ragger.egg-info/top_level.txt +0 -0
  96. {ragger-1.39.0 → ragger-1.40.0}/template/.dispatch_to_your_test_folder +0 -0
  97. {ragger-1.39.0 → ragger-1.40.0}/template/conftest.py +0 -0
  98. {ragger-1.39.0 → ragger-1.40.0}/template/usage.md +0 -0
  99. {ragger-1.39.0 → ragger-1.40.0}/tests/__init__.py +0 -0
  100. {ragger-1.39.0 → ragger-1.40.0}/tests/functional/__init__.py +0 -0
  101. {ragger-1.39.0 → ragger-1.40.0}/tests/functional/backend/__init__.py +0 -0
  102. {ragger-1.39.0 → ragger-1.40.0}/tests/functional/backend/test_speculos.py +0 -0
  103. {ragger-1.39.0 → ragger-1.40.0}/tests/functional/conftest.py +0 -0
  104. {ragger-1.39.0 → ragger-1.40.0}/tests/functional/navigator/__init__.py +0 -0
  105. {ragger-1.39.0 → ragger-1.40.0}/tests/functional/navigator/test_navigator.py +0 -0
  106. {ragger-1.39.0 → ragger-1.40.0}/tests/functional/test_boilerplate.py +0 -0
  107. {ragger-1.39.0 → ragger-1.40.0}/tests/pytest.ini +0 -0
  108. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/flex/waiting_screen/00000.png +0 -0
  109. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/flex/waiting_screen/00001.png +0 -0
  110. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/flex/waiting_screen/00002.png +0 -0
  111. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/flex/waiting_screen/00003.png +0 -0
  112. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/flex/waiting_screen/00004.png +0 -0
  113. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/generic/00000.png +0 -0
  114. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/generic/00001.png +0 -0
  115. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/generic/00002.png +0 -0
  116. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/generic/00003.png +0 -0
  117. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/generic/00004.png +0 -0
  118. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_and_compare/00000.png +0 -0
  119. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_and_compare/00001.png +0 -0
  120. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_and_compare/00002.png +0 -0
  121. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_and_compare/00003.png +0 -0
  122. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_and_compare/00004.png +0 -0
  123. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_and_compare/00005.png +0 -0
  124. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_and_compare/00006.png +0 -0
  125. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_and_compare/00007.png +0 -0
  126. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_and_compare_no_golden/00000.png +0 -0
  127. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_and_compare_wrong_golden/00000.png +0 -0
  128. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_and_compare_wrong_golden/00001.png +0 -0
  129. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_until_text_and_compare/00000.png +0 -0
  130. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_until_text_and_compare/00001.png +0 -0
  131. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_until_text_and_compare/00002.png +0 -0
  132. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/nanos/test_navigate_until_text_and_compare/00003.png +0 -0
  133. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/stax/waiting_screen/00000.png +0 -0
  134. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/stax/waiting_screen/00001.png +0 -0
  135. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/stax/waiting_screen/00002.png +0 -0
  136. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/stax/waiting_screen/00003.png +0 -0
  137. {ragger-1.39.0 → ragger-1.40.0}/tests/snapshots/stax/waiting_screen/00004.png +0 -0
  138. {ragger-1.39.0 → ragger-1.40.0}/tests/stubs.py +0 -0
  139. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/__init__.py +0 -0
  140. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/backend/__init__.py +0 -0
  141. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/backend/test_interface.py +0 -0
  142. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/backend/test_ledgercomm.py +0 -0
  143. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/backend/test_ledgerwallet.py +0 -0
  144. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/backend/test_physical_backend.py +0 -0
  145. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/backend/test_speculos.py +0 -0
  146. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/backend/test_stub.py +0 -0
  147. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/bip/test_path.py +0 -0
  148. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/bip/test_seed.py +0 -0
  149. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/conftests/__init__.py +0 -0
  150. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/conftests/test_base_conftest.py +0 -0
  151. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/firmware/test_structs_Firmware.py +0 -0
  152. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/firmware/touch/test_element.py +0 -0
  153. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/firmware/touch/test_screen_FullScreen.py +0 -0
  154. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/firmware/touch/test_screen_MetaScreen.py +0 -0
  155. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/helpers.py +0 -0
  156. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/navigator/__init__.py +0 -0
  157. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/navigator/test_nano_navigator.py +0 -0
  158. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/navigator/test_navigation_scenario.py +0 -0
  159. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/navigator/test_navigator.py +0 -0
  160. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/navigator/test_touch_navigator.py +0 -0
  161. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/test_error_ApplicationError.py +0 -0
  162. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/utils/__init__.py +0 -0
  163. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/utils/test_misc.py +0 -0
  164. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/utils/test_packing.py +0 -0
  165. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/utils/test_path.py +0 -0
  166. {ragger-1.39.0 → ragger-1.40.0}/tests/unit/utils/test_structs.py +0 -0
@@ -5,6 +5,12 @@ 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.40.0] - 2025-08-01
9
+
10
+ ### Added
11
+
12
+ - Add two new devices: Apex_p and Apex_m
13
+
8
14
  ## [1.39.0] - 2025-07-22
9
15
 
10
16
  ### Added
@@ -48,6 +54,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
48
54
  ### Changed
49
55
 
50
56
  - Enable to use both MAIN_APP_DIR and SIDELOADED_APPS options (required to perform Swap tests)
57
+
51
58
 
52
59
  ## [1.35.0] - 2025-05-14
53
60
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ragger
3
- Version: 1.39.0
3
+ Version: 1.40.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
@@ -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.
@@ -1,7 +1,14 @@
1
1
  # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
3
 
4
- __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
4
+ __all__ = [
5
+ "__version__",
6
+ "__version_tuple__",
7
+ "version",
8
+ "version_tuple",
9
+ "__commit_id__",
10
+ "commit_id",
11
+ ]
5
12
 
6
13
  TYPE_CHECKING = False
7
14
  if TYPE_CHECKING:
@@ -9,13 +16,19 @@ if TYPE_CHECKING:
9
16
  from typing import Union
10
17
 
11
18
  VERSION_TUPLE = Tuple[Union[int, str], ...]
19
+ COMMIT_ID = Union[str, None]
12
20
  else:
13
21
  VERSION_TUPLE = object
22
+ COMMIT_ID = object
14
23
 
15
24
  version: str
16
25
  __version__: str
17
26
  __version_tuple__: VERSION_TUPLE
18
27
  version_tuple: VERSION_TUPLE
28
+ commit_id: COMMIT_ID
29
+ __commit_id__: COMMIT_ID
19
30
 
20
- __version__ = version = '1.39.0'
21
- __version_tuple__ = version_tuple = (1, 39, 0)
31
+ __version__ = version = '1.40.0'
32
+ __version_tuple__ = version_tuple = (1, 40, 0)
33
+
34
+ __commit_id__ = commit_id = 'g3d7c1dd19'
@@ -28,6 +28,8 @@ class Firmware(IntEnum):
28
28
  NANOX = DeviceType.NANOX
29
29
  STAX = DeviceType.STAX
30
30
  FLEX = DeviceType.FLEX
31
+ APEX_P = DeviceType.APEX_P
32
+ APEX_M = DeviceType.APEX_M
31
33
 
32
34
  @staticmethod
33
35
  def deprec_warning() -> None:
@@ -88,18 +88,6 @@ class TappableCenter(_TappableElement):
88
88
  pass
89
89
 
90
90
 
91
- class KeyboardConfirmationButton(Element):
92
- """
93
- This layout is to be used as the confirmation button when coupled with a keyboard.
94
-
95
- On Stax devices, the screen is high enough that this is equivalent to TappableCenter, however
96
- on Flex, this button is not centered, but slightly closer to the top of the screen.
97
- """
98
-
99
- def confirm(self):
100
- self.client.finger_touch(*self.positions)
101
-
102
-
103
91
  # Headers
104
92
  #########
105
93
  class RightHeader(_TappableElement):
@@ -28,42 +28,62 @@ class Position:
28
28
 
29
29
  _stax_res: Resolution = Devices.get_by_type(DeviceType.STAX).resolution
30
30
  _flex_res: Resolution = Devices.get_by_type(DeviceType.FLEX).resolution
31
+ _apex_p_res: Resolution = Devices.get_by_type(DeviceType.APEX_P).resolution
32
+ _apex_m_res: Resolution = Devices.get_by_type(DeviceType.APEX_M).resolution
31
33
 
32
34
  # Floor division '//' required, else the result will be a float, which can lead to issues when
33
35
  # using Speculos, which performs actions such as `var.to_bytes()` which does not work with a float.
34
36
  STAX_X_CENTER = _stax_res.x // 2
35
37
  FLEX_X_CENTER = _flex_res.x // 2
38
+ APEX_P_X_CENTER = _apex_p_res.x // 2
39
+ APEX_M_X_CENTER = _apex_m_res.x // 2
36
40
 
37
41
  STAX_CENTER = Position(STAX_X_CENTER, _stax_res.y // 2)
38
42
  FLEX_CENTER = Position(FLEX_X_CENTER, _flex_res.y // 2)
39
-
40
- STAX_BUTTON_UPPER_CENTER_MIDDLE = Position(STAX_X_CENTER, 280)
41
- FLEX_BUTTON_UPPER_CENTER_MIDDLE = Position(FLEX_X_CENTER, 250)
43
+ APEX_P_CENTER = Position(APEX_P_X_CENTER, _apex_p_res.y // 2)
44
+ APEX_M_CENTER = Position(APEX_M_X_CENTER, _apex_m_res.y // 2)
42
45
 
43
46
  STAX_BUTTON_UPPER_LEFT = Position(36, 36)
44
47
  FLEX_BUTTON_UPPER_LEFT = Position(45, 45)
48
+ APEX_P_BUTTON_UPPER_LEFT = Position(30, 30)
49
+ APEX_M_BUTTON_UPPER_LEFT = Position(30, 30)
45
50
 
46
51
  STAX_BUTTON_UPPER_RIGHT = Position(342, 55)
47
52
  FLEX_BUTTON_UPPER_RIGHT = Position(405, 75)
53
+ APEX_P_BUTTON_UPPER_RIGHT = Position(256, 43)
54
+ APEX_M_BUTTON_UPPER_RIGHT = Position(256, 43)
48
55
 
49
56
  STAX_BUTTON_LOWER_LEFT = Position(36, 606)
50
57
  FLEX_BUTTON_LOWER_LEFT = Position(55, 530)
58
+ APEX_P_BUTTON_LOWER_LEFT = Position(56, 370)
59
+ APEX_M_BUTTON_LOWER_LEFT = Position(56, 370)
51
60
 
52
61
  STAX_BUTTON_LOWER_MIDDLE = Position(STAX_X_CENTER, 606)
53
62
  FLEX_BUTTON_LOWER_MIDDLE = Position(FLEX_X_CENTER, 550)
63
+ APEX_P_BUTTON_LOWER_MIDDLE = Position(APEX_P_X_CENTER, 370)
64
+ APEX_M_BUTTON_LOWER_MIDDLE = Position(APEX_M_X_CENTER, 370)
54
65
 
55
66
  STAX_BUTTON_LOWER_RIGHT = Position(342, 606)
56
67
  FLEX_BUTTON_LOWER_RIGHT = Position(430, 550)
68
+ APEX_P_BUTTON_LOWER_RIGHT = Position(270, 370)
69
+ APEX_M_BUTTON_LOWER_RIGHT = Position(270, 370)
70
+
57
71
  STAX_BUTTON_LOWER_MIDDLE_RIGHT = Position(266, 615)
58
72
  FLEX_BUTTON_LOWER_MIDDLE_RIGHT = Position(320, 550)
73
+ APEX_P_BUTTON_LOWER_MIDDLE_RIGHT = Position(207, 370)
74
+ APEX_M_BUTTON_LOWER_MIDDLE_RIGHT = Position(207, 370)
59
75
 
60
- STAX_BUTTON_ABOVE_LOWER_MIDDLE = Position(200, 515)
61
- FLEX_BUTTON_ABOVE_LOWER_MIDDLE = Position(240, 435)
76
+ STAX_BUTTON_ABOVE_LOWER_MIDDLE = Position(STAX_X_CENTER, 515)
77
+ FLEX_BUTTON_ABOVE_LOWER_MIDDLE = Position(FLEX_X_CENTER, 435)
78
+ APEX_P_BUTTON_ABOVE_LOWER_MIDDLE = Position(APEX_P_X_CENTER, 312)
79
+ APEX_M_BUTTON_ABOVE_LOWER_MIDDLE = Position(APEX_M_X_CENTER, 312)
62
80
 
63
81
  POSITIONS = {
64
82
  "Center": {
65
83
  DeviceType.STAX: STAX_CENTER,
66
84
  DeviceType.FLEX: FLEX_CENTER,
85
+ DeviceType.APEX_P: APEX_P_CENTER,
86
+ DeviceType.APEX_M: APEX_M_CENTER,
67
87
  },
68
88
  "ChoiceList": {
69
89
  DeviceType.STAX: {
@@ -81,7 +101,23 @@ POSITIONS = {
81
101
  3: Position(FLEX_X_CENTER, 330),
82
102
  4: Position(FLEX_X_CENTER, 420),
83
103
  5: Position(FLEX_X_CENTER, 510),
84
- }
104
+ },
105
+ DeviceType.APEX_P: {
106
+ # Up to 5 choices in a list
107
+ 1: Position(APEX_P_X_CENTER, 90),
108
+ 2: Position(APEX_P_X_CENTER, 160),
109
+ 3: Position(APEX_P_X_CENTER, 230),
110
+ 4: Position(APEX_P_X_CENTER, 300),
111
+ 5: Position(APEX_P_X_CENTER, 370),
112
+ },
113
+ DeviceType.APEX_M: {
114
+ # Up to 5 choices in a list
115
+ 1: Position(APEX_M_X_CENTER, 90),
116
+ 2: Position(APEX_M_X_CENTER, 160),
117
+ 3: Position(APEX_M_X_CENTER, 230),
118
+ 4: Position(APEX_M_X_CENTER, 300),
119
+ 5: Position(APEX_M_X_CENTER, 370),
120
+ },
85
121
  },
86
122
  "Suggestions": {
87
123
  DeviceType.STAX: {
@@ -382,30 +418,38 @@ POSITIONS = {
382
418
  "TappableCenter": {
383
419
  DeviceType.STAX: STAX_CENTER,
384
420
  DeviceType.FLEX: FLEX_CENTER,
385
- },
386
- "KeyboardConfirmationButton": {
387
- DeviceType.STAX: STAX_BUTTON_UPPER_CENTER_MIDDLE,
388
- DeviceType.FLEX: FLEX_BUTTON_UPPER_CENTER_MIDDLE,
421
+ DeviceType.APEX_P: APEX_P_CENTER,
422
+ DeviceType.APEX_M: APEX_M_CENTER
389
423
  },
390
424
  "RightHeader": {
391
425
  DeviceType.STAX: STAX_BUTTON_UPPER_RIGHT,
392
- DeviceType.FLEX: FLEX_BUTTON_UPPER_RIGHT
426
+ DeviceType.FLEX: FLEX_BUTTON_UPPER_RIGHT,
427
+ DeviceType.APEX_P: APEX_P_BUTTON_UPPER_RIGHT,
428
+ DeviceType.APEX_M: APEX_M_BUTTON_UPPER_RIGHT
393
429
  },
394
430
  "LeftHeader": {
395
431
  DeviceType.STAX: STAX_BUTTON_UPPER_LEFT,
396
- DeviceType.FLEX: FLEX_BUTTON_UPPER_LEFT
432
+ DeviceType.FLEX: FLEX_BUTTON_UPPER_LEFT,
433
+ DeviceType.APEX_P: APEX_P_BUTTON_UPPER_LEFT,
434
+ DeviceType.APEX_M: APEX_M_BUTTON_UPPER_LEFT
397
435
  },
398
436
  "CenteredFooter": {
399
437
  DeviceType.STAX: STAX_BUTTON_LOWER_MIDDLE,
400
- DeviceType.FLEX: FLEX_BUTTON_LOWER_MIDDLE
438
+ DeviceType.FLEX: FLEX_BUTTON_LOWER_MIDDLE,
439
+ DeviceType.APEX_P: APEX_P_BUTTON_LOWER_MIDDLE,
440
+ DeviceType.APEX_M: APEX_M_BUTTON_LOWER_MIDDLE
401
441
  },
402
442
  "LeftFooter": {
403
443
  DeviceType.STAX: STAX_BUTTON_LOWER_LEFT,
404
- DeviceType.FLEX: FLEX_BUTTON_LOWER_LEFT
444
+ DeviceType.FLEX: FLEX_BUTTON_LOWER_LEFT,
445
+ DeviceType.APEX_P: APEX_P_BUTTON_LOWER_LEFT,
446
+ DeviceType.APEX_M: APEX_M_BUTTON_LOWER_LEFT
405
447
  },
406
448
  "CancelFooter": {
407
449
  DeviceType.STAX: STAX_BUTTON_LOWER_LEFT,
408
- DeviceType.FLEX: FLEX_BUTTON_LOWER_LEFT
450
+ DeviceType.FLEX: FLEX_BUTTON_LOWER_LEFT,
451
+ DeviceType.APEX_P: APEX_P_BUTTON_LOWER_LEFT,
452
+ DeviceType.APEX_M: APEX_M_BUTTON_LOWER_LEFT
409
453
  },
410
454
  "UseCaseHome": {
411
455
  DeviceType.STAX: {
@@ -417,6 +461,16 @@ POSITIONS = {
417
461
  "info": FLEX_BUTTON_UPPER_RIGHT,
418
462
  "settings": FLEX_BUTTON_UPPER_RIGHT,
419
463
  "quit": FLEX_BUTTON_LOWER_MIDDLE
464
+ },
465
+ DeviceType.APEX_P: {
466
+ "info": APEX_P_BUTTON_UPPER_RIGHT,
467
+ "settings": APEX_P_BUTTON_UPPER_RIGHT,
468
+ "quit": APEX_P_BUTTON_LOWER_MIDDLE
469
+ },
470
+ DeviceType.APEX_M: {
471
+ "info": APEX_M_BUTTON_UPPER_RIGHT,
472
+ "settings": APEX_M_BUTTON_UPPER_RIGHT,
473
+ "quit": APEX_M_BUTTON_LOWER_MIDDLE
420
474
  }
421
475
  },
422
476
  "UseCaseHomeExt": {
@@ -431,6 +485,18 @@ POSITIONS = {
431
485
  "settings": FLEX_BUTTON_UPPER_RIGHT,
432
486
  "action": FLEX_BUTTON_ABOVE_LOWER_MIDDLE,
433
487
  "quit": FLEX_BUTTON_LOWER_MIDDLE
488
+ },
489
+ DeviceType.APEX_P: {
490
+ "info": APEX_P_BUTTON_UPPER_RIGHT,
491
+ "settings": APEX_P_BUTTON_UPPER_RIGHT,
492
+ "action": APEX_P_BUTTON_ABOVE_LOWER_MIDDLE,
493
+ "quit": APEX_P_BUTTON_LOWER_MIDDLE
494
+ },
495
+ DeviceType.APEX_M: {
496
+ "info": APEX_M_BUTTON_UPPER_RIGHT,
497
+ "settings": APEX_M_BUTTON_UPPER_RIGHT,
498
+ "action": APEX_M_BUTTON_ABOVE_LOWER_MIDDLE,
499
+ "quit": APEX_M_BUTTON_LOWER_MIDDLE
434
500
  }
435
501
  },
436
502
  "UseCaseSettings": {
@@ -445,6 +511,18 @@ POSITIONS = {
445
511
  "multi_page_exit": FLEX_BUTTON_UPPER_LEFT,
446
512
  "previous": FLEX_BUTTON_LOWER_MIDDLE_RIGHT,
447
513
  "next": FLEX_BUTTON_LOWER_RIGHT,
514
+ },
515
+ DeviceType.APEX_P: {
516
+ "single_page_exit": APEX_P_BUTTON_UPPER_LEFT,
517
+ "multi_page_exit": APEX_P_BUTTON_UPPER_LEFT,
518
+ "previous": APEX_P_BUTTON_LOWER_MIDDLE_RIGHT,
519
+ "next": APEX_P_BUTTON_LOWER_RIGHT,
520
+ },
521
+ DeviceType.APEX_M: {
522
+ "single_page_exit": APEX_M_BUTTON_UPPER_LEFT,
523
+ "multi_page_exit": APEX_M_BUTTON_UPPER_LEFT,
524
+ "previous": APEX_M_BUTTON_LOWER_MIDDLE_RIGHT,
525
+ "next": APEX_M_BUTTON_LOWER_RIGHT,
448
526
  }
449
527
  },
450
528
  "UseCaseSubSettings": {
@@ -457,6 +535,16 @@ POSITIONS = {
457
535
  "exit": FLEX_BUTTON_UPPER_LEFT,
458
536
  "previous": FLEX_BUTTON_LOWER_LEFT,
459
537
  "next": FLEX_BUTTON_LOWER_RIGHT,
538
+ },
539
+ DeviceType.APEX_P: {
540
+ "exit": APEX_P_BUTTON_UPPER_LEFT,
541
+ "previous": APEX_P_BUTTON_LOWER_LEFT,
542
+ "next": APEX_P_BUTTON_LOWER_RIGHT,
543
+ },
544
+ DeviceType.APEX_M: {
545
+ "exit": APEX_M_BUTTON_UPPER_LEFT,
546
+ "previous": APEX_M_BUTTON_LOWER_LEFT,
547
+ "next": APEX_M_BUTTON_LOWER_RIGHT,
460
548
  }
461
549
  },
462
550
  "UseCaseChoice": {
@@ -467,6 +555,14 @@ POSITIONS = {
467
555
  DeviceType.FLEX: {
468
556
  "confirm": FLEX_BUTTON_ABOVE_LOWER_MIDDLE,
469
557
  "reject": FLEX_BUTTON_LOWER_LEFT,
558
+ },
559
+ DeviceType.APEX_P: {
560
+ "confirm": APEX_P_BUTTON_ABOVE_LOWER_MIDDLE,
561
+ "reject": APEX_P_BUTTON_LOWER_LEFT,
562
+ },
563
+ DeviceType.APEX_M: {
564
+ "confirm": APEX_M_BUTTON_ABOVE_LOWER_MIDDLE,
565
+ "reject": APEX_M_BUTTON_LOWER_LEFT,
470
566
  }
471
567
  },
472
568
  "UseCaseStatus": {
@@ -475,6 +571,12 @@ POSITIONS = {
475
571
  },
476
572
  DeviceType.FLEX: {
477
573
  "dismiss": FLEX_CENTER,
574
+ },
575
+ DeviceType.APEX_P: {
576
+ "dismiss": APEX_P_CENTER,
577
+ },
578
+ DeviceType.APEX_M: {
579
+ "dismiss": APEX_M_CENTER,
478
580
  }
479
581
  },
480
582
  "UseCaseReview": {
@@ -489,6 +591,18 @@ POSITIONS = {
489
591
  "previous": FLEX_BUTTON_LOWER_MIDDLE,
490
592
  "confirm": FLEX_BUTTON_ABOVE_LOWER_MIDDLE,
491
593
  "reject": FLEX_BUTTON_LOWER_LEFT,
594
+ },
595
+ DeviceType.APEX_P: {
596
+ "tap": APEX_P_BUTTON_LOWER_RIGHT,
597
+ "previous": APEX_P_BUTTON_LOWER_MIDDLE,
598
+ "confirm": APEX_P_BUTTON_ABOVE_LOWER_MIDDLE,
599
+ "reject": APEX_P_BUTTON_LOWER_LEFT,
600
+ },
601
+ DeviceType.APEX_M: {
602
+ "tap": APEX_M_BUTTON_LOWER_RIGHT,
603
+ "previous": APEX_M_BUTTON_LOWER_MIDDLE,
604
+ "confirm": APEX_M_BUTTON_ABOVE_LOWER_MIDDLE,
605
+ "reject": APEX_M_BUTTON_LOWER_LEFT,
492
606
  }
493
607
  },
494
608
  "UseCaseViewDetails": {
@@ -501,6 +615,16 @@ POSITIONS = {
501
615
  "exit": FLEX_BUTTON_LOWER_LEFT,
502
616
  "previous": FLEX_BUTTON_LOWER_MIDDLE,
503
617
  "next": FLEX_BUTTON_LOWER_RIGHT,
618
+ },
619
+ DeviceType.APEX_P: {
620
+ "exit": APEX_P_BUTTON_LOWER_LEFT,
621
+ "previous": APEX_P_BUTTON_LOWER_MIDDLE,
622
+ "next": APEX_P_BUTTON_LOWER_RIGHT,
623
+ },
624
+ DeviceType.APEX_M: {
625
+ "exit": APEX_M_BUTTON_LOWER_LEFT,
626
+ "previous": APEX_M_BUTTON_LOWER_MIDDLE,
627
+ "next": APEX_M_BUTTON_LOWER_RIGHT,
504
628
  }
505
629
  },
506
630
  "UseCaseAddressConfirmation": {
@@ -515,6 +639,18 @@ POSITIONS = {
515
639
  "exit_qr": FLEX_BUTTON_LOWER_MIDDLE,
516
640
  "confirm": FLEX_BUTTON_ABOVE_LOWER_MIDDLE,
517
641
  "cancel": FLEX_BUTTON_LOWER_LEFT,
642
+ },
643
+ DeviceType.APEX_P: {
644
+ "tap": APEX_P_BUTTON_ABOVE_LOWER_MIDDLE,
645
+ "exit_qr": APEX_P_BUTTON_LOWER_MIDDLE,
646
+ "confirm": APEX_P_BUTTON_ABOVE_LOWER_MIDDLE,
647
+ "cancel": APEX_P_BUTTON_LOWER_LEFT,
648
+ },
649
+ DeviceType.APEX_M: {
650
+ "tap": APEX_M_BUTTON_ABOVE_LOWER_MIDDLE,
651
+ "exit_qr": APEX_M_BUTTON_LOWER_MIDDLE,
652
+ "confirm": APEX_M_BUTTON_ABOVE_LOWER_MIDDLE,
653
+ "cancel": APEX_M_BUTTON_LOWER_LEFT,
518
654
  }
519
655
  },
520
656
  }
@@ -79,7 +79,15 @@ class RaggerMainWindow(QMainWindow):
79
79
  self._screenshot.setObjectName("screenshot")
80
80
  self._screenshot.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
81
81
  self._screenshot.setAlignment(Qt.AlignmentFlag.AlignVCenter)
82
- dict_margin = {"nanos": 75, "nanox": 90, "nanosp": 55, "stax": 65, "flex": 65}
82
+ dict_margin = {
83
+ "nanos": 75,
84
+ "nanox": 90,
85
+ "nanosp": 55,
86
+ "stax": 65,
87
+ "flex": 65,
88
+ "apex_p": 65,
89
+ "apex_m": 65
90
+ }
83
91
  margin = dict_margin[self._device]
84
92
  self._screenshot.setStyleSheet(f"QLabel {{margin-left: {margin}px;}}")
85
93
 
@@ -233,7 +241,7 @@ class RaggerMainWindow(QMainWindow):
233
241
  self._init_screenshot()
234
242
  self._init_validation_buttons()
235
243
 
236
- if self._device in ["stax", "flex"]:
244
+ if self._device in ["stax", "flex", "apex_p", "apex_m"]:
237
245
  self._devicebody.raise_()
238
246
  self._touch.raise_()
239
247
  self._swipe_left.raise_()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ragger
3
- Version: 1.39.0
3
+ Version: 1.40.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
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