1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
using System;
using System.Dynamic;
using System.Linq;
using System.Security.Cryptography;
using Xamarin.UITest;
using Xamarin.UITest.Android;
using Xamarin.UITest.iOS;
using Xamarin.UITest.Queries;
namespace Xamarin.Forms.Core.UITests
{
internal static class Gestures
{
public static bool ScrollForElement (this IApp app, string query, Drag drag, int maxSteps = 25)
{
int count = 0;
int centerTolerance = 50;
Func<AppQuery, AppQuery> elementQuery = q => q.Raw (query);
// Visible elements
if (app.Query (elementQuery).Length > 1) {
throw new UITestQueryMultipleResultsException (query);
}
// check to see if the element is visible already
if (app.Query (elementQuery).Length == 1) {
// centering an element whos CenterX is close to the bounding rectangle's center X can sometime register the swipe as a tap
float elementDistanceToDragCenter = Math.Abs (app.Query (elementQuery).First ().Rect.CenterY - drag.DragBounds.CenterY);
if (elementDistanceToDragCenter > centerTolerance)
app.CenterElementInView (elementQuery, drag.DragBounds, drag.DragDirection);
return true;
}
// loop until element is seen
while (app.Query (elementQuery).Length == 0 && count < maxSteps) {
app.DragCoordinates (drag.XStart, drag.YStart, drag.XEnd, drag.YEnd);
count++;
}
if (count != maxSteps) {
// centering an element whos CenterX is close to the bounding rectangle's center X can sometime register the swipe as a tap
float elementDistanceToDragCenter = Math.Abs (app.Query (elementQuery).First ().Rect.CenterY - drag.DragBounds.CenterY);
if (elementDistanceToDragCenter > centerTolerance)
app.CenterElementInView (elementQuery, drag.DragBounds, drag.DragDirection);
return true;
}
count = 0;
drag.DragDirection = drag.OppositeDirection;
while (app.Query (elementQuery).Length == 0 && count < maxSteps) {
app.DragCoordinates (drag.XStart, drag.YStart, drag.XEnd, drag.YEnd);
count++;
}
if (count != maxSteps) {
app.CenterElementInView (elementQuery, drag.DragBounds, drag.DragDirection);
return true;
}
return false;
}
static void CenterElementInView (this IApp app, Func<AppQuery, AppQuery> element, AppRect containingView, Drag.Direction direction)
{
// TODO Implement horizontal centering
if (direction == Drag.Direction.BottomToTop || direction == Drag.Direction.TopToBottom) {
var elementBounds = app.Query (element).First ().Rect;
bool elementCenterBelowContainerCenter = elementBounds.CenterY > containingView.CenterY;
bool elementCenterAboveContainerCenter = elementBounds.CenterY < containingView.CenterY;
var displacementToCenter = Math.Abs (elementBounds.CenterY - containingView.CenterY) / 2;
// avoid drag as touch
if (displacementToCenter < 50)
return;
if (elementCenterBelowContainerCenter) {
var drag = new Drag (
containingView,
containingView.CenterX, containingView.CenterY + displacementToCenter,
containingView.CenterX, containingView.CenterY - displacementToCenter,
Drag.Direction.BottomToTop
);
app.DragCoordinates (drag.XStart, drag.YStart, drag.XEnd, drag.YEnd);
} else if (elementCenterAboveContainerCenter) {
var drag = new Drag (
containingView,
containingView.CenterX, containingView.CenterY - displacementToCenter,
containingView.CenterX, containingView.CenterY + displacementToCenter,
Drag.Direction.TopToBottom
);
app.DragCoordinates (drag.XStart, drag.YStart, drag.XEnd, drag.YEnd);
}
}
}
public static void Pan (this IApp app, Drag drag)
{
app.DragCoordinates (drag.XStart, drag.YStart, drag.XEnd, drag.YEnd);
}
}
}
|