Your data. Anywhere you go.

New Relic for iOS or Android


Download on the App Store    Android App on Google play


New Relic Insights App for iOS


Download on the App Store


Learn more

Close icon

Is it possible to consume a REST API within a Synthetics browser test? - Use $browser and $http in the same synthetic browser test

api

#1

Is it possible to consume a REST API within a Synthetics browser test?

As part of a browser synthetic test we are implementing, we need to call a REST API to set a flag in set up and to reset the flag in tear down of the test via a PUT request.

It seems in a browser test we only have access to $browser. $http is not available as in an API test.

We tried var request = require(‘request’) so we can use the request object in the browser test to consume the REST end-point. However this appears to override the functionality of the $browser object and we see ‘NetworkError: Monitor produced no traffic’ after a request is made with the imported request when using $broswer after.


#2

Hi, @lmolloy: The following browser script works for me:

var assert = require('assert');
var request = require('request');

request.post('http://httpbin.org/post',
  // Post data
  {
    json: {
      widgetType: 'gear',
      widgetCount: 10
    }
  },
  // Callback
  function (err, response, body) {
    assert.equal(response.statusCode, 200, 'Expected a 200 OK response');

    console.log('Response:', body.json);
    assert.equal(body.json.widgetType, 'gear', 'Expected a gear widget type');
    assert.equal(body.json.widgetCount, 10, 'Expected 10 widgets');
  }
);

$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');
    });
  });
}); 

Are you sure your $browser object is successfully loading a page?


#3

Thanks for your help Phil. Your posted example works great. However the post and get are fired sync. We need to execute the $browser.get after the post has happened. I moved the .GET into the callback that happens once the post is returned and get the ‘NetworkError: Monitor produced no traffic’ error with no validation screen shot.

var assert = require(‘assert’);
var request = require(‘request’);

request.post(‘http://httpbin.org/post’,
// Post data
{
json: {
widgetType: ‘gear’,
widgetCount: 10
}
},
// Callback
function (err, response, body) {
assert.equal(response.statusCode, 200, ‘Expected a 200 OK response’);

console.log('Response:', body.json);
assert.equal(body.json.widgetType, 'gear', 'Expected a gear widget type');
assert.equal(body.json.widgetCount, 10, 'Expected 10 widgets');

$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');
    });
  });
}); 

}
);


#4

This seems to work; there has to be at least one $browser request outside of any functions or callbacks. After the initial dummy request, the rest of the script works as expected:

var assert = require('assert');
var request = require('request');

// Dummy browser request to satisfy Synthetics
$browser.get('https://www.google.com');

request.post('http://httpbin.org/post',
  // Post data
  {
    json: {
      widgetType: 'gear',
      widgetCount: 10
    }
  },
  // Callback
  function (err, response, body) {
    assert.equal(response.statusCode, 200, 'Expected a 200 OK response');

    console.log('Response:', body.json);
    assert.equal(body.json.widgetType, 'gear', 'Expected a gear widget type');
    assert.equal(body.json.widgetCount, 10, 'Expected 10 widgets');

    $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) {
          console.log('h1 text = ' + text);
          assert.equal('Example Domain', text, 'Page H1 title did not match');
        });
      });
    });
  }
);

#5

I tried the example above and it works as long as the browser.get is the only item in the chain.

In the example below I have attempted to perform other items after the browser.get by performing a search on bing. What appears to happen is the the first action after the browser.get happens but after that nothing appears to happen. The screen shot shows the search term gets entered but the button is not clicked and the search results are not shown.

If I remove the request then the search works as expected. It is like everything after the first action performed after $browser.get is ignored.

var assert = require(‘assert’);
var request = require(‘request’);

// Dummy browser request to satisfy Synthetics
$browser.get(‘http://www.example.com’);

request.post(‘http://httpbin.org/post’,
// Post data
{
json: {
widgetType: ‘gear’,
widgetCount: 10
}
},
// Callback
function (err, response, body) {
assert.equal(response.statusCode, 200, ‘Expected a 200 OK response’);

console.log('Response:', body.json);
assert.equal(body.json.widgetType, 'gear', 'Expected a gear widget type');
assert.equal(body.json.widgetCount, 10, 'Expected 10 widgets');
 
$browser.get('https://www.bing.com').then(function() {
  console.log('enter search term');
  return $browser.findElement($driver.By.id("sb_form_q")).sendKeys('new relic');
}).then(function(){
  console.log('click search button');
  return $browser.findElement($driver.By.id('sb_form_go')).click();
}).then(function(){
  console.log('wait for results');
  return $browser.findElement($driver.By.id('b_results'));
});

}
);


#6

Hi @lmolloy,

It looks like there may be an issue with asynchronous requests happening here. Placing the functions in .then() statements will help ensure that the steps are being performed in the order you would expect. I modified your code a bit for testing and the following appears to work:

var assert = require('assert');
var request = require('request');

// Dummy browser request to satisfy Synthetics
$browser.get('http://www.example.com')
.then(function(){
request.post('http://httpbin.org/post',
// Post data
{
json: {
widgetType: 'gear',
widgetCount: 10
}
},
// Callback
function (err, response, body) {
assert.equal(response.statusCode, 200, 'Expected a 200 OK response');

console.log('Response:', body.json);
assert.equal(body.json.widgetType, 'gear', 'Expected a gear widget type');
assert.equal(body.json.widgetCount, 10, 'Expected 10 widgets');
})
})


.then(function(){
    $browser.get('https://www.bing.com').then(function() {
  console.log('enter search term');
  return $browser.findElement($driver.By.id("sb_form_q")).sendKeys('new relic');
}).then(function(){
  console.log('click search button');
  return $browser.findElement($driver.By.id('sb_form_go')).click();
}).then(function(){
  console.log('wait for results');
  return $browser.findElement($driver.By.id('b_results'));
});
})

Let us know if that works for you!