wait_util.mm 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #import "base/test/ios/wait_util.h"
  5. #import <Foundation/Foundation.h>
  6. #include "base/check.h"
  7. #include "base/mac/scoped_nsobject.h"
  8. #include "base/run_loop.h"
  9. #include "base/test/test_timeouts.h"
  10. #include "base/timer/elapsed_timer.h"
  11. namespace base {
  12. namespace test {
  13. namespace ios {
  14. const NSTimeInterval kSpinDelaySeconds = 0.01;
  15. const NSTimeInterval kWaitForJSCompletionTimeout = 6.0;
  16. const NSTimeInterval kWaitForUIElementTimeout = 4.0;
  17. const NSTimeInterval kWaitForDownloadTimeout = 10.0;
  18. const NSTimeInterval kWaitForPageLoadTimeout = 10.0;
  19. const NSTimeInterval kWaitForActionTimeout = 10.0;
  20. const NSTimeInterval kWaitForClearBrowsingDataTimeout = 45.0;
  21. const NSTimeInterval kWaitForCookiesTimeout = 4.0;
  22. const NSTimeInterval kWaitForFileOperationTimeout = 2.0;
  23. bool WaitUntilConditionOrTimeout(NSTimeInterval timeout,
  24. ConditionBlock condition) {
  25. NSDate* deadline = [NSDate dateWithTimeIntervalSinceNow:timeout];
  26. bool success = condition();
  27. while (!success && [[NSDate date] compare:deadline] != NSOrderedDescending) {
  28. base::test::ios::SpinRunLoopWithMaxDelay(base::Seconds(kSpinDelaySeconds));
  29. success = condition();
  30. }
  31. return success;
  32. }
  33. TimeDelta TimeUntilCondition(ProceduralBlock action,
  34. ConditionBlock condition,
  35. bool run_message_loop,
  36. TimeDelta timeout) {
  37. ElapsedTimer timer;
  38. if (action)
  39. action();
  40. if (timeout.is_zero())
  41. timeout = TestTimeouts::action_timeout();
  42. const TimeDelta spin_delay(Milliseconds(10));
  43. bool condition_evaluation_result = false;
  44. while (timer.Elapsed() < timeout &&
  45. (!condition || !(condition_evaluation_result = condition()))) {
  46. SpinRunLoopWithMaxDelay(spin_delay);
  47. if (run_message_loop)
  48. RunLoop().RunUntilIdle();
  49. }
  50. const TimeDelta elapsed = timer.Elapsed();
  51. // If DCHECK is ever hit, check if |action| is doing something that is
  52. // taking an unreasonably long time, or if |condition| does not come
  53. // true quickly enough. Increase |timeout| only if necessary.
  54. DCHECK(!condition || condition_evaluation_result);
  55. return elapsed;
  56. }
  57. void WaitUntilCondition(ConditionBlock condition,
  58. bool run_message_loop,
  59. TimeDelta timeout) {
  60. TimeUntilCondition(nil, condition, run_message_loop, timeout);
  61. }
  62. void WaitUntilCondition(ConditionBlock condition) {
  63. WaitUntilCondition(condition, false, TimeDelta());
  64. }
  65. void SpinRunLoopWithMaxDelay(TimeDelta max_delay) {
  66. scoped_nsobject<NSDate> beforeDate(
  67. [[NSDate alloc] initWithTimeIntervalSinceNow:max_delay.InSecondsF()]);
  68. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
  69. beforeDate:beforeDate];
  70. }
  71. void SpinRunLoopWithMinDelay(TimeDelta min_delay) {
  72. ElapsedTimer timer;
  73. while (timer.Elapsed() < min_delay) {
  74. SpinRunLoopWithMaxDelay(Milliseconds(10));
  75. }
  76. }
  77. } // namespace ios
  78. } // namespace test
  79. } // namespace base