| 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/web_test_with_web_state.h" | 5 #import "ios/web/public/test/web_test_with_web_state.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/test/ios/wait_util.h" | 8 #include "base/test/ios/wait_util.h" |
| 9 #import "ios/testing/ocmock_complex_type_helper.h" | 9 #import "ios/testing/ocmock_complex_type_helper.h" |
| 10 #import "ios/web/navigation/crw_session_controller.h" | 10 #import "ios/web/navigation/crw_session_controller.h" |
| 11 #import "ios/web/web_state/ui/crw_web_controller.h" | 11 #import "ios/web/web_state/ui/crw_web_controller.h" |
| 12 #import "ios/web/web_state/web_state_impl.h" | 12 #import "ios/web/web_state/web_state_impl.h" |
| 13 | 13 |
| 14 // Helper Mock to stub out API with C++ objects in arguments. | 14 // Helper Mock to stub out API with C++ objects in arguments. |
| 15 @interface WebDelegateMock : OCMockComplexTypeHelper | 15 @interface WebDelegateMock : OCMockComplexTypeHelper |
| 16 @end | 16 @end |
| 17 | 17 |
| 18 @implementation WebDelegateMock | 18 @implementation WebDelegateMock |
| 19 // Stub implementation always returns YES. | 19 // Stub implementation always returns YES. |
| 20 - (BOOL)webController:(CRWWebController*)webController | 20 - (BOOL)webController:(CRWWebController*)webController |
| 21 shouldOpenURL:(const GURL&)url | 21 shouldOpenURL:(const GURL&)url |
| 22 mainDocumentURL:(const GURL&)mainDocumentURL | 22 mainDocumentURL:(const GURL&)mainDocumentURL |
| 23 linkClicked:(BOOL)linkClicked { | 23 linkClicked:(BOOL)linkClicked { |
| 24 return YES; | 24 return YES; |
| 25 } | 25 } |
| 26 @end | 26 @end |
| 27 | 27 |
| 28 namespace { |
| 29 // Returns CRWWebController for the given |web_state|. |
| 30 CRWWebController* GetWebController(web::WebState* web_state) { |
| 31 web::WebStateImpl* web_state_impl = |
| 32 static_cast<web::WebStateImpl*>(web_state); |
| 33 return web_state_impl->GetWebController(); |
| 34 } |
| 35 } // namespace |
| 36 |
| 28 namespace web { | 37 namespace web { |
| 29 | 38 |
| 30 WebTestWithWebState::WebTestWithWebState() {} | 39 WebTestWithWebState::WebTestWithWebState() {} |
| 31 | 40 |
| 32 WebTestWithWebState::~WebTestWithWebState() {} | 41 WebTestWithWebState::~WebTestWithWebState() {} |
| 33 | 42 |
| 34 static int s_html_load_count; | 43 static int s_html_load_count; |
| 35 | 44 |
| 36 void WebTestWithWebState::SetUp() { | 45 void WebTestWithWebState::SetUp() { |
| 37 WebTest::SetUp(); | 46 WebTest::SetUp(); |
| 38 std::unique_ptr<WebStateImpl> web_state(new WebStateImpl(GetBrowserState())); | 47 std::unique_ptr<WebStateImpl> web_state(new WebStateImpl(GetBrowserState())); |
| 39 web_state->GetNavigationManagerImpl().InitializeSession(nil, nil, NO, 0); | 48 web_state->GetNavigationManagerImpl().InitializeSession(nil, nil, NO, 0); |
| 40 web_state->SetWebUsageEnabled(true); | 49 web_state->SetWebUsageEnabled(true); |
| 41 webController_.reset(web_state->GetWebController()); | |
| 42 web_state_.reset(web_state.release()); | 50 web_state_.reset(web_state.release()); |
| 43 | 51 |
| 44 // Force generation of child views; necessary for some tests. | 52 // Force generation of child views; necessary for some tests. |
| 45 [webController_ triggerPendingLoad]; | 53 [GetWebController(web_state_.get()) triggerPendingLoad]; |
| 46 s_html_load_count = 0; | 54 s_html_load_count = 0; |
| 47 } | 55 } |
| 48 | 56 |
| 49 void WebTestWithWebState::TearDown() { | 57 void WebTestWithWebState::TearDown() { |
| 50 web_state_.reset(); | 58 web_state_.reset(); |
| 51 WebTest::TearDown(); | 59 WebTest::TearDown(); |
| 52 } | 60 } |
| 53 | 61 |
| 54 void WebTestWithWebState::WillProcessTask( | 62 void WebTestWithWebState::WillProcessTask( |
| 55 const base::PendingTask& pending_task) { | 63 const base::PendingTask& pending_task) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 74 LoadURL(url); | 82 LoadURL(url); |
| 75 | 83 |
| 76 if (ResetPageIfNavigationStalled(load_check)) { | 84 if (ResetPageIfNavigationStalled(load_check)) { |
| 77 LoadHtml(html); | 85 LoadHtml(html); |
| 78 } | 86 } |
| 79 } | 87 } |
| 80 | 88 |
| 81 void WebTestWithWebState::LoadURL(const GURL& url) { | 89 void WebTestWithWebState::LoadURL(const GURL& url) { |
| 82 // First step is to ensure that the web controller has finished any previous | 90 // First step is to ensure that the web controller has finished any previous |
| 83 // page loads so the new load is not confused. | 91 // page loads so the new load is not confused. |
| 84 while ([webController_ loadPhase] != PAGE_LOADED) | 92 while ([GetWebController(web_state()) loadPhase] != PAGE_LOADED) |
| 85 WaitForBackgroundTasks(); | 93 WaitForBackgroundTasks(); |
| 86 id originalMockDelegate = | 94 id originalMockDelegate = |
| 87 [OCMockObject niceMockForProtocol:@protocol(CRWWebDelegate)]; | 95 [OCMockObject niceMockForProtocol:@protocol(CRWWebDelegate)]; |
| 88 id mockDelegate = | 96 id mockDelegate = |
| 89 [[WebDelegateMock alloc] initWithRepresentedObject:originalMockDelegate]; | 97 [[WebDelegateMock alloc] initWithRepresentedObject:originalMockDelegate]; |
| 90 id existingDelegate = webController_.get().delegate; | 98 id existingDelegate = GetWebController(web_state()).delegate; |
| 91 webController_.get().delegate = mockDelegate; | 99 GetWebController(web_state()).delegate = mockDelegate; |
| 92 | 100 |
| 93 web::NavigationManagerImpl& navManager = | 101 web::NavigationManagerImpl& navManager = |
| 94 [webController_ webStateImpl]->GetNavigationManagerImpl(); | 102 [GetWebController(web_state()) webStateImpl]->GetNavigationManagerImpl(); |
| 95 navManager.InitializeSession(@"name", nil, NO, 0); | 103 navManager.InitializeSession(@"name", nil, NO, 0); |
| 96 [navManager.GetSessionController() addPendingEntry:url | 104 [navManager.GetSessionController() addPendingEntry:url |
| 97 referrer:web::Referrer() | 105 referrer:web::Referrer() |
| 98 transition:ui::PAGE_TRANSITION_TYPED | 106 transition:ui::PAGE_TRANSITION_TYPED |
| 99 rendererInitiated:NO]; | 107 rendererInitiated:NO]; |
| 100 | 108 |
| 101 [webController_ loadCurrentURL]; | 109 [GetWebController(web_state()) loadCurrentURL]; |
| 102 while ([webController_ loadPhase] != PAGE_LOADED) | 110 while ([GetWebController(web_state()) loadPhase] != PAGE_LOADED) |
| 103 WaitForBackgroundTasks(); | 111 WaitForBackgroundTasks(); |
| 104 webController_.get().delegate = existingDelegate; | 112 GetWebController(web_state()).delegate = existingDelegate; |
| 105 [[webController_ view] layoutIfNeeded]; | 113 [web_state()->GetView() layoutIfNeeded]; |
| 106 } | 114 } |
| 107 | 115 |
| 108 void WebTestWithWebState::WaitForBackgroundTasks() { | 116 void WebTestWithWebState::WaitForBackgroundTasks() { |
| 109 // Because tasks can add new tasks to either queue, the loop continues until | 117 // Because tasks can add new tasks to either queue, the loop continues until |
| 110 // the first pass where no activity is seen from either queue. | 118 // the first pass where no activity is seen from either queue. |
| 111 bool activitySeen = false; | 119 bool activitySeen = false; |
| 112 base::MessageLoop* messageLoop = base::MessageLoop::current(); | 120 base::MessageLoop* messageLoop = base::MessageLoop::current(); |
| 113 messageLoop->AddTaskObserver(this); | 121 messageLoop->AddTaskObserver(this); |
| 114 do { | 122 do { |
| 115 activitySeen = false; | 123 activitySeen = false; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 132 | 140 |
| 133 void WebTestWithWebState::WaitForCondition(ConditionBlock condition) { | 141 void WebTestWithWebState::WaitForCondition(ConditionBlock condition) { |
| 134 base::MessageLoop* messageLoop = base::MessageLoop::current(); | 142 base::MessageLoop* messageLoop = base::MessageLoop::current(); |
| 135 DCHECK(messageLoop); | 143 DCHECK(messageLoop); |
| 136 base::test::ios::WaitUntilCondition(condition, messageLoop, | 144 base::test::ios::WaitUntilCondition(condition, messageLoop, |
| 137 base::TimeDelta::FromSeconds(10)); | 145 base::TimeDelta::FromSeconds(10)); |
| 138 } | 146 } |
| 139 | 147 |
| 140 NSString* WebTestWithWebState::EvaluateJavaScriptAsString(NSString* script) { | 148 NSString* WebTestWithWebState::EvaluateJavaScriptAsString(NSString* script) { |
| 141 __block base::scoped_nsobject<NSString> evaluationResult; | 149 __block base::scoped_nsobject<NSString> evaluationResult; |
| 142 [webController_ evaluateJavaScript:script | 150 [GetWebController(web_state()) |
| 143 stringResultHandler:^(NSString* result, NSError*) { | 151 evaluateJavaScript:script |
| 144 DCHECK([result isKindOfClass:[NSString class]]); | 152 stringResultHandler:^(NSString* result, NSError*) { |
| 145 evaluationResult.reset([result copy]); | 153 DCHECK([result isKindOfClass:[NSString class]]); |
| 146 }]; | 154 evaluationResult.reset([result copy]); |
| 155 }]; |
| 147 base::test::ios::WaitUntilCondition(^bool() { | 156 base::test::ios::WaitUntilCondition(^bool() { |
| 148 return evaluationResult; | 157 return evaluationResult; |
| 149 }); | 158 }); |
| 150 return [[evaluationResult retain] autorelease]; | 159 return [[evaluationResult retain] autorelease]; |
| 151 } | 160 } |
| 152 | 161 |
| 153 id WebTestWithWebState::ExecuteJavaScript(NSString* script) { | 162 id WebTestWithWebState::ExecuteJavaScript(NSString* script) { |
| 154 __block base::scoped_nsprotocol<id> executionResult; | 163 __block base::scoped_nsprotocol<id> executionResult; |
| 155 __block bool executionCompleted = false; | 164 __block bool executionCompleted = false; |
| 156 [webController_ executeJavaScript:script | 165 [GetWebController(web_state()) executeJavaScript:script |
| 157 completionHandler:^(id result, NSError*) { | 166 completionHandler:^(id result, NSError*) { |
| 158 executionResult.reset([result copy]); | 167 executionResult.reset([result copy]); |
| 159 executionCompleted = true; | 168 executionCompleted = true; |
| 160 }]; | 169 }]; |
| 161 base::test::ios::WaitUntilCondition(^{ | 170 base::test::ios::WaitUntilCondition(^{ |
| 162 return executionCompleted; | 171 return executionCompleted; |
| 163 }); | 172 }); |
| 164 return [[executionResult retain] autorelease]; | 173 return [[executionResult retain] autorelease]; |
| 165 } | 174 } |
| 166 | 175 |
| 167 web::WebState* WebTestWithWebState::web_state() { | 176 web::WebState* WebTestWithWebState::web_state() { |
| 168 return web_state_.get(); | 177 return web_state_.get(); |
| 169 } | 178 } |
| 170 | 179 |
| 171 const web::WebState* WebTestWithWebState::web_state() const { | 180 const web::WebState* WebTestWithWebState::web_state() const { |
| 172 return web_state_.get(); | 181 return web_state_.get(); |
| 173 } | 182 } |
| 174 | 183 |
| 175 bool WebTestWithWebState::ResetPageIfNavigationStalled(NSString* load_check) { | 184 bool WebTestWithWebState::ResetPageIfNavigationStalled(NSString* load_check) { |
| 176 NSString* inner_html = EvaluateJavaScriptAsString( | 185 NSString* inner_html = EvaluateJavaScriptAsString( |
| 177 @"(document && document.body && document.body.innerHTML) || 'undefined'"); | 186 @"(document && document.body && document.body.innerHTML) || 'undefined'"); |
| 178 if ([inner_html rangeOfString:load_check].location == NSNotFound) { | 187 if ([inner_html rangeOfString:load_check].location == NSNotFound) { |
| 179 web_state_->SetWebUsageEnabled(false); | 188 web_state_->SetWebUsageEnabled(false); |
| 180 web_state_->SetWebUsageEnabled(true); | 189 web_state_->SetWebUsageEnabled(true); |
| 181 [webController_ triggerPendingLoad]; | 190 [GetWebController(web_state()) triggerPendingLoad]; |
| 182 return true; | 191 return true; |
| 183 } | 192 } |
| 184 return false; | 193 return false; |
| 185 } | 194 } |
| 186 | 195 |
| 187 NSString* WebTestWithWebState::CreateLoadCheck() { | 196 NSString* WebTestWithWebState::CreateLoadCheck() { |
| 188 return [NSString stringWithFormat:@"<p style=\"display: none;\">%d</p>", | 197 return [NSString stringWithFormat:@"<p style=\"display: none;\">%d</p>", |
| 189 s_html_load_count++]; | 198 s_html_load_count++]; |
| 190 } | 199 } |
| 191 | 200 |
| 192 } // namespace web | 201 } // namespace web |
| OLD | NEW |