8e4f3223b01ee8a0b8edb9578c76e49bed47a610
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / ios / AccessibilityTestsIOS.mm
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #if PLATFORM(IOS_FAMILY)
29
30 #import "PlatformUtilities.h"
31 #import "TestWKWebView.h"
32 #import <WebKit/WKWebViewPrivate.h>
33
34 @implementation WKWebView (WKAccessibilityTesting)
35 - (NSArray<NSValue *> *)rectsAtSelectionOffset:(NSInteger)offset withText:(NSString *)text
36 {
37     __block RetainPtr<NSArray> selectionRects;
38     __block bool done = false;
39     [self _accessibilityRetrieveRectsAtSelectionOffset:offset withText:text completionHandler:^(NSArray<NSValue *> *rects) {
40         selectionRects = rects;
41         done = true;
42     }];
43     TestWebKitAPI::Util::run(&done);
44     return selectionRects.autorelease();
45 }
46 @end
47
48 static void checkCGRectValueAtIndex(NSArray<NSValue *> *rectValues, CGRect expectedRect, NSUInteger index)
49 {
50     EXPECT_LT(index, rectValues.count);
51     auto observedRect = [rectValues[index] CGRectValue];
52     EXPECT_EQ(expectedRect.origin.x, observedRect.origin.x);
53     EXPECT_EQ(expectedRect.origin.y, observedRect.origin.y);
54     EXPECT_EQ(expectedRect.size.width, observedRect.size.width);
55     EXPECT_EQ(expectedRect.size.height, observedRect.size.height);
56 }
57
58 namespace TestWebKitAPI {
59
60 TEST(AccessibilityTests, RectsForSpeakingSelectionBasic)
61 {
62     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
63     [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width,initial-scale=1'><span id='first'>first</span><span id='second'> second</span><br><span id='third'> third</span>"];
64     [webView stringByEvaluatingJavaScript:@"document.execCommand('SelectAll')"];
65
66     checkCGRectValueAtIndex([webView rectsAtSelectionOffset:0 withText:@"first"], CGRectMake(8, 8, 26, 19), 0);
67     checkCGRectValueAtIndex([webView rectsAtSelectionOffset:6 withText:@"second"], CGRectMake(37, 8, 46, 19), 0);
68     checkCGRectValueAtIndex([webView rectsAtSelectionOffset:13 withText:@"third"], CGRectMake(8, 27, 31, 20), 0);
69 }
70
71 TEST(AccessibilityTests, RectsForSpeakingSelectionWithLineWrapping)
72 {
73     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
74     [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width,initial-scale=1'><body style='font-size: 100px; word-wrap: break-word'><span id='text'>abcdefghijklmnopqrstuvwxyz</span></body>"];
75     [webView stringByEvaluatingJavaScript:@"document.execCommand('SelectAll')"];
76
77     NSArray<NSValue *> *rects = [webView rectsAtSelectionOffset:0 withText:@"abcdefghijklmnopqrstuvwxyz"];
78     checkCGRectValueAtIndex(rects, CGRectMake(8, 8, 304, 114), 0);
79     checkCGRectValueAtIndex(rects, CGRectMake(8, 122, 304, 117), 1);
80     checkCGRectValueAtIndex(rects, CGRectMake(8, 239, 304, 117), 2);
81     checkCGRectValueAtIndex(rects, CGRectMake(8, 356, 304, 117), 3);
82     checkCGRectValueAtIndex(rects, CGRectMake(8, 473, 145, 117), 4);
83 }
84
85 TEST(AccessibilityTests, RectsForSpeakingSelectionDoNotCrashWhenChangingSelection)
86 {
87     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
88     [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width,initial-scale=1'><span id='first'>first</span><span id='second'> second</span><br><span id='third'> third</span>"];
89
90     [webView stringByEvaluatingJavaScript:@"getSelection().setBaseAndExtent(third, 0, third, 1)"];
91     EXPECT_EQ(0UL, [webView rectsAtSelectionOffset:13 withText:@"third"].count);
92     EXPECT_WK_STREQ("third", [webView stringByEvaluatingJavaScript:@"getSelection().toString()"]);
93
94     [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
95     EXPECT_EQ(0UL, [webView rectsAtSelectionOffset:13 withText:@"third"].count);
96     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"getSelection().toString()"]);
97 }
98
99 TEST(AccessibilityTests, StoreSelection)
100 {
101     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
102     [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width,initial-scale=1'><span id='first'>first</span><br><span id='second'>first</span>"];
103     
104     // Select first node and store the selection
105     [webView stringByEvaluatingJavaScript:@"getSelection().setBaseAndExtent(first, 0, first, 1)"];
106     [webView _accessibilityStoreSelection];
107     checkCGRectValueAtIndex([webView rectsAtSelectionOffset:0 withText:@"first"], CGRectMake(8, 8, 26, 19), 0);
108     // Now select the second node, we should use the stored selection to retrieve rects
109     [webView stringByEvaluatingJavaScript:@"getSelection().setBaseAndExtent(second, 0, second, 1)"];
110     checkCGRectValueAtIndex([webView rectsAtSelectionOffset:0 withText:@"first"], CGRectMake(8, 8, 26, 19), 0);
111     
112     // Clear the stored selection, we should use the current selection to retrieve rects
113     [webView _accessibilityClearSelection];
114     checkCGRectValueAtIndex([webView rectsAtSelectionOffset:0 withText:@"first"], CGRectMake(8, 27, 26, 20), 0);
115 }
116
117 } // namespace TestWebKitAPI
118
119 #endif // PLATFORM(IOS_FAMILY)
120