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

Trying to Recreate .Net Selenium Tests in Scripted Browser - Checking DFP Ad Delivery

rfb

#1

I come from a .Net background and am trying to teach myself Scripted Browsers on the fly (admittedly, I’m not good with JavaScript). I have a bunch of tests that I’ve created in .Net that need to be ‘converted’ to be used in a scripted browser. I’ve read a bunch of tutorials and examples but none seem to address what I’m trying to accomplish.

What I’m trying to do is identify all of the DIVs, on my company’s Home page, that will contain a DFP ad slot. Once I identify all of the DIVs, I’ll check each to see if they contain an iFrame as a child. I’m using xPath to find the initial group of DIVs but I’m getting a different number when using NR versus the correct number when using .Net. I know .Net is correct.

So, I guess I need to know what I’m doing wrong. This is my script. I’m expecting to identify twelve DIVs but am getting twenty-one. I was trying to iterate thru the returned array of found elements, to see the DIV IDs, but can’t seem to do that either (element.id returns ‘undefined’).

$browser.get(‘https://www.agweb.com/’)
.then(function(){
// get all of the DIV elements by partial ID
return $browser.findElements($driver.By.xpath("//div[contains(@id,‘div-gpt-ad-’)]"))
.then(function(foundElements){
// get a count of the found ad slot DIVs
var eleCt = foundElements.length;
console.log("Ad Slot DIVs Found: " + eleCt);
// iterate thru the foundElements array
foundElements.forEach(function(element){
console.log(element.id);
});
})
});


#2

Hi @dast - Coming from a .Net background myself, I found XPath to be both confusing in it’s querying structure and slower compared to other methods. I would suggest that you look at CSS Selectors on the web and use the $driver.By.css function instead. It makes for easier to read scripts as well :wink:


#3

Thanks Stefan, I’ll try CSS.

Although, I’ve found that xPath can find things when there aren’t IDs or Names and the like. I’ve actually gotten very comfortable with it. Granted, there are a lot of subtleties but it’s pretty powerful when used correctly. Interestingly, I’ve heard that xPath is faster than other methods, huh. I’ll let you know how it goes.


#4

OK, so I took Stefan’s advice and switched to using CSS to locate the DIVs for which I am searching. That worked. However, I’m still having a hard time figuring out how to iterate thru the returned ‘foundElements’ array. Here’s what the script looks like now:

$browser.get(‘https://www.agweb.com/’)
.then(function(){
// get all of the elements by partial CSS = “^=” means ‘starts with’
return $browser.findElements($driver.By.css(“div[class^=‘adblock adblock-size’]”))
.then(function(foundElements){
// get a count of the found ad slot DIVs
console.log("Ad Slot DIVs Found: " + foundElements.length);
//console.log("index: " + foundElements[0].getAttribute(“id”));
// iterate thru the foundElements array
foundElements.forEach(function(element){
console.log(element.id);
});
})
});

element.id returns ‘undefined’ fifteen times. :grimacing:


#7

Hi, @dast: This seems to work:

$browser.get('https://www.agweb.com/')
  .then(function() {
    // get all of the elements by CSS
    return $browser.findElements($driver.By.css('div.adblock'))
      .then(function(foundElements) {
        // get a count of the found ad slot DIVs
        console.log("Ad Slot DIVs Found: " + foundElements.length);
        // iterate thru the foundElements array
        foundElements.forEach(function(element) {
          element.getId()
            .then(function(id) {
              console.log(id);
            });
          });
        });
      });

#8

Thanks Phil. I’m getting values now but they do not seem to be what I am expecting. For instance, this is the first value returned from the foundElements array: 0.3972134928741007-1

I’m expecting something like this: div-gpt-ad-7924843-1

Is there a reason you changed the By.css() text?

Even when I use the ‘class starts with’ in the By.css() method the results are not what I’m expecting. :expressionless:


#9

I try to use the simplest selector that works; I assume that it will perform better. Apparently the value returned by getId() is some server-assigned ID, not the value of the id attribute. Try this:

$browser.get('https://www.agweb.com/')
  .then(function() {
    // get all of the elements by CSS
    return $browser.findElements($driver.By.css('div.adblock'))
      .then(function(foundElements) {
        // get a count of the found ad slot DIVs
        console.log("Ad Slot DIVs Found: " + foundElements.length);
        // iterate thru the foundElements array
        foundElements.forEach(function(element) {
          element.getAttribute('id')
            .then(function(id) {
              console.log(id);
            });
          });
        });
      });

#10

Thanks Phil! That’s working. Now I need to figure out how to find an iFrame that is a child of those DIVs and if that iFrame is displaying.


#11

I figured that I’d come ‘full circle’ here and post what now have that’s working (I’ve commented all of the ‘console.log’ statements that are used for testing):

var assert = require(‘assert’);
let ifrmCt = 0;
$browser.get(‘https://www.agweb.com/’)
.then(function() {
// get all of the DFP DIVs by xPath
return $browser.findElements($driver.By.xpath("//div[contains(@id,‘div-gpt-ad-’)]"))
.then(function(foundDFPDivs) {
// get a count of the found ad slot DIVs
//console.log("Ad Slot DIVs Found: " + foundDFPDivs.length);
// iterate thru the foundDFPDivs list
foundDFPDivs.forEach(function(dfpDiv) {
dfpDiv.getAttribute(‘id’)
.then(function(divId) {
// log the ID of each of the DIVs
//console.log('DIV id: ’ + divId);
// scroll the DIV element into view
$browser.executeScript(“arguments[0].scrollIntoView(true);”, dfpDiv);
// see of the dfpDiv elements contain an iFrame element
return dfpDiv.findElements($driver.By.tagName(‘iframe’))
.then(function(childIframes){
// increment the iFrame counter
ifrmCt = ifrmCt + childIframes.length;
//console.log('iFrames found: ’ + childIframes.length);
//childIframes.forEach(function(iframeTag){
// iframeTag.getAttribute(‘id’)
// .then(function(iframeId){
// console.log('iFrame id: ’ + iframeId);
// })
//})
});
});
});
})
.then(function(){
//console.log('iFrame total count: ’ + ifrmCt);
assert.notEqual(ifrmCt,0,‘Error Condition: No Ad(s) Showing’);
});
});

The key to finding child elements is using the FindElements (plural) method. If you use FindElement and the child, for which you are looking, is not present an error (that cannot be suppressed) will be generated. Using FindElements will not generate an error if the child is not found.


#12

Hey @dast - Thanks for posting your solution here :smiley:


#13

Just hoping my solution could help others. Thx, Ryan!