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 "autotoolsconfig.h" 22#include <errno.h> 23#include <unistd.h> 24#include <glib.h> 25#include <glib/gstdio.h> 26#include <gtk/gtk.h> 27#include <webkit/webkit.h> 28 29static int numberOfFramesCreated = 0; 30 31static void createFrameSignalTestFrameCreatedCallback(WebKitWebView* webView, WebKitWebFrame* frame, gpointer data) 32{ 33 numberOfFramesCreated++; 34} 35 36static gboolean createFrameSignalTestTimeout(gpointer data) 37{ 38 g_assert_cmpint(numberOfFramesCreated, ==, 2); 39 g_main_loop_quit((GMainLoop*) data); 40 return FALSE; 41} 42 43static void test_webkit_web_frame_created_signal(void) 44{ 45 GtkWidget* webView; 46 GtkWidget* window; 47 GMainLoop* loop = g_main_loop_new(NULL, TRUE); 48 49 window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 50 51 webView = webkit_web_view_new(); 52 g_signal_connect(webView, "frame-created", G_CALLBACK(createFrameSignalTestFrameCreatedCallback), loop); 53 54 // We want to ensure that exactly two create-frame signals are 55 // fired and no more, so we set a timeout here. There does not appear 56 // to be a simple way via the API to figure out when all frames have 57 // loaded. 58 g_timeout_add(500, createFrameSignalTestTimeout, loop); 59 60 gtk_container_add(GTK_CONTAINER(window), webView); 61 gtk_widget_show(window); 62 gtk_widget_show(webView); 63 64 webkit_web_view_load_string(WEBKIT_WEB_VIEW(webView), 65 "<html><body>Frames!" 66 "<iframe></iframe>" 67 "<iframe></iframe>" 68 "</body></html>", 69 "text/html", "utf-8", "file://"); 70 g_main_loop_run(loop); 71} 72 73static void test_webkit_web_frame_create_destroy(void) 74{ 75 GtkWidget *webView; 76 GtkWidget *window; 77 78 g_test_bug("21837"); 79 webView = webkit_web_view_new(); 80 g_object_ref_sink(webView); 81 g_assert_cmpint(G_OBJECT(webView)->ref_count, ==, 1); 82 // This crashed with the original version 83 g_object_unref(webView); 84 85 g_test_bug("25042"); 86 window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 87 webView = webkit_web_view_new(); 88 gtk_container_add(GTK_CONTAINER(window), webView); 89 gtk_widget_show(window); 90 gtk_widget_show(webView); 91 gtk_widget_destroy(webView); 92} 93 94static void test_webkit_web_frame_lifetime(void) 95{ 96 WebKitWebView* webView; 97 WebKitWebFrame* webFrame; 98 g_test_bug("21837"); 99 100 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); 101 g_object_ref_sink(webView); 102 g_assert_cmpint(G_OBJECT(webView)->ref_count, ==, 1); 103 webFrame = webkit_web_view_get_main_frame(webView); 104 g_assert_cmpint(G_OBJECT(webFrame)->ref_count, ==, 1); 105 106 // Add dummy reference on the WebKitWebFrame to keep it alive 107 g_object_ref(webFrame); 108 g_assert_cmpint(G_OBJECT(webFrame)->ref_count, ==, 2); 109 110 // This crashed with the original version 111 g_object_unref(webView); 112 113 // Make sure that the frame got deleted as well. We did this 114 // by adding an extra ref on the WebKitWebFrame and we should 115 // be the one holding the last reference. 116 g_assert_cmpint(G_OBJECT(webFrame)->ref_count, ==, 1); 117 g_object_unref(webFrame); 118} 119 120static gboolean print_requested_cb(WebKitWebView* webView, WebKitWebFrame* webFrame, GMainLoop* loop) 121{ 122 g_object_set_data(G_OBJECT(webView), "signal-handled", GINT_TO_POINTER(TRUE)); 123 g_main_loop_quit(loop); 124 return TRUE; 125} 126 127static void print_timeout(GMainLoop* loop) 128{ 129 if (g_main_loop_is_running(loop)) 130 g_main_loop_quit(loop); 131} 132 133static void test_webkit_web_frame_printing(void) 134{ 135 WebKitWebView* webView; 136 137 webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); 138 g_object_ref_sink(webView); 139 g_assert_cmpint(G_OBJECT(webView)->ref_count, ==, 1); 140 141 webkit_web_view_load_string(webView, 142 "<html><body><h1>WebKitGTK+!</h1></body></html>", 143 "text/html", 144 "utf-8", 145 "file://"); 146 147 GMainLoop* loop = g_main_loop_new(NULL, TRUE); 148 149 // Does javascript print() work correctly? 150 g_signal_connect(webView, "print-requested", 151 G_CALLBACK(print_requested_cb), 152 loop); 153 154 g_object_set_data(G_OBJECT(webView), "signal-handled", GINT_TO_POINTER(FALSE)); 155 webkit_web_view_execute_script (webView, "print();"); 156 157 // Give javascriptcore some time to process the print request, but 158 // prepare a timeout to avoid it running forever in case the signal is 159 // never emitted. 160 g_timeout_add(1000, (GSourceFunc)print_timeout, loop); 161 g_main_loop_run(loop); 162 163 g_assert_cmpint(GPOINTER_TO_INT(g_object_get_data(G_OBJECT(webView), "signal-handled")), ==, TRUE); 164 165 // Does printing directly to a file? 166 GError *error = NULL; 167 gchar* temporaryFilename = NULL; 168 gint fd = g_file_open_tmp ("webkit-testwebframe-XXXXXX", &temporaryFilename, &error); 169 close(fd); 170 171 if (error) { 172 g_critical("Failed to open a temporary file for writing: %s.", error->message); 173 g_error_free(error); 174 goto cleanup; 175 } 176 177 // We delete the file, so that we can easily figure out that the 178 // file got printed; 179 if (g_unlink(temporaryFilename) == -1) { 180 g_warning("Failed to delete the temporary file: %s.\nThis may cause the test to be bogus.", g_strerror(errno)); 181 } 182 183 WebKitWebFrame* webFrame = webkit_web_view_get_main_frame(webView); 184 GtkPrintOperation* operation = gtk_print_operation_new(); 185 GtkPrintOperationAction action = GTK_PRINT_OPERATION_ACTION_EXPORT; 186 GtkPrintOperationResult result; 187 188 gtk_print_operation_set_export_filename(operation, temporaryFilename); 189 result = webkit_web_frame_print_full (webFrame, operation, action, NULL); 190 191 g_assert_cmpint(result, ==, GTK_PRINT_OPERATION_RESULT_APPLY); 192 g_assert_cmpint(g_file_test(temporaryFilename, G_FILE_TEST_IS_REGULAR), ==, TRUE); 193 194 g_unlink(temporaryFilename); 195 g_object_unref(operation); 196cleanup: 197 g_object_unref(webView); 198 g_free(temporaryFilename); 199} 200 201static void test_webkit_web_frame_response() 202{ 203 WebKitWebFrame* frame = g_object_new(WEBKIT_TYPE_WEB_FRAME, NULL); 204 WebKitNetworkResponse* response = webkit_web_frame_get_network_response(frame); 205 g_assert(!response); 206 g_object_unref(frame); 207} 208 209int main(int argc, char** argv) 210{ 211 gtk_test_init(&argc, &argv, NULL); 212 213 g_test_bug_base("https://bugs.webkit.org/"); 214 g_test_add_func("/webkit/webview/create_destroy", test_webkit_web_frame_create_destroy); 215 g_test_add_func("/webkit/webview/frame-created_signal", test_webkit_web_frame_created_signal); 216 g_test_add_func("/webkit/webframe/lifetime", test_webkit_web_frame_lifetime); 217 g_test_add_func("/webkit/webview/printing", test_webkit_web_frame_printing); 218 g_test_add_func("/webkit/webview/response", test_webkit_web_frame_response); 219 return g_test_run (); 220} 221