| 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
|
|
|