Title: [269635] trunk
Revision
269635
Author
[email protected]
Date
2020-11-10 11:21:32 -0800 (Tue, 10 Nov 2020)

Log Message

Fix for LayoutTests/accessibility/mac/search-predicate.html in isolated tree mode.
https://bugs.webkit.org/show_bug.cgi?id=218732

Reviewed by Chris Fleizach.

Source/WebCore:

Test: accessibility/mac/search-predicate.html.

- Implemented AXIsolatedObject::scrollXXX methods.
- Added handling of "AXIsOnScreen" attribute to WebAccessibilityOobjectWrapperMac.

* accessibility/isolatedtree/AXIsolatedObject.cpp:
(WebCore::AXIsolatedObject::performFunctionOnMainThread const):
(WebCore::AXIsolatedObject::scrollToMakeVisible const):
(WebCore::AXIsolatedObject::scrollToMakeVisibleWithSubFocus const):
(WebCore::AXIsolatedObject::scrollToGlobalPoint const):
(WebCore::AXIsolatedObject::performFunctionOnMainThread): Deleted.
(WebCore::AXIsolatedObject::isVisible const): Deleted.
* accessibility/isolatedtree/AXIsolatedObject.h:
* accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
(-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):

Tools:

Exposed isOnScreen method to JS.

* WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp:
(WTR::AccessibilityUIElement::isOnScreen const):
* WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
* WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
* WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
(WTR::AccessibilityUIElement::isOnScreen const):

LayoutTests:

This test now passes in both isolated tree mode on and off.

* accessibility/mac/search-predicate.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (269634 => 269635)


--- trunk/LayoutTests/ChangeLog	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/LayoutTests/ChangeLog	2020-11-10 19:21:32 UTC (rev 269635)
@@ -1,3 +1,14 @@
+2020-11-10  Andres Gonzalez  <[email protected]>
+
+        Fix for LayoutTests/accessibility/mac/search-predicate.html in isolated tree mode.
+        https://bugs.webkit.org/show_bug.cgi?id=218732
+
+        Reviewed by Chris Fleizach.
+
+        This test now passes in both isolated tree mode on and off.
+
+        * accessibility/mac/search-predicate.html:
+
 2020-11-10  Chris Dumez  <[email protected]>
 
         Crash when accessing OfflineAudioContext.length after failing to construct rendering AudioBuffer

Modified: trunk/LayoutTests/accessibility/mac/search-predicate.html (269634 => 269635)


--- trunk/LayoutTests/accessibility/mac/search-predicate.html	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/LayoutTests/accessibility/mac/search-predicate.html	2020-11-10 19:21:32 UTC (rev 269635)
@@ -2,8 +2,9 @@
 <html>
 <head>
 <script src=""
+<script src=""
 </head>
-<body id="body">
+<body id="body" role="group">
 
 <blockquote>first blockquote level 1</blockquote>
 <blockquote>second blockquote level 1</blockquote>
@@ -59,149 +60,146 @@
 
 <script>
     description("This tests the ability to search for accessible elements by key or text.");
