protractor: StaleElementReferenceError when interacting with browser

Hey there, thanks for the project, it really simplifies angular UI testing!

I’m very new to using protractor so this very well may be user error, but I’ve tried everything I’ve seen online and not found a solution that addresses my issue.

  • Node Version: 8.7.0
  • Protractor Version: 5.3.0
  • Angular Version: 5.2.4
  • Browser(s): chrome
  • Operating System and Version OSX 10.3.4
  • Your protractor configuration file
const { SpecReporter } = require('jasmine-spec-reporter');

const config = {
  allScriptsTimeout: 11000,
  capabilities: {
    browserName: 'chrome'
  },
  directConnect: true,
  baseUrl: 'http://localhost:4200/',
  useAllAngular2AppRoots: true,

  framework: 'custom',
  frameworkPath: require.resolve('protractor-cucumber-framework'),

  specs: ['./e2e/**/*.feature'],
  cucumberOpts: {
    require: ['./e2e/_shared/setup.ts', './e2e/**/*.steps.ts'],
    tags: [],
    format: ['node_modules/cucumber-pretty'],
    strict: true,
    dryRun: false,
    compiler: []
  },

  beforeLaunch: function () {
    require('ts-node').register({
      project: 'e2e/tsconfig.e2e.json'
    });
  },

  // Work around for EPIPE errors that I was running into (serializing execution
  // as recommended by https://github.com/angular/protractor/issues/4294#issuecomment-357941307)
  onPrepare: function () {
    let currentCommand = Promise.resolve();
    const webdriverSchedule = browser.driver.schedule;
    browser.driver.schedule = (command, description) => {
      currentCommand = currentCommand.then(() =>
        webdriverSchedule.call(browser.driver, command, description)
      );
      return currentCommand;
    };
  },
};

exports.config = config;
  • A relevant example test I am consistently getting a StaleElementReferenceError when interacting with the ProtractorBrowser. Specifically I’m testing against when I call browser.get('/') or browser.driver.getTitle().
  • Output from running the test
StaleElementReferenceError: stale element reference: element is not attached to the page document
  (Session info: chrome=66.0.3359.181)
  (Driver info: chromedriver=2.38.552518 (183d19265345f54ce39cbb94cf81ba5f15905011),platform=Mac OS X 10.13.4 x86_64)
    at Object.checkLegacyResponse ([...]/node_modules/selenium-webdriver/lib/error.js:546:15)
    at parseHttpResponse ([...]/node_modules/selenium-webdriver/lib/http.js:509:13)
    at doSend.then.response ([...]/node_modules/selenium-webdriver/lib/http.js:441:30)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
From: Task: WebElement.isEnabled()
    at Driver.schedule ([...]/node_modules/selenium-webdriver/lib/webdriver.js:807:17)
    at currentCommand.then ([...]/protractor.conf.js:47:27)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
  • Steps to reproduce the bug It seems to only occur along with certain cucumber scenarios that I am running, but I’m really struggling to understand what state could be saved that is triggering the error in the first place.

Some notes on what I’ve done:

  1. I don’t interact with any WebElements directly (in fact I wrapped all my ElementFinders in functions just to be sure I was generating a new one every time I interacted with it)
  2. I have added try/catch retries around the failing code
  3. I’ve tried adding sleeps before the failing code

Any insight is much appreciated, let me know if you need more information. Thank you!

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 21 (7 by maintainers)

Most upvoted comments

Alright, I’ve gone ahead and verified that your advice fixed my original application as well @awarecan. Many, many thanks for your help!

Again, for future readers, the gist of my issues were fixed by:

  1. Ensuring all instances of selenium promises were converted to regular promises. e.g. instead of
foo() {
    return browser.get('/person');
}

do

async foo() {
    await browser.get('/person');
}
  1. Dont return promises to cucumber e.g. instead of
Given('I am on the dashboard', function() {
    return dashboardPage.navigateTo();
})

do

Given('I am on the dashboard', async function() {
    await dashboardPage.navigateTo();
})
  1. Remove EPIPE workaround https://github.com/J-Swift/protractor-repro/blob/bc3c87c757a91461e94b99c333d37551d5a55e03/protractor.conf.js#L28-L38

By doing this, I was able to get rid of the StaleElementReferenceError but I did have a couple issues with EPIPE that I had to work through. It ended up being related to how I was interacting with ElementArrayFinder to parse table data. Once I restructured those patterns, my tests are all green again!

Ok, thank you @awarecan, I was not familiar with the selenium promise vs normal promise. I think you are right that treating these the same are where I’m having issues.

I went through the repro app and replaced all returns of wdPromise with a normal promise, then removed the EPIPE workaround, and it looks like that fixes my issue! I’m going to go ahead and do the same for the real application.

I’ve pushed the updated app in case it is helpful for someone in the future working through the same issues: https://github.com/J-Swift/protractor-repro