summaryrefslogtreecommitdiff
path: root/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestUIClient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestUIClient.cpp')
-rw-r--r--Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestUIClient.cpp469
1 files changed, 443 insertions, 26 deletions
diff --git a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestUIClient.cpp b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestUIClient.cpp
index d24edc601..4c44039cc 100644
--- a/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestUIClient.cpp
+++ b/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestUIClient.cpp
@@ -20,13 +20,14 @@
#include "config.h"
#include "WebViewTest.h"
#include <wtf/HashSet.h>
-#include <wtf/gobject/GRefPtr.h>
+#include <wtf/glib/GRefPtr.h>
#include <wtf/text/StringHash.h>
static const char* kAlertDialogMessage = "WebKitGTK+ alert dialog message";
static const char* kConfirmDialogMessage = "WebKitGTK+ confirm dialog message";
static const char* kPromptDialogMessage = "WebKitGTK+ prompt dialog message";
static const char* kPromptDialogReturnedText = "WebKitGTK+ prompt dialog returned text";
+static const char* kBeforeUnloadConfirmDialogMessage = "WebKitGTK+ beforeunload dialog message";
class UIClientTest: public WebViewTest {
public:
@@ -117,9 +118,9 @@ public:
test->m_windowPropertiesChanged.add(g_param_spec_get_name(paramSpec));
}
- static GtkWidget* viewCreateCallback(WebKitWebView* webView, UIClientTest* test)
+ static GtkWidget* viewCreateCallback(WebKitWebView* webView, WebKitNavigationAction* navigation, UIClientTest* test)
{
- return test->viewCreate(webView);
+ return test->viewCreate(webView, navigation);
}
static void viewReadyToShowCallback(WebKitWebView* webView, UIClientTest* test)
@@ -146,6 +147,9 @@ public:
case WEBKIT_SCRIPT_DIALOG_PROMPT:
g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kPromptDialogReturnedText);
break;
+ case WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM:
+ g_assert_not_reached();
+ break;
}
g_main_loop_quit(m_mainLoop);
@@ -165,6 +169,13 @@ public:
webkit_script_dialog_prompt_set_text(dialog, kPromptDialogReturnedText);
}
+ void scriptBeforeUnloadConfirm(WebKitScriptDialog* dialog)
+ {
+ g_assert_cmpstr(webkit_script_dialog_get_message(dialog), ==, kBeforeUnloadConfirmDialogMessage);
+ m_scriptDialogConfirmed = true;
+ webkit_script_dialog_confirm_set_confirmed(dialog, m_scriptDialogConfirmed);
+ }
+
static gboolean scriptDialog(WebKitWebView*, WebKitScriptDialog* dialog, UIClientTest* test)
{
switch (webkit_script_dialog_get_dialog_type(dialog)) {
@@ -177,6 +188,9 @@ public:
case WEBKIT_SCRIPT_DIALOG_PROMPT:
test->scriptPrompt(dialog);
break;
+ case WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM:
+ test->scriptBeforeUnloadConfirm(dialog);
+ break;
}
return TRUE;
@@ -197,6 +211,12 @@ public:
g_assert(WEBKIT_IS_PERMISSION_REQUEST(request));
test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));
+ if (test->m_verifyMediaTypes && WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST(request)) {
+ WebKitUserMediaPermissionRequest* userMediaRequest = WEBKIT_USER_MEDIA_PERMISSION_REQUEST(request);
+ g_assert(webkit_user_media_permission_is_for_audio_device(userMediaRequest) == test->m_expectedAudioMedia);
+ g_assert(webkit_user_media_permission_is_for_video_device(userMediaRequest) == test->m_expectedVideoMedia);
+ }
+
if (test->m_allowPermissionRequests)
webkit_permission_request_allow(request);
else
@@ -205,10 +225,19 @@ public:
return TRUE;
}
+ static void permissionResultMessageReceivedCallback(WebKitUserContentManager* userContentManager, WebKitJavascriptResult* javascriptResult, UIClientTest* test)
+ {
+ test->m_permissionResult.reset(WebViewTest::javascriptResultToCString(javascriptResult));
+ g_main_loop_quit(test->m_mainLoop);
+ }
+
UIClientTest()
: m_scriptDialogType(WEBKIT_SCRIPT_DIALOG_ALERT)
, m_scriptDialogConfirmed(true)
, m_allowPermissionRequests(false)
+ , m_verifyMediaTypes(false)
+ , m_expectedAudioMedia(false)
+ , m_expectedVideoMedia(false)
, m_mouseTargetModifiers(0)
{
webkit_settings_set_javascript_can_open_windows_automatically(webkit_web_view_get_settings(m_webView), TRUE);
@@ -216,11 +245,33 @@ public:
g_signal_connect(m_webView, "script-dialog", G_CALLBACK(scriptDialog), this);
g_signal_connect(m_webView, "mouse-target-changed", G_CALLBACK(mouseTargetChanged), this);
g_signal_connect(m_webView, "permission-request", G_CALLBACK(permissionRequested), this);
+ webkit_user_content_manager_register_script_message_handler(m_userContentManager.get(), "permission");
+ g_signal_connect(m_userContentManager.get(), "script-message-received::permission", G_CALLBACK(permissionResultMessageReceivedCallback), this);
}
~UIClientTest()
{
g_signal_handlers_disconnect_matched(m_webView, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+ g_signal_handlers_disconnect_matched(m_userContentManager.get(), G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, this);
+ webkit_user_content_manager_unregister_script_message_handler(m_userContentManager.get(), "permission");
+ }
+
+ static void tryWebViewCloseCallback(UIClientTest* test)
+ {
+ g_main_loop_quit(test->m_mainLoop);
+ }
+
+ void tryCloseAndWaitUntilClosed()
+ {
+ gulong handler = g_signal_connect_swapped(m_webView, "close", G_CALLBACK(tryWebViewCloseCallback), this);
+ // Use an idle because webkit_web_view_try_close can emit the close signal in the
+ // current run loop iteration.
+ g_idle_add([](gpointer data) -> gboolean {
+ webkit_web_view_try_close(WEBKIT_WEB_VIEW(data));
+ return G_SOURCE_REMOVE;
+ }, m_webView);
+ g_main_loop_run(m_mainLoop);
+ g_signal_handler_disconnect(m_webView, handler);
}
void waitUntilMainLoopFinishes()
@@ -228,6 +279,13 @@ public:
g_main_loop_run(m_mainLoop);
}
+ const char* waitUntilPermissionResultMessageReceived()
+ {
+ m_permissionResult = nullptr;
+ g_main_loop_run(m_mainLoop);
+ return m_permissionResult.get();
+ }
+
void setExpectedWindowProperties(const WindowProperties& windowProperties)
{
m_windowProperties = windowProperties;
@@ -240,9 +298,19 @@ public:
return m_mouseTargetHitTestResult.get();
}
- virtual GtkWidget* viewCreate(WebKitWebView* webView)
+ void simulateUserInteraction()
+ {
+ runJavaScriptAndWaitUntilFinished("document.getElementById('testInput').focus()", nullptr);
+ keyStroke(GDK_KEY_a);
+ keyStroke(GDK_KEY_b);
+ while (gtk_events_pending())
+ gtk_main_iteration();
+ }
+
+ virtual GtkWidget* viewCreate(WebKitWebView* webView, WebKitNavigationAction* navigation)
{
g_assert(webView == m_webView);
+ g_assert(navigation);
GtkWidget* newWebView = webkit_web_view_new_with_context(webkit_web_view_get_context(webView));
g_object_ref_sink(newWebView);
@@ -287,10 +355,14 @@ public:
WebKitScriptDialogType m_scriptDialogType;
bool m_scriptDialogConfirmed;
bool m_allowPermissionRequests;
+ gboolean m_verifyMediaTypes;
+ gboolean m_expectedAudioMedia;
+ gboolean m_expectedVideoMedia;
WindowProperties m_windowProperties;
HashSet<WTF::String> m_windowPropertiesChanged;
GRefPtr<WebKitHitTestResult> m_mouseTargetHitTestResult;
unsigned m_mouseTargetModifiers;
+ GUniquePtr<char> m_permissionResult;
};
static void testWebViewCreateReadyClose(UIClientTest* test, gconstpointer)
@@ -305,6 +377,91 @@ static void testWebViewCreateReadyClose(UIClientTest* test, gconstpointer)
g_assert_cmpint(events[2], ==, UIClientTest::Close);
}
+class CreateNavigationDataTest: public UIClientTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(CreateNavigationDataTest);
+
+ CreateNavigationDataTest()
+ : m_navigation(nullptr)
+ {
+ }
+
+ ~CreateNavigationDataTest()
+ {
+ clearNavigation();
+ }
+
+ void clearNavigation()
+ {
+ if (m_navigation)
+ webkit_navigation_action_free(m_navigation);
+ m_navigation = nullptr;
+ }
+
+ GtkWidget* viewCreate(WebKitWebView* webView, WebKitNavigationAction* navigation)
+ {
+ g_assert(navigation);
+ g_assert(!m_navigation);
+ m_navigation = webkit_navigation_action_copy(navigation);
+ g_main_loop_quit(m_mainLoop);
+ return nullptr;
+ }
+
+ void loadHTML(const char* html)
+ {
+ clearNavigation();
+ WebViewTest::loadHtml(html, nullptr);
+ }
+
+ void clickAndWaitUntilMainLoopFinishes(int x, int y)
+ {
+ clearNavigation();
+ clickMouseButton(x, y, 1);
+ g_main_loop_run(m_mainLoop);
+ }
+
+ WebKitNavigationAction* m_navigation;
+};
+
+static void testWebViewCreateNavigationData(CreateNavigationDataTest* test, gconstpointer)
+{
+ test->showInWindowAndWaitUntilMapped();
+
+ test->loadHTML(
+ "<html><body>"
+ "<input style=\"position:absolute; left:0; top:0; margin:0; padding:0\" type=\"button\" value=\"click to show a popup\" onclick=\"window.open('data:foo');\"/>"
+ "<a style=\"position:absolute; left:20; top:20;\" href=\"data:bar\" target=\"_blank\">popup link</a>"
+ "</body></html>");
+ test->waitUntilLoadFinished();
+
+ // Click on a button.
+ test->clickAndWaitUntilMainLoopFinishes(5, 5);
+ g_assert_cmpstr(webkit_uri_request_get_uri(webkit_navigation_action_get_request(test->m_navigation)), ==, "data:foo");
+ g_assert_cmpuint(webkit_navigation_action_get_navigation_type(test->m_navigation), ==, WEBKIT_NAVIGATION_TYPE_OTHER);
+ // FIXME: This should be button 1.
+ g_assert_cmpuint(webkit_navigation_action_get_mouse_button(test->m_navigation), ==, 0);
+ g_assert_cmpuint(webkit_navigation_action_get_modifiers(test->m_navigation), ==, 0);
+ g_assert(webkit_navigation_action_is_user_gesture(test->m_navigation));
+
+ // Click on a link.
+ test->clickAndWaitUntilMainLoopFinishes(21, 21);
+ g_assert_cmpstr(webkit_uri_request_get_uri(webkit_navigation_action_get_request(test->m_navigation)), ==, "data:bar");
+ g_assert_cmpuint(webkit_navigation_action_get_navigation_type(test->m_navigation), ==, WEBKIT_NAVIGATION_TYPE_LINK_CLICKED);
+ g_assert_cmpuint(webkit_navigation_action_get_mouse_button(test->m_navigation), ==, 1);
+ g_assert_cmpuint(webkit_navigation_action_get_modifiers(test->m_navigation), ==, 0);
+ g_assert(webkit_navigation_action_is_user_gesture(test->m_navigation));
+
+ // No user interaction.
+ test->loadHTML("<html><body onLoad=\"window.open();\"></html>");
+ test->waitUntilMainLoopFinishes();
+
+ g_assert_cmpstr(webkit_uri_request_get_uri(webkit_navigation_action_get_request(test->m_navigation)), ==, "");
+ g_assert_cmpuint(webkit_navigation_action_get_navigation_type(test->m_navigation), ==, WEBKIT_NAVIGATION_TYPE_OTHER);
+ g_assert_cmpuint(webkit_navigation_action_get_mouse_button(test->m_navigation), ==, 0);
+ g_assert_cmpuint(webkit_navigation_action_get_modifiers(test->m_navigation), ==, 0);
+ g_assert(!webkit_navigation_action_is_user_gesture(test->m_navigation));
+}
+
static gboolean checkMimeTypeForFilter(GtkFileFilter* filter, const gchar* mimeType)
{
GtkFileFilterInfo filterInfo;
@@ -323,11 +480,11 @@ public:
test->m_webViewEvents.append(RunAsModal);
}
- GtkWidget* viewCreate(WebKitWebView* webView)
+ GtkWidget* viewCreate(WebKitWebView* webView, WebKitNavigationAction* navigation)
{
g_assert(webView == m_webView);
- GtkWidget* newWebView = UIClientTest::viewCreate(webView);
+ GtkWidget* newWebView = UIClientTest::viewCreate(webView, navigation);
g_signal_connect(newWebView, "run-as-modal", G_CALLBACK(dialogRunAsModalCallback), this);
return newWebView;
}
@@ -371,28 +528,80 @@ static void testWebViewDisallowModalDialogs(ModalDialogsTest* test, gconstpointe
static void testWebViewJavaScriptDialogs(UIClientTest* test, gconstpointer)
{
+ test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL);
+
static const char* htmlOnLoadFormat = "<html><body onLoad=\"%s\"></body></html>";
static const char* jsAlertFormat = "alert('%s')";
static const char* jsConfirmFormat = "do { confirmed = confirm('%s'); } while (!confirmed); alert('confirmed');";
static const char* jsPromptFormat = "alert(prompt('%s', 'default'));";
+ static const char* htmlOnBeforeUnloadFormat =
+ "<html><body onbeforeunload=\"return beforeUnloadHandler();\"><input id=\"testInput\" type=\"text\"></input><script>function beforeUnloadHandler() { return \"%s\"; }</script></body></html>";
test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_ALERT;
GUniquePtr<char> alertDialogMessage(g_strdup_printf(jsAlertFormat, kAlertDialogMessage));
GUniquePtr<char> alertHTML(g_strdup_printf(htmlOnLoadFormat, alertDialogMessage.get()));
test->loadHtml(alertHTML.get(), 0);
test->waitUntilMainLoopFinishes();
+ webkit_web_view_stop_loading(test->m_webView);
+ test->waitUntilLoadFinished();
test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_CONFIRM;
GUniquePtr<char> confirmDialogMessage(g_strdup_printf(jsConfirmFormat, kConfirmDialogMessage));
GUniquePtr<char> confirmHTML(g_strdup_printf(htmlOnLoadFormat, confirmDialogMessage.get()));
test->loadHtml(confirmHTML.get(), 0);
test->waitUntilMainLoopFinishes();
+ webkit_web_view_stop_loading(test->m_webView);
+ test->waitUntilLoadFinished();
test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_PROMPT;
GUniquePtr<char> promptDialogMessage(g_strdup_printf(jsPromptFormat, kPromptDialogMessage));
GUniquePtr<char> promptHTML(g_strdup_printf(htmlOnLoadFormat, promptDialogMessage.get()));
test->loadHtml(promptHTML.get(), 0);
test->waitUntilMainLoopFinishes();
+ webkit_web_view_stop_loading(test->m_webView);
+ test->waitUntilLoadFinished();
+
+ test->m_scriptDialogType = WEBKIT_SCRIPT_DIALOG_BEFORE_UNLOAD_CONFIRM;
+ GUniquePtr<char> beforeUnloadDialogHTML(g_strdup_printf(htmlOnBeforeUnloadFormat, kBeforeUnloadConfirmDialogMessage));
+ test->loadHtml(beforeUnloadDialogHTML.get(), nullptr);
+ test->waitUntilLoadFinished();
+
+ // Reload should trigger onbeforeunload.
+#if 0
+ test->simulateUserInteraction();
+ // FIXME: reloading HTML data doesn't emit finished load event.
+ // See https://bugs.webkit.org/show_bug.cgi?id=139089.
+ test->m_scriptDialogConfirmed = false;
+ webkit_web_view_reload(test->m_webView);
+ test->waitUntilLoadFinished();
+ g_assert(test->m_scriptDialogConfirmed);
+#endif
+
+ // Navigation should trigger onbeforeunload.
+ test->simulateUserInteraction();
+ test->m_scriptDialogConfirmed = false;
+ test->loadHtml("<html></html>", nullptr);
+ test->waitUntilLoadFinished();
+ g_assert(test->m_scriptDialogConfirmed);
+
+ // Try close should trigger onbeforeunload.
+ test->m_scriptDialogConfirmed = false;
+ test->loadHtml(beforeUnloadDialogHTML.get(), nullptr);
+ test->waitUntilLoadFinished();
+ test->simulateUserInteraction();
+ test->tryCloseAndWaitUntilClosed();
+ g_assert(test->m_scriptDialogConfirmed);
+
+ // Try close on a page with no unload handlers should not trigger onbeforeunload,
+ // but should actually close the page.
+ test->m_scriptDialogConfirmed = false;
+ test->loadHtml("<html><body></body></html>", nullptr);
+ test->waitUntilLoadFinished();
+ // We got a onbeforeunload of the previous page.
+ g_assert(test->m_scriptDialogConfirmed);
+ test->m_scriptDialogConfirmed = false;
+ test->tryCloseAndWaitUntilClosed();
+ g_assert(!test->m_scriptDialogConfirmed);
}
static void testWebViewWindowProperties(UIClientTest* test, gconstpointer)
@@ -423,13 +632,22 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer)
test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL);
const char* linksHoveredHTML =
- "<html><body>"
+ "<html><head>"
+ " <script>"
+ " window.onload = function () {"
+ " window.getSelection().removeAllRanges();"
+ " var select_range = document.createRange();"
+ " select_range.selectNodeContents(document.getElementById('text_to_select'));"
+ " window.getSelection().addRange(select_range);"
+ " }"
+ " </script>"
+ "</head><body>"
" <a style='position:absolute; left:1; top:1' href='http://www.webkitgtk.org' title='WebKitGTK+ Title'>WebKitGTK+ Website</a>"
" <img style='position:absolute; left:1; top:10' src='0xdeadbeef' width=5 height=5></img>"
" <a style='position:absolute; left:1; top:20' href='http://www.webkitgtk.org/logo' title='WebKitGTK+ Logo'><img src='0xdeadbeef' width=5 height=5></img></a>"
" <input style='position:absolute; left:1; top:30' size='10'></input>"
- " <div style='position:absolute; left:1; top:50; width:30; height:30; overflow:scroll'>&nbsp;</div>"
" <video style='position:absolute; left:1; top:100' width='300' height='300' controls='controls' preload='none'><source src='movie.ogg' type='video/ogg' /></video>"
+ " <p style='position:absolute; left:1; top:120' id='text_to_select'>Lorem ipsum.</p>"
"</body></html>";
test->loadHtml(linksHoveredHTML, "file:///");
@@ -441,6 +659,7 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer)
g_assert(!webkit_hit_test_result_context_is_image(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_media(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult));
+ g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult));
g_assert_cmpstr(webkit_hit_test_result_get_link_uri(hitTestResult), ==, "http://www.webkitgtk.org/");
g_assert_cmpstr(webkit_hit_test_result_get_link_title(hitTestResult), ==, "WebKitGTK+ Title");
g_assert_cmpstr(webkit_hit_test_result_get_link_label(hitTestResult), ==, "WebKitGTK+ Website");
@@ -452,6 +671,7 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer)
g_assert(!webkit_hit_test_result_context_is_image(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_media(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult));
+ g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult));
g_assert(!test->m_mouseTargetModifiers);
// Move over image with GDK_CONTROL_MASK.
@@ -460,6 +680,7 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer)
g_assert(webkit_hit_test_result_context_is_image(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_media(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult));
+ g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_scrollbar(hitTestResult));
g_assert_cmpstr(webkit_hit_test_result_get_image_uri(hitTestResult), ==, "file:///0xdeadbeef");
g_assert(test->m_mouseTargetModifiers & GDK_CONTROL_MASK);
@@ -471,6 +692,7 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer)
g_assert(!webkit_hit_test_result_context_is_media(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_scrollbar(hitTestResult));
+ g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult));
g_assert_cmpstr(webkit_hit_test_result_get_link_uri(hitTestResult), ==, "http://www.webkitgtk.org/logo");
g_assert_cmpstr(webkit_hit_test_result_get_image_uri(hitTestResult), ==, "file:///0xdeadbeef");
g_assert_cmpstr(webkit_hit_test_result_get_link_title(hitTestResult), ==, "WebKitGTK+ Logo");
@@ -484,6 +706,7 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer)
g_assert(webkit_hit_test_result_context_is_media(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_scrollbar(hitTestResult));
+ g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult));
g_assert_cmpstr(webkit_hit_test_result_get_media_uri(hitTestResult), ==, "file:///movie.ogg");
g_assert(!test->m_mouseTargetModifiers);
@@ -494,19 +717,32 @@ static void testWebViewMouseTarget(UIClientTest* test, gconstpointer)
g_assert(!webkit_hit_test_result_context_is_media(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_scrollbar(hitTestResult));
g_assert(webkit_hit_test_result_context_is_editable(hitTestResult));
+ g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult));
g_assert(!test->m_mouseTargetModifiers);
// Move over scrollbar.
- hitTestResult = test->moveMouseAndWaitUntilMouseTargetChanged(5, 75);
+ hitTestResult = test->moveMouseAndWaitUntilMouseTargetChanged(gtk_widget_get_allocated_width(GTK_WIDGET(test->m_webView)) - 4, 5);
g_assert(!webkit_hit_test_result_context_is_link(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_image(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_media(hitTestResult));
g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult));
g_assert(webkit_hit_test_result_context_is_scrollbar(hitTestResult));
+ g_assert(!webkit_hit_test_result_context_is_selection(hitTestResult));
+ g_assert(!test->m_mouseTargetModifiers);
+
+ // Move over selection.
+ hitTestResult = test->moveMouseAndWaitUntilMouseTargetChanged(2, 145);
+ g_assert(!webkit_hit_test_result_context_is_link(hitTestResult));
+ g_assert(!webkit_hit_test_result_context_is_image(hitTestResult));
+ g_assert(!webkit_hit_test_result_context_is_media(hitTestResult));
+ g_assert(!webkit_hit_test_result_context_is_editable(hitTestResult));
+ g_assert(!webkit_hit_test_result_context_is_scrollbar(hitTestResult));
+ g_assert(webkit_hit_test_result_context_is_selection(hitTestResult));
g_assert(!test->m_mouseTargetModifiers);
+
}
-static void testWebViewPermissionRequests(UIClientTest* test, gconstpointer)
+static void testWebViewGeolocationPermissionRequests(UIClientTest* test, gconstpointer)
{
// Some versions of geoclue give a runtime warning because it tries
// to register the error quark twice. See https://bugs.webkit.org/show_bug.cgi?id=89858.
@@ -518,35 +754,108 @@ static void testWebViewPermissionRequests(UIClientTest* test, gconstpointer)
" <script>"
" function runTest()"
" {"
- " navigator.geolocation.getCurrentPosition(function(p) { document.title = \"OK\" },"
- " function(e) { document.title = e.code });"
+ " navigator.geolocation.getCurrentPosition(function(p) { window.webkit.messageHandlers.permission.postMessage('OK'); },"
+ " function(e) { window.webkit.messageHandlers.permission.postMessage(e.code.toString()); });"
" }"
" </script>"
" <body onload='runTest();'></body>"
"</html>";
- // Test denying a permission request.
+ // Geolocation is not allowed from insecure connections like HTTP,
+ // POSITION_UNAVAILABLE ('2') is returned in that case without even
+ // asking the API layer.
test->m_allowPermissionRequests = false;
- test->loadHtml(geolocationRequestHTML, 0);
- test->waitUntilTitleChanged();
+ test->loadHtml(geolocationRequestHTML, "http://foo.com/bar");
+ const gchar* result = test->waitUntilPermissionResultMessageReceived();
+ g_assert_cmpstr(result, ==, "2");
- // According to the Geolocation API specification, '1' is the
- // error code returned for the PERMISSION_DENIED error.
- // http://dev.w3.org/geo/api/spec-source.html#position_error_interface
- const gchar* result = webkit_web_view_get_title(test->m_webView);
+ // Test denying a permission request. PERMISSION_DENIED ('1') is
+ // returned in this case.
+ test->m_allowPermissionRequests = false;
+ test->loadHtml(geolocationRequestHTML, "https://foo.com/bar");
+ result = test->waitUntilPermissionResultMessageReceived();
g_assert_cmpstr(result, ==, "1");
- // Test allowing a permission request.
+ // Test allowing a permission request. Result should be different
+ // to PERMISSION_DENIED ('1').
test->m_allowPermissionRequests = true;
- test->loadHtml(geolocationRequestHTML, 0);
- test->waitUntilTitleChanged();
-
- // Check that we did not get the PERMISSION_DENIED error now.
- result = webkit_web_view_get_title(test->m_webView);
+ test->loadHtml(geolocationRequestHTML, "https://foo.com/bar");
+ result = test->waitUntilPermissionResultMessageReceived();
g_assert_cmpstr(result, !=, "1");
test->addLogFatalFlag(G_LOG_LEVEL_WARNING);
}
+#if ENABLE(MEDIA_STREAM)
+static void testWebViewUserMediaPermissionRequests(UIClientTest* test, gconstpointer)
+{
+ WebKitSettings* settings = webkit_web_view_get_settings(test->m_webView);
+ gboolean enabled = webkit_settings_get_enable_media_stream(settings);
+ webkit_settings_set_enable_media_stream(settings, TRUE);
+
+ test->showInWindowAndWaitUntilMapped();
+ static const char* userMediaRequestHTML =
+ "<html>"
+ " <script>"
+ " function runTest()"
+ " {"
+ " navigator.webkitGetUserMedia({audio: true, video: true},"
+ " function(s) { document.title = \"OK\" },"
+ " function(e) { document.title = e.name });"
+ " }"
+ " </script>"
+ " <body onload='runTest();'></body>"
+ "</html>";
+
+ test->m_verifyMediaTypes = TRUE;
+ test->m_expectedAudioMedia = TRUE;
+ test->m_expectedVideoMedia = TRUE;
+
+ // Test denying a permission request.
+ test->m_allowPermissionRequests = false;
+ test->loadHtml(userMediaRequestHTML, nullptr);
+ test->waitUntilTitleChangedTo("PermissionDeniedError");
+
+ // Test allowing a permission request.
+ test->m_allowPermissionRequests = true;
+ test->loadHtml(userMediaRequestHTML, nullptr);
+ test->waitUntilTitleChangedTo("OK");
+
+ webkit_settings_set_enable_media_stream(settings, enabled);
+}
+
+static void testWebViewAudioOnlyUserMediaPermissionRequests(UIClientTest* test, gconstpointer)
+{
+ WebKitSettings* settings = webkit_web_view_get_settings(test->m_webView);
+ gboolean enabled = webkit_settings_get_enable_media_stream(settings);
+ webkit_settings_set_enable_media_stream(settings, TRUE);
+
+ test->showInWindowAndWaitUntilMapped();
+ static const char* userMediaRequestHTML =
+ "<html>"
+ " <script>"
+ " function runTest()"
+ " {"
+ " navigator.webkitGetUserMedia({audio: true, video: false},"
+ " function(s) { document.title = \"OK\" },"
+ " function(e) { document.title = e.name });"
+ " }"
+ " </script>"
+ " <body onload='runTest();'></body>"
+ "</html>";
+
+ test->m_verifyMediaTypes = TRUE;
+ test->m_expectedAudioMedia = TRUE;
+ test->m_expectedVideoMedia = FALSE;
+
+ // Test denying a permission request.
+ test->m_allowPermissionRequests = false;
+ test->loadHtml(userMediaRequestHTML, nullptr);
+ test->waitUntilTitleChangedTo("PermissionDeniedError");
+
+ webkit_settings_set_enable_media_stream(settings, enabled);
+}
+#endif // ENABLE(MEDIA_STREAM)
+
class FileChooserTest: public UIClientTest {
public:
MAKE_GLIB_TEST_FIXTURE(FileChooserTest);
@@ -662,16 +971,124 @@ static void testWebViewFileChooserRequest(FileChooserTest* test, gconstpointer)
webkit_file_chooser_request_cancel(fileChooserRequest);
}
+class ColorChooserTest: public WebViewTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(ColorChooserTest);
+
+ static gboolean runColorChooserCallback(WebKitWebView*, WebKitColorChooserRequest* request, ColorChooserTest* test)
+ {
+ test->runColorChooser(request);
+ return TRUE;
+ }
+
+ static void requestFinishedCallback(WebKitColorChooserRequest* request, ColorChooserTest* test)
+ {
+ g_assert(test->m_request.get() == request);
+ test->m_request = nullptr;
+ if (g_main_loop_is_running(test->m_mainLoop))
+ g_main_loop_quit(test->m_mainLoop);
+ }
+
+ ColorChooserTest()
+ {
+ g_signal_connect(m_webView, "run-color-chooser", G_CALLBACK(runColorChooserCallback), this);
+ }
+
+ void runColorChooser(WebKitColorChooserRequest* request)
+ {
+ g_assert(WEBKIT_IS_COLOR_CHOOSER_REQUEST(request));
+ assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));
+ m_request = request;
+ g_signal_connect(request, "finished", G_CALLBACK(requestFinishedCallback), this);
+ g_main_loop_quit(m_mainLoop);
+ }
+
+ void finishRequest()
+ {
+ g_assert(m_request.get());
+ webkit_color_chooser_request_finish(m_request.get());
+ g_assert(!m_request);
+ }
+
+ void cancelRequest()
+ {
+ g_assert(m_request.get());
+ webkit_color_chooser_request_cancel(m_request.get());
+ g_assert(!m_request);
+ }
+
+ WebKitColorChooserRequest* clickMouseButtonAndWaitForColorChooserRequest(int x, int y)
+ {
+ clickMouseButton(x, y);
+ g_main_loop_run(m_mainLoop);
+ g_assert(m_request.get());
+ return m_request.get();
+ }
+
+private:
+ GRefPtr<WebKitColorChooserRequest> m_request;
+};
+
+static void testWebViewColorChooserRequest(ColorChooserTest* test, gconstpointer)
+{
+ static const char* colorChooserHTMLFormat = "<html><body><input style='position:absolute;left:1;top:1;margin:0;padding:0;width:45;height:25' type='color' %s/></body></html>";
+ test->showInWindowAndWaitUntilMapped();
+
+ GUniquePtr<char> defaultColorHTML(g_strdup_printf(colorChooserHTMLFormat, ""));
+ test->loadHtml(defaultColorHTML.get(), nullptr);
+ test->waitUntilLoadFinished();
+ WebKitColorChooserRequest* request = test->clickMouseButtonAndWaitForColorChooserRequest(5, 5);
+
+ // Default color is black (#000000).
+ GdkRGBA rgba1;
+ GdkRGBA rgba2 = { 0., 0., 0., 1. };
+ webkit_color_chooser_request_get_rgba(request, &rgba1);
+ g_assert(gdk_rgba_equal(&rgba1, &rgba2));
+
+ // Set a different color.
+ rgba2.green = 1;
+ webkit_color_chooser_request_set_rgba(request, &rgba2);
+ webkit_color_chooser_request_get_rgba(request, &rgba1);
+ g_assert(gdk_rgba_equal(&rgba1, &rgba2));
+
+ GdkRectangle rect;
+ webkit_color_chooser_request_get_element_rectangle(request, &rect);
+ g_assert_cmpint(rect.x, == , 1);
+ g_assert_cmpint(rect.y, == , 1);
+ g_assert_cmpint(rect.width, == , 45);
+ g_assert_cmpint(rect.height, == , 25);
+
+ test->finishRequest();
+
+ // Use an initial color.
+ GUniquePtr<char> initialColorHTML(g_strdup_printf(colorChooserHTMLFormat, "value='#FF00FF'"));
+ test->loadHtml(initialColorHTML.get(), nullptr);
+ test->waitUntilLoadFinished();
+ request = test->clickMouseButtonAndWaitForColorChooserRequest(5, 5);
+
+ webkit_color_chooser_request_get_rgba(request, &rgba1);
+ GdkRGBA rgba3 = { 1., 0., 1., 1. };
+ g_assert(gdk_rgba_equal(&rgba1, &rgba3));
+
+ test->cancelRequest();
+}
+
void beforeAll()
{
UIClientTest::add("WebKitWebView", "create-ready-close", testWebViewCreateReadyClose);
+ CreateNavigationDataTest::add("WebKitWebView", "create-navigation-data", testWebViewCreateNavigationData);
ModalDialogsTest::add("WebKitWebView", "allow-modal-dialogs", testWebViewAllowModalDialogs);
ModalDialogsTest::add("WebKitWebView", "disallow-modal-dialogs", testWebViewDisallowModalDialogs);
UIClientTest::add("WebKitWebView", "javascript-dialogs", testWebViewJavaScriptDialogs);
UIClientTest::add("WebKitWebView", "window-properties", testWebViewWindowProperties);
UIClientTest::add("WebKitWebView", "mouse-target", testWebViewMouseTarget);
- UIClientTest::add("WebKitWebView", "permission-requests", testWebViewPermissionRequests);
+ UIClientTest::add("WebKitWebView", "geolocation-permission-requests", testWebViewGeolocationPermissionRequests);
+#if ENABLE(MEDIA_STREAM)
+ UIClientTest::add("WebKitWebView", "usermedia-permission-requests", testWebViewUserMediaPermissionRequests);
+ UIClientTest::add("WebKitWebView", "audio-usermedia-permission-request", testWebViewAudioOnlyUserMediaPermissionRequests);
+#endif
FileChooserTest::add("WebKitWebView", "file-chooser-request", testWebViewFileChooserRequest);
+ ColorChooserTest::add("WebKitWebView", "color-chooser-request", testWebViewColorChooserRequest);
}
void afterAll()