Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(465)

Side by Side Diff: headless/lib/headless_devtools_client_browsertest.cc

Issue 2119063002: Add commands to manage tabs and contexts to Browser Domain (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added a check to prevent Browser.closeContext from closing a context that is in use. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #include <memory> 5 #include <memory>
6 6
7 #include "base/json/json_reader.h"
7 #include "content/public/test/browser_test.h" 8 #include "content/public/test/browser_test.h"
9 #include "headless/public/domains/browser.h"
8 #include "headless/public/domains/network.h" 10 #include "headless/public/domains/network.h"
9 #include "headless/public/domains/page.h" 11 #include "headless/public/domains/page.h"
10 #include "headless/public/domains/runtime.h" 12 #include "headless/public/domains/runtime.h"
11 #include "headless/public/headless_browser.h" 13 #include "headless/public/headless_browser.h"
12 #include "headless/public/headless_devtools_client.h" 14 #include "headless/public/headless_devtools_client.h"
13 #include "headless/test/headless_browser_test.h" 15 #include "headless/test/headless_browser_test.h"
14 #include "testing/gtest/include/gtest/gtest.h" 16 #include "testing/gtest/include/gtest/gtest.h"
15 #include "url/gurl.h" 17 #include "url/gurl.h"
16 18
17 namespace headless { 19 namespace headless {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 167 }
166 168
167 void OnFrameStoppedLoading( 169 void OnFrameStoppedLoading(
168 const page::FrameStoppedLoadingParams& params) override { 170 const page::FrameStoppedLoadingParams& params) override {
169 FinishAsynchronousTest(); 171 FinishAsynchronousTest();
170 } 172 }
171 }; 173 };
172 174
173 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessDevToolsClientExperimentalTest); 175 HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessDevToolsClientExperimentalTest);
174 176
177 class BrowserDomainCreateAndDeletePageTest
178 : public HeadlessAsyncDevTooledBrowserTest,
179 public HeadlessBrowser::Observer {
180 void RunDevTooledTest() override {
181 EXPECT_TRUE(embedded_test_server()->Start());
182
183 EXPECT_EQ(1u, browser()->GetAllWebContents().size());
184
185 browser()->AddObserver(this);
186 devtools_client_->GetBrowser()->GetExperimental()->NewPage(
187 browser::NewPageParams::Builder()
188 .SetInitialUrl(embedded_test_server()->GetURL("/hello.html").spec())
189 .SetWidth(1)
190 .SetHeight(1)
191 .Build(),
192 base::Bind(&BrowserDomainCreateAndDeletePageTest::OnNewPageResult,
193 base::Unretained(this)));
194 }
195
196 void HeadlessWebContentsCreated(HeadlessWebContents* web_contents) override {
197 DCHECK(!web_contents2_);
198 web_contents2_ = web_contents;
199 }
200
201 void OnNewPageResult(std::unique_ptr<browser::NewPageResult> result) {
202 EXPECT_EQ(2u, browser()->GetAllWebContents().size());
203
204 devtools_client_->GetBrowser()->GetExperimental()->ClosePage(
205 browser::ClosePageParams::Builder()
206 .SetPageId(result->GetPageId())
207 .Build(),
208 base::Bind(&BrowserDomainCreateAndDeletePageTest::OnClosePageResult,
209 base::Unretained(this)));
210 }
211
212 void OnClosePageResult(std::unique_ptr<browser::ClosePageResult> result) {
213 EXPECT_TRUE(result->GetSuccess());
214 }
215
216 void HeadlessWebContentsDestroyed(
217 HeadlessWebContents* web_contents) override {
218 EXPECT_EQ(web_contents2_, web_contents);
219 EXPECT_EQ(1u, browser()->GetAllWebContents().size());
220 browser()->RemoveObserver(this);
221 FinishAsynchronousTest();
222 }
223
224 private:
225 HeadlessWebContents* web_contents2_ = nullptr;
226 };
227
228 HEADLESS_ASYNC_DEVTOOLED_TEST_F(BrowserDomainCreateAndDeletePageTest);
229
230 class BrowserDomainCloseContextFailsIfInUse
231 : public HeadlessAsyncDevTooledBrowserTest {
232 void RunDevTooledTest() override {
233 EXPECT_TRUE(embedded_test_server()->Start());
234
235 EXPECT_EQ(1u, browser()->GetAllWebContents().size());
236 devtools_client_->GetBrowser()->GetExperimental()->NewContext(
237 browser::NewContextParams::Builder().Build(),
238 base::Bind(&BrowserDomainCloseContextFailsIfInUse::OnContextCreated,
239 base::Unretained(this)));
240 }
241
242 void OnContextCreated(std::unique_ptr<browser::NewContextResult> result) {
243 context_id_ = result->GetContextId();
244
245 devtools_client_->GetBrowser()->GetExperimental()->NewPage(
246 browser::NewPageParams::Builder()
247 .SetInitialUrl(embedded_test_server()->GetURL("/hello.html").spec())
248 .SetContextId(context_id_)
249 .Build(),
250 base::Bind(&BrowserDomainCloseContextFailsIfInUse::OnNewPageResult,
251 base::Unretained(this)));
252 }
253
254 void OnNewPageResult(std::unique_ptr<browser::NewPageResult> result) {
255 page_id_ = result->GetPageId();
256
257 devtools_client_->GetBrowser()->GetExperimental()->CloseContext(
258 browser::CloseContextParams::Builder()
259 .SetContextId(context_id_)
260 .Build(),
261 base::Bind(&BrowserDomainCloseContextFailsIfInUse::OnCloseContextResult,
262 base::Unretained(this)));
263 }
264
265 void OnCloseContextResult(
266 std::unique_ptr<browser::CloseContextResult> result) {
267 EXPECT_FALSE(result->GetSuccess());
268
269 // Close the page and try again.
270 devtools_client_->GetBrowser()->GetExperimental()->ClosePage(
271 browser::ClosePageParams::Builder().SetPageId(page_id_).Build(),
272 base::Bind(&BrowserDomainCloseContextFailsIfInUse::OnClosePageResult,
273 base::Unretained(this)));
274 }
275
276 void OnClosePageResult(std::unique_ptr<browser::ClosePageResult> result) {
277 EXPECT_TRUE(result->GetSuccess());
278
279 devtools_client_->GetBrowser()->GetExperimental()->CloseContext(
280 browser::CloseContextParams::Builder()
281 .SetContextId(context_id_)
282 .Build(),
283 base::Bind(
284 &BrowserDomainCloseContextFailsIfInUse::OnCloseContextResult2,
285 base::Unretained(this)));
286 }
287
288 void OnCloseContextResult2(
289 std::unique_ptr<browser::CloseContextResult> result) {
290 EXPECT_TRUE(result->GetSuccess());
291 FinishAsynchronousTest();
292 }
293
294 private:
295 std::string context_id_;
296 std::string page_id_;
297 };
298
299 HEADLESS_ASYNC_DEVTOOLED_TEST_F(BrowserDomainCloseContextFailsIfInUse);
300
301 class BrowserDomainCreateTwoContexts : public HeadlessAsyncDevTooledBrowserTest,
302 public browser::ExperimentalObserver {
303 public:
304 void RunDevTooledTest() override {
305 EXPECT_TRUE(embedded_test_server()->Start());
306
307 devtools_client_->GetBrowser()->GetExperimental()->AddObserver(this);
308 devtools_client_->GetBrowser()->GetExperimental()->NewContext(
309 browser::NewContextParams::Builder().Build(),
310 base::Bind(&BrowserDomainCreateTwoContexts::OnContextOneCreated,
311 base::Unretained(this)));
312
313 devtools_client_->GetBrowser()->GetExperimental()->NewContext(
314 browser::NewContextParams::Builder().Build(),
315 base::Bind(&BrowserDomainCreateTwoContexts::OnContextTwoCreated,
316 base::Unretained(this)));
317 }
318
319 void OnContextOneCreated(std::unique_ptr<browser::NewContextResult> result) {
320 context_id_one_ = result->GetContextId();
321 MaybeCreatePages();
322 }
323
324 void OnContextTwoCreated(std::unique_ptr<browser::NewContextResult> result) {
325 context_id_two_ = result->GetContextId();
326 MaybeCreatePages();
327 }
328
329 void MaybeCreatePages() {
330 if (context_id_one_.empty() || context_id_two_.empty())
331 return;
332
333 devtools_client_->GetBrowser()->GetExperimental()->NewPage(
334 browser::NewPageParams::Builder()
335 .SetInitialUrl(embedded_test_server()->GetURL("/hello.html").spec())
336 .SetContextId(context_id_one_)
337 .Build(),
338 base::Bind(&BrowserDomainCreateTwoContexts::OnNewPageOneResult,
339 base::Unretained(this)));
340
341 devtools_client_->GetBrowser()->GetExperimental()->NewPage(
342 browser::NewPageParams::Builder()
343 .SetInitialUrl(embedded_test_server()->GetURL("/hello.html").spec())
344 .SetContextId(context_id_two_)
345 .Build(),
346 base::Bind(&BrowserDomainCreateTwoContexts::OnNewPageTwoResult,
347 base::Unretained(this)));
348 }
349
350 void OnNewPageOneResult(std::unique_ptr<browser::NewPageResult> result) {
351 page_id_one_ = result->GetPageId();
352 MaybeTestIsolation();
353 }
354
355 void OnNewPageTwoResult(std::unique_ptr<browser::NewPageResult> result) {
356 page_id_two_ = result->GetPageId();
357 MaybeTestIsolation();
358 }
359
360 void MaybeTestIsolation() {
361 if (page_id_one_.empty() || page_id_two_.empty())
362 return;
363
364 devtools_client_->GetBrowser()->GetExperimental()->Attach(
365 browser::AttachParams::Builder().SetTargetId(page_id_one_).Build(),
366 base::Bind(&BrowserDomainCreateTwoContexts::OnAttachedOne,
367 base::Unretained(this)));
368
369 devtools_client_->GetBrowser()->GetExperimental()->Attach(
370 browser::AttachParams::Builder().SetTargetId(page_id_two_).Build(),
371 base::Bind(&BrowserDomainCreateTwoContexts::OnAttachedTwo,
372 base::Unretained(this)));
373 }
374
375 void OnAttachedOne(std::unique_ptr<browser::AttachResult> result) {
376 devtools_client_->GetBrowser()->GetExperimental()->SendMessage(
377 browser::SendMessageParams::Builder()
378 .SetTargetId(page_id_one_)
379 .SetMessage("{\"id\":101, \"method\": \"Page.enable\"}")
380 .Build());
381 }
382
383 void OnAttachedTwo(std::unique_ptr<browser::AttachResult> result) {
384 devtools_client_->GetBrowser()->GetExperimental()->SendMessage(
385 browser::SendMessageParams::Builder()
386 .SetTargetId(page_id_two_)
387 .SetMessage("{\"id\":102, \"method\": \"Page.enable\"}")
388 .Build());
389 }
390
391 void MaybeSetCookieOnPageOne() {
392 if (!page_one_loaded_ || !page_two_loaded_)
393 return;
394
395 devtools_client_->GetBrowser()->GetExperimental()->SendMessage(
396 browser::SendMessageParams::Builder()
397 .SetTargetId(page_id_one_)
398 .SetMessage("{\"id\":201, \"method\": \"Runtime.evaluate\", "
399 "\"params\": {\"expression\": "
400 "\"document.cookie = 'foo=bar';\"}}")
401 .Build());
402 }
403
404 void OnDispatchMessage(
405 const browser::DispatchMessageParams& params) override {
406 std::unique_ptr<base::Value> message =
407 base::JSONReader::Read(params.GetMessage(), base::JSON_PARSE_RFC);
408 const base::DictionaryValue* message_dict;
409 if (!message || !message->GetAsDictionary(&message_dict)) {
410 return;
411 }
412 std::string method;
413 if (message_dict->GetString("method", &method) &&
414 method == "Page.loadEventFired") {
415 if (params.GetTargetId() == page_id_one_) {
416 page_one_loaded_ = true;
417 } else if (params.GetTargetId() == page_id_two_) {
418 page_two_loaded_ = true;
419 }
420 MaybeSetCookieOnPageOne();
421 return;
422 }
423 const base::DictionaryValue* result_dict;
424 if (message_dict->GetDictionary("result", &result_dict)) {
425 // There's a nested result. We want the inner one.
426 if (!result_dict->GetDictionary("result", &result_dict))
427 return;
428 std::string value;
429 if (params.GetTargetId() == page_id_one_) {
430 // TODO(alexclarke): Make some better bindings for Browser.sendMessage.
431 devtools_client_->GetBrowser()->GetExperimental()->SendMessage(
432 browser::SendMessageParams::Builder()
433 .SetTargetId(page_id_two_)
434 .SetMessage("{\"id\":202, \"method\": \"Runtime.evaluate\", "
435 "\"params\": {\"expression\": "
436 "\"document.cookie;\"}}")
437 .Build());
438 } else if (params.GetTargetId() == page_id_two_ &&
439 result_dict->GetString("value", &value)) {
440 EXPECT_EQ("", value) << "Page 2 should not share cookies from page one";
441
442 devtools_client_->GetBrowser()->GetExperimental()->ClosePage(
443 browser::ClosePageParams::Builder().SetPageId(page_id_one_).Build(),
444 base::Bind(&BrowserDomainCreateTwoContexts::OnClosePage,
445 base::Unretained(this)));
446
447 devtools_client_->GetBrowser()->GetExperimental()->ClosePage(
448 browser::ClosePageParams::Builder().SetPageId(page_id_two_).Build(),
449 base::Bind(&BrowserDomainCreateTwoContexts::OnClosePage,
450 base::Unretained(this)));
451
452 devtools_client_->GetBrowser()->GetExperimental()->RemoveObserver(this);
453 }
454 }
455 }
456
457 void OnClosePage(std::unique_ptr<browser::ClosePageResult> result) {
458 page_close_count_++;
459
460 if (page_close_count_ < 2)
461 return;
462
463 devtools_client_->GetBrowser()->GetExperimental()->CloseContext(
464 browser::CloseContextParams::Builder()
465 .SetContextId(context_id_one_)
466 .Build(),
467 base::Bind(&BrowserDomainCreateTwoContexts::OnCloseContext,
468 base::Unretained(this)));
469
470 devtools_client_->GetBrowser()->GetExperimental()->CloseContext(
471 browser::CloseContextParams::Builder()
472 .SetContextId(context_id_two_)
473 .Build(),
474 base::Bind(&BrowserDomainCreateTwoContexts::OnCloseContext,
475 base::Unretained(this)));
476 }
477
478 void OnCloseContext(std::unique_ptr<browser::CloseContextResult> result) {
479 EXPECT_TRUE(result->GetSuccess());
480 if (++context_closed_count_ < 2)
481 return;
482
483 FinishAsynchronousTest();
484 }
485
486 private:
487 std::string context_id_one_;
488 std::string context_id_two_;
489 std::string page_id_one_;
490 std::string page_id_two_;
491 bool page_one_loaded_ = false;
492 bool page_two_loaded_ = false;
493 int page_close_count_ = 0;
494 int context_closed_count_ = 0;
495 };
496
497 HEADLESS_ASYNC_DEVTOOLED_TEST_F(BrowserDomainCreateTwoContexts);
498
175 } // namespace headless 499 } // namespace headless
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698