Rationale
Testing, easily manipulating a Ledger application is hard. Although Speculos strongly eases it, it cannot always replace IRL tests on physical devices.
There are libraries allowing to communicate with a physical device. However, it would be very convenient to be able to develop code which would be compatible wherever the application runs, either on an emulator or on a physical device.
On top of this, all these libraries provides low-level functions like pressing a button or sending APDUs. Applications can be complex pieces of software and testing one require higher-level code.
Abstracting the backends
The original goal of Ragger
is to make the manipulation of an
application oblivious of the underlying device. Most applications are
tested against Speculos, the Ledger device emulator, but it is not
always enough, and testing on real physical devices is often required.
Ragger
provides an interface which wraps several libraries:
one emulator-only library: Speculos (which uses itself as an emulator),
two agnostic libraries, which can communicate with either a physical device, or an emulated one:
In Ragger
, the classes embedding these libraries are called
backends. Any other backend can be added, given it respects the
BackendInterface
interface.
Application clients using Ragger
must comply with this
interface to communicate with the application. Once it’s done, the client
can communicate with an application running either on top of an emulator or on
a real, physical device with very little cost.
Why not no cost? That’s because the backend actually needs to talk to something. Speculos is conveniently able to start its emulator itself, however the other backends will need the application to be already started. Typically, the application will have to be installed on a physical device, started, and the device connected to the computer launching the client.
How to exploit these capabilities to write test running on both emulated or physical device is documented in the tutorial section.
Easing the development of application clients
On top of abstracting the backend, Ragger
provides tools and mechanisms
allowing to ease the development of application clients and write more thorough
tests.
Touch screen management
Dealing with UI and user interaction is never simple. Nano devices has only two user physical inputs, through the two buttons, which already allows some elaborate combinations that could be challenging to test automatically.
With the touchable screens of Stax or Flex devices, the number of possibilities drastically increases.
Ragger
embeds tools allowing to ease the development and the maintenance of
UI clients. this tools mainly consist of 3 components:
the
layout classes
, representing the layouts proposed in the NBGL section of the C SDK,the
use cases classes
, representing the use cases proposed in the NBGL section of the C SDK,the
screen module
, allowing to nest the previous components in a single, centralized object.
Note
If you are familiar with the NBGL library, you will notice that
Ragger
does not implement a Page representation. It will be
integrated eventually.
These components bring multiple benefits:
these abstractions prevent to directly use
(X, Y)
coordinates to interact with the screen and propose higher-level methods (for instance, when using theUseCaseHome
use case, going to the settings is triggered with the methodUseCaseHome.settings()
instead of touching the screen at(342, 55)
). The client’s code is meaningful.Ragger
internally keeps track of these positions on every SDK version. If a new SDK version moves a button to other coordinates, the code written with theRagger
components will stay valid and functional.the layouts and use cases mimic the NBGL capabilities, so that the
Ragger
client screen architecture is close to the application one.the
FullScreen
class embeds every existinglayout
anduse case
in a single class, providing a fast way of testing an interface without any other configuration.the
MetaScreen
metaclass allows to build custom screen classes nesting thelayouts
and theuse cases
of your choosing, creating a convenient and meaningful screen object where all UI interactions are centralized.
You can find example of these components in this tutorial.