angular / protractor

E2E test framework for Angular apps
http://www.protractortest.org
MIT License
8.75k stars 2.31k forks source link

Automatically retry alert commands on chromedriver #3925

Open heathkit opened 7 years ago

heathkit commented 7 years ago

Since chromedriver 2.25, there's been an issue (chromedriver issue #1500) that randomly makes alert commands fail with the message {"code":-32603,"message":"Could not handle JavaScript dialog"}.

In 2.26, they added a single retry when handling JavaScript dialog which reduces the frequency of the problem, though it still occurs. Until they fix it properly, we might want to consider adding some kind of retry for alert commands to Protractor, to help shield people from this issue.

wswebcreation commented 7 years ago

@heathkit

Still valid? We are now on 2.31

rafaelcs commented 7 years ago

I'm getting this error:

UnexpectedAlertOpenError: unexpected alert open: {Alert text : ¿Estás seguro de borrar este Patch? Esta acción no se puede deshacer}
    (Session info: chrome=61.0.3163.100)
    (Driver info: chromedriver=2.31.488763 (092de99f48a300323ecf8c2a4e2e7cab51de5ba8),platform=Linux 3.13.0-129-generic x86_64)
  - UnexpectedAlertOpenError: unexpected alert open: {Alert text : ¿Estás seguro de borrar este Patch? Esta acción no se puede deshacer}
    (Session info: chrome=61.0.3163.100)
    (Driver info: chromedriver=2.31.488763 (092de99f48a300323ecf8c2a4e2e7cab51de5ba8),platform=Linux 3.13.0-129-generic x86_64)

This error is very random! My code:

    this.removeAllPatches = function () {
        var removeButton = this.borrarButton;

        removeButton.count().then(function(countButtons) {
            while (countButtons > 0) {
                removeButton.first().click();
                basePage.alertIsPresent(), basePage.timeout.xxl;
                browser.switchTo().alert().accept();
                countButtons--;
            };
        });
    };

Let me know if you need more informations :)

wswebcreation commented 7 years ago

Hi @rafaelcs

I think the problem could be in your code. You are using a while-loop with promises. The countButtons-- will be executed sooner then the browser.switchTo().alert().accept(); which is a promise

Maybe change that to this

    this.removeAllPatches = function () {
        var removeButton = this.borrarButton;

        removeButton.count().then(function(countButtons) {
            while (countButtons > 0) {
                removeButton.first().click();
                basePage.alertIsPresent(), basePage.timeout.xxl;
                                // First resolve the accept before you do the count
                browser.switchTo().alert().accept()
                                    .then(function(){
                        countButtons--;
                                    });
            };
        });
    };
rafaelcs commented 7 years ago

Hello @wswebcreation,

Testing with the above code, I'm getting an error:

[23:29:14] I/launcher - Running 1 instances of WebDriver
[23:29:14] I/direct - Using ChromeDriver directly...
problem trying to remove a folder:test_evidences/
Spec started

<--- Last few GCs --->

   72502 ms: Mark-sweep 1367.8 (1439.3) -> 1367.4 (1439.3) MB, 2901.7 / 0.0 ms [allocation failure] [GC in old space requested].
   75403 ms: Mark-sweep 1367.4 (1439.3) -> 1367.4 (1439.3) MB, 2900.9 / 0.0 ms [allocation failure] [GC in old space requested].
   77977 ms: Mark-sweep 1367.4 (1439.3) -> 1367.4 (1419.3) MB, 2573.0 / 0.0 ms [last resort gc].
   80548 ms: Mark-sweep 1367.4 (1419.3) -> 1367.4 (1419.3) MB, 2571.3 / 0.0 ms [last resort gc].

<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0xcf2d34cfb51 <JS Object>
    1: /* anonymous */(aka /* anonymous */) [/Users/rafaelcarvalho/Desktop/projects/sf-chile-backend/node_modules/protractor/built/element.js:~827] [pc=0xfee7a6f375e] (this=0xcf2d3404381 <undefined>,fnName=0x26d7f3b064b9 <String[5]: click>)
    2: arguments adaptor frame: 3->1
    3: InnerArrayForEach(aka InnerArrayForEach) [native array.js:~935] [pc=0xfee7a6d0613] (this=0xcf2d3404381 <undefined...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/usr/local/bin/node]
 2: node::FatalException(v8::Isolate*, v8::Local<v8::Value>, v8::Local<v8::Message>) [/usr/local/bin/node]
 3: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/local/bin/node]
 4: v8::internal::Handle<v8::internal::JSFunction> v8::internal::Factory::New<v8::internal::JSFunction>(v8::internal::Handle<v8::internal::Map>, v8::internal::AllocationSpace) [/usr/local/bin/node]
 5: v8::internal::Factory::NewFunction(v8::internal::Handle<v8::internal::Map>, v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::Handle<v8::internal::Context>, v8::internal::PretenureFlag) [/usr/local/bin/node]
 6: v8::internal::Factory::NewFunctionFromSharedFunctionInfo(v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::Handle<v8::internal::Context>, v8::internal::PretenureFlag) [/usr/local/bin/node]
 7: v8::internal::Runtime_NewClosure_Tenured(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/local/bin/node]
 8: 0xfee7a1092a7
Abort trap: 6
wswebcreation commented 7 years ago

Hmm, think now the while-loop is breaking stuff.

You could refactor your code to something like this.

removeButton.each(function(button){
    button.first().click();
    // don't know what basePage.timeout.xxl is doing
    basePage.alertIsPresent(), basePage.timeout.xxl; 
    browser.switchTo().alert().accept();
});

The problem you are now facing is more a integration / coding issue and not an issue with Protractor itself. Your question is better suited for StackOverflow or Gitter. Please ask a question there with the 'protractor' tag or post in the Gitter Channel to get help.

From the the getting help section of the README:

Please ask usage and debugging questions on StackOverflow (use the "protractor" tag) or in the Angular discussion group. (Please do not ask support questions here on Github.)