• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 Holger Hans Peter Freyther
3  * Copyright (C) 2009 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public License
16  * along with this library; see the file COPYING.LIB.  If not, write to
17  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #include <errno.h>
22 #include <unistd.h>
23 #include <glib.h>
24 #include <glib/gstdio.h>
25 #include <gtk/gtk.h>
26 #include <webkit/webkit.h>
27 
28 #if GTK_CHECK_VERSION(2, 14, 0)
29 
30 static int numberOfFramesCreated = 0;
31 
createFrameSignalTestFrameCreatedCallback(WebKitWebView * webView,WebKitWebFrame * frame,gpointer data)32 static void createFrameSignalTestFrameCreatedCallback(WebKitWebView* webView, WebKitWebFrame* frame, gpointer data)
33 {
34     numberOfFramesCreated++;
35 }
36 
createFrameSignalTestTimeout(gpointer data)37 static gboolean createFrameSignalTestTimeout(gpointer data)
38 {
39     g_assert_cmpint(numberOfFramesCreated, ==, 2);
40     g_main_loop_quit((GMainLoop*) data);
41     return FALSE;
42 }
43 
test_webkit_web_frame_created_signal(void)44 static void test_webkit_web_frame_created_signal(void)
45 {
46     GtkWidget* webView;
47     GtkWidget* window;
48     GMainLoop* loop = g_main_loop_new(NULL, TRUE);
49 
50     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
51 
52     webView = webkit_web_view_new();
53     g_signal_connect(webView, "frame-created", G_CALLBACK(createFrameSignalTestFrameCreatedCallback), loop);
54 
55     // We want to ensure that exactly two create-frame signals are
56     // fired and no more, so we set a timeout here. There does not appear
57     // to be a simple way via the API to figure out when all frames have
58     // loaded.
59     g_timeout_add(500, createFrameSignalTestTimeout, loop);
60 
61     gtk_container_add(GTK_CONTAINER(window), webView);
62     gtk_widget_show(window);
63     gtk_widget_show(webView);
64 
65     webkit_web_view_load_string(WEBKIT_WEB_VIEW(webView),
66         "<html><body>Frames!"
67         "<iframe></iframe>"
68         "<iframe></iframe>"
69         "</body></html>",
70         "text/html", "utf-8", "file://");
71     g_main_loop_run(loop);
72 }
73 
test_webkit_web_frame_create_destroy(void)74 static void test_webkit_web_frame_create_destroy(void)
75 {
76     GtkWidget *webView;
77     GtkWidget *window;
78 
79     g_test_bug("21837");
80     webView = webkit_web_view_new();
81     g_object_ref_sink(webView);
82     g_assert_cmpint(G_OBJECT(webView)->ref_count, ==, 1);
83     // This crashed with the original version
84     g_object_unref(webView);
85 
86     g_test_bug("25042");
87     window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
88     webView = webkit_web_view_new();
89     gtk_container_add(GTK_CONTAINER(window), webView);
90     gtk_widget_show(window);
91     gtk_widget_show(webView);
92     gtk_widget_destroy(webView);
93 }
94 
test_webkit_web_frame_lifetime(void)95 static void test_webkit_web_frame_lifetime(void)
96 {
97     WebKitWebView* webView;
98     WebKitWebFrame* webFrame;
99     g_test_bug("21837");
100 
101     webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
102     g_object_ref_sink(webView);
103     g_assert_cmpint(G_OBJECT(webView)->ref_count, ==, 1);
104     webFrame = webkit_web_view_get_main_frame(webView);
105     g_assert_cmpint(G_OBJECT(webFrame)->ref_count, ==, 1);
106 
107     // Add dummy reference on the WebKitWebFrame to keep it alive
108     g_object_ref(webFrame);
109     g_assert_cmpint(G_OBJECT(webFrame)->ref_count, ==, 2);
110 
111     // This crashed with the original version
112     g_object_unref(webView);
113 
114     // Make sure that the frame got deleted as well. We did this
115     // by adding an extra ref on the WebKitWebFrame and we should
116     // be the one holding the last reference.
117     g_assert_cmpint(G_OBJECT(webFrame)->ref_count, ==, 1);
118     g_object_unref(webFrame);
119 }
120 
print_requested_cb(WebKitWebView * webView,WebKitWebFrame * webFrame,GMainLoop * loop)121 static gboolean print_requested_cb(WebKitWebView* webView, WebKitWebFrame* webFrame, GMainLoop* loop)
122 {
123     g_object_set_data(G_OBJECT(webView), "signal-handled", GINT_TO_POINTER(TRUE));
124     g_main_loop_quit(loop);
125     return TRUE;
126 }
127 
print_timeout(GMainLoop * loop)128 static void print_timeout(GMainLoop* loop)
129 {
130     if (g_main_loop_is_running(loop))
131         g_main_loop_quit(loop);
132 }
133 
test_webkit_web_frame_printing(void)134 static void test_webkit_web_frame_printing(void)
135 {
136     WebKitWebView* webView;
137 
138     webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
139     g_object_ref_sink(webView);
140     g_assert_cmpint(G_OBJECT(webView)->ref_count, ==, 1);
141 
142     webkit_web_view_load_string(webView,
143                                 "<html><body><h1>WebKitGTK+!</h1></body></html>",
144                                 "text/html",
145                                 "utf-8",
146                                 "file://");
147 
148     GMainLoop* loop = g_main_loop_new(NULL, TRUE);
149 
150     // Does javascript print() work correctly?
151     g_signal_connect(webView, "print-requested",
152                      G_CALLBACK(print_requested_cb),
153                      loop);
154 
155     g_object_set_data(G_OBJECT(webView), "signal-handled", GINT_TO_POINTER(FALSE));
156     webkit_web_view_execute_script (webView, "print();");
157 
158     // Give javascriptcore some time to process the print request, but
159     // prepare a timeout to avoid it running forever in case the signal is
160     // never emitted.
161     g_timeout_add(1000, (GSourceFunc)print_timeout, loop);
162     g_main_loop_run(loop);
163 
164     g_assert_cmpint(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(webView), "signal-handled")), ==, TRUE);
165 
166     // Does printing directly to a file?
167     GError *error = NULL;
168     gchar* temporaryFilename = NULL;
169     gint fd = g_file_open_tmp ("webkit-testwebframe-XXXXXX", &temporaryFilename, &error);
170     close(fd);
171 
172     if (error) {
173         g_critical("Failed to open a temporary file for writing: %s.", error->message);
174         g_error_free(error);
175         goto cleanup;
176     }
177 
178     // We delete the file, so that we can easily figure out that the
179     // file got printed;
180     if (g_unlink(temporaryFilename) == -1) {
181         g_warning("Failed to delete the temporary file: %s.\nThis may cause the test to be bogus.", g_strerror(errno));
182     }
183 
184     WebKitWebFrame* webFrame = webkit_web_view_get_main_frame(webView);
185     GtkPrintOperation* operation = gtk_print_operation_new();
186     GtkPrintOperationAction action = GTK_PRINT_OPERATION_ACTION_EXPORT;
187     GtkPrintOperationResult result;
188 
189     gtk_print_operation_set_export_filename(operation, temporaryFilename);
190     result = webkit_web_frame_print_full (webFrame, operation, action, NULL);
191 
192     g_assert_cmpint(result, ==, GTK_PRINT_OPERATION_RESULT_APPLY);
193     g_assert_cmpint(g_file_test(temporaryFilename, G_FILE_TEST_IS_REGULAR), ==, TRUE);
194 
195     g_unlink(temporaryFilename);
196     g_object_unref(operation);
197 cleanup:
198     g_object_unref(webView);
199     g_free(temporaryFilename);
200 }
201 
test_webkit_web_frame_response()202 static void test_webkit_web_frame_response()
203 {
204     WebKitWebFrame* frame = g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL);
205     WebKitNetworkResponse* response = webkit_web_frame_get_network_response(frame);
206     g_assert(!response);
207     g_object_unref(frame);
208 }
209 
main(int argc,char ** argv)210 int main(int argc, char** argv)
211 {
212     g_thread_init(NULL);
213     gtk_test_init(&argc, &argv, NULL);
214 
215     g_test_bug_base("https://bugs.webkit.org/");
216     g_test_add_func("/webkit/webview/create_destroy", test_webkit_web_frame_create_destroy);
217     g_test_add_func("/webkit/webview/frame-created_signal", test_webkit_web_frame_created_signal);
218     g_test_add_func("/webkit/webframe/lifetime", test_webkit_web_frame_lifetime);
219     g_test_add_func("/webkit/webview/printing", test_webkit_web_frame_printing);
220     g_test_add_func("/webkit/webview/response", test_webkit_web_frame_response);
221     return g_test_run ();
222 }
223 
224 #else
main(int argc,char ** argv)225 int main(int argc, char** argv)
226 {
227     g_critical("You will need gtk-2.14.0 to run the unit tests. Doing nothing now.");
228     return 0;
229 }
230 
231 #endif
232