0
# Touch Actions & Gestures
1
2
Advanced touch gesture support using TouchAction, MultiAction, and W3C Actions builders for mobile and touch-enabled devices.
3
4
## Capabilities
5
6
### TouchAction Class
7
8
Build and execute single touch gesture sequences.
9
10
```javascript { .api }
11
/**
12
* TouchAction constructor
13
* @param driver - WebDriver instance
14
*/
15
class TouchAction {
16
constructor(driver: Webdriver);
17
18
/**
19
* Add tap gesture
20
* @param opts - Tap options
21
*/
22
tap(opts?: {element?: Element, x?: number, y?: number, count?: number}): TouchAction;
23
24
/**
25
* Add press gesture
26
* @param opts - Press options
27
*/
28
press(opts?: {element?: Element, x?: number, y?: number}): TouchAction;
29
30
/**
31
* Add long press gesture
32
* @param opts - Long press options
33
*/
34
longPress(opts?: {element?: Element, x?: number, y?: number}): TouchAction;
35
36
/**
37
* Add move gesture
38
* @param opts - Move options
39
*/
40
moveTo(opts?: {element?: Element, x?: number, y?: number}): TouchAction;
41
42
/**
43
* Add release gesture
44
*/
45
release(): TouchAction;
46
47
/**
48
* Add wait/pause
49
* @param opts - Wait options or duration in milliseconds
50
*/
51
wait(opts: {ms: number} | number): TouchAction;
52
53
/**
54
* Cancel all gestures
55
*/
56
cancel(): TouchAction;
57
58
/**
59
* Execute the touch action sequence
60
* @param cb - Callback receiving (err)
61
*/
62
perform(cb?: callback): void;
63
}
64
```
65
66
**Usage Examples:**
67
68
```javascript
69
const wd = require('wd');
70
71
// Simple tap gesture
72
const touchAction = new wd.TouchAction(browser);
73
touchAction
74
.tap({element: targetElement})
75
.perform(function(err) {
76
console.log('Tap gesture completed');
77
});
78
79
// Tap at coordinates
80
touchAction
81
.tap({x: 100, y: 200})
82
.perform();
83
84
// Long press gesture
85
touchAction
86
.longPress({element: menuButton})
87
.wait(1000)
88
.release()
89
.perform(function(err) {
90
console.log('Long press menu opened');
91
});
92
93
// Drag and drop gesture
94
touchAction
95
.press({element: draggableItem})
96
.wait(500)
97
.moveTo({element: dropZone})
98
.release()
99
.perform(function(err) {
100
console.log('Item dragged and dropped');
101
});
102
103
// Swipe gesture
104
touchAction
105
.press({x: 300, y: 400})
106
.wait(100)
107
.moveTo({x: 300, y: 100}) // Swipe up
108
.release()
109
.perform(function(err) {
110
console.log('Swipe up completed');
111
});
112
```
113
114
### MultiAction Class
115
116
Execute multiple TouchAction sequences simultaneously.
117
118
```javascript { .api }
119
/**
120
* MultiAction constructor
121
* @param browserOrElement - WebDriver instance or Element
122
*/
123
class MultiAction {
124
constructor(browserOrElement: Webdriver | Element);
125
126
/**
127
* Add TouchAction to the multi-action
128
* @param touchActions - One or more TouchAction instances
129
*/
130
add(...touchActions: TouchAction[]): MultiAction;
131
132
/**
133
* Cancel all actions
134
*/
135
cancel(): MultiAction;
136
137
/**
138
* Execute all touch actions simultaneously
139
* @param cb - Callback receiving (err)
140
*/
141
perform(cb?: callback): void;
142
}
143
```
144
145
**Usage Examples:**
146
147
```javascript
148
// Two-finger pinch gesture
149
const finger1 = new wd.TouchAction(browser);
150
finger1.press({x: 200, y: 200}).wait(100).moveTo({x: 150, y: 150}).release();
151
152
const finger2 = new wd.TouchAction(browser);
153
finger2.press({x: 300, y: 300}).wait(100).moveTo({x: 350, y: 350}).release();
154
155
const pinchOut = new wd.MultiAction(browser);
156
pinchOut.add(finger1, finger2).perform(function(err) {
157
console.log('Pinch out gesture completed');
158
});
159
160
// Two-finger zoom in
161
const zoom1 = new wd.TouchAction(browser);
162
zoom1.press({x: 150, y: 150}).wait(100).moveTo({x: 100, y: 100}).release();
163
164
const zoom2 = new wd.TouchAction(browser);
165
zoom2.press({x: 350, y: 350}).wait(100).moveTo({x: 400, y: 400}).release();
166
167
const zoomIn = new wd.MultiAction(browser);
168
zoomIn.add(zoom1, zoom2).perform(function(err) {
169
console.log('Zoom in gesture completed');
170
});
171
172
// Multi-finger tap
173
const tap1 = new wd.TouchAction(browser).tap({x: 100, y: 200});
174
const tap2 = new wd.TouchAction(browser).tap({x: 200, y: 200});
175
const tap3 = new wd.TouchAction(browser).tap({x: 300, y: 200});
176
177
const multiTap = new wd.MultiAction(browser);
178
multiTap.add(tap1, tap2, tap3).perform(function(err) {
179
console.log('Multi-finger tap completed');
180
});
181
```
182
183
### W3C Actions
184
185
Modern W3C Actions API for complex input sequences.
186
187
```javascript { .api }
188
/**
189
* W3C Actions constructor
190
* @param driver - WebDriver instance
191
*/
192
class W3CActions {
193
constructor(driver: Webdriver);
194
195
/**
196
* Add input device to the action sequence
197
* @param inputSource - InputDevice instance
198
*/
199
addInputDevice(inputSource: InputDevice): W3CActions;
200
201
/**
202
* Add touch input device
203
*/
204
addTouchInput(): InputDevice;
205
206
/**
207
* Add mouse input device
208
*/
209
addMouseInput(): InputDevice;
210
211
/**
212
* Add pen input device
213
*/
214
addPenInput(): InputDevice;
215
216
/**
217
* Add keyboard input device
218
*/
219
addKeyInput(): InputDevice;
220
221
/**
222
* Execute the W3C actions
223
* @param cb - Callback receiving (err)
224
*/
225
perform(cb?: callback): void;
226
}
227
228
/**
229
* InputDevice for W3C Actions
230
*/
231
class InputDevice {
232
constructor(opts?: {type?: string, id?: string, pointerType?: string, parameters?: object});
233
234
/**
235
* Pause input source
236
* @param opts - Pause options or duration
237
*/
238
pause(opts: {duration: number} | number): InputDevice;
239
240
// Key input methods (for type='key')
241
keyDown(opts: {value: string} | string): InputDevice;
242
keyUp(opts: {value: string} | string): InputDevice;
243
244
// Pointer input methods (for type='pointer')
245
pointerDown(opts?: {button?: number}): InputDevice;
246
pointerUp(opts?: {button?: number}): InputDevice;
247
pointerMove(opts: {element?: Element, duration?: number, origin?: string, x?: number, y?: number}): InputDevice;
248
pointerCancel(opts?: {button?: number}): InputDevice;
249
}
250
```
251
252
**Usage Examples:**
253
254
```javascript
255
// Basic W3C touch gesture
256
const w3cActions = new wd.W3CActions(browser);
257
const finger = w3cActions.addTouchInput();
258
259
finger
260
.pointerMove({x: 100, y: 200})
261
.pointerDown()
262
.pause(100)
263
.pointerMove({x: 300, y: 200})
264
.pointerUp();
265
266
w3cActions.perform(function(err) {
267
console.log('W3C touch gesture completed');
268
});
269
270
// Multi-touch W3C gesture
271
const w3cMultiTouch = new wd.W3CActions(browser);
272
const finger1 = w3cMultiTouch.addTouchInput();
273
const finger2 = w3cMultiTouch.addTouchInput();
274
275
// Pinch gesture
276
finger1
277
.pointerMove({x: 200, y: 200})
278
.pointerDown()
279
.pause(100)
280
.pointerMove({x: 150, y: 150})
281
.pointerUp();
282
283
finger2
284
.pointerMove({x: 300, y: 300})
285
.pointerDown()
286
.pause(100)
287
.pointerMove({x: 350, y: 350})
288
.pointerUp();
289
290
w3cMultiTouch.perform(function(err) {
291
console.log('W3C pinch gesture completed');
292
});
293
294
// Combined input types
295
const mixedActions = new wd.W3CActions(browser);
296
const touch = mixedActions.addTouchInput();
297
const keyboard = mixedActions.addKeyInput();
298
299
// Touch and type simultaneously
300
touch.pointerMove({x: 100, y: 100}).pointerDown();
301
keyboard.keyDown('a').keyUp('a');
302
touch.pointerUp();
303
304
mixedActions.perform(function(err) {
305
console.log('Mixed input actions completed');
306
});
307
```
308
309
### Gesture Helpers
310
311
Common gesture patterns and helper functions.
312
313
**Usage Examples:**
314
315
```javascript
316
// Swipe helper functions
317
function swipeUp(element, distance = 100) {
318
const touchAction = new wd.TouchAction(browser);
319
return touchAction
320
.press({element: element})
321
.wait(100)
322
.moveTo({element: element, x: 0, y: -distance})
323
.release()
324
.perform();
325
}
326
327
function swipeDown(element, distance = 100) {
328
const touchAction = new wd.TouchAction(browser);
329
return touchAction
330
.press({element: element})
331
.wait(100)
332
.moveTo({element: element, x: 0, y: distance})
333
.release()
334
.perform();
335
}
336
337
function swipeLeft(element, distance = 100) {
338
const touchAction = new wd.TouchAction(browser);
339
return touchAction
340
.press({element: element})
341
.wait(100)
342
.moveTo({element: element, x: -distance, y: 0})
343
.release()
344
.perform();
345
}
346
347
function swipeRight(element, distance = 100) {
348
const touchAction = new wd.TouchAction(browser);
349
return touchAction
350
.press({element: element})
351
.wait(100)
352
.moveTo({element: element, x: distance, y: 0})
353
.release()
354
.perform();
355
}
356
357
// Usage of swipe helpers
358
browser.elementByCss('.swipeable-area', function(err, area) {
359
swipeUp(area, 200); // Swipe up 200 pixels
360
});
361
362
// Pinch zoom helper
363
function pinchZoom(centerX, centerY, scale = 1.5) {
364
const distance = 100;
365
const scaledDistance = distance * scale;
366
367
const finger1 = new wd.TouchAction(browser);
368
finger1
369
.press({x: centerX - distance/2, y: centerY})
370
.wait(100)
371
.moveTo({x: centerX - scaledDistance/2, y: centerY})
372
.release();
373
374
const finger2 = new wd.TouchAction(browser);
375
finger2
376
.press({x: centerX + distance/2, y: centerY})
377
.wait(100)
378
.moveTo({x: centerX + scaledDistance/2, y: centerY})
379
.release();
380
381
const multiAction = new wd.MultiAction(browser);
382
return multiAction.add(finger1, finger2).perform();
383
}
384
385
// Usage of pinch zoom
386
pinchZoom(200, 300, 2.0); // Zoom 2x at coordinates (200, 300)
387
388
// Scroll helper using touch
389
function touchScroll(element, direction, distance) {
390
const directions = {
391
up: {x: 0, y: -distance},
392
down: {x: 0, y: distance},
393
left: {x: -distance, y: 0},
394
right: {x: distance, y: 0}
395
};
396
397
const offset = directions[direction] || directions.down;
398
399
const touchAction = new wd.TouchAction(browser);
400
return touchAction
401
.press({element: element})
402
.wait(200)
403
.moveTo({element: element, x: offset.x, y: offset.y})
404
.release()
405
.perform();
406
}
407
408
// Usage of touch scroll
409
browser.elementByCss('.scrollable-list', function(err, list) {
410
touchScroll(list, 'down', 300); // Scroll down 300 pixels
411
});
412
413
// Double tap helper
414
function doubleTap(element, delay = 100) {
415
const touchAction = new wd.TouchAction(browser);
416
return touchAction
417
.tap({element: element})
418
.wait(delay)
419
.tap({element: element})
420
.perform();
421
}
422
423
// Custom gesture builder
424
class GestureBuilder {
425
constructor(browser) {
426
this.browser = browser;
427
}
428
429
createSwipe(startX, startY, endX, endY, duration = 1000) {
430
const touchAction = new wd.TouchAction(this.browser);
431
return touchAction
432
.press({x: startX, y: startY})
433
.wait(100)
434
.moveTo({x: endX, y: endY})
435
.release();
436
}
437
438
createTap(x, y, count = 1) {
439
const touchAction = new wd.TouchAction(this.browser);
440
let action = touchAction;
441
442
for (let i = 0; i < count; i++) {
443
action = action.tap({x: x, y: y});
444
if (i < count - 1) {
445
action = action.wait(100);
446
}
447
}
448
449
return action;
450
}
451
452
createPinch(centerX, centerY, startDistance, endDistance) {
453
const finger1 = new wd.TouchAction(this.browser);
454
finger1
455
.press({x: centerX - startDistance/2, y: centerY})
456
.wait(100)
457
.moveTo({x: centerX - endDistance/2, y: centerY})
458
.release();
459
460
const finger2 = new wd.TouchAction(this.browser);
461
finger2
462
.press({x: centerX + startDistance/2, y: centerY})
463
.wait(100)
464
.moveTo({x: centerX + endDistance/2, y: centerY})
465
.release();
466
467
return new wd.MultiAction(this.browser).add(finger1, finger2);
468
}
469
}
470
471
// Usage of gesture builder
472
const gestureBuilder = new GestureBuilder(browser);
473
474
// Create and execute custom gestures
475
gestureBuilder.createSwipe(100, 300, 400, 300).perform(); // Horizontal swipe
476
gestureBuilder.createTap(200, 200, 3).perform(); // Triple tap
477
gestureBuilder.createPinch(250, 400, 50, 150).perform(); // Pinch out
478
```
479
480
### Performance and Optimization
481
482
Best practices for efficient touch gesture automation.
483
484
**Usage Examples:**
485
486
```javascript
487
// Batch gestures for better performance
488
const gestures = [];
489
490
// Create multiple gestures
491
for (let i = 0; i < 5; i++) {
492
const touchAction = new wd.TouchAction(browser);
493
touchAction.tap({x: 100 + i * 50, y: 200});
494
gestures.push(touchAction);
495
}
496
497
// Execute gestures in sequence
498
async function executeGestures(gestures) {
499
for (const gesture of gestures) {
500
await new Promise((resolve, reject) => {
501
gesture.perform(function(err) {
502
if (err) reject(err);
503
else resolve();
504
});
505
});
506
}
507
}
508
509
executeGestures(gestures).then(() => {
510
console.log('All gestures completed');
511
});
512
513
// Optimize gesture timing
514
function createOptimizedSwipe(element, direction) {
515
const touchAction = new wd.TouchAction(browser);
516
517
// Shorter waits for faster execution
518
return touchAction
519
.press({element: element})
520
.wait(50) // Reduced from 100ms
521
.moveTo({element: element, x: direction.x, y: direction.y})
522
.release();
523
}
524
525
// Error handling for gestures
526
function safeGesture(gestureFunction, retries = 3) {
527
return new Promise((resolve, reject) => {
528
let attempt = 0;
529
530
function tryGesture() {
531
attempt++;
532
gestureFunction().perform(function(err) {
533
if (err && attempt < retries) {
534
console.log(`Gesture attempt ${attempt} failed, retrying...`);
535
setTimeout(tryGesture, 1000);
536
} else if (err) {
537
reject(err);
538
} else {
539
resolve();
540
}
541
});
542
}
543
544
tryGesture();
545
});
546
}
547
548
// Usage of safe gesture
549
const swipeGesture = () => new wd.TouchAction(browser)
550
.press({x: 100, y: 200})
551
.moveTo({x: 300, y: 200})
552
.release();
553
554
safeGesture(swipeGesture, 3).then(() => {
555
console.log('Gesture completed successfully');
556
}).catch(err => {
557
console.error('Gesture failed after retries:', err);
558
});
559
```