-    
+
     if (window.accessibilityController) {
-        document.getElementById("body").focus();
-        var containerElement = accessibilityController.focusedElement;
-        var startElement;
-        var resultElement;
-        var testButton2;
+        window.jsTestIsAsync = true;
 
+        window.containerElement = accessibilityController.accessibleElementById("body");
         // Any element.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXAnyTypeSearchKey", "", false);
+        window.startElement = containerElement.childAtIndex(0);
+        window.resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXAnyTypeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXStaticText'");
         shouldBe("resultElement.stringValue", "'AXValue: first blockquote level 1'");
 
         // Same level blockquote.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXBlockquoteSameLevelSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: second blockquote level 1'");
 
         // Blockquote.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXBlockquoteSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: second blockquote level 1'");
 
         // Bold font.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXBoldFontSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: sans-serif black bold text with underline'");
         
         // Button.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXButton'");
         
         // Check box.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXCheckBoxSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXCheckBox'");
         
         // Control.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXCheckBoxSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXCheckBox'");
         
         // Different type element.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXDifferentTypeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXStaticText'");
         shouldBe("resultElement.stringValue", "'AXValue: first blockquote level 1'");
         
         // Font change.
-        startElement = accessibilityController.focusedElement.childAtIndex(2);
+        startElement = containerElement.childAtIndex(2);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXFontChangeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: serif blue italic text'");
         
         // Font color change.
-        startElement = accessibilityController.focusedElement.childAtIndex(2);
+        startElement = containerElement.childAtIndex(2);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXFontColorChangeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: serif blue italic text'");
         
         // Graphic.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXGraphicSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXImage'");
         
         // Heading level 1.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel1SearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: first heading level 1'");
         
         // Heading level 2.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel2SearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 2'");
         
         // Heading level 3.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel3SearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 3'");
         
         // Heading level 4.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel4SearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 4'");
         
         // Heading level 5.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel5SearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 5'");
         
         // Heading level 6.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingLevel6SearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 6'");
         
         // Same level heading.
-        startElement = accessibilityController.focusedElement.childAtIndex(6);
+        startElement = containerElement.childAtIndex(6);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingSameLevelSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: second heading level 1'");
         
         // Heading.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXHeadingSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: first heading level 1'");
         
         // Italic font.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXItalicFontSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: serif blue italic text'");
         
         // Landmark.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXLandmarkSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.subrole", "'AXSubrole: AXLandmarkBanner'");
         
         // Link.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXLinkSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXLink'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: link'");
         
         // List.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXListSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXList'");
         
         // Live Region.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXLiveRegionSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.stringAttributeValue('AXARIALive')", "'polite'");
@@ -210,77 +208,77 @@
         // FIXME: Handle this search key.
         
         // Outline.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXOutlineSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXOutline'");
         shouldBe("resultElement.childAtIndex(0).childAtIndex(0).stringValue", "'AXValue: tree item'");
         
         // Plain text.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXPlainTextSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXStaticText'");
         shouldBe("resultElement.stringValue", "'AXValue: first blockquote level 1'");
         
         // Radio group.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXRadioGroupSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXRadioGroup'");
         
         // Same type element.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXSameTypeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: second blockquote level 1'");
         
         // Static text.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXStaticTextSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXStaticText'");
         shouldBe("resultElement.stringValue", "'AXValue: first blockquote level 1'");
         
         // Style change.
-        startElement = accessibilityController.focusedElement.childAtIndex(2);
+        startElement = containerElement.childAtIndex(2);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXStyleChangeSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: serif blue italic text'");
         
         // Same level table.
-        startElement = accessibilityController.focusedElement.childAtIndex(18);
+        startElement = containerElement.childAtIndex(18);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTableSameLevelSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXTable'");
         shouldBe("resultElement.childAtIndex(0).childAtIndex(0).childAtIndex(0).stringValue", "'AXValue: second table heading level 1'");
         
         // Table.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTableSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXTable'");
         shouldBe("resultElement.childAtIndex(0).childAtIndex(0).childAtIndex(0).stringValue", "'AXValue: first table heading level 1'");
         
         // Text field.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXTextFieldSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXTextField'");
         
         // Underline.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXUnderlineSearchKey", "", false);
         shouldBe("resultElement.role", "'AXRole: AXGroup'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: sans-serif black bold text with underline'");
         
         // Unvisited link.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXUnvisitedLinkSearchKey", "", false);
         shouldBe("resultElement.boolAttributeValue('AXVisited')", "false");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: link'");
 
         // Previous text search.
-        startElement = accessibilityController.focusedElement.childAtIndex(10);
+        startElement = containerElement.childAtIndex(10);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, false, "", "sans-serif black bold text with underline", false);
         shouldBe("resultElement.role", "'AXRole: AXStaticText'");
         shouldBe("resultElement.stringValue", "'AXValue: sans-serif black bold text with underline'");
         
         // Execute a search for the next heading level 2 or the next link.
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
+        startElement = containerElement.childAtIndex(0);
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, ["AXHeadingLevel2SearchKey", "AXLinkSearchKey"], "", false);
         shouldBe("resultElement.role", "'AXRole: AXHeading'");
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 2'");
@@ -296,67 +294,75 @@
         shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: heading level 2'");
            
         // Now, we need to test isVisible. Save off the first object
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
-        
+        startElement = containerElement.childAtIndex(0);
+
         // Scroll all the way to the bottom of the content
         resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "", "test button 3", false);
         shouldBe("resultElement.role", "'AXRole: AXButton'");
         shouldBe("resultElement.title", "'AXTitle: test button 3'");
