| 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 <WebKit/WebKit.h> | 8 #import <WebKit/WebKit.h> |
| 8 | 9 |
| 9 #include "base/mac/bind_objc_block.h" | 10 #include "base/mac/bind_objc_block.h" |
| 11 #import "base/mac/scoped_nsobject.h" |
| 10 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
| 11 #include "base/strings/sys_string_conversions.h" | 13 #include "base/strings/sys_string_conversions.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 14 #include "base/strings/utf_string_conversions.h" |
| 13 #include "base/test/ios/wait_util.h" | 15 #include "base/test/ios/wait_util.h" |
| 14 #include "base/values.h" | 16 #include "base/values.h" |
| 15 #include "ios/testing/wait_util.h" | 17 #include "ios/testing/wait_util.h" |
| 16 #import "ios/web/interstitials/web_interstitial_impl.h" | 18 #import "ios/web/interstitials/web_interstitial_impl.h" |
| 17 #import "ios/web/public/test/earl_grey/js_test_util.h" | 19 #import "ios/web/public/test/earl_grey/js_test_util.h" |
| 18 #import "ios/web/public/test/web_view_interaction_test_util.h" | 20 #import "ios/web/public/test/web_view_interaction_test_util.h" |
| 21 #import "net/base/mac/url_conversions.h" |
| 19 | 22 |
| 23 using testing::kWaitForDownloadTimeout; |
| 20 using testing::WaitUntilConditionOrTimeout; | 24 using testing::WaitUntilConditionOrTimeout; |
| 21 | 25 |
| 26 // A helper delegate class that allows downloading responses with invalid |
| 27 // SSL certs. |
| 28 @interface TestURLSessionDelegate : NSObject<NSURLSessionDelegate> |
| 29 @end |
| 30 |
| 31 @implementation TestURLSessionDelegate |
| 32 |
| 33 - (void)URLSession:(NSURLSession*)session |
| 34 didReceiveChallenge:(NSURLAuthenticationChallenge*)challenge |
| 35 completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, |
| 36 NSURLCredential*))completionHandler { |
| 37 SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; |
| 38 completionHandler(NSURLSessionAuthChallengeUseCredential, |
| 39 [NSURLCredential credentialForTrust:serverTrust]); |
| 40 } |
| 41 |
| 42 @end |
| 43 |
| 22 namespace { | 44 namespace { |
| 23 | 45 |
| 24 // Script that returns document.body as a string. | 46 // Script that returns document.body as a string. |
| 25 char kGetDocumentBodyJavaScript[] = | 47 char kGetDocumentBodyJavaScript[] = |
| 26 "document.body ? document.body.textContent : null"; | 48 "document.body ? document.body.textContent : null"; |
| 27 // Script that tests presence of css selector. | 49 // Script that tests presence of css selector. |
| 28 char kTestCssSelectorJavaScriptTemplate[] = "!!document.querySelector(\"%s\");"; | 50 char kTestCssSelectorJavaScriptTemplate[] = "!!document.querySelector(\"%s\");"; |
| 29 | 51 |
| 30 // Helper function for matching web views containing or not containing |text|, | 52 // Helper function for matching web views containing or not containing |text|, |
| 31 // depending on the value of |should_contain_text|. | 53 // depending on the value of |should_contain_text|. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 51 [description appendText:base::SysUTF8ToNSString(text)]; | 73 [description appendText:base::SysUTF8ToNSString(text)]; |
| 52 }; | 74 }; |
| 53 | 75 |
| 54 return grey_allOf(webViewInWebState(web_state), | 76 return grey_allOf(webViewInWebState(web_state), |
| 55 [[[GREYElementMatcherBlock alloc] | 77 [[[GREYElementMatcherBlock alloc] |
| 56 initWithMatchesBlock:matches | 78 initWithMatchesBlock:matches |
| 57 descriptionBlock:describe] autorelease], | 79 descriptionBlock:describe] autorelease], |
| 58 nil); | 80 nil); |
| 59 } | 81 } |
| 60 | 82 |
| 83 // Fetches the image from |image_url|. |
| 84 UIImage* LoadImage(const GURL& image_url) { |
| 85 __block base::scoped_nsobject<UIImage> image; |
| 86 __block base::scoped_nsobject<NSError> error; |
| 87 TestURLSessionDelegate* session_delegate = |
| 88 [[TestURLSessionDelegate alloc] init]; |
| 89 NSURLSessionConfiguration* session_config = |
| 90 [NSURLSessionConfiguration defaultSessionConfiguration]; |
| 91 NSURLSession* session = |
| 92 [NSURLSession sessionWithConfiguration:session_config |
| 93 delegate:session_delegate |
| 94 delegateQueue:nil]; |
| 95 id completion_handler = ^(NSData* data, NSURLResponse*, NSError* task_error) { |
| 96 if (task_error) { |
| 97 error.reset([task_error retain]); |
| 98 } else { |
| 99 image.reset([[UIImage alloc] initWithData:data]); |
| 100 } |
| 101 [session_delegate autorelease]; |
| 102 }; |
| 103 |
| 104 NSURLSessionDataTask* task = |
| 105 [session dataTaskWithURL:net::NSURLWithGURL(image_url) |
| 106 completionHandler:completion_handler]; |
| 107 [task resume]; |
| 108 |
| 109 bool image_loaded = WaitUntilConditionOrTimeout(kWaitForDownloadTimeout, ^{ |
| 110 return image || error; |
| 111 }); |
| 112 GREYAssert(image_loaded, @"Failed to download image"); |
| 113 |
| 114 return [[image retain] autorelease]; |
| 115 } |
| 116 |
| 61 } // namespace | 117 } // namespace |
| 62 | 118 |
| 63 namespace web { | 119 namespace web { |
| 64 | 120 |
| 65 id<GREYMatcher> webViewInWebState(WebState* web_state) { | 121 id<GREYMatcher> webViewInWebState(WebState* web_state) { |
| 66 MatchesBlock matches = ^BOOL(UIView* view) { | 122 MatchesBlock matches = ^BOOL(UIView* view) { |
| 67 return [view isKindOfClass:[WKWebView class]] && | 123 return [view isKindOfClass:[WKWebView class]] && |
| 68 [view isDescendantOfView:web_state->GetView()]; | 124 [view isDescendantOfView:web_state->GetView()]; |
| 69 }; | 125 }; |
| 70 | 126 |
| 71 DescribeToBlock describe = ^(id<GREYDescription> description) { | 127 DescribeToBlock describe = ^(id<GREYDescription> description) { |
| 72 [description appendText:@"web view in web state"]; | 128 [description appendText:@"web view in web state"]; |
| 73 }; | 129 }; |
| 74 | 130 |
| 75 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches | 131 return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches |
| 76 descriptionBlock:describe] | 132 descriptionBlock:describe] |
| 77 autorelease]; | 133 autorelease]; |
| 78 } | 134 } |
| 79 | 135 |
| 80 id<GREYMatcher> webViewContainingText(std::string text, WebState* web_state) { | 136 id<GREYMatcher> webViewContainingText(std::string text, WebState* web_state) { |
| 81 return webViewWithText(text, web_state, true); | 137 return webViewWithText(text, web_state, true); |
| 82 } | 138 } |
| 83 | 139 |
| 84 id<GREYMatcher> webViewNotContainingText(std::string text, | 140 id<GREYMatcher> webViewNotContainingText(std::string text, |
| 85 WebState* web_state) { | 141 WebState* web_state) { |
| 86 return webViewWithText(text, web_state, false); | 142 return webViewWithText(text, web_state, false); |
| 87 } | 143 } |
| 88 | 144 |
| 89 id<GREYMatcher> webViewContainingBlockedImage(std::string image_id, | 145 id<GREYMatcher> webViewContainingBlockedImage(std::string image_id, |
| 146 WebState* web_state) { |
| 147 std::string get_url_script = |
| 148 base::StringPrintf("document.getElementById('%s').src", image_id.c_str()); |
| 149 std::unique_ptr<base::Value> url_as_value = |
| 150 test::ExecuteJavaScript(web_state, get_url_script); |
| 151 std::string url_as_string; |
| 152 if (!url_as_value->GetAsString(&url_as_string)) |
| 153 return grey_nil(); |
| 154 |
| 155 UIImage* image = LoadImage(GURL(url_as_string)); |
| 156 if (!image) |
| 157 return grey_nil(); |
| 158 |
| 159 return webViewContainingBlockedImage(image_id, image.size, web_state); |
| 160 } |
| 161 |
| 162 id<GREYMatcher> webViewContainingBlockedImage(std::string image_id, |
| 90 CGSize expected_size, | 163 CGSize expected_size, |
| 91 WebState* web_state) { | 164 WebState* web_state) { |
| 92 MatchesBlock matches = ^BOOL(WKWebView*) { | 165 MatchesBlock matches = ^BOOL(WKWebView*) { |
| 93 return WaitUntilConditionOrTimeout(testing::kWaitForUIElementTimeout, ^{ | 166 return WaitUntilConditionOrTimeout(testing::kWaitForUIElementTimeout, ^{ |
| 94 NSString* const kGetElementAttributesScript = [NSString | 167 NSString* const kGetElementAttributesScript = [NSString |
| 95 stringWithFormat:@"var image = document.getElementById('%@');" | 168 stringWithFormat:@"var image = document.getElementById('%@');" |
| 96 @"var imageHeight = image.height;" | 169 @"var imageHeight = image.height;" |
| 97 @"var imageWidth = image.width;" | 170 @"var imageWidth = image.width;" |
| 98 @"JSON.stringify({" | 171 @"JSON.stringify({" |
| 99 @" height:imageHeight," | 172 @" height:imageHeight," |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 }; | 282 }; |
| 210 | 283 |
| 211 return grey_allOf(interstitial(web_state), | 284 return grey_allOf(interstitial(web_state), |
| 212 [[[GREYElementMatcherBlock alloc] | 285 [[[GREYElementMatcherBlock alloc] |
| 213 initWithMatchesBlock:matches | 286 initWithMatchesBlock:matches |
| 214 descriptionBlock:describe] autorelease], | 287 descriptionBlock:describe] autorelease], |
| 215 nil); | 288 nil); |
| 216 } | 289 } |
| 217 | 290 |
| 218 } // namespace web | 291 } // namespace web |
| OLD | NEW |