Swiping and Getting Away with it
The Device Swipe() method simulates a user flicking an object across the screen. Mobile objects don’t have their own swipe methods, so Device Swipe() uses starting and ending X and Y coordinates instead. Object Spy shows the parameter list in the description.
The code below performs a left swipe on an alias that I’ve named “Pager”. The pager is an Android ViewPager control, but can be seen as a generic view for our purposes. The first job is to get the left edge, where you’re going to end the swipe. You can’t use the exact edge without generating “Out of bounds” errors, so add a small amount of padding. Determine the right edge where the drag will start. The vertical or Y coordinates should stay constant. In fact, try manually swiping diagonally on your device – that doesn’t work well, so use the center vertical point of the object for both start and end Y coordinates.
var leftEdge = Aliases.Pager.Left + 20; var rightEdge = leftEdge + (Aliases.Pager.Width - 40); var verticalCenter = Aliases.Pager.Top + Aliases.Pager.Height / 2; // swipe from center, leftwards, not moving up and down. Mobile.Device().Swipe(rightEdge, verticalCenter, leftEdge, verticalCenter); Log.Picture(Mobile.Device().Desktop, "After Left Swipe");
Use an object that doesn’t change its position after the swipe. If you were to use the image inside each page as the object, the swipe would move it off screen, so you wouldn’t be able to swipe a second time. Instead, use a stationary container like the Pager.
Note: The device is a TestComplete abstraction that can be used for both Android and iOS apps. Device is an AndroidDevice or iOSDevice object, depending on the platform you’re testing. Both have the same Swipe() method and parameters.
Wrapping in a Simple JavaScript Object
You can abstract swiping and bounds checking behavior by wrapping the previous logic in a simple JavaScript object. Here’s a snippet that takes an object passed to it and allows it to be swiped right or left on the current device.
var Directions = { Left: "Left", Right: "Right" } var Swipable = function(obj){ var padding = 10; this.swipe = function(direction){ var startX = direction == Directions.Left ? obj.Left + (obj.Width - padding) : obj.Left + padding; var endX = direction == Directions.Left ? startX - (obj.Width - padding): startX + (obj.Width - (padding * 2)); var verticalCenter = obj.Top + obj.Height / 2; Mobile.Device().Swipe( startX, verticalCenter, endX, verticalCenter); } }
To use the object, create a new instance and pass the object that should be swiped. The object can be an alias, the full path to the object or even the result of a Find method. Then call the swipe() method and pass the custom Directions.Left or Directions.Right defined above.
var page = new Swipable(Aliases.Pager); // swipe to Tuesday page.swipe(Directions.Left); // swipe to Wednesday page.swipe(Directions.Left); // swipe back to Tuesday page.swipe(Directions.Right);
Swipe Speed
The Swipe() method has parameters for the number of steps and duration of the transition. By default, these are 10 steps that animate in one second. The example below uses only 5 steps, animated in a half a second:
Mobile.Device().Swipe(startX, verticalCenter, endX, verticalCenter, 5, 500);
To extend the wrapper to handle swipe speed, store steps and duration in another custom JSON object, Speed. The example Speed object labels a combination of steps and duration as Fast, Medium and Slow:
var Directions = { Left: "Left", Right: "Right" } var Speed = { Fast: { Steps: 5, Duration: 5000 }, Medium: { Steps: 10, Duration: 1000 }, Slow: { Steps: 20, Duration: 1200 } }
We can change the wrapper object’s swipe() method to accept a speed parameter.
var Swipable = function(obj){ var padding = 10; this.swipe = function(direction, speed){ var startX = direction == Directions.Left ? obj.Left + (obj.Width - padding) : obj.Left + padding; var endX = direction == Directions.Left ? startX - (obj.Width - padding): startX + (obj.Width - (padding * 2)); var verticalCenter = obj.Top + obj.Height / 2; var device = Mobile.Device(); if (speed) { device.Swipe(startX, verticalCenter, endX, verticalCenter, speed.Steps, speed.Duration); } else { device.Swipe(startX, verticalCenter, endX, verticalCenter); } } }
The wrapper object’s swipe() method can be called with combinations of directions and speeds:
var page = new Swipable(Aliases.Pager); page.swipe(Directions.Left, Speed.Fast); page.swipe(Directions.Left, Speed.Medium); page.swipe(Directions.Right, Speed.Slow);
Native Methods
I used the pager as a convenience to demonstrate swiping mechanics. Swiping works anywhere on the device surface using coordinates, but if you just want to page left and right, ViewPager has its own native Java methods to get the job done. Filtering ViewPager in Object Spy for “page” reveals pageLeft() and pageRight():
The script calls the native Java pageRight() and pageLeft() methods to navigate without swiping.
function nativeMethods(){ Mobile.SetCurrent(Project.Variables.MyAndroidDevice); TestedApps.DrivenGallery.Run(); // moves to "Tuesday" Aliases.Pager.pageRight(); // moves to "Wednesday" Aliases.Pager.pageRight(); // moves back to "Tuesday" Aliases.Pager.pageLeft(); }
Wrap Up
Swiping is a generic behavior that simulates a user flicking the surface of the screen and is strictly coordinate based. The Swipe() method’s start and end coordinates must stay within the bounds of the device screen. You can wrap the logic to handle bounds checking, direction and speed, in a custom JavaScript object. If you don’t need to swipe, research in the Object Inspector or Spy may reveal simpler methods. Tomorrow’s blog on user actions explores dragging objects on screen at both the device and object level, waiting for state changes, and controlling drag delay. See you then.
The post Android User Actions II appeared first on Falafel Software Blog.