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

Unified Diff: headless/lib/embedder_mojo_browsertest.cc

Issue 2049363003: Adds support for headless chrome embedder mojo services (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added a comment Created 4 years, 6 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/embedder_mojo_browsertest.cc
diff --git a/headless/lib/embedder_mojo_browsertest.cc b/headless/lib/embedder_mojo_browsertest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3346ba6e395fa03ae060853be9b77348fd14ee37
--- /dev/null
+++ b/headless/lib/embedder_mojo_browsertest.cc
@@ -0,0 +1,199 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include "base/path_service.h"
+#include "content/public/test/browser_test.h"
+#include "headless/lib/embedder_test.mojom.h"
+#include "headless/public/domains/page.h"
+#include "headless/public/domains/runtime.h"
+#include "headless/public/headless_browser.h"
+#include "headless/public/headless_devtools_client.h"
+#include "headless/public/headless_devtools_target.h"
+#include "headless/public/headless_web_contents.h"
+#include "headless/test/headless_browser_test.h"
+#include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/interface_ptr_set.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace headless {
+
+namespace {
+bool GetBuildDirectory(base::FilePath* result) {
+ if (!base::PathService::Get(base::DIR_EXE, result))
+ return false;
+
+#if defined(OS_MACOSX)
Sami 2016/06/10 10:27:39 Let's leave this out until we actually support mac
alex clarke (OOO till 29th) 2016/06/11 20:51:50 Done.
+ if (base::mac::AmIBundled()) {
+ // The bundled app executables (Chromium, TestShell, etc) live three
+ // levels down from the build directory, eg:
+ // Chromium.app/Contents/MacOS/Chromium
+ *result = result->DirName().DirName().DirName();
+ }
+#endif
+ return true;
+}
+} // namespace
+
+#define DEVTOOLS_CLIENT_TEST_F(TEST_FIXTURE_NAME) \
+ IN_PROC_BROWSER_TEST_F(TEST_FIXTURE_NAME, RunAsyncTest) { RunTest(); } \
+ class AsyncHeadlessBrowserTestNeedsSemicolon##TEST_FIXTURE_NAME {}
+
+// A test fixture which attaches a devtools client before starting the test.
+class EmbedderMojoTest : public HeadlessBrowserTest,
Sami 2016/06/10 10:27:39 Would it simplify things to subclass HeadlessAsync
alex clarke (OOO till 29th) 2016/06/11 20:51:50 This has got a lot simpler and I'm not sure that's
+ public HeadlessWebContents::Observer,
+ public page::Observer,
+ public embedder_test::TestEmbedderService {
+ public:
+ EmbedderMojoTest()
+ : web_contents_(nullptr),
+ devtools_client_(HeadlessDevToolsClient::Create()),
+ processed_page_ready_(false) {}
+ ~EmbedderMojoTest() override {}
+
+ // HeadlessWebContentsObserver implementation:
+ void DevToolsTargetReady() override {
Sami 2016/06/10 10:27:38 nit: Could you move these into chronological order
alex clarke (OOO till 29th) 2016/06/11 20:51:50 Most of these methods have gone.
+ EXPECT_TRUE(web_contents_->GetDevToolsTarget());
+ web_contents_->GetDevToolsTarget()->AttachClient(devtools_client_.get());
+
+ devtools_client_->GetPage()->AddObserver(this);
+ devtools_client_->GetPage()->Enable();
+
+ // Check if the page has reached the ready state.
+ devtools_client_->GetRuntime()->Evaluate(
+ "document.readyState",
+ base::Bind(&EmbedderMojoTest::OnReadyState, base::Unretained(this)));
+ }
+
+ virtual void RunMojoTest() = 0;
+
+ protected:
+ void RunTest() {
+ // The browser main thread does not have IO permissions so we need to ask
+ // another thread to load the mojo js bindings.
+ browser()->BrowserFileThread()->PostTask(
+ FROM_HERE,
+ base::Bind(&EmbedderMojoTest::LoadMojoJsBindingOnBrowserFileThread,
+ base::Unretained(this)));
+
+ RunAsynchronousTest();
+
+ web_contents_->GetDevToolsTarget()->DetachClient(devtools_client_.get());
+ web_contents_->RemoveObserver(this);
+ web_contents_->Close();
+ web_contents_ = nullptr;
+ }
+
+ void LoadMojoJsBindingOnBrowserFileThread() {
+ base::FilePath mojo_bindings_path;
+ ASSERT_TRUE(GetBuildDirectory(&mojo_bindings_path));
+ mojo_bindings_path = mojo_bindings_path.AppendASCII(
+ "gen/headless/lib/embedder_test.mojom.js");
+
+ ASSERT_TRUE(ReadFileToString(mojo_bindings_path, &mojo_js_binding_));
+
+ browser()->BrowserMainThread()->PostTask(
+ FROM_HERE,
+ base::Bind(&EmbedderMojoTest::CreateWebContentsOnBrowserMainThread,
+ base::Unretained(this)));
+ }
+
+ void CreateWebContentsOnBrowserMainThread() {
+ web_contents_ =
+ browser()
+ ->CreateWebContentsBuilder()
+ .AddEmbedderMojoService(
+ base::Bind(&EmbedderMojoTest::CreateTestEmbedderMojoService,
+ base::Unretained(this)),
+ mojo_js_binding_)
+ .Build();
+
+ web_contents_->AddObserver(this);
+ }
+
+ void CreateTestEmbedderMojoService(
+ mojo::InterfaceRequest<embedder_test::TestEmbedderService> request) {
+ test_embedder_mojo_bindings_.AddBinding(this, std::move(request));
+ }
+
+ void OnReadyState(std::unique_ptr<runtime::EvaluateResult> result) {
+ std::string ready_state;
+ if (result->GetResult()->GetValue()->GetAsString(&ready_state) &&
+ ready_state == "complete") {
+ OnPageReady();
+ return;
+ }
+ }
+
+ // page::Observer implementation:
+ void OnLoadEventFired(const page::LoadEventFiredParams& params) override {
+ OnPageReady();
+ }
+
+ void OnPageReady() {
+ if (processed_page_ready_)
+ return;
+ processed_page_ready_ = true;
+ RunMojoTest();
+ }
+
+ HeadlessWebContents* web_contents_;
+ std::unique_ptr<HeadlessDevToolsClient> devtools_client_;
+
+ mojo::BindingSet<embedder_test::TestEmbedderService>
+ test_embedder_mojo_bindings_;
+ std::string mojo_js_binding_;
+ bool processed_page_ready_;
+};
+
+class EmbedderMojoBindingsTest : public EmbedderMojoTest {
+ public:
+ void RunMojoTest() override {
+ devtools_client_->GetRuntime()->Evaluate(
+ R"(
+ (function() {
+ // Note define() is the the mojo module dependency system.
+ define([
+ "headless/lib/embedder_test.mojom",
+ "mojo/public/js/core",
+ "mojo/public/js/router",
+ "content/public/renderer/frame_service_registry",
+ ], function(embedderMojom, mojoCore, routerModule,
+ serviceProvider) {
+ var testEmbedderService =
+ new embedderMojom.TestEmbedderService.proxyClass(
+ new routerModule.Router(
+ serviceProvider.connectToService(
+ embedderMojom.TestEmbedderService.name)));
+
+ // Send a message to the embedder!
+ testEmbedderService.returnTestResult("hello world");
+ });
+ })(); )",
+ base::Bind(&EmbedderMojoBindingsTest::OnEvalResult,
+ base::Unretained(this)));
+ }
+
+ void OnEvalResult(std::unique_ptr<runtime::EvaluateResult> result) {
+ EXPECT_FALSE(result->HasExceptionDetails())
+ << "JS exception: " << result->GetExceptionDetails()->GetText();
+ if (result->HasExceptionDetails()) {
+ FinishAsynchronousTest();
+ }
+ }
+
+ // embedder_test::TestEmbedderService:
+ void ReturnTestResult(const mojo::String& result) override {
+ EXPECT_EQ("hello world", result.get());
+ FinishAsynchronousTest();
+ }
+};
+
+DEVTOOLS_CLIENT_TEST_F(EmbedderMojoBindingsTest);
+
+} // namespace headless

Powered by Google App Engine
This is Rietveld 408576698