rstacruz/jsdom-global

[Discussion] [Support needed] Best way to use jQuery

Opened this issue · 4 comments

This code seems to be working:

var jsdom = require('jsdom');

this.jsdom = require('jsdom-global')(
  htmlContent
);

// The second jsdom instance is used
jsdom.jQueryify(window, "http://code.jquery.com/jquery.js", function () {
   done()
});

But it requires to use second jsdom instance : I cannot access jsdom from 'jsdom-global'

Is there antipattern? Is there another way to use jQuery and another libs?

Is there good idea to expose jsdom instance from jsdom-global?

webxl commented

You just need to plug window into jQuery:

let jQuery = require('jquery');

console.log('Setting up jsdom for node env');

let cleanDom = require('jsdom-global')();;

let $ = jQuery(window);
global.$ = $; // make availble to other files if necessary

$('body').append('<div class="hi">Hello World!</div>');

console.log($('.hi').text());

@webxl How can you make it work with jQuery plugins ? Thank you.

webxl commented

@lionel-bijaoui The plugin just needs to be required after jQuery is added to the window global.

let jQuery = require('jquery');
console.log('Setting up jsdom for node env');
let cleanDom = require('jsdom-global')();;
let $ = jQuery(window);
require('jquery-collapse/src/jquery.collapse.js');
global.$ = $; // make availble to other files if necessary
global.jQueryCollapseSection = window.jQueryCollapseSection;
$('body').append(`<div id="test" data-collapse>
  <h2>Section 1</h2>
  <p>I'm first</p>
  <h2>Section 2</h2>
  <p>I'm second/p>
</div>`);
$('#test').collapse();

If the plugin references implicit globals, like jquery-collapse does, then you need to copy it to the node.js global object.

@webxl Thank you for your help. I think I should give you more context.
I'm testing Vue components. One of them check if (window.$ && window.$.fn.datetimepicker).
I have followed your instructions and added that in the start of the spec file

let jQuery = require("jquery");
let $ = jQuery(window);
require("eonasdan-bootstrap-datetimepicker");
global.$ = $; // make availble to other files if necessary
global.datetimepicker = window.datetimepicker;

But it fail the condition. If I change the component condition to if ($ && $.fn.datetimepicker) then it just fail because $.fn is undefined.
Simply put, $ doesn't contain a fn property, which it seem to have in a normal browser context.
Any help would be welcome, I'm in the process of updating vue-form-generator to use mocha+jsdom.

Thanks !