[email protected] | 9c1662b | 2012-03-06 15:44:33 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 4af869a | 2010-04-02 21:49:53 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
avi | a2f4804a | 2015-12-24 23:11:13 | [diff] [blame] | 5 | #include <stddef.h> |
| 6 | |
vitbar | e6d0456 | 2015-07-31 16:08:24 | [diff] [blame] | 7 | #include "base/strings/string_number_conversions.h" |
[email protected] | 135cb80 | 2013-06-09 16:44:20 | [diff] [blame] | 8 | #include "base/strings/utf_string_conversions.h" |
[email protected] | 4af869a | 2010-04-02 21:49:53 | [diff] [blame] | 9 | #include "chrome/browser/extensions/extension_apitest.h" |
[email protected] | 8ecad5e | 2010-12-02 21:18:33 | [diff] [blame] | 10 | #include "chrome/browser/profiles/profile.h" |
[email protected] | 7b5dc00 | 2010-11-16 23:08:10 | [diff] [blame] | 11 | #include "chrome/browser/ui/browser.h" |
[email protected] | af44e7fb | 2011-07-29 18:32:32 | [diff] [blame] | 12 | #include "chrome/test/base/ui_test_utils.h" |
vitbar | e6d0456 | 2015-07-31 16:08:24 | [diff] [blame] | 13 | #include "components/app_modal/app_modal_dialog_queue.h" |
| 14 | #include "components/app_modal/javascript_app_modal_dialog.h" |
| 15 | #include "components/app_modal/native_app_modal_dialog.h" |
[email protected] | f13ab89 | 2014-03-12 06:48:52 | [diff] [blame] | 16 | #include "content/public/browser/render_frame_host.h" |
vitbar | e6d0456 | 2015-07-31 16:08:24 | [diff] [blame] | 17 | #include "content/public/test/test_utils.h" |
[email protected] | 22401dc | 2014-03-21 01:38:57 | [diff] [blame] | 18 | #include "extensions/browser/extension_host.h" |
[email protected] | 98b6d94 | 2013-11-10 00:34:07 | [diff] [blame] | 19 | #include "extensions/browser/process_manager.h" |
[email protected] | e4452d3 | 2013-11-15 23:07:41 | [diff] [blame] | 20 | #include "extensions/common/extension.h" |
[email protected] | 4af869a | 2010-04-02 21:49:53 | [diff] [blame] | 21 | |
vitbar | e6d0456 | 2015-07-31 16:08:24 | [diff] [blame] | 22 | namespace { |
| 23 | |
| 24 | void GetNextDialog(app_modal::NativeAppModalDialog** native_dialog) { |
| 25 | DCHECK(native_dialog); |
| 26 | *native_dialog = nullptr; |
avi | 373e72a | 2017-05-26 20:33:52 | [diff] [blame] | 27 | app_modal::JavaScriptAppModalDialog* dialog = |
| 28 | ui_test_utils::WaitForAppModalDialog(); |
| 29 | *native_dialog = dialog->native_dialog(); |
vitbar | e6d0456 | 2015-07-31 16:08:24 | [diff] [blame] | 30 | ASSERT_TRUE(*native_dialog); |
| 31 | } |
| 32 | |
| 33 | void CloseDialog() { |
| 34 | app_modal::NativeAppModalDialog* dialog = nullptr; |
| 35 | ASSERT_NO_FATAL_FAILURE(GetNextDialog(&dialog)); |
| 36 | dialog->CloseAppModalDialog(); |
| 37 | } |
| 38 | |
| 39 | void AcceptDialog() { |
| 40 | app_modal::NativeAppModalDialog* dialog = nullptr; |
| 41 | ASSERT_NO_FATAL_FAILURE(GetNextDialog(&dialog)); |
| 42 | dialog->AcceptAppModalDialog(); |
| 43 | } |
| 44 | |
| 45 | void CancelDialog() { |
| 46 | app_modal::NativeAppModalDialog* dialog = nullptr; |
| 47 | ASSERT_NO_FATAL_FAILURE(GetNextDialog(&dialog)); |
| 48 | dialog->CancelAppModalDialog(); |
| 49 | } |
| 50 | |
| 51 | void CheckAlertResult(const std::string& dialog_name, |
| 52 | size_t* call_count, |
| 53 | const base::Value* value) { |
| 54 | ASSERT_TRUE(value) << dialog_name; |
jdoerrie | 1f536b2 | 2017-10-23 17:15:11 | [diff] [blame] | 55 | ASSERT_TRUE(value->is_none()); |
vitbar | e6d0456 | 2015-07-31 16:08:24 | [diff] [blame] | 56 | ++*call_count; |
| 57 | } |
| 58 | |
| 59 | void CheckConfirmResult(const std::string& dialog_name, |
| 60 | bool expected_value, |
| 61 | size_t* call_count, |
| 62 | const base::Value* value) { |
| 63 | ASSERT_TRUE(value) << dialog_name; |
| 64 | bool current_value; |
| 65 | ASSERT_TRUE(value->GetAsBoolean(¤t_value)) << dialog_name; |
| 66 | ASSERT_EQ(expected_value, current_value) << dialog_name; |
| 67 | ++*call_count; |
| 68 | } |
| 69 | |
| 70 | } // namespace |
| 71 | |
[email protected] | bf194880 | 2010-04-08 20:58:35 | [diff] [blame] | 72 | IN_PROC_BROWSER_TEST_F(ExtensionApiTest, AlertBasic) { |
[email protected] | 4af869a | 2010-04-02 21:49:53 | [diff] [blame] | 73 | ASSERT_TRUE(RunExtensionTest("alert")) << message_; |
| 74 | |
[email protected] | 1c321ee | 2012-05-21 03:02:34 | [diff] [blame] | 75 | const extensions::Extension* extension = GetSingleLoadedExtension(); |
[email protected] | 3a1dc57 | 2012-07-31 22:25:13 | [diff] [blame] | 76 | extensions::ExtensionHost* host = |
reillyg | 0ea3fa90 | 2014-10-28 15:30:23 | [diff] [blame] | 77 | extensions::ProcessManager::Get(browser()->profile()) |
| 78 | ->GetBackgroundHostForExtension(extension->id()); |
[email protected] | 4af869a | 2010-04-02 21:49:53 | [diff] [blame] | 79 | ASSERT_TRUE(host); |
Jochen Eisinger | 14ea977 | 2015-07-24 12:04:37 | [diff] [blame] | 80 | host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests( |
[email protected] | 0433872 | 2013-12-24 23:18:05 | [diff] [blame] | 81 | base::ASCIIToUTF16("alert('This should not crash.');")); |
[email protected] | 4af869a | 2010-04-02 21:49:53 | [diff] [blame] | 82 | |
vitbar | e6d0456 | 2015-07-31 16:08:24 | [diff] [blame] | 83 | ASSERT_NO_FATAL_FAILURE(CloseDialog()); |
| 84 | } |
| 85 | |
| 86 | IN_PROC_BROWSER_TEST_F(ExtensionApiTest, AlertQueue) { |
| 87 | ASSERT_TRUE(RunExtensionTest("alert")) << message_; |
| 88 | |
| 89 | const extensions::Extension* extension = GetSingleLoadedExtension(); |
| 90 | extensions::ExtensionHost* host = |
| 91 | extensions::ProcessManager::Get(browser()->profile()) |
| 92 | ->GetBackgroundHostForExtension(extension->id()); |
| 93 | ASSERT_TRUE(host); |
| 94 | |
| 95 | // Creates several dialogs at the same time. |
| 96 | const size_t num_dialogs = 3; |
| 97 | size_t call_count = 0; |
| 98 | for (size_t i = 0; i != num_dialogs; ++i) { |
Brett Wilson | 5accd24 | 2017-11-30 22:07:32 | [diff] [blame] | 99 | const std::string dialog_name = "Dialog #" + base::NumberToString(i) + "."; |
vitbar | e6d0456 | 2015-07-31 16:08:24 | [diff] [blame] | 100 | host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests( |
| 101 | base::ASCIIToUTF16("alert('" + dialog_name + "');"), |
| 102 | base::Bind(&CheckAlertResult, dialog_name, |
| 103 | base::Unretained(&call_count))); |
| 104 | } |
| 105 | |
| 106 | // Closes these dialogs. |
| 107 | for (size_t i = 0; i != num_dialogs; ++i) { |
| 108 | ASSERT_NO_FATAL_FAILURE(AcceptDialog()); |
| 109 | } |
| 110 | |
| 111 | // All dialogs must be closed now. |
| 112 | app_modal::AppModalDialogQueue* queue = |
| 113 | app_modal::AppModalDialogQueue::GetInstance(); |
| 114 | ASSERT_TRUE(queue); |
| 115 | EXPECT_FALSE(queue->HasActiveDialog()); |
| 116 | EXPECT_EQ(0, queue->end() - queue->begin()); |
| 117 | while (call_count < num_dialogs) |
| 118 | ASSERT_NO_FATAL_FAILURE(content::RunAllPendingInMessageLoop()); |
| 119 | } |
| 120 | |
| 121 | IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ConfirmQueue) { |
| 122 | ASSERT_TRUE(RunExtensionTest("alert")) << message_; |
| 123 | |
| 124 | const extensions::Extension* extension = GetSingleLoadedExtension(); |
| 125 | extensions::ExtensionHost* host = |
| 126 | extensions::ProcessManager::Get(browser()->profile()) |
| 127 | ->GetBackgroundHostForExtension(extension->id()); |
| 128 | ASSERT_TRUE(host); |
| 129 | |
| 130 | // Creates several dialogs at the same time. |
| 131 | const size_t num_accepted_dialogs = 3; |
| 132 | const size_t num_cancelled_dialogs = 3; |
| 133 | size_t call_count = 0; |
| 134 | for (size_t i = 0; i != num_accepted_dialogs; ++i) { |
| 135 | const std::string dialog_name = |
Brett Wilson | 5accd24 | 2017-11-30 22:07:32 | [diff] [blame] | 136 | "Accepted dialog #" + base::NumberToString(i) + "."; |
vitbar | e6d0456 | 2015-07-31 16:08:24 | [diff] [blame] | 137 | host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests( |
| 138 | base::ASCIIToUTF16("confirm('" + dialog_name + "');"), |
| 139 | base::Bind(&CheckConfirmResult, dialog_name, true, |
| 140 | base::Unretained(&call_count))); |
| 141 | } |
| 142 | for (size_t i = 0; i != num_cancelled_dialogs; ++i) { |
| 143 | const std::string dialog_name = |
Brett Wilson | 5accd24 | 2017-11-30 22:07:32 | [diff] [blame] | 144 | "Cancelled dialog #" + base::NumberToString(i) + "."; |
vitbar | e6d0456 | 2015-07-31 16:08:24 | [diff] [blame] | 145 | host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests( |
| 146 | base::ASCIIToUTF16("confirm('" + dialog_name + "');"), |
| 147 | base::Bind(&CheckConfirmResult, dialog_name, false, |
| 148 | base::Unretained(&call_count))); |
| 149 | } |
| 150 | |
| 151 | // Closes these dialogs. |
| 152 | for (size_t i = 0; i != num_accepted_dialogs; ++i) |
| 153 | ASSERT_NO_FATAL_FAILURE(AcceptDialog()); |
| 154 | for (size_t i = 0; i != num_cancelled_dialogs; ++i) |
| 155 | ASSERT_NO_FATAL_FAILURE(CancelDialog()); |
| 156 | |
| 157 | // All dialogs must be closed now. |
| 158 | app_modal::AppModalDialogQueue* queue = |
| 159 | app_modal::AppModalDialogQueue::GetInstance(); |
| 160 | ASSERT_TRUE(queue); |
| 161 | EXPECT_FALSE(queue->HasActiveDialog()); |
| 162 | EXPECT_EQ(0, queue->end() - queue->begin()); |
| 163 | while (call_count < num_accepted_dialogs + num_cancelled_dialogs) |
| 164 | ASSERT_NO_FATAL_FAILURE(content::RunAllPendingInMessageLoop()); |
[email protected] | 4af869a | 2010-04-02 21:49:53 | [diff] [blame] | 165 | } |