f096591ad0123f385b575143d2dc9a4143a8b1ea
[WebKit-https.git] / LayoutTests / resources / ui-helper.js
1
2 window.UIHelper = class UIHelper {
3     static isIOS()
4     {
5         return navigator.userAgent.includes('iPhone') || navigator.userAgent.includes('iPad');
6     }
7
8     static isWebKit2()
9     {
10         return window.testRunner.isWebKit2;
11     }
12
13     static tapAt(x, y)
14     {
15         console.assert(this.isIOS());
16
17         if (!this.isWebKit2()) {
18             eventSender.addTouchPoint(x, y);
19             eventSender.touchStart();
20             eventSender.releaseTouchPoint(0);
21             eventSender.touchEnd();
22             return Promise.resolve();
23         }
24
25         return new Promise((resolve) => {
26             testRunner.runUIScript(`
27                 uiController.singleTapAtPoint(${x}, ${y}, function() {
28                     uiController.uiScriptComplete('Done');
29                 });`, resolve);
30         });
31     }
32
33     static activateAt(x, y)
34     {
35         if (!this.isWebKit2() || !this.isIOS()) {
36             eventSender.mouseMoveTo(x, y);
37             eventSender.mouseDown();
38             eventSender.mouseUp();
39             return Promise.resolve();
40         }
41
42         return new Promise((resolve) => {
43             testRunner.runUIScript(`
44                 uiController.singleTapAtPoint(${x}, ${y}, function() {
45                     uiController.uiScriptComplete('Done');
46                 });`, resolve);
47         });
48     }
49
50     static activateElement(element)
51     {
52         const x = element.offsetLeft + element.offsetWidth / 2;
53         const y = element.offsetTop + element.offsetHeight / 2;
54         return UIHelper.activateAt(x, y);
55     }
56
57     static keyDown(key)
58     {
59         if (!this.isWebKit2() || !this.isIOS()) {
60             eventSender.keyDown(key);
61             return Promise.resolve();
62         }
63
64         return new Promise((resolve) => {
65             testRunner.runUIScript(`
66                 uiController.keyDownUsingHardwareKeyboard("downArrow", function() {
67                     uiController.uiScriptComplete("Done");
68                 });`, resolve);
69         });
70     }
71
72     static ensurePresentationUpdate()
73     {
74         if (!this.isWebKit2()) {
75             testRunner.display();
76             return Promise.resolve();
77         }
78
79         return new Promise(resolve => {
80             testRunner.runUIScript(`
81                 uiController.doAfterPresentationUpdate(function() {
82                     uiController.uiScriptComplete('Done');
83                 });`, resolve);
84         });
85     }
86
87     static ensureVisibleContentRectUpdate()
88     {
89         if (!this.isWebKit2())
90             return Promise.resolve();
91
92         return new Promise(resolve => {
93             const visibleContentRectUpdateScript = "uiController.doAfterVisibleContentRectUpdate(() => uiController.uiScriptComplete())";
94             testRunner.runUIScript(visibleContentRectUpdateScript, resolve);
95         });
96     }
97
98     static activateAndWaitForInputSessionAt(x, y)
99     {
100         if (!this.isWebKit2() || !this.isIOS())
101             return this.activateAt(x, y);
102
103         return new Promise(resolve => {
104             testRunner.runUIScript(`
105                 (function() {
106                     uiController.didShowKeyboardCallback = function() {
107                         uiController.uiScriptComplete("Done");
108                     };
109                     uiController.singleTapAtPoint(${x}, ${y}, function() { });
110                 })()`, resolve);
111         });
112     }
113
114     static activateFormControl(element)
115     {
116         if (!this.isWebKit2() || !this.isIOS())
117             return this.activateElement(element);
118
119         const x = element.offsetLeft + element.offsetWidth / 2;
120         const y = element.offsetTop + element.offsetHeight / 2;
121
122         return new Promise(resolve => {
123             testRunner.runUIScript(`
124                 (function() {
125                     uiController.didStartFormControlInteractionCallback = function() {
126                         uiController.uiScriptComplete("Done");
127                     };
128                     uiController.singleTapAtPoint(${x}, ${y}, function() { });
129                 })()`, resolve);
130         });
131     }
132
133     static waitForKeyboardToHide()
134     {
135         if (!this.isWebKit2() || !this.isIOS())
136             return Promise.resolve();
137
138         return new Promise(resolve => {
139             testRunner.runUIScript(`
140                 (function() {
141                     if (uiController.isShowingKeyboard)
142                         uiController.didHideKeyboardCallback = () => uiController.uiScriptComplete();
143                     else
144                         uiController.uiScriptComplete();
145                 })()`, resolve);
146         });
147     }
148
149     static getUICaretRect()
150     {
151         if (!this.isWebKit2() || !this.isIOS())
152             return Promise.resolve();
153
154         return new Promise(resolve => {
155             testRunner.runUIScript(`(function() {
156                 uiController.doAfterNextStablePresentationUpdate(function() {
157                     uiController.uiScriptComplete(JSON.stringify(uiController.textSelectionCaretRect));
158                 });
159             })()`, jsonString => {
160                 resolve(JSON.parse(jsonString));
161             });
162         });
163     }
164
165     static getUISelectionRects()
166     {
167         if (!this.isWebKit2() || !this.isIOS())
168             return Promise.resolve();
169
170         return new Promise(resolve => {
171             testRunner.runUIScript(`(function() {
172                 uiController.doAfterNextStablePresentationUpdate(function() {
173                     uiController.uiScriptComplete(JSON.stringify(uiController.textSelectionRangeRects));
174                 });
175             })()`, jsonString => {
176                 resolve(JSON.parse(jsonString));
177             });
178         });
179     }
180
181     static getUICaretViewRect()
182     {
183         if (!this.isWebKit2() || !this.isIOS())
184             return Promise.resolve();
185
186         return new Promise(resolve => {
187             testRunner.runUIScript(`(function() {
188                 uiController.doAfterNextStablePresentationUpdate(function() {
189                     uiController.uiScriptComplete(JSON.stringify(uiController.selectionCaretViewRect));
190                 });
191             })()`, jsonString => {
192                 resolve(JSON.parse(jsonString));
193             });
194         });
195     }
196
197     static getUISelectionViewRects()
198     {
199         if (!this.isWebKit2() || !this.isIOS())
200             return Promise.resolve();
201
202         return new Promise(resolve => {
203             testRunner.runUIScript(`(function() {
204                 uiController.doAfterNextStablePresentationUpdate(function() {
205                     uiController.uiScriptComplete(JSON.stringify(uiController.selectionRangeViewRects));
206                 });
207             })()`, jsonString => {
208                 resolve(JSON.parse(jsonString));
209             });
210         });
211     }
212
213     static getSelectionStartGrabberViewRect()
214     {
215         if (!this.isWebKit2() || !this.isIOS())
216             return Promise.resolve();
217
218         return new Promise(resolve => {
219             testRunner.runUIScript(`(function() {
220                 uiController.doAfterNextStablePresentationUpdate(function() {
221                     uiController.uiScriptComplete(JSON.stringify(uiController.selectionStartGrabberViewRect));
222                 });
223             })()`, jsonString => {
224                 resolve(JSON.parse(jsonString));
225             });
226         });
227     }
228
229     static getSelectionEndGrabberViewRect()
230     {
231         if (!this.isWebKit2() || !this.isIOS())
232             return Promise.resolve();
233
234         return new Promise(resolve => {
235             testRunner.runUIScript(`(function() {
236                 uiController.doAfterNextStablePresentationUpdate(function() {
237                     uiController.uiScriptComplete(JSON.stringify(uiController.selectionEndGrabberViewRect));
238                 });
239             })()`, jsonString => {
240                 resolve(JSON.parse(jsonString));
241             });
242         });
243     }
244
245     static replaceTextAtRange(text, location, length) {
246         return new Promise(resolve => {
247             testRunner.runUIScript(`(() => {
248                 uiController.replaceTextAtRange("${text}", ${location}, ${length});
249                 uiController.uiScriptComplete('Done');
250             })()`, resolve);
251         });
252     }
253
254     static wait(promise)
255     {
256         testRunner.waitUntilDone();
257         if (window.finishJSTest)
258             window.jsTestIsAsync = true;
259
260         let finish = () => {
261             if (window.finishJSTest)
262                 finishJSTest();
263             else
264                 testRunner.notifyDone();
265         }
266
267         return promise.then(finish, finish);
268     }
269
270     static withUserGesture(callback)
271     {
272         internals.withUserGesture(callback);
273     }
274
275     static selectFormAccessoryPickerRow(rowIndex)
276     {
277         const selectRowScript = `(() => uiController.selectFormAccessoryPickerRow(${rowIndex}))()`;
278         return new Promise(resolve => testRunner.runUIScript(selectRowScript, resolve));
279     }
280
281     static selectFormPopoverTitle()
282     {
283         return new Promise(resolve => {
284             testRunner.runUIScript(`(() => {
285                 uiController.uiScriptComplete(uiController.selectFormPopoverTitle);
286             })()`, resolve);
287         });
288     }
289
290     static enterText(text)
291     {
292         const escapedText = text.replace(/`/g, "\\`");
293         const enterTextScript = `(() => uiController.enterText(\`${escapedText}\`))()`;
294         return new Promise(resolve => testRunner.runUIScript(enterTextScript, resolve));
295     }
296
297     static setTimePickerValue(hours, minutes)
298     {
299         const setValueScript = `(() => uiController.setTimePickerValue(${hours}, ${minutes}))()`;
300         return new Promise(resolve => testRunner.runUIScript(setValueScript, resolve));
301     }
302
303     static setShareSheetCompletesImmediatelyWithResolution(resolved)
304     {
305         const resolveShareSheet = `(() => uiController.setShareSheetCompletesImmediatelyWithResolution(${resolved}))()`;
306         return new Promise(resolve => testRunner.runUIScript(resolveShareSheet, resolve));
307     }
308
309     static textContentType()
310     {
311         return new Promise(resolve => {
312             testRunner.runUIScript(`(() => {
313                 uiController.uiScriptComplete(uiController.textContentType);
314             })()`, resolve);
315         });
316     }
317
318     static formInputLabel()
319     {
320         return new Promise(resolve => {
321             testRunner.runUIScript(`(() => {
322                 uiController.uiScriptComplete(uiController.formInputLabel);
323             })()`, resolve);
324         });
325     }
326
327     static isShowingDataListSuggestions()
328     {
329         return new Promise(resolve => {
330             testRunner.runUIScript(`(() => {
331                 uiController.uiScriptComplete(uiController.isShowingDataListSuggestions);
332             })()`, result => resolve(result === "true" ? true : false));
333         });
334     }
335
336     static zoomScale()
337     {
338         return new Promise(resolve => {
339             testRunner.runUIScript(`(() => {
340                 uiController.uiScriptComplete(uiController.zoomScale);
341             })()`, scaleAsString => resolve(parseFloat(scaleAsString)));
342         });
343     }
344
345     static typeCharacter(characterString)
346     {
347         if (!this.isWebKit2() || !this.isIOS()) {
348             eventSender.keyDown(characterString);
349             return;
350         }
351
352         const escapedString = characterString.replace(/\\/g, "\\\\").replace(/`/g, "\\`");
353         const uiScript = `uiController.typeCharacterUsingHardwareKeyboard(\`${escapedString}\`, () => uiController.uiScriptComplete())`;
354         return new Promise(resolve => testRunner.runUIScript(uiScript, resolve));
355     }
356
357     static applyAutocorrection(newText, oldText)
358     {
359         if (!this.isWebKit2())
360             return;
361
362         const [escapedNewText, escapedOldText] = [newText.replace(/`/g, "\\`"), oldText.replace(/`/g, "\\`")];
363         const uiScript = `uiController.applyAutocorrection(\`${escapedNewText}\`, \`${escapedOldText}\`, () => uiController.uiScriptComplete())`;
364         return new Promise(resolve => testRunner.runUIScript(uiScript, resolve));
365     }
366
367     static inputViewBounds()
368     {
369         if (!this.isWebKit2() || !this.isIOS())
370             return Promise.resolve();
371
372         return new Promise(resolve => {
373             testRunner.runUIScript(`(() => {
374                 uiController.uiScriptComplete(JSON.stringify(uiController.inputViewBounds));
375             })()`, jsonString => {
376                 resolve(JSON.parse(jsonString));
377             });
378         });
379     }
380
381     static calendarType()
382     {
383         if (!this.isWebKit2())
384             return Promise.resolve();
385
386         return new Promise(resolve => {
387             testRunner.runUIScript(`(() => {
388                 uiController.doAfterNextStablePresentationUpdate(() => {
389                     uiController.uiScriptComplete(JSON.stringify(uiController.calendarType));
390                 })
391             })()`, jsonString => {
392                 resolve(JSON.parse(jsonString));
393             });
394         });
395     }
396
397     static setDefaultCalendarType(calendarIdentifier)
398     {
399         if (!this.isWebKit2())
400             return Promise.resolve();
401
402         return new Promise(resolve => testRunner.runUIScript(`uiController.setDefaultCalendarType('${calendarIdentifier}')`, resolve));
403
404     }
405
406     static setViewScale(scale)
407     {
408         if (!this.isWebKit2())
409             return Promise.resolve();
410
411         return new Promise(resolve => testRunner.runUIScript(`uiController.setViewScale(${scale})`, resolve));
412     }
413
414     static resignFirstResponder()
415     {
416         if (!this.isWebKit2())
417             return Promise.resolve();
418
419         return new Promise(resolve => testRunner.runUIScript(`uiController.resignFirstResponder()`, resolve));
420     }
421
422     static minimumZoomScale()
423     {
424         if (!this.isWebKit2())
425             return Promise.resolve();
426
427         return new Promise(resolve => {
428             testRunner.runUIScript(`(() => {
429                 uiController.uiScriptComplete(uiController.minimumZoomScale);
430             })()`, scaleAsString => resolve(parseFloat(scaleAsString)))
431         });
432     }
433
434     static drawSquareInEditableImage()
435     {
436         if (!this.isWebKit2())
437             return Promise.resolve();
438
439         return new Promise(resolve => testRunner.runUIScript(`uiController.drawSquareInEditableImage()`, resolve));
440     }
441
442     static numberOfStrokesInEditableImage()
443     {
444         if (!this.isWebKit2())
445             return Promise.resolve();
446
447         return new Promise(resolve => {
448             testRunner.runUIScript(`(() => {
449                 uiController.uiScriptComplete(uiController.numberOfStrokesInEditableImage);
450             })()`, numberAsString => resolve(parseInt(numberAsString, 10)))
451         });
452     }
453 }