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 |