Skip Huffman
Skip Huffman

Reputation: 5469

jsdom not triggering internal <script>

I am trying to sample a page that has a script on it that changes the CSS of certain elements such that an attribute toggles between "active" and "inactive" based on the width of the window.

I have written nodeJS code that gathers and analyzes the page, but I cannot seem to trigger, or detect the triggering of the script. I suspect it has to do with defaultDocumentFeatures, but I could be wrong.

The script opens the page in JSDOM with a default width, then changes it to a specified block of other widths. This should result in changes in the output, but it does not. I am getting the same results for all situations. I suspect that the script on the page simply isn't running, but need help to make it do so

Here is my code (expurgated for public viewing.)

var express = require('express');
var router = express.Router();
var jsdom=require('jsdom');

router.get('/getSamplePage', function(req, res) {
    getaEpicPage(req, res, function(contents){ 
        console.log("got an sample page"+contents+"000000000");
        //contents gets replaced by the actual results that will be processed upstream
        res.send({'msg':'', 'contents':contents});
            });
});



var getaSamplePage=function (req, res, callback) {
    jsdom.defaultDocumentFeatures={
        FetchExternalResources      : ['script', 'css'],
        ProcessExternalResources    : ['script', 'css'],
        MutationEvents              : '2.0',
        QuerySelector               : false
    };
    var elementLocations=[
                    'sample_01',
                    'sample_02',
                    'sample_03'];

    var contents=[{label:'DIV ID', value:'Is Populated', width: "Screen Width", position:"element size"}];
    var windowWidths=[
        479,
        481,
        781,
        783,
        1023,
        1025,
        ]
    for (var i in windowWidths){
        jsdom.env({
            url:'http://sourcefilelocation/',
            scripts: ['http://code.jquery.com/jquery.js'],
            created: function(errors, tstWindow) {
                tstWindow.tstWindowWidth=windowWidths.pop();
                tstWindow.addEventListener('resize', function() {
                    //verify that resize is triggered
                    console.log('Resize event completed');
                });
                tstWindow.constructor.prototype.resize = function (width){
                    //defining a "resize" event, since that may be what triggers things
                    console.log("resize has been attempted");
                    tstWindow.originalWidth=tstWindow.innerWidth;
                    tstWindow.outerWidth=tstWindow.innerWidth=width;
                }
                tstWindow.readyState="complete";

            },
            done: function(errors, tstWindow) {
                setTimeout(function () {
                    //setting a timeout to ensure that any elements have finished I have put this as high as ten seconds.
                    console.log("ready state "+tstWindow.readyState);
                    tstWindow.resize(tstWindow.tstWindowWidth)

                    $=tstWindow.$;
                    for (var sampleLocation in sampleLocations) {
                        var sampleID=sampleLocations[sampleLocation];
                        $('div > [sampleAttribute='+sampleID+']').each(function(){
                            //If the script I am trying to watch work triggers, it should change the "content" attribute
                            var elementActive=$(this).css('content');
                            var position=$(this).attr('sample-position');
                            console.log("element css>>>>>>  "+tstWindow.innerWidth+" "+sampleID+" "+position+" "+elementActive);
                            if (elementActive=='"active"'){
                                contents.push({label:sampleID, value: elementActive, width: tstWindow.originalWidth+"/"+tstWindow.innerWidth, position:position});
                            }
                            });
                    };
                }, 50);
            }


            });
    };
    setTimeout(function () { callback(contents);}, 100);
};

module.exports = router;

Per suggestion I added this to my jsDom config object, just after the url:

    FetchExternalResources      : ['script', 'css'],
    ProcessExternalResources    : ['script', 'css'],
    MutationEvents              : '2.0',
    QuerySelector               : false,

But it has made no apparent difference.

Upvotes: 0

Views: 692

Answers (1)

Sebmaster
Sebmaster

Reputation: 569

As per the jsdom Readme when you're using jsdom.env the default feature set does not include processing scripts.

You have to pass the FetchExternalResources and ProcessExternalResources to jsdom.env specifically.

jsdom.env({
  html: input,
  url: url,
  features: {
    FetchExternalResources: ["script", "img", "css", "frame", "iframe", "link"],
    ProcessExternalResources: ["script"]
  },
  created: function (err, window) {
      console.log('Created');
  },

  loaded: function (err, window) {
    console.log('Loaded');
  }
});

jsdom.env doesn't use the jsdom.defaultDocumentFeatures object.

Upvotes: 4

Related Questions