-        resultElement.scrollToMakeVisible();
-        
-        // find the start of the isVisible test section
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "", "isVisible test start", false);
-        shouldBe("resultElement.role", "'AXRole: AXHeading'");
-        shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: isVisible test start'");       
-        
-        // save away the "isVisible test start" heading as the start element
-        startElement = resultElement;
-        
-        // If we don't care about visible only, then we should easily find 3 buttons
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", false);
-        shouldBe("resultElement.role", "'AXRole: AXButton'");
-        shouldBe("resultElement.title", "'AXTitle: test button 1'");
-        
-        resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", false);
-        shouldBe("resultElement.role", "'AXRole: AXButton'");
-        shouldBe("resultElement.title", "'AXTitle: test button 2'");
-        
-        // save away testButton2 so we can make it visible later
-        testButton2 = resultElement;
+        setTimeout(async function() {
+            resultElement.scrollToMakeVisible();
+            await waitFor(() => {
+                return resultElement.isOnScreen;
+            });
 
-        resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", false);
-        shouldBe("resultElement.role", "'AXRole: AXButton'");
-        shouldBe("resultElement.title", "'AXTitle: test button 3'");
+            // find the start of the isVisible test section
+            resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "", "isVisible test start", false);
+            shouldBe("resultElement.role", "'AXRole: AXHeading'");
+            shouldBe("resultElement.childAtIndex(0).stringValue", "'AXValue: isVisible test start'");
 
-        // if we care about visible only, then we should not find "test button 2"
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
-        shouldBe("resultElement.role", "'AXRole: AXButton'");
-        shouldBe("resultElement.title", "'AXTitle: test button 1'");
+            // save away the "isVisible test start" heading as the start element
+            startElement = resultElement;
 
-        resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
-        shouldBe("resultElement.role", "'AXRole: AXButton'");
-        shouldBe("resultElement.title", "'AXTitle: test button 3'");
+            // If we don't care about visible only, then we should easily find 3 buttons
+            resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", false);
+            shouldBe("resultElement.role", "'AXRole: AXButton'");
+            shouldBe("resultElement.title", "'AXTitle: test button 1'");
 
-        // now, scroll to the second button, and confirm that we don't see the first button
-        testButton2.scrollToMakeVisible();
+            resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", false);
+            shouldBe("resultElement.role", "'AXRole: AXButton'");
+            shouldBe("resultElement.title", "'AXTitle: test button 2'");
 
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
-        shouldBe("resultElement.role", "'AXRole: AXButton'");
-        shouldBe("resultElement.title", "'AXTitle: test button 2'");
+            // save away testButton2 so we can make it visible later
+            window.testButton2 = resultElement;
 
-        resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
-        shouldBe("resultElement.role", "'AXRole: AXButton'");
-        shouldBe("resultElement.title", "'AXTitle: test button 3'");
+            resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", false);
+            shouldBe("resultElement.role", "'AXRole: AXButton'");
+            shouldBe("resultElement.title", "'AXTitle: test button 3'");
 
-        // Now since the page is scrolled to the bottom, the first visible button should be #2
-        startElement = accessibilityController.focusedElement.childAtIndex(0);
-        resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
-        shouldBe("resultElement.role", "'AXRole: AXButton'");
-        shouldBe("resultElement.title", "'AXTitle: test button 2'");
+            // if we care about visible only, then we should not find "test button 2"
+            resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
+            shouldBe("resultElement.role", "'AXRole: AXButton'");
+            shouldBe("resultElement.title", "'AXTitle: test button 1'");
+
+            resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
+            shouldBe("resultElement.role", "'AXRole: AXButton'");
+            shouldBe("resultElement.title", "'AXTitle: test button 3'");
+
+            // now, scroll to the second button, and confirm that we don't see the first button
+            testButton2.scrollToMakeVisible();
+            await waitFor(() => {
+                return testButton2.isOnScreen;
+            });
+
+            resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
+            shouldBe("resultElement.role", "'AXRole: AXButton'");
+            shouldBe("resultElement.title", "'AXTitle: test button 2'");
+
+            resultElement = containerElement.uiElementForSearchPredicate(resultElement, true, "AXButtonSearchKey", "", true);
+            shouldBe("resultElement.role", "'AXRole: AXButton'");
+            shouldBe("resultElement.title", "'AXTitle: test button 3'");
+
+            // Now since the page is scrolled to the bottom, the first visible button should be #2
+            startElement = containerElement.childAtIndex(0);
+            resultElement = containerElement.uiElementForSearchPredicate(startElement, true, "AXButtonSearchKey", "", true);
+            shouldBe("resultElement.role", "'AXRole: AXButton'");
+            shouldBe("resultElement.title", "'AXTitle: test button 2'");
+
+            finishJSTest();
+        }, 0);
     }
