@@ -45,6 +45,7 @@ namespace webdriver {
45
45
46
46
struct WaitThreadContext {
47
47
HWND window_handle;
48
+ bool is_deferred_command;
48
49
LPSTR deferred_response;
49
50
};
50
51
@@ -183,12 +184,15 @@ LRESULT IECommandExecutor::OnWait(UINT uMsg,
183
184
std::string deferred_response (str);
184
185
delete[] str;
185
186
187
+ bool is_single_wait = (wParam == 0 );
188
+
186
189
BrowserHandle browser;
187
190
int status_code = this ->GetCurrentBrowser (&browser);
188
191
if (status_code == WD_SUCCESS && !browser->is_closing ()) {
189
192
if (this ->page_load_timeout_ >= 0 && this ->wait_timeout_ < clock ()) {
190
193
Response timeout_response;
191
- timeout_response.SetErrorResponse (ERROR_WEBDRIVER_TIMEOUT, " Timed out waiting for page to load." );
194
+ timeout_response.SetErrorResponse (ERROR_WEBDRIVER_TIMEOUT,
195
+ " Timed out waiting for page to load." );
192
196
this ->serialized_response_ = timeout_response.Serialize ();
193
197
this ->is_waiting_ = false ;
194
198
browser->set_wait_required (false );
@@ -198,14 +202,20 @@ LRESULT IECommandExecutor::OnWait(UINT uMsg,
198
202
if (this ->IsAlertActive (browser, &alert_handle)) {
199
203
LOG (WARN) << " Found alert" ;
200
204
}
201
- if (this -> is_waiting_ ) {
202
- this ->CreateWaitThread (deferred_response) ;
205
+ if (is_single_wait ) {
206
+ this ->is_waiting_ = false ;
203
207
} else {
204
- this ->serialized_response_ = deferred_response;
208
+ if (this ->is_waiting_ ) {
209
+ this ->CreateWaitThread (deferred_response);
210
+ } else {
211
+ LOG (DEBUG) << " Setting serialized response to " << deferred_response;
212
+ this ->serialized_response_ = deferred_response;
213
+ }
205
214
}
206
215
}
207
216
} else {
208
217
this ->is_waiting_ = false ;
218
+ LOG (DEBUG) << " Setting serialized response to " << deferred_response;
209
219
this ->serialized_response_ = deferred_response;
210
220
}
211
221
return 0 ;
@@ -548,6 +558,7 @@ unsigned int WINAPI IECommandExecutor::WaitThreadProc(LPVOID lpParameter) {
548
558
LOG (TRACE) << " Entering IECommandExecutor::WaitThreadProc" ;
549
559
WaitThreadContext* thread_context = reinterpret_cast <WaitThreadContext*>(lpParameter);
550
560
HWND window_handle = thread_context->window_handle ;
561
+ bool is_deferred_command = thread_context->is_deferred_command ;
551
562
std::string deferred_response (thread_context->deferred_response );
552
563
delete thread_context->deferred_response ;
553
564
delete thread_context;
@@ -560,8 +571,14 @@ unsigned int WINAPI IECommandExecutor::WaitThreadProc(LPVOID lpParameter) {
560
571
::Sleep (WAIT_TIME_IN_MILLISECONDS);
561
572
::PostMessage (window_handle,
562
573
WD_WAIT,
563
- NULL ,
574
+ static_cast <WPARAM>(deferred_response.size()) ,
564
575
reinterpret_cast<LPARAM>(message_payload));
576
+ if (is_deferred_command) {
577
+ // This wait is requested by the automatic handling of a user prompt
578
+ // before a command was executed, so re-queue the command execution
579
+ // for after the wait.
580
+ ::PostMessage (window_handle, WD_EXEC_COMMAND, NULL , NULL );
581
+ }
565
582
return 0 ;
566
583
}
567
584
@@ -675,22 +692,37 @@ void IECommandExecutor::DispatchCommand() {
675
692
command_type == webdriver::CommandType::SwitchToWindow) {
676
693
LOG (DEBUG) << " Alert is detected, and the sent command is valid" ;
677
694
} else {
678
- LOG (DEBUG) << " Unexpected alert is detected, and the sent command is invalid when an alert is present" ;
695
+ LOG (DEBUG) << " Unexpected alert is detected, and the sent command "
696
+ << " is invalid when an alert is present" ;
679
697
std::string alert_text;
680
698
bool is_quit_command = command_type == webdriver::CommandType::Quit;
681
699
bool is_notify_unexpected_alert = this ->HandleUnexpectedAlert (browser,
682
700
alert_handle,
683
701
is_quit_command,
684
702
&alert_text);
685
- if (!is_quit_command && is_notify_unexpected_alert) {
686
- // To keep pace with what Firefox does, we'll return the text of the
687
- // alert in the error response.
688
- response.SetErrorResponse (EUNEXPECTEDALERTOPEN, " Modal dialog present with text: " + alert_text);
689
- response.AddAdditionalData (" text" , alert_text);
690
- this ->serialized_response_ = response.Serialize ();
691
- return ;
703
+ if (!is_quit_command) {
704
+ if (is_notify_unexpected_alert) {
705
+ // To keep pace with what the specification suggests, we'll
706
+ // return the text of the alert in the error response.
707
+ response.SetErrorResponse (EUNEXPECTEDALERTOPEN,
708
+ " Modal dialog present with text: " + alert_text);
709
+ response.AddAdditionalData (" text" , alert_text);
710
+ this ->serialized_response_ = response.Serialize ();
711
+ return ;
712
+ } else {
713
+ LOG (DEBUG) << " Command other than quit was issued, and option "
714
+ << " to not notify was specified. Continuing with "
715
+ << " command after automatically closing alert." ;
716
+ // Push a wait cycle, then re-execute the current command (which
717
+ // hasn't actually been executed yet). Note that an empty string
718
+ // for the deferred response parameter of CreateWaitThread will
719
+ // re-queue the execution of the command.
720
+ this ->CreateWaitThread (" " , true );
721
+ return ;
722
+ }
692
723
} else {
693
- LOG (DEBUG) << " Quit command was issued. Continuing with command after automatically closing alert." ;
724
+ LOG (DEBUG) << " Quit command was issued. Continuing with "
725
+ << " command after automatically closing alert." ;
694
726
}
695
727
}
696
728
}
@@ -751,16 +783,28 @@ void IECommandExecutor::DispatchCommand() {
751
783
}
752
784
753
785
this ->serialized_response_ = response.Serialize ();
786
+ LOG (DEBUG) << " Setting serialized response to " << this ->serialized_response_ ;
787
+ LOG (DEBUG) << " Is waiting flag: " << this ->is_waiting_ ? " true" : " false" ;
754
788
}
755
789
756
790
void IECommandExecutor::CreateWaitThread (const std::string& deferred_response) {
791
+ this ->CreateWaitThread (deferred_response, false );
792
+ }
793
+
794
+ void IECommandExecutor::CreateWaitThread (const std::string& deferred_response,
795
+ const bool is_deferred_command_execution) {
757
796
// If we are still waiting, we need to wait a bit then post a message to
758
797
// ourselves to run the wait again. However, we can't wait using Sleep()
759
798
// on this thread. This call happens in a message loop, and we would be
760
799
// unable to process the COM events in the browser if we put this thread
761
800
// to sleep.
801
+ LOG (DEBUG) << " Creating wait thread with deferred response of `" << deferred_response << " `" ;
802
+ if (is_deferred_command_execution) {
803
+ LOG (DEBUG) << " Command execution will be rescheduled." ;
804
+ }
762
805
WaitThreadContext* thread_context = new WaitThreadContext;
763
806
thread_context->window_handle = this ->m_hWnd ;
807
+ thread_context->is_deferred_command = is_deferred_command_execution;
764
808
thread_context->deferred_response = new CHAR[deferred_response.size () + 1 ];
765
809
strcpy_s (thread_context->deferred_response ,
766
810
deferred_response.size () + 1 ,
@@ -808,6 +852,12 @@ bool IECommandExecutor::HandleUnexpectedAlert(BrowserHandle browser,
808
852
LOG (TRACE) << " Entering IECommandExecutor::HandleUnexpectedAlert" ;
809
853
Alert dialog (browser, alert_handle);
810
854
*alert_text = dialog.GetText ();
855
+ if (!dialog.is_standard_alert ()) {
856
+ // The dialog was non-standard. The most common case of this is
857
+ // an onBeforeUnload dialog, which must be accepted to continue.
858
+ dialog.Accept ();
859
+ return false ;
860
+ }
811
861
if (this ->unexpected_alert_behavior_ == ACCEPT_UNEXPECTED_ALERTS ||
812
862
this ->unexpected_alert_behavior_ == ACCEPT_AND_NOTIFY_UNEXPECTED_ALERTS) {
813
863
LOG (DEBUG) << " Automatically accepting the alert" ;
@@ -832,6 +882,7 @@ bool IECommandExecutor::HandleUnexpectedAlert(BrowserHandle browser,
832
882
this ->unexpected_alert_behavior_ == IGNORE_UNEXPECTED_ALERTS ||
833
883
this ->unexpected_alert_behavior_ == DISMISS_AND_NOTIFY_UNEXPECTED_ALERTS ||
834
884
this ->unexpected_alert_behavior_ == ACCEPT_AND_NOTIFY_UNEXPECTED_ALERTS;
885
+ is_notify_unexpected_alert = is_notify_unexpected_alert && dialog.is_standard_alert ();
835
886
return is_notify_unexpected_alert;
836
887
}
837
888
0 commit comments