6
votes

I'm testing my Angular app with Protractor. I've looked through the docs and can't find any way to get the text of an alert. It's not an element in the DOM per se (at least, not that I can figure out; when there's an alert up, Chrome's inspector won't allow you to inspect it). How would I test that an alert has the correct message? Or even, that one is present?

Edit

Here is my code. HTML:

  <button id='alertButton' data-ng-click='ngAlert()'>Button</button>

JS:

$scope.ngAlert = function(){
  window.alert('Hello');
};

Protractor spec:

  describe('alert', function(){
    var ptor = protractor.getInstance();
    beforeEach(function(){
      button = $('#alertButton');
      button.click();
    });
    it('tells the alert message', function(){
      expect(button.getText()).toEqual('Button');
    });
  });

When I make an assertion on the button text like this:

it('tells the alert message', function(){
  expect(button.getText()).toEqual('Button');
});

It passes. But if I try to read an alert like this:

it('tells the alert message', function(){
  var alertDialog = ptor.switchTo().alert();
  expect(alertDialog.getText()).toEqual('Hello');
});

I get this error:

$ protractor spec/e2e/conf.js Using the selenium server at http://localhost:4444/wd/hub .F

Failures:

1) alert tells the alert message Message: NoSuchAlertError: no alert open (Session info: chrome=30.0.1599.101) (Driver info: chromedriver=2.2,platform=Mac OS X 10.9.0 x86_64) (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 3 milliseconds Build info: version: '2.35.0', revision: 'c916b9d', time: '2013-08-12 15:42:01' System info: os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.9', java.version: '1.6.0_65' Session ID: edbaa752eb14ad45f7e961903b69a466 Driver info: org.openqa.selenium.chrome.ChromeDriver Capabilities [{platform=MAC, acceptSslCerts=true, javascriptEnabled=true, browserName=chrome, chrome={chromedriverVersion=2.2}, rotatable=false, locationContextEnabled=true, version=30.0.1599.101, cssSelectorsEnabled=true, databaseEnabled=true, handlesAlerts=true, browserConnectionEnabled=false, nativeEvents=true, webStorageEnabled=true, applicationCacheEnabled=false, takesScreenshot=true}]

Finished in 2.125 seconds 2 tests, 2 assertions, 1 failure

/usr/local/lib/node_modules/protractor/node_modules/selenium-webdriver/lib/webdriver/promise.js:1542 throw error; ^ NoSuchAlertError: no alert open

But I've tested it on the page and it works, and the test can clearly find the button in the DOM. So either the click() function isn't working, or something else is going on?

2

2 Answers

10
votes

Inside your test, get the current Protractor instance and use switchTo().alert() to access the alert dialog box:

var ptor = protractor.getInstance();

var alertDialog = ptor.switchTo().alert();

expect(alertDialog.getText()).toEqual("Hello");

Keep in mind that Protractor is basically just a wrapper for Selenium WebDriver so, as far as I know, anything you can do with Selenium WebDriver you can do with Protractor.

Edited to include the full test:

describe('Alert dialog', function () {

    var ptor = protractor.getInstance(),
        button;

    beforeEach(function () {
        // This line is necessary on my end to get to my test page.
        // browser.driver.get('http://localhost:8000/test.html');
        button = ptor.findElement(protractor.By.id('alertButton'));
        button.click();
    });

    it('tells the alert message', function () {
        var alertDialog = ptor.switchTo().alert();
        expect(alertDialog.getText()).toEqual("Hello");
    });

});

It is possible that your app is still initializing at the point that your test is executed, which would explain why no dialog seems to be appearing. Ensure that your app is "ready to go" and can actually display the alert before making your assertion. Hope that helps!

4
votes

You have to wait for the browser to open/display the alert. Example using Protractor 2.2.0:

   var timeoutInMilliseconds = 1000;
   browser.wait(protractor.ExpectedConditions.alertIsPresent(), timeoutInMilliseconds);
   var alertDialog = browser.switchTo().alert();
   expect(alertDialog.getText()).toEqual("Hello World!");