login_screen_test_api.cc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  1. // Copyright 2018 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. #include "ash/public/cpp/login_screen_test_api.h"
  5. #include <memory>
  6. #include <utility>
  7. #include <vector>
  8. #include "ash/login/ui/arrow_button_view.h"
  9. #include "ash/login/ui/kiosk_app_default_message.h"
  10. #include "ash/login/ui/lock_contents_view.h"
  11. #include "ash/login/ui/lock_screen.h"
  12. #include "ash/login/ui/login_auth_user_view.h"
  13. #include "ash/login/ui/login_big_user_view.h"
  14. #include "ash/login/ui/login_expanded_public_account_view.h"
  15. #include "ash/login/ui/login_password_view.h"
  16. #include "ash/login/ui/login_pin_view.h"
  17. #include "ash/login/ui/login_remove_account_dialog.h"
  18. #include "ash/login/ui/login_user_view.h"
  19. #include "ash/login/ui/pin_request_view.h"
  20. #include "ash/login/ui/pin_request_widget.h"
  21. #include "ash/public/cpp/login_screen.h"
  22. #include "ash/public/cpp/login_screen_client.h"
  23. #include "ash/shelf/login_shelf_view.h"
  24. #include "ash/shelf/shelf.h"
  25. #include "ash/shelf/shelf_widget.h"
  26. #include "ash/shell.h"
  27. #include "base/callback.h"
  28. #include "base/check.h"
  29. #include "base/run_loop.h"
  30. #include "testing/gtest/include/gtest/gtest.h"
  31. #include "ui/base/test/ui_controls.h"
  32. #include "ui/compositor/layer.h"
  33. #include "ui/events/test/event_generator.h"
  34. #include "ui/gfx/geometry/rect.h"
  35. #include "ui/views/controls/button/label_button.h"
  36. #include "ui/views/controls/textfield/textfield.h"
  37. #include "ui/views/test/button_test_api.h"
  38. #include "ui/views/view.h"
  39. namespace ash {
  40. namespace {
  41. // Creates an event generator for simulating interactions with the Ash window.
  42. std::unique_ptr<ui::test::EventGenerator> MakeAshEventGenerator() {
  43. return std::make_unique<ui::test::EventGenerator>(
  44. Shell::GetPrimaryRootWindow());
  45. }
  46. LoginShelfView* GetLoginShelfView() {
  47. if (!Shell::HasInstance())
  48. return nullptr;
  49. return Shelf::ForWindow(Shell::GetPrimaryRootWindow())
  50. ->shelf_widget()
  51. ->GetLoginShelfView();
  52. }
  53. bool IsLoginShelfViewButtonShown(int button_view_id) {
  54. LoginShelfView* shelf_view = GetLoginShelfView();
  55. if (!shelf_view)
  56. return false;
  57. views::View* button_view = shelf_view->GetViewByID(button_view_id);
  58. return button_view && button_view->GetVisible();
  59. }
  60. views::View* GetShutDownButton() {
  61. LoginShelfView* shelf_view = GetLoginShelfView();
  62. if (!shelf_view)
  63. return nullptr;
  64. return shelf_view->GetViewByID(LoginShelfView::kShutdown);
  65. }
  66. LoginBigUserView* GetBigUserView(const AccountId& account_id) {
  67. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  68. LockContentsView::TestApi lock_contents_test(
  69. lock_screen_test.contents_view());
  70. return lock_contents_test.FindBigUser(account_id);
  71. }
  72. bool SimulateButtonPressedForTesting(LoginShelfView::ButtonId button_id) {
  73. LoginShelfView* shelf_view = GetLoginShelfView();
  74. if (!shelf_view)
  75. return false;
  76. views::View* button = shelf_view->GetViewByID(button_id);
  77. if (!button->GetEnabled())
  78. return false;
  79. views::test::ButtonTestApi(views::Button::AsButton(button))
  80. .NotifyClick(ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::PointF(),
  81. gfx::PointF(), base::TimeTicks(), 0, 0));
  82. return true;
  83. }
  84. } // anonymous namespace
  85. class ShelfTestUiUpdateDelegate : public LoginShelfView::TestUiUpdateDelegate {
  86. public:
  87. // Returns instance owned by LoginShelfView. Installs instance of
  88. // ShelfTestUiUpdateDelegate when needed.
  89. static ShelfTestUiUpdateDelegate* Get(LoginShelfView* shelf) {
  90. if (!shelf->test_ui_update_delegate()) {
  91. shelf->InstallTestUiUpdateDelegate(
  92. std::make_unique<ShelfTestUiUpdateDelegate>());
  93. }
  94. return static_cast<ShelfTestUiUpdateDelegate*>(
  95. shelf->test_ui_update_delegate());
  96. }
  97. ShelfTestUiUpdateDelegate() = default;
  98. ShelfTestUiUpdateDelegate(const ShelfTestUiUpdateDelegate&) = delete;
  99. ShelfTestUiUpdateDelegate& operator=(const ShelfTestUiUpdateDelegate&) =
  100. delete;
  101. ~ShelfTestUiUpdateDelegate() override {
  102. for (PendingCallback& entry : heap_)
  103. std::move(entry.callback).Run();
  104. }
  105. // Returns UI update count.
  106. int64_t ui_update_count() const { return ui_update_count_; }
  107. // Add a callback to be invoked when ui update count is greater than
  108. // |previous_update_count|. Note |callback| could be invoked synchronously
  109. // when the current ui update count is already greater than
  110. // |previous_update_count|.
  111. void AddCallback(int64_t previous_update_count, base::OnceClosure callback) {
  112. if (previous_update_count < ui_update_count_) {
  113. std::move(callback).Run();
  114. } else {
  115. heap_.emplace_back(previous_update_count, std::move(callback));
  116. std::push_heap(heap_.begin(), heap_.end());
  117. }
  118. }
  119. // LoginShelfView::TestUiUpdateDelegate
  120. void OnUiUpdate() override {
  121. ++ui_update_count_;
  122. while (!heap_.empty() && heap_.front().old_count < ui_update_count_) {
  123. std::move(heap_.front().callback).Run();
  124. std::pop_heap(heap_.begin(), heap_.end());
  125. heap_.pop_back();
  126. }
  127. }
  128. private:
  129. struct PendingCallback {
  130. PendingCallback(int64_t old_count, base::OnceClosure callback)
  131. : old_count(old_count), callback(std::move(callback)) {}
  132. bool operator<(const PendingCallback& right) const {
  133. // We need min_heap, therefore this returns true when another element on
  134. // the right is less than this count. (regular heap is max_heap).
  135. return old_count > right.old_count;
  136. }
  137. int64_t old_count = 0;
  138. base::OnceClosure callback;
  139. };
  140. std::vector<PendingCallback> heap_;
  141. int64_t ui_update_count_ = 0;
  142. };
  143. // static
  144. bool LoginScreenTestApi::IsLockShown() {
  145. return LockScreen::HasInstance() && LockScreen::Get()->is_shown() &&
  146. LockScreen::Get()->screen_type() == LockScreen::ScreenType::kLock;
  147. }
  148. // static
  149. void LoginScreenTestApi::AddOnLockScreenShownCallback(
  150. base::OnceClosure on_lock_screen_shown) {
  151. if (!LockScreen::HasInstance())
  152. FAIL() << "No lock screen";
  153. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  154. lock_screen_test.AddOnShownCallback(std::move(on_lock_screen_shown));
  155. }
  156. // static
  157. bool LoginScreenTestApi::IsLoginShelfShown() {
  158. LoginShelfView* view = GetLoginShelfView();
  159. return view && view->GetVisible();
  160. }
  161. // static
  162. bool LoginScreenTestApi::IsRestartButtonShown() {
  163. return IsLoginShelfViewButtonShown(LoginShelfView::kRestart);
  164. }
  165. // static
  166. bool LoginScreenTestApi::IsShutdownButtonShown() {
  167. return IsLoginShelfViewButtonShown(LoginShelfView::kShutdown);
  168. }
  169. // static
  170. bool LoginScreenTestApi::IsAppsButtonShown() {
  171. return IsLoginShelfViewButtonShown(LoginShelfView::kApps);
  172. }
  173. // static
  174. bool LoginScreenTestApi::IsAuthErrorBubbleShown() {
  175. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  176. LockContentsView::TestApi lock_contents_test(
  177. lock_screen_test.contents_view());
  178. return lock_contents_test.auth_error_bubble()->GetVisible();
  179. }
  180. // static
  181. bool LoginScreenTestApi::IsGuestButtonShown() {
  182. return IsLoginShelfViewButtonShown(LoginShelfView::kBrowseAsGuest);
  183. }
  184. // static
  185. bool LoginScreenTestApi::IsAddUserButtonShown() {
  186. return IsLoginShelfViewButtonShown(LoginShelfView::kAddUser);
  187. }
  188. // static
  189. bool LoginScreenTestApi::IsCancelButtonShown() {
  190. return IsLoginShelfViewButtonShown(LoginShelfView::kCancel);
  191. }
  192. // static
  193. bool LoginScreenTestApi::IsParentAccessButtonShown() {
  194. return IsLoginShelfViewButtonShown(LoginShelfView::kParentAccess);
  195. }
  196. // static
  197. bool LoginScreenTestApi::IsEnterpriseEnrollmentButtonShown() {
  198. return IsLoginShelfViewButtonShown(LoginShelfView::kEnterpriseEnrollment);
  199. }
  200. // static
  201. bool LoginScreenTestApi::IsOsInstallButtonShown() {
  202. return IsLoginShelfViewButtonShown(LoginShelfView::kOsInstall);
  203. }
  204. // static
  205. bool LoginScreenTestApi::IsUserAddingScreenIndicatorShown() {
  206. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  207. LockContentsView::TestApi lock_contents_test(
  208. lock_screen_test.contents_view());
  209. views::View* indicator = lock_contents_test.user_adding_screen_indicator();
  210. return indicator && indicator->GetVisible();
  211. }
  212. // static
  213. bool LoginScreenTestApi::IsWarningBubbleShown() {
  214. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  215. LockContentsView::TestApi lock_contents_test(
  216. lock_screen_test.contents_view());
  217. return lock_contents_test.warning_banner_bubble()->GetVisible();
  218. }
  219. // static
  220. bool LoginScreenTestApi::IsSystemInfoShown() {
  221. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  222. LockContentsView::TestApi lock_contents_test(
  223. lock_screen_test.contents_view());
  224. // Check if all views in the hierarchy are visible.
  225. for (views::View* view = lock_contents_test.system_info(); view != nullptr;
  226. view = view->parent()) {
  227. if (!view->GetVisible())
  228. return false;
  229. }
  230. return true;
  231. }
  232. // static
  233. bool LoginScreenTestApi::IsKioskDefaultMessageShown() {
  234. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  235. LockContentsView::TestApi test_api(lock_screen_test.contents_view());
  236. return test_api.kiosk_default_message() &&
  237. test_api.kiosk_default_message()->GetVisible();
  238. }
  239. // static
  240. bool LoginScreenTestApi::IsKioskInstructionBubbleShown() {
  241. LoginShelfView* view = GetLoginShelfView();
  242. return view->GetKioskInstructionBubbleForTesting() &&
  243. view->GetKioskInstructionBubbleForTesting()->GetWidget() &&
  244. view->GetKioskInstructionBubbleForTesting()->GetWidget()->IsVisible();
  245. }
  246. // static
  247. bool LoginScreenTestApi::IsPasswordFieldShown(const AccountId& account_id) {
  248. if (GetFocusedUser() != account_id) {
  249. ADD_FAILURE() << "The user " << account_id.Serialize() << " is not focused";
  250. return false;
  251. }
  252. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  253. if (!big_user_view) {
  254. ADD_FAILURE() << "Could not find user " << account_id.Serialize();
  255. return false;
  256. }
  257. LoginAuthUserView::TestApi auth_test(big_user_view->auth_user());
  258. return auth_test.password_view()->IsDrawn();
  259. }
  260. // static
  261. bool LoginScreenTestApi::IsDisplayPasswordButtonShown(
  262. const AccountId& account_id) {
  263. if (!FocusUser(account_id)) {
  264. ADD_FAILURE() << "Could not focus on user " << account_id.Serialize();
  265. return false;
  266. }
  267. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  268. if (!big_user_view) {
  269. ADD_FAILURE() << "Could not find user " << account_id.Serialize();
  270. return false;
  271. }
  272. if (!big_user_view->IsAuthEnabled()) {
  273. ADD_FAILURE() << "Auth is not enabled for user " << account_id.Serialize();
  274. return false;
  275. }
  276. LoginAuthUserView::TestApi auth_test(big_user_view->auth_user());
  277. if (!auth_test.HasAuthMethod(LoginAuthUserView::AUTH_PASSWORD)) {
  278. ADD_FAILURE() << "Password auth is not enabled for user "
  279. << account_id.Serialize();
  280. return false;
  281. }
  282. LoginPasswordView::TestApi password_test(auth_test.password_view());
  283. bool display_password_button_visible =
  284. auth_test.user_view()->current_user().show_display_password_button;
  285. EXPECT_EQ(display_password_button_visible,
  286. password_test.display_password_button()->GetVisible());
  287. return display_password_button_visible;
  288. }
  289. // static
  290. bool LoginScreenTestApi::IsManagedIconShown(const AccountId& account_id) {
  291. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  292. if (!big_user_view) {
  293. ADD_FAILURE() << "Could not find user " << account_id.Serialize();
  294. return false;
  295. }
  296. LoginUserView::TestApi user_test(big_user_view->GetUserView());
  297. auto* enterprise_icon = user_test.enterprise_icon();
  298. return enterprise_icon->GetVisible();
  299. }
  300. // static
  301. bool LoginScreenTestApi::IsManagedMessageInDialogShown(
  302. const AccountId& account_id) {
  303. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  304. if (!big_user_view) {
  305. ADD_FAILURE() << "Could not find user " << account_id.Serialize();
  306. return false;
  307. }
  308. LoginUserView::TestApi user_test(big_user_view->GetUserView());
  309. LoginRemoveAccountDialog::TestApi user_dialog_test(
  310. user_test.remove_account_dialog());
  311. auto* management_disclosure_label =
  312. user_dialog_test.management_disclosure_label();
  313. return management_disclosure_label &&
  314. management_disclosure_label->GetVisible();
  315. }
  316. // static
  317. bool LoginScreenTestApi::IsForcedOnlineSignin(const AccountId& account_id) {
  318. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  319. if (!big_user_view) {
  320. ADD_FAILURE() << "Could not find user " << account_id.Serialize();
  321. return false;
  322. }
  323. LoginAuthUserView::TestApi auth_test(big_user_view->auth_user());
  324. return auth_test.HasAuthMethod(LoginAuthUserView::AUTH_ONLINE_SIGN_IN);
  325. }
  326. // static
  327. void LoginScreenTestApi::SubmitPassword(const AccountId& account_id,
  328. const std::string& password,
  329. bool check_if_submittable) {
  330. // It'd be better to generate keyevents dynamically and dispatch them instead
  331. // of reaching into the views structure, but at the time of writing I could
  332. // not find a good way to do this. If you know of a way feel free to change
  333. // this code.
  334. ASSERT_TRUE(FocusUser(account_id));
  335. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  336. ASSERT_TRUE(big_user_view);
  337. ASSERT_TRUE(big_user_view->IsAuthEnabled());
  338. LoginAuthUserView::TestApi auth_test(big_user_view->auth_user());
  339. if (check_if_submittable)
  340. ASSERT_TRUE(auth_test.HasAuthMethod(LoginAuthUserView::AUTH_PASSWORD));
  341. LoginPasswordView::TestApi password_test(auth_test.password_view());
  342. ASSERT_EQ(account_id,
  343. auth_test.user_view()->current_user().basic_user_info.account_id);
  344. password_test.SubmitPassword(password);
  345. }
  346. // static
  347. std::u16string LoginScreenTestApi::GetChallengeResponseLabel(
  348. const AccountId& account_id) {
  349. if (GetFocusedUser() != account_id) {
  350. ADD_FAILURE() << "The user " << account_id.Serialize() << " is not focused";
  351. return std::u16string();
  352. }
  353. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  354. if (!big_user_view) {
  355. ADD_FAILURE() << "Could not find user " << account_id.Serialize();
  356. return std::u16string();
  357. }
  358. LoginAuthUserView::TestApi auth_test(big_user_view->auth_user());
  359. if (!auth_test.challenge_response_label()->IsDrawn()) {
  360. ADD_FAILURE() << "Challenge-response label is not drawn for user "
  361. << account_id.Serialize();
  362. return std::u16string();
  363. }
  364. return auth_test.challenge_response_label()->GetText();
  365. }
  366. // static
  367. bool LoginScreenTestApi::IsChallengeResponseButtonClickable(
  368. const AccountId& account_id) {
  369. if (GetFocusedUser() != account_id) {
  370. ADD_FAILURE() << "The user " << account_id.Serialize() << " is not focused";
  371. return false;
  372. }
  373. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  374. if (!big_user_view) {
  375. ADD_FAILURE() << "Could not find user " << account_id.Serialize();
  376. return false;
  377. }
  378. LoginAuthUserView::TestApi auth_test(big_user_view->auth_user());
  379. if (!auth_test.challenge_response_button()->IsDrawn()) {
  380. ADD_FAILURE() << "Challenge-response button is not drawn for user "
  381. << account_id.Serialize();
  382. return false;
  383. }
  384. return auth_test.challenge_response_button()->GetEnabled();
  385. }
  386. // static
  387. void LoginScreenTestApi::ClickChallengeResponseButton(
  388. const AccountId& account_id) {
  389. if (!FocusUser(account_id))
  390. FAIL() << "Could not focus on user " << account_id.Serialize();
  391. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  392. if (!big_user_view)
  393. FAIL() << "Could not find user " << account_id.Serialize();
  394. if (!big_user_view->IsAuthEnabled())
  395. FAIL() << "Auth is not enabled for user " << account_id.Serialize();
  396. LoginAuthUserView::TestApi auth_test(big_user_view->auth_user());
  397. if (!auth_test.HasAuthMethod(LoginAuthUserView::AUTH_CHALLENGE_RESPONSE)) {
  398. FAIL() << "Challenge-response auth is not enabled for user "
  399. << account_id.Serialize();
  400. }
  401. if (!auth_test.challenge_response_button()->IsDrawn()) {
  402. FAIL() << "Challenge-response button is not drawn for user "
  403. << account_id.Serialize();
  404. }
  405. auto event_generator = MakeAshEventGenerator();
  406. event_generator->MoveMouseTo(
  407. auth_test.challenge_response_button()->GetBoundsInScreen().CenterPoint());
  408. event_generator->ClickLeftButton();
  409. }
  410. // static
  411. int64_t LoginScreenTestApi::GetUiUpdateCount() {
  412. LoginShelfView* view = GetLoginShelfView();
  413. return view ? ShelfTestUiUpdateDelegate::Get(view)->ui_update_count() : 0;
  414. }
  415. // static
  416. bool LoginScreenTestApi::LaunchApp(const std::string& app_id) {
  417. LoginShelfView* view = GetLoginShelfView();
  418. return view && view->LaunchAppForTesting(app_id);
  419. }
  420. // static
  421. bool LoginScreenTestApi::ClickAppsButton() {
  422. return SimulateButtonPressedForTesting(LoginShelfView::kApps);
  423. }
  424. // static
  425. bool LoginScreenTestApi::ClickAddUserButton() {
  426. return SimulateButtonPressedForTesting(LoginShelfView::kAddUser);
  427. }
  428. // static
  429. bool LoginScreenTestApi::ClickCancelButton() {
  430. return SimulateButtonPressedForTesting(LoginShelfView::kCancel);
  431. }
  432. // static
  433. bool LoginScreenTestApi::ClickGuestButton() {
  434. return SimulateButtonPressedForTesting(LoginShelfView::kBrowseAsGuest);
  435. }
  436. // static
  437. bool LoginScreenTestApi::ClickEnterpriseEnrollmentButton() {
  438. return SimulateButtonPressedForTesting(LoginShelfView::kEnterpriseEnrollment);
  439. }
  440. // static
  441. bool LoginScreenTestApi::ClickOsInstallButton() {
  442. return SimulateButtonPressedForTesting(LoginShelfView::kOsInstall);
  443. }
  444. // static
  445. bool LoginScreenTestApi::PressAccelerator(const ui::Accelerator& accelerator) {
  446. // TODO(https://crbug.com/1321609): Migrate to SendAcceleratorNatively.
  447. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  448. return lock_screen_test.contents_view()->AcceleratorPressed(accelerator);
  449. }
  450. // static
  451. bool LoginScreenTestApi::SendAcceleratorNatively(
  452. const ui::Accelerator& accelerator) {
  453. gfx::NativeWindow login_window = nullptr;
  454. if (LockScreen::HasInstance()) {
  455. login_window = LockScreen::Get()->widget()->GetNativeWindow();
  456. } else {
  457. login_window =
  458. LoginScreen::Get()->GetLoginWindowWidget()->GetNativeWindow();
  459. }
  460. if (!login_window)
  461. return false;
  462. return ui_controls::SendKeyPress(
  463. login_window, accelerator.key_code(), accelerator.IsCtrlDown(),
  464. accelerator.IsShiftDown(), accelerator.IsAltDown(),
  465. accelerator.IsCmdDown());
  466. }
  467. // static
  468. bool LoginScreenTestApi::WaitForUiUpdate(int64_t previous_update_count) {
  469. LoginShelfView* view = GetLoginShelfView();
  470. if (view) {
  471. base::RunLoop run_loop;
  472. ShelfTestUiUpdateDelegate::Get(view)->AddCallback(previous_update_count,
  473. run_loop.QuitClosure());
  474. run_loop.Run();
  475. return true;
  476. }
  477. return false;
  478. }
  479. int LoginScreenTestApi::GetUsersCount() {
  480. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  481. LockContentsView::TestApi lock_contents_test(
  482. lock_screen_test.contents_view());
  483. return lock_contents_test.users().size();
  484. }
  485. // static
  486. bool LoginScreenTestApi::FocusKioskDefaultMessage() {
  487. if (!IsKioskDefaultMessageShown()) {
  488. ADD_FAILURE() << "Kiosk default message is not visible.";
  489. return false;
  490. }
  491. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  492. LockContentsView::TestApi test_api(lock_screen_test.contents_view());
  493. auto event_generator = MakeAshEventGenerator();
  494. event_generator->MoveMouseTo(
  495. test_api.kiosk_default_message()->GetBoundsInScreen().CenterPoint());
  496. event_generator->ClickLeftButton();
  497. return true;
  498. }
  499. // static
  500. bool LoginScreenTestApi::FocusUser(const AccountId& account_id) {
  501. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  502. if (!big_user_view) {
  503. ADD_FAILURE() << "User not found " << account_id;
  504. return false;
  505. }
  506. LoginUserView::TestApi user_test(big_user_view->GetUserView());
  507. user_test.OnTap();
  508. return GetFocusedUser() == account_id;
  509. }
  510. // static
  511. bool LoginScreenTestApi::ExpandPublicSessionPod(const AccountId& account_id) {
  512. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  513. LockContentsView::TestApi lock_contents_test(
  514. lock_screen_test.contents_view());
  515. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  516. if (!big_user_view)
  517. return false;
  518. LoginPublicAccountUserView::TestApi public_account_test(
  519. big_user_view->public_account());
  520. if (!public_account_test.arrow_button()->GetVisible()) {
  521. ADD_FAILURE() << "Arrow button not visible";
  522. return false;
  523. }
  524. views::test::ButtonTestApi(
  525. views::Button::AsButton(public_account_test.arrow_button()))
  526. .NotifyClick(ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::PointF(),
  527. gfx::PointF(), base::TimeTicks(), 0, 0));
  528. return lock_contents_test.expanded_view();
  529. }
  530. // static
  531. bool LoginScreenTestApi::HidePublicSessionExpandedPod() {
  532. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  533. LockContentsView::TestApi lock_contents_test(
  534. lock_screen_test.contents_view());
  535. LoginExpandedPublicAccountView* expanded_view =
  536. lock_contents_test.expanded_view();
  537. if (!expanded_view || !expanded_view->GetVisible())
  538. return false;
  539. expanded_view->Hide();
  540. return true;
  541. }
  542. // static
  543. bool LoginScreenTestApi::IsPublicSessionExpanded() {
  544. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  545. LockContentsView::TestApi lock_contents_test(
  546. lock_screen_test.contents_view());
  547. LoginExpandedPublicAccountView* expanded_view =
  548. lock_contents_test.expanded_view();
  549. return expanded_view && expanded_view->GetVisible();
  550. }
  551. // static
  552. bool LoginScreenTestApi::IsExpandedPublicSessionAdvanced() {
  553. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  554. LockContentsView::TestApi lock_contents_test(
  555. lock_screen_test.contents_view());
  556. LoginExpandedPublicAccountView::TestApi expanded_test(
  557. lock_contents_test.expanded_view());
  558. return expanded_test.advanced_view()->GetVisible();
  559. }
  560. bool LoginScreenTestApi::IsPublicSessionWarningShown() {
  561. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  562. LockContentsView::TestApi lock_contents_test(
  563. lock_screen_test.contents_view());
  564. LoginExpandedPublicAccountView::TestApi expanded_test(
  565. lock_contents_test.expanded_view());
  566. return expanded_test.monitoring_warning_icon() &&
  567. expanded_test.monitoring_warning_label();
  568. }
  569. // static
  570. void LoginScreenTestApi::ClickPublicExpandedAdvancedViewButton() {
  571. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  572. LockContentsView::TestApi lock_contents_test(
  573. lock_screen_test.contents_view());
  574. LoginExpandedPublicAccountView::TestApi expanded_test(
  575. lock_contents_test.expanded_view());
  576. views::test::ButtonTestApi(
  577. views::Button::AsButton(expanded_test.advanced_view_button()))
  578. .NotifyClick(ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::PointF(),
  579. gfx::PointF(), base::TimeTicks(), 0, 0));
  580. }
  581. // static
  582. void LoginScreenTestApi::ClickPublicExpandedSubmitButton() {
  583. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  584. LockContentsView::TestApi lock_contents_test(
  585. lock_screen_test.contents_view());
  586. LoginExpandedPublicAccountView::TestApi expanded_test(
  587. lock_contents_test.expanded_view());
  588. views::test::ButtonTestApi(
  589. views::Button::AsButton(expanded_test.submit_button()))
  590. .NotifyClick(ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::PointF(),
  591. gfx::PointF(), base::TimeTicks(), 0, 0));
  592. }
  593. // static
  594. void LoginScreenTestApi::SetPublicSessionLocale(const std::string& locale) {
  595. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  596. LockContentsView::TestApi lock_contents_test(
  597. lock_screen_test.contents_view());
  598. LoginExpandedPublicAccountView::TestApi expanded_test(
  599. lock_contents_test.expanded_view());
  600. ASSERT_TRUE(expanded_test.SelectLanguage(locale));
  601. }
  602. // static
  603. void LoginScreenTestApi::SetPublicSessionKeyboard(const std::string& ime_id) {
  604. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  605. LockContentsView::TestApi lock_contents_test(
  606. lock_screen_test.contents_view());
  607. LoginExpandedPublicAccountView::TestApi expanded_test(
  608. lock_contents_test.expanded_view());
  609. ASSERT_TRUE(expanded_test.SelectKeyboard(ime_id))
  610. << "Failed to select " << ime_id;
  611. }
  612. // static
  613. std::vector<ash::LocaleItem> LoginScreenTestApi::GetPublicSessionLocales(
  614. const AccountId& account_id) {
  615. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  616. if (!big_user_view) {
  617. ADD_FAILURE() << "Could not find user " << account_id.Serialize();
  618. return std::vector<ash::LocaleItem>();
  619. }
  620. return big_user_view->public_account()
  621. ->user_view()
  622. ->current_user()
  623. .public_account_info->available_locales;
  624. }
  625. // static
  626. std::vector<ash::LocaleItem>
  627. LoginScreenTestApi::GetExpandedPublicSessionLocales() {
  628. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  629. LockContentsView::TestApi lock_contents_test(
  630. lock_screen_test.contents_view());
  631. LoginExpandedPublicAccountView::TestApi expanded_test(
  632. lock_contents_test.expanded_view());
  633. return expanded_test.GetLocales();
  634. }
  635. // static
  636. std::string LoginScreenTestApi::GetExpandedPublicSessionSelectedLocale() {
  637. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  638. LockContentsView::TestApi lock_contents_test(
  639. lock_screen_test.contents_view());
  640. LoginExpandedPublicAccountView::TestApi expanded_test(
  641. lock_contents_test.expanded_view());
  642. return expanded_test.selected_language_item_value();
  643. }
  644. // static
  645. std::string LoginScreenTestApi::GetExpandedPublicSessionSelectedKeyboard() {
  646. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  647. LockContentsView::TestApi lock_contents_test(
  648. lock_screen_test.contents_view());
  649. LoginExpandedPublicAccountView::TestApi expanded_test(
  650. lock_contents_test.expanded_view());
  651. return expanded_test.selected_keyboard_item_value();
  652. }
  653. // static
  654. AccountId LoginScreenTestApi::GetFocusedUser() {
  655. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  656. LockContentsView::TestApi lock_contents_test(
  657. lock_screen_test.contents_view());
  658. return lock_contents_test.focused_user();
  659. }
  660. // static
  661. bool LoginScreenTestApi::RemoveUser(const AccountId& account_id) {
  662. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  663. LockContentsView::TestApi lock_contents_test(
  664. lock_screen_test.contents_view());
  665. return lock_contents_test.RemoveUser(account_id);
  666. }
  667. // static
  668. std::string LoginScreenTestApi::GetDisplayedName(const AccountId& account_id) {
  669. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  670. LockContentsView::TestApi lock_contents_test(
  671. lock_screen_test.contents_view());
  672. LoginUserView* user_view = lock_contents_test.FindUserView(account_id);
  673. if (!user_view) {
  674. ADD_FAILURE() << "Could not find user " << account_id.Serialize();
  675. return std::string();
  676. }
  677. LoginUserView::TestApi user_view_test(user_view);
  678. return base::UTF16ToUTF8(user_view_test.displayed_name());
  679. }
  680. // static
  681. std::u16string LoginScreenTestApi::GetDisabledAuthMessage(
  682. const AccountId& account_id) {
  683. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  684. if (!big_user_view) {
  685. ADD_FAILURE() << "Could not find user " << account_id.Serialize();
  686. return std::u16string();
  687. }
  688. LoginAuthUserView::TestApi auth_test(big_user_view->auth_user());
  689. return auth_test.GetDisabledAuthMessageContent();
  690. }
  691. // static
  692. std::u16string LoginScreenTestApi::GetManagementDisclosureText(
  693. const AccountId& account_id) {
  694. LoginBigUserView* big_user_view = GetBigUserView(account_id);
  695. if (!big_user_view) {
  696. ADD_FAILURE() << "Could not find user " << account_id.Serialize();
  697. return std::u16string();
  698. }
  699. LoginUserView::TestApi user_test(big_user_view->GetUserView());
  700. LoginRemoveAccountDialog::TestApi dialog(user_test.remove_account_dialog());
  701. return dialog.management_disclosure_label()->GetText();
  702. }
  703. // static
  704. bool LoginScreenTestApi::IsOobeDialogVisible() {
  705. LockScreen::TestApi lock_screen_test(LockScreen::Get());
  706. LockContentsView::TestApi lock_contents_test(
  707. lock_screen_test.contents_view());
  708. return lock_contents_test.IsOobeDialogVisible();
  709. }
  710. // static
  711. std::u16string LoginScreenTestApi::GetShutDownButtonLabel() {
  712. views::View* button = GetShutDownButton();
  713. if (!button)
  714. return std::u16string();
  715. return static_cast<views::LabelButton*>(button)->GetText();
  716. }
  717. // static
  718. gfx::Rect LoginScreenTestApi::GetShutDownButtonTargetBounds() {
  719. views::View* button = GetShutDownButton();
  720. if (!button)
  721. return gfx::Rect();
  722. return button->layer()->GetTargetBounds();
  723. }
  724. // static
  725. gfx::Rect LoginScreenTestApi::GetShutDownButtonMirroredBounds() {
  726. views::View* button = GetShutDownButton();
  727. if (!button)
  728. return gfx::Rect();
  729. return button->GetMirroredBounds();
  730. }
  731. // static
  732. void LoginScreenTestApi::SetPinRequestWidgetShownCallback(
  733. base::RepeatingClosure on_pin_request_widget_shown) {
  734. PinRequestWidget::SetShownCallbackForTesting(on_pin_request_widget_shown);
  735. }
  736. // static
  737. std::u16string LoginScreenTestApi::GetPinRequestWidgetTitle() {
  738. if (!PinRequestWidget::Get()) {
  739. ADD_FAILURE() << "No PIN request widget is shown";
  740. return std::u16string();
  741. }
  742. PinRequestWidget::TestApi pin_widget_test(PinRequestWidget::Get());
  743. PinRequestView::TestApi pin_view_test(pin_widget_test.pin_request_view());
  744. return pin_view_test.title_label()->GetText();
  745. }
  746. // static
  747. void LoginScreenTestApi::SubmitPinRequestWidget(const std::string& pin) {
  748. if (!PinRequestWidget::Get())
  749. FAIL() << "No PIN request widget is shown";
  750. auto event_generator = MakeAshEventGenerator();
  751. PinRequestWidget::TestApi pin_widget_test(PinRequestWidget::Get());
  752. PinRequestView::TestApi pin_test(pin_widget_test.pin_request_view());
  753. LoginPinView::TestApi pin_keyboard_test(pin_test.pin_keyboard_view());
  754. for (char c : pin) {
  755. DCHECK_GE(c, '0');
  756. DCHECK_LE(c, '9');
  757. event_generator->MoveMouseTo(pin_keyboard_test.GetButton(c - '0')
  758. ->GetBoundsInScreen()
  759. .CenterPoint());
  760. event_generator->ClickLeftButton();
  761. }
  762. event_generator->MoveMouseTo(
  763. pin_test.submit_button()->GetBoundsInScreen().CenterPoint());
  764. event_generator->ClickLeftButton();
  765. }
  766. // static
  767. void LoginScreenTestApi::CancelPinRequestWidget() {
  768. if (!PinRequestWidget::Get())
  769. FAIL() << "No PIN request widget is shown";
  770. auto event_generator = MakeAshEventGenerator();
  771. PinRequestWidget::TestApi pin_widget_test(PinRequestWidget::Get());
  772. PinRequestView::TestApi pin_view_test(pin_widget_test.pin_request_view());
  773. event_generator->MoveMouseTo(
  774. pin_view_test.back_button()->GetBoundsInScreen().CenterPoint());
  775. event_generator->ClickLeftButton();
  776. }
  777. } // namespace ash