| 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" |
| 11 #include "base/test/ios/wait_util.h" | 11 #include "base/test/ios/wait_util.h" |
| 12 #include "base/values.h" | 12 #include "base/values.h" |
| 13 #import "ios/testing/earl_grey/wait_util.h" | 13 #import "ios/testing/wait_util.h" |
| 14 #import "ios/web/public/test/earl_grey/web_view_matchers.h" | 14 #import "ios/web/public/test/earl_grey/web_view_matchers.h" |
| 15 #import "ios/web/public/test/web_view_interaction_test_util.h" | 15 #import "ios/web/public/test/web_view_interaction_test_util.h" |
| 16 #import "ios/web/web_state/web_state_impl.h" | 16 #import "ios/web/web_state/web_state_impl.h" |
| 17 | 17 |
| 18 using web::test::ExecuteJavaScript; | 18 using web::test::ExecuteJavaScript; |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 // Long press duration to trigger context menu. | 22 // Long press duration to trigger context menu. |
| 23 const NSTimeInterval kContextMenuLongPressDuration = 0.3; | 23 const NSTimeInterval kContextMenuLongPressDuration = 0.3; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 " __gCrWeb.message.invokeOnHost(" | 55 " __gCrWeb.message.invokeOnHost(" |
| 56 // Second template param: callback command. | 56 // Second template param: callback command. |
| 57 " {'command' : '%2$s' });" | 57 " {'command' : '%2$s' });" |
| 58 " }, options);" | 58 " }, options);" |
| 59 " return true;" | 59 " return true;" |
| 60 "})();"; | 60 "})();"; |
| 61 | 61 |
| 62 const std::string kAddVerifierScript = | 62 const std::string kAddVerifierScript = |
| 63 base::StringPrintf(kAddInteractionVerifierScriptTemplate, | 63 base::StringPrintf(kAddInteractionVerifierScriptTemplate, |
| 64 element_id.c_str(), kCallbackInvocation.c_str()); | 64 element_id.c_str(), kCallbackInvocation.c_str()); |
| 65 NSDate* deadline = | |
| 66 [NSDate dateWithTimeIntervalSinceNow:testing::kWaitForUIElementTimeout]; | |
| 67 bool verifier_added = false; | |
| 68 while (([[NSDate date] compare:deadline] != NSOrderedDescending) && | |
| 69 !verifier_added) { | |
| 70 std::unique_ptr<base::Value> value = | |
| 71 web::test::ExecuteJavaScript(web_state, kAddVerifierScript); | |
| 72 if (value) { | |
| 73 std::string error; | |
| 74 if (value->GetAsString(&error)) { | |
| 75 DLOG(ERROR) << "Verifier injection failed: " << error << ", retrying."; | |
| 76 } else if (value->GetAsBoolean(&verifier_added)) { | |
| 77 verifier_added = true; | |
| 78 } | |
| 79 } | |
| 80 base::test::ios::SpinRunLoopWithMaxDelay( | |
| 81 base::TimeDelta::FromSecondsD(testing::kSpinDelaySeconds)); | |
| 82 } | |
| 83 | 65 |
| 84 if (!verifier_added) | 66 bool success = testing::WaitUntilConditionOrTimeout( |
| 67 testing::kWaitForUIElementTimeout, ^bool() { |
| 68 bool verifier_added = false; |
| 69 std::unique_ptr<base::Value> value = |
| 70 web::test::ExecuteJavaScript(web_state, kAddVerifierScript); |
| 71 if (value) { |
| 72 std::string error; |
| 73 if (value->GetAsString(&error)) { |
| 74 DLOG(ERROR) << "Verifier injection failed: " << error |
| 75 << ", retrying."; |
| 76 } else if (value->GetAsBoolean(&verifier_added)) { |
| 77 return true; |
| 78 } |
| 79 } |
| 80 return false; |
| 81 }); |
| 82 |
| 83 if (!success) |
| 85 return false; | 84 return false; |
| 86 | 85 |
| 87 // The callback doesn't care about any of the parameters, just whether it is | 86 // The callback doesn't care about any of the parameters, just whether it is |
| 88 // called or not. | 87 // called or not. |
| 89 auto callback = base::BindBlock(^bool(const base::DictionaryValue& /* json */, | 88 auto callback = base::BindBlock(^bool(const base::DictionaryValue& /* json */, |
| 90 const GURL& /* origin_url */, | 89 const GURL& /* origin_url */, |
| 91 bool /* user_is_interacting */) { | 90 bool /* user_is_interacting */) { |
| 92 *verified = true; | 91 *verified = true; |
| 93 return true; | 92 return true; |
| 94 }); | 93 }); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 | 167 |
| 169 if (*error) { | 168 if (*error) { |
| 170 return NO; | 169 return NO; |
| 171 } | 170 } |
| 172 | 171 |
| 173 // Wait for the verified to trigger and set |verified|. | 172 // Wait for the verified to trigger and set |verified|. |
| 174 NSString* verification_timeout_message = | 173 NSString* verification_timeout_message = |
| 175 [NSString stringWithFormat:@"The action (%@) on element_id %s wasn't " | 174 [NSString stringWithFormat:@"The action (%@) on element_id %s wasn't " |
| 176 @"verified before timing out.", | 175 @"verified before timing out.", |
| 177 action.name, element_id.c_str()]; | 176 action.name, element_id.c_str()]; |
| 178 testing::WaitUntilCondition(testing::kWaitForJSCompletionTimeout, | 177 GREYAssert(testing::WaitUntilConditionOrTimeout( |
| 179 verification_timeout_message, ^{ | 178 testing::kWaitForJSCompletionTimeout, |
| 180 return verified; | 179 ^{ |
| 181 }); | 180 return verified; |
| 181 }), |
| 182 verification_timeout_message); |
| 182 | 183 |
| 183 // If |verified| is not true, the wait condition should have already exited | 184 // If |verified| is not true, the wait condition should have already exited |
| 184 // this control flow, so sanity check that it has in fact been set to | 185 // this control flow, so sanity check that it has in fact been set to |
| 185 // true by this point. | 186 // true by this point. |
| 186 DCHECK(verified); | 187 DCHECK(verified); |
| 187 return YES; | 188 return YES; |
| 188 }; | 189 }; |
| 189 | 190 |
| 190 return [GREYActionBlock actionWithName:action_name | 191 return [GREYActionBlock actionWithName:action_name |
| 191 constraints:webViewInWebState(state) | 192 constraints:webViewInWebState(state) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 212 id<GREYAction> webViewTapElement(WebState* state, | 213 id<GREYAction> webViewTapElement(WebState* state, |
| 213 const std::string& element_id) { | 214 const std::string& element_id) { |
| 214 CGRect rect = web::test::GetBoundingRectOfElementWithId(state, element_id); | 215 CGRect rect = web::test::GetBoundingRectOfElementWithId(state, element_id); |
| 215 CGPoint point = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); | 216 CGPoint point = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); |
| 216 return CGRectIsEmpty(rect) ? webViewElementNotFound(element_id) | 217 return CGRectIsEmpty(rect) ? webViewElementNotFound(element_id) |
| 217 : webViewVerifiedActionOnElement( | 218 : webViewVerifiedActionOnElement( |
| 218 state, grey_tapAtPoint(point), element_id); | 219 state, grey_tapAtPoint(point), element_id); |
| 219 } | 220 } |
| 220 | 221 |
| 221 } // namespace web | 222 } // namespace web |
| OLD | NEW |