1
votes

I have a piece of code which is try to see if a text is not present in an element

browser.wait(protractor.ExpectedConditions.not(protractor.ExpectedConditions.textToBePresentInElement(self.btnDashboards(),dashboardName)));

where

self.btnDashboards = function() {
    return element(this.selectors.btnDashboards);
};
var dashboardName = 'foo';

However this occasionally returns

    Fatal error: 09:54:11.129 WARN - Exception thrown
org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
  (Session info: chrome=44.0.2403.155)
  (Driver info: chromedriver=2.15.322455 (ae8db840dac8d0c453355d3d922c91adfb61df8f),platform=Mac OS X 10.10.4 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 182 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
Build info: version: '2.45.0', revision: '5017cb8', time: '2015-02-26 23:59:50'
System info: host: 'Sujits-MacBook-Pro.local', ip: '10.80.132.90', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.10.4', java.version: '1.8.0_51'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{applicationCacheEnabled=false, rotatable=false, mobileEmulationEnabled=false, chrome={userDataDir=/var/folders/tc/89n0t1qs5p3fyw_n9hk1x7fc0000gn/T/.org.chromium.Chromium.QSwwCm}, takesHeapSnapshot=true, databaseEnabled=false, handlesAlerts=true, version=44.0.2403.155, platform=MAC, browserConnectionEnabled=false, nativeEvents=true, acceptSslCerts=true, locationContextEnabled=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, cssSelectorsEnabled=true}]
Session ID: bbd4b5004df6ff3855bccacf8d16e8c0
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:204)
    at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:156)
    at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:599)
    at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:268)
    at org.openqa.selenium.remote.RemoteWebElement.getText(RemoteWebElement.java:152)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.openqa.selenium.support.events.EventFiringWebDriver$EventFiringWebElement$1.invoke(EventFiringWebDriver.java:331)
    at com.sun.proxy.$Proxy2.getText(Unknown Source)
    at org.openqa.selenium.support.events.EventFiringWebDriver$EventFiringWebElement.getText(EventFiringWebDriver.java:381)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.openqa.selenium.remote.server.KnownElements$1.invoke(KnownElements.java:63)
    at com.sun.proxy.$Proxy3.getText(Unknown Source)
    at org.openqa.selenium.remote.server.handler.GetElementText.call(GetElementText.java:29)
    at org.openqa.selenium.remote.server.handler.GetElementText.call(GetElementText.java:1)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.openqa.selenium.remote.server.DefaultSession$1.run(DefaultSession.java:168)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Is there a better way to code this so that it doesn't happen at all? Also Why is this happening occasionally rather than regularly?

1
How is btnDashboards() defined? Also, post the complete error traceback. - alecxe
It seems as issue with the selectors itself. Also I can't say, that I like the code. It is possible to declare some variables, so Protractor doesn't process everything at once. Protractor allows inserting magic in the code, but the result is not pleasant. - Dejan Toteff
@DejanToteff Could you explain the " It is possible to declare some variables, so Protractor doesn't process everything at once. Protractor allows inserting magic in the code, but the result is not pleasant" a bit more or link me to a doc. I'm new to protractor ( I came from a java background) so any tips would be nice. - user3626708
Sure thing- Protractor is not as stable, as it seems. Do everything possible to go away from complexity in your tests. For more - I wrote some tips on github.com/selfrefactor/Protractor-testing-patterns - Dejan Toteff
Thanks. For my current issue i should assign each function call as a variable to improve this? - user3626708

1 Answers

0
votes

Because browser.wait returns a promise you can use the .then({passed function}, {failed function}) to trap the error and try again. Here's what I used.

browser.prototype.wait2 = function (waitFunction, timeout, timeoutMessage) {
  var self = this;
  return browser.wait(waitFunction, timeout, timeoutMessage).then(function(pass){return pass}, function(error){
    //retry if the error is a stale element, half the timeout
    if(error.name == "StaleElementReferenceError") {
      return self.wait2(waitFunction, timeout/2, timeoutMessage);
    } else {
      throw error;
    }
  });
};