Swipe gesture tests don't work on macOS Sierra
[WebKit-https.git] / Tools / WebKitTestRunner / mac / UIScriptControllerMac.mm
1 /*
2  * Copyright (C) 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "UIScriptController.h"
28
29 #import "EventSerializerMac.h"
30 #import "PlatformWebView.h"
31 #import "SharedEventStreamsMac.h"
32 #import "TestController.h"
33 #import "PlatformWebView.h"
34 #import "StringFunctions.h"
35 #import "TestController.h"
36 #import "TestRunnerWKWebView.h"
37 #import "UIScriptContext.h"
38 #import <JavaScriptCore/JSContext.h>
39 #import <JavaScriptCore/JSStringRefCF.h>
40 #import <JavaScriptCore/JSValue.h>
41 #import <JavaScriptCore/JavaScriptCore.h>
42 #import <JavaScriptCore/OpaqueJSString.h>
43 #import <WebKit/WKWebViewPrivate.h>
44
45 namespace WTR {
46
47 NSString *nsString(JSStringRef string)
48 {
49     return (NSString *)adoptCF(JSStringCopyCFString(kCFAllocatorDefault, string)).autorelease();
50 }
51
52 void UIScriptController::doAsyncTask(JSValueRef callback)
53 {
54     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
55
56     dispatch_async(dispatch_get_main_queue(), ^{
57         if (!m_context)
58             return;
59         m_context->asyncTaskComplete(callbackID);
60     });
61 }
62
63 void UIScriptController::doAfterPresentationUpdate(JSValueRef callback)
64 {
65     return doAsyncTask(callback);
66 }
67
68 void UIScriptController::doAfterNextStablePresentationUpdate(JSValueRef callback)
69 {
70     doAsyncTask(callback);
71 }
72
73 void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef callback)
74 {
75     doAsyncTask(callback);
76 }
77
78 void UIScriptController::insertText(JSStringRef text, int location, int length)
79 {
80 #if WK_API_ENABLED
81     if (location == -1)
82         location = NSNotFound;
83
84     auto* webView = TestController::singleton().mainWebView()->platformView();
85     [webView _insertText:nsString(text) replacementRange:NSMakeRange(location, length)];
86 #else
87     UNUSED_PARAM(text);
88     UNUSED_PARAM(location);
89     UNUSED_PARAM(length);
90 #endif
91 }
92
93 void UIScriptController::zoomToScale(double scale, JSValueRef callback)
94 {
95 #if WK_API_ENABLED
96     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
97
98     auto* webView = TestController::singleton().mainWebView()->platformView();
99     [webView _setPageScale:scale withOrigin:CGPointZero];
100
101     [webView _doAfterNextPresentationUpdate: ^ {
102         if (!m_context)
103             return;
104         m_context->asyncTaskComplete(callbackID);
105     }];
106 #else
107     UNUSED_PARAM(scale);
108     UNUSED_PARAM(callback);
109 #endif
110 }
111
112 void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValueRef callback)
113 {
114 #if WK_API_ENABLED
115     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
116
117     auto* webView = TestController::singleton().mainWebView()->platformView();
118     NSNotificationCenter *center = [[NSWorkspace sharedWorkspace] notificationCenter];
119     [center postNotificationName:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification object:webView];
120
121     [webView _doAfterNextPresentationUpdate: ^{
122         if (!m_context)
123             return;
124         m_context->asyncTaskComplete(callbackID);
125     }];
126 #else
127     UNUSED_PARAM(callback);
128 #endif
129 }
130
131 JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const
132 {
133 #if WK_API_ENABLED
134     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
135     NSDictionary *contentDictionary = [webView _contentsOfUserInterfaceItem:toWTFString(toWK(interfaceItem))];
136     return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:contentDictionary inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr);
137 #else
138     UNUSED_PARAM(interfaceItem);
139     return nullptr;
140 #endif
141 }
142
143 void UIScriptController::overridePreference(JSStringRef preferenceRef, JSStringRef valueRef)
144 {
145 #if WK_API_ENABLED
146     TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView();
147     WKPreferences *preferences = webView.configuration.preferences;
148
149     String preference = toWTFString(toWK(preferenceRef));
150     String value = toWTFString(toWK(valueRef));
151     if (preference == "WebKitMinimumFontSize")
152         preferences.minimumFontSize = value.toDouble();
153 #else
154     UNUSED_PARAM(preferenceRef);
155     UNUSED_PARAM(valueRef);
156 #endif
157 }
158
159 void UIScriptController::removeViewFromWindow(JSValueRef callback)
160 {
161 #if WK_API_ENABLED
162     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
163
164     auto* mainWebView = TestController::singleton().mainWebView();
165     mainWebView->removeFromWindow();
166
167     [mainWebView->platformView() _doAfterNextPresentationUpdate: ^ {
168         if (!m_context)
169             return;
170         m_context->asyncTaskComplete(callbackID);
171     }];
172 #else
173     UNUSED_PARAM(callback);
174 #endif
175 }
176
177 void UIScriptController::addViewToWindow(JSValueRef callback)
178 {
179 #if WK_API_ENABLED
180     unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
181
182     auto* mainWebView = TestController::singleton().mainWebView();
183     mainWebView->addToWindow();
184
185     [mainWebView->platformView() _doAfterNextPresentationUpdate: ^ {
186         if (!m_context)
187             return;
188         m_context->asyncTaskComplete(callbackID);
189     }];
190 #else
191     UNUSED_PARAM(callback);
192 #endif
193 }
194
195 static void playBackEvents(UIScriptContext *context, NSString *eventStream, JSValueRef callback)
196 {
197     NSError *error = nil;
198     NSArray *eventDicts = [NSJSONSerialization JSONObjectWithData:[eventStream dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error];
199
200     if (error) {
201         NSLog(@"ERROR: %@", error);
202         return;
203     }
204
205     unsigned callbackID = context->prepareForAsyncTask(callback, CallbackTypeNonPersistent);
206
207     NSWindow *window = [TestController::singleton().mainWebView()->platformView() window];
208
209     [EventStreamPlayer playStream:eventDicts window:window completionHandler:^ {
210         context->asyncTaskComplete(callbackID);
211     }];
212 }
213
214 void UIScriptController::beginBackSwipe(JSValueRef callback)
215 {
216     playBackEvents(m_context, beginSwipeBackEventStream(), callback);
217 }
218
219 void UIScriptController::completeBackSwipe(JSValueRef callback)
220 {
221     playBackEvents(m_context, completeSwipeBackEventStream(), callback);
222 }
223
224 void UIScriptController::platformPlayBackEventStream(JSStringRef eventStream, JSValueRef callback)
225 {
226     RetainPtr<CFStringRef> stream = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, eventStream));
227     playBackEvents(m_context, (NSString *)stream.get(), callback);
228 }
229
230 } // namespace WTR