protractor: browser.switchTo().alert() no longer works as expected on dialogs

Overview

I have a set of tests which rely on browser.switchTo().alert() to accept and dismiss both alerts and dialogs. The tests no longer work on the dialogs. The dialogs remain open, the test is not able to accept or dismiss the dialog, and the test control flow hangs.

// PASSES
it('should handle alerts', function() {
  // trigger $location.url('/page2');
  element(by.id('navigateAway')).click();
  var alertDialog = browser.switchTo().alert();
  expect(alertDialog.accept).toBeDefined();
  alertDialog.accept();
});

// FAILS
it('should handle dialogs', function() {
  // trigger window.onbeforeunload = function() { return 'are you sure?'; }
  browser.navigate().refresh();
  var alertDialog = browser.switchTo().alert();
  expect(alertDialog.accept).toBeDefined(); // fails
  alertDialog.accept(); // alertDialog and accept are not defined 
});

The full test suite is here

Investigation

There is discussion on the interwebs about similar problems where dialogs are not accessible by using browser.switchTo(). There is an open bug on selenium chromedriver here

There are a few related issues on protractor, specifically https://github.com/angular/protractor/issues/308 and https://github.com/angular/protractor/issues/55

I’ve tried using getAllWindowHandles and this fails too:

browser.getAllWindowHandles().then(function (handles) {
  browser.switchTo().window(handles[0]);
});

I’ve also tried rolling back to previous versions of protractor.

  • In protractor 1.0.0 the tests still fail, however the open dialog box is somehow ignored and doesn’t block the control flow - all tests run and fail.
  • In 0.9.0 the tests fail AND block the control flow - the first failing test stops the remaining tests from running.

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Reactions: 2
  • Comments: 29 (2 by maintainers)

Most upvoted comments

I was able to clear up many of the issues I was experiencing by updating ChromeDriver to 2.22, Selenium.WebDriver to 2.53.1 (from 2.53.0).

I try chrome driver 2.23 and it start working again

On Thu, Sep 15, 2016 at 11:54 AM, jv notifications@github.com wrote:

Hi, I am also experience this issue now.

I read through all this comment and none of the solutions works for me. Sample code bellow was working fine, but It doesn’t work anymore and none of soultions above as well.

  function (alert) {
    alert.accept();
  },function (err) {
  }
);

Is anyone else experience this issue still?

chrome=53.0.2785.116 chromedriver=2.19.346078

Thank you

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/angular/protractor/issues/1486#issuecomment-247369634, or mute the thread https://github.com/notifications/unsubscribe-auth/ABF6jU5MgQ1QYdIym_e8V1KeHWDaIYByks5qqWotgaJpZM4C2A7- .

@niieani I’ve done a bit of research and signs are pointing to Chrome 52’s release as of last week.

All of my chrome tests have been failing, regardless of branch, since that time. The only shared dependency in our CI pipeline is 1) protractor (unchanged), 2) selenium (unchanged) and 3) chrome (updated).

It may be worth investigating further.

You should put a catch handler onto the navigate and place your expect/check code there:

            browser.navigate().refresh().catch(function() {
                return browser.switchTo().alert().then(function (alert) {
                      // Is this expected?
                });
            });

You cannot do:

browser....navigate to somewhere
... go and get alert box and do something

As the exception has ALREADY been thrown and your test has failed.

I have a popup that opens on browser refresh. Try as I might, it doesn’t go away when calling browser.switchTo().alert().accept();. Instead all subsequent tests fail with Failed: unexpected alert open: {Alert text : XXX}. This is what my code looks like right now:

browser.refresh();
browser.wait(protractor.ExpectedConditions.alertIsPresent(), 1000);
browser.switchTo().alert().accept();

I observed that “Alert” is not caught when user is trying to navigate away from current URL, where as it works when user navigates to subpage or clicks links or any action in current URL.

This was the issue reported - https://github.com/angular/protractor/issues/1486#issue-47537339 where user is trying to refresh whole page to remove all unsaved changed.

I found below working solution - where we have to ignoresynchronization by disabling Angular.

    await browser.waitForAngularEnabled(false);
    await browser.refresh();
    await (await browser.switchTo().alert()).accept();
    await browser.waitForAngularEnabled(true);

Hope this helps.

Hi, I am also experience this issue now.

I read through all this comment and none of the solutions works for me. Sample code bellow was working fine, but It doesn’t work anymore and none of soultions above as well.

browser.driver.switchTo().alert().then(
      function (alert) {
        alert.accept();
      },function (err) {
throw (err);
      });

Is anyone else experience this issue still?

chrome=53.0.2785.116 chromedriver=2.19.346078

Thank you

Have gone around in circles for a few days on this one, trying the various solutions and workarounds, but no luck. Was trying to put in a test for an unauthorised login. The (angular/Ionic) app pops up an access denied alert as expected and have been attempting to get protractor to deal with it using variants of browser.switchTo().alert() . One way out is to redesign the app to not use any alerting functionality for errors and confirmations (currently provided through $ionicPopup), but protractor really should be able to deal with alerts (and it sounds like it could in the past so something must have changed).

Fails for me in similar way with both Firefox and Chrome. The alert pops up in the browser, but is not found by protractor so it get’s stuck.

Agree that this is blocking usage of protractor (which otherwise looks very handy).

Here are some of the attempts (inspired by various people’s postings):

// A) the code below should deal with the ionic.Popup alert
// but fails to find it currently, so this is a bit broken
// for some reason (google "protractor NoSuchAlertError: no alert open")
// Seems to be a bug in protractor: https://github.com/angular/protractor/issues/1486

var alertDialog = browser.switchTo().alert();
expect(alertDialog.getText()).toEqual("unauthorized access");

// B) here is another attempt which did not quite work out either.
// 27 maps to bot.ErrorCode.NO_MODAL_DIALOG_OPEN: http://selenium.googlecode.com/git/docs/api/javascript/source/lib/atoms/error.js.src.html#l31
var alertDialog = browser.switchTo().alert().thenCatch(function (e) {
    if (e.code !== 27) { throw e; }
})
.then(function (alert) {
    if (alert) {
        expect(alertDialog.getText()).toEqual("unauthorized access");
        return alert.dismiss();
    }
});

// C) another attempt to solve the alert problem. No luck in finding the alert despite
// it being clearly present. Times out after 30 secs
// http://stackoverflow.com/questions/24037460/make-protractor-wait-for-an-alert-box
browser.wait(function() {
    return browser.switchTo().alert().then(
        function(alert) {
            expect(alert.getText()).toEqual("unauthorized access");
            alert.accept();
            return true;
            },
        function() { return false; }
    );
});

Using the javascript console in Chrome, I can directly find what I need from my app as per below, but not through protractor:

// from chrome javascript console, what we want is:
   document.getElementsByClassName("popup-body")[0].childNodes[0]
// which gives:
//   "<span>unauthorized access</span>"
// and the buttons are available from:
   document.getElementsByClassName("popup-buttons")