summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-25 22:42:02 +0000
committerkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-25 22:42:02 +0000
commit2b49673d0fd51ec44b9558bdd42e63d7047358d6 (patch)
treee86dff8dd51f8635be75be5fc2208a42f64a9d8b
parent00bab587b3b4cf5de2f7cb9131e9ac882c921cd5 (diff)
downloadchromium_src-2b49673d0fd51ec44b9558bdd42e63d7047358d6.zip
chromium_src-2b49673d0fd51ec44b9558bdd42e63d7047358d6.tar.gz
chromium_src-2b49673d0fd51ec44b9558bdd42e63d7047358d6.tar.bz2
In chromedriver, do not hang when an alert becomes active during an action.
Prohibit certain actions when an alert is active. BUG=87679 TEST=none Review URL: http://codereview.chromium.org/7492016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@93983 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc69
-rw-r--r--chrome/browser/automation/automation_provider_observers.h23
-rw-r--r--chrome/browser/automation/automation_util.cc11
-rw-r--r--chrome/browser/automation/automation_util.h5
-rw-r--r--chrome/browser/automation/testing_automation_provider.cc55
-rw-r--r--chrome/browser/automation/testing_automation_provider.h2
-rw-r--r--chrome/common/automation_constants.h1
-rw-r--r--chrome/test/webdriver/test/WEBDRIVER_TESTS1
-rw-r--r--chrome/test/webdriver/test/alert_on_load.html7
-rw-r--r--chrome/test/webdriver/test/alerts.html7
-rw-r--r--chrome/test/webdriver/test/chromedriver_tests.py42
11 files changed, 208 insertions, 15 deletions
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
index 89e3f8a..d1e434f 100644
--- a/chrome/browser/automation/automation_provider_observers.cc
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -245,6 +245,8 @@ NavigationNotificationObserver::NavigationNotificationObserver(
registrar_.Add(this, chrome::NOTIFICATION_AUTH_NEEDED, source);
registrar_.Add(this, chrome::NOTIFICATION_AUTH_SUPPLIED, source);
registrar_.Add(this, chrome::NOTIFICATION_AUTH_CANCELLED, source);
+ registrar_.Add(this, chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
+ NotificationService::AllSources());
if (include_current_navigation && controller->tab_contents()->IsLoading())
navigation_started_ = true;
@@ -296,6 +298,8 @@ void NavigationNotificationObserver::Observe(
// Respond that authentication is needed.
navigation_started_ = false;
ConditionMet(AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
+ } else if (type == chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN) {
+ ConditionMet(AUTOMATION_MSG_NAVIGATION_BLOCKED_BY_MODAL_DIALOG);
} else {
NOTREACHED();
}
@@ -1158,6 +1162,8 @@ const int FindInPageNotificationObserver::kFindInPageRequestId = -1;
DomOperationObserver::DomOperationObserver() {
registrar_.Add(this, chrome::NOTIFICATION_DOM_OPERATION_RESPONSE,
NotificationService::AllSources());
+ registrar_.Add(this, chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
+ NotificationService::AllSources());
}
DomOperationObserver::~DomOperationObserver() {}
@@ -1165,9 +1171,11 @@ DomOperationObserver::~DomOperationObserver() {}
void DomOperationObserver::Observe(
int type, const NotificationSource& source,
const NotificationDetails& details) {
- if (chrome::NOTIFICATION_DOM_OPERATION_RESPONSE == type) {
+ if (type == chrome::NOTIFICATION_DOM_OPERATION_RESPONSE) {
Details<DomOperationNotificationDetails> dom_op_details(details);
OnDomOperationCompleted(dom_op_details->json());
+ } else if (type == chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN) {
+ OnModalDialogShown();
}
}
@@ -1198,6 +1206,15 @@ void DomOperationMessageSender::OnDomOperationCompleted(
delete this;
}
+void DomOperationMessageSender::OnModalDialogShown() {
+ if (automation_ && use_json_interface_) {
+ AutomationJSONReply(automation_, reply_message_.release())
+ .SendError("Could not complete script execution because a modal "
+ "dialog is active");
+ delete this;
+ }
+}
+
DocumentPrintedNotificationObserver::DocumentPrintedNotificationObserver(
AutomationProvider* automation, IPC::Message* reply_message)
: automation_(automation->AsWeakPtr()),
@@ -1881,8 +1898,7 @@ void PageSnapshotTaker::Start() {
void PageSnapshotTaker::OnDomOperationCompleted(const std::string& json) {
int dimension;
if (!base::StringToInt(json, &dimension)) {
- LOG(ERROR) << "Could not parse received dimensions: " << json;
- SendMessage(false);
+ SendMessage(false, "could not parse received dimensions: " + json);
} else if (!received_width_) {
received_width_ = true;
entire_page_size_.set_width(dimension);
@@ -1905,13 +1921,21 @@ void PageSnapshotTaker::OnDomOperationCompleted(const std::string& json) {
}
}
+void PageSnapshotTaker::OnModalDialogShown() {
+ SendMessage(false, "a modal dialog is active");
+}
+
void PageSnapshotTaker::OnSnapshotTaken(const SkBitmap& bitmap) {
base::ThreadRestrictions::ScopedAllowIO allow_io;
std::vector<unsigned char> png_data;
gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data);
int bytes_written = file_util::WriteFile(image_path_,
reinterpret_cast<char*>(&png_data[0]), png_data.size());
- SendMessage(bytes_written == static_cast<int>(png_data.size()));
+ bool success = bytes_written == static_cast<int>(png_data.size());
+ std::string error_msg;
+ if (!success)
+ error_msg = "could not write snapshot to disk";
+ SendMessage(success, error_msg);
}
void PageSnapshotTaker::ExecuteScript(const std::wstring& javascript) {
@@ -1927,14 +1951,15 @@ void PageSnapshotTaker::ExecuteScript(const std::wstring& javascript) {
WideToUTF16Hack(javascript));
}
-void PageSnapshotTaker::SendMessage(bool success) {
+void PageSnapshotTaker::SendMessage(bool success,
+ const std::string& error_msg) {
if (automation_) {
if (success) {
AutomationJSONReply(automation_, reply_message_.release())
.SendSuccess(NULL);
} else {
AutomationJSONReply(automation_, reply_message_.release())
- .SendError("Failed to take snapshot of page");
+ .SendError("Failed to take snapshot of page: " + error_msg);
}
}
delete this;
@@ -2413,7 +2438,12 @@ InputEventAckNotificationObserver::InputEventAckNotificationObserver(
count_(count) {
DCHECK(1 <= count);
registrar_.Add(
- this, content::NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK,
+ this,
+ content::NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK,
+ NotificationService::AllSources());
+ registrar_.Add(
+ this,
+ chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
NotificationService::AllSources());
}
@@ -2423,6 +2453,13 @@ void InputEventAckNotificationObserver::Observe(
int type,
const NotificationSource& source,
const NotificationDetails& details) {
+ if (type == chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN) {
+ AutomationJSONReply(automation_,
+ reply_message_.release()).SendSuccess(NULL);
+ delete this;
+ return;
+ }
+
Details<int> request_details(details);
// If the event type matches for |count_| times, replies with a JSON message.
if (event_type_ == *request_details.ptr()) {
@@ -2443,6 +2480,9 @@ AllTabsStoppedLoadingObserver::AllTabsStoppedLoadingObserver(
IPC::Message* reply_message)
: automation_(automation->AsWeakPtr()),
reply_message_(reply_message) {
+ registrar_.Add(this,
+ chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
+ NotificationService::AllSources());
for (BrowserList::const_iterator iter = BrowserList::begin();
iter != BrowserList::end();
++iter) {
@@ -2483,6 +2523,17 @@ void AllTabsStoppedLoadingObserver::OnNoMorePendingLoads(
CheckIfNoMorePendingLoads();
}
+void AllTabsStoppedLoadingObserver::Observe(
+ int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (!automation_) {
+ AutomationJSONReply(automation_,
+ reply_message_.release()).SendSuccess(NULL);
+ delete this;
+ }
+}
+
void AllTabsStoppedLoadingObserver::CheckIfNoMorePendingLoads() {
if (!automation_) {
delete this;
@@ -2585,6 +2636,10 @@ DragTargetDropAckNotificationObserver::DragTargetDropAckNotificationObserver(
this,
content::NOTIFICATION_RENDER_VIEW_HOST_DID_RECEIVE_DRAG_TARGET_DROP_ACK,
NotificationService::AllSources());
+ registrar_.Add(
+ this,
+ chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
+ NotificationService::AllSources());
}
DragTargetDropAckNotificationObserver::
diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h
index 3f6c390..947518a 100644
--- a/chrome/browser/automation/automation_provider_observers.h
+++ b/chrome/browser/automation/automation_provider_observers.h
@@ -584,9 +584,10 @@ class DomOperationObserver : public NotificationObserver {
virtual void Observe(int type,
const NotificationSource& source,
- const NotificationDetails& details);
+ const NotificationDetails& details) OVERRIDE;
virtual void OnDomOperationCompleted(const std::string& json) = 0;
+ virtual void OnModalDialogShown() = 0;
private:
NotificationRegistrar registrar_;
@@ -603,7 +604,8 @@ class DomOperationMessageSender : public DomOperationObserver {
bool use_json_interface);
virtual ~DomOperationMessageSender();
- virtual void OnDomOperationCompleted(const std::string& json);
+ virtual void OnDomOperationCompleted(const std::string& json) OVERRIDE;
+ virtual void OnModalDialogShown() OVERRIDE;
private:
base::WeakPtr<AutomationProvider> automation_;
@@ -1235,7 +1237,8 @@ class PageSnapshotTaker : public DomOperationObserver {
private:
// Overriden from DomOperationObserver.
- virtual void OnDomOperationCompleted(const std::string& json);
+ virtual void OnDomOperationCompleted(const std::string& json) OVERRIDE;
+ virtual void OnModalDialogShown() OVERRIDE;
// Called by the ThumbnailGenerator when the requested snapshot has been
// generated.
@@ -1245,7 +1248,7 @@ class PageSnapshotTaker : public DomOperationObserver {
void ExecuteScript(const std::wstring& javascript);
// Helper method to send a response back to the client. Deletes this.
- void SendMessage(bool success);
+ void SendMessage(bool success, const std::string& error_msg);
base::WeakPtr<AutomationProvider> automation_;
scoped_ptr<IPC::Message> reply_message_;
@@ -1483,15 +1486,21 @@ class InputEventAckNotificationObserver : public NotificationObserver {
// pending loads. This only waits for tabs that exist at the observer's
// creation. Will send a message on construction if no tabs are loading
// currently.
-class AllTabsStoppedLoadingObserver : public TabEventObserver {
+class AllTabsStoppedLoadingObserver : public TabEventObserver,
+ public NotificationObserver {
public:
AllTabsStoppedLoadingObserver(AutomationProvider* automation,
IPC::Message* reply_message);
virtual ~AllTabsStoppedLoadingObserver();
// TabEventObserver implementation.
- virtual void OnFirstPendingLoad(TabContents* tab_contents);
- virtual void OnNoMorePendingLoads(TabContents* tab_contents);
+ virtual void OnFirstPendingLoad(TabContents* tab_contents) OVERRIDE;
+ virtual void OnNoMorePendingLoads(TabContents* tab_contents) OVERRIDE;
+
+ // NotificationObserver implementation.
+ virtual void Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) OVERRIDE;
private:
typedef std::set<TabContents*> TabSet;
diff --git a/chrome/browser/automation/automation_util.cc b/chrome/browser/automation/automation_util.cc
index fa6a7b9..1c605f3 100644
--- a/chrome/browser/automation/automation_util.cc
+++ b/chrome/browser/automation/automation_util.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/automation/automation_provider_json.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "content/browser/browser_thread.h"
@@ -373,4 +374,14 @@ void SetCookieJSON(AutomationProvider* provider,
reply.SendSuccess(NULL);
}
+bool SendErrorIfModalDialogActive(AutomationProvider* provider,
+ IPC::Message* message) {
+ bool active = AppModalDialogQueue::GetInstance()->HasActiveDialog();
+ if (active) {
+ AutomationJSONReply(provider, message).SendError(
+ "Command cannot be performed because a modal dialog is active");
+ }
+ return active;
+}
+
} // namespace automation_util
diff --git a/chrome/browser/automation/automation_util.h b/chrome/browser/automation/automation_util.h
index b15cf2a..fb3a3f6 100644
--- a/chrome/browser/automation/automation_util.h
+++ b/chrome/browser/automation/automation_util.h
@@ -72,6 +72,11 @@ void SetCookieJSON(AutomationProvider* provider,
base::DictionaryValue* args,
IPC::Message* reply_message);
+// Sends a JSON error reply if an app modal dialog is active. Returns whether
+// an error reply was sent.
+bool SendErrorIfModalDialogActive(AutomationProvider* provider,
+ IPC::Message* message);
+
} // namespace automation_util
#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_UTIL_H_
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc
index e26268b..745868d 100644
--- a/chrome/browser/automation/testing_automation_provider.cc
+++ b/chrome/browser/automation/testing_automation_provider.cc
@@ -115,6 +115,8 @@
#include "chrome/browser/download/download_shelf.h"
#endif
+using automation_util::SendErrorIfModalDialogActive;
+
namespace {
void SendMouseClick(int flags) {
@@ -876,6 +878,9 @@ void TestingAutomationProvider::WindowSimulateKeyPress(
void TestingAutomationProvider::WebkitMouseClick(DictionaryValue* args,
IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
TabContents* tab_contents;
std::string error;
if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
@@ -922,6 +927,9 @@ void TestingAutomationProvider::WebkitMouseClick(DictionaryValue* args,
void TestingAutomationProvider::WebkitMouseMove(
DictionaryValue* args, IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
TabContents* tab_contents;
std::string error;
if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
@@ -945,6 +953,9 @@ void TestingAutomationProvider::WebkitMouseMove(
void TestingAutomationProvider::WebkitMouseDrag(DictionaryValue* args,
IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
TabContents* tab_contents;
std::string error;
if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
@@ -994,6 +1005,9 @@ void TestingAutomationProvider::WebkitMouseDrag(DictionaryValue* args,
void TestingAutomationProvider::WebkitMouseButtonDown(
DictionaryValue* args, IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
TabContents* tab_contents;
std::string error;
if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
@@ -1019,6 +1033,9 @@ void TestingAutomationProvider::WebkitMouseButtonDown(
void TestingAutomationProvider::WebkitMouseButtonUp(
DictionaryValue* args, IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
TabContents* tab_contents;
std::string error;
if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
@@ -1044,6 +1061,9 @@ void TestingAutomationProvider::WebkitMouseButtonUp(
void TestingAutomationProvider::WebkitMouseDoubleClick(
DictionaryValue* args, IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
TabContents* tab_contents;
std::string error;
if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
@@ -1079,6 +1099,9 @@ void TestingAutomationProvider::WebkitMouseDoubleClick(
void TestingAutomationProvider::DragAndDropFilePaths(
DictionaryValue* args, IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
TabContents* tab_contents;
std::string error;
if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
@@ -5187,6 +5210,9 @@ void TestingAutomationProvider::SendWebKeyPressEventAsync(
void TestingAutomationProvider::SendWebkitKeyEvent(
DictionaryValue* args,
IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
NativeWebKeyboardEvent event;
// In the event of an error, BuildWebKeyEventFromArgs handles telling what
// went wrong and sending the reply message; if it fails, we just have to
@@ -5209,6 +5235,9 @@ void TestingAutomationProvider::SendWebkitKeyEvent(
void TestingAutomationProvider::SendOSLevelKeyEventToTab(
DictionaryValue* args,
IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
int modifiers, keycode;
if (!args->GetInteger("keyCode", &keycode)) {
AutomationJSONReply(this, reply_message)
@@ -5562,6 +5591,11 @@ void TestingAutomationProvider::SetAppLaunchType(
void TestingAutomationProvider::WaitForAllTabsToStopLoading(
DictionaryValue* args,
IPC::Message* reply_message) {
+ if (AppModalDialogQueue::GetInstance()->HasActiveDialog()) {
+ AutomationJSONReply(this, reply_message).SendSuccess(NULL);
+ return;
+ }
+
// This class will send the message immediately if no tab is loading.
new AllTabsStoppedLoadingObserver(this, reply_message);
}
@@ -5617,6 +5651,9 @@ void TestingAutomationProvider::GetIndicesFromTab(
void TestingAutomationProvider::NavigateToURL(
DictionaryValue* args,
IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
int navigation_count;
std::string url, error;
Browser* browser;
@@ -5645,6 +5682,9 @@ void TestingAutomationProvider::NavigateToURL(
void TestingAutomationProvider::ExecuteJavascriptJSON(
DictionaryValue* args,
IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
string16 frame_xpath, javascript;
std::string error;
TabContents* tab_contents;
@@ -5682,6 +5722,9 @@ void TestingAutomationProvider::ExecuteJavascriptJSON(
void TestingAutomationProvider::GoForward(
DictionaryValue* args,
IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
TabContents* tab_contents;
std::string error;
if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
@@ -5703,6 +5746,9 @@ void TestingAutomationProvider::GoForward(
void TestingAutomationProvider::GoBack(
DictionaryValue* args,
IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
TabContents* tab_contents;
std::string error;
if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
@@ -5724,6 +5770,9 @@ void TestingAutomationProvider::GoBack(
void TestingAutomationProvider::ReloadJSON(
DictionaryValue* args,
IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
TabContents* tab_contents;
std::string error;
if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
@@ -5769,6 +5818,9 @@ void TestingAutomationProvider::GetTabTitleJSON(
void TestingAutomationProvider::CaptureEntirePageJSON(
DictionaryValue* args,
IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
TabContents* tab_contents;
std::string error;
@@ -5871,6 +5923,9 @@ void TestingAutomationProvider::CloseTabJSON(
void TestingAutomationProvider::ActivateTabJSON(
DictionaryValue* args,
IPC::Message* reply_message) {
+ if (SendErrorIfModalDialogActive(this, reply_message))
+ return;
+
AutomationJSONReply reply(this, reply_message);
Browser* browser;
TabContents* tab_contents;
diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h
index 399e798..497c55e 100644
--- a/chrome/browser/automation/testing_automation_provider.h
+++ b/chrome/browser/automation/testing_automation_provider.h
@@ -837,7 +837,7 @@ class TestingAutomationProvider : public AutomationProvider,
base::DictionaryValue* args,
IPC::Message* reply_message);
- // Waits for all tabs to stop loading.
+ // Waits for all tabs to stop loading or a modal dialog to become active.
void WaitForAllTabsToStopLoading(base::DictionaryValue* args,
IPC::Message* reply_message);
diff --git a/chrome/common/automation_constants.h b/chrome/common/automation_constants.h
index ae7df0c..1b524d1 100644
--- a/chrome/common/automation_constants.h
+++ b/chrome/common/automation_constants.h
@@ -77,6 +77,7 @@ enum AutomationMsg_NavigationResponseValues {
AUTOMATION_MSG_NAVIGATION_ERROR = 0,
AUTOMATION_MSG_NAVIGATION_SUCCESS,
AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED,
+ AUTOMATION_MSG_NAVIGATION_BLOCKED_BY_MODAL_DIALOG,
};
enum AutomationMsg_ExtensionResponseValues {
diff --git a/chrome/test/webdriver/test/WEBDRIVER_TESTS b/chrome/test/webdriver/test/WEBDRIVER_TESTS
index d95b536..b17d401 100644
--- a/chrome/test/webdriver/test/WEBDRIVER_TESTS
+++ b/chrome/test/webdriver/test/WEBDRIVER_TESTS
@@ -23,6 +23,7 @@
# features. See bug 71237.
{
'all': [
+ 'alerts_tests',
'children_finding_tests',
# Cookie tests try to set the domain explicitly to 'localhost', which
# is not allowed.
diff --git a/chrome/test/webdriver/test/alert_on_load.html b/chrome/test/webdriver/test/alert_on_load.html
new file mode 100644
index 0000000..a325163
--- /dev/null
+++ b/chrome/test/webdriver/test/alert_on_load.html
@@ -0,0 +1,7 @@
+<html>
+ <script>
+ window.onload = function() {
+ alert('hi');
+ }
+ </script>
+</html>
diff --git a/chrome/test/webdriver/test/alerts.html b/chrome/test/webdriver/test/alerts.html
new file mode 100644
index 0000000..93fc102
--- /dev/null
+++ b/chrome/test/webdriver/test/alerts.html
@@ -0,0 +1,7 @@
+<html>
+ <body>
+ <input name='onkeypress' type='text' onkeypress='alert("ok")'></input>
+ <input name='onkeyup' type='text' onkeyup='alert("ok")'></input>
+ <input name='normal' type='text'></input>
+ </body>
+</html>
diff --git a/chrome/test/webdriver/test/chromedriver_tests.py b/chrome/test/webdriver/test/chromedriver_tests.py
index 10d1064..49f5311 100644
--- a/chrome/test/webdriver/test/chromedriver_tests.py
+++ b/chrome/test/webdriver/test/chromedriver_tests.py
@@ -735,6 +735,48 @@ class FrameSwitchingTest(ChromeDriverTest):
self.assertEquals(str(i), driver.current_url.split('?')[-1])
driver.switch_to_default_content()
+class AlertTest(ChromeDriverTest):
+
+ def testAlertOnLoadDoesNotHang(self):
+ driver = self.GetNewDriver()
+ driver.get(GetTestDataUrl() + '/alert_on_load.html')
+ driver.switch_to_alert().accept()
+
+ def testAlertWhenTypingThrows(self):
+ driver = self.GetNewDriver()
+ driver.get(GetTestDataUrl() + '/alerts.html')
+ input_box = driver.find_element_by_name('onkeypress')
+ self.assertRaises(WebDriverException, input_box.send_keys, 'a')
+
+ def testAlertJustAfterTypingDoesNotThrow(self):
+ driver = self.GetNewDriver()
+ driver.get(GetTestDataUrl() + '/alerts.html')
+ driver.find_element_by_name('onkeyup').send_keys('a')
+ driver.switch_to_alert().accept()
+
+ def testAlertOnScriptDoesNotHang(self):
+ driver = self.GetNewDriver()
+ driver.get(GetTestDataUrl() + '/alerts.html')
+ self.assertRaises(WebDriverException, driver.execute_script, 'alert("ok")')
+
+ def testMustHandleAlertFirst(self):
+ driver = self.GetNewDriver()
+ driver.get(GetTestDataUrl() + '/alerts.html')
+ input_box = driver.find_element_by_name('normal')
+ driver.execute_async_script('arguments[0](); window.alert("ok")')
+
+ self.assertRaises(WebDriverException, driver.execute_script, 'a = 1')
+
+ self.assertRaises(WebDriverException, input_box.send_keys, 'abc')
+
+ self.assertRaises(WebDriverException, driver.get,
+ GetTestDataUrl() + '/test_page.html')
+
+ self.assertRaises(WebDriverException, driver.refresh)
+ self.assertRaises(WebDriverException, driver.back)
+ self.assertRaises(WebDriverException, driver.forward)
+ self.assertRaises(WebDriverException, driver.get_screenshot_as_base64)
+
"""Chrome functional test section. All implementation tests of ChromeDriver
should go above.