-    
 </script>
-
 <script src=""
 </body>
 </html>

Modified: trunk/Source/WebCore/ChangeLog (269634 => 269635)


--- trunk/Source/WebCore/ChangeLog	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/Source/WebCore/ChangeLog	2020-11-10 19:21:32 UTC (rev 269635)
@@ -1,3 +1,26 @@
+2020-11-10  Andres Gonzalez  <[email protected]>
+
+        Fix for LayoutTests/accessibility/mac/search-predicate.html in isolated tree mode.
+        https://bugs.webkit.org/show_bug.cgi?id=218732
+
+        Reviewed by Chris Fleizach.
+
+        Test: accessibility/mac/search-predicate.html.
+
+        - Implemented AXIsolatedObject::scrollXXX methods.
+        - Added handling of "AXIsOnScreen" attribute to WebAccessibilityOobjectWrapperMac.
+
+        * accessibility/isolatedtree/AXIsolatedObject.cpp:
+        (WebCore::AXIsolatedObject::performFunctionOnMainThread const):
+        (WebCore::AXIsolatedObject::scrollToMakeVisible const):
+        (WebCore::AXIsolatedObject::scrollToMakeVisibleWithSubFocus const):
+        (WebCore::AXIsolatedObject::scrollToGlobalPoint const):
+        (WebCore::AXIsolatedObject::performFunctionOnMainThread): Deleted.
+        (WebCore::AXIsolatedObject::isVisible const): Deleted.
+        * accessibility/isolatedtree/AXIsolatedObject.h:
+        * accessibility/mac/WebAccessibilityObjectWrapperMac.mm:
+        (-[WebAccessibilityObjectWrapper accessibilityAttributeValue:]):
+
 2020-11-10  Chris Dumez  <[email protected]>
 
         Crash when accessing OfflineAudioContext.length after failing to construct rendering AudioBuffer

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp (269634 => 269635)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.cpp	2020-11-10 19:21:32 UTC (rev 269635)
@@ -622,7 +622,7 @@
 }
 
 template<typename U>
-void AXIsolatedObject::performFunctionOnMainThread(U&& lambda)
+void AXIsolatedObject::performFunctionOnMainThread(U&& lambda) const
 {
     Accessibility::performFunctionOnMainThread([&lambda, this] () {
         if (auto* object = associatedAXObject())
@@ -653,6 +653,27 @@
     });
 }
 
