| Index: components/scheduler/renderer/web_view_scheduler_impl_browsertest.cc
|
| diff --git a/components/scheduler/renderer/web_view_scheduler_impl_browsertest.cc b/components/scheduler/renderer/web_view_scheduler_impl_browsertest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..dd44e493545f34247187ebd23ac6b546b6fa755c
|
| --- /dev/null
|
| +++ b/components/scheduler/renderer/web_view_scheduler_impl_browsertest.cc
|
| @@ -0,0 +1,160 @@
|
| +// 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/scheduler/renderer/web_view_scheduler_impl.h"
|
| +
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "content/public/renderer/render_view.h"
|
| +#include "content/public/test/render_view_test.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "third_party/WebKit/public/web/WebLocalFrame.h"
|
| +#include "third_party/WebKit/public/web/WebScriptSource.h"
|
| +#include "third_party/WebKit/public/web/WebView.h"
|
| +#include "v8/include/v8.h"
|
| +
|
| +namespace scheduler {
|
| +
|
| +// RenderViewTest-based tests crash on Android
|
| +// http://crbug.com/187500
|
| +#if defined(OS_ANDROID)
|
| +#define MAYBE_WebViewSchedulerBrowserTest DISABLED_WebViewSchedulerBrowserTest
|
| +#else
|
| +#define MAYBE_WebViewSchedulerBrowserTest WebViewSchedulerBrowserTest
|
| +#endif // defined(OS_ANDROID)
|
| +
|
| +class MAYBE_WebViewSchedulerBrowserTest : public content::RenderViewTest {
|
| + public:
|
| + MAYBE_WebViewSchedulerBrowserTest() : content::RenderViewTest() {}
|
| + ~MAYBE_WebViewSchedulerBrowserTest() override {}
|
| +
|
| + protected:
|
| + void SetUp() override {
|
| + content::RenderViewTest::SetUp();
|
| + }
|
| +
|
| + void TearDown() override {
|
| + content::RenderViewTest::TearDown();
|
| + }
|
| +
|
| + bool ExecuteJavaScriptAndReturnStringValue(
|
| + const base::string16& script, std::string* out_result);
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(MAYBE_WebViewSchedulerBrowserTest);
|
| +};
|
| +
|
| +bool MAYBE_WebViewSchedulerBrowserTest::ExecuteJavaScriptAndReturnStringValue(
|
| + const base::string16& script,
|
| + std::string* out_result) {
|
| + v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
|
| + v8::Local<v8::Value> result = GetMainFrame()->executeScriptAndReturnValue(
|
| + blink::WebScriptSource(script));
|
| + if (result.IsEmpty() || !result->IsString())
|
| + return false;
|
| +
|
| + v8::String::Utf8Value utf8_result(result);
|
| + *out_result = std::string(*utf8_result, utf8_result.length());
|
| + return true;
|
| +}
|
| +
|
| +TEST_F(MAYBE_WebViewSchedulerBrowserTest, DOMTimersFireInExpectedOrder) {
|
| + ExecuteJavaScriptForTests(
|
| + "window.run_order = [];"
|
| + "window.timerFn = function(delay, value){"
|
| + " setTimeout(function(){ window.run_order.push(value);}, delay);"
|
| + "};"
|
| + "var one_hour = 60 * 60 * 1000;"
|
| + "window.timerFn(one_hour * 100, 'a');"
|
| + "window.timerFn(one_hour * 10, 'b');"
|
| + "window.timerFn(one_hour, 'c');");
|
| +
|
| + view_->GetWebView()->scheduler()->useVirtualTime();
|
| + base::TimeTicks start = base::TimeTicks::Now();
|
| + ProcessPendingMessages();
|
| + base::TimeTicks end = base::TimeTicks::Now();
|
| +
|
| + std::string result;
|
| + EXPECT_TRUE(ExecuteJavaScriptAndReturnStringValue(
|
| + base::ASCIIToUTF16("window.run_order.join(', ')"), &result));
|
| + EXPECT_EQ("c, b, a", result);
|
| +
|
| + base::TimeDelta elapsed_time = end - start;
|
| + // Normally the above JS would take 100 hours to run, but thanks to timer
|
| + // fast forwarding we can run it in milliseconds. Note I've used 1s here to
|
| + // try and avoid a flaky test.
|
| + EXPECT_LT(elapsed_time, base::TimeDelta::FromSeconds(1));
|
| +}
|
| +
|
| +TEST_F(MAYBE_WebViewSchedulerBrowserTest, SetInterval) {
|
| + ExecuteJavaScriptForTests(
|
| + "window.run_order = [];"
|
| + "window.count = 10;"
|
| + "window.interval_handle = setInterval(function(){"
|
| + " if (--window.count == 0) {"
|
| + " clearInterval(window.interval_handle);"
|
| + " }"
|
| + " window.run_order.push(window.count);"
|
| + "}, 1000);"
|
| + "setTimeout(function(){ window.run_order.push('timer');}, 1500);");
|
| +
|
| + view_->GetWebView()->scheduler()->useVirtualTime();
|
| + ProcessPendingMessages();
|
| +
|
| + std::string result;
|
| + EXPECT_TRUE(ExecuteJavaScriptAndReturnStringValue(
|
| + base::ASCIIToUTF16("window.run_order.join(', ')"), &result));
|
| + // If virtual time is not supplied to TimeBase then the setInterval won't
|
| + // fire 10x.
|
| + EXPECT_EQ("9, timer, 8, 7, 6, 5, 4, 3, 2, 1, 0", result);
|
| +}
|
| +
|
| +TEST_F(MAYBE_WebViewSchedulerBrowserTest, AllowVirtualTimeToAdvance) {
|
| + ExecuteJavaScriptForTests(
|
| + "window.run_order = [];"
|
| + "window.timerFn = function(delay, value){"
|
| + " setTimeout(function(){ window.run_order.push(value);}, delay);"
|
| + "};"
|
| + "window.timerFn(100, 'a');"
|
| + "window.timerFn(10, 'b');"
|
| + "window.timerFn(1, 'c');");
|
| +
|
| + view_->GetWebView()->scheduler()->useVirtualTime();
|
| + view_->GetWebView()->scheduler()->setAllowVirtualTimeToAdvance(false);
|
| + ProcessPendingMessages();
|
| +
|
| + std::string result;
|
| + EXPECT_TRUE(ExecuteJavaScriptAndReturnStringValue(
|
| + base::ASCIIToUTF16("window.run_order.join(', ')"), &result));
|
| + EXPECT_EQ("", result);
|
| +
|
| + view_->GetWebView()->scheduler()->setAllowVirtualTimeToAdvance(true);
|
| + ProcessPendingMessages();
|
| +
|
| + EXPECT_TRUE(ExecuteJavaScriptAndReturnStringValue(
|
| + base::ASCIIToUTF16("window.run_order.join(', ')"), &result));
|
| + EXPECT_EQ("c, b, a", result);
|
| +}
|
| +
|
| +TEST_F(MAYBE_WebViewSchedulerBrowserTest, Normal_NonVirtualTime) {
|
| + ExecuteJavaScriptForTests(
|
| + "window.run_order = [];"
|
| + "window.timerFn = function(delay, value){"
|
| + " setTimeout(function(){ window.run_order.push(value);}, delay);"
|
| + "};"
|
| + "window.timerFn(20, 'a');"
|
| + "window.timerFn(10, 'b');"
|
| + "window.timerFn(1, 'c');");
|
| +
|
| + msg_loop_.task_runner()->PostDelayedTask(
|
| + FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
|
| + base::TimeDelta::FromMilliseconds(30));
|
| + msg_loop_.Run();
|
| +
|
| + std::string result;
|
| + EXPECT_TRUE(ExecuteJavaScriptAndReturnStringValue(
|
| + base::ASCIIToUTF16("window.run_order.join(', ')"), &result));
|
| + EXPECT_EQ("c, b, a", result);
|
| +}
|
| +
|
| +} // namespace scheduler
|
|
|