javascriptjqueryd3.jsjasminejasmine-jquery

Jasmine testing mouseover events in d3


I'm looking at producing interactive chart elements using d3.js

I'm trying to test the change in fill colours due to a mouseover event with jasmine. Ideally, I want the colour of the path element to change to '#ff0000' on a mouseover but my jasmine terminal tells me that isn't happening - the element appear to remain the same colour as initially set, for instance my element with id #1 produces: Expected '#1f77b4' to be '#ff0000'.

I'm using the jquery and jasmine-jquery libraries as well.

Relevant code from my donut chart fixture, DonutChartFixture.html

var color = d3.scale.category20();

var path = svg.selectAll("path")
              .data(pie(data))
              .enter().append("path").attr("class", "path")
              .attr("fill", function(d, i) { return color(i); })
              // removed id declaration here
              .attr("d", arc)
              .on("mouseover", function(){d3.select(this).style("fill", "#ff0000");})
              .on("mouseout" , function(){d3.select(this).style("fill", function(d) {   
                                                                   return d.color;
                                                                 });});

// want to highlight the first path element
var path_one = d3.select('.path').attr("id", "path_one");

And a test from my spec file, DonutChart.js

function loadDonutChart() {
    loadFixtures('DonutChartFixture.html');
}

describe("Mouseover events", function() {
    var spyEvent;

    beforeEach(function() {
        loadDonutChart();
    });

    // updated test for element d3.select('.path').attr("id", "path_one")
    it("#path_one should change fill colour to rgb(255,0,0)", function() {
        spyEvent = spyOnEvent('#path_one', 'mouseover');
        $('#path_one').trigger("mouseover");
        // expect('mouseover').toHaveBeenTriggeredOn('#path_one');
        expect(path_one.style('fill')).toEqual('rgb(255,0,0)');
    });

});

As you can see, I've tried selecting elements by id as well as by tag name to no avail, both produce the same readout as given above. Cheers.


Solution

  • So I've come up with a passing testing, largely inspired by the answer provided here, Testing Mouseover event in D3 with Sinon. The only real difference is using d3/jasmine syntax in place of Sinon. The following passes correctly:

    it("#path_one should change fill colour to rgb(255,0,0)", function() {
        var oldColor = path.style('fill');
        document.getElementById('path_one').dispatchEvent(new MouseEvent('mouseover'));
        expect(d3.select('#path_one').style('fill')).not.toEqual(oldColor);
    });