+void AXIsolatedObject::scrollToMakeVisible() const
+{
+    performFunctionOnMainThread([] (AXCoreObject* axObject) {
+        axObject->scrollToMakeVisible();
+    });
+}
+
+void AXIsolatedObject::scrollToMakeVisibleWithSubFocus(const IntRect& rect) const
+{
+    performFunctionOnMainThread([&rect] (AXCoreObject* axObject) {
+        axObject->scrollToMakeVisibleWithSubFocus(rect);
+    });
+}
+
+void AXIsolatedObject::scrollToGlobalPoint(const IntPoint& point) const
+{
+    performFunctionOnMainThread([&point] (AXCoreObject* axObject) {
+        axObject->scrollToGlobalPoint(point);
+    });
+}
+
 bool AXIsolatedObject::setValue(float value)
 {
     return Accessibility::retrieveValueFromMainThread<bool>([&value, this] () -> bool {
@@ -1273,12 +1294,6 @@
     return false;
 }
 
-bool AXIsolatedObject::isVisible() const
-{
-    ASSERT_NOT_REACHED();
-    return false;
-}
-
 bool AXIsolatedObject::isCollapsed() const
 {
     ASSERT_NOT_REACHED();

Modified: trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h (269634 => 269635)


--- trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/Source/WebCore/accessibility/isolatedtree/AXIsolatedObject.h	2020-11-10 19:21:32 UTC (rev 269635)
@@ -113,7 +113,7 @@
     void fillChildrenVectorForProperty(AXPropertyName, AccessibilityChildrenVector&) const;
     void setMathscripts(AXPropertyName, AXCoreObject&);
     void insertMathPairs(Vector<std::pair<AXID, AXID>>&, AccessibilityMathMultiscriptPairs&);
-    template<typename U> void performFunctionOnMainThread(U&&);
+    template<typename U> void performFunctionOnMainThread(U&&) const;
 
     // Attribute retrieval overrides.
     bool isHeading() const override { return boolAttributeValue(AXPropertyName::IsHeading); }
@@ -455,9 +455,9 @@
     void increment() override;
     void decrement() override;
     bool performDismissAction() override;
-    void scrollToMakeVisible() const override { }
-    void scrollToMakeVisibleWithSubFocus(const IntRect&) const override { }
-    void scrollToGlobalPoint(const IntPoint&) const override { }
+    void scrollToMakeVisible() const override;
+    void scrollToMakeVisibleWithSubFocus(const IntRect&) const override;
+    void scrollToGlobalPoint(const IntPoint&) const override;
     bool replaceTextInRange(const String&, const PlainTextRange&) override;
     bool insertText(const String&) override;
     void makeRangeVisible(const PlainTextRange&) override { }
@@ -503,7 +503,7 @@
     bool isPressed() const override;
     bool isUnvisited() const override { return boolAttributeValue(AXPropertyName::IsUnvisited); }
     bool isLinked() const override;
-    bool isVisible() const override;
+    bool isVisible() const override { return boolAttributeValue(AXPropertyName::IsVisible); }
     bool isCollapsed() const override;
     bool isSelectedOptionActive() const override;
     bool hasBoldFont() const override { return boolAttributeValue(AXPropertyName::HasBoldFont); }

Modified: trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm (269634 => 269635)


--- trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/Source/WebCore/accessibility/mac/WebAccessibilityObjectWrapperMac.mm	2020-11-10 19:21:32 UTC (rev 269635)
@@ -3100,6 +3100,9 @@
         return object ? object->wrapper() : nil;
     }
 
+    if ([attributeName isEqualToString:@"AXIsOnScreen"])
+        return [NSNumber numberWithBool:backingObject->isOnScreen()];
+
     return nil;
 }
 

Modified: trunk/Tools/ChangeLog (269634 => 269635)


--- trunk/Tools/ChangeLog	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/Tools/ChangeLog	2020-11-10 19:21:32 UTC (rev 269635)
@@ -1,3 +1,19 @@
+2020-11-10  Andres Gonzalez  <[email protected]>
+
+        Fix for LayoutTests/accessibility/mac/search-predicate.html in isolated tree mode.
+        https://bugs.webkit.org/show_bug.cgi?id=218732
+
+        Reviewed by Chris Fleizach.
+
+        Exposed isOnScreen method to JS.
+
+        * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp:
+        (WTR::AccessibilityUIElement::isOnScreen const):
+        * WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h:
+        * WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl:
+        * WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm:
+        (WTR::AccessibilityUIElement::isOnScreen const):
+
 2020-11-10  Aakash Jain  <[email protected]>
 
         [build.webkit.org] Only upload to S3 when running on production server

Modified: trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp (269634 => 269635)


--- trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/Tools/DumpRenderTree/AccessibilityUIElement.cpp	2020-11-10 19:21:32 UTC (rev 269635)
@@ -1381,6 +1381,11 @@
     return JSValueMakeBoolean(context, toAXElement(thisObject)->isVisible());
 }
 
