Problem
I am testing some Blaze templates that include <svg>
elements with various <g>
children. The tests use jQuery to check, whether the correct children are rendered by various input.
While I can at least check for the existence of svg
I can't however get any of it's children - neither by class nor by id.
Empty child elements
Logging the svg .children
to the console reveals for every child {}
. The templates are rendering fine when running my application and this behavior only occurs when trying to access the children of the Template in the tests.
Empty SVG contentDocument
I am also not able to retrieve the svg's content doc:
// does unfortunately not return contentDoc
const svgDom = template.find('svg').get(0).contentDoc;
Code Example
To reproduce, consider the following template:
<template name="svgtest">
<svg width="100%" height="100%">
<g class="element1"></g>
<g class="element2"></g>
</svg>
</template>
and the corresponding tests:
import { _ } from 'meteor/underscore';
import { Template } from 'meteor/templating';
import { Blaze } from 'meteor/blaze';
import { Tracker } from 'meteor/tracker';
import { assert } from 'meteor/practicalmeteor:chai';
// the test helpers, you know them
// from the Meteor testing guide
const withDiv = function withDiv(callback) {
const el = document.createElement('div');
document.body.appendChild(el);
try {
callback(el);
} finally {
document.body.removeChild(el);
}
};
const withRenderedTemplate = function withRenderedTemplate(template, data, callback) {
withDiv((el) => {
const ourTemplate = _.isString(template) ? Template[template] : template;
Blaze.renderWithData(ourTemplate, data, el);
Tracker.flush();
callback(el);
});
};
describe('svgtest', function () {
beforeEach(function () {
Template.registerHelper('_', key => key);
});
afterEach(function () {
Template.deregisterHelper('_');
});
it('renders correctly with simple data', function () {
withRenderedTemplate('svgtest', {}, (el) => {
const template = $(el);
// passes
assert.equal(template.find('svg').length, 1);
// does unfortunately not return contentDoc
const svgDom = template.find('svg').get(0).contentDoc;
// fails with AssertionError: expected 0 to equal 1
assert.equal(template.find('.element1').length, 1);
assert.equal(template.find('.element2').length, 1);
});
});
});
Related
I checked already the following SO resources to access the elements:
retrieve child elements of svg g
JQuery and SVG - how to find the 'g' tag
How to use jquery in SVG (Scalable Vector Graphics)?
How to access SVG elements with Javascript
However, they only work in my running app but not in the tests. I also would like to avoid the jQuery svg plugin as this messes up the Meteor builtin jQuery.
I assume that this needs a Blaze-specific solution in order to make the SVG DOM accessible to the unit context.
Has somebody solved this already or found a workaround?