1 /* 2 * Copyright (C) 2010 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 Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 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 "test_utils.h" 21 22 #include <glib.h> 23 #include <glib/gstdio.h> 24 #include <gtk/gtk.h> 25 #include <webkit/webkit.h> 26 27 #if GTK_CHECK_VERSION(2, 14, 0) 28 29 #define HTML_DOCUMENT_TITLE "<html><head><title>This is the title</title></head><body></body></html>" 30 #define HTML_DOCUMENT_ELEMENTS "<html><body><ul><li>1</li><li>2</li><li>3</li></ul></body></html>" 31 #define HTML_DOCUMENT_ELEMENTS_CLASS "<html><body><div class=\"test\"></div><div class=\"strange\"></div><div class=\"test\"></div></body></html>" 32 #define HTML_DOCUMENT_ELEMENTS_ID "<html><body><div id=\"testok\"></div><div id=\"testbad\">first</div><div id=\"testbad\">second</div></body></html>" 33 #define HTML_DOCUMENT_LINKS "<html><head><title>Title</title></head><body><a href=\"about:blank\">blank</a><a href=\"http://www.google.com\">google</a><a href=\"http://www.webkit.org\">webkit</a></body></html>" 34 #define HTML_DOCUMENT_IFRAME "<html><head><title>IFrame</title></head><body><iframe id='iframe'></iframe><div id='test'></div></body></html>" 35 36 typedef struct { 37 GtkWidget* webView; 38 GMainLoop* loop; 39 } DomDocumentFixture; 40 41 static gboolean finish_loading(DomDocumentFixture* fixture) 42 { 43 if (g_main_loop_is_running(fixture->loop)) 44 g_main_loop_quit(fixture->loop); 45 46 return FALSE; 47 } 48 49 static void dom_document_fixture_setup(DomDocumentFixture* fixture, gconstpointer data) 50 { 51 fixture->loop = g_main_loop_new(NULL, TRUE); 52 fixture->webView = webkit_web_view_new(); 53 g_object_ref_sink(fixture->webView); 54 55 if (data != NULL) 56 webkit_web_view_load_string(WEBKIT_WEB_VIEW (fixture->webView), (const char*) data, NULL, NULL, NULL); 57 58 g_idle_add((GSourceFunc)finish_loading, fixture); 59 g_main_loop_run(fixture->loop); 60 } 61 62 static void dom_document_fixture_teardown(DomDocumentFixture* fixture, gconstpointer data) 63 { 64 if (fixture->webView) 65 g_object_unref(fixture->webView); 66 g_main_loop_unref(fixture->loop); 67 } 68 69 static void test_dom_document_title(DomDocumentFixture* fixture, gconstpointer data) 70 { 71 g_assert(fixture); 72 WebKitWebView* view = (WebKitWebView*)fixture->webView; 73 g_assert(view); 74 WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); 75 g_assert(document); 76 gchar* title = webkit_dom_document_get_title(document); 77 g_assert(title); 78 g_assert_cmpstr(title, ==, "This is the title"); 79 g_free(title); 80 webkit_dom_document_set_title(document, "This is the second title"); 81 title = webkit_dom_document_get_title(document); 82 g_assert(title); 83 g_assert_cmpstr(title, ==, "This is the second title"); 84 g_free(title); 85 } 86 87 static void test_dom_document_get_elements_by_tag_name(DomDocumentFixture* fixture, gconstpointer data) 88 { 89 g_assert(fixture); 90 WebKitWebView* view = (WebKitWebView*)fixture->webView; 91 g_assert(view); 92 WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); 93 g_assert(document); 94 WebKitDOMNodeList* list = webkit_dom_document_get_elements_by_tag_name(document, "li"); 95 g_assert(list); 96 gulong length = webkit_dom_node_list_get_length(list); 97 g_assert_cmpint(length, ==, 3); 98 99 guint i; 100 101 for (i = 0; i < length; i++) { 102 WebKitDOMNode* item = webkit_dom_node_list_item(list, i); 103 g_assert(item); 104 WebKitDOMElement* element = (WebKitDOMElement*)item; 105 g_assert(element); 106 g_assert_cmpstr(webkit_dom_element_get_tag_name(element), ==, "LI"); 107 WebKitDOMHTMLElement* htmlElement = (WebKitDOMHTMLElement*)element; 108 char* n = g_strdup_printf("%d", i+1); 109 g_assert_cmpstr(webkit_dom_html_element_get_inner_text(htmlElement), ==, n); 110 g_free(n); 111 } 112 113 g_object_unref(list); 114 } 115 116 static void test_dom_document_get_elements_by_class_name(DomDocumentFixture* fixture, gconstpointer data) 117 { 118 g_assert(fixture); 119 WebKitWebView* view = (WebKitWebView*)fixture->webView; 120 g_assert(view); 121 WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); 122 g_assert(document); 123 WebKitDOMNodeList* list = webkit_dom_document_get_elements_by_class_name(document, "test"); 124 g_assert(list); 125 gulong length = webkit_dom_node_list_get_length(list); 126 g_assert_cmpint(length, ==, 2); 127 128 guint i; 129 130 for (i = 0; i < length; i++) { 131 WebKitDOMNode* item = webkit_dom_node_list_item(list, i); 132 g_assert(item); 133 WebKitDOMElement* element = (WebKitDOMElement*)item; 134 g_assert(element); 135 g_assert_cmpstr(webkit_dom_element_get_tag_name(element), ==, "DIV"); 136 } 137 138 g_object_unref(list); 139 } 140 141 static void test_dom_document_get_element_by_id(DomDocumentFixture* fixture, gconstpointer data) 142 { 143 g_assert(fixture); 144 WebKitWebView* view = (WebKitWebView*)fixture->webView; 145 g_assert(view); 146 WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); 147 g_assert(document); 148 WebKitDOMElement* element = webkit_dom_document_get_element_by_id(document, "testok"); 149 g_assert(element); 150 element = webkit_dom_document_get_element_by_id(document, "this-id-does-not-exist"); 151 g_assert(element == 0); 152 /* The DOM spec says the return value is undefined when there's 153 * more than one element with the same id; in our case the first 154 * one will be returned */ 155 element = webkit_dom_document_get_element_by_id(document, "testbad"); 156 g_assert(element); 157 WebKitDOMHTMLElement* htmlElement = (WebKitDOMHTMLElement*)element; 158 g_assert_cmpstr(webkit_dom_html_element_get_inner_text(htmlElement), ==, "first"); 159 } 160 161 static void test_dom_document_get_links(DomDocumentFixture* fixture, gconstpointer data) 162 { 163 g_assert(fixture); 164 WebKitWebView* view = (WebKitWebView*)fixture->webView; 165 g_assert(view); 166 WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); 167 g_assert(document); 168 WebKitDOMHTMLCollection *collection = webkit_dom_document_get_links(document); 169 g_assert(collection); 170 gulong length = webkit_dom_html_collection_get_length(collection); 171 g_assert_cmpint(length, ==, 3); 172 173 guint i; 174 175 for (i = 0; i < length; i++) { 176 static const char* names[] = { "blank", "google", "webkit" }; 177 static const char* uris[] = { "about:blank", "http://www.google.com/", "http://www.webkit.org/" }; 178 WebKitDOMNode *node = webkit_dom_html_collection_item(collection, i); 179 g_assert(node); 180 WebKitDOMElement* element = (WebKitDOMElement*)node; 181 g_assert_cmpstr(webkit_dom_element_get_tag_name(element), ==, "A"); 182 WebKitDOMHTMLElement *htmlElement = (WebKitDOMHTMLElement*)element; 183 g_assert_cmpstr(webkit_dom_html_element_get_inner_text(htmlElement), ==, names[i]); 184 WebKitDOMHTMLAnchorElement *anchor = (WebKitDOMHTMLAnchorElement*)element; 185 g_assert_cmpstr(webkit_dom_html_anchor_element_get_href(anchor), ==, uris[i]); 186 } 187 g_object_unref(collection); 188 } 189 190 static void weak_notify(gpointer data, GObject* zombie) 191 { 192 guint* count = (guint*)data; 193 (*count)++; 194 } 195 196 static void test_dom_document_garbage_collection(DomDocumentFixture* fixture, gconstpointer data) 197 { 198 guint count = 0; 199 g_assert(fixture); 200 WebKitWebView* view = (WebKitWebView*)fixture->webView; 201 g_assert(view); 202 WebKitDOMDocument* document = webkit_web_view_get_dom_document(view); 203 g_assert(document); 204 g_object_weak_ref(G_OBJECT(document), (GWeakNotify)weak_notify, &count); 205 WebKitDOMHTMLHeadElement* head = webkit_dom_document_get_head(document); 206 g_assert(head); 207 g_object_weak_ref(G_OBJECT(head), (GWeakNotify)weak_notify, &count); 208 WebKitDOMHTMLElement* body = webkit_dom_document_get_body(document); 209 g_assert(body); 210 g_object_weak_ref(G_OBJECT(body), (GWeakNotify)weak_notify, &count); 211 WebKitDOMHTMLCollection *collection = webkit_dom_document_get_links(document); 212 g_assert(collection); 213 g_object_weak_ref(G_OBJECT(collection), (GWeakNotify)weak_notify, &count); 214 215 webkit_web_view_load_string(WEBKIT_WEB_VIEW(view), HTML_DOCUMENT_LINKS, NULL, NULL, NULL); 216 217 while (g_main_context_pending(NULL)) 218 g_main_context_iteration(NULL, FALSE); 219 220 g_assert_cmpuint(count, ==, 3); 221 222 g_object_unref(collection); 223 g_assert_cmpuint(count, ==, 4); 224 225 count = 0; 226 227 document = webkit_web_view_get_dom_document(view); 228 g_assert(document); 229 g_object_weak_ref(G_OBJECT(document), (GWeakNotify)weak_notify, &count); 230 head = webkit_dom_document_get_head(document); 231 g_assert(head); 232 g_object_weak_ref(G_OBJECT(head), (GWeakNotify)weak_notify, &count); 233 body = webkit_dom_document_get_body(document); 234 g_assert(body); 235 g_object_weak_ref(G_OBJECT(body), (GWeakNotify)weak_notify, &count); 236 collection = webkit_dom_document_get_links(document); 237 g_assert(collection); 238 g_object_weak_ref(G_OBJECT(collection), (GWeakNotify)weak_notify, &count); 239 /* Ask twice for the same object */ 240 WebKitDOMHTMLCollection* collection2 = webkit_dom_document_get_links(document); 241 g_assert(collection2); 242 g_object_weak_ref(G_OBJECT(collection2), (GWeakNotify)weak_notify, &count); 243 244 g_object_unref(document); 245 g_object_unref(head); 246 g_object_unref(body); 247 g_object_unref(collection); 248 g_object_unref(collection2); 249 250 g_assert_cmpuint(count, ==, 5); 251 252 webkit_web_view_load_string(WEBKIT_WEB_VIEW(view), HTML_DOCUMENT_IFRAME, NULL, NULL, NULL); 253 254 while (g_main_context_pending(NULL)) 255 g_main_context_iteration(NULL, FALSE); 256 257 count = 0; 258 259 document = webkit_web_view_get_dom_document(view); 260 WebKitDOMElement* div = webkit_dom_document_get_element_by_id(document, "test"); 261 g_assert(div); 262 g_object_weak_ref(G_OBJECT(div), (GWeakNotify)weak_notify, &count); 263 WebKitDOMElement* iframe = webkit_dom_document_get_element_by_id(document, "iframe"); 264 g_assert(iframe); 265 266 webkit_dom_element_set_attribute(iframe, "src", "data:<html><head></head></html>", NULL); 267 268 while (g_main_context_pending(NULL)) 269 g_main_context_iteration(NULL, FALSE); 270 271 WebKitDOMDocument* iframeDocument = webkit_dom_html_iframe_element_get_content_document(WEBKIT_DOM_HTML_IFRAME_ELEMENT(iframe)); 272 g_assert(iframeDocument); 273 head = webkit_dom_document_get_head(iframeDocument); 274 g_assert(head); 275 g_object_weak_ref(G_OBJECT(head), (GWeakNotify)weak_notify, &count); 276 277 webkit_dom_element_set_attribute(iframe, "src", "about:blank", NULL); 278 279 while (g_main_context_pending(NULL)) 280 g_main_context_iteration(NULL, FALSE); 281 282 g_assert_cmpuint(count, ==, 1); 283 284 webkit_web_view_load_string(WEBKIT_WEB_VIEW(view), HTML_DOCUMENT_LINKS, NULL, NULL, NULL); 285 286 while (g_main_context_pending(NULL)) 287 g_main_context_iteration(NULL, FALSE); 288 289 g_assert_cmpuint(count, ==, 2); 290 291 count = 0; 292 293 document = webkit_web_view_get_dom_document(view); 294 g_assert(document); 295 g_object_weak_ref(G_OBJECT(document), (GWeakNotify)weak_notify, &count); 296 /* Ask twice for the Document */ 297 WebKitDOMDocument* document2 = webkit_web_view_get_dom_document(view); 298 g_assert(document2); 299 g_object_weak_ref(G_OBJECT(document2), (GWeakNotify)weak_notify, &count); 300 head = webkit_dom_document_get_head(document); 301 g_assert(head); 302 g_object_weak_ref(G_OBJECT(head), (GWeakNotify)weak_notify, &count); 303 body = webkit_dom_document_get_body(document); 304 g_assert(body); 305 g_object_weak_ref(G_OBJECT(body), (GWeakNotify)weak_notify, &count); 306 collection = webkit_dom_document_get_links(document); 307 g_assert(collection); 308 g_object_weak_ref(G_OBJECT(collection), (GWeakNotify)weak_notify, &count); 309 310 gtk_widget_destroy(fixture->webView); 311 fixture->webView = NULL; 312 313 g_assert_cmpuint(count, ==, 4); 314 315 g_object_unref(collection); 316 317 g_assert_cmpuint(count, ==, 5); 318 } 319 320 int main(int argc, char** argv) 321 { 322 if (!g_thread_supported()) 323 g_thread_init(NULL); 324 325 gtk_test_init(&argc, &argv, NULL); 326 327 g_test_bug_base("https://bugs.webkit.org/"); 328 329 g_test_add("/webkit/domdocument/test_title", 330 DomDocumentFixture, HTML_DOCUMENT_TITLE, 331 dom_document_fixture_setup, 332 test_dom_document_title, 333 dom_document_fixture_teardown); 334 335 g_test_add("/webkit/domdocument/test_get_elements_by_tag_name", 336 DomDocumentFixture, HTML_DOCUMENT_ELEMENTS, 337 dom_document_fixture_setup, 338 test_dom_document_get_elements_by_tag_name, 339 dom_document_fixture_teardown); 340 341 g_test_add("/webkit/domdocument/test_get_elements_by_class_name", 342 DomDocumentFixture, HTML_DOCUMENT_ELEMENTS_CLASS, 343 dom_document_fixture_setup, 344 test_dom_document_get_elements_by_class_name, 345 dom_document_fixture_teardown); 346 347 g_test_add("/webkit/domdocument/test_get_element_by_id", 348 DomDocumentFixture, HTML_DOCUMENT_ELEMENTS_ID, 349 dom_document_fixture_setup, 350 test_dom_document_get_element_by_id, 351 dom_document_fixture_teardown); 352 353 g_test_add("/webkit/domdocument/test_get_links", 354 DomDocumentFixture, HTML_DOCUMENT_LINKS, 355 dom_document_fixture_setup, 356 test_dom_document_get_links, 357 dom_document_fixture_teardown); 358 359 g_test_add("/webkit/domdocument/test_garbage_collection", 360 DomDocumentFixture, HTML_DOCUMENT_LINKS, 361 dom_document_fixture_setup, 362 test_dom_document_garbage_collection, 363 dom_document_fixture_teardown); 364 365 return g_test_run(); 366 } 367 368 #else 369 int main(int argc, char** argv) 370 { 371 g_critical("You will gtk-2.14.0 to run the unit tests. Doing nothing now."); 372 return 0; 373 } 374 375 #endif 376