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 #import <WebKit/WebKit.h> | 7 #import <WebKit/WebKit.h> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/strings/sys_string_conversions.h" | 10 #include "base/strings/sys_string_conversions.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 void WebTestWithWebState::WillProcessTask( | 66 void WebTestWithWebState::WillProcessTask( |
67 const base::PendingTask& pending_task) { | 67 const base::PendingTask& pending_task) { |
68 // Nothing to do. | 68 // Nothing to do. |
69 } | 69 } |
70 | 70 |
71 void WebTestWithWebState::DidProcessTask( | 71 void WebTestWithWebState::DidProcessTask( |
72 const base::PendingTask& pending_task) { | 72 const base::PendingTask& pending_task) { |
73 processed_a_task_ = true; | 73 processed_a_task_ = true; |
74 } | 74 } |
75 | 75 |
| 76 void WebTestWithWebState::LoadHtml(NSString* html, const GURL& url) { |
| 77 ASSERT_FALSE(web_state()->IsLoading()); |
| 78 |
| 79 CRWWebController* web_controller = GetWebController(web_state()); |
| 80 [web_controller loadHTML:html forURL:url]; |
| 81 |
| 82 // Wait until the navigation is committed to update MIME type. |
| 83 ASSERT_EQ(LOAD_REQUESTED, web_controller.loadPhase); |
| 84 base::TimeDelta spin_delay = base::TimeDelta::FromMilliseconds(10); |
| 85 while (web_controller.loadPhase != PAGE_LOADING) |
| 86 base::test::ios::SpinRunLoopWithMaxDelay(spin_delay); |
| 87 |
| 88 // loadHTML:forURL: does not notify web view delegate about received response, |
| 89 // so web controller does not get a chance to properly update MIME type and it |
| 90 // should be set manually after navigation is committed but before WebState |
| 91 // signal load completion and clients will start checking if MIME type is in |
| 92 // fact HTML. |
| 93 [web_controller webStateImpl]->SetContentsMimeType("text/html"); |
| 94 |
| 95 // Wait until the page is loaded. |
| 96 ASSERT_EQ(PAGE_LOADING, web_controller.loadPhase); |
| 97 while (web_controller.loadPhase != PAGE_LOADED) |
| 98 base::test::ios::SpinRunLoopWithMaxDelay(spin_delay); |
| 99 |
| 100 // Wait until scripts execution becomes possible. |
| 101 base::test::ios::WaitUntilCondition(^bool { |
| 102 return [ExecuteJavaScript(@"0;") isEqual:@0]; |
| 103 }); |
| 104 } |
| 105 |
76 void WebTestWithWebState::LoadHtml(NSString* html) { | 106 void WebTestWithWebState::LoadHtml(NSString* html) { |
77 LoadHtml([html UTF8String]); | 107 GURL url("https://chromium.test/"); |
| 108 LoadHtml(html, url); |
78 } | 109 } |
79 | 110 |
80 void WebTestWithWebState::LoadHtml(const std::string& html) { | 111 void WebTestWithWebState::LoadHtml(const std::string& html) { |
81 NSString* load_check = CreateLoadCheck(); | 112 LoadHtml(base::SysUTF8ToNSString(html)); |
82 std::string marked_html = html + [load_check UTF8String]; | |
83 std::string encoded_html; | |
84 base::Base64Encode(marked_html, &encoded_html); | |
85 GURL url("data:text/html;charset=utf8;base64," + encoded_html); | |
86 LoadURL(url); | |
87 | |
88 if (ResetPageIfNavigationStalled(load_check)) { | |
89 LoadHtml(html); | |
90 } | |
91 } | |
92 | |
93 void WebTestWithWebState::LoadURL(const GURL& url) { | |
94 // First step is to ensure that the web controller has finished any previous | |
95 // page loads so the new load is not confused. | |
96 while ([GetWebController(web_state()) loadPhase] != PAGE_LOADED) | |
97 WaitForBackgroundTasks(); | |
98 id originalMockDelegate = | |
99 [OCMockObject niceMockForProtocol:@protocol(CRWWebDelegate)]; | |
100 id mockDelegate = | |
101 [[WebDelegateMock alloc] initWithRepresentedObject:originalMockDelegate]; | |
102 id existingDelegate = GetWebController(web_state()).delegate; | |
103 GetWebController(web_state()).delegate = mockDelegate; | |
104 | |
105 web::NavigationManagerImpl& navManager = | |
106 [GetWebController(web_state()) webStateImpl]->GetNavigationManagerImpl(); | |
107 navManager.InitializeSession(@"name", nil, NO, 0); | |
108 [navManager.GetSessionController() addPendingEntry:url | |
109 referrer:web::Referrer() | |
110 transition:ui::PAGE_TRANSITION_TYPED | |
111 rendererInitiated:NO]; | |
112 | |
113 [GetWebController(web_state()) loadCurrentURL]; | |
114 while ([GetWebController(web_state()) loadPhase] != PAGE_LOADED) | |
115 WaitForBackgroundTasks(); | |
116 GetWebController(web_state()).delegate = existingDelegate; | |
117 [web_state()->GetView() layoutIfNeeded]; | |
118 } | 113 } |
119 | 114 |
120 void WebTestWithWebState::WaitForBackgroundTasks() { | 115 void WebTestWithWebState::WaitForBackgroundTasks() { |
121 // Because tasks can add new tasks to either queue, the loop continues until | 116 // Because tasks can add new tasks to either queue, the loop continues until |
122 // the first pass where no activity is seen from either queue. | 117 // the first pass where no activity is seen from either queue. |
123 bool activitySeen = false; | 118 bool activitySeen = false; |
124 base::MessageLoop* messageLoop = base::MessageLoop::current(); | 119 base::MessageLoop* messageLoop = base::MessageLoop::current(); |
125 messageLoop->AddTaskObserver(this); | 120 messageLoop->AddTaskObserver(this); |
126 do { | 121 do { |
127 activitySeen = false; | 122 activitySeen = false; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 } | 165 } |
171 | 166 |
172 web::WebState* WebTestWithWebState::web_state() { | 167 web::WebState* WebTestWithWebState::web_state() { |
173 return web_state_.get(); | 168 return web_state_.get(); |
174 } | 169 } |
175 | 170 |
176 const web::WebState* WebTestWithWebState::web_state() const { | 171 const web::WebState* WebTestWithWebState::web_state() const { |
177 return web_state_.get(); | 172 return web_state_.get(); |
178 } | 173 } |
179 | 174 |
180 bool WebTestWithWebState::ResetPageIfNavigationStalled(NSString* load_check) { | |
181 id inner_html = ExecuteJavaScript( | |
182 @"(document && document.body && document.body.innerHTML) || 'undefined'"); | |
183 if (![inner_html rangeOfString:load_check].length) { | |
184 web_state_->SetWebUsageEnabled(false); | |
185 web_state_->SetWebUsageEnabled(true); | |
186 [GetWebController(web_state()) triggerPendingLoad]; | |
187 return true; | |
188 } | |
189 return false; | |
190 } | |
191 | |
192 NSString* WebTestWithWebState::CreateLoadCheck() { | 175 NSString* WebTestWithWebState::CreateLoadCheck() { |
193 return [NSString stringWithFormat:@"<p style=\"display: none;\">%d</p>", | 176 return [NSString stringWithFormat:@"<p style=\"display: none;\">%d</p>", |
194 s_html_load_count++]; | 177 s_html_load_count++]; |
195 } | 178 } |
196 | 179 |
197 } // namespace web | 180 } // namespace web |
OLD | NEW |