protractor: Catch certain webdriver errors like StaleElementReferenceError

I’m using protractor intensively on a heavy angular app.

Sometimes i get random webdriver errors that depend on unknown factors like server speed at that time or browser processor cpu too high at one particular moment. They happen more often in IE10/IE9, less often in FF27/IE11 and almost never in Chrome 32.

My question/request is, if there is a way i can enclose some kind of try { } catch() block around webdriver errors like StaleElementReferenceError or NoSuchWindowError so i can recover and retry instead of failing the test for things that are more selenium-webdriver related than the application or protractor itself.

I’ve tried this but doesn’t catch the error probably because webdriver errors aren’t exposed as javascript exceptions:

// Fighting against StaleElementReferenceError
var retryFindIdxElementAndExpectTextContains = function(listElms, idx, subElm, subText, attempts) {
    if (attempts == null) {
        attempts = 3;
    };

    browser.driver.findElements(listElms).
        then(function(elems) {
            elems[idx].findElement(subElm).then(function(elm) {
                try {
                    expect(elm.getText()).toContain(subText);
                } catch(err) {
                    if (attempts > 0) {
                        retryFindIdxElementAndExpectTextContains(listElms, idx, subElm, subText, attempts - 1);
                    } else {
                        throw err;
                    }
                }
            });
        });
};

About this issue

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

Most upvoted comments

You should be able to use the promise error handling returned by elm.getText(). Try

elm.getText().then(function() { // passing case}, function(err) { // error handling here})

Stop using findElement in your page objects, replace for example

this.username = ptor.findElement(protractor.By.css(‘input[name=“email”]’));

With

this.username = $('input[name=email]'); // or element(by.css('input[name="email"]')) if you're verbose

Do the same with the rest, retry and if still getting StaleElementReferenceError let us know.