Changeset 244212 in webkit
- Timestamp:
- Apr 12, 2019 1:46:57 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r244210 r244212 1 2019-04-11 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GTK] REGRESSION(r243860): Many tests failing 4 https://bugs.webkit.org/show_bug.cgi?id=196791 5 6 Reviewed by Joanmarie Diggs. 7 8 Remove expectations for tests that pass now. 9 10 * platform/gtk/TestExpectations: 11 1 12 2019-04-11 Megan Gardner <megan_gardner@apple.com> 2 13 -
trunk/LayoutTests/platform/gtk/TestExpectations
r244187 r244212 1894 1894 webkit.org/b/181030 wasm/iframe-postmessage.html [ Pass Failure ] 1895 1895 webkit.org/b/179948 [ Release ] fast/hidpi/filters-reference.html [ Pass ImageOnlyFailure ] 1896 webkit.org/b/1 96791 webkit.org/b/181031 fast/frames/crash-when-iframe-is-remove-in-eventhandler.html [ Pass Crash Failure]1896 webkit.org/b/181031 fast/frames/crash-when-iframe-is-remove-in-eventhandler.html [ Pass Crash ] 1897 1897 1898 1898 webkit.org/b/181528 http/tests/cache/memory-cache-pruning.html [ Pass Crash ] … … 3818 3818 webkit.org/b/196541 editing/pasteboard/paste-content-with-overflow-auto-parent-across-origin.html [ Failure ] 3819 3819 3820 webkit.org/b/196791 tables/mozilla/dom/deleteCol1.html [ Failure ]3821 webkit.org/b/196791 tables/mozilla/dom/deleteCol2.html [ Failure ]3822 webkit.org/b/196791 tables/mozilla/dom/deleteCol3.html [ Failure ]3823 webkit.org/b/196791 tables/mozilla/dom/deleteColGroup1.html [ Failure ]3824 webkit.org/b/196791 tables/mozilla/dom/deleteColGroup2.html [ Failure ]3825 webkit.org/b/196791 tables/mozilla/dom/insertColGroups1.html [ Failure ]3826 webkit.org/b/196791 tables/mozilla/dom/insertColGroups2.html [ Failure ]3827 webkit.org/b/196791 tables/mozilla/dom/insertCols1.html [ Failure ]3828 webkit.org/b/196791 tables/mozilla/dom/insertCols2.html [ Failure ]3829 webkit.org/b/196791 tables/mozilla/dom/insertCols3.html [ Failure ]3830 webkit.org/b/196791 tables/mozilla/dom/insertCols4.html [ Failure ]3831 webkit.org/b/196791 tables/mozilla/dom/insertCols5.html [ Failure ]3832 webkit.org/b/196791 svg/hixie/text/003.html [ Failure ]3833 webkit.org/b/196791 svg/custom/linking-uri-01-b.svg [ Failure ]3834 webkit.org/b/196791 imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute-width-1000px.html [ Failure ]3835 webkit.org/b/196791 fast/text/international/bidi-listbox-atsui.html [ Failure ]3836 webkit.org/b/196791 fast/text/international/bidi-innertext.html [ Failure ]3837 webkit.org/b/196791 fast/text/international/bidi-L2-run-reordering.html [ Failure ]3838 webkit.org/b/196791 fast/scrolling/scroll-animator-select-list-events.html [ Failure ]3839 webkit.org/b/196791 fast/scrolling/scroll-animator-overlay-scrollbars-hovered.html [ Failure ]3840 webkit.org/b/196791 fast/scrolling/scroll-animator-overlay-scrollbars-clicked.html [ Failure ]3841 webkit.org/b/196791 fast/scrolling/scroll-animator-basic-events.html [ Failure ]3842 webkit.org/b/196791 fast/frames/inline-object-inside-frameset.html [ Failure ]3843 webkit.org/b/196791 fast/forms/visual-hebrew-text-field.html [ Failure ]3844 webkit.org/b/196791 fast/forms/select-visual-hebrew.html [ Failure ]3845 webkit.org/b/196791 fast/forms/form-submission-crash-3.html [ Failure ]3846 webkit.org/b/196791 compositing/backing/backing-store-attachment-empty-keyframe.html [ Failure ]3847 webkit.org/b/196791 fast/images/animated-gif-no-layout.html [ Failure ]3848 webkit.org/b/196791 http/tests/incremental/stylesheet-body-incremental-rendering.html [ Failure ]3849 webkit.org/b/196791 http/tests/webfont/font-loading-system-fallback-visibility-FontRanges.html [ Failure ]3850 webkit.org/b/196791 mathml/scripts-removeChild.html [ Failure ]3851 webkit.org/b/196791 mathml/presentation/attributes-accent-accentunder-dynamic.html [ Failure ]3852 webkit.org/b/196791 mathml/presentation/menclose-notation-attribute-add.html [ Failure ]3853 webkit.org/b/196791 mathml/presentation/menclose-notation-attribute-change-value.html [ Failure ]3854 webkit.org/b/196791 mathml/presentation/menclose-notation-attribute-remove.html [ Failure ]3855 webkit.org/b/196791 mathml/presentation/mo-form-dynamic.html [ Failure ]3856 webkit.org/b/196791 mathml/presentation/mpadded-dynamic.html [ Failure ]3857 webkit.org/b/196791 mathml/presentation/stretchy-minsize-maxsize-dynamic.html [ Failure ]3858 webkit.org/b/196791 svg/custom/textPath-change-id-pattern.svg [ Failure ]3859 webkit.org/b/196791 svg/custom/textPath-change-id.svg [ Failure ]3860 webkit.org/b/196791 svg/custom/textPath-insert-path-pattern.svg [ Failure ]3861 webkit.org/b/196791 svg/custom/textPath-insert-path.svg [ Failure ]3862 3863 3820 #//////////////////////////////////////////////////////////////////////////////////////// 3864 3821 # End of non-crashing, non-flaky tests failing -
trunk/Source/WebKit/ChangeLog
r244205 r244212 1 2019-04-11 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GTK] REGRESSION(r243860): Many tests failing 4 https://bugs.webkit.org/show_bug.cgi?id=196791 5 6 Reviewed by Joanmarie Diggs. 7 8 Calling updateAccessibilityTree() on document loaded was causing a re-layout because of the backing store update 9 that confused all those tests. We shouldn't need to update the accessibility tree on document load, it should 10 happen automatically when root object is attached/detached. This patch emits children-changed::add when the root 11 object wrapper is attached and children-changed::remove when the root object is detached. That way ATs are 12 notified of the changes in the accessibility tree. 13 14 * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: 15 (WebKit::WebFrameLoaderClient::dispatchDidFinishDocumentLoad): Remove call to WebPage::updateAccessibilityTree(). 16 * WebProcess/WebPage/WebPage.h: Remove updateAccessibilityTree(). 17 * WebProcess/WebPage/atk/WebKitWebPageAccessibilityObject.cpp: 18 (coreRootObjectWrapperDetachedCallback): Emit children-changed::remove. 19 (rootWebAreaWrapper): Helper to get the root WebArea wrapper. 20 (accessibilityRootObjectWrapper): Set the parent here when root object is created and emit children-changed::add. 21 (webkitWebPageAccessibilityObjectRefChild): Dot no set the parent here, it's now set when the root object is created. 22 * WebProcess/WebPage/atk/WebKitWebPageAccessibilityObject.h: Remove webkitWebPageAccessibilityObjectRefresh(). 23 * WebProcess/WebPage/gtk/WebPageGtk.cpp: 24 1 25 2019-04-11 Megan Gardner <megan_gardner@apple.com> 2 26 -
trunk/Source/WebKit/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp
r244161 r244212 600 600 // Notify the UIProcess. 601 601 webPage->send(Messages::WebPageProxy::DidFinishDocumentLoadForFrame(m_frame->frameID(), navigationID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); 602 603 #if HAVE(ACCESSIBILITY) && PLATFORM(GTK)604 // Ensure the accessibility hierarchy is updated.605 webPage->updateAccessibilityTree();606 #endif607 602 } 608 603 -
trunk/Source/WebKit/WebProcess/WebPage/WebPage.h
r244202 r244212 806 806 #endif 807 807 808 #if HAVE(ACCESSIBILITY) && PLATFORM(GTK)809 void updateAccessibilityTree();810 #endif811 812 808 void setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length, bool suppressUnderline); 813 809 bool hasCompositionForTesting(); -
trunk/Source/WebKit/WebProcess/WebPage/atk/WebKitWebPageAccessibilityObject.cpp
r243928 r244212 31 31 #include "WebPage.h" 32 32 #include <WebCore/AXObjectCache.h> 33 #include <WebCore/AccessibilityScrollView.h> 33 34 #include <WebCore/Document.h> 34 35 #include <WebCore/Frame.h> … … 44 45 45 46 WEBKIT_DEFINE_TYPE(WebKitWebPageAccessibilityObject, webkit_web_page_accessibility_object, ATK_TYPE_PLUG) 47 48 static void coreRootObjectWrapperDetachedCallback(AtkObject* wrapper, const char*, gboolean value, AtkObject* atkObject) 49 { 50 if (!value) 51 return; 52 53 g_signal_emit_by_name(atkObject, "children-changed::remove", 0, wrapper); 54 } 55 56 static AccessibilityObjectWrapper* rootWebAreaWrapper(AccessibilityObject& rootObject) 57 { 58 if (!rootObject.isAccessibilityScrollView()) 59 return nullptr; 60 61 if (auto* webAreaObject = downcast<AccessibilityScrollView>(rootObject).webAreaObject()) 62 return webAreaObject->wrapper(); 63 64 return nullptr; 65 } 46 66 47 67 static AtkObject* accessibilityRootObjectWrapper(AtkObject* atkObject) … … 70 90 return nullptr; 71 91 72 return ATK_OBJECT(coreRootObject->wrapper()); 92 auto* wrapper = ATK_OBJECT(coreRootObject->wrapper()); 93 if (!wrapper) 94 return nullptr; 95 96 if (atk_object_peek_parent(wrapper) != ATK_OBJECT(accessible)) { 97 atk_object_set_parent(wrapper, ATK_OBJECT(accessible)); 98 g_signal_emit_by_name(accessible, "children-changed::add", 0, wrapper); 99 100 if (auto* webAreaWrapper = rootWebAreaWrapper(*coreRootObject)) { 101 g_signal_connect_object(webAreaWrapper, "state-change::defunct", 102 G_CALLBACK(coreRootObjectWrapperDetachedCallback), accessible, static_cast<GConnectFlags>(0)); 103 } 104 } 105 106 return wrapper; 73 107 } 74 108 … … 99 133 return nullptr; 100 134 101 AtkObject* rootObject = accessibilityRootObjectWrapper(atkObject); 102 if (!rootObject) 103 return nullptr; 135 if (auto* rootObjectWrapper = accessibilityRootObjectWrapper(atkObject)) 136 return ATK_OBJECT(g_object_ref(rootObjectWrapper)); 104 137 105 atk_object_set_parent(rootObject, atkObject); 106 g_object_ref(rootObject); 107 108 return rootObject; 138 return nullptr; 109 139 } 110 140 … … 128 158 } 129 159 130 void webkitWebPageAccessibilityObjectRefresh(WebKitWebPageAccessibilityObject* accessible)131 {132 // We just need to ensure that there's a connection in the ATK133 // world between this accessibility object and the AtkObject of134 // the accessibility object for the root of the DOM tree.135 if (auto* rootObject = accessibilityRootObjectWrapper(ATK_OBJECT(accessible)))136 atk_object_set_parent(rootObject, ATK_OBJECT(accessible));137 }138 139 160 #endif // HAVE(ACCESSIBILITY) -
trunk/Source/WebKit/WebProcess/WebPage/atk/WebKitWebPageAccessibilityObject.h
r243863 r244212 61 61 AtkObject* webkitWebPageAccessibilityObjectNew(WebKit::WebPage*); 62 62 63 void webkitWebPageAccessibilityObjectRefresh(WebKitWebPageAccessibilityObject*);64 65 63 G_END_DECLS 66 64 -
trunk/Source/WebKit/WebProcess/WebPage/gtk/WebPageGtk.cpp
r243863 r244212 112 112 } 113 113 114 #if HAVE(ACCESSIBILITY)115 void WebPage::updateAccessibilityTree()116 {117 if (!m_accessibilityObject)118 return;119 120 webkitWebPageAccessibilityObjectRefresh(WEBKIT_WEB_PAGE_ACCESSIBILITY_OBJECT(m_accessibilityObject.get()));121 }122 #endif123 124 114 bool WebPage::performDefaultBehaviorForKeyEvent(const WebKeyboardEvent& keyboardEvent) 125 115 { -
trunk/Tools/ChangeLog
r244207 r244212 1 2019-04-11 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [GTK] REGRESSION(r243860): Many tests failing 4 https://bugs.webkit.org/show_bug.cgi?id=196791 5 6 Reviewed by Joanmarie Diggs. 7 8 Rework the accessibility unit test to use DBus for the communication with the server. This way we can load 9 multiple documents and check that accessibility hierarchy is updated after a navigation. 10 11 * TestWebKitAPI/Tests/WebKitGtk/AccessibilityTestServer.cpp: 12 (loadChangedCallback): 13 * TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp: 14 (AccessibilityTest::AccessibilityTest): 15 (AccessibilityTest::~AccessibilityTest): 16 (AccessibilityTest::loadHTMLAndWaitUntilFinished): 17 (AccessibilityTest::findTestServerApplication): 18 (AccessibilityTest::findDocumentWeb): 19 (AccessibilityTest::findRootObject): 20 (AccessibilityTest::waitUntilChildrenRemoved): 21 (AccessibilityTest::ensureProxy): 22 (testAtspiBasicHierarchy): 23 (beforeAll): 24 (afterAll): 25 1 26 2019-04-11 Aakash Jain <aakash_jain@apple.com> 2 27 -
trunk/Tools/TestWebKitAPI/Tests/WebKitGtk/AccessibilityTestServer.cpp
r161366 r244212 1 1 /* 2 * Copyright (C) 2012 Igalia S.L.2 * Copyright (C) 2012, 2019 Igalia S.L. 3 3 * 4 4 * This library is free software; you can redistribute it and/or … … 23 23 #include <webkit2/webkit2.h> 24 24 25 static void loadChangedCallback(WebKitWebView*, WebKitLoadEvent loadEvent, gpointer) 25 static const char introspectionXML[] = 26 "<node>" 27 " <interface name='org.webkit.gtk.AccessibilityTest'>" 28 " <method name='LoadHTML'>" 29 " <arg type='s' name='html' direction='in'/>" 30 " <arg type='s' name='baseURI' direction='in'/>" 31 " </method>" 32 " </interface>" 33 "</node>"; 34 35 static void loadChangedCallback(WebKitWebView* webView, WebKitLoadEvent loadEvent, GDBusMethodInvocation* invocation) 26 36 { 27 // Send a message to the parent process when we're ready. 28 if (loadEvent == WEBKIT_LOAD_FINISHED) 29 g_print("OK"); 37 if (loadEvent != WEBKIT_LOAD_FINISHED) 38 return; 39 40 g_signal_handlers_disconnect_by_func(webView, reinterpret_cast<void*>(loadChangedCallback), invocation); 41 g_dbus_method_invocation_return_value(invocation, nullptr); 30 42 } 43 44 static const GDBusInterfaceVTable interfaceVirtualTable = { 45 // methodCall 46 [](GDBusConnection* connection, const char* sender, const char* objectPath, const char* interfaceName, const char* methodName, GVariant* parameters, GDBusMethodInvocation* invocation, gpointer userData) { 47 if (g_strcmp0(interfaceName, "org.webkit.gtk.AccessibilityTest")) 48 return; 49 50 auto* webView = WEBKIT_WEB_VIEW(userData); 51 52 if (!g_strcmp0(methodName, "LoadHTML")) { 53 const char* html; 54 const char* baseURI; 55 g_variant_get(parameters, "(&s&s)", &html, &baseURI); 56 g_signal_connect(webView, "load-changed", G_CALLBACK(loadChangedCallback), invocation); 57 webkit_web_view_load_html(webView, html, baseURI && *baseURI ? baseURI : nullptr); 58 } 59 }, 60 nullptr, 61 nullptr, 62 { 0, } 63 }; 31 64 32 65 int main(int argc, char** argv) … … 37 70 gtk_init(&argc, &argv); 38 71 39 WebKitWebView* webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); 40 webkit_web_view_load_html(webView, 41 "<html>" 42 " <body>" 43 " <h1>This is a test</h1>" 44 " <p>This is a paragraph with some plain text.</p>" 45 " <p>This paragraph contains <a href=\"http://www.webkitgtk.org\">a link</a> in the middle.</p>" 46 " </body>" 47 "</html>", 48 0); 72 GtkWidget* webView = webkit_web_view_new(); 49 73 50 74 GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 75 g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), nullptr); 51 76 gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(webView)); 52 77 gtk_widget_show_all(window); 53 78 54 g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), 0); 55 g_signal_connect(webView, "load-changed", G_CALLBACK(loadChangedCallback), 0); 79 g_bus_own_name(G_BUS_TYPE_SESSION, "org.webkit.gtk.AccessibilityTest", G_BUS_NAME_OWNER_FLAGS_NONE, 80 [](GDBusConnection* connection, const char* name, gpointer userData) { 81 static GDBusNodeInfo *introspectionData = nullptr; 82 if (!introspectionData) 83 introspectionData = g_dbus_node_info_new_for_xml(introspectionXML, nullptr); 84 85 g_dbus_connection_register_object(connection, "/org/webkit/gtk/AccessibilityTest", introspectionData->interfaces[0], 86 &interfaceVirtualTable, userData, nullptr, nullptr); 87 }, nullptr, nullptr, webView, nullptr); 56 88 57 89 gtk_main(); -
trunk/Tools/TestWebKitAPI/Tests/WebKitGtk/TestWebKitAccessibility.cpp
r239772 r244212 1 1 /* 2 * Copyright (C) 2012 Igalia S.L.2 * Copyright (C) 2012, 2019 Igalia S.L. 3 3 * 4 4 * This library is free software; you can redistribute it and/or … … 21 21 22 22 #include "TestMain.h" 23 #include "Web ViewTest.h"23 #include "WebKitTestBus.h" 24 24 25 25 // The libatspi headers don't use G_BEGIN_DECLS … … 28 28 } 29 29 30 #include <errno.h> 31 #include <fcntl.h> 32 #include <glib.h> 33 #include <signal.h> 34 #include <unistd.h> 35 #include <wtf/glib/GRefPtr.h> 36 #include <wtf/glib/GUniquePtr.h> 37 38 // Name of the test server application creating the webView object. 39 static const char* kTestServerAppName = "AccessibilityTestServer"; 40 41 // Max seconds to wait for the test server before inspecting it. 42 static const int kMaxWaitForChild = 5; 43 44 // The PID for the test server running, so we can kill it if needed. 45 static GPid kChildProcessPid = 0; 46 47 // Whether the child has replied and it's ready. 48 static bool kChildIsReady = false; 49 50 static void stopTestServer() 30 static WebKitTestBus* bus; 31 32 class AccessibilityTest : public Test { 33 public: 34 MAKE_GLIB_TEST_FIXTURE(AccessibilityTest); 35 36 AccessibilityTest() 37 { 38 GUniquePtr<char> testServerPath(g_build_filename(WEBKIT_EXEC_PATH, "TestWebKitAPI", "WebKit2Gtk", "AccessibilityTestServer", nullptr)); 39 char* args[2]; 40 args[0] = testServerPath.get(); 41 args[1] = nullptr; 42 43 g_assert_true(g_spawn_async(nullptr, args, nullptr, G_SPAWN_DEFAULT, nullptr, nullptr, &m_childProcessID, nullptr)); 44 } 45 46 ~AccessibilityTest() 47 { 48 if (m_childProcessID) { 49 g_spawn_close_pid(m_childProcessID); 50 kill(m_childProcessID, SIGTERM); 51 } 52 } 53 54 void loadHTMLAndWaitUntilFinished(const char* html, const char* baseURI) 55 { 56 ensureProxy(); 57 58 GUniqueOutPtr<GError> error; 59 GRefPtr<GVariant> result = adoptGRef(g_dbus_proxy_call_sync(m_proxy.get(), "LoadHTML", 60 g_variant_new("(ss)", html, baseURI ? baseURI : ""), G_DBUS_CALL_FLAGS_NONE, -1, nullptr, &error.outPtr())); 61 g_assert_no_error(error.get()); 62 } 63 64 GRefPtr<AtspiAccessible> findTestServerApplication() 65 { 66 // Only one desktop is supported by ATSPI at the moment. 67 GRefPtr<AtspiAccessible> desktop = adoptGRef(atspi_get_desktop(0)); 68 69 int childCount = atspi_accessible_get_child_count(desktop.get(), nullptr); 70 for (int i = 0; i < childCount; ++i) { 71 GRefPtr<AtspiAccessible> current = adoptGRef(atspi_accessible_get_child_at_index(desktop.get(), i, nullptr)); 72 if (!g_strcmp0(atspi_accessible_get_name(current.get(), nullptr), "AccessibilityTestServer")) 73 return current; 74 } 75 76 return 0; 77 } 78 79 GRefPtr<AtspiAccessible> findDocumentWeb(AtspiAccessible* accessible) 80 { 81 int childCount = atspi_accessible_get_child_count(accessible, nullptr); 82 for (int i = 0; i < childCount; ++i) { 83 GRefPtr<AtspiAccessible> child = adoptGRef(atspi_accessible_get_child_at_index(accessible, i, nullptr)); 84 if (atspi_accessible_get_role(child.get(), nullptr) == ATSPI_ROLE_DOCUMENT_WEB) 85 return child; 86 87 if (auto documentWeb = findDocumentWeb(child.get())) 88 return documentWeb; 89 } 90 return nullptr; 91 } 92 93 GRefPtr<AtspiAccessible> findRootObject(AtspiAccessible* application) 94 { 95 // Find the document web, its parent is the scroll view (WebCore root object) and its parent is 96 // the GtkPlug (WebProcess root element). 97 auto documentWeb = findDocumentWeb(application); 98 if (!documentWeb) 99 return nullptr; 100 101 auto parent = adoptGRef(atspi_accessible_get_parent(documentWeb.get(), nullptr)); 102 return parent ? adoptGRef(atspi_accessible_get_parent(parent.get(), nullptr)) : nullptr; 103 } 104 105 void waitUntilChildrenRemoved(AtspiAccessible* accessible) 106 { 107 m_eventSource = accessible; 108 GRefPtr<AtspiEventListener> listener = adoptGRef(atspi_event_listener_new( 109 [](AtspiEvent* event, gpointer userData) { 110 auto* test = static_cast<AccessibilityTest*>(userData); 111 if (event->source == test->m_eventSource) 112 g_main_loop_quit(test->m_mainLoop.get()); 113 }, this, nullptr)); 114 atspi_event_listener_register(listener.get(), "object:children-changed:remove", nullptr); 115 g_main_loop_run(m_mainLoop.get()); 116 m_eventSource = nullptr; 117 } 118 119 private: 120 void ensureProxy() 121 { 122 if (m_proxy) 123 return; 124 125 m_mainLoop = adoptGRef(g_main_loop_new(nullptr, FALSE)); 126 m_proxy = adoptGRef(bus->createProxy("org.webkit.gtk.AccessibilityTest", "/org/webkit/gtk/AccessibilityTest", "org.webkit.gtk.AccessibilityTest", m_mainLoop.get())); 127 } 128 129 GPid m_childProcessID { 0 }; 130 GRefPtr<GDBusProxy> m_proxy; 131 GRefPtr<GMainLoop> m_mainLoop; 132 AtspiAccessible* m_eventSource { nullptr }; 133 }; 134 135 static void testAtspiBasicHierarchy(AccessibilityTest* test, gconstpointer) 51 136 { 52 // Do nothing if there's no server running. 53 if (!kChildProcessPid) 54 return; 55 56 g_spawn_close_pid(kChildProcessPid); 57 kill(kChildProcessPid, SIGTERM); 58 kChildProcessPid = 0; 59 } 60 61 static void sigAbortHandler(int sigNum) 62 { 63 // Just stop the test server if SIGABRT was received. 64 stopTestServer(); 65 } 66 67 static gpointer testServerMonitorThreadFunc(gpointer) 68 { 69 // Wait for the specified timeout to happen. 70 g_usleep(kMaxWaitForChild * G_USEC_PER_SEC); 71 72 // Kill the child process if not ready yet. 73 if (!kChildIsReady) 74 stopTestServer(); 75 76 g_thread_exit(0); 77 return 0; 78 } 79 80 static void startTestServerMonitor() 81 { 82 kChildIsReady = false; 83 g_thread_new("TestServerMonitor", testServerMonitorThreadFunc, 0); 84 } 85 86 static void startTestServer() 87 { 88 // Prepare argv[] for spawning the server process. 89 GUniquePtr<char> testServerPath(g_build_filename(WEBKIT_EXEC_PATH, "TestWebKitAPI", "WebKit2Gtk", kTestServerAppName, nullptr)); 90 91 char* testServerArgv[2]; 92 testServerArgv[0] = testServerPath.get(); 93 testServerArgv[1] = 0; 94 95 // Spawn the server, getting its stdout file descriptor to set a 96 // communication channel, so we know when it's ready. 97 int childStdout = 0; 98 if (!g_spawn_async_with_pipes(0, testServerArgv, 0, static_cast<GSpawnFlags>(0), 0, 0, &kChildProcessPid, 0, &childStdout, 0, 0)) { 99 close(childStdout); 100 return; 101 } 102 103 // Start monitoring the test server (in a separate thread) to 104 // ensure we don't block on the child process more than a timeout. 105 startTestServerMonitor(); 106 107 char msg[2]; 108 GIOChannel* ioChannel = g_io_channel_unix_new(childStdout); 109 if (g_io_channel_read_chars(ioChannel, msg, 2, 0, 0) == G_IO_STATUS_NORMAL) { 110 // Check whether the server sent a message saying it's ready 111 // and store the result globally, so the monitor can see it. 112 kChildIsReady = msg[0] == 'O' && msg[1] == 'K'; 113 } 114 g_io_channel_unref(ioChannel); 115 close(childStdout); 116 117 // The timeout was reached and the server is not ready yet, so 118 // stop it inmediately, and let the unit tests fail. 119 if (!kChildIsReady) 120 stopTestServer(); 121 } 122 123 static void checkAtspiAccessible(AtspiAccessible* accessible, const char* targetName, AtspiRole targetRole) 124 { 125 g_assert_true(ATSPI_IS_ACCESSIBLE(accessible)); 126 127 GUniquePtr<char> name(atspi_accessible_get_name(accessible, 0)); 128 g_assert_cmpstr(targetName, ==, name.get()); 129 g_assert_cmpint(targetRole, ==, atspi_accessible_get_role(accessible, 0)); 130 } 131 132 static GRefPtr<AtspiAccessible> findTestServerApplication() 133 { 134 // Only one desktop is supported by ATSPI at the moment. 135 GRefPtr<AtspiAccessible> desktop = adoptGRef(atspi_get_desktop(0)); 136 137 // Look for the server application in the list of apps. 138 GRefPtr<AtspiAccessible> current; 139 int childCount = atspi_accessible_get_child_count(desktop.get(), 0); 140 for (int i = 0; i < childCount; i++) { 141 current = adoptGRef(atspi_accessible_get_child_at_index(desktop.get(), i, 0)); 142 if (!g_strcmp0(atspi_accessible_get_name(current.get(), 0), kTestServerAppName)) 143 return current; 144 } 145 146 return 0; 147 } 148 149 static void testAtspiBasicHierarchy(WebViewTest* test, gconstpointer) 150 { 151 // The test server's accessibility object (UI Process). 152 GRefPtr<AtspiAccessible> testServerApp = findTestServerApplication(); 137 test->loadHTMLAndWaitUntilFinished( 138 "<html>" 139 " <body>" 140 " <h1>This is a test</h1>" 141 " <p>This is a paragraph with some plain text.</p>" 142 " <p>This paragraph contains <a href=\"http://www.webkitgtk.org\">a link</a> in the middle.</p>" 143 " </body>" 144 "</html>", 145 nullptr); 146 147 auto testServerApp = test->findTestServerApplication(); 153 148 g_assert_true(ATSPI_IS_ACCESSIBLE(testServerApp.get())); 154 checkAtspiAccessible(testServerApp.get(), "AccessibilityTestServer", ATSPI_ROLE_APPLICATION); 155 156 // The main window's accessibility object (UI Process). 157 GRefPtr<AtspiAccessible> currentParent = testServerApp; 158 GRefPtr<AtspiAccessible> currentChild = adoptGRef(atspi_accessible_get_child_at_index(currentParent.get(), 0, 0)); 159 g_assert_true(ATSPI_IS_ACCESSIBLE(currentChild.get())); 160 checkAtspiAccessible(currentChild.get(), "", ATSPI_ROLE_FRAME); 161 162 // The WebView's accessibility object (UI Process). 163 currentParent = currentChild; 164 currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 0, 0); 165 g_assert_true(ATSPI_IS_ACCESSIBLE(currentChild.get())); 166 checkAtspiAccessible(currentChild.get(), "", ATSPI_ROLE_FILLER); 167 168 // The WebPage's accessibility object (Web Process). 169 currentParent = currentChild; 170 currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 0, 0); 171 g_assert_true(ATSPI_IS_ACCESSIBLE(currentChild.get())); 172 checkAtspiAccessible(currentChild.get(), "", ATSPI_ROLE_FILLER); 173 174 // HTML root element's accessible element (Web Process). 175 currentParent = currentChild; 176 currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 0, 0); 177 g_assert_true(ATSPI_IS_ACCESSIBLE(currentChild.get())); 178 179 // HTML body's accessible element (Web Process). 180 currentParent = currentChild; 181 currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 0, 0); 182 g_assert_true(ATSPI_IS_ACCESSIBLE(currentChild.get())); 183 checkAtspiAccessible(currentChild.get(), "", ATSPI_ROLE_DOCUMENT_WEB); 184 185 // HTML H1's accessible element (Web Process). 186 currentParent = currentChild; 187 currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 0, 0); 188 g_assert_true(ATSPI_IS_ACCESSIBLE(currentChild.get())); 189 checkAtspiAccessible(currentChild.get(), "This is a test", ATSPI_ROLE_HEADING); 190 191 // HTML first paragraph's accessible element (Web Process). 192 currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 1, 0); 193 g_assert_true(ATSPI_IS_ACCESSIBLE(currentChild.get())); 194 checkAtspiAccessible(currentChild.get(), "", ATSPI_ROLE_PARAGRAPH); 195 196 // HTML second paragraph's accessible element (Web Process). 197 currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 2, 0); 198 g_assert_true(ATSPI_IS_ACCESSIBLE(currentChild.get())); 199 checkAtspiAccessible(currentChild.get(), "", ATSPI_ROLE_PARAGRAPH); 200 201 // HTML link's accessible element (Web Process). 202 currentParent = currentChild; 203 currentChild = atspi_accessible_get_child_at_index(currentParent.get(), 0, 0); 204 g_assert_true(ATSPI_IS_ACCESSIBLE(currentChild.get())); 205 checkAtspiAccessible(currentChild.get(), "a link", ATSPI_ROLE_LINK); 149 GUniquePtr<char> name(atspi_accessible_get_name(testServerApp.get(), nullptr)); 150 g_assert_cmpstr(name.get(), ==, "AccessibilityTestServer"); 151 g_assert_cmpint(atspi_accessible_get_role(testServerApp.get(), nullptr), ==, ATSPI_ROLE_APPLICATION); 152 153 auto rootObject = test->findRootObject(testServerApp.get()); 154 g_assert_true(ATSPI_IS_ACCESSIBLE(rootObject.get())); 155 g_assert_cmpint(atspi_accessible_get_role(rootObject.get(), nullptr), ==, ATSPI_ROLE_FILLER); 156 157 auto scrollView = adoptGRef(atspi_accessible_get_child_at_index(rootObject.get(), 0, nullptr)); 158 g_assert_true(ATSPI_IS_ACCESSIBLE(scrollView.get())); 159 g_assert_cmpint(atspi_accessible_get_role(scrollView.get(), nullptr), ==, ATSPI_ROLE_SCROLL_PANE); 160 161 auto documentWeb = adoptGRef(atspi_accessible_get_child_at_index(scrollView.get(), 0, nullptr)); 162 g_assert_true(ATSPI_IS_ACCESSIBLE(documentWeb.get())); 163 g_assert_cmpint(atspi_accessible_get_role(documentWeb.get(), nullptr), ==, ATSPI_ROLE_DOCUMENT_WEB); 164 165 auto h1 = adoptGRef(atspi_accessible_get_child_at_index(documentWeb.get(), 0, nullptr)); 166 g_assert_true(ATSPI_IS_ACCESSIBLE(h1.get())); 167 name.reset(atspi_accessible_get_name(h1.get(), nullptr)); 168 g_assert_cmpstr(name.get(), ==, "This is a test"); 169 g_assert_cmpint(atspi_accessible_get_role(h1.get(), nullptr), ==, ATSPI_ROLE_HEADING); 170 171 auto p1 = adoptGRef(atspi_accessible_get_child_at_index(documentWeb.get(), 1, nullptr)); 172 g_assert_true(ATSPI_IS_ACCESSIBLE(p1.get())); 173 g_assert_cmpint(atspi_accessible_get_role(p1.get(), nullptr), ==, ATSPI_ROLE_PARAGRAPH); 174 175 auto p2 = adoptGRef(atspi_accessible_get_child_at_index(documentWeb.get(), 2, nullptr)); 176 g_assert_true(ATSPI_IS_ACCESSIBLE(p2.get())); 177 g_assert_cmpint(atspi_accessible_get_role(p2.get(), nullptr), ==, ATSPI_ROLE_PARAGRAPH); 178 179 auto link = adoptGRef(atspi_accessible_get_child_at_index(p2.get(), 0, nullptr)); 180 g_assert_true(ATSPI_IS_ACCESSIBLE(link.get())); 181 name.reset(atspi_accessible_get_name(link.get(), nullptr)); 182 g_assert_cmpstr(name.get(), ==, "a link"); 183 g_assert_cmpint(atspi_accessible_get_role(link.get(), nullptr), ==, ATSPI_ROLE_LINK); 184 185 test->loadHTMLAndWaitUntilFinished( 186 "<html>" 187 " <body>" 188 " <h1>This is another test</h1>" 189 " <img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AYWDTMVwnSZnwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAFklEQVQI12P8z8DAwMDAxMDAwMDAAAANHQEDK+mmyAAAAABJRU5ErkJggg=='/>" 190 " </body>" 191 "</html>", 192 nullptr); 193 194 // Check that children-changed::remove is emitted on the root object on navigation, 195 // and the a11y hierarchy is updated. 196 test->waitUntilChildrenRemoved(rootObject.get()); 197 198 documentWeb = test->findDocumentWeb(testServerApp.get()); 199 g_assert_true(ATSPI_IS_ACCESSIBLE(documentWeb.get())); 200 g_assert_cmpint(atspi_accessible_get_role(documentWeb.get(), nullptr), ==, ATSPI_ROLE_DOCUMENT_WEB); 201 202 h1 = adoptGRef(atspi_accessible_get_child_at_index(documentWeb.get(), 0, nullptr)); 203 g_assert_true(ATSPI_IS_ACCESSIBLE(h1.get())); 204 name.reset(atspi_accessible_get_name(h1.get(), nullptr)); 205 g_assert_cmpstr(name.get(), ==, "This is another test"); 206 g_assert_cmpint(atspi_accessible_get_role(h1.get(), nullptr), ==, ATSPI_ROLE_HEADING); 207 208 auto section = adoptGRef(atspi_accessible_get_child_at_index(documentWeb.get(), 1, nullptr)); 209 g_assert_true(ATSPI_IS_ACCESSIBLE(section.get())); 210 g_assert_cmpint(atspi_accessible_get_role(section.get(), nullptr), ==, ATSPI_ROLE_SECTION); 211 212 auto img = adoptGRef(atspi_accessible_get_child_at_index(section.get(), 0, nullptr)); 213 g_assert_true(ATSPI_IS_ACCESSIBLE(img.get())); 214 g_assert_cmpint(atspi_accessible_get_role(img.get(), nullptr), ==, ATSPI_ROLE_IMAGE); 206 215 } 207 216 208 217 void beforeAll() 209 218 { 210 // We install a handler to ensure that we kill the child process 211 // if the parent dies because of whatever the reason is. 212 signal(SIGABRT, sigAbortHandler); 213 214 // Start the accessibility test server and load the tests. 215 startTestServer(); 216 WebViewTest::add("WebKitAccessibility", "atspi-basic-hierarchy", testAtspiBasicHierarchy); 219 bus = new WebKitTestBus(); 220 if (!bus->run()) 221 return; 222 223 AccessibilityTest::add("WebKitAccessibility", "atspi-basic-hierarchy", testAtspiBasicHierarchy); 217 224 } 218 225 219 226 void afterAll() 220 227 { 221 // Ensure we stop the server. 222 stopTestServer(); 223 } 228 delete bus; 229 }
Note: See TracChangeset
for help on using the changeset viewer.