Android User Actions III – Dragging
Dragging is like swiping except that the touch isn’t released after the user presses the screen and moves to a new location. Both the Device object and mobile objects (views, layouts, etc.) have their own Drag() methods:
Mobile.Device().Drag(startX, startY, endX, endY); Aliases.ScrollView.Drag(startX, startY, distanceX, distanceY);
Watch out for the last two parameters. Mobile objects use distances along the X and Y axis, but the device object uses an absolute ending X and Y coordinate. Using the device Drag() method, you can drag from the bottom of a view area (using its height), to the top Y coordinate of the view. In the case of mobile objects, the last parameter moves a distance along the Y axis. Positive numbers move downward from the starting point; negative numbers move upward. The coordinates are relative to the control. The example below is using the Driven Gallery sample project that ships with TestComplete.
function dragExample(){ TestedApps.DrivenGallery.Run(); Mobile.SetCurrent(Project.Variables.MyAndroidDevice); // get a reference to the desktop var desktop = Mobile.Device().Desktop; // get a reference to the selected tab var tab = Aliases.Pager.Tabstrip.Selected; // get the main ImageView's dimensions var view = Aliases.Pager.TabPage; var leftEdge = view.Left; var rightEdge = (view.Left + view.Width) - 1; var centerY = view.Height / 2; // save the currently selected day before dragging var day = tab.ControlText; // drag left using Device method Mobile.Device().Drag( rightEdge, desktop.Height / 2, // vertical center leftEdge, desktop.Height / 2 // vertical center ); // drag right, from inside the mobile object view.Drag(1, centerY, view.Width, 0); }
The device drag starts at the ImageView’s right edge and drags left. Notice that the assignment for rightEdge has a single pixel shaved off. This keeps the initial touch to start the drag inside the screen bounds. Without this adjustment, you will get an error message similar to this:
There was an attempt to perform a touch at point (1440, 1280), which is out of the device’s screen bounds.
The last script line drags right, this time using the mobile object’s Drag() method. The drag starts from 1 and moves right for the entire width of the control. Unlike the device Drag() method, mobile objects, such as the ImageView, can have Drag() parameters that exceed screen dimensions.
Waiting for State Changes
The timing for the drag may vary quite a bit and cause problems with the test. The code example “dragExample” above may fail because a previous drag operation hasn’t finished. To fix it, you can wait for the selected tab to change before dragging a second time. Before performing the initial drag, you can save off the tab’s ControlText (e.g. “Monday”). The while loop below uses the WaitProperty() method to detect when the selected tab ControlText changes.
// wait for the selected day to change while(tab.WaitProperty("ControlText", day, 100)){ Delay(500); }
The test can still fail if the tab changing animation is too slow and the view is still moving when you try to drag a second time. You can force the example to fail by manually touching and holding the ImageView before it can move. Then drag it over slowly until the next tab highlights, but hold the view in place instead of letting go. This will trigger the “attempt to perform an action at a point, which is beyond the screen” error.
The example below uses the new TestComplete 11 aqPerformance keyword to ensure that at least one second passes without the view’s Left property changing. aqPerformance methods all have a single counter name parameter to allow multiple instances. Use the Start() method to initialize aqPerformance or to reset aqPerformance after its already running. The Value() method returns the number elapsed milliseconds since starting. To detect horizontal movement changes, first save off the Left property of the view before the drag, and then check it against the current Left property. If the Left property changes before Value() exceeds a certain number of milliseconds, restart aqPerformance.
// wait to stop moving for at least 1 second var minimumWait = 1000; var counterName = "Movement"; aqPerformance.Start(counterName); while(aqPerformance.Value(counterName) < minimumWait){ Delay(100); if (leftEdge != view.Left){ Log.Message("View is moving... " + view.Left); // restart timer aqPerformance.Start(counterName); // save off the new value leftEdge = view.Left; } } Log.Message("View stopped moving... " + view.Left);
Controlling Drag Behavior
The last parameter of the device Drag() method, Delay, controls how long the control is touched before the drag begins. The default is 1000 milliseconds, but a one second touch triggers the long touch behavior of the view and shows a Toast — not desirable for this test. Instead, pass zero in the Delay parameter to start the drag immediately.
// drag left using Device method Mobile.Device().Drag( rightEdge, desktop.Height / 2, // vertical center leftEdge, desktop.Height / 2, // vertical center 0 // drag immediately );
The last parameter for mobile objects Drag() method controls the duration of the drag (defaults to zero). You can put in larger values to slow down the animation.
view.Drag(0, centerY, view.Width, 0, 2000);
Wrap Up
Dragging simulates the user moving touch between locations on the screen without releasing. The Drag() method is implemented for both Device and general mobile objects, but with different parameter semantics. To avoid timing issues where a previous drag operation hasn’t completed, consider waiting for the object to change state. The TestComplete WaitProperty() method can watch for text property changes.
Tomorrow we’ll automate Android controls, starting with ListView, using their extended properties and action methods. See you then.
The post Android User Actions III appeared first on Falafel Software Blog.