UnknownError when mixing native promises and selenium

Hello. When mixing native promises with webdriver promises, NR monitor checks fail with UnknownError without any logging information.

Please consider the following script. It’s based on default template, I just put native promise in the middle of execution flow.

var assert = require('assert');

$browser.get('http://example.com').then(function(){
  // Check the H1 title matches "Example Domain"
  return $browser.findElement($driver.By.css('h1')).then(function(element){
    return element.getText().then(function(text){
      assert.equal('Example Domain', text, 'Page H1 title did not match');
    });
  });
}).then(function(){
  return new Promise(function(resolve, reject){
    resolve();
  })
}).then(function(){
  // Check that the external link matches "http://www.iana.org/domains/example"
  return $browser.findElement($driver.By.css('div > p > a')).then(function(element){
    return element.getAttribute('href').then(function(link){
      assert.equal('http://www.iana.org/domains/example', link, 'More information link did not match');
    });
  });
});

Executing it in validation mode gives UnknownError, no log is available. Running similar script in local environment works fine for me.

1 Like

Hi Evgeny,

I reached out to you via the ticket but wanted to post my response here too for the community. Please let me know if you have any questions on any of this:


In order to use native promises in a script, we have to wrap it in $browser.executeScript(), ie something like:

$browser.get('http://example.com').then(function () {
  // Check the H1 title matches "Example Domain"
  return $browser.findElement($driver.By.css('h1')).then(function (element) {
    return element.getText().then(function (text) {
      assert.equal('Example Domain', text, 'Page H1 title did not match');
    });
  });
}).then(function () {
  return $browser.executeScript(function () {
    return new Promise(function (resolve, reject) {
      return resolve();
    })
  })
}).then(function () {

Another option is to use the urllib-sync module:

https://docs.newrelic.com/docs/synthetics/new-relic-synthetics/scripting-monitors/import-nodejs-modules#supported-third-party-modules

Here is an example:

var request = require('urllib-sync').request;

$browser.get('http://example.com').then(function () {
  // Check the H1 title matches "Example Domain"
  return $browser.findElement($driver.By.css('h1')).then(function (element) {
    return element.getText().then(function (text) {
      assert.equal('Example Domain', text, 'Page H1 title did not match');
    });
  });
}).then(function () {
  return request('https://www.newrelic.com')
}).then(function () {

Another option is to use the q module, here is an example:

var Q = require('q');
var request = require('request');

var httpGet = function (opts) {
  var deferred = Q.defer();
  request.get(opts, deferred.resolve);
  return deferred.promise;
};

$browser.get('http://example.com').then(function () {
  // Check the H1 title matches "Example Domain"
  return $browser.findElement($driver.By.css('h1')).then(function (element) {
    return element.getText().then(function (text) {
      assert.equal('Example Domain', text, 'Page H1 title did not match');
    });
  });
}).then(function () {
  httpGet('https://www.newrelic.com');
}).then(function () {

Hope this helps!

-David

3 Likes