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 15 namespace chromeos { 16 17 class 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 if (!on_step_shown_callback_.is_null()) 39 on_step_shown_callback_.Run(); 40 controller()->OnStepShown(step_name); 41 } 42 43 virtual void OnStepHidden(const std::string& step_name) OVERRIDE { 44 controller()->OnStepHidden(step_name); 45 } 46 47 virtual void OnHelpButtonClicked() OVERRIDE { 48 controller()->OnHelpButtonClicked(); 49 } 50 51 virtual void OnActorFinalized() OVERRIDE { 52 finalized_ = true; 53 if (!on_finalized_callback_.is_null()) 54 on_finalized_callback_.Run(); 55 controller()->OnActorFinalized(); 56 } 57 58 virtual void OnActorDestroyed() OVERRIDE { 59 controller()->OnActorDestroyed(); 60 } 61 62 void LaunchTutorial() { 63 chromeos::first_run::LaunchTutorial(); 64 EXPECT_TRUE(controller() != NULL); 65 // Replacing delegate to observe all messages coming from WebUI to 66 // controller. 67 controller()->actor_->set_delegate(this); 68 initialized_ = controller()->actor_->IsInitialized(); 69 } 70 71 void WaitForInitialization() { 72 if (initialized_) 73 return; 74 WaitUntilCalled(&on_initialized_callback_); 75 EXPECT_TRUE(initialized_); 76 js().set_web_contents(controller()->web_contents_for_tests_); 77 } 78 79 void WaitForStep(const std::string& step_name) { 80 if (GetCurrentStepName() == step_name) 81 return; 82 WaitUntilCalled(&on_step_shown_callback_); 83 EXPECT_EQ(GetCurrentStepName(), step_name); 84 } 85 86 void AdvanceStep() { 87 js().Evaluate("cr.FirstRun.currentStep_.nextButton_.click()"); 88 } 89 90 void WaitForFinalization() { 91 if (!finalized_) { 92 WaitUntilCalled(&on_finalized_callback_); 93 EXPECT_TRUE(finalized_); 94 } 95 } 96 97 void WaitUntilCalled(base::Closure* callback) { 98 scoped_refptr<content::MessageLoopRunner> runner = 99 new content::MessageLoopRunner; 100 *callback = runner->QuitClosure(); 101 runner->Run(); 102 callback->Reset(); 103 } 104 105 std::string GetCurrentStepName() { 106 return js().GetString( 107 "cr.FirstRun.currentStep_ ? cr.FirstRun.currentStep_.getName() : ''"); 108 } 109 110 test::JSChecker& js() { return js_; } 111 112 ash::FirstRunHelper* shell_helper() { 113 return controller()->shell_helper_.get(); 114 } 115 116 FirstRunController* controller() { 117 return FirstRunController::GetInstanceForTest(); 118 } 119 120 private: 121 bool initialized_; 122 bool finalized_; 123 base::Closure on_initialized_callback_; 124 base::Closure on_step_shown_callback_; 125 base::Closure on_finalized_callback_; 126 test::JSChecker js_; 127 }; 128 129 IN_PROC_BROWSER_TEST_F(FirstRunUIBrowserTest, FirstRunFlow) { 130 LaunchTutorial(); 131 WaitForInitialization(); 132 WaitForStep(first_run::kAppListStep); 133 EXPECT_FALSE(shell_helper()->IsTrayBubbleOpened()); 134 AdvanceStep(); 135 WaitForStep(first_run::kTrayStep); 136 EXPECT_TRUE(shell_helper()->IsTrayBubbleOpened()); 137 AdvanceStep(); 138 WaitForStep(first_run::kHelpStep); 139 EXPECT_TRUE(shell_helper()->IsTrayBubbleOpened()); 140 AdvanceStep(); 141 WaitForFinalization(); 142 content::RunAllPendingInMessageLoop(); 143 EXPECT_EQ(controller(), (void*)NULL); 144 // shell_helper() is destructed already, thats why we call Shell directly. 145 EXPECT_FALSE(ash::Shell::GetInstance()->GetPrimarySystemTray()-> 146 HasSystemBubble()); 147 } 148 149 } // namespace chromeos 150 151