1// Copyright 2013 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 "ash/first_run/first_run_helper.h"
6#include "ash/shell.h"
7#include "ash/system/tray/system_tray.h"
8#include "chrome/browser/chromeos/first_run/first_run.h"
9#include "chrome/browser/chromeos/first_run/first_run_controller.h"
10#include "chrome/browser/chromeos/first_run/step_names.h"
11#include "chrome/browser/chromeos/login/test/js_checker.h"
12#include "chrome/test/base/in_process_browser_test.h"
13#include "content/public/test/test_utils.h"
14
15namespace chromeos {
16
17class FirstRunUIBrowserTest : public InProcessBrowserTest,
18                              public FirstRunActor::Delegate {
19 public:
20  FirstRunUIBrowserTest()
21      : initialized_(false),
22        finalized_(false) {
23  }
24
25  // FirstRunActor::Delegate overrides.
26  virtual void OnActorInitialized() OVERRIDE {
27    initialized_ = true;
28    if (!on_initialized_callback_.is_null())
29      on_initialized_callback_.Run();
30    controller()->OnActorInitialized();
31  }
32
33  virtual void OnNextButtonClicked(const std::string& step_name) OVERRIDE {
34    controller()->OnNextButtonClicked(step_name);
35  }
36
37  virtual void OnStepShown(const std::string& step_name) OVERRIDE {
38    current_step_name_ = step_name;
39    if (!on_step_shown_callback_.is_null())
40      on_step_shown_callback_.Run();
41    controller()->OnStepShown(step_name);
42  }
43
44  virtual void OnStepHidden(const std::string& step_name) OVERRIDE {
45    controller()->OnStepHidden(step_name);
46  }
47
48  virtual void OnHelpButtonClicked() OVERRIDE {
49    controller()->OnHelpButtonClicked();
50  }
51
52  virtual void OnActorFinalized() OVERRIDE {
53    finalized_ = true;
54    if (!on_finalized_callback_.is_null())
55      on_finalized_callback_.Run();
56    controller()->OnActorFinalized();
57  }
58
59  virtual void OnActorDestroyed() OVERRIDE {
60    controller()->OnActorDestroyed();
61  }
62
63  void LaunchTutorial() {
64    chromeos::first_run::LaunchTutorial();
65    EXPECT_TRUE(controller() != NULL);
66    // Replacing delegate to observe all messages coming from WebUI to
67    // controller.
68    controller()->actor_->set_delegate(this);
69    initialized_ = controller()->actor_->IsInitialized();
70  }
71
72  void WaitForInitialization() {
73    if (initialized_)
74      return;
75    WaitUntilCalled(&on_initialized_callback_);
76    EXPECT_TRUE(initialized_);
77    js().set_web_contents(controller()->web_contents_for_tests_);
78  }
79
80  void WaitForStep(const std::string& step_name) {
81    if (current_step_name_ == step_name)
82      return;
83    WaitUntilCalled(&on_step_shown_callback_);
84    EXPECT_EQ(current_step_name_, step_name);
85  }
86
87  void AdvanceStep() {
88    js().Evaluate("cr.FirstRun.currentStep_.nextButton_.click()");
89  }
90
91  void WaitForFinalization() {
92    if (!finalized_) {
93      WaitUntilCalled(&on_finalized_callback_);
94      EXPECT_TRUE(finalized_);
95    }
96  }
97
98  void WaitUntilCalled(base::Closure* callback) {
99    scoped_refptr<content::MessageLoopRunner> runner =
100        new content::MessageLoopRunner;
101    *callback = runner->QuitClosure();
102    runner->Run();
103    callback->Reset();
104  }
105
106  test::JSChecker& js() { return js_; }
107
108  ash::FirstRunHelper* shell_helper() {
109    return controller()->shell_helper_.get();
110  }
111
112  FirstRunController* controller() {
113    return FirstRunController::GetInstanceForTest();
114  }
115
116 private:
117  std::string current_step_name_;
118  bool initialized_;
119  bool finalized_;
120  base::Closure on_initialized_callback_;
121  base::Closure on_step_shown_callback_;
122  base::Closure on_finalized_callback_;
123  test::JSChecker js_;
124};
125
126IN_PROC_BROWSER_TEST_F(FirstRunUIBrowserTest, FirstRunFlow) {
127  LaunchTutorial();
128  WaitForInitialization();
129  WaitForStep(first_run::kAppListStep);
130  EXPECT_FALSE(shell_helper()->IsTrayBubbleOpened());
131  AdvanceStep();
132  WaitForStep(first_run::kTrayStep);
133  EXPECT_TRUE(shell_helper()->IsTrayBubbleOpened());
134  AdvanceStep();
135  WaitForStep(first_run::kHelpStep);
136  EXPECT_TRUE(shell_helper()->IsTrayBubbleOpened());
137  AdvanceStep();
138  WaitForFinalization();
139  content::RunAllPendingInMessageLoop();
140  EXPECT_EQ(controller(), (void*)NULL);
141  // shell_helper() is destructed already, thats why we call Shell directly.
142  EXPECT_FALSE(ash::Shell::GetInstance()->GetPrimarySystemTray()->
143      HasSystemBubble());
144}
145
146}  // namespace chromeos
147
148