Scripting: Basic Scripting Info - nomovok-opensource/cutedriver-agent_qt GitHub Wiki

Running an application with scripts

Script initialization and Application Startup

The basic initialization of a cuTeDriver Ruby-script contains the following:

NOTE: For API compatibility cuTeDriver has not changed the API namings from TDriver to cuTeDriver.

require 'tdriver'

## Initialize SUT`
## Remember to use correct SUT name, as defined for the SUT you want to test  `
sut = TDriver.sut(:SUT_NAME)`

The first part includes the TDriver gems, while the second initializes the SUT. Note, that "SUT_NAME" corresponds to the name of the SUT you have specified in TDriver's XML file.

Once the script has been initialized, you can remotely start the application on SUT using:

# Start Application
# :name specifiec name of executable that is seen by qttas-server
# :start_command specifies the start command used
app = sut.run(:name => 'APPLICATION_NAME', :start_command => 'APPLICATION_BINARY -testability')

Here the parameters are as follows:

  • APPLICATION_NAME: The name of the application started by invoker, this needs to correspond to what is seen by qttas_ui / ps, otherwise the connection between Host and the started application will fail.
  • APPLICATION_BINARY: Absolute path to application executable, without environment variables.

NOTE: For QML applications (or other applications using QGuiApplication), the testability library needs to be correctly loaded. QApplication does the loading automatically, so regular Qt applications and QML applications using QApplication do not need to do this. If you are using invoker with QML, then it will also handle this automatically for you.

Once an application is started, it is best to let it fully boot up before interacting with UI:

# Sleep for 4 seconds to wait for application to be fully loaded
sleep(4)

However, signal fixture can also be used to verify that application is fully operational after the application launch. Signal fixture can also be utilized to avoid any predetermined sleeps in any ui interactions as there are usually a set of signals emitted at the start, during and at the end of any ui action.

Interacting with Elements

Interacting based on object name

You can interact with any named UI elements via cuTeDriver script. You can check current object naming via cuTeDriver Visualizer, and instructions for adding object-naming can be found further on this page.

Any element can be located based on name, by searching for it from the main application element (created when starting the application):
app.child( :name => 'OBJECT_NAME' )

Once you've located an element, you can start interacting with it through the available functions.

For example, to tap an object:
app.child( :name => 'OBJECT_NAME' ).tap

Or to send an upwards swipe to an object with speed 5 and distance of 500px:
app.child( :name => 'OBJECT_NAME' ).gesture(:Up,5,200)

If the object is of a basic QML type, then searching will be a bit faster when specifying the type for the search. For example, for a Flickable element:
app.QQuickFlickable( :name => 'OBJECT_NAME' ).tap

The types can be checked through Visualizer. For custom defined types, this is not possible as the types will be randomly numbered during creation.

Interacting based on position

If you do not have object naming in place, but rather want to interact with elements based on their position, it is best to send the corresponding events to the root UI element of your application. Events sent to it are propagated further down to it's child elements.

Coordinates of various elements can be checked using Visualizer and by checking the lower left corner of Visualizer UI for the coordinates of the position hovered.

So, to send a tap to screen coordinates X, Y you can use:

# Send tap to (x,y) coordinates
app.child( :name => 'rootObjectName' ).tap_object(X,Y)
sleep(2)

Similarly, a gesture can be sent via:

# Send flick to (x,y) coordinates
app.child( :name => 'rootObjectName' ).gesture_from(X,Y,SPEED,DISTANCE,DIRECTION)
sleep(4)
  • rootObjectName: The name set for your UIs root object
  • X,Y: Coordinates in int
  • SPEED: Speed
  • DISTANCE: Distance in pixels
  • DIRECTION: One of :Up, :Down, :Left, :Right, or angle

Waiting for interaction to finish

Since locating of objects by searching and interaction in general can be a bit slow, one should always allow for time for the UI to execute the instructions, by adding sufficient sleep intervals between commands. For example, if we want to wait 2 seconds after performing the tap:

app.child( :name => 'OBJECT_NAME' ).tap
sleep(2)

One should wait around 2 seconds after a tap, and a slightly longer time after more complex instructions.

Further reading

cuTeDriver is quite a complex tool for remote execution, a full explanation is not provided here, but we will soon make the original (somewhat outdated) API documentation available.

Closing application after script interaction has been done

After the script has performed the desired steps, it should close the application on the device:

# Close the application
app.close