Process Swap on Navigation causes many webpages to hang due to attempted process...
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WebKitCocoa / UserContentController.mm
1 /*
2  * Copyright (C) 2014 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
28 #import "PlatformUtilities.h"
29 #import "Test.h"
30 #import "TestNavigationDelegate.h"
31 #import <WebKit/WKProcessPoolPrivate.h>
32 #import <WebKit/WKUserContentControllerPrivate.h>
33 #import <WebKit/WKUserScript.h>
34 #import <WebKit/WKUserScriptPrivate.h>
35 #import <WebKit/WebKit.h>
36 #import <WebKit/_WKProcessPoolConfiguration.h>
37 #import <WebKit/_WKUserContentWorld.h>
38 #import <WebKit/_WKUserStyleSheet.h>
39 #import <wtf/RetainPtr.h>
40
41 #if WK_API_ENABLED
42
43 static bool isDoneWithNavigation;
44
45 @interface SimpleNavigationDelegate : NSObject <WKNavigationDelegate>
46 @end
47
48 @implementation SimpleNavigationDelegate
49
50 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
51 {
52     isDoneWithNavigation = true;
53 }
54
55 @end
56
57 static bool receivedScriptMessage;
58 static RetainPtr<WKScriptMessage> lastScriptMessage;
59
60 @interface ScriptMessageHandler : NSObject <WKScriptMessageHandler>
61 @end
62
63 @implementation ScriptMessageHandler
64
65 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
66 {
67     receivedScriptMessage = true;
68     lastScriptMessage = message;
69 }
70
71 @end
72
73 TEST(WKUserContentController, ScriptMessageHandlerBasicPost)
74 {
75     RetainPtr<ScriptMessageHandler> handler = adoptNS([[ScriptMessageHandler alloc] init]);
76     RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
77     [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
78
79     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
80
81     NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
82
83     [webView loadRequest:request];
84     [webView _test_waitForDidFinishNavigation];
85
86     [webView evaluateJavaScript:@"window.webkit.messageHandlers.testHandler.postMessage('Hello')" completionHandler:nil];
87
88     TestWebKitAPI::Util::run(&receivedScriptMessage);
89     receivedScriptMessage = false;
90
91     EXPECT_WK_STREQ(@"Hello", (NSString *)[lastScriptMessage body]);
92 }
93
94 TEST(WKUserContentController, ScriptMessageHandlerBasicPostIsolatedWorld)
95 {
96     RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
97
98     RetainPtr<ScriptMessageHandler> handler = adoptNS([[ScriptMessageHandler alloc] init]);
99     RetainPtr<WKUserScript> userScript = adoptNS([[WKUserScript alloc] _initWithSource:@"window.webkit.messageHandlers.testHandler.postMessage('Hello')" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
100
101     RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
102     [[configuration userContentController] _addScriptMessageHandler:handler.get() name:@"testHandler" userContentWorld:world.get()];
103     [[configuration userContentController] addUserScript:userScript.get()];
104
105     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
106
107     RetainPtr<SimpleNavigationDelegate> delegate = adoptNS([[SimpleNavigationDelegate alloc] init]);
108     [webView setNavigationDelegate:delegate.get()];
109
110     NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
111
112     isDoneWithNavigation = false;
113     [webView loadRequest:request];
114
115     TestWebKitAPI::Util::run(&receivedScriptMessage);
116     receivedScriptMessage = false;
117
118     EXPECT_WK_STREQ(@"Hello", (NSString *)[lastScriptMessage body]);
119
120     if (!isDoneWithNavigation)
121         TestWebKitAPI::Util::run(&isDoneWithNavigation);
122
123     __block bool isDoneEvaluatingScript = false;
124     __block NSString *resultValue = @"";
125     [webView evaluateJavaScript:
126         @"var result;"
127          "if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.testHandler) {"
128          "    result = { 'result': 'FAIL' };"
129          "} else {"
130          "    result = { 'result': 'PASS' };"
131          "} " 
132          "result;"
133          completionHandler:^(id value, NSError *error) {
134             resultValue = [((NSDictionary *)value)[@"result"] copy];
135             isDoneEvaluatingScript = true;
136         }];
137
138     TestWebKitAPI::Util::run(&isDoneEvaluatingScript);
139
140     EXPECT_WK_STREQ(@"PASS", resultValue);
141 }
142
143 TEST(WKUserContentController, ScriptMessageHandlerBasicRemove)
144 {
145     RetainPtr<ScriptMessageHandler> handler = adoptNS([[ScriptMessageHandler alloc] init]);
146     RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
147     RetainPtr<WKUserContentController> userContentController = [configuration userContentController];
148     [userContentController addScriptMessageHandler:handler.get() name:@"handlerToRemove"];
149     [userContentController addScriptMessageHandler:handler.get() name:@"handlerToPost"];
150
151     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
152
153     NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
154
155     [webView loadRequest:request];
156     [webView _test_waitForDidFinishNavigation];
157
158     // Test that handlerToRemove was succesfully added.
159     [webView evaluateJavaScript:
160         @"if (window.webkit.messageHandlers.handlerToRemove) {"
161          "    window.webkit.messageHandlers.handlerToPost.postMessage('PASS');"
162          "} else {"
163          "    window.webkit.messageHandlers.handlerToPost.postMessage('FAIL');"
164          "}" completionHandler:nil];
165
166     TestWebKitAPI::Util::run(&receivedScriptMessage);
167     receivedScriptMessage = false;
168
169     EXPECT_WK_STREQ(@"PASS", (NSString *)[lastScriptMessage body]);
170
171     [userContentController removeScriptMessageHandlerForName:@"handlerToRemove"];
172
173     // Test that handlerToRemove has been removed.
174     [webView evaluateJavaScript:
175         @"if (window.webkit.messageHandlers.handlerToRemove) {"
176          "    window.webkit.messageHandlers.handlerToPost.postMessage('FAIL');"
177          "} else {"
178          "    window.webkit.messageHandlers.handlerToPost.postMessage('PASS');"
179          "}" completionHandler:nil];
180
181     TestWebKitAPI::Util::run(&receivedScriptMessage);
182     receivedScriptMessage = false;
183
184     EXPECT_WK_STREQ(@"PASS", (NSString *)[lastScriptMessage body]);
185 }
186
187 TEST(WKUserContentController, ScriptMessageHandlerCallRemovedHandler)
188 {
189     RetainPtr<ScriptMessageHandler> handler = adoptNS([[ScriptMessageHandler alloc] init]);
190     RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
191     RetainPtr<WKUserContentController> userContentController = [configuration userContentController];
192     [userContentController addScriptMessageHandler:handler.get() name:@"handlerToRemove"];
193     [userContentController addScriptMessageHandler:handler.get() name:@"handlerToPost"];
194
195     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
196
197     NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
198
199     [webView loadRequest:request];
200     [webView _test_waitForDidFinishNavigation];
201
202     [webView evaluateJavaScript:@"var handlerToRemove = window.webkit.messageHandlers.handlerToRemove;" completionHandler:nil];
203
204     [userContentController removeScriptMessageHandlerForName:@"handlerToRemove"];
205
206     // Test that we throw an exception if you try to use a message handler that has been removed.
207     [webView evaluateJavaScript:
208         @"try {"
209          "    handlerToRemove.postMessage('FAIL');"
210          "} catch (e) {"
211          "    window.webkit.messageHandlers.handlerToPost.postMessage('PASS');"
212          "}" completionHandler:nil];
213
214     TestWebKitAPI::Util::run(&receivedScriptMessage);
215     receivedScriptMessage = false;
216
217     EXPECT_WK_STREQ(@"PASS", (NSString *)[lastScriptMessage body]);
218 }
219
220 static RetainPtr<WKWebView> webViewForScriptMessageHandlerMultipleHandlerRemovalTest(WKWebViewConfiguration *configuration)
221 {
222     RetainPtr<ScriptMessageHandler> handler = adoptNS([[ScriptMessageHandler alloc] init]);
223     RetainPtr<WKWebViewConfiguration> configurationCopy = adoptNS([configuration copy]);
224     [configurationCopy setUserContentController:[[[WKUserContentController alloc] init] autorelease]];
225     [[configurationCopy userContentController] addScriptMessageHandler:handler.get() name:@"handlerToRemove"];
226     [[configurationCopy userContentController] addScriptMessageHandler:handler.get() name:@"handlerToPost"];
227     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configurationCopy.get()]);
228     NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
229     [webView loadRequest:request];
230     [webView _test_waitForDidFinishNavigation];
231
232     return webView;
233 }
234
235 TEST(WKUserContentController, ScriptMessageHandlerMultipleHandlerRemoval)
236 {
237     RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
238     RetainPtr<_WKProcessPoolConfiguration> processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
239     [processPoolConfiguration setMaximumProcessCount:1];
240     [configuration setProcessPool:[[[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()] autorelease]];
241
242     RetainPtr<WKWebView> webView = webViewForScriptMessageHandlerMultipleHandlerRemovalTest(configuration.get());
243     RetainPtr<WKWebView> webView2 = webViewForScriptMessageHandlerMultipleHandlerRemovalTest(configuration.get());
244
245     [[[webView configuration] userContentController] removeScriptMessageHandlerForName:@"handlerToRemove"];
246     [[[webView2 configuration] userContentController] removeScriptMessageHandlerForName:@"handlerToRemove"];
247
248     [webView evaluateJavaScript:
249      @"try {"
250      "    handlerToRemove.postMessage('FAIL');"
251      "} catch (e) {"
252      "    window.webkit.messageHandlers.handlerToPost.postMessage('PASS');"
253      "}" completionHandler:nil];
254
255     TestWebKitAPI::Util::run(&receivedScriptMessage);
256     receivedScriptMessage = false;
257
258     EXPECT_WK_STREQ(@"PASS", (NSString *)[lastScriptMessage body]);
259 }
260
261 #if !PLATFORM(IOS) // FIXME: hangs in the iOS simulator
262 TEST(WKUserContentController, ScriptMessageHandlerWithNavigation)
263 {
264     RetainPtr<ScriptMessageHandler> handler = adoptNS([[ScriptMessageHandler alloc] init]);
265     RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
266     [[configuration userContentController] addScriptMessageHandler:handler.get() name:@"testHandler"];
267
268     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
269
270     NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
271     [webView loadRequest:request];
272     [webView _test_waitForDidFinishNavigation];
273
274     [webView evaluateJavaScript:@"window.webkit.messageHandlers.testHandler.postMessage('First Message')" completionHandler:nil];
275
276     TestWebKitAPI::Util::run(&receivedScriptMessage);
277
278     EXPECT_WK_STREQ(@"First Message", (NSString *)[lastScriptMessage body]);
279     
280     receivedScriptMessage = false;
281     lastScriptMessage = nullptr;
282
283     [webView loadRequest:request];
284     [webView _test_waitForDidFinishNavigation];
285
286     [webView evaluateJavaScript:@"window.webkit.messageHandlers.testHandler.postMessage('Second Message')" completionHandler:nil];
287
288     TestWebKitAPI::Util::run(&receivedScriptMessage);
289
290     EXPECT_WK_STREQ(@"Second Message", (NSString *)[lastScriptMessage body]);    
291 }
292 #endif
293
294 TEST(WKUserContentController, ScriptMessageHandlerReplaceWithSameName)
295 {
296     RetainPtr<ScriptMessageHandler> handler = adoptNS([[ScriptMessageHandler alloc] init]);
297     RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
298     RetainPtr<WKUserContentController> userContentController = [configuration userContentController];
299     [userContentController addScriptMessageHandler:handler.get() name:@"handlerToReplace"];
300
301     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
302
303     NSURLRequest *request = [NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]];
304
305     [webView loadRequest:request];
306     [webView _test_waitForDidFinishNavigation];
307
308     // Test that handlerToReplace was succesfully added.
309     [webView evaluateJavaScript:@"window.webkit.messageHandlers.handlerToReplace.postMessage('PASS1');" completionHandler:nil];
310
311     TestWebKitAPI::Util::run(&receivedScriptMessage);
312     receivedScriptMessage = false;
313
314     EXPECT_WK_STREQ(@"PASS1", (NSString *)[lastScriptMessage body]);
315
316     [userContentController removeScriptMessageHandlerForName:@"handlerToReplace"];
317     [userContentController addScriptMessageHandler:handler.get() name:@"handlerToReplace"];
318
319     // Test that handlerToReplace still works.
320     [webView evaluateJavaScript:@"window.webkit.messageHandlers.handlerToReplace.postMessage('PASS2');" completionHandler:nil];
321
322     TestWebKitAPI::Util::run(&receivedScriptMessage);
323     receivedScriptMessage = false;
324
325     EXPECT_WK_STREQ(@"PASS2", (NSString *)[lastScriptMessage body]);
326 }
327
328 static NSString *styleSheetSource = @"body { background-color: green !important; }";
329 static NSString *backgroundColorScript = @"window.getComputedStyle(document.body, null).getPropertyValue('background-color')";
330 static NSString *frameBackgroundColorScript = @"window.getComputedStyle(document.getElementsByTagName('iframe')[0].contentDocument.body, null).getPropertyValue('background-color')";
331 static const char* greenInRGB = "rgb(0, 128, 0)";
332 static const char* redInRGB = "rgb(255, 0, 0)";
333 static const char* whiteInRGB = "rgba(0, 0, 0, 0)";
334
335 static void expectScriptEvaluatesToColor(WKWebView *webView, NSString *script, const char* color)
336 {
337     static bool didCheckBackgroundColor;
338
339     [webView evaluateJavaScript:script completionHandler:^ (id value, NSError * error) {
340         EXPECT_TRUE([value isKindOfClass:[NSString class]]);
341         EXPECT_WK_STREQ(color, value);
342         didCheckBackgroundColor = true;
343     }];
344
345     TestWebKitAPI::Util::run(&didCheckBackgroundColor);
346     didCheckBackgroundColor = false;
347 }
348
349 TEST(WKUserContentController, AddUserStyleSheetBeforeCreatingView)
350 {
351     RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
352
353     RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:YES]);
354     [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
355
356     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
357
358     [webView loadHTMLString:@"<body style='background-color: red;'></body>" baseURL:nil];
359     [webView _test_waitForDidFinishNavigation];
360
361     expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, greenInRGB);
362 }
363
364 TEST(WKUserContentController, NonCanonicalizedURL)
365 {
366     RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
367     RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] baseURL:[[NSURL alloc] initWithString:@"http://CamelCase/"] userContentWorld:world.get()]);
368 }
369
370 TEST(WKUserContentController, AddUserStyleSheetAfterCreatingView)
371 {
372     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
373
374     [webView loadHTMLString:@"<body style='background-color: red;'></body>" baseURL:nil];
375     [webView _test_waitForDidFinishNavigation];
376
377     expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, redInRGB);
378
379     RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:YES]);
380     [[webView configuration].userContentController _addUserStyleSheet:styleSheet.get()];
381
382     expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, greenInRGB);
383 }
384
385 TEST(WKUserContentController, UserStyleSheetAffectingOnlyMainFrame)
386 {
387     RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
388
389     RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:YES]);
390     [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
391
392     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
393
394     [webView loadHTMLString:@"<body style='background-color: red;'><iframe></iframe></body>" baseURL:nil];
395     [webView _test_waitForDidFinishNavigation];
396
397     // The main frame should be affected.
398     expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, greenInRGB);
399
400     // The subframe shouldn't be affected.
401     expectScriptEvaluatesToColor(webView.get(), frameBackgroundColorScript, whiteInRGB);
402 }
403
404 TEST(WKUserContentController, UserStyleSheetAffectingAllFrames)
405 {
406     RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
407
408     RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO]);
409     [[configuration userContentController] _addUserStyleSheet:styleSheet.get()];
410
411     RetainPtr<WKWebView> webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
412
413     [webView loadHTMLString:@"<body style='background-color: red;'><iframe></iframe></body>" baseURL:nil];
414     [webView _test_waitForDidFinishNavigation];
415
416     // The main frame should be affected.
417     expectScriptEvaluatesToColor(webView.get(), backgroundColorScript, greenInRGB);
418
419     // The subframe should also be affected.
420     expectScriptEvaluatesToColor(webView.get(), frameBackgroundColorScript, greenInRGB);
421 }
422
423 TEST(WKUserContentController, UserStyleSheetRemove)
424 {
425     RetainPtr<WKUserContentController> userContentController = adoptNS([[WKUserContentController alloc] init]);
426     RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO]);
427     [userContentController _addUserStyleSheet:styleSheet.get()];
428     
429     EXPECT_EQ(1u, [userContentController _userStyleSheets].count);
430     EXPECT_EQ(styleSheet.get(), [userContentController _userStyleSheets][0]);
431
432     [userContentController _removeUserStyleSheet:styleSheet.get()];
433
434     EXPECT_EQ(0u, [userContentController _userStyleSheets].count);
435 }
436
437 TEST(WKUserContentController, UserStyleSheetRemoveAll)
438 {
439     RetainPtr<WKUserContentController> userContentController = adoptNS([[WKUserContentController alloc] init]);
440
441     RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
442
443     RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO]);
444     RetainPtr<_WKUserStyleSheet> styleSheetAssociatedWithWorld = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
445     
446     [userContentController _addUserStyleSheet:styleSheet.get()];
447     [userContentController _addUserStyleSheet:styleSheetAssociatedWithWorld.get()];
448     
449     EXPECT_EQ(2u, [userContentController _userStyleSheets].count);
450     EXPECT_EQ(styleSheet.get(), [userContentController _userStyleSheets][0]);
451     EXPECT_EQ(styleSheetAssociatedWithWorld.get(), [userContentController _userStyleSheets][1]);
452
453     [userContentController _removeAllUserStyleSheets];
454
455     EXPECT_EQ(0u, [userContentController _userStyleSheets].count);
456 }
457
458 TEST(WKUserContentController, UserStyleSheetRemoveAllByWorld)
459 {
460     RetainPtr<WKUserContentController> userContentController = adoptNS([[WKUserContentController alloc] init]);
461
462     RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
463
464     RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO]);
465     RetainPtr<_WKUserStyleSheet> styleSheetAssociatedWithWorld = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
466     RetainPtr<_WKUserStyleSheet> styleSheetAssociatedWithWorld2 = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
467     
468     [userContentController _addUserStyleSheet:styleSheet.get()];
469     [userContentController _addUserStyleSheet:styleSheetAssociatedWithWorld.get()];
470     [userContentController _addUserStyleSheet:styleSheetAssociatedWithWorld2.get()];
471     
472     EXPECT_EQ(3u, [userContentController _userStyleSheets].count);
473     EXPECT_EQ(styleSheet.get(), [userContentController _userStyleSheets][0]);
474     EXPECT_EQ(styleSheetAssociatedWithWorld.get(), [userContentController _userStyleSheets][1]);
475     EXPECT_EQ(styleSheetAssociatedWithWorld2.get(), [userContentController _userStyleSheets][2]);
476
477     [userContentController _removeAllUserStyleSheetsAssociatedWithUserContentWorld:world.get()];
478
479     EXPECT_EQ(1u, [userContentController _userStyleSheets].count);
480     EXPECT_EQ(styleSheet.get(), [userContentController _userStyleSheets][0]);
481 }
482
483 TEST(WKUserContentController, UserStyleSheetRemoveAllByNormalWorld)
484 {
485     RetainPtr<WKUserContentController> userContentController = adoptNS([[WKUserContentController alloc] init]);
486
487     RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
488
489     RetainPtr<_WKUserStyleSheet> styleSheet = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO]);
490     RetainPtr<_WKUserStyleSheet> styleSheetAssociatedWithWorld = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
491     RetainPtr<_WKUserStyleSheet> styleSheetAssociatedWithWorld2 = adoptNS([[_WKUserStyleSheet alloc] initWithSource:styleSheetSource forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
492     
493     [userContentController _addUserStyleSheet:styleSheet.get()];
494     [userContentController _addUserStyleSheet:styleSheetAssociatedWithWorld.get()];
495     [userContentController _addUserStyleSheet:styleSheetAssociatedWithWorld2.get()];
496     
497     EXPECT_EQ(3u, [userContentController _userStyleSheets].count);
498     EXPECT_EQ(styleSheet.get(), [userContentController _userStyleSheets][0]);
499     EXPECT_EQ(styleSheetAssociatedWithWorld.get(), [userContentController _userStyleSheets][1]);
500     EXPECT_EQ(styleSheetAssociatedWithWorld2.get(), [userContentController _userStyleSheets][2]);
501
502     [userContentController _removeAllUserStyleSheetsAssociatedWithUserContentWorld:[_WKUserContentWorld normalWorld]];
503
504     EXPECT_EQ(2u, [userContentController _userStyleSheets].count);
505     EXPECT_EQ(styleSheetAssociatedWithWorld.get(), [userContentController _userStyleSheets][0]);
506     EXPECT_EQ(styleSheetAssociatedWithWorld2.get(), [userContentController _userStyleSheets][1]);
507 }
508
509 TEST(WKUserContentController, UserScriptRemove)
510 {
511     RetainPtr<WKUserContentController> userContentController = adoptNS([[WKUserContentController alloc] init]);
512     RetainPtr<WKUserScript> userScript = adoptNS([[WKUserScript alloc] initWithSource:@"" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO]);
513     [userContentController addUserScript:userScript.get()];
514     
515     EXPECT_EQ(1u, [userContentController userScripts].count);
516     EXPECT_EQ(userScript.get(), [userContentController userScripts][0]);
517
518     [userContentController _removeUserScript:userScript.get()];
519
520     EXPECT_EQ(0u, [userContentController userScripts].count);
521 }
522
523 TEST(WKUserContentController, UserScriptRemoveAll)
524 {
525     RetainPtr<WKUserContentController> userContentController = adoptNS([[WKUserContentController alloc] init]);
526
527     RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
528
529     RetainPtr<WKUserScript> userScript = adoptNS([[WKUserScript alloc] initWithSource:@"" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO]);
530     RetainPtr<WKUserScript> userScriptAssociatedWithWorld = adoptNS([[WKUserScript alloc] _initWithSource:@"" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
531     
532     [userContentController addUserScript:userScript.get()];
533     [userContentController addUserScript:userScriptAssociatedWithWorld.get()];
534     
535     EXPECT_EQ(2u, [userContentController userScripts].count);
536     EXPECT_EQ(userScript.get(), [userContentController userScripts][0]);
537     EXPECT_EQ(userScriptAssociatedWithWorld.get(), [userContentController userScripts][1]);
538
539     [userContentController removeAllUserScripts];
540
541     EXPECT_EQ(0u, [userContentController userScripts].count);
542 }
543
544 TEST(WKUserContentController, UserScriptRemoveAllByWorld)
545 {
546     RetainPtr<WKUserContentController> userContentController = adoptNS([[WKUserContentController alloc] init]);
547
548     RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
549
550     RetainPtr<WKUserScript> userScript = adoptNS([[WKUserScript alloc] initWithSource:@"" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO]);
551     RetainPtr<WKUserScript> userScriptAssociatedWithWorld = adoptNS([[WKUserScript alloc] _initWithSource:@"" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
552     RetainPtr<WKUserScript> userScriptAssociatedWithWorld2 = adoptNS([[WKUserScript alloc] _initWithSource:@"" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
553     
554     [userContentController addUserScript:userScript.get()];
555     [userContentController addUserScript:userScriptAssociatedWithWorld.get()];
556     [userContentController addUserScript:userScriptAssociatedWithWorld2.get()];
557     
558     EXPECT_EQ(3u, [userContentController userScripts].count);
559     EXPECT_EQ(userScript.get(), [userContentController userScripts][0]);
560     EXPECT_EQ(userScriptAssociatedWithWorld.get(), [userContentController userScripts][1]);
561     EXPECT_EQ(userScriptAssociatedWithWorld2.get(), [userContentController userScripts][2]);
562
563     [userContentController _removeAllUserScriptsAssociatedWithUserContentWorld:world.get()];
564
565     EXPECT_EQ(1u, [userContentController userScripts].count);
566     EXPECT_EQ(userScript.get(), [userContentController userScripts][0]);
567 }
568
569 TEST(WKUserContentController, UserScriptRemoveAllByNormalWorld)
570 {
571     RetainPtr<WKUserContentController> userContentController = adoptNS([[WKUserContentController alloc] init]);
572
573     RetainPtr<_WKUserContentWorld> world = [_WKUserContentWorld worldWithName:@"TestWorld"];
574
575     RetainPtr<WKUserScript> userScript = adoptNS([[WKUserScript alloc] initWithSource:@"" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO]);
576     RetainPtr<WKUserScript> userScriptAssociatedWithWorld = adoptNS([[WKUserScript alloc] _initWithSource:@"" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
577     RetainPtr<WKUserScript> userScriptAssociatedWithWorld2 = adoptNS([[WKUserScript alloc] _initWithSource:@"" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO legacyWhitelist:@[] legacyBlacklist:@[] userContentWorld:world.get()]);
578     
579     [userContentController addUserScript:userScript.get()];
580     [userContentController addUserScript:userScriptAssociatedWithWorld.get()];
581     [userContentController addUserScript:userScriptAssociatedWithWorld2.get()];
582     
583     EXPECT_EQ(3u, [userContentController userScripts].count);
584     EXPECT_EQ(userScript.get(), [userContentController userScripts][0]);
585     EXPECT_EQ(userScriptAssociatedWithWorld.get(), [userContentController userScripts][1]);
586     EXPECT_EQ(userScriptAssociatedWithWorld2.get(), [userContentController userScripts][2]);
587
588     [userContentController _removeAllUserScriptsAssociatedWithUserContentWorld:[_WKUserContentWorld normalWorld]];
589
590     EXPECT_EQ(2u, [userContentController userScripts].count);
591     EXPECT_EQ(userScriptAssociatedWithWorld.get(), [userContentController userScripts][0]);
592     EXPECT_EQ(userScriptAssociatedWithWorld2.get(), [userContentController userScripts][1]);
593 }
594
595 #endif