Unreviewed. Fix /webkit2/WebKitWebExtension/isolated-world after r163797.
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WebKit2Gtk / TestWebExtensions.cpp
1 /*
2  * Copyright (C) 2012 Igalia S.L.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2,1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21
22 #include "WebKitTestBus.h"
23 #include "WebViewTest.h"
24 #include <wtf/gobject/GRefPtr.h>
25
26 static const char* webExtensionsUserData = "Web Extensions user data";
27 static WebKitTestBus* bus;
28 static GUniquePtr<char> scriptDialogResult;
29
30 static void testWebExtensionGetTitle(WebViewTest* test, gconstpointer)
31 {
32     test->loadHtml("<html><head><title>WebKitGTK+ Web Extensions Test</title></head><body></body></html>", 0);
33     test->waitUntilLoadFinished();
34
35     GRefPtr<GDBusProxy> proxy = adoptGRef(bus->createProxy("org.webkit.gtk.WebExtensionTest",
36         "/org/webkit/gtk/WebExtensionTest" , "org.webkit.gtk.WebExtensionTest", test->m_mainLoop));
37     GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync(
38         proxy.get(),
39         "GetTitle",
40         g_variant_new("(t)", webkit_web_view_get_page_id(test->m_webView)),
41         G_DBUS_CALL_FLAGS_NONE,
42         -1, 0, 0));
43     g_assert(result);
44
45     const char* title;
46     g_variant_get(result.get(), "(&s)", &title);
47     g_assert_cmpstr(title, ==, "WebKitGTK+ Web Extensions Test");
48 }
49
50 static void documentLoadedCallback(GDBusConnection*, const char*, const char*, const char*, const char*, GVariant*, WebViewTest* test)
51 {
52     g_main_loop_quit(test->m_mainLoop);
53 }
54
55 static void testDocumentLoadedSignal(WebViewTest* test, gconstpointer)
56 {
57     GRefPtr<GDBusProxy> proxy = adoptGRef(bus->createProxy("org.webkit.gtk.WebExtensionTest",
58         "/org/webkit/gtk/WebExtensionTest", "org.webkit.gtk.WebExtensionTest", test->m_mainLoop));
59     GDBusConnection* connection = g_dbus_proxy_get_connection(proxy.get());
60     guint id = g_dbus_connection_signal_subscribe(connection,
61         0,
62         "org.webkit.gtk.WebExtensionTest",
63         "DocumentLoaded",
64         "/org/webkit/gtk/WebExtensionTest",
65         0,
66         G_DBUS_SIGNAL_FLAGS_NONE,
67         reinterpret_cast<GDBusSignalCallback>(documentLoadedCallback),
68         test,
69         0);
70     g_assert(id);
71
72     test->loadHtml("<html><head><title>WebKitGTK+ Web Extensions Test</title></head><body></body></html>", 0);
73     g_main_loop_run(test->m_mainLoop);
74     g_dbus_connection_signal_unsubscribe(connection, id);
75 }
76
77 static gboolean webProcessCrashedCallback(WebKitWebView*, WebViewTest* test)
78 {
79     test->quitMainLoop();
80
81     return FALSE;
82 }
83
84 static void testWebKitWebViewProcessCrashed(WebViewTest* test, gconstpointer)
85 {
86     test->loadHtml("<html></html>", 0);
87     test->waitUntilLoadFinished();
88
89     g_signal_connect(test->m_webView, "web-process-crashed",
90         G_CALLBACK(webProcessCrashedCallback), test);
91
92     GRefPtr<GDBusProxy> proxy = adoptGRef(bus->createProxy("org.webkit.gtk.WebExtensionTest",
93         "/org/webkit/gtk/WebExtensionTest", "org.webkit.gtk.WebExtensionTest", test->m_mainLoop));
94
95     GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync(
96         proxy.get(),
97         "AbortProcess",
98         0,
99         G_DBUS_CALL_FLAGS_NONE,
100         -1, 0, 0));
101     g_assert(!result);
102     g_main_loop_run(test->m_mainLoop);
103 }
104
105 static void testWebExtensionWindowObjectCleared(WebViewTest* test, gconstpointer)
106 {
107     test->loadHtml("<html><header></header><body></body></html>", 0);
108     test->waitUntilLoadFinished();
109
110     GUniqueOutPtr<GError> error;
111     WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("window.echo('Foo');", &error.outPtr());
112     g_assert(javascriptResult);
113     g_assert(!error.get());
114     GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
115     g_assert_cmpstr(valueString.get(), ==, "Foo");
116 }
117
118 static gboolean scriptDialogCallback(WebKitWebView*, WebKitScriptDialog* dialog, gpointer)
119 {
120     g_assert_cmpuint(webkit_script_dialog_get_dialog_type(dialog), ==, WEBKIT_SCRIPT_DIALOG_ALERT);
121     scriptDialogResult.reset(g_strdup(webkit_script_dialog_get_message(dialog)));
122     return TRUE;
123 }
124
125 static void runJavaScriptInIsolatedWorldFinishedCallback(GDBusProxy* proxy, GAsyncResult* result, WebViewTest* test)
126 {
127     g_dbus_proxy_call_finish(proxy, result, 0);
128     g_main_loop_quit(test->m_mainLoop);
129 }
130
131 static void testWebExtensionIsolatedWorld(WebViewTest* test, gconstpointer)
132 {
133     test->loadHtml("<html><header></header><body><div id='console'></div></body></html>", 0);
134     test->waitUntilLoadFinished();
135
136     gulong scriptDialogID = g_signal_connect(test->m_webView, "script-dialog", G_CALLBACK(scriptDialogCallback), nullptr);
137
138     static const char* mainWorldScript =
139         "top.foo = 'Foo';\n"
140         "document.getElementById('console').innerHTML = top.foo;\n"
141         "window.open = function () { alert('Main World'); }\n"
142         "document.open(1, 2, 3);";
143     test->runJavaScriptAndWaitUntilFinished(mainWorldScript, 0);
144     g_assert_cmpstr(scriptDialogResult.get(), ==, "Main World");
145
146     WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementById('console').innerHTML", 0);
147     g_assert(javascriptResult);
148     GUniquePtr<char> valueString(WebViewTest::javascriptResultToCString(javascriptResult));
149     g_assert_cmpstr(valueString.get(), ==, "Foo");
150
151     static const char* isolatedWorldScript =
152         "document.getElementById('console').innerHTML = top.foo;\n"
153         "window.open = function () { alert('Isolated World'); }\n"
154         "document.open(1, 2, 3);";
155     GRefPtr<GDBusProxy> proxy = adoptGRef(bus->createProxy("org.webkit.gtk.WebExtensionTest",
156         "/org/webkit/gtk/WebExtensionTest" , "org.webkit.gtk.WebExtensionTest", test->m_mainLoop));
157     g_dbus_proxy_call(proxy.get(),
158         "RunJavaScriptInIsolatedWorld",
159         g_variant_new("(t&s)", webkit_web_view_get_page_id(test->m_webView), isolatedWorldScript),
160         G_DBUS_CALL_FLAGS_NONE,
161         -1, 0,
162         reinterpret_cast<GAsyncReadyCallback>(runJavaScriptInIsolatedWorldFinishedCallback),
163         test);
164     g_main_loop_run(test->m_mainLoop);
165     g_assert_cmpstr(scriptDialogResult.get(), ==, "Isolated World");
166
167     // Check that 'top.foo' defined in main world is not visible in isolated world.
168     javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementById('console').innerHTML", 0);
169     g_assert(javascriptResult);
170     valueString.reset(WebViewTest::javascriptResultToCString(javascriptResult));
171     g_assert_cmpstr(valueString.get(), ==, "undefined");
172
173     g_signal_handler_disconnect(test->m_webView, scriptDialogID);
174 }
175
176 static void testWebExtensionInitializationUserData(WebViewTest* test, gconstpointer)
177 {
178     test->loadHtml("<html></html>", 0);
179     test->waitUntilLoadFinished();
180
181     GRefPtr<GDBusProxy> proxy = adoptGRef(bus->createProxy("org.webkit.gtk.WebExtensionTest",
182         "/org/webkit/gtk/WebExtensionTest", "org.webkit.gtk.WebExtensionTest", test->m_mainLoop));
183
184     GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync(
185         proxy.get(),
186         "GetInitializationUserData",
187         nullptr,
188         G_DBUS_CALL_FLAGS_NONE,
189         -1, 0, 0));
190     g_assert(result);
191
192     const gchar* userData = nullptr;
193     g_variant_get(result.get(), "(&s)", &userData);
194     g_assert_cmpstr(userData, ==, webExtensionsUserData);
195 }
196
197 static void initializeWebExtensions(WebKitWebContext* context, gpointer)
198 {
199     webkit_web_context_set_web_extensions_directory(context, WEBKIT_TEST_WEB_EXTENSIONS_DIR);
200     webkit_web_context_set_web_extensions_initialization_user_data(context,
201         g_variant_new("&s", webExtensionsUserData));
202 }
203
204 void beforeAll()
205 {
206     g_signal_connect(webkit_web_context_get_default(),
207         "initialize-web-extensions", G_CALLBACK(initializeWebExtensions), nullptr);
208
209     bus = new WebKitTestBus();
210     if (!bus->run())
211         return;
212
213     WebViewTest::add("WebKitWebContext", "initialization-user-data", testWebExtensionInitializationUserData);
214     WebViewTest::add("WebKitWebExtension", "dom-document-title", testWebExtensionGetTitle);
215     WebViewTest::add("WebKitWebExtension", "document-loaded-signal", testDocumentLoadedSignal);
216     WebViewTest::add("WebKitWebView", "web-process-crashed", testWebKitWebViewProcessCrashed);
217     WebViewTest::add("WebKitWebExtension", "window-object-cleared", testWebExtensionWindowObjectCleared);
218     WebViewTest::add("WebKitWebExtension", "isolated-world", testWebExtensionIsolatedWorld);
219 }
220
221 void afterAll()
222 {
223     delete bus;
224 }