12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_reader.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/navigation_tracker.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/status.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/stub_devtools_client.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AssertPendingState(NavigationTracker* tracker,
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        const std::string& frame_id,
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        bool expected_is_pending) {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_pending = !expected_is_pending;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(kOk, tracker->IsPendingNavigation(frame_id, &is_pending).code());
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(expected_is_pending, is_pending);
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(NavigationTracker, FrameLoadStartStop) {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StubDevToolsClient client;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationTracker tracker(&client);
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk, tracker.OnEvent(&client, "Page.frameStartedLoading", params).code());
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk, tracker.OnEvent(&client, "Page.frameStoppedLoading", params).code());
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(NavigationTracker, NavigationScheduledThenLoaded) {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StubDevToolsClient client;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationTracker tracker(&client, NavigationTracker::kNotLoading);
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.SetString("frameId", "f");
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params_scheduled;
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params_scheduled.SetInteger("delay", 0);
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params_scheduled.SetString("frameId", "f");
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk,
51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      tracker.OnEvent(
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          &client, "Page.frameScheduledNavigation", params_scheduled).code());
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk, tracker.OnEvent(&client, "Page.frameStartedLoading", params).code());
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk,
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      tracker.OnEvent(&client, "Page.frameClearedScheduledNavigation", params)
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          .code());
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
63868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk, tracker.OnEvent(&client, "Page.frameStoppedLoading", params).code());
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(NavigationTracker, NavigationScheduledForOtherFrame) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StubDevToolsClient client;
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationTracker tracker(&client, NavigationTracker::kNotLoading);
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params_scheduled;
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params_scheduled.SetInteger("delay", 0);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params_scheduled.SetString("frameId", "other");
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk,
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      tracker.OnEvent(
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          &client, "Page.frameScheduledNavigation", params_scheduled).code());
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(NavigationTracker, NavigationScheduledThenCancelled) {
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StubDevToolsClient client;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationTracker tracker(&client, NavigationTracker::kNotLoading);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params.SetString("frameId", "f");
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params_scheduled;
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params_scheduled.SetInteger("delay", 0);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params_scheduled.SetString("frameId", "f");
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk,
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      tracker.OnEvent(
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          &client, "Page.frameScheduledNavigation", params_scheduled).code());
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk,
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      tracker.OnEvent(&client, "Page.frameClearedScheduledNavigation", params)
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          .code());
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(NavigationTracker, NavigationScheduledTooFarAway) {
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StubDevToolsClient client;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationTracker tracker(&client, NavigationTracker::kNotLoading);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params_scheduled;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params_scheduled.SetInteger("delay", 10);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params_scheduled.SetString("frameId", "f");
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk,
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      tracker.OnEvent(
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          &client, "Page.frameScheduledNavigation", params_scheduled).code());
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(NavigationTracker, DiscardScheduledNavigationsOnMainFrameCommit) {
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StubDevToolsClient client;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationTracker tracker(&client, NavigationTracker::kNotLoading);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params_scheduled;
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params_scheduled.SetString("frameId", "subframe");
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params_scheduled.SetInteger("delay", 0);
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk,
125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      tracker.OnEvent(
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          &client, "Page.frameScheduledNavigation", params_scheduled).code());
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "subframe", true));
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params_navigated;
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params_navigated.SetString("frame.parentId", "something");
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk,
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      tracker.OnEvent(&client, "Page.frameNavigated", params_navigated).code());
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "subframe", true));
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  params_navigated.Clear();
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  ASSERT_EQ(
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      kOk,
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      tracker.OnEvent(&client, "Page.frameNavigated", params_navigated).code());
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "subframe", false));
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class FailToEvalScriptDevToolsClient : public StubDevToolsClient {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~FailToEvalScriptDevToolsClient() {}
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual Status SendCommandAndGetResult(
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& method,
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::DictionaryValue& params,
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<base::DictionaryValue>* result) OVERRIDE {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_STREQ("Runtime.evaluate", method.c_str());
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return Status(kUnknownError, "failed to eval script");
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(NavigationTracker, UnknownStateFailsToDetermineState) {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FailToEvalScriptDevToolsClient client;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationTracker tracker(&client);
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_pending;
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(kUnknownError,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            tracker.IsPendingNavigation("f", &is_pending).code());
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class DeterminingLoadStateDevToolsClient : public StubDevToolsClient {
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterminingLoadStateDevToolsClient(
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool is_loading,
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& send_event_first,
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::DictionaryValue* send_event_first_params)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : is_loading_(is_loading),
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        send_event_first_(send_event_first),
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        send_event_first_params_(send_event_first_params) {}
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~DeterminingLoadStateDevToolsClient() {}
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual Status SendCommandAndGetResult(
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& method,
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const base::DictionaryValue& params,
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      scoped_ptr<base::DictionaryValue>* result) OVERRIDE {
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (send_event_first_.length()) {
186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      Status status = listeners_.front()
187868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)          ->OnEvent(this, send_event_first_, *send_event_first_params_);
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (status.IsError())
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        return status;
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::DictionaryValue result_dict;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result_dict.SetBoolean("result.value", is_loading_);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    result->reset(result_dict.DeepCopy());
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return Status(kOk);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_loading_;
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string send_event_first_;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue* send_event_first_params_;
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(NavigationTracker, UnknownStateForcesStart) {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DeterminingLoadStateDevToolsClient client(true, std::string(), &params);
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationTracker tracker(&client);
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST(NavigationTracker, UnknownStateForcesStartReceivesStop) {
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::DictionaryValue params;
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DeterminingLoadStateDevToolsClient client(
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      true, "Page.frameStoppedLoading", &params);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NavigationTracker tracker(&client);
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
22158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST(NavigationTracker, OnSuccessfulNavigate) {
22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::DictionaryValue params;
22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DeterminingLoadStateDevToolsClient client(
22458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      true, "Page.frameStoppedLoading", &params);
22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NavigationTracker tracker(&client, NavigationTracker::kNotLoading);
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  tracker.OnCommandSuccess(&client, "Page.navigate");
22758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", false));
22858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)TEST(NavigationTracker, OnSuccessfulNavigateStillWaiting) {
23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  base::DictionaryValue params;
23258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  DeterminingLoadStateDevToolsClient client(true, std::string(), &params);
23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  NavigationTracker tracker(&client, NavigationTracker::kNotLoading);
23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  tracker.OnCommandSuccess(&client, "Page.navigate");
23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  ASSERT_NO_FATAL_FAILURE(AssertPendingState(&tracker, "f", true));
23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
237