javascript - Selenium WebDriverJS thenCatch not catching StaleElementException -


i running node.js , selenium webdriverjs. 1 of tests failing following error:

unknownerror: unknown error: runtime.evaluate threw exception: error: element not attached page document 

i understand staleelementreferenceexception, have not been able find reliable workaround. have tried following without success:

  1. waiting element appear on page before finding , clicking on element

    waitforelement: function (selector, timeout) {     if (typeof(timeout) === 'undefined') { timeout = 3000; }     driver.wait(function() {         return driver.findelements(selector).then(function(list) {             return list.length > 0;         });     }, timeout); } 
  2. waiting explicit time period (driver.sleep(1000)) before finding , clicking on element
  3. finding element multiple times (using .findelement()) before clicking on element
  4. using promise chain catch errors , try re-clicking on element

    driver.gettitle().then(function(title) {     driver.findelement(webdriver.by.xpath(...)).click(); }).thencatch(function(e) {     driver.findelement(webdriver.by.xpath(...)).click(); }); 
  5. using promise chain recursive function keep trying re-click element

    var getstaleelement = function(selector, callback) {     var element = driver.findelement(selector);     callback(element); }).thencatch(function(e) {     getstaleelement(selector, callback); });  var clickself = function(ele) { return ele.click() };  driver.gettitle().then(function(title) {     driver.findelement(webdriver.by.xpath(...)).click(); }).thencatch(function(e) {     getstaleelement(webdriver.by.xpath(...), clickself); }); 
  6. methods 4 , 5 using errback argument of .then() in place of .thencatch()
  7. combinations of above

it seems selenium not able catch specific error. used print statements confirm other errors such nosuchelementerror caught .thencatch(). there workaround allow me deal stale elements?

i had similar problem, made below work-around, can give try ...

/*  * params.config - {  *           opposite - {boolean} - if true, wait till negative result reached/ error thrown.  *           maxwaittime - {number} - if time exceeds, throw error , leave.  *           waittime - {number} - wait time between 2 checks.  *           expectvalue - {boolean} - want run without error, or should expect value  *           expectedvalue - {object} - object value should or should not match.  *         }  *  params.fn - function returns promise want keep checking till desire value reached  */ function waiter(fn, config){     config = config || {};     var deffered = driver.promise.defer(),           wt = config.waittime || 100,         mwt = config.maxwaittime || 3000,         timeoutreached = false,         pcall = function(){                         fn().then(pthen, pcatch);                     },         pthen = function(data){                     if(timeoutreached)  return;                     if(config.expectvalue){                         if(config.opposite){                                                     if(data == config.expectedvalue){                                 settimeout(pcall, wt);                             }else{                                 cleartimeout(vtimeout);                                 deffered.fulfill(true);                             }                         }else{                             if(data == config.expectedvalue){                                 cleartimeout(vtimeout);                                 deffered.fulfill(true);                             }else{                                 settimeout(pcall, wt);                             }                         }                     }else{                         deffered.fulfill(true);                     }                 },           pcatch = function(err){                     if(timeoutreached)  return;                     if(config.opposite){                         deffered.fulfill(true);                     }else{                         settimeout(pcall, wt);                     }                 };        pcall();          var vtimeout = settimeout(function(){         timeoutreached = true;         if(config.opposite){             deffered.fulfill(true);                  }else{             deffered.reject(new error('timed-out'));         }     }, mwt);     return deffered.promise; } 

example usage( case):

var mypromise = function(){     return driver.findelement(webdriver.by.xpath(...)).click(); };  //default use waiter(mypromise).then(function(){     console.log('finally...'); }).catch(fucntion(err){     console.log('not working: ', err); });  // custom timeout after 10 seconds waiter(mypromise, {maxwaittime: 10000}).then(function(){     console.log('finally...'); }).catch(fucntion(err){     console.log('not working: ', err); }); 

Comments