OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "ios/web/public/test/earl_grey/web_view_matchers.h" | 5 #import "ios/web/public/test/earl_grey/web_view_matchers.h" |
6 | 6 |
7 #import <WebKit/WebKit.h> | 7 #import <WebKit/WebKit.h> |
8 | 8 |
9 #include "base/mac/bind_objc_block.h" | 9 #include "base/mac/bind_objc_block.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
11 #include "base/strings/sys_string_conversions.h" | 11 #include "base/strings/sys_string_conversions.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "base/test/ios/wait_util.h" | 13 #include "base/test/ios/wait_util.h" |
14 #include "base/values.h" | 14 #include "base/values.h" |
15 #include "ios/testing/earl_grey/wait_util.h" | 15 #include "ios/testing/wait_util.h" |
16 #import "ios/web/public/test/web_view_interaction_test_util.h" | 16 #import "ios/web/public/test/web_view_interaction_test_util.h" |
17 | 17 |
18 using web::test::ExecuteJavaScript; | 18 using web::test::ExecuteJavaScript; |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 // Script that returns document.body as a string. | 22 // Script that returns document.body as a string. |
23 char kGetDocumentBodyJavaScript[] = | 23 char kGetDocumentBodyJavaScript[] = |
24 "document.body ? document.body.textContent : null"; | 24 "document.body ? document.body.textContent : null"; |
25 // Script that tests presence of css selector. | 25 // Script that tests presence of css selector. |
(...skipping 13 matching lines...) Expand all Loading... |
39 [description appendText:@"web view in web state"]; | 39 [description appendText:@"web view in web state"]; |
40 }; | 40 }; |
41 | 41 |
42 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches | 42 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches |
43 descriptionBlock:describe] | 43 descriptionBlock:describe] |
44 autorelease]; | 44 autorelease]; |
45 } | 45 } |
46 | 46 |
47 id<GREYMatcher> webViewContainingText(std::string text, WebState* web_state) { | 47 id<GREYMatcher> webViewContainingText(std::string text, WebState* web_state) { |
48 MatchesBlock matches = ^BOOL(WKWebView*) { | 48 MatchesBlock matches = ^BOOL(WKWebView*) { |
49 __block BOOL did_succeed = NO; | 49 return testing::WaitUntilConditionOrTimeout( |
50 NSDate* deadline = | 50 testing::kWaitForUIElementTimeout, ^{ |
51 [NSDate dateWithTimeIntervalSinceNow:testing::kWaitForUIElementTimeout]; | 51 std::unique_ptr<base::Value> value = |
52 while (([[NSDate date] compare:deadline] != NSOrderedDescending) && | 52 ExecuteJavaScript(web_state, kGetDocumentBodyJavaScript); |
53 !did_succeed) { | 53 std::string body; |
54 std::unique_ptr<base::Value> value = | 54 if (value && value->GetAsString(&body)) { |
55 ExecuteJavaScript(web_state, kGetDocumentBodyJavaScript); | 55 return body.find(text) != std::string::npos; |
56 std::string body; | 56 } |
57 if (value && value->GetAsString(&body)) { | 57 return false; |
58 did_succeed = body.find(text) != std::string::npos; | 58 }); |
59 } | |
60 base::test::ios::SpinRunLoopWithMaxDelay( | |
61 base::TimeDelta::FromSecondsD(testing::kSpinDelaySeconds)); | |
62 } | |
63 return did_succeed; | |
64 }; | 59 }; |
65 | 60 |
66 DescribeToBlock describe = ^(id<GREYDescription> description) { | 61 DescribeToBlock describe = ^(id<GREYDescription> description) { |
67 [description appendText:@"web view containing "]; | 62 [description appendText:@"web view containing "]; |
68 [description appendText:base::SysUTF8ToNSString(text)]; | 63 [description appendText:base::SysUTF8ToNSString(text)]; |
69 }; | 64 }; |
70 | 65 |
71 return grey_allOf(webViewInWebState(web_state), | 66 return grey_allOf(webViewInWebState(web_state), |
72 [[[GREYElementMatcherBlock alloc] | 67 [[[GREYElementMatcherBlock alloc] |
73 initWithMatchesBlock:matches | 68 initWithMatchesBlock:matches |
74 descriptionBlock:describe] autorelease], | 69 descriptionBlock:describe] autorelease], |
75 nil); | 70 nil); |
76 } | 71 } |
77 | 72 |
78 id<GREYMatcher> webViewContainingBlockedImage(std::string image_id, | 73 id<GREYMatcher> webViewContainingBlockedImage(std::string image_id, |
79 CGSize expected_size, | 74 CGSize expected_size, |
80 WebState* web_state) { | 75 WebState* web_state) { |
81 MatchesBlock matches = ^BOOL(WKWebView*) { | 76 MatchesBlock matches = ^BOOL(WKWebView*) { |
82 __block BOOL did_succeed = NO; | 77 return testing::WaitUntilConditionOrTimeout( |
83 NSDate* deadline = | 78 testing::kWaitForUIElementTimeout, ^{ |
84 [NSDate dateWithTimeIntervalSinceNow:testing::kWaitForUIElementTimeout]; | 79 NSString* const kGetElementAttributesScript = [NSString |
85 while (([[NSDate date] compare:deadline] != NSOrderedDescending) && | 80 stringWithFormat:@"var image = document.getElementById('%@');" |
86 !did_succeed) { | 81 @"var imageHeight = image.height;" |
87 NSString* const kGetElementAttributesScript = [NSString | 82 @"var imageWidth = image.width;" |
88 stringWithFormat:@"var image = document.getElementById('%@');" | 83 @"JSON.stringify({" |
89 @"var imageHeight = image.height;" | 84 @" height:imageHeight," |
90 @"var imageWidth = image.width;" | 85 @" width:imageWidth" |
91 @"JSON.stringify({" | 86 @"});", |
92 @" height:imageHeight," | 87 base::SysUTF8ToNSString(image_id)]; |
93 @" width:imageWidth" | 88 std::unique_ptr<base::Value> value = ExecuteJavaScript( |
94 @"});", | 89 web_state, base::SysNSStringToUTF8(kGetElementAttributesScript)); |
95 base::SysUTF8ToNSString(image_id)]; | 90 std::string result; |
96 std::unique_ptr<base::Value> value = ExecuteJavaScript( | 91 if (value && value->GetAsString(&result)) { |
97 web_state, base::SysNSStringToUTF8(kGetElementAttributesScript)); | 92 NSString* evaluation_result = base::SysUTF8ToNSString(result); |
98 std::string result; | 93 NSData* image_attributes_as_data = |
99 if (value && value->GetAsString(&result)) { | 94 [evaluation_result dataUsingEncoding:NSUTF8StringEncoding]; |
100 NSString* evaluation_result = base::SysUTF8ToNSString(result); | 95 NSDictionary* image_attributes = |
101 NSData* image_attributes_as_data = | 96 [NSJSONSerialization JSONObjectWithData:image_attributes_as_data |
102 [evaluation_result dataUsingEncoding:NSUTF8StringEncoding]; | 97 options:0 |
103 NSDictionary* image_attributes = | 98 error:nil]; |
104 [NSJSONSerialization JSONObjectWithData:image_attributes_as_data | 99 CGFloat height = [image_attributes[@"height"] floatValue]; |
105 options:0 | 100 CGFloat width = [image_attributes[@"width"] floatValue]; |
106 error:nil]; | 101 return (height < expected_size.height && |
107 CGFloat height = [image_attributes[@"height"] floatValue]; | 102 width < expected_size.width); |
108 CGFloat width = [image_attributes[@"width"] floatValue]; | 103 } |
109 did_succeed = | 104 return false; |
110 (height < expected_size.height && width < expected_size.width); | 105 }); |
111 } | |
112 base::test::ios::SpinRunLoopWithMaxDelay( | |
113 base::TimeDelta::FromSecondsD(testing::kSpinDelaySeconds)); | |
114 } | |
115 return did_succeed; | |
116 }; | 106 }; |
117 | 107 |
118 DescribeToBlock describe = ^(id<GREYDescription> description) { | 108 DescribeToBlock describe = ^(id<GREYDescription> description) { |
119 [description appendText:@"web view blocking resource with id "]; | 109 [description appendText:@"web view blocking resource with id "]; |
120 [description appendText:base::SysUTF8ToNSString(image_id)]; | 110 [description appendText:base::SysUTF8ToNSString(image_id)]; |
121 }; | 111 }; |
122 | 112 |
123 return grey_allOf(webViewInWebState(web_state), | 113 return grey_allOf(webViewInWebState(web_state), |
124 [[[GREYElementMatcherBlock alloc] | 114 [[[GREYElementMatcherBlock alloc] |
125 initWithMatchesBlock:matches | 115 initWithMatchesBlock:matches |
126 descriptionBlock:describe] autorelease], | 116 descriptionBlock:describe] autorelease], |
127 nil); | 117 nil); |
128 } | 118 } |
129 | 119 |
130 id<GREYMatcher> webViewCssSelector(std::string selector, WebState* web_state) { | 120 id<GREYMatcher> webViewCssSelector(std::string selector, WebState* web_state) { |
131 MatchesBlock matches = ^BOOL(WKWebView*) { | 121 MatchesBlock matches = ^BOOL(WKWebView*) { |
132 std::string script = base::StringPrintf(kTestCssSelectorJavaScriptTemplate, | 122 std::string script = base::StringPrintf(kTestCssSelectorJavaScriptTemplate, |
133 selector.c_str()); | 123 selector.c_str()); |
134 __block bool did_succeed = false; | 124 return testing::WaitUntilConditionOrTimeout( |
135 NSDate* deadline = | 125 testing::kWaitForUIElementTimeout, ^{ |
136 [NSDate dateWithTimeIntervalSinceNow:testing::kWaitForUIElementTimeout]; | 126 bool did_succeed = false; |
137 while (([[NSDate date] compare:deadline] != NSOrderedDescending) && | 127 std::unique_ptr<base::Value> value = |
138 !did_succeed) { | 128 ExecuteJavaScript(web_state, script); |
139 std::unique_ptr<base::Value> value = ExecuteJavaScript(web_state, script); | 129 if (value) { |
140 if (value) | 130 value->GetAsBoolean(&did_succeed); |
141 value->GetAsBoolean(&did_succeed); | 131 } |
142 base::test::ios::SpinRunLoopWithMaxDelay( | 132 return did_succeed; |
143 base::TimeDelta::FromSecondsD(testing::kSpinDelaySeconds)); | 133 }); |
144 } | |
145 return did_succeed; | |
146 }; | 134 }; |
147 | 135 |
148 DescribeToBlock describe = ^(id<GREYDescription> description) { | 136 DescribeToBlock describe = ^(id<GREYDescription> description) { |
149 [description appendText:@"web view selector "]; | 137 [description appendText:@"web view selector "]; |
150 [description appendText:base::SysUTF8ToNSString(selector)]; | 138 [description appendText:base::SysUTF8ToNSString(selector)]; |
151 }; | 139 }; |
152 | 140 |
153 return grey_allOf(webViewInWebState(web_state), | 141 return grey_allOf(webViewInWebState(web_state), |
154 [[[GREYElementMatcherBlock alloc] | 142 [[[GREYElementMatcherBlock alloc] |
155 initWithMatchesBlock:matches | 143 initWithMatchesBlock:matches |
(...skipping 11 matching lines...) Expand all Loading... |
167 DescribeToBlock describe = ^(id<GREYDescription> description) { | 155 DescribeToBlock describe = ^(id<GREYDescription> description) { |
168 [description appendText:@"web view scroll view"]; | 156 [description appendText:@"web view scroll view"]; |
169 }; | 157 }; |
170 | 158 |
171 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches | 159 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches |
172 descriptionBlock:describe] | 160 descriptionBlock:describe] |
173 autorelease]; | 161 autorelease]; |
174 } | 162 } |
175 | 163 |
176 } // namespace web | 164 } // namespace web |
OLD | NEW |