Source/WebKit:
[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 "AccessibilityTestSupportProtocol.h"
31 #import "PlatformUtilities.h"
32 #import "TestWKWebView.h"
33 #import "WKWebViewConfigurationExtras.h"
34 #import <WebKit/WKWebViewPrivate.h>
35 #import <WebKit/_WKRemoteObjectInterface.h>
36 #import <WebKit/_WKRemoteObjectRegistry.h>
37
38 @implementation WKWebView (WKAccessibilityTesting)
39 - (NSArray<NSValue *> *)rectsAtSelectionOffset:(NSInteger)offset withText:(NSString *)text
40 {
41     __block RetainPtr<NSArray> selectionRects;
42     __block bool done = false;
43     [self _accessibilityRetrieveRectsAtSelectionOffset:offset withText:text completionHandler:^(NSArray<NSValue *> *rects) {
44         selectionRects = rects;
45         done = true;
46     }];
47     TestWebKitAPI::Util::run(&done);
48     return selectionRects.autorelease();
49 }
50 @end
51
52 static void checkCGRectValueAtIndex(NSArray<NSValue *> *rectValues, CGRect expectedRect, NSUInteger index)
53 {
54     EXPECT_LT(index, rectValues.count);
55     auto observedRect = [rectValues[index] CGRectValue];
56     EXPECT_EQ(expectedRect.origin.x, observedRect.origin.x);
57     EXPECT_EQ(expectedRect.origin.y, observedRect.origin.y);
58     EXPECT_EQ(expectedRect.size.width, observedRect.size.width);
59     EXPECT_EQ(expectedRect.size.height, observedRect.size.height);
60 }
61
62 namespace TestWebKitAPI {
63
64 TEST(AccessibilityTests, RectsForSpeakingSelectionBasic)
65 {
66     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
67     [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>"];
68     [webView stringByEvaluatingJavaScript:@"document.execCommand('SelectAll')"];
69
70     checkCGRectValueAtIndex([webView rectsAtSelectionOffset:0 withText:@"first"], CGRectMake(8, 8, 26, 19), 0);
71     checkCGRectValueAtIndex([webView rectsAtSelectionOffset:6 withText:@"second"], CGRectMake(37, 8, 46, 19), 0);
72     checkCGRectValueAtIndex([webView rectsAtSelectionOffset:13 withText:@"third"], CGRectMake(8, 27, 31, 20), 0);
73 }
74
75 TEST(AccessibilityTests, RectsForSpeakingSelectionWithLineWrapping)
76 {
77     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
78     [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>"];
79     [webView stringByEvaluatingJavaScript:@"document.execCommand('SelectAll')"];
80
81     NSArray<NSValue *> *rects = [webView rectsAtSelectionOffset:0 withText:@"abcdefghijklmnopqrstuvwxyz"];
82     checkCGRectValueAtIndex(rects, CGRectMake(8, 8, 304, 114), 0);
83     checkCGRectValueAtIndex(rects, CGRectMake(8, 122, 304, 117), 1);
84     checkCGRectValueAtIndex(rects, CGRectMake(8, 239, 304, 117), 2);
85     checkCGRectValueAtIndex(rects, CGRectMake(8, 356, 304, 117), 3);
86     checkCGRectValueAtIndex(rects, CGRectMake(8, 473, 145, 117), 4);
87 }
88
89 TEST(AccessibilityTests, RectsForSpeakingSelectionDoNotCrashWhenChangingSelection)
90 {
91     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
92     [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>"];
93
94     [webView stringByEvaluatingJavaScript:@"getSelection().setBaseAndExtent(third, 0, third, 1)"];
95     EXPECT_EQ(0UL, [webView rectsAtSelectionOffset:13 withText:@"third"].count);
96     EXPECT_WK_STREQ("third", [webView stringByEvaluatingJavaScript:@"getSelection().toString()"]);
97
98     [webView stringByEvaluatingJavaScript:@"getSelection().removeAllRanges()"];
99     EXPECT_EQ(0UL, [webView rectsAtSelectionOffset:13 withText:@"third"].count);
100     EXPECT_WK_STREQ("", [webView stringByEvaluatingJavaScript:@"getSelection().toString()"]);
101 }
102
103 TEST(AccessibilityTests, StoreSelection)
104 {
105     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]);
106     [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width,initial-scale=1'><span id='first'>first</span><br><span id='second'>first</span>"];
107     
108     // Select first node and store the selection
109     [webView stringByEvaluatingJavaScript:@"getSelection().setBaseAndExtent(first, 0, first, 1)"];
110     [webView _accessibilityStoreSelection];
111     checkCGRectValueAtIndex([webView rectsAtSelectionOffset:0 withText:@"first"], CGRectMake(8, 8, 26, 19), 0);
112     // Now select the second node, we should use the stored selection to retrieve rects
113     [webView stringByEvaluatingJavaScript:@"getSelection().setBaseAndExtent(second, 0, second, 1)"];
114     checkCGRectValueAtIndex([webView rectsAtSelectionOffset:0 withText:@"first"], CGRectMake(8, 8, 26, 19), 0);
115     
116     // Clear the stored selection, we should use the current selection to retrieve rects
117     [webView _accessibilityClearSelection];
118     checkCGRectValueAtIndex([webView rectsAtSelectionOffset:0 withText:@"first"], CGRectMake(8, 27, 26, 20), 0);
119 }
120
121 TEST(AccessibilityTests, WebProcessLoaderBundleLoaded)
122 {
123     WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"AccessibilityTestPlugin"];
124     auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500) configuration:configuration]);
125     _WKRemoteObjectInterface *interface = [_WKRemoteObjectInterface remoteObjectInterfaceWithProtocol:@protocol(AccessibilityTestSupportProtocol)];
126     id <AccessibilityTestSupportProtocol> remoteObjectProxy = [[webView _remoteObjectRegistry] remoteObjectProxyWithInterface:interface];
127
128     [webView synchronouslyLoadHTMLString:@"<meta name='viewport' content='width=device-width,initial-scale=1'><span id='first'>first</span><br><span id='second'>first</span>"];
129
130     __block bool isDone = false;
131     [remoteObjectProxy checkAccessibilityWebProcessLoaderBundleIsLoaded:^(BOOL bundleLoaded, NSString *loadedPath) {
132 #if PLATFORM(IOS_FAMILY)
133         EXPECT_TRUE(bundleLoaded);
134 #if PLATFORM(MACCATALYST)
135         EXPECT_TRUE([loadedPath hasSuffix:@"/System/iOSSupport/System/Library/AccessibilityBundles/WebProcessLoader.axbundle"]);
136 #else
137         EXPECT_TRUE([loadedPath hasSuffix:@"/System/Library/AccessibilityBundles/WebProcessLoader.axbundle"]);
138         EXPECT_FALSE([loadedPath hasSuffix:@"/System/iOSSupport/System/Library/AccessibilityBundles/WebProcessLoader.axbundle"]);
139 #endif
140 #elif PLATFORM(MAC)
141         EXPECT_FALSE(bundleLoaded);
142 #endif // PLATFORM(IOS_FAMILY)
143         isDone = true;
144     }];
145     TestWebKitAPI::Util::run(&isDone);
146 }
147
148 } // namespace TestWebKitAPI
149
150 #endif // PLATFORM(IOS_FAMILY)
151