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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: headless/lib/headless_devtools_client_browsertest.cc
diff --git a/headless/lib/headless_devtools_client_browsertest.cc b/headless/lib/headless_devtools_client_browsertest.cc
index 8b51fecac515e7b06cec68960f844c6c65ee38a5..78a675148e09a453f48cf921ca012b18f6449236 100644
--- a/headless/lib/headless_devtools_client_browsertest.cc
+++ b/headless/lib/headless_devtools_client_browsertest.cc
@@ -4,7 +4,9 @@
#include <memory>
+#include "base/json/json_reader.h"
#include "content/public/test/browser_test.h"
+#include "headless/public/domains/browser.h"
#include "headless/public/domains/network.h"
#include "headless/public/domains/page.h"
#include "headless/public/domains/runtime.h"
@@ -172,4 +174,326 @@ class HeadlessDevToolsClientExperimentalTest
HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessDevToolsClientExperimentalTest);
+class BrowserDomainCreateAndDeletePageTest
+ : public HeadlessAsyncDevTooledBrowserTest,
+ public HeadlessBrowser::Observer {
+ void RunDevTooledTest() override {
+ EXPECT_TRUE(embedded_test_server()->Start());
+
+ EXPECT_EQ(1u, browser()->GetAllWebContents().size());
+
+ browser()->AddObserver(this);
+ devtools_client_->GetBrowser()->GetExperimental()->NewPage(
+ browser::NewPageParams::Builder()
+ .SetInitialUrl(embedded_test_server()->GetURL("/hello.html").spec())
+ .SetWidth(1)
+ .SetHeight(1)
+ .Build(),
+ base::Bind(&BrowserDomainCreateAndDeletePageTest::OnNewPageResult,
+ base::Unretained(this)));
+ }
+
+ void HeadlessWebContentsCreated(HeadlessWebContents* web_contents) override {
+ DCHECK(!web_contents2_);
+ web_contents2_ = web_contents;
+ }
+
+ void OnNewPageResult(std::unique_ptr<browser::NewPageResult> result) {
+ EXPECT_EQ(2u, browser()->GetAllWebContents().size());
+
+ devtools_client_->GetBrowser()->GetExperimental()->ClosePage(
+ browser::ClosePageParams::Builder()
+ .SetPageId(result->GetPageId())
+ .Build(),
+ base::Bind(&BrowserDomainCreateAndDeletePageTest::OnClosePageResult,
+ base::Unretained(this)));
+ }
+
+ void OnClosePageResult(std::unique_ptr<browser::ClosePageResult> result) {
+ EXPECT_TRUE(result->GetSuccess());
+ }
+
+ void HeadlessWebContentsDestroyed(
+ HeadlessWebContents* web_contents) override {
+ EXPECT_EQ(web_contents2_, web_contents);
+ EXPECT_EQ(1u, browser()->GetAllWebContents().size());
+ browser()->RemoveObserver(this);
+ FinishAsynchronousTest();
+ }
+
+ private:
+ HeadlessWebContents* web_contents2_ = nullptr;
+};
+
+HEADLESS_ASYNC_DEVTOOLED_TEST_F(BrowserDomainCreateAndDeletePageTest);
+
+class BrowserDomainCloseContextFailsIfInUse
+ : public HeadlessAsyncDevTooledBrowserTest {
+ void RunDevTooledTest() override {
+ EXPECT_TRUE(embedded_test_server()->Start());
+
+ EXPECT_EQ(1u, browser()->GetAllWebContents().size());
+ devtools_client_->GetBrowser()->GetExperimental()->NewContext(
+ browser::NewContextParams::Builder().Build(),
+ base::Bind(&BrowserDomainCloseContextFailsIfInUse::OnContextCreated,
+ base::Unretained(this)));
+ }
+
+ void OnContextCreated(std::unique_ptr<browser::NewContextResult> result) {
+ context_id_ = result->GetContextId();
+
+ devtools_client_->GetBrowser()->GetExperimental()->NewPage(
+ browser::NewPageParams::Builder()
+ .SetInitialUrl(embedded_test_server()->GetURL("/hello.html").spec())
+ .SetContextId(context_id_)
+ .Build(),
+ base::Bind(&BrowserDomainCloseContextFailsIfInUse::OnNewPageResult,
+ base::Unretained(this)));
+ }
+
+ void OnNewPageResult(std::unique_ptr<browser::NewPageResult> result) {
+ page_id_ = result->GetPageId();
+
+ devtools_client_->GetBrowser()->GetExperimental()->CloseContext(
+ browser::CloseContextParams::Builder()
+ .SetContextId(context_id_)
+ .Build(),
+ base::Bind(&BrowserDomainCloseContextFailsIfInUse::OnCloseContextResult,
+ base::Unretained(this)));
+ }
+
+ void OnCloseContextResult(
+ std::unique_ptr<browser::CloseContextResult> result) {
+ EXPECT_FALSE(result->GetSuccess());
+
+ // Close the page and try again.
+ devtools_client_->GetBrowser()->GetExperimental()->ClosePage(
+ browser::ClosePageParams::Builder().SetPageId(page_id_).Build(),
+ base::Bind(&BrowserDomainCloseContextFailsIfInUse::OnClosePageResult,
+ base::Unretained(this)));
+ }
+
+ void OnClosePageResult(std::unique_ptr<browser::ClosePageResult> result) {
+ EXPECT_TRUE(result->GetSuccess());
+
+ devtools_client_->GetBrowser()->GetExperimental()->CloseContext(
+ browser::CloseContextParams::Builder()
+ .SetContextId(context_id_)
+ .Build(),
+ base::Bind(
+ &BrowserDomainCloseContextFailsIfInUse::OnCloseContextResult2,
+ base::Unretained(this)));
+ }
+
+ void OnCloseContextResult2(
+ std::unique_ptr<browser::CloseContextResult> result) {
+ EXPECT_TRUE(result->GetSuccess());
+ FinishAsynchronousTest();
+ }
+
+ private:
+ std::string context_id_;
+ std::string page_id_;
+};
+
+HEADLESS_ASYNC_DEVTOOLED_TEST_F(BrowserDomainCloseContextFailsIfInUse);
+
+class BrowserDomainCreateTwoContexts : public HeadlessAsyncDevTooledBrowserTest,
+ public browser::ExperimentalObserver {
+ public:
+ void RunDevTooledTest() override {
+ EXPECT_TRUE(embedded_test_server()->Start());
+
+ devtools_client_->GetBrowser()->GetExperimental()->AddObserver(this);
+ devtools_client_->GetBrowser()->GetExperimental()->NewContext(
+ browser::NewContextParams::Builder().Build(),
+ base::Bind(&BrowserDomainCreateTwoContexts::OnContextOneCreated,
+ base::Unretained(this)));
+
+ devtools_client_->GetBrowser()->GetExperimental()->NewContext(
+ browser::NewContextParams::Builder().Build(),
+ base::Bind(&BrowserDomainCreateTwoContexts::OnContextTwoCreated,
+ base::Unretained(this)));
+ }
+
+ void OnContextOneCreated(std::unique_ptr<browser::NewContextResult> result) {
+ context_id_one_ = result->GetContextId();
+ MaybeCreatePages();
+ }
+
+ void OnContextTwoCreated(std::unique_ptr<browser::NewContextResult> result) {
+ context_id_two_ = result->GetContextId();
+ MaybeCreatePages();
+ }
+
+ void MaybeCreatePages() {
+ if (context_id_one_.empty() || context_id_two_.empty())
+ return;
+
+ devtools_client_->GetBrowser()->GetExperimental()->NewPage(
+ browser::NewPageParams::Builder()
+ .SetInitialUrl(embedded_test_server()->GetURL("/hello.html").spec())
+ .SetContextId(context_id_one_)
+ .Build(),
+ base::Bind(&BrowserDomainCreateTwoContexts::OnNewPageOneResult,
+ base::Unretained(this)));
+
+ devtools_client_->GetBrowser()->GetExperimental()->NewPage(
+ browser::NewPageParams::Builder()
+ .SetInitialUrl(embedded_test_server()->GetURL("/hello.html").spec())
+ .SetContextId(context_id_two_)
+ .Build(),
+ base::Bind(&BrowserDomainCreateTwoContexts::OnNewPageTwoResult,
+ base::Unretained(this)));
+ }
+
+ void OnNewPageOneResult(std::unique_ptr<browser::NewPageResult> result) {
+ page_id_one_ = result->GetPageId();
+ MaybeTestIsolation();
+ }
+
+ void OnNewPageTwoResult(std::unique_ptr<browser::NewPageResult> result) {
+ page_id_two_ = result->GetPageId();
+ MaybeTestIsolation();
+ }
+
+ void MaybeTestIsolation() {
+ if (page_id_one_.empty() || page_id_two_.empty())
+ return;
+
+ devtools_client_->GetBrowser()->GetExperimental()->Attach(
+ browser::AttachParams::Builder().SetTargetId(page_id_one_).Build(),
+ base::Bind(&BrowserDomainCreateTwoContexts::OnAttachedOne,
+ base::Unretained(this)));
+
+ devtools_client_->GetBrowser()->GetExperimental()->Attach(
+ browser::AttachParams::Builder().SetTargetId(page_id_two_).Build(),
+ base::Bind(&BrowserDomainCreateTwoContexts::OnAttachedTwo,
+ base::Unretained(this)));
+ }
+
+ void OnAttachedOne(std::unique_ptr<browser::AttachResult> result) {
+ devtools_client_->GetBrowser()->GetExperimental()->SendMessage(
+ browser::SendMessageParams::Builder()
+ .SetTargetId(page_id_one_)
+ .SetMessage("{\"id\":101, \"method\": \"Page.enable\"}")
+ .Build());
+ }
+
+ void OnAttachedTwo(std::unique_ptr<browser::AttachResult> result) {
+ devtools_client_->GetBrowser()->GetExperimental()->SendMessage(
+ browser::SendMessageParams::Builder()
+ .SetTargetId(page_id_two_)
+ .SetMessage("{\"id\":102, \"method\": \"Page.enable\"}")
+ .Build());
+ }
+
+ void MaybeSetCookieOnPageOne() {
+ if (!page_one_loaded_ || !page_two_loaded_)
+ return;
+
+ devtools_client_->GetBrowser()->GetExperimental()->SendMessage(
+ browser::SendMessageParams::Builder()
+ .SetTargetId(page_id_one_)
+ .SetMessage("{\"id\":201, \"method\": \"Runtime.evaluate\", "
+ "\"params\": {\"expression\": "
+ "\"document.cookie = 'foo=bar';\"}}")
+ .Build());
+ }
+
+ void OnDispatchMessage(
+ const browser::DispatchMessageParams& params) override {
+ std::unique_ptr<base::Value> message =
+ base::JSONReader::Read(params.GetMessage(), base::JSON_PARSE_RFC);
+ const base::DictionaryValue* message_dict;
+ if (!message || !message->GetAsDictionary(&message_dict)) {
+ return;
+ }
+ std::string method;
+ if (message_dict->GetString("method", &method) &&
+ method == "Page.loadEventFired") {
+ if (params.GetTargetId() == page_id_one_) {
+ page_one_loaded_ = true;
+ } else if (params.GetTargetId() == page_id_two_) {
+ page_two_loaded_ = true;
+ }
+ MaybeSetCookieOnPageOne();
+ return;
+ }
+ const base::DictionaryValue* result_dict;
+ if (message_dict->GetDictionary("result", &result_dict)) {
+ // There's a nested result. We want the inner one.
+ if (!result_dict->GetDictionary("result", &result_dict))
+ return;
+ std::string value;
+ if (params.GetTargetId() == page_id_one_) {
+ // TODO(alexclarke): Make some better bindings for Browser.sendMessage.
+ devtools_client_->GetBrowser()->GetExperimental()->SendMessage(
+ browser::SendMessageParams::Builder()
+ .SetTargetId(page_id_two_)
+ .SetMessage("{\"id\":202, \"method\": \"Runtime.evaluate\", "
+ "\"params\": {\"expression\": "
+ "\"document.cookie;\"}}")
+ .Build());
+ } else if (params.GetTargetId() == page_id_two_ &&
+ result_dict->GetString("value", &value)) {
+ EXPECT_EQ("", value) << "Page 2 should not share cookies from page one";
+
+ devtools_client_->GetBrowser()->GetExperimental()->ClosePage(
+ browser::ClosePageParams::Builder().SetPageId(page_id_one_).Build(),
+ base::Bind(&BrowserDomainCreateTwoContexts::OnClosePage,
+ base::Unretained(this)));
+
+ devtools_client_->GetBrowser()->GetExperimental()->ClosePage(
+ browser::ClosePageParams::Builder().SetPageId(page_id_two_).Build(),
+ base::Bind(&BrowserDomainCreateTwoContexts::OnClosePage,
+ base::Unretained(this)));
+
+ devtools_client_->GetBrowser()->GetExperimental()->RemoveObserver(this);
+ }
+ }
+ }
+
+ void OnClosePage(std::unique_ptr<browser::ClosePageResult> result) {
+ page_close_count_++;
+
+ if (page_close_count_ < 2)
+ return;
+
+ devtools_client_->GetBrowser()->GetExperimental()->CloseContext(
+ browser::CloseContextParams::Builder()
+ .SetContextId(context_id_one_)
+ .Build(),
+ base::Bind(&BrowserDomainCreateTwoContexts::OnCloseContext,
+ base::Unretained(this)));
+
+ devtools_client_->GetBrowser()->GetExperimental()->CloseContext(
+ browser::CloseContextParams::Builder()
+ .SetContextId(context_id_two_)
+ .Build(),
+ base::Bind(&BrowserDomainCreateTwoContexts::OnCloseContext,
+ base::Unretained(this)));
+ }
+
+ void OnCloseContext(std::unique_ptr<browser::CloseContextResult> result) {
+ EXPECT_TRUE(result->GetSuccess());
+ if (++context_closed_count_ < 2)
+ return;
+
+ FinishAsynchronousTest();
+ }
+
+ private:
+ std::string context_id_one_;
+ std::string context_id_two_;
+ std::string page_id_one_;
+ std::string page_id_two_;
+ bool page_one_loaded_ = false;
+ bool page_two_loaded_ = false;
+ int page_close_count_ = 0;
+ int context_closed_count_ = 0;
+};
+
+HEADLESS_ASYNC_DEVTOOLED_TEST_F(BrowserDomainCreateTwoContexts);
+
} // namespace headless

Powered by Google App Engine
This is Rietveld 408576698