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 theProtractorBrowser
. Specifically I’m testing against when I callbrowser.get('/')
orbrowser.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:
- I don’t interact with any
WebElements
directly (in fact I wrapped all myElementFinders
in functions just to be sure I was generating a new one every time I interacted with it) - I have added try/catch retries around the failing code
- 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)
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:
do
do
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 withElementArrayFinder
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
https://github.com/J-Swift/protractor-repro/blob/bc3c87c757a91461e94b99c333d37551d5a55e03/e2e/person/person.page.ts#L17-L24
https://github.com/J-Swift/protractor-repro/blob/bc3c87c757a91461e94b99c333d37551d5a55e03/e2e/person/person.steps.ts#L17-L19
Moreover, you are not mixing async/await and promise (they are compatible). You are mixing selenium promise manager and TypeScript async/await, that is a problematic usage.
At least, you should target ES6 to get native async/await support https://github.com/J-Swift/protractor-repro/blob/bc3c87c757a91461e94b99c333d37551d5a55e03/e2e/tsconfig.e2e.json#L7