summaryrefslogtreecommitdiffstats
path: root/components
diff options
context:
space:
mode:
authorlukasza <lukasza@chromium.org>2016-01-27 14:27:33 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-27 22:28:39 +0000
commita8960461e06e8478f79fde21531e237443b5629f (patch)
tree60f46222cbfafbfe70910d87304adb4ff43e9592 /components
parentdfd23e822ec821850cabeac8b0e372c08fe0a113 (diff)
downloadchromium_src-a8960461e06e8478f79fde21531e237443b5629f.zip
chromium_src-a8960461e06e8478f79fde21531e237443b5629f.tar.gz
chromium_src-a8960461e06e8478f79fde21531e237443b5629f.tar.bz2
OOPIF support for testRunner.dumpAsText and similar layout dumps.
Layout Tests dump page contents (to compare against expected results). The dump can include frame contents (i.e. dump as text, dump as markup, dump scroll positions with extra flavors like dump as printed, dump line box trees, etc.). Since renderer process is (for security / by design) not able to see frame contents of remote frames, it means that old Layout Tests code is not able to dump frame contents when site isolation is enabled (i.e. when running with --additional-drt-flag=--site-per-process). This CL is a step toward making layout tests compatible with site isolation. After this CL, if recursing over all frames is required, then BlinkTestRunner::CaptureDump will ask the browser process for stiching together the frame contents, before continuing with the other dump flavors in BlinkTestRunner::OnLayoutDumpCompleted. The above means testRunner.notifyDone() might no longer perform dumps synchronously. This is okay, because: - The dumps were already performed asynchronously in some cases: - pixel dumps (i.e. see how dumping is resumed after BlinkTestRunner::CaptureDumpPixels aka OnPixelsDumpCompleted), - ShouldDumpBackForwardList (i.e. see how dumping is resumed after BlinkTestRunner::OnSessionHistory), - the case where notifyDone is called from a secondary window (i.e. see how BlinkTestRunner::TestFinished asks the browser to continue in the main window). - The synchronous dumps are still performed if the test didn't ask for recursing over all the frames. Retaining the synchronous behavior in this case is needed, because in some tests the dump is captured while the frame is being detached (and would no longer be present after an extra hop to the browser process). This CL doesn't affect the following dump modes (which for now remain potentially incompatible with OOPIFs): dump as audio, dump as custom text, dump pixels, dump back/forward list). Additionally, setting and reading of dump modes is done in a renderer process (which can be incompatible with OOPIFs when testRunner.dumpAsText() and testRunner.notifyDone() are called in cross-site frames running in different renderer processes). BUG=477150 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1589643003 Cr-Commit-Position: refs/heads/master@{#371896}
Diffstat (limited to 'components')
-rw-r--r--components/test_runner/BUILD.gn3
-rw-r--r--components/test_runner/layout_dump.cc98
-rw-r--r--components/test_runner/layout_dump.h24
-rw-r--r--components/test_runner/layout_dump_flags.h27
-rw-r--r--components/test_runner/test_runner.cc30
-rw-r--r--components/test_runner/test_runner.gyp3
-rw-r--r--components/test_runner/test_runner.h2
-rw-r--r--components/test_runner/web_test_proxy.cc122
-rw-r--r--components/test_runner/web_test_proxy.h1
-rw-r--r--components/test_runner/web_test_runner.h12
10 files changed, 215 insertions, 107 deletions
diff --git a/components/test_runner/BUILD.gn b/components/test_runner/BUILD.gn
index 7639406..577c04e 100644
--- a/components/test_runner/BUILD.gn
+++ b/components/test_runner/BUILD.gn
@@ -29,6 +29,9 @@ component("test_runner") {
"gamepad_controller.h",
"gc_controller.cc",
"gc_controller.h",
+ "layout_dump.cc",
+ "layout_dump.h",
+ "layout_dump_flags.h",
"mock_color_chooser.cc",
"mock_color_chooser.h",
"mock_credential_manager_client.cc",
diff --git a/components/test_runner/layout_dump.cc b/components/test_runner/layout_dump.cc
new file mode 100644
index 0000000..9fc7f18
--- /dev/null
+++ b/components/test_runner/layout_dump.cc
@@ -0,0 +1,98 @@
+// 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 "components/test_runner/layout_dump.h"
+
+#include "base/logging.h"
+#include "base/strings/stringprintf.h"
+#include "third_party/WebKit/public/platform/WebSize.h"
+#include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/web/WebDocument.h"
+#include "third_party/WebKit/public/web/WebElement.h"
+#include "third_party/WebKit/public/web/WebFrame.h"
+#include "third_party/WebKit/public/web/WebLocalFrame.h"
+
+namespace test_runner {
+
+using blink::WebFrame;
+using blink::WebLocalFrame;
+using blink::WebSize;
+
+namespace {
+
+std::string DumpFrameHeaderIfNeeded(WebFrame* frame) {
+ std::string result;
+
+ // Add header for all but the main frame. Skip empty frames.
+ if (frame->parent() && !frame->document().documentElement().isNull()) {
+ result.append("\n--------\nFrame: '");
+ result.append(frame->uniqueName().utf8());
+ result.append("'\n--------\n");
+ }
+
+ return result;
+}
+
+std::string DumpFrameScrollPosition(WebFrame* frame) {
+ std::string result;
+ WebSize offset = frame->scrollOffset();
+ if (offset.width > 0 || offset.height > 0) {
+ if (frame->parent()) {
+ result =
+ std::string("frame '") + frame->uniqueName().utf8().data() + "' ";
+ }
+ base::StringAppendF(&result, "scrolled to %d,%d\n", offset.width,
+ offset.height);
+ }
+
+ return result;
+}
+
+} // namespace
+
+std::string DumpLayout(WebLocalFrame* frame, const LayoutDumpFlags& flags) {
+ DCHECK(frame);
+ std::string result;
+
+ switch (flags.main_dump_mode) {
+ case LayoutDumpMode::DUMP_AS_TEXT:
+ result = DumpFrameHeaderIfNeeded(frame);
+ if (flags.dump_as_printed && frame->document().isHTMLDocument()) {
+ result +=
+ frame->layoutTreeAsText(WebFrame::LayoutAsTextPrinting).utf8();
+ } else {
+ result += frame->document().contentAsTextForTesting().utf8();
+ }
+ result += "\n";
+ break;
+ case LayoutDumpMode::DUMP_AS_MARKUP:
+ DCHECK(!flags.dump_as_printed);
+ result = DumpFrameHeaderIfNeeded(frame);
+ result += frame->contentAsMarkup().utf8();
+ result += "\n";
+ break;
+ case LayoutDumpMode::DUMP_SCROLL_POSITIONS:
+ if (frame->parent() == nullptr) {
+ WebFrame::LayoutAsTextControls layout_text_behavior =
+ WebFrame::LayoutAsTextNormal;
+ if (flags.dump_as_printed)
+ layout_text_behavior |= WebFrame::LayoutAsTextPrinting;
+ if (flags.debug_render_tree)
+ layout_text_behavior |= WebFrame::LayoutAsTextDebug;
+ if (flags.dump_line_box_trees)
+ layout_text_behavior |= WebFrame::LayoutAsTextWithLineTrees;
+ result = frame->layoutTreeAsText(layout_text_behavior).utf8();
+ }
+ result += DumpFrameScrollPosition(frame);
+ break;
+ default:
+ DCHECK(false) << static_cast<int>(flags.main_dump_mode);
+ result = "";
+ break;
+ }
+
+ return result;
+}
+
+} // namespace test_runner
diff --git a/components/test_runner/layout_dump.h b/components/test_runner/layout_dump.h
new file mode 100644
index 0000000..5582ee9
--- /dev/null
+++ b/components/test_runner/layout_dump.h
@@ -0,0 +1,24 @@
+// 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.
+
+#ifndef COMPONENTS_TEST_RUNNER_LAYOUT_DUMP_H_
+#define COMPONENTS_TEST_RUNNER_LAYOUT_DUMP_H_
+
+#include <string>
+
+#include "components/test_runner/layout_dump_flags.h"
+#include "components/test_runner/test_runner_export.h"
+
+namespace blink {
+class WebLocalFrame;
+} // namespace blink
+
+namespace test_runner {
+
+TEST_RUNNER_EXPORT std::string DumpLayout(blink::WebLocalFrame* frame,
+ const LayoutDumpFlags& flags);
+
+} // namespace test_runner
+
+#endif // COMPONENTS_TEST_RUNNER_LAYOUT_DUMP_H_
diff --git a/components/test_runner/layout_dump_flags.h b/components/test_runner/layout_dump_flags.h
new file mode 100644
index 0000000..5253e15
--- /dev/null
+++ b/components/test_runner/layout_dump_flags.h
@@ -0,0 +1,27 @@
+// 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.
+
+#ifndef COMPONENTS_TEST_RUNNER_LAYOUT_DUMP_FLAGS_H_
+#define COMPONENTS_TEST_RUNNER_LAYOUT_DUMP_FLAGS_H_
+
+namespace test_runner {
+
+enum class LayoutDumpMode {
+ DUMP_AS_TEXT,
+ DUMP_AS_MARKUP,
+ DUMP_SCROLL_POSITIONS
+};
+
+struct LayoutDumpFlags {
+ LayoutDumpMode main_dump_mode;
+
+ bool dump_as_printed;
+ bool dump_child_frames;
+ bool dump_line_box_trees;
+ bool debug_render_tree;
+};
+
+} // namespace test_runner
+
+#endif // COMPONENTS_TEST_RUNNER_LAYOUT_DUMP_FLAGS_H_
diff --git a/components/test_runner/test_runner.cc b/components/test_runner/test_runner.cc
index e4e5877..8d41bbd 100644
--- a/components/test_runner/test_runner.cc
+++ b/components/test_runner/test_runner.cc
@@ -1863,6 +1863,36 @@ void TestRunner::GetAudioData(std::vector<unsigned char>* buffer_view) const {
*buffer_view = audio_data_;
}
+LayoutDumpFlags TestRunner::GetLayoutDumpFlags() {
+ LayoutDumpFlags result;
+
+ if (shouldDumpAsText()) {
+ result.main_dump_mode = LayoutDumpMode::DUMP_AS_TEXT;
+ result.dump_child_frames = shouldDumpChildFramesAsText();
+ } else if (shouldDumpAsMarkup()) {
+ result.main_dump_mode = LayoutDumpMode::DUMP_AS_MARKUP;
+ result.dump_child_frames = shouldDumpChildFramesAsMarkup();
+ } else {
+ result.main_dump_mode = LayoutDumpMode::DUMP_SCROLL_POSITIONS;
+ result.dump_child_frames = shouldDumpChildFrameScrollPositions();
+ }
+
+ result.dump_as_printed = isPrinting();
+
+ result.dump_line_box_trees = result.debug_render_tree = false;
+
+ return result;
+}
+
+bool TestRunner::HasCustomTextDump(std::string* custom_text_dump) const {
+ if (shouldDumpAsCustomText()) {
+ *custom_text_dump = customDumpText();
+ return true;
+ }
+
+ return false;
+}
+
bool TestRunner::shouldDumpFrameLoadCallbacks() const {
return test_is_running_ && dump_frame_load_callbacks_;
}
diff --git a/components/test_runner/test_runner.gyp b/components/test_runner/test_runner.gyp
index 2882d14..1d1ffec 100644
--- a/components/test_runner/test_runner.gyp
+++ b/components/test_runner/test_runner.gyp
@@ -56,6 +56,9 @@
'gamepad_controller.h',
'gc_controller.cc',
'gc_controller.h',
+ 'layout_dump.cc',
+ 'layout_dump.h',
+ 'layout_dump_flags.h',
'mock_color_chooser.cc',
'mock_color_chooser.h',
'mock_credential_manager_client.cc',
diff --git a/components/test_runner/test_runner.h b/components/test_runner/test_runner.h
index 372aff9..a7add70 100644
--- a/components/test_runner/test_runner.h
+++ b/components/test_runner/test_runner.h
@@ -72,6 +72,8 @@ class TestRunner : public WebTestRunner,
bool ShouldStayOnPageAfterHandlingBeforeUnload() const override;
bool ShouldDumpAsAudio() const override;
void GetAudioData(std::vector<unsigned char>* buffer_view) const override;
+ LayoutDumpFlags GetLayoutDumpFlags() override;
+ bool HasCustomTextDump(std::string* custom_text_dump) const override;
bool ShouldDumpBackForwardList() const override;
blink::WebContentSettingsClient* GetWebContentSettings() const override;
diff --git a/components/test_runner/web_test_proxy.cc b/components/test_runner/web_test_proxy.cc
index 76fa570..2de0450 100644
--- a/components/test_runner/web_test_proxy.cc
+++ b/components/test_runner/web_test_proxy.cc
@@ -21,6 +21,7 @@
#include "base/trace_event/trace_event.h"
#include "components/test_runner/accessibility_controller.h"
#include "components/test_runner/event_sender.h"
+#include "components/test_runner/layout_dump.h"
#include "components/test_runner/mock_color_chooser.h"
#include "components/test_runner/mock_credential_manager_client.h"
#include "components/test_runner/mock_screen_orientation_client.h"
@@ -289,90 +290,20 @@ const char* WebNavigationPolicyToString(blink::WebNavigationPolicy policy) {
}
}
-std::string DumpFrameHeaderIfNeeded(blink::WebFrame* frame) {
- std::string result;
-
- // Add header for all but the main frame. Skip empty frames.
- if (frame->parent() && !frame->document().documentElement().isNull()) {
- result.append("\n--------\nFrame: '");
- result.append(frame->uniqueName().utf8().data());
- result.append("'\n--------\n");
- }
-
- return result;
-}
-
-std::string DumpFramesAsMarkup(blink::WebFrame* frame, bool recursive) {
- std::string result = DumpFrameHeaderIfNeeded(frame);
- result.append(frame->contentAsMarkup().utf8());
- result.append("\n");
-
- if (recursive) {
- for (blink::WebFrame* child = frame->firstChild(); child;
- child = child->nextSibling())
- result.append(DumpFramesAsMarkup(child, recursive));
- }
-
- return result;
-}
-
-std::string DumpDocumentText(blink::WebFrame* frame) {
- return frame->document().contentAsTextForTesting().utf8();
-}
-
-std::string DumpFramesAsText(blink::WebFrame* frame, bool recursive) {
- std::string result = DumpFrameHeaderIfNeeded(frame);
- result.append(DumpDocumentText(frame));
- result.append("\n");
-
- if (recursive) {
- for (blink::WebFrame* child = frame->firstChild(); child;
- child = child->nextSibling())
- result.append(DumpFramesAsText(child, recursive));
- }
-
- return result;
-}
-
-std::string DumpFramesAsPrintedText(blink::WebFrame* frame, bool recursive) {
- // Cannot do printed format for anything other than HTML
- if (!frame->document().isHTMLDocument())
- return std::string();
-
- std::string result = DumpFrameHeaderIfNeeded(frame);
- result.append(
- frame->layoutTreeAsText(blink::WebFrame::LayoutAsTextPrinting).utf8());
- result.append("\n");
+std::string DumpDeepLayout(blink::WebFrame* frame,
+ LayoutDumpFlags flags,
+ bool recursive) {
+ std::string result = DumpLayout(frame->toWebLocalFrame(), flags);
if (recursive) {
for (blink::WebFrame* child = frame->firstChild(); child;
child = child->nextSibling())
- result.append(DumpFramesAsPrintedText(child, recursive));
+ result.append(DumpDeepLayout(child, flags, recursive));
}
return result;
}
-std::string DumpFrameScrollPosition(blink::WebFrame* frame, bool recursive) {
- std::string result;
- blink::WebSize offset = frame->scrollOffset();
- if (offset.width > 0 || offset.height > 0) {
- if (frame->parent()) {
- result =
- std::string("frame '") + frame->uniqueName().utf8().data() + "' ";
- }
- base::StringAppendF(
- &result, "scrolled to %d,%d\n", offset.width, offset.height);
- }
-
- if (!recursive)
- return result;
- for (blink::WebFrame* child = frame->firstChild(); child;
- child = child->nextSibling())
- result += DumpFrameScrollPosition(child, recursive);
- return result;
-}
-
std::string DumpAllBackForwardLists(TestInterfaces* interfaces,
WebTestDelegate* delegate) {
std::string result;
@@ -488,50 +419,27 @@ void WebTestProxyBase::ShowValidationMessage(
std::string WebTestProxyBase::CaptureTree(
bool debug_render_tree,
bool dump_line_box_trees) {
- bool should_dump_custom_text =
- test_interfaces_->GetTestRunner()->shouldDumpAsCustomText();
- bool should_dump_as_text =
- test_interfaces_->GetTestRunner()->shouldDumpAsText();
- bool should_dump_as_markup =
- test_interfaces_->GetTestRunner()->shouldDumpAsMarkup();
- bool should_dump_as_printed = test_interfaces_->GetTestRunner()->isPrinting();
+ TestRunner* test_runner = test_interfaces_->GetTestRunner();
blink::WebFrame* frame = GetWebView()->mainFrame();
std::string data_utf8;
- if (should_dump_custom_text) {
+ if (test_runner->shouldDumpAsCustomText()) {
// Append a newline for the test driver.
data_utf8 = test_interfaces_->GetTestRunner()->customDumpText() + "\n";
- } else if (should_dump_as_text) {
- bool recursive =
- test_interfaces_->GetTestRunner()->shouldDumpChildFramesAsText();
- data_utf8 = should_dump_as_printed ?
- DumpFramesAsPrintedText(frame, recursive) :
- DumpFramesAsText(frame, recursive);
- } else if (should_dump_as_markup) {
- bool recursive =
- test_interfaces_->GetTestRunner()->shouldDumpChildFramesAsMarkup();
- // Append a newline for the test driver.
- data_utf8 = DumpFramesAsMarkup(frame, recursive);
} else {
- bool recursive = test_interfaces_->GetTestRunner()
- ->shouldDumpChildFrameScrollPositions();
- blink::WebFrame::LayoutAsTextControls layout_text_behavior =
- blink::WebFrame::LayoutAsTextNormal;
- if (should_dump_as_printed)
- layout_text_behavior |= blink::WebFrame::LayoutAsTextPrinting;
- if (debug_render_tree)
- layout_text_behavior |= blink::WebFrame::LayoutAsTextDebug;
- if (dump_line_box_trees)
- layout_text_behavior |= blink::WebFrame::LayoutAsTextWithLineTrees;
- data_utf8 = frame->layoutTreeAsText(layout_text_behavior).utf8();
- data_utf8 += DumpFrameScrollPosition(frame, recursive);
+ LayoutDumpFlags flags = test_runner->GetLayoutDumpFlags();
+ data_utf8 = DumpDeepLayout(frame, flags, flags.dump_child_frames);
}
if (test_interfaces_->GetTestRunner()->ShouldDumpBackForwardList())
- data_utf8 += DumpAllBackForwardLists(test_interfaces_, delegate_);
+ data_utf8 += DumpBackForwardLists();
return data_utf8;
}
+std::string WebTestProxyBase::DumpBackForwardLists() {
+ return DumpAllBackForwardLists(test_interfaces_, delegate_);
+}
+
void WebTestProxyBase::DrawSelectionRect(SkCanvas* canvas) {
// See if we need to draw the selection bounds rect. Selection bounds
// rect is the rect enclosing the (possibly transformed) selection.
diff --git a/components/test_runner/web_test_proxy.h b/components/test_runner/web_test_proxy.h
index d304f64..445df4b 100644
--- a/components/test_runner/web_test_proxy.h
+++ b/components/test_runner/web_test_proxy.h
@@ -114,6 +114,7 @@ class TEST_RUNNER_EXPORT WebTestProxyBase {
void MoveValidationMessage(const blink::WebRect& anchor_in_root_view);
std::string CaptureTree(bool debug_render_tree, bool dump_line_box_trees);
+ std::string DumpBackForwardLists();
void CapturePixelsForPrinting(
const base::Callback<void(const SkBitmap&)>& callback);
void CopyImageAtAndCapturePixels(
diff --git a/components/test_runner/web_test_runner.h b/components/test_runner/web_test_runner.h
index 177e2ba..b5040df 100644
--- a/components/test_runner/web_test_runner.h
+++ b/components/test_runner/web_test_runner.h
@@ -5,8 +5,11 @@
#ifndef COMPONENTS_TEST_RUNNER_WEB_TEST_RUNNER_H_
#define COMPONENTS_TEST_RUNNER_WEB_TEST_RUNNER_H_
+#include <string>
#include <vector>
+#include "components/test_runner/layout_dump_flags.h"
+
namespace blink {
class WebContentSettingsClient;
}
@@ -28,6 +31,15 @@ class WebTestRunner {
virtual bool ShouldDumpAsAudio() const = 0;
virtual void GetAudioData(std::vector<unsigned char>* buffer_view) const = 0;
+ // Gets layout dump flags (i.e. dump-as-text or dump-as-markup) requested
+ // by the test (i.e. via testRunner.dumpAsText() called from javascript).
+ virtual LayoutDumpFlags GetLayoutDumpFlags() = 0;
+
+ // If custom text dump is present (i.e. if testRunner.setCustomTextOutput has
+ // been called from javascript), then returns |true| and populates the
+ // |custom_text_dump| argument. Otherwise returns |false|.
+ virtual bool HasCustomTextDump(std::string* custom_text_dump) const = 0;
+
// Returns true if the call to WebTestProxy::captureTree will invoke
// WebTestDelegate::captureHistoryForWindow.
virtual bool ShouldDumpBackForwardList() const = 0;