REGRESSION(r224179): [GTK] Several WebViewEditor tests are failing since r224179
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WebKitGtk / TestWebViewEditor.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 #include "WebViewTest.h"
22 #include <wtf/glib/GRefPtr.h>
23
24 class EditorTest: public WebViewTest {
25 public:
26     MAKE_GLIB_TEST_FIXTURE(EditorTest);
27
28     static const unsigned kClipboardWaitTimeout = 50;
29     static const unsigned kClipboardWaitMaxTries = 2;
30
31     EditorTest()
32         : m_clipboard(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD))
33         , m_canExecuteEditingCommand(false)
34         , m_triesCount(0)
35         , m_editorState(nullptr)
36     {
37         showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL);
38         gtk_clipboard_clear(m_clipboard);
39     }
40
41     static gboolean webViewDrawCallback(GMainLoop* mainLoop)
42     {
43         g_main_loop_quit(mainLoop);
44         return FALSE;
45     }
46
47     void flushEditorState()
48     {
49         auto signalID = g_signal_connect_swapped(m_webView, "draw", G_CALLBACK(webViewDrawCallback), m_mainLoop);
50         gtk_widget_queue_draw(GTK_WIDGET(m_webView));
51         g_main_loop_run(m_mainLoop);
52         g_signal_handler_disconnect(m_webView, signalID);
53     }
54
55     static void canExecuteEditingCommandReadyCallback(GObject*, GAsyncResult* result, EditorTest* test)
56     {
57         GUniqueOutPtr<GError> error;
58         test->m_canExecuteEditingCommand = webkit_web_view_can_execute_editing_command_finish(test->m_webView, result, &error.outPtr());
59         g_assert(!error.get());
60         g_main_loop_quit(test->m_mainLoop);
61     }
62
63     bool canExecuteEditingCommand(const char* command)
64     {
65         m_canExecuteEditingCommand = false;
66         webkit_web_view_can_execute_editing_command(m_webView, command, 0, reinterpret_cast<GAsyncReadyCallback>(canExecuteEditingCommandReadyCallback), this);
67         g_main_loop_run(m_mainLoop);
68
69         if (!strcmp(command, WEBKIT_EDITING_COMMAND_CUT))
70             g_assert(m_canExecuteEditingCommand == webkit_editor_state_is_cut_available(editorState()));
71         else if (!strcmp(command, WEBKIT_EDITING_COMMAND_COPY))
72             g_assert(m_canExecuteEditingCommand == webkit_editor_state_is_copy_available(editorState()));
73         else if (!strcmp(command, WEBKIT_EDITING_COMMAND_PASTE))
74             g_assert(m_canExecuteEditingCommand == webkit_editor_state_is_paste_available(editorState()));
75         // FIXME: Figure out how to add tests for undo and redo. It will probably require using user
76         // scripts to message the UI process when the content has been altered.
77         else if (!strcmp(command, WEBKIT_EDITING_COMMAND_UNDO))
78             g_assert(m_canExecuteEditingCommand == webkit_editor_state_is_undo_available(editorState()));
79         else if (!strcmp(command, WEBKIT_EDITING_COMMAND_REDO))
80             g_assert(m_canExecuteEditingCommand == webkit_editor_state_is_redo_available(editorState()));
81
82         return m_canExecuteEditingCommand;
83     }
84
85     static gboolean waitForClipboardText(EditorTest* test)
86     {
87         test->m_triesCount++;
88         if (gtk_clipboard_wait_is_text_available(test->m_clipboard) || test->m_triesCount > kClipboardWaitMaxTries) {
89             g_main_loop_quit(test->m_mainLoop);
90             return FALSE;
91         }
92
93         return TRUE;
94     }
95
96     void copyClipboard()
97     {
98         webkit_web_view_execute_editing_command(m_webView, WEBKIT_EDITING_COMMAND_COPY);
99         // There's no way to know when the selection has been copied to
100         // the clipboard, so use a timeout source to query the clipboard.
101         m_triesCount = 0;
102         g_timeout_add(kClipboardWaitTimeout, reinterpret_cast<GSourceFunc>(waitForClipboardText), this);
103         g_main_loop_run(m_mainLoop);
104     }
105
106     gchar* cutSelection()
107     {
108         g_assert(canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT));
109         g_assert(canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE));
110
111         webkit_web_view_execute_editing_command(m_webView, WEBKIT_EDITING_COMMAND_CUT);
112         // There's no way to know when the selection has been cut to
113         // the clipboard, so use a timeout source to query the clipboard.
114         m_triesCount = 0;
115         g_timeout_add(kClipboardWaitTimeout, reinterpret_cast<GSourceFunc>(waitForClipboardText), this);
116         g_main_loop_run(m_mainLoop);
117
118         return gtk_clipboard_wait_for_text(m_clipboard);
119     }
120
121     WebKitEditorState* editorState()
122     {
123         if (m_editorState)
124             return m_editorState;
125
126         m_editorState = webkit_web_view_get_editor_state(m_webView);
127         assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_editorState));
128         return m_editorState;
129     }
130
131     static void quitMainLoopInCallback(EditorTest* test)
132     {
133         g_main_loop_quit(test->m_mainLoop);
134     }
135
136     unsigned typingAttributes()
137     {
138         return webkit_editor_state_get_typing_attributes(editorState());
139     }
140
141     unsigned waitUntilTypingAttributesChanged()
142     {
143         unsigned long handlerID = g_signal_connect_swapped(editorState(), "notify::typing-attributes", G_CALLBACK(quitMainLoopInCallback), this);
144         g_main_loop_run(m_mainLoop);
145         g_signal_handler_disconnect(m_editorState, handlerID);
146         return typingAttributes();
147     }
148
149     GtkClipboard* m_clipboard;
150     bool m_canExecuteEditingCommand;
151     size_t m_triesCount;
152     WebKitEditorState* m_editorState;
153 };
154
155 static const char* selectedSpanHTMLFormat =
156     "<html><body contentEditable=\"%s\">"
157     "<span id=\"mainspan\">All work and no play <span id=\"subspan\">make Jack a dull</span> boy.</span>"
158     "<script>document.getSelection().removeAllRanges();\n"
159     "document.getSelection().selectAllChildren(document.getElementById('subspan'));\n"
160     "</script></body></html>";
161
162 static void testWebViewEditorCutCopyPasteNonEditable(EditorTest* test, gconstpointer)
163 {
164     // Nothing loaded yet.
165     g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT));
166     g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_COPY));
167     g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE));
168
169     GUniquePtr<char> selectedSpanHTML(g_strdup_printf(selectedSpanHTMLFormat, "false"));
170     test->loadHtml(selectedSpanHTML.get(), nullptr);
171     test->waitUntilLoadFinished();
172     test->flushEditorState();
173
174     g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_COPY));
175     // It's not possible to cut and paste when content is not editable
176     // even if there's a selection.
177     g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT));
178     g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE));
179
180     test->copyClipboard();
181     GUniquePtr<char> clipboardText(gtk_clipboard_wait_for_text(test->m_clipboard));
182     g_assert_cmpstr(clipboardText.get(), ==, "make Jack a dull");
183 }
184
185 static void testWebViewEditorCutCopyPasteEditable(EditorTest* test, gconstpointer)
186 {
187     // Nothing loaded yet.
188     g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT));
189     g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_COPY));
190     g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE));
191
192     g_assert(!test->isEditable());
193     test->setEditable(true);
194     g_assert(test->isEditable());
195
196     GUniquePtr<char> selectedSpanHTML(g_strdup_printf(selectedSpanHTMLFormat, "false"));
197     test->loadHtml(selectedSpanHTML.get(), nullptr);
198     test->waitUntilLoadFinished();
199     test->flushEditorState();
200
201     // There's a selection.
202     g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT));
203     g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_COPY));
204     g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE));
205
206     test->copyClipboard();
207     GUniquePtr<char> clipboardText(gtk_clipboard_wait_for_text(test->m_clipboard));
208     g_assert_cmpstr(clipboardText.get(), ==, "make Jack a dull");
209 }
210
211 static void testWebViewEditorSelectAllNonEditable(EditorTest* test, gconstpointer)
212 {
213     g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_SELECT_ALL));
214
215     GUniquePtr<char> selectedSpanHTML(g_strdup_printf(selectedSpanHTMLFormat, "false"));
216     test->loadHtml(selectedSpanHTML.get(), nullptr);
217     test->waitUntilLoadFinished();
218     test->flushEditorState();
219
220     g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_SELECT_ALL));
221
222     test->copyClipboard();
223     GUniquePtr<char> clipboardText(gtk_clipboard_wait_for_text(test->m_clipboard));
224
225     // Initially only the subspan is selected.
226     g_assert_cmpstr(clipboardText.get(), ==, "make Jack a dull");
227
228     webkit_web_view_execute_editing_command(test->m_webView, WEBKIT_EDITING_COMMAND_SELECT_ALL);
229     test->copyClipboard();
230     clipboardText.reset(gtk_clipboard_wait_for_text(test->m_clipboard));
231
232     // The mainspan should be selected after calling SELECT_ALL.
233     g_assert_cmpstr(clipboardText.get(), ==, "All work and no play make Jack a dull boy.");
234 }
235
236 static void testWebViewEditorSelectAllEditable(EditorTest* test, gconstpointer)
237 {
238     g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_SELECT_ALL));
239
240     g_assert(!test->isEditable());
241     test->setEditable(true);
242     g_assert(test->isEditable());
243
244     GUniquePtr<char> selectedSpanHTML(g_strdup_printf(selectedSpanHTMLFormat, "false"));
245     test->loadHtml(selectedSpanHTML.get(), nullptr);
246     test->waitUntilLoadFinished();
247     test->flushEditorState();
248
249     g_assert(test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_SELECT_ALL));
250
251     test->copyClipboard();
252     GUniquePtr<char> clipboardText(gtk_clipboard_wait_for_text(test->m_clipboard));
253
254     // Initially only the subspan is selected.
255     g_assert_cmpstr(clipboardText.get(), ==, "make Jack a dull");
256
257     webkit_web_view_execute_editing_command(test->m_webView, WEBKIT_EDITING_COMMAND_SELECT_ALL);
258     test->copyClipboard();
259     clipboardText.reset(gtk_clipboard_wait_for_text(test->m_clipboard));
260
261     // The mainspan should be selected after calling SELECT_ALL.
262     g_assert_cmpstr(clipboardText.get(), ==, "All work and no play make Jack a dull boy.");
263 }
264
265 static void loadContentsAndTryToCutSelection(EditorTest* test, bool contentEditable)
266 {
267     // View is not editable by default.
268     g_assert(!test->isEditable());
269
270     GUniquePtr<char> selectedSpanHTML(g_strdup_printf(selectedSpanHTMLFormat, contentEditable ? "true" : "false"));
271     test->loadHtml(selectedSpanHTML.get(), nullptr);
272     test->waitUntilLoadFinished();
273     test->flushEditorState();
274
275     g_assert(!test->isEditable());
276     test->setEditable(true);
277     g_assert(test->isEditable());
278
279     test->flushEditorState();
280
281     // Cut the selection to the clipboard to see if the view is indeed editable.
282     GUniquePtr<char> clipboardText(test->cutSelection());
283     g_assert_cmpstr(clipboardText.get(), ==, "make Jack a dull");
284
285     // Reset the editable for next test.
286     test->setEditable(false);
287     g_assert(!test->isEditable());
288 }
289
290 static void testWebViewEditorNonEditable(EditorTest* test)
291 {
292     GUniquePtr<char> selectedSpanHTML(g_strdup_printf(selectedSpanHTMLFormat, "false"));
293     test->loadHtml(selectedSpanHTML.get(), nullptr);
294     test->waitUntilLoadFinished();
295     test->flushEditorState();
296
297     g_assert(!test->isEditable());
298     test->setEditable(true);
299     g_assert(test->isEditable());
300     test->setEditable(false);
301     g_assert(!test->isEditable());
302
303     // Check if view is indeed non-editable.
304     g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_CUT));
305     g_assert(!test->canExecuteEditingCommand(WEBKIT_EDITING_COMMAND_PASTE));
306 }
307
308 static void testWebViewEditorEditable(EditorTest* test, gconstpointer)
309 {
310     testWebViewEditorNonEditable(test);
311
312     // Reset the editable for next test.
313     test->setEditable(false);
314     g_assert(!test->isEditable());
315
316     loadContentsAndTryToCutSelection(test, true);
317
318     // Reset the editable for next test.
319     test->setEditable(false);
320     g_assert(!test->isEditable());
321
322     loadContentsAndTryToCutSelection(test, false);
323 }
324
325 static void testWebViewEditorEditorStateTypingAttributes(EditorTest* test, gconstpointer)
326 {
327     static const char* typingAttributesHTML =
328         "<html><body>"
329         "normal <b>bold </b><i>italic </i><u>underline </u><strike>strike </strike>"
330         "<b><i>boldanditalic </i></b>"
331         "</body></html>";
332
333     test->loadHtml(typingAttributesHTML, nullptr);
334     test->waitUntilLoadFinished();
335     test->flushEditorState();
336     test->setEditable(true);
337
338     unsigned typingAttributes = test->typingAttributes();
339     g_assert_cmpuint(typingAttributes, ==, WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE);
340
341     webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward");
342     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
343     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
344     typingAttributes = test->waitUntilTypingAttributesChanged();
345     g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD);
346     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC));
347     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
348     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
349
350     webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward");
351     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
352     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
353     typingAttributes = test->waitUntilTypingAttributesChanged();
354     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD));
355     g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC);
356     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
357     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
358
359     webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward");
360     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
361     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
362     typingAttributes = test->waitUntilTypingAttributesChanged();
363     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD));
364     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC));
365     g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE);
366     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
367
368     webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward");
369     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
370     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
371     typingAttributes = test->waitUntilTypingAttributesChanged();
372     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD));
373     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC));
374     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
375     g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH);
376
377     webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForward");
378     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
379     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
380     typingAttributes = test->waitUntilTypingAttributesChanged();
381     g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD);
382     g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC);
383     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
384     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
385
386     // Selections.
387     webkit_web_view_execute_editing_command(test->m_webView, "MoveToBeginningOfDocument");
388     webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection");
389     typingAttributes = test->waitUntilTypingAttributesChanged();
390     g_assert_cmpuint(typingAttributes, ==, WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE);
391
392     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
393     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
394     webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection");
395     typingAttributes = test->waitUntilTypingAttributesChanged();
396     g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD);
397     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC));
398     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
399     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
400
401     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
402     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
403     webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection");
404     typingAttributes = test->waitUntilTypingAttributesChanged();
405     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD));
406     g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC);
407     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
408     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
409
410     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
411     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
412     webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection");
413     typingAttributes = test->waitUntilTypingAttributesChanged();
414     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD));
415     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC));
416     g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE);
417     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
418
419     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
420     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
421     webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection");
422     typingAttributes = test->waitUntilTypingAttributesChanged();
423     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD));
424     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC));
425     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
426     g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH);
427
428     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
429     webkit_web_view_execute_editing_command(test->m_webView, "MoveForward");
430     webkit_web_view_execute_editing_command(test->m_webView, "MoveWordForwardAndModifySelection");
431     typingAttributes = test->waitUntilTypingAttributesChanged();
432     g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_BOLD);
433     g_assert(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_ITALIC);
434     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_UNDERLINE));
435     g_assert(!(typingAttributes & WEBKIT_EDITOR_TYPING_ATTRIBUTE_STRIKETHROUGH));
436
437     webkit_web_view_execute_editing_command(test->m_webView, "SelectAll");
438     typingAttributes = test->waitUntilTypingAttributesChanged();
439     g_assert_cmpuint(typingAttributes, ==, WEBKIT_EDITOR_TYPING_ATTRIBUTE_NONE);
440 }
441
442 static void testWebViewEditorInsertImage(EditorTest* test, gconstpointer)
443 {
444     test->loadHtml("<html><body></body></html>", "file:///");
445     test->waitUntilLoadFinished();
446     test->flushEditorState();
447     test->setEditable(true);
448
449     GUniquePtr<char> imagePath(g_build_filename(Test::getResourcesDir().data(), "blank.ico", nullptr));
450     GUniquePtr<char> imageURI(g_filename_to_uri(imagePath.get(), nullptr, nullptr));
451     webkit_web_view_execute_editing_command_with_argument(test->m_webView, WEBKIT_EDITING_COMMAND_INSERT_IMAGE, imageURI.get());
452     GUniqueOutPtr<GError> error;
453     WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementsByTagName('IMG')[0].src", &error.outPtr());
454     g_assert(javascriptResult);
455     g_assert(!error);
456     GUniquePtr<char> resultString(WebViewTest::javascriptResultToCString(javascriptResult));
457     g_assert_cmpstr(resultString.get(), ==, imageURI.get());
458 }
459
460 static void testWebViewEditorCreateLink(EditorTest* test, gconstpointer)
461 {
462     test->loadHtml("<html><body onload=\"document.getSelection().selectAllChildren(document.body);\">webkitgtk.org</body></html>", nullptr);
463     test->waitUntilLoadFinished();
464     test->flushEditorState();
465     test->setEditable(true);
466
467     static const char* webkitGTKURL = "http://www.webkitgtk.org/";
468     webkit_web_view_execute_editing_command_with_argument(test->m_webView, WEBKIT_EDITING_COMMAND_CREATE_LINK, webkitGTKURL);
469     GUniqueOutPtr<GError> error;
470     WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementsByTagName('A')[0].href;", &error.outPtr());
471     g_assert(javascriptResult);
472     g_assert(!error);
473     GUniquePtr<char> resultString(WebViewTest::javascriptResultToCString(javascriptResult));
474     g_assert_cmpstr(resultString.get(), ==, webkitGTKURL);
475     javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementsByTagName('A')[0].innerText;", &error.outPtr());
476     g_assert(javascriptResult);
477     g_assert(!error);
478     resultString.reset(WebViewTest::javascriptResultToCString(javascriptResult));
479     g_assert_cmpstr(resultString.get(), ==, "webkitgtk.org");
480
481     // When there isn't text selected, the URL is used as link text.
482     webkit_web_view_execute_editing_command(test->m_webView, "MoveToEndOfLine");
483     webkit_web_view_execute_editing_command_with_argument(test->m_webView, WEBKIT_EDITING_COMMAND_CREATE_LINK, webkitGTKURL);
484     javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementsByTagName('A')[1].href;", &error.outPtr());
485     g_assert(javascriptResult);
486     g_assert(!error);
487     resultString.reset(WebViewTest::javascriptResultToCString(javascriptResult));
488     g_assert_cmpstr(resultString.get(), ==, webkitGTKURL);
489     javascriptResult = test->runJavaScriptAndWaitUntilFinished("document.getElementsByTagName('A')[1].innerText;", &error.outPtr());
490     g_assert(javascriptResult);
491     g_assert(!error);
492     resultString.reset(WebViewTest::javascriptResultToCString(javascriptResult));
493     g_assert_cmpstr(resultString.get(), ==, webkitGTKURL);
494 }
495
496 void beforeAll()
497 {
498     EditorTest::add("WebKitWebView", "editable/editable", testWebViewEditorEditable);
499     EditorTest::add("WebKitWebView", "cut-copy-paste/non-editable", testWebViewEditorCutCopyPasteNonEditable);
500     EditorTest::add("WebKitWebView", "cut-copy-paste/editable", testWebViewEditorCutCopyPasteEditable);
501     EditorTest::add("WebKitWebView", "select-all/non-editable", testWebViewEditorSelectAllNonEditable);
502     EditorTest::add("WebKitWebView", "select-all/editable", testWebViewEditorSelectAllEditable);
503     EditorTest::add("WebKitWebView", "editor-state/typing-attributes", testWebViewEditorEditorStateTypingAttributes);
504     EditorTest::add("WebKitWebView", "insert/image", testWebViewEditorInsertImage);
505     EditorTest::add("WebKitWebView", "insert/link", testWebViewEditorCreateLink);
506 }
507
508 void afterAll()
509 {
510 }