| 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 <UIKit/UIKit.h> | 7 #import <UIKit/UIKit.h> |
| 8 #import <WebKit/WebKit.h> | 8 #import <WebKit/WebKit.h> |
| 9 | 9 |
| 10 #import "base/mac/bind_objc_block.h" | 10 #import "base/mac/bind_objc_block.h" |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 bool image_loaded = WaitUntilConditionOrTimeout(kWaitForDownloadTimeout, ^{ | 86 bool image_loaded = WaitUntilConditionOrTimeout(kWaitForDownloadTimeout, ^{ |
| 87 return image || error; | 87 return image || error; |
| 88 }); | 88 }); |
| 89 GREYAssert(image_loaded, @"Failed to download image"); | 89 GREYAssert(image_loaded, @"Failed to download image"); |
| 90 | 90 |
| 91 return [[image retain] autorelease]; | 91 return [[image retain] autorelease]; |
| 92 } | 92 } |
| 93 | 93 |
| 94 // Helper function for matching web views containing or not containing |text|, | 94 // Helper function for matching web views containing or not containing |text|, |
| 95 // depending on the value of |should_contain_text|. | 95 // depending on the value of |should_contain_text|. |
| 96 id<GREYMatcher> webViewWithText(std::string text, | 96 id<GREYMatcher> WebViewWithText(std::string text, |
| 97 web::WebState* web_state, | 97 web::WebState* web_state, |
| 98 bool should_contain_text) { | 98 bool should_contain_text) { |
| 99 MatchesBlock matches = ^BOOL(WKWebView*) { | 99 MatchesBlock matches = ^BOOL(WKWebView*) { |
| 100 return WaitUntilConditionOrTimeout(testing::kWaitForUIElementTimeout, ^{ | 100 return WaitUntilConditionOrTimeout(testing::kWaitForUIElementTimeout, ^{ |
| 101 std::unique_ptr<base::Value> value = | 101 std::unique_ptr<base::Value> value = |
| 102 web::test::ExecuteJavaScript(web_state, kGetDocumentBodyJavaScript); | 102 web::test::ExecuteJavaScript(web_state, kGetDocumentBodyJavaScript); |
| 103 std::string body; | 103 std::string body; |
| 104 if (value && value->GetAsString(&body)) { | 104 if (value && value->GetAsString(&body)) { |
| 105 BOOL contains_text = body.find(text) != std::string::npos; | 105 BOOL contains_text = body.find(text) != std::string::npos; |
| 106 return contains_text == should_contain_text; | 106 return contains_text == should_contain_text; |
| 107 } | 107 } |
| 108 return false; | 108 return false; |
| 109 }); | 109 }); |
| 110 }; | 110 }; |
| 111 | 111 |
| 112 DescribeToBlock describe = ^(id<GREYDescription> description) { | 112 DescribeToBlock describe = ^(id<GREYDescription> description) { |
| 113 [description appendText:should_contain_text ? @"web view containing " | 113 [description appendText:should_contain_text ? @"web view containing " |
| 114 : @"web view not containing "]; | 114 : @"web view not containing "]; |
| 115 [description appendText:base::SysUTF8ToNSString(text)]; | 115 [description appendText:base::SysUTF8ToNSString(text)]; |
| 116 }; | 116 }; |
| 117 | 117 |
| 118 return grey_allOf(webViewInWebState(web_state), | 118 return grey_allOf(WebViewInWebState(web_state), |
| 119 [[[GREYElementMatcherBlock alloc] | 119 [[[GREYElementMatcherBlock alloc] |
| 120 initWithMatchesBlock:matches | 120 initWithMatchesBlock:matches |
| 121 descriptionBlock:describe] autorelease], | 121 descriptionBlock:describe] autorelease], |
| 122 nil); | 122 nil); |
| 123 } | 123 } |
| 124 | 124 |
| 125 // Matcher for WKWebView containing loaded or blocked image with |image_id|. | 125 // Matcher for WKWebView containing loaded or blocked image with |image_id|. |
| 126 // Pass IMAGE_STATE_LOADED |image_state| to match fully loaded image and | 126 // Pass IMAGE_STATE_LOADED |image_state| to match fully loaded image and |
| 127 // IMAGE_STATE_BLOCKED to match fully blocked image. | 127 // IMAGE_STATE_BLOCKED to match fully blocked image. |
| 128 id<GREYMatcher> webViewContainingImage(std::string image_id, | 128 id<GREYMatcher> WebViewContainingImage(std::string image_id, |
| 129 web::WebState* web_state, | 129 web::WebState* web_state, |
| 130 ImageState image_state) { | 130 ImageState image_state) { |
| 131 std::string get_url_script = | 131 std::string get_url_script = |
| 132 base::StringPrintf("document.getElementById('%s').src", image_id.c_str()); | 132 base::StringPrintf("document.getElementById('%s').src", image_id.c_str()); |
| 133 std::unique_ptr<base::Value> url_as_value = | 133 std::unique_ptr<base::Value> url_as_value = |
| 134 web::test::ExecuteJavaScript(web_state, get_url_script); | 134 web::test::ExecuteJavaScript(web_state, get_url_script); |
| 135 std::string url_as_string; | 135 std::string url_as_string; |
| 136 if (!url_as_value->GetAsString(&url_as_string)) | 136 if (!url_as_value->GetAsString(&url_as_string)) |
| 137 return grey_nil(); | 137 return grey_nil(); |
| 138 | 138 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 [description appendText:@"web view blocked resource with id "]; | 184 [description appendText:@"web view blocked resource with id "]; |
| 185 break; | 185 break; |
| 186 case IMAGE_STATE_LOADED: | 186 case IMAGE_STATE_LOADED: |
| 187 [description appendText:@"web view loaded resource with id "]; | 187 [description appendText:@"web view loaded resource with id "]; |
| 188 break; | 188 break; |
| 189 } | 189 } |
| 190 | 190 |
| 191 [description appendText:base::SysUTF8ToNSString(image_id)]; | 191 [description appendText:base::SysUTF8ToNSString(image_id)]; |
| 192 }; | 192 }; |
| 193 | 193 |
| 194 return grey_allOf(webViewInWebState(web_state), | 194 return grey_allOf(WebViewInWebState(web_state), |
| 195 [[[GREYElementMatcherBlock alloc] | 195 [[[GREYElementMatcherBlock alloc] |
| 196 initWithMatchesBlock:matches | 196 initWithMatchesBlock:matches |
| 197 descriptionBlock:describe] autorelease], | 197 descriptionBlock:describe] autorelease], |
| 198 nil); | 198 nil); |
| 199 } | 199 } |
| 200 | 200 |
| 201 } // namespace | 201 } // namespace |
| 202 | 202 |
| 203 namespace web { | 203 namespace web { |
| 204 | 204 |
| 205 id<GREYMatcher> webViewInWebState(WebState* web_state) { | 205 id<GREYMatcher> WebViewInWebState(WebState* web_state) { |
| 206 MatchesBlock matches = ^BOOL(UIView* view) { | 206 MatchesBlock matches = ^BOOL(UIView* view) { |
| 207 return [view isKindOfClass:[WKWebView class]] && | 207 return [view isKindOfClass:[WKWebView class]] && |
| 208 [view isDescendantOfView:web_state->GetView()]; | 208 [view isDescendantOfView:web_state->GetView()]; |
| 209 }; | 209 }; |
| 210 | 210 |
| 211 DescribeToBlock describe = ^(id<GREYDescription> description) { | 211 DescribeToBlock describe = ^(id<GREYDescription> description) { |
| 212 [description appendText:@"web view in web state"]; | 212 [description appendText:@"web view in web state"]; |
| 213 }; | 213 }; |
| 214 | 214 |
| 215 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches | 215 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches |
| 216 descriptionBlock:describe] | 216 descriptionBlock:describe] |
| 217 autorelease]; | 217 autorelease]; |
| 218 } | 218 } |
| 219 | 219 |
| 220 id<GREYMatcher> webViewContainingText(std::string text, WebState* web_state) { | 220 id<GREYMatcher> WebViewContainingText(std::string text, WebState* web_state) { |
| 221 return webViewWithText(text, web_state, true); | 221 return WebViewWithText(text, web_state, true); |
| 222 } | 222 } |
| 223 | 223 |
| 224 id<GREYMatcher> webViewNotContainingText(std::string text, | 224 id<GREYMatcher> WebViewNotContainingText(std::string text, |
| 225 WebState* web_state) { | 225 WebState* web_state) { |
| 226 return webViewWithText(text, web_state, false); | 226 return WebViewWithText(text, web_state, false); |
| 227 } | 227 } |
| 228 | 228 |
| 229 id<GREYMatcher> webViewContainingBlockedImage(std::string image_id, | 229 id<GREYMatcher> WebViewContainingBlockedImage(std::string image_id, |
| 230 WebState* web_state) { | 230 WebState* web_state) { |
| 231 return webViewContainingImage(image_id, web_state, IMAGE_STATE_BLOCKED); | 231 return WebViewContainingImage(image_id, web_state, IMAGE_STATE_BLOCKED); |
| 232 } | 232 } |
| 233 | 233 |
| 234 id<GREYMatcher> webViewContainingLoadedImage(std::string image_id, | 234 id<GREYMatcher> WebViewContainingLoadedImage(std::string image_id, |
| 235 WebState* web_state) { | 235 WebState* web_state) { |
| 236 return webViewContainingImage(image_id, web_state, IMAGE_STATE_LOADED); | 236 return WebViewContainingImage(image_id, web_state, IMAGE_STATE_LOADED); |
| 237 } | 237 } |
| 238 | 238 |
| 239 id<GREYMatcher> webViewCssSelector(std::string selector, WebState* web_state) { | 239 id<GREYMatcher> WebViewCssSelector(std::string selector, WebState* web_state) { |
| 240 MatchesBlock matches = ^BOOL(WKWebView*) { | 240 MatchesBlock matches = ^BOOL(WKWebView*) { |
| 241 std::string script = base::StringPrintf(kTestCssSelectorJavaScriptTemplate, | 241 std::string script = base::StringPrintf(kTestCssSelectorJavaScriptTemplate, |
| 242 selector.c_str()); | 242 selector.c_str()); |
| 243 return WaitUntilConditionOrTimeout(testing::kWaitForUIElementTimeout, ^{ | 243 return WaitUntilConditionOrTimeout(testing::kWaitForUIElementTimeout, ^{ |
| 244 bool did_succeed = false; | 244 bool did_succeed = false; |
| 245 std::unique_ptr<base::Value> value = | 245 std::unique_ptr<base::Value> value = |
| 246 web::test::ExecuteJavaScript(web_state, script); | 246 web::test::ExecuteJavaScript(web_state, script); |
| 247 if (value) { | 247 if (value) { |
| 248 value->GetAsBoolean(&did_succeed); | 248 value->GetAsBoolean(&did_succeed); |
| 249 } | 249 } |
| 250 return did_succeed; | 250 return did_succeed; |
| 251 }); | 251 }); |
| 252 }; | 252 }; |
| 253 | 253 |
| 254 DescribeToBlock describe = ^(id<GREYDescription> description) { | 254 DescribeToBlock describe = ^(id<GREYDescription> description) { |
| 255 [description appendText:@"web view selector "]; | 255 [description appendText:@"web view selector "]; |
| 256 [description appendText:base::SysUTF8ToNSString(selector)]; | 256 [description appendText:base::SysUTF8ToNSString(selector)]; |
| 257 }; | 257 }; |
| 258 | 258 |
| 259 return grey_allOf(webViewInWebState(web_state), | 259 return grey_allOf(WebViewInWebState(web_state), |
| 260 [[[GREYElementMatcherBlock alloc] | 260 [[[GREYElementMatcherBlock alloc] |
| 261 initWithMatchesBlock:matches | 261 initWithMatchesBlock:matches |
| 262 descriptionBlock:describe] autorelease], | 262 descriptionBlock:describe] autorelease], |
| 263 nil); | 263 nil); |
| 264 } | 264 } |
| 265 | 265 |
| 266 id<GREYMatcher> webViewScrollView(WebState* web_state) { | 266 id<GREYMatcher> WebViewScrollView(WebState* web_state) { |
| 267 MatchesBlock matches = ^BOOL(UIView* view) { | 267 MatchesBlock matches = ^BOOL(UIView* view) { |
| 268 return [view isKindOfClass:[UIScrollView class]] && | 268 return [view isKindOfClass:[UIScrollView class]] && |
| 269 [view.superview isKindOfClass:[WKWebView class]] && | 269 [view.superview isKindOfClass:[WKWebView class]] && |
| 270 [view isDescendantOfView:web_state->GetView()]; | 270 [view isDescendantOfView:web_state->GetView()]; |
| 271 }; | 271 }; |
| 272 | 272 |
| 273 DescribeToBlock describe = ^(id<GREYDescription> description) { | 273 DescribeToBlock describe = ^(id<GREYDescription> description) { |
| 274 [description appendText:@"web view scroll view"]; | 274 [description appendText:@"web view scroll view"]; |
| 275 }; | 275 }; |
| 276 | 276 |
| 277 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches | 277 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches |
| 278 descriptionBlock:describe] | 278 descriptionBlock:describe] |
| 279 autorelease]; | 279 autorelease]; |
| 280 } | 280 } |
| 281 | 281 |
| 282 id<GREYMatcher> interstitial(WebState* web_state) { | 282 id<GREYMatcher> Interstitial(WebState* web_state) { |
| 283 MatchesBlock matches = ^BOOL(WKWebView* view) { | 283 MatchesBlock matches = ^BOOL(WKWebView* view) { |
| 284 web::WebInterstitialImpl* interstitial = | 284 web::WebInterstitialImpl* interstitial = |
| 285 static_cast<web::WebInterstitialImpl*>(web_state->GetWebInterstitial()); | 285 static_cast<web::WebInterstitialImpl*>(web_state->GetWebInterstitial()); |
| 286 return interstitial && | 286 return interstitial && |
| 287 [view isDescendantOfView:interstitial->GetContentView()]; | 287 [view isDescendantOfView:interstitial->GetContentView()]; |
| 288 }; | 288 }; |
| 289 | 289 |
| 290 DescribeToBlock describe = ^(id<GREYDescription> description) { | 290 DescribeToBlock describe = ^(id<GREYDescription> description) { |
| 291 [description appendText:@"interstitial displayed"]; | 291 [description appendText:@"interstitial displayed"]; |
| 292 }; | 292 }; |
| 293 | 293 |
| 294 return grey_allOf(webViewInWebState(web_state), | 294 return grey_allOf(WebViewInWebState(web_state), |
| 295 [[[GREYElementMatcherBlock alloc] | 295 [[[GREYElementMatcherBlock alloc] |
| 296 initWithMatchesBlock:matches | 296 initWithMatchesBlock:matches |
| 297 descriptionBlock:describe] autorelease], | 297 descriptionBlock:describe] autorelease], |
| 298 nil); | 298 nil); |
| 299 } | 299 } |
| 300 | 300 |
| 301 id<GREYMatcher> interstitialContainingText(NSString* text, | 301 id<GREYMatcher> InterstitialContainingText(NSString* text, |
| 302 WebState* web_state) { | 302 WebState* web_state) { |
| 303 MatchesBlock matches = ^BOOL(WKWebView* view) { | 303 MatchesBlock matches = ^BOOL(WKWebView* view) { |
| 304 return WaitUntilConditionOrTimeout(testing::kWaitForUIElementTimeout, ^{ | 304 return WaitUntilConditionOrTimeout(testing::kWaitForUIElementTimeout, ^{ |
| 305 NSString* script = base::SysUTF8ToNSString(kGetDocumentBodyJavaScript); | 305 NSString* script = base::SysUTF8ToNSString(kGetDocumentBodyJavaScript); |
| 306 id body = ExecuteScriptOnInterstitial(web_state, script); | 306 id body = ExecuteScriptOnInterstitial(web_state, script); |
| 307 return [body containsString:text] ? true : false; | 307 return [body containsString:text] ? true : false; |
| 308 }); | 308 }); |
| 309 }; | 309 }; |
| 310 | 310 |
| 311 DescribeToBlock describe = ^(id<GREYDescription> description) { | 311 DescribeToBlock describe = ^(id<GREYDescription> description) { |
| 312 [description appendText:@"interstitial containing "]; | 312 [description appendText:@"interstitial containing "]; |
| 313 [description appendText:text]; | 313 [description appendText:text]; |
| 314 }; | 314 }; |
| 315 | 315 |
| 316 return grey_allOf(interstitial(web_state), | 316 return grey_allOf(Interstitial(web_state), |
| 317 [[[GREYElementMatcherBlock alloc] | 317 [[[GREYElementMatcherBlock alloc] |
| 318 initWithMatchesBlock:matches | 318 initWithMatchesBlock:matches |
| 319 descriptionBlock:describe] autorelease], | 319 descriptionBlock:describe] autorelease], |
| 320 nil); | 320 nil); |
| 321 } | 321 } |
| 322 | 322 |
| 323 } // namespace web | 323 } // namespace web |
| OLD | NEW |