+static JSValueRef getIsOnScreenCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
+{
+    return JSValueMakeBoolean(context, toAXElement(thisObject)->isOnScreen());
+}
+
 static JSValueRef getIsOffScreenCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef, JSValueRef*)
 {
     return JSValueMakeBoolean(context, toAXElement(thisObject)->isOffScreen());
@@ -1637,6 +1642,7 @@
 
 #if !PLATFORM(MAC)
 void AccessibilityUIElement::setBoolAttributeValue(JSStringRef, bool) { }
+bool AccessibilityUIElement::isOnScreen() const { return true; }
 #endif
 
 #if !SUPPORTS_AX_TEXTMARKERS
@@ -1891,6 +1897,7 @@
         { "isChecked", getIsCheckedCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "isIndeterminate", getIsIndeterminate, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "isVisible", getIsVisibleCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "isOnScreen", getIsOnScreenCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "isOffScreen", getIsOffScreenCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "isCollapsed", getIsCollapsedCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "hasPopup", getHasPopupCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },

Modified: trunk/Tools/DumpRenderTree/AccessibilityUIElement.h (269634 => 269635)


--- trunk/Tools/DumpRenderTree/AccessibilityUIElement.h	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/Tools/DumpRenderTree/AccessibilityUIElement.h	2020-11-10 19:21:32 UTC (rev 269635)
@@ -153,6 +153,7 @@
     bool isExpanded() const;
     bool isChecked() const;
     bool isVisible() const;
+    bool isOnScreen() const;
     bool isOffScreen() const;
     bool isCollapsed() const;
     bool isIgnored() const;

Modified: trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm (269634 => 269635)


--- trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/Tools/DumpRenderTree/mac/AccessibilityUIElementMac.mm	2020-11-10 19:21:32 UTC (rev 269635)
@@ -1540,6 +1540,17 @@
     return false;
 }
 
+bool AccessibilityUIElement::isOnScreen() const
+{
+    BEGIN_AX_OBJC_EXCEPTIONS
+    id value = [m_element accessibilityAttributeValue:@"AXIsOnScreen"];
+    if ([value isKindOfClass:[NSNumber class]])
+        return [value boolValue];
+    END_AX_OBJC_EXCEPTIONS
+
+    return false;
+}
+
 bool AccessibilityUIElement::isOffScreen() const
 {
     // FIXME: implement

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp (269634 => 269635)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.cpp	2020-11-10 19:21:32 UTC (rev 269635)
@@ -104,6 +104,7 @@
 void AccessibilityUIElement::setBoolAttributeValue(JSStringRef, bool) { }
 void AccessibilityUIElement::setValue(JSStringRef) { }
 JSValueRef AccessibilityUIElement::searchTextWithCriteria(JSContextRef, JSValueRef, JSStringRef, JSStringRef) { return nullptr; }
+bool AccessibilityUIElement::isOnScreen() const { return true; }
 #endif
 
 #if !PLATFORM(COCOA) || !HAVE(ACCESSIBILITY)

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h (269634 => 269635)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/AccessibilityUIElement.h	2020-11-10 19:21:32 UTC (rev 269635)
@@ -175,6 +175,7 @@
     bool isChecked() const;
     bool isIndeterminate() const;
     bool isVisible() const;
+    bool isOnScreen() const;
     bool isOffScreen() const;
     bool isCollapsed() const;
     bool isIgnored() const;

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl (269634 => 269635)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/AccessibilityUIElement.idl	2020-11-10 19:21:32 UTC (rev 269635)
@@ -99,6 +99,7 @@
     readonly attribute boolean isIgnored;
     readonly attribute boolean isSingleLine;
     readonly attribute boolean isMultiLine;
+    readonly attribute boolean isOnScreen;
     readonly attribute boolean isOffScreen;
     readonly attribute boolean isValid;
     readonly attribute long hierarchicalLevel;

Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm (269634 => 269635)


--- trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm	2020-11-10 19:20:21 UTC (rev 269634)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/mac/AccessibilityUIElementMac.mm	2020-11-10 19:21:32 UTC (rev 269635)
@@ -1613,6 +1613,14 @@
     return false;
 }
 
+bool AccessibilityUIElement::isOnScreen() const
+{
+    id value = attributeValue(m_element.get(), @"AXIsOnScreen");
+    if ([value isKindOfClass:[NSNumber class]])
+        return [value boolValue];
+    return false;
+}
+
 bool AccessibilityUIElement::isOffScreen() const
 {
     return false;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to