Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 246
tpgmartin Avatar asked Oct 20 '22 07:10

tpgmartin


2 Answers

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);
});
like image 90
tpgmartin Avatar answered Oct 23 '22 03:10

tpgmartin


In the code you are setting the style, and in the test, you are setting the attribute. Trying changing to one or the other for both. In addition, the browser will mostly likely coerce the hex color string into a rgb color string. Therefore, if you set the color to '#ff0000', it will likely be coerced into 'rgb(255, 0, 0)'. Finally, jQuery's trigger won't fire event's registered with d3's on. See https://github.com/mbostock/d3/issues/100 for details.

like image 25
Andy Thornton Avatar answered Oct 23 '22 02:10

Andy Thornton