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

Side by Side 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: . 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/web_view/test_runner/test_runner_application_delegate.h"
6
7 #include <iostream>
8
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/files/scoped_temp_dir.h"
14 #include "base/location.h"
15 #include "base/path_service.h"
16 #include "base/thread_task_runner_handle.h"
17 #include "base/threading/thread_restrictions.h"
18 #include "components/view_manager/public/cpp/scoped_view_ptr.h"
19 #include "components/view_manager/public/cpp/view.h"
20 #include "components/view_manager/public/cpp/view_tree_connection.h"
21 #include "components/view_manager/public/cpp/view_tree_host_factory.h"
22 #include "mojo/application/public/cpp/application_connection.h"
23 #include "mojo/application/public/cpp/application_impl.h"
24 #include "mojo/converters/geometry/geometry_type_converters.h"
25 #include "mojo/services/network/public/interfaces/url_loader.mojom.h"
26 #include "net/base/filename_util.h"
27 #include "ui/gfx/geometry/rect.h"
28 #include "ui/gfx/geometry/size.h"
29 #include "url/gurl.h"
30
31 #if defined(OS_WIN)
32 #include "base/strings/sys_string_conversions.h"
33 #include "base/strings/utf_string_conversions.h"
34 #endif
35
36 namespace web_view {
37
38 namespace {
39
40 GURL GetURLForLayoutTest(const std::string& test_name,
41 base::FilePath* current_working_directory,
42 bool* enable_pixel_dumping,
43 std::string* expected_pixel_hash) {
44 // A test name is formated like file:///path/to/test'--pixel-test'pixelhash
45 std::string path_or_url = test_name;
46 std::string pixel_switch;
47 std::string pixel_hash;
48 std::string::size_type separator_position = path_or_url.find('\'');
49 if (separator_position != std::string::npos) {
50 pixel_switch = path_or_url.substr(separator_position + 1);
51 path_or_url.erase(separator_position);
52 }
53 separator_position = pixel_switch.find('\'');
54 if (separator_position != std::string::npos) {
55 pixel_hash = pixel_switch.substr(separator_position + 1);
56 pixel_switch.erase(separator_position);
57 }
58 if (enable_pixel_dumping) {
59 *enable_pixel_dumping =
60 (pixel_switch == "--pixel-test" || pixel_switch == "-p");
61 }
62 if (expected_pixel_hash)
63 *expected_pixel_hash = pixel_hash;
64
65 GURL test_url(path_or_url);
66 if (!(test_url.is_valid() && test_url.has_scheme())) {
67 // This is a test.
68 base::ThreadRestrictions::ScopedAllowIO allow_io;
69 #if defined(OS_WIN)
70 base::FilePath::StringType wide_path_or_url =
71 base::SysNativeMBToWide(path_or_url);
72 base::FilePath local_file(wide_path_or_url);
73 #else
74 base::FilePath local_file(path_or_url);
75 #endif
76 if (!base::PathExists(local_file)) {
77 base::FilePath base_path;
78 PathService::Get(base::DIR_SOURCE_ROOT, &base_path);
79 local_file = base_path.Append(FILE_PATH_LITERAL("third_party"))
80 .Append(FILE_PATH_LITERAL("WebKit"))
81 .Append(FILE_PATH_LITERAL("LayoutTests"))
82 .Append(local_file);
83 }
84 test_url = net::FilePathToFileURL(base::MakeAbsoluteFilePath(local_file));
85 }
86 base::FilePath local_path;
87 if (current_working_directory) {
88 // We're outside of the message loop here, and this is a test.
89 base::ThreadRestrictions::ScopedAllowIO allow_io;
90 if (net::FileURLToFilePath(test_url, &local_path))
91 *current_working_directory = local_path.DirName();
92 else
93 base::GetCurrentDirectory(current_working_directory);
94 }
95 return test_url;
96 }
97
98 bool GetNextTestURL(const base::CommandLine::StringVector& args,
99 size_t* position,
100 GURL* test_url) {
101 std::string test_string;
102 if (*position >= args.size())
103 return false;
104 if (args[*position] == FILE_PATH_LITERAL("-")) {
105 do {
106 bool success = !!std::getline(std::cin, test_string, '\n');
107 if (!success)
108 return false;
109 } while (test_string.empty());
110 } else {
111 #if defined(OS_WIN)
112 test_string = base::WideToUTF8(args[(*position)++]);
113 #else
114 test_string = args[(*position)++];
115 #endif
116 }
117
118 DCHECK(!test_string.empty());
119 if (test_string == "QUIT")
120 return false;
121 bool enable_pixel_dumps;
122 std::string pixel_hash;
123 base::FilePath cwd;
124 *test_url =
125 GetURLForLayoutTest(test_string, &cwd, &enable_pixel_dumps, &pixel_hash);
126 return true;
127 }
128
129 } // namespace
130
131 TestRunnerApplicationDelegate::TestRunnerApplicationDelegate()
132 : app_(nullptr),
133 root_(nullptr),
134 content_(nullptr),
135 web_view_(this),
136 web_view_inited_(false),
sky 2015/09/03 23:01:02 I would wrap web_view_ in a scoped_ptr and create
sadrul 2015/09/04 03:48:57 Agree. Done.
137 cmdline_position_(0) {}
sky 2015/09/03 23:01:02 0u
sadrul 2015/09/04 03:48:57 Done.
138
139 TestRunnerApplicationDelegate::~TestRunnerApplicationDelegate() {
140 if (root_)
141 mojo::ScopedViewPtr::DeleteViewOrViewManager(root_);
142 }
143
144 void TestRunnerApplicationDelegate::LaunchURL(const GURL& test_url) {
145 if (!web_view_inited_) {
146 web_view_.Init(app_, content_);
147 web_view_inited_ = true;
148 }
149 mojo::URLRequestPtr request(mojo::URLRequest::New());
150 request->url = test_url.spec();
151 web_view_.web_view()->LoadRequest(request.Pass());
152 }
153
154 void TestRunnerApplicationDelegate::Terminate() {
155 if (root_)
sky 2015/09/03 23:01:02 As the destructor also deals with root_, could you
sadrul 2015/09/04 03:48:57 Unfortunately not. As an mojo::ApplicationDelegate
156 mojo::ScopedViewPtr::DeleteViewOrViewManager(root_);
157 }
158
159 ////////////////////////////////////////////////////////////////////////////////
160 // mojo::ApplicationDelegate implementation:
161
162 void TestRunnerApplicationDelegate::Initialize(mojo::ApplicationImpl* app) {
163 app_ = app;
164 mojo::CreateSingleViewTreeHost(app_, this, &host_);
165 }
166
167 bool TestRunnerApplicationDelegate::ConfigureIncomingConnection(
168 mojo::ApplicationConnection* connection) {
169 connection->AddService<web_view::LayoutTestRunner>(this);
170 return true;
171 }
172
173 ////////////////////////////////////////////////////////////////////////////////
174 // mojo::ViewTreeDelegate implementation:
175
176 void TestRunnerApplicationDelegate::OnEmbed(mojo::View* root) {
177 root_ = root;
178 root_->connection()->SetEmbedRoot();
179
180 // If this is a sys-check, then terminate in the next cycle.
181 const char kCheckLayoutTestSysDeps[] = "check-layout-test-sys-deps";
182 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
183 kCheckLayoutTestSysDeps)) {
184 base::ThreadTaskRunnerHandle::Get()->PostTask(
185 FROM_HERE, base::Bind(&TestRunnerApplicationDelegate::Terminate,
186 base::Unretained(this)));
187 return;
188 }
189
190 const gfx::Size kViewportSize(800, 600);
191 host_->SetSize(mojo::Size::From(kViewportSize));
192
193 content_ = root_->connection()->CreateView();
194 root_->AddChild(content_);
195 content_->SetBounds(*mojo::Rect::From(gfx::Rect(kViewportSize)));
196 content_->SetVisible(true);
197
198 cmdline_args_ = base::CommandLine::ForCurrentProcess()->GetArgs();
199 std::cout << "#READY\n";
200 std::cout.flush();
201
202 cmdline_position_ = 0;
203 GURL test_url;
204 if (GetNextTestURL(cmdline_args_, &cmdline_position_, &test_url))
205 LaunchURL(test_url);
206 }
207
208 void TestRunnerApplicationDelegate::OnConnectionLost(
209 mojo::ViewTreeConnection* connection) {
210 root_ = nullptr;
211 app_->Quit();
212 }
213
214 ////////////////////////////////////////////////////////////////////////////////
215 // mojom::WebViewClient implementation:
216
217 void TestRunnerApplicationDelegate::TopLevelNavigate(
218 mojo::URLRequestPtr request) {
219 web_view_.web_view()->LoadRequest(request.Pass());
220 }
221
222 void TestRunnerApplicationDelegate::LoadingStateChanged(bool is_loading) {}
223 void TestRunnerApplicationDelegate::ProgressChanged(double progress) {}
224 void TestRunnerApplicationDelegate::TitleChanged(const mojo::String& title) {}
225
226 ////////////////////////////////////////////////////////////////////////////////
227 // LayoutTestRunner implementation:
228
229 void TestRunnerApplicationDelegate::TestFinished() {
230 std::cout << "#EOF\n";
231 std::cout.flush();
232
233 std::cerr << "#EOF\n";
234 std::cerr.flush();
235
236 GURL test_url;
237 if (GetNextTestURL(cmdline_args_, &cmdline_position_, &test_url))
238 LaunchURL(test_url);
239 else
240 Terminate();
241 }
242
243 ////////////////////////////////////////////////////////////////////////////////
244 // mojo::InterfaceFactory<LayoutTestRunner> implementation:
245
246 void TestRunnerApplicationDelegate::Create(
247 mojo::ApplicationConnection* connection,
248 mojo::InterfaceRequest<web_view::LayoutTestRunner> request) {
249 layout_test_runner_.AddBinding(this, request.Pass());
250 }
251
252 } // namespace web_view
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698