| 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_actions.h" | 5 #import "ios/web/public/test/earl_grey/web_view_actions.h" |
| 6 | 6 |
| 7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 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" |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 return true; | 98 return true; |
| 99 } | 99 } |
| 100 | 100 |
| 101 // Removes the injected callback. | 101 // Removes the injected callback. |
| 102 void RemoveVerifierForElementWithId(web::WebState* web_state, | 102 void RemoveVerifierForElementWithId(web::WebState* web_state, |
| 103 const std::string& element_id) { | 103 const std::string& element_id) { |
| 104 static_cast<web::WebStateImpl*>(web_state)->RemoveScriptCommandCallback( | 104 static_cast<web::WebStateImpl*>(web_state)->RemoveScriptCommandCallback( |
| 105 CallbackPrefixForElementId(element_id)); | 105 CallbackPrefixForElementId(element_id)); |
| 106 } | 106 } |
| 107 | 107 |
| 108 // Returns a no element found error. |
| 109 id<GREYAction> webViewElementNotFound(const std::string& element_id) { |
| 110 NSString* description = [NSString |
| 111 stringWithFormat:@"Couldn't locate a bounding rect for element_id %s; " |
| 112 @"either it isn't there or it has no area.", |
| 113 element_id.c_str()]; |
| 114 GREYPerformBlock throw_error = |
| 115 ^BOOL(id /* element */, __strong NSError** error) { |
| 116 NSDictionary* user_info = @{NSLocalizedDescriptionKey : description}; |
| 117 *error = [NSError errorWithDomain:kGREYInteractionErrorDomain |
| 118 code:kGREYInteractionActionFailedErrorCode |
| 119 userInfo:user_info]; |
| 120 return NO; |
| 121 }; |
| 122 return [GREYActionBlock actionWithName:@"Locate element bounds" |
| 123 performBlock:throw_error]; |
| 124 } |
| 125 |
| 108 } // namespace | 126 } // namespace |
| 109 | 127 |
| 110 namespace web { | 128 namespace web { |
| 111 | 129 |
| 112 id<GREYAction> webViewVerifiedActionOnElement(WebState* state, | 130 id<GREYAction> webViewVerifiedActionOnElement(WebState* state, |
| 113 id<GREYAction> action, | 131 id<GREYAction> action, |
| 114 const std::string& element_id) { | 132 const std::string& element_id) { |
| 115 NSString* action_name = | 133 NSString* action_name = |
| 116 [NSString stringWithFormat:@"Verified action (%@) on webview element %s.", | 134 [NSString stringWithFormat:@"Verified action (%@) on webview element %s.", |
| 117 action.name, element_id.c_str()]; | 135 action.name, element_id.c_str()]; |
| 118 | 136 |
| 119 GREYPerformBlock verified_tap = ^BOOL(id element, __strong NSError** error) { | 137 GREYPerformBlock verified_tap = ^BOOL(id element, __strong NSError** error) { |
| 120 // A pointer to |verified| is passed into AddVerifierToElementWithId() so | 138 // A pointer to |verified| is passed into AddVerifierToElementWithId() so |
| 121 // the verifier can update its value, but |verified| also needs to be marked | 139 // the verifier can update its value, but |verified| also needs to be marked |
| 122 // as __block so that waitUntilCondition(), below, can access it by | 140 // as __block so that waitUntilCondition(), below, can access it by |
| 123 // reference. | 141 // reference. |
| 124 __block bool verified = false; | 142 __block bool verified = false; |
| 125 | 143 |
| 126 // Ensure that RemoveVerifierForElementWithId() is run regardless of how | 144 // Ensure that RemoveVerifierForElementWithId() is run regardless of how |
| 127 // the block exits. | 145 // the block exits. |
| 128 base::ScopedClosureRunner cleanup( | 146 base::ScopedClosureRunner cleanup( |
| 129 base::Bind(&RemoveVerifierForElementWithId, state, element_id)); | 147 base::Bind(&RemoveVerifierForElementWithId, state, element_id)); |
| 130 | 148 |
| 131 // Inject the vefifier. | 149 // Inject the verifier. |
| 132 bool verifier_added = | 150 bool verifier_added = |
| 133 AddVerifierToElementWithId(state, element_id, &verified); | 151 AddVerifierToElementWithId(state, element_id, &verified); |
| 134 if (!verifier_added) { | 152 if (!verifier_added) { |
| 135 NSString* description = [NSString | 153 NSString* description = [NSString |
| 136 stringWithFormat:@"It wasn't possible to add the verification " | 154 stringWithFormat:@"It wasn't possible to add the verification " |
| 137 @"javascript for element_id %s", | 155 @"javascript for element_id %s", |
| 138 element_id.c_str()]; | 156 element_id.c_str()]; |
| 139 NSDictionary* user_info = @{NSLocalizedDescriptionKey : description}; | 157 NSDictionary* user_info = @{NSLocalizedDescriptionKey : description}; |
| 140 *error = [NSError errorWithDomain:kGREYInteractionErrorDomain | 158 *error = [NSError errorWithDomain:kGREYInteractionErrorDomain |
| 141 code:kGREYInteractionActionFailedErrorCode | 159 code:kGREYInteractionActionFailedErrorCode |
| (...skipping 30 matching lines...) Expand all Loading... |
| 172 return [GREYActionBlock actionWithName:action_name | 190 return [GREYActionBlock actionWithName:action_name |
| 173 constraints:webViewInWebState(state) | 191 constraints:webViewInWebState(state) |
| 174 performBlock:verified_tap]; | 192 performBlock:verified_tap]; |
| 175 } | 193 } |
| 176 | 194 |
| 177 id<GREYAction> webViewLongPressElementForContextMenu( | 195 id<GREYAction> webViewLongPressElementForContextMenu( |
| 178 WebState* state, | 196 WebState* state, |
| 179 const std::string& element_id, | 197 const std::string& element_id, |
| 180 bool triggers_context_menu) { | 198 bool triggers_context_menu) { |
| 181 CGRect rect = web::test::GetBoundingRectOfElementWithId(state, element_id); | 199 CGRect rect = web::test::GetBoundingRectOfElementWithId(state, element_id); |
| 182 // Check if |rect| is empty; if it is, return an action that just throws an | |
| 183 // error. | |
| 184 if (CGRectIsEmpty(rect)) { | 200 if (CGRectIsEmpty(rect)) { |
| 185 NSString* description = [NSString | 201 return webViewElementNotFound(element_id); |
| 186 stringWithFormat:@"Couldn't locate a bounding rect for element_id %s; " | |
| 187 @"either it isn't there or it has no area.", | |
| 188 element_id.c_str()]; | |
| 189 GREYPerformBlock throw_error = ^BOOL(id /* element */, | |
| 190 __strong NSError** error) { | |
| 191 NSDictionary* user_info = @{NSLocalizedDescriptionKey : description}; | |
| 192 *error = [NSError errorWithDomain:kGREYInteractionErrorDomain | |
| 193 code:kGREYInteractionActionFailedErrorCode | |
| 194 userInfo:user_info]; | |
| 195 return NO; | |
| 196 }; | |
| 197 return [GREYActionBlock actionWithName:@"Locate element bounds" | |
| 198 performBlock:throw_error]; | |
| 199 } | 202 } |
| 200 | |
| 201 // If there's a usable rect, long-press in the center. | |
| 202 CGPoint point = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); | 203 CGPoint point = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); |
| 203 | |
| 204 id<GREYAction> longpress = | 204 id<GREYAction> longpress = |
| 205 grey_longPressAtPointWithDuration(point, kContextMenuLongPressDuration); | 205 grey_longPressAtPointWithDuration(point, kContextMenuLongPressDuration); |
| 206 id<GREYAction> action = longpress; | 206 if (triggers_context_menu) { |
| 207 return longpress; |
| 208 } |
| 209 return webViewVerifiedActionOnElement(state, longpress, element_id); |
| 210 } |
| 207 | 211 |
| 208 if (!triggers_context_menu) { | 212 id<GREYAction> webViewTapElement(WebState* state, |
| 209 action = webViewVerifiedActionOnElement(state, longpress, element_id); | 213 const std::string& element_id) { |
| 210 } | 214 CGRect rect = web::test::GetBoundingRectOfElementWithId(state, element_id); |
| 211 | 215 CGPoint point = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); |
| 212 return action; | 216 return CGRectIsEmpty(rect) ? webViewElementNotFound(element_id) |
| 217 : webViewVerifiedActionOnElement( |
| 218 state, grey_tapAtPoint(point), element_id); |
| 213 } | 219 } |
| 214 | 220 |
| 215 } // namespace web | 221 } // namespace web |
| OLD | NEW |