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

Unified Diff: components/web_view/test_runner/test_runner_application_delegate.cc

Issue 1308973005: html_viewer/web_view: An app for running layout-tests. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: tot/merge Created 5 years, 3 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: components/web_view/test_runner/test_runner_application_delegate.cc
diff --git a/components/web_view/test_runner/test_runner_application_delegate.cc b/components/web_view/test_runner/test_runner_application_delegate.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ca8cb45241caf5e3946a356b3aae799584e75d8c
--- /dev/null
+++ b/components/web_view/test_runner/test_runner_application_delegate.cc
@@ -0,0 +1,250 @@
+// Copyright 2015 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 "components/web_view/test_runner/test_runner_application_delegate.h"
+
+#include <iostream>
+
+#include "base/bind.h"
+#include "base/command_line.h"
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/location.h"
+#include "base/path_service.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/threading/thread_restrictions.h"
+#include "components/view_manager/public/cpp/scoped_view_ptr.h"
+#include "components/view_manager/public/cpp/view.h"
+#include "components/view_manager/public/cpp/view_tree_connection.h"
+#include "components/view_manager/public/cpp/view_tree_host_factory.h"
+#include "mojo/application/public/cpp/application_connection.h"
+#include "mojo/application/public/cpp/application_impl.h"
+#include "mojo/converters/geometry/geometry_type_converters.h"
+#include "mojo/services/network/public/interfaces/url_loader.mojom.h"
+#include "net/base/filename_util.h"
+#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
+#include "url/gurl.h"
+
+#if defined(OS_WIN)
+#include "base/strings/sys_string_conversions.h"
+#include "base/strings/utf_string_conversions.h"
+#endif
+
+namespace web_view {
+
+namespace {
+
+GURL GetURLForLayoutTest(const std::string& test_name,
+ base::FilePath* current_working_directory,
+ bool* enable_pixel_dumping,
+ std::string* expected_pixel_hash) {
+ // A test name is formated like file:///path/to/test'--pixel-test'pixelhash
+ std::string path_or_url = test_name;
+ std::string pixel_switch;
+ std::string pixel_hash;
+ std::string::size_type separator_position = path_or_url.find('\'');
+ if (separator_position != std::string::npos) {
+ pixel_switch = path_or_url.substr(separator_position + 1);
+ path_or_url.erase(separator_position);
+ }
+ separator_position = pixel_switch.find('\'');
+ if (separator_position != std::string::npos) {
+ pixel_hash = pixel_switch.substr(separator_position + 1);
+ pixel_switch.erase(separator_position);
+ }
+ if (enable_pixel_dumping) {
+ *enable_pixel_dumping =
+ (pixel_switch == "--pixel-test" || pixel_switch == "-p");
+ }
+ if (expected_pixel_hash)
+ *expected_pixel_hash = pixel_hash;
+
+ GURL test_url(path_or_url);
+ if (!(test_url.is_valid() && test_url.has_scheme())) {
+ // This is a test.
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+#if defined(OS_WIN)
+ base::FilePath::StringType wide_path_or_url =
+ base::SysNativeMBToWide(path_or_url);
+ base::FilePath local_file(wide_path_or_url);
+#else
+ base::FilePath local_file(path_or_url);
+#endif
+ if (!base::PathExists(local_file)) {
+ base::FilePath base_path;
+ PathService::Get(base::DIR_SOURCE_ROOT, &base_path);
+ local_file = base_path.Append(FILE_PATH_LITERAL("third_party"))
+ .Append(FILE_PATH_LITERAL("WebKit"))
+ .Append(FILE_PATH_LITERAL("LayoutTests"))
+ .Append(local_file);
+ }
+ test_url = net::FilePathToFileURL(base::MakeAbsoluteFilePath(local_file));
+ }
+ base::FilePath local_path;
+ if (current_working_directory) {
+ // We're outside of the message loop here, and this is a test.
+ base::ThreadRestrictions::ScopedAllowIO allow_io;
+ if (net::FileURLToFilePath(test_url, &local_path))
+ *current_working_directory = local_path.DirName();
+ else
+ base::GetCurrentDirectory(current_working_directory);
+ }
+ return test_url;
+}
+
+bool GetNextTestURL(const base::CommandLine::StringVector& args,
+ size_t* position,
+ GURL* test_url) {
+ std::string test_string;
+ if (*position >= args.size())
+ return false;
+ if (args[*position] == FILE_PATH_LITERAL("-")) {
+ do {
+ bool success = !!std::getline(std::cin, test_string, '\n');
+ if (!success)
+ return false;
+ } while (test_string.empty());
+ } else {
+#if defined(OS_WIN)
+ test_string = base::WideToUTF8(args[(*position)++]);
+#else
+ test_string = args[(*position)++];
+#endif
+ }
+
+ DCHECK(!test_string.empty());
+ if (test_string == "QUIT")
+ return false;
+ bool enable_pixel_dumps;
+ std::string pixel_hash;
+ base::FilePath cwd;
+ *test_url =
+ GetURLForLayoutTest(test_string, &cwd, &enable_pixel_dumps, &pixel_hash);
+ return true;
+}
+
+} // namespace
+
+TestRunnerApplicationDelegate::TestRunnerApplicationDelegate()
+ : app_(nullptr),
+ root_(nullptr),
+ content_(nullptr),
+ cmdline_position_(0u) {}
+
+TestRunnerApplicationDelegate::~TestRunnerApplicationDelegate() {
+ if (root_)
+ mojo::ScopedViewPtr::DeleteViewOrViewManager(root_);
+}
+
+void TestRunnerApplicationDelegate::LaunchURL(const GURL& test_url) {
+ if (!web_view_) {
+ content_->SetAccessPolicy(mojo::ViewTree::ACCESS_POLICY_EMBED_ROOT);
+ web_view_.reset(new WebView(this));
+ web_view_->Init(app_, content_);
+ }
+ mojo::URLRequestPtr request(mojo::URLRequest::New());
+ request->url = test_url.spec();
+ web_view_->web_view()->LoadRequest(request.Pass());
+}
+
+void TestRunnerApplicationDelegate::Terminate() {
+ if (root_)
+ mojo::ScopedViewPtr::DeleteViewOrViewManager(root_);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// mojo::ApplicationDelegate implementation:
+
+void TestRunnerApplicationDelegate::Initialize(mojo::ApplicationImpl* app) {
+ app_ = app;
+ mojo::CreateSingleViewTreeHost(app_, this, &host_);
+}
+
+bool TestRunnerApplicationDelegate::ConfigureIncomingConnection(
+ mojo::ApplicationConnection* connection) {
+ connection->AddService<web_view::LayoutTestRunner>(this);
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// mojo::ViewTreeDelegate implementation:
+
+void TestRunnerApplicationDelegate::OnEmbed(mojo::View* root) {
+ root_ = root;
+
+ // If this is a sys-check, then terminate in the next cycle.
+ const char kCheckLayoutTestSysDeps[] = "check-layout-test-sys-deps";
+ if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+ kCheckLayoutTestSysDeps)) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::Bind(&TestRunnerApplicationDelegate::Terminate,
+ base::Unretained(this)));
+ return;
+ }
+
+ const gfx::Size kViewportSize(800, 600);
+ host_->SetSize(mojo::Size::From(kViewportSize));
+
+ content_ = root_->connection()->CreateView();
+ root_->AddChild(content_);
+ content_->SetBounds(*mojo::Rect::From(gfx::Rect(kViewportSize)));
+ content_->SetVisible(true);
+
+ cmdline_args_ = base::CommandLine::ForCurrentProcess()->GetArgs();
+ std::cout << "#READY\n";
+ std::cout.flush();
+
+ cmdline_position_ = 0;
+ GURL test_url;
+ if (GetNextTestURL(cmdline_args_, &cmdline_position_, &test_url))
+ LaunchURL(test_url);
+}
+
+void TestRunnerApplicationDelegate::OnConnectionLost(
+ mojo::ViewTreeConnection* connection) {
+ root_ = nullptr;
+ app_->Quit();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// mojom::WebViewClient implementation:
+
+void TestRunnerApplicationDelegate::TopLevelNavigate(
+ mojo::URLRequestPtr request) {
+ web_view_->web_view()->LoadRequest(request.Pass());
+}
+
+void TestRunnerApplicationDelegate::LoadingStateChanged(bool is_loading) {}
+void TestRunnerApplicationDelegate::ProgressChanged(double progress) {}
+void TestRunnerApplicationDelegate::TitleChanged(const mojo::String& title) {}
+
+////////////////////////////////////////////////////////////////////////////////
+// LayoutTestRunner implementation:
+
+void TestRunnerApplicationDelegate::TestFinished() {
+ std::cout << "#EOF\n";
+ std::cout.flush();
+
+ std::cerr << "#EOF\n";
+ std::cerr.flush();
+
+ GURL test_url;
+ if (GetNextTestURL(cmdline_args_, &cmdline_position_, &test_url))
+ LaunchURL(test_url);
+ else
+ Terminate();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// mojo::InterfaceFactory<LayoutTestRunner> implementation:
+
+void TestRunnerApplicationDelegate::Create(
+ mojo::ApplicationConnection* connection,
+ mojo::InterfaceRequest<web_view::LayoutTestRunner> request) {
+ layout_test_runner_.AddBinding(this, request.Pass());
+}
+
+} // namespace web_view

Powered by Google App Engine
This is Rietveld 408576698