Commit 3d1e7a12 authored by Sergei Datsenko's avatar Sergei Datsenko Committed by Commit Bot

Add virtualtime support to render tests.

Clean up render tests structure and require virtual time exhaustion as
an indication of rendering completion.

Change-Id: I62a7ed9389facaab223ab3ddebb80496ece5c203
Reviewed-on: https://chromium-review.googlesource.com/776517Reviewed-by: default avatarAlex Clarke <alexclarke@chromium.org>
Commit-Queue: Sergei Datsenko <dats@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517813}
parent a9230364
<html>
<body>
<script type="text/javascript">
setTimeout(() => {
var div = document.getElementById("content");
var p = document.createElement("p");
p.textContent = "delayed text";
div.appendChild(p);
}, 3000);
</script>
</body>
<div id="content"/>
</html>
...@@ -14,6 +14,10 @@ ...@@ -14,6 +14,10 @@
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#define HEADLESS_RENDER_BROWSERTEST(clazz) \
class HeadlessRenderBrowserTest##clazz : public clazz {}; \
HEADLESS_ASYNC_DEVTOOLED_TEST_F(HeadlessRenderBrowserTest##clazz)
namespace headless { namespace headless {
namespace { namespace {
...@@ -46,21 +50,6 @@ bool IsTag(const DOMNode& node) { ...@@ -46,21 +50,6 @@ bool IsTag(const DOMNode& node) {
bool IsText(const DOMNode& node) { bool IsText(const DOMNode& node) {
return HasType(3, node); return HasType(3, node);
} }
bool IsTagWithName(const char* name, const DOMNode& node) {
return IsTag(node) && HasName(name, node);
}
std::vector<std::string> Structure(const GetSnapshotResult* snapshot) {
return ElementsView<std::string, DOMNode>(
*snapshot->GetDomNodes(), IsTag,
[](const auto& node) { return node.GetNodeName(); });
}
std::vector<std::string> Contents(const GetSnapshotResult* snapshot) {
return ElementsView<std::string, DOMNode>(
*snapshot->GetDomNodes(), IsText,
[](const auto& node) { return node.GetNodeValue(); });
}
std::vector<std::string> TextLayout(const GetSnapshotResult* snapshot) { std::vector<std::string> TextLayout(const GetSnapshotResult* snapshot) {
return ElementsView<std::string, LayoutTreeNode>( return ElementsView<std::string, LayoutTreeNode>(
...@@ -76,6 +65,13 @@ std::vector<const DOMNode*> FilterDOM( ...@@ -76,6 +65,13 @@ std::vector<const DOMNode*> FilterDOM(
*snapshot->GetDomNodes(), filter, [](const auto& n) { return &n; }); *snapshot->GetDomNodes(), filter, [](const auto& n) { return &n; });
} }
std::vector<const DOMNode*> FindTags(const GetSnapshotResult* snapshot,
const char* name = nullptr) {
return FilterDOM(snapshot, [name](const auto& n) {
return IsTag(n) && (!name || HasName(name, n));
});
}
size_t IndexInDOM(const GetSnapshotResult* snapshot, const DOMNode* node) { size_t IndexInDOM(const GetSnapshotResult* snapshot, const DOMNode* node) {
for (size_t i = 0; i < snapshot->GetDomNodes()->size(); ++i) { for (size_t i = 0; i < snapshot->GetDomNodes()->size(); ++i) {
if (snapshot->GetDomNodes()->at(i).get() == node) if (snapshot->GetDomNodes()->at(i).get() == node)
...@@ -113,57 +109,54 @@ using testing::StartsWith; ...@@ -113,57 +109,54 @@ using testing::StartsWith;
class HelloWorldTest : public HeadlessRenderTest { class HelloWorldTest : public HeadlessRenderTest {
private: private:
GURL GetPageUrl(HeadlessDevToolsClient* client) override { GURL GetPageUrl(HeadlessDevToolsClient* client) override {
return embedded_test_server()->GetURL("/hello.html"); return GetURL("/hello.html");
} }
void VerifyDom(GetSnapshotResult* dom_snapshot) override { void VerifyDom(GetSnapshotResult* dom_snapshot) override {
EXPECT_THAT(Structure(dom_snapshot), EXPECT_THAT(FindTags(dom_snapshot),
ElementsAre("HTML", "HEAD", "BODY", "H1")); ElementsAre(NodeName("HTML"), NodeName("HEAD"),
EXPECT_THAT(Contents(dom_snapshot), NodeName("BODY"), NodeName("H1")));
ElementsAre("Hello headless world!", "\n")); EXPECT_THAT(
FilterDOM(dom_snapshot, IsText),
ElementsAre(NodeValue("Hello headless world!"), NodeValue("\n")));
EXPECT_THAT(TextLayout(dom_snapshot), ElementsAre("Hello headless world!")); EXPECT_THAT(TextLayout(dom_snapshot), ElementsAre("Hello headless world!"));
AllDone();
} }
}; };
HEADLESS_ASYNC_DEVTOOLED_TEST_F(HelloWorldTest); HEADLESS_RENDER_BROWSERTEST(HelloWorldTest);
class TimeoutTest : public HeadlessRenderTest { class TimeoutTest : public HeadlessRenderTest {
private: private:
void OnPageRenderCompleted() override {
// Never complete.
}
GURL GetPageUrl(HeadlessDevToolsClient* client) override { GURL GetPageUrl(HeadlessDevToolsClient* client) override {
base::RunLoop run_loop; return GetURL("/hello.html");
client->GetPage()->Disable(run_loop.QuitClosure());
base::MessageLoop::ScopedNestableTaskAllower nest_loop(
base::MessageLoop::current());
run_loop.Run();
return embedded_test_server()->GetURL("/hello.html");
} }
void VerifyDom(GetSnapshotResult* dom_snapshot) override { void VerifyDom(GetSnapshotResult* dom_snapshot) override {
FAIL() << "Should not reach here"; FAIL() << "Should not reach here";
} }
void OnTimeout() override { AllDone(); } void OnTimeout() override { SetTestCompleted(); }
}; };
HEADLESS_ASYNC_DEVTOOLED_TEST_F(TimeoutTest); HEADLESS_RENDER_BROWSERTEST(TimeoutTest);
class JavaScriptOverrideTitle_JsEnabled : public HeadlessRenderTest { class JavaScriptOverrideTitle_JsEnabled : public HeadlessRenderTest {
private: private:
GURL GetPageUrl(HeadlessDevToolsClient* client) override { GURL GetPageUrl(HeadlessDevToolsClient* client) override {
return embedded_test_server()->GetURL( return GetURL("/render/javascript_override_title.html");
"/render/javascript_override_title.html");
} }
void VerifyDom(GetSnapshotResult* dom_snapshot) override { void VerifyDom(GetSnapshotResult* dom_snapshot) override {
auto dom = FilterDOM( auto dom = FindTags(dom_snapshot, "TITLE");
dom_snapshot, [](const auto& n) { return IsTagWithName("TITLE", n); });
ASSERT_THAT(dom, ElementsAre(NodeName("TITLE"))); ASSERT_THAT(dom, ElementsAre(NodeName("TITLE")));
size_t pos = IndexInDOM(dom_snapshot, dom[0]); size_t pos = IndexInDOM(dom_snapshot, dom[0]);
const DOMNode* value = GetAt(dom_snapshot, pos + 1); const DOMNode* value = GetAt(dom_snapshot, pos + 1);
EXPECT_THAT(value, NodeValue("JavaScript is on")); EXPECT_THAT(value, NodeValue("JavaScript is on"));
AllDone();
} }
}; };
HEADLESS_ASYNC_DEVTOOLED_TEST_F(JavaScriptOverrideTitle_JsEnabled); HEADLESS_RENDER_BROWSERTEST(JavaScriptOverrideTitle_JsEnabled);
class JavaScriptOverrideTitle_JsDisabled : public HeadlessRenderTest { class JavaScriptOverrideTitle_JsDisabled : public HeadlessRenderTest {
private: private:
...@@ -173,21 +166,18 @@ class JavaScriptOverrideTitle_JsDisabled : public HeadlessRenderTest { ...@@ -173,21 +166,18 @@ class JavaScriptOverrideTitle_JsDisabled : public HeadlessRenderTest {
} }
GURL GetPageUrl(HeadlessDevToolsClient* client) override { GURL GetPageUrl(HeadlessDevToolsClient* client) override {
return embedded_test_server()->GetURL( return GetURL("/render/javascript_override_title.html");
"/render/javascript_override_title.html");
} }
void VerifyDom(GetSnapshotResult* dom_snapshot) override { void VerifyDom(GetSnapshotResult* dom_snapshot) override {
auto dom = FilterDOM( auto dom = FindTags(dom_snapshot, "TITLE");
dom_snapshot, [](const auto& n) { return IsTagWithName("TITLE", n); });
ASSERT_THAT(dom, ElementsAre(NodeName("TITLE"))); ASSERT_THAT(dom, ElementsAre(NodeName("TITLE")));
size_t pos = IndexInDOM(dom_snapshot, dom[0]); size_t pos = IndexInDOM(dom_snapshot, dom[0]);
const DOMNode* value = GetAt(dom_snapshot, pos + 1); const DOMNode* value = GetAt(dom_snapshot, pos + 1);
EXPECT_THAT(value, NodeValue("JavaScript is off")); EXPECT_THAT(value, NodeValue("JavaScript is off"));
AllDone();
} }
}; };
HEADLESS_ASYNC_DEVTOOLED_TEST_F(JavaScriptOverrideTitle_JsDisabled); HEADLESS_RENDER_BROWSERTEST(JavaScriptOverrideTitle_JsDisabled);
class JavaScriptConsoleErrors : public HeadlessRenderTest, class JavaScriptConsoleErrors : public HeadlessRenderTest,
public runtime::ExperimentalObserver { public runtime::ExperimentalObserver {
...@@ -204,7 +194,7 @@ class JavaScriptConsoleErrors : public HeadlessRenderTest, ...@@ -204,7 +194,7 @@ class JavaScriptConsoleErrors : public HeadlessRenderTest,
base::MessageLoop::ScopedNestableTaskAllower nest_loop( base::MessageLoop::ScopedNestableTaskAllower nest_loop(
base::MessageLoop::current()); base::MessageLoop::current());
run_loop.Run(); run_loop.Run();
return embedded_test_server()->GetURL("/render/console_errors.html"); return GetURL("/render/console_errors.html");
} }
void OnConsoleAPICalled( void OnConsoleAPICalled(
...@@ -229,9 +219,36 @@ class JavaScriptConsoleErrors : public HeadlessRenderTest, ...@@ -229,9 +219,36 @@ class JavaScriptConsoleErrors : public HeadlessRenderTest,
StartsWith("Uncaught ReferenceError: func1"), StartsWith("Uncaught ReferenceError: func1"),
StartsWith("Uncaught ReferenceError: func2"), StartsWith("Uncaught ReferenceError: func2"),
StartsWith("Uncaught ReferenceError: func3"))); StartsWith("Uncaught ReferenceError: func3")));
AllDone();
} }
}; };
HEADLESS_ASYNC_DEVTOOLED_TEST_F(JavaScriptConsoleErrors); HEADLESS_RENDER_BROWSERTEST(JavaScriptConsoleErrors);
class DelayedCompletion : public HeadlessRenderTest {
private:
base::TimeTicks start_;
GURL GetPageUrl(HeadlessDevToolsClient* client) override {
start_ = base::TimeTicks::Now();
return GetURL("/render/delayed_completion.html");
}
void VerifyDom(GetSnapshotResult* dom_snapshot) override {
base::TimeTicks end = base::TimeTicks::Now();
EXPECT_THAT(
FindTags(dom_snapshot),
ElementsAre(NodeName("HTML"), NodeName("HEAD"), NodeName("BODY"),
NodeName("SCRIPT"), NodeName("DIV"), NodeName("P")));
auto dom = FindTags(dom_snapshot, "P");
ASSERT_THAT(dom, ElementsAre(NodeName("P")));
size_t pos = IndexInDOM(dom_snapshot, dom[0]);
const DOMNode* value = GetAt(dom_snapshot, pos + 1);
EXPECT_THAT(value, NodeValue("delayed text"));
// The page delays output for 3 seconds. Due to virtual time this should
// take significantly less actual time.
base::TimeDelta passed = end - start_;
EXPECT_THAT(passed.InSecondsF(), testing::Le(2.9f));
}
};
HEADLESS_RENDER_BROWSERTEST(DelayedCompletion);
} // namespace headless } // namespace headless
...@@ -6,30 +6,39 @@ ...@@ -6,30 +6,39 @@
#include "headless/public/devtools/domains/dom_snapshot.h" #include "headless/public/devtools/domains/dom_snapshot.h"
#include "headless/public/headless_devtools_client.h" #include "headless/public/headless_devtools_client.h"
#include "headless/public/util/virtual_time_controller.h"
#include "net/url_request/url_request.h" #include "net/url_request/url_request.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace headless { namespace headless {
namespace {
void SetVirtualTimePolicyDoneCallback(
base::RunLoop* run_loop,
std::unique_ptr<emulation::SetVirtualTimePolicyResult>) {
run_loop->Quit();
}
} // namespace
HeadlessRenderTest::HeadlessRenderTest() : weak_ptr_factory_(this) {} HeadlessRenderTest::HeadlessRenderTest() : weak_ptr_factory_(this) {}
HeadlessRenderTest::~HeadlessRenderTest() {} HeadlessRenderTest::~HeadlessRenderTest() {}
void HeadlessRenderTest::PostRunAsynchronousTest() { void HeadlessRenderTest::PostRunAsynchronousTest() {
// Make sure the test did complete. // Make sure the test did complete.
EXPECT_TRUE(done_called_) << "The test did not finish. AllDone() not called."; EXPECT_EQ(FINISHED, state_) << "The test did not finish.";
} }
void HeadlessRenderTest::RunDevTooledTest() { void HeadlessRenderTest::RunDevTooledTest() {
EXPECT_TRUE(embedded_test_server()->Start()); EXPECT_TRUE(embedded_test_server()->Start());
base::RunLoop run_loop;
virtual_time_controller_ =
std::make_unique<VirtualTimeController>(devtools_client_.get());
devtools_client_->GetPage()->GetExperimental()->AddObserver(this); devtools_client_->GetPage()->GetExperimental()->AddObserver(this);
devtools_client_->GetNetwork()->GetExperimental()->AddObserver(this); devtools_client_->GetNetwork()->GetExperimental()->AddObserver(this);
devtools_client_->GetPage()->Enable(run_loop.QuitClosure()); devtools_client_->GetPage()->Enable(Sync());
base::MessageLoop::ScopedNestableTaskAllower nest_loop( devtools_client_->GetNetwork()->Enable(Sync());
base::MessageLoop::current());
run_loop.Run();
devtools_client_->GetNetwork()->Enable();
std::unique_ptr<headless::network::RequestPattern> match_all = std::unique_ptr<headless::network::RequestPattern> match_all =
headless::network::RequestPattern::Builder().SetUrlPattern("*").Build(); headless::network::RequestPattern::Builder().SetUrlPattern("*").Build();
...@@ -41,16 +50,34 @@ void HeadlessRenderTest::RunDevTooledTest() { ...@@ -41,16 +50,34 @@ void HeadlessRenderTest::RunDevTooledTest() {
.Build()); .Build());
GURL url = GetPageUrl(devtools_client_.get()); GURL url = GetPageUrl(devtools_client_.get());
// Pause virtual time until we actually start loading content.
{
base::RunLoop run_loop;
devtools_client_->GetEmulation()->GetExperimental()->SetVirtualTimePolicy(
emulation::SetVirtualTimePolicyParams::Builder()
.SetPolicy(emulation::VirtualTimePolicy::PAUSE)
.Build(),
base::Bind(&SetVirtualTimePolicyDoneCallback, &run_loop));
base::MessageLoop::ScopedNestableTaskAllower nest_loop(
base::MessageLoop::current());
run_loop.Run();
}
state_ = STARTING;
devtools_client_->GetPage()->Navigate(url.spec()); devtools_client_->GetPage()->Navigate(url.spec());
browser()->BrowserMainThread()->PostDelayedTask( browser()->BrowserMainThread()->PostDelayedTask(
FROM_HERE, FROM_HERE,
base::Bind(&HeadlessRenderTest::HandleTimeout, base::Bind(&HeadlessRenderTest::HandleTimeout,
weak_ptr_factory_.GetWeakPtr()), weak_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromSeconds(10)); base::TimeDelta::FromSeconds(10));
// The caller will loop until FinishAsynchronousTest() is called either
// from OnGetDomSnapshotDone() or from HandleTimeout().
} }
void HeadlessRenderTest::OnTimeout() { void HeadlessRenderTest::OnTimeout() {
FAIL() << "Renderer timeout"; ADD_FAILURE() << "Rendering timed out!";
} }
void HeadlessRenderTest::CustomizeHeadlessBrowserContext( void HeadlessRenderTest::CustomizeHeadlessBrowserContext(
...@@ -71,14 +98,15 @@ void HeadlessRenderTest::UrlRequestFailed(net::URLRequest* request, ...@@ -71,14 +98,15 @@ void HeadlessRenderTest::UrlRequestFailed(net::URLRequest* request,
bool canceled_by_devtools) { bool canceled_by_devtools) {
if (canceled_by_devtools) if (canceled_by_devtools)
return; return;
FAIL() << "Network request failed: " << net_error << " for " ADD_FAILURE() << "Network request failed: " << net_error << " for "
<< request->url().spec(); << request->url().spec();
} }
void HeadlessRenderTest::OnRequestIntercepted( void HeadlessRenderTest::OnRequestIntercepted(
const network::RequestInterceptedParams& params) { const network::RequestInterceptedParams& params) {
CHECK_NE(INIT, state_);
if (params.GetIsNavigationRequest()) if (params.GetIsNavigationRequest())
navigation_requested_ = true; navigation_performed_ = true;
requests_.push_back(params.Clone()); requests_.push_back(params.Clone());
// Allow the navigation to proceed. // Allow the navigation to proceed.
devtools_client_->GetNetwork()->GetExperimental()->ContinueInterceptedRequest( devtools_client_->GetNetwork()->GetExperimental()->ContinueInterceptedRequest(
...@@ -87,8 +115,33 @@ void HeadlessRenderTest::OnRequestIntercepted( ...@@ -87,8 +115,33 @@ void HeadlessRenderTest::OnRequestIntercepted(
.Build()); .Build());
} }
void HeadlessRenderTest::OnLoadEventFired( void HeadlessRenderTest::OnLoadEventFired(const page::LoadEventFiredParams&) {
const page::LoadEventFiredParams& params) { CHECK_NE(INIT, state_);
if (state_ == LOADING || state_ == STARTING) {
state_ = RENDERING;
}
}
void HeadlessRenderTest::OnFrameStartedLoading(
const page::FrameStartedLoadingParams&) {
CHECK_NE(INIT, state_);
if (state_ == STARTING) {
state_ = LOADING;
virtual_time_controller_->GrantVirtualTimeBudget(
emulation::VirtualTimePolicy::PAUSE_IF_NETWORK_FETCHES_PENDING, 5000,
base::Closure(),
base::Bind(&HeadlessRenderTest::HandleVirtualTimeExhausted,
weak_ptr_factory_.GetWeakPtr()));
}
}
void HeadlessRenderTest::OnPageRenderCompleted() {
CHECK(navigation_performed_);
CHECK_GE(state_, LOADING);
if (state_ >= DONE)
return;
state_ = DONE;
devtools_client_->GetDOMSnapshot()->GetExperimental()->GetSnapshot( devtools_client_->GetDOMSnapshot()->GetExperimental()->GetSnapshot(
dom_snapshot::GetSnapshotParams::Builder() dom_snapshot::GetSnapshotParams::Builder()
.SetComputedStyleWhitelist(std::vector<std::string>()) .SetComputedStyleWhitelist(std::vector<std::string>())
...@@ -97,19 +150,25 @@ void HeadlessRenderTest::OnLoadEventFired( ...@@ -97,19 +150,25 @@ void HeadlessRenderTest::OnLoadEventFired(
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
} }
void HeadlessRenderTest::HandleVirtualTimeExhausted() {
if (state_ < DONE) {
OnPageRenderCompleted();
}
}
void HeadlessRenderTest::OnGetDomSnapshotDone( void HeadlessRenderTest::OnGetDomSnapshotDone(
std::unique_ptr<dom_snapshot::GetSnapshotResult> result) { std::unique_ptr<dom_snapshot::GetSnapshotResult> result) {
EXPECT_TRUE(navigation_requested_); CHECK_EQ(DONE, state_);
state_ = FINISHED;
FinishAsynchronousTest();
VerifyDom(result.get()); VerifyDom(result.get());
if (done_called_)
FinishAsynchronousTest();
} }
void HeadlessRenderTest::HandleTimeout() { void HeadlessRenderTest::HandleTimeout() {
if (!done_called_) if (state_ != FINISHED) {
FinishAsynchronousTest();
OnTimeout(); OnTimeout();
EXPECT_TRUE(done_called_); }
FinishAsynchronousTest();
} }
} // namespace headless } // namespace headless
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <string> #include <string>
#include "base/macros.h" #include "base/macros.h"
#include "headless/public/devtools/domains/emulation.h"
#include "headless/public/devtools/domains/network.h" #include "headless/public/devtools/domains/network.h"
#include "headless/public/devtools/domains/page.h" #include "headless/public/devtools/domains/page.h"
#include "headless/public/headless_browser.h" #include "headless/public/headless_browser.h"
...@@ -19,6 +20,7 @@ ...@@ -19,6 +20,7 @@
namespace headless { namespace headless {
class HeadlessDevToolsClient; class HeadlessDevToolsClient;
class VirtualTimeController;
namespace dom_snapshot { namespace dom_snapshot {
class GetSnapshotResult; class GetSnapshotResult;
} // namespace dom_snapshot } // namespace dom_snapshot
...@@ -32,16 +34,39 @@ class HeadlessRenderTest : public HeadlessAsyncDevTooledBrowserTest, ...@@ -32,16 +34,39 @@ class HeadlessRenderTest : public HeadlessAsyncDevTooledBrowserTest,
void RunDevTooledTest() override; void RunDevTooledTest() override;
protected: protected:
// Automatically waits in destructor until callback is called.
class Sync {
public:
Sync() {}
~Sync() {
base::MessageLoop::ScopedNestableTaskAllower nest_loop(
base::MessageLoop::current());
run_loop.Run();
}
operator base::Closure() { return run_loop.QuitClosure(); }
private:
base::RunLoop run_loop;
DISALLOW_COPY_AND_ASSIGN(Sync);
};
HeadlessRenderTest(); HeadlessRenderTest();
~HeadlessRenderTest() override; ~HeadlessRenderTest() override;
void SetTestCompleted() { state_ = FINISHED; }
GURL GetURL(const std::string& path) const {
return embedded_test_server()->GetURL(path);
}
void PostRunAsynchronousTest() override; void PostRunAsynchronousTest() override;
virtual GURL GetPageUrl(HeadlessDevToolsClient* client) = 0; virtual GURL GetPageUrl(HeadlessDevToolsClient* client) = 0;
virtual void VerifyDom(dom_snapshot::GetSnapshotResult* dom_snapshot) = 0; virtual void VerifyDom(dom_snapshot::GetSnapshotResult* dom_snapshot) = 0;
virtual void OnPageRenderCompleted();
virtual void OnTimeout(); virtual void OnTimeout();
virtual void OverrideWebPreferences(WebPreferences* preferences); virtual void OverrideWebPreferences(WebPreferences* preferences);
void AllDone() { done_called_ = true; }
void CustomizeHeadlessBrowserContext( void CustomizeHeadlessBrowserContext(
HeadlessBrowserContext::Builder& builder) override; HeadlessBrowserContext::Builder& builder) override;
...@@ -53,6 +78,8 @@ class HeadlessRenderTest : public HeadlessAsyncDevTooledBrowserTest, ...@@ -53,6 +78,8 @@ class HeadlessRenderTest : public HeadlessAsyncDevTooledBrowserTest,
// page::ExperimentalObserver implementation: // page::ExperimentalObserver implementation:
void OnLoadEventFired(const page::LoadEventFiredParams& params) override; void OnLoadEventFired(const page::LoadEventFiredParams& params) override;
void OnFrameStartedLoading(
const page::FrameStartedLoadingParams& params) override;
// network::ExperimentalObserver // network::ExperimentalObserver
void OnRequestIntercepted( void OnRequestIntercepted(
...@@ -61,12 +88,23 @@ class HeadlessRenderTest : public HeadlessAsyncDevTooledBrowserTest, ...@@ -61,12 +88,23 @@ class HeadlessRenderTest : public HeadlessAsyncDevTooledBrowserTest,
std::vector<std::unique_ptr<network::RequestInterceptedParams>> requests_; std::vector<std::unique_ptr<network::RequestInterceptedParams>> requests_;
private: private:
void HandleVirtualTimeExhausted();
void OnGetDomSnapshotDone( void OnGetDomSnapshotDone(
std::unique_ptr<dom_snapshot::GetSnapshotResult> result); std::unique_ptr<dom_snapshot::GetSnapshotResult> result);
void HandleTimeout(); void HandleTimeout();
bool navigation_requested_ = false; enum State {
bool done_called_ = false; INIT, // Setting up the client, no navigation performed yet.
STARTING, // Navigation request issued but URL not being loaded yet.
LOADING, // URL was requested but resources are not fully loaded yet.
RENDERING, // Main resources were loaded but page is still being rendered.
DONE, // Page considered to be fully rendered.
FINISHED, // Test has finished.
};
State state_ = INIT;
std::unique_ptr<VirtualTimeController> virtual_time_controller_;
bool navigation_performed_ = false;
base::WeakPtrFactory<HeadlessRenderTest> weak_ptr_factory_; base::WeakPtrFactory<HeadlessRenderTest> weak_ptr_factory_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment