diff --git a/test/jasmine/tests/gl2d_click_test.js b/test/jasmine/tests/gl2d_click_test.js index a7d679a09ed..f53282b6f8f 100644 --- a/test/jasmine/tests/gl2d_click_test.js +++ b/test/jasmine/tests/gl2d_click_test.js @@ -4,6 +4,7 @@ var Lib = require('@src/lib'); var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); var customMatchers = require('../assets/custom_matchers'); +var fail = require('../assets/fail_test.js'); // cartesian click events events use the hover data // from the mousemove events and then simulate @@ -16,585 +17,283 @@ Plotly.register([ require('@lib/contourgl') ]); -describe('@noCI Test hover and click interactions', function() { - - var mock = require('@mocks/gl2d_14.json'); - var mock2 = require('@mocks/gl2d_pointcloud-basic.json'); - var mock3 = { - 'data': [ - { - 'type': 'contourgl', - 'z': [ - [ - 10, - 10.625, - 12.5, - 15.625, - 20 - ], - [ - 5.625, - 6.25, - 8.125, - 11.25, - 15.625 - ], - [ - 2.5, - 3.125, - 5, - 8.125, - 12.5 - ], - [ - 0.625, - 1.25, - 3.125, - 6.25, - 10.625 - ], - [ - 0, - 0.625, - 2.5, - 5.625, - 10 - ] - ], - 'colorscale': 'Jet', -/* 'contours': { - 'start': 2, - 'end': 10, - 'size': 1 - },*/ - 'uid': 'ad5624', - 'zmin': 0, - 'zmax': 20 - } +var mock1 = require('@mocks/gl2d_14.json'); +var mock2 = require('@mocks/gl2d_pointcloud-basic.json'); + +var mock3 = { + data: [{ + type: 'contourgl', + z: [ + [10, 10.625, 12.5, 15.625, 20], + [5.625, 6.25, 8.125, 11.25, 15.625], + [2.5, 3.125, 5, 8.125, 12.5], + [0.625, 1.25, 3.125, 6.25, 10.625], + [0, 0.625, 2.5, 5.625, 10] ], - 'layout': { - 'xaxis': { - 'range': [ - 0, - 4 - ], - 'autorange': true - }, - 'yaxis': { - 'range': [ - 0, - 4 - ], - 'autorange': true - }, - 'height': 450, - 'width': 1000, - 'autosize': true - } - }; - var mock4 = { - data: [ - { - x: [1, 2, 3, 4], - y: [12, 3, 14, 4], - type: 'scattergl', - mode: 'markers' - }, - { - x: [4, 5, 6, 7], - y: [1, 31, 24, 14], - type: 'scattergl', - mode: 'markers' - }, - { - x: [8, 9, 10, 11], - y: [18, 13, 10, 3], - type: 'scattergl', - mode: 'markers' - }], - layout: {} - }; - - var mockCopy, gd; - - function check(pt) { - expect(Object.keys(pt)).toEqual([ - 'x', 'y', 'curveNumber', 'pointNumber', 'data', 'fullData', 'xaxis', 'yaxis' - ]); - - expect(pt.x).toEqual(15.772); - expect(pt.y).toEqual(0.387); - expect(pt.curveNumber).toEqual(0); - expect(pt.pointNumber).toEqual(33); - expect(pt.fullData.length).toEqual(1); - expect(typeof pt.data.uid).toEqual('string'); - expect(pt.xaxis.domain.length).toEqual(2); - expect(pt.yaxis.domain.length).toEqual(2); - } - - beforeAll(function() { - jasmine.addMatchers(customMatchers); - }); - - beforeEach(function() { - gd = createGraphDiv(); - mockCopy = Lib.extendDeep({}, mock); - }); - - afterEach(destroyGraphDiv); - - describe('hover event is fired on hover', function() { - var futureData; - - it('in general', function(done) { - - var modifiedMockCopy = Lib.extendDeep({}, mockCopy); - - Plotly.plot(gd, modifiedMockCopy.data, modifiedMockCopy.layout) - - .then(new Promise(function() { - - gd.on('plotly_hover', function(data) { - futureData = data; - }); - - hover(654.7712871743302, 316.97670766680994); - - window.setTimeout(function() { - - expect(futureData.points.length).toEqual(1); - - var pt = futureData.points[0]; - - check(pt); - - done(); - }, 250); - })); - - + colorscale: 'Jet', + // contours: { start: 2, end: 10, size: 1 }, + zmin: 0, + zmax: 20 + }], + layout: {} +}; + +var mock4 = { + data: [{ + x: [1, 2, 3, 4], + y: [12, 3, 14, 4], + type: 'scattergl', + mode: 'markers' + }, { + x: [4, 5, 6, 7], + y: [1, 31, 24, 14], + type: 'scattergl', + mode: 'markers' + }, { + x: [8, 9, 10, 11], + y: [18, 13, 10, 3], + type: 'scattergl', + mode: 'markers' + }], + layout: {} +}; + +describe('Test hover and click interactions', function() { + var gd; + + // need to wait a little bit before canvas can properly catch mouse events + function wait() { + return new Promise(function(resolve) { + setTimeout(resolve, 100); }); + } - it('even when hoverinfo (== plotly tooltip) is set to none', function(done) { - - var modifiedMockCopy = Lib.extendDeep({}, mockCopy); - modifiedMockCopy.data[0].hoverinfo = 'none'; - - Plotly.plot(gd, modifiedMockCopy.data, modifiedMockCopy.layout) - - .then(new Promise(function() { - - gd.on('plotly_hover', function(data) { - futureData = data; - }); - - hover(654.7712871743302, 316.97670766680994); - - window.setTimeout(function() { - - expect(futureData.points.length).toEqual(1); - - var pt = futureData.points[0]; - - check(pt); - - done(); - }, 250); - })); - - - }); - - it('event happens even on a click interaction', function(done) { - - var modifiedMockCopy = Lib.extendDeep({}, mockCopy); - modifiedMockCopy.data[0].hoverinfo = 'none'; - - Plotly.plot(gd, modifiedMockCopy.data, modifiedMockCopy.layout) - - .then(new Promise(function() { - - gd.on('plotly_hover', function(data) { - futureData = data; - }); - - click(654.7712871743302, 316.97670766680994); - - window.setTimeout(function() { - - expect(futureData.points.length).toEqual(1); - - var pt = futureData.points[0]; - - check(pt); - - done(); - }, 250); - })); - - - }); - - it('unhover happens', function(done) { - - var modifiedMockCopy = Lib.extendDeep({}, mockCopy); - modifiedMockCopy.data[0].hoverinfo = 'none'; - - Plotly.plot(gd, modifiedMockCopy.data, modifiedMockCopy.layout) - - .then(new Promise(function() { - - futureData = undefined; - - gd.on('plotly_unhover', function() { - futureData = 'emitted plotly_unhover'; - }); - - hover(654.7712871743302, 316.97670766680994); - - // fairly realistic simulation of moving with the cursor - window.setTimeout(function() { - - var x = 654, y = 316; // we start here - var canceler = window.setInterval(function() { - hover(x--, y++); // move the cursor - }, 10); + function makeHoverFn(gd, x, y) { + return function() { + return new Promise(function(resolve) { + gd.on('plotly_hover', resolve); + hover(x, y); + }); + }; + } - window.setTimeout(function() { - window.clearInterval(canceler); // stop the mouse at some point - }, 250); + function makeClickFn(gd, x, y) { + return function() { + return new Promise(function(resolve) { + gd.on('plotly_click', resolve); + click(x, y); + }); + }; + } - window.setTimeout(function() { + function makeUnhoverFn(gd, x0, y0) { + return function() { + return new Promise(function(resolve) { + var eventData = null; - expect(futureData).toEqual('emitted plotly_unhover'); + gd.on('plotly_unhover', function() { + eventData = 'emitted plotly_unhover'; + }); - done(); + // fairly realistic simulation of moving with the cursor + var canceler = setInterval(function() { + hover(x0--, y0--); + }, 10); + + setTimeout(function() { + clearInterval(canceler); + resolve(eventData); + }, 350); + }); + }; + } - }, 250); + function assertEventData(actual, expected) { + expect(actual.points.length).toEqual(1, 'points length'); - }, 250); - })); + var pt = actual.points[0]; - }); + expect(Object.keys(pt)).toEqual([ + 'x', 'y', 'curveNumber', 'pointNumber', + 'data', 'fullData', 'xaxis', 'yaxis' + ], 'event data keys'); + + expect(typeof pt.data.uid).toEqual('string', 'uid'); + expect(pt.xaxis.domain.length).toEqual(2, 'xaxis'); + expect(pt.yaxis.domain.length).toEqual(2, 'yaxis'); + + expect(pt.x).toEqual(expected.x, 'x'); + expect(pt.y).toEqual(expected.y, 'y'); + expect(pt.curveNumber).toEqual(expected.curveNumber, 'curve number'); + expect(pt.pointNumber).toEqual(expected.pointNumber, 'point number'); + } + // returns basic hover/click/unhover runner for one xy position + function makeRunner(pos, expected, opts) { + opts = opts || {}; + + var _hover = makeHoverFn(gd, pos[0], pos[1]); + var _click = makeClickFn(gd, pos[0], pos[1]); + + var _unhover = opts.noUnHover ? + function() { return 'emitted plotly_unhover'; } : + makeUnhoverFn(gd, pos[0], pos[1]); + + return function() { + return wait() + .then(_hover) + .then(function(eventData) { + assertEventData(eventData, expected); + }) + .then(_click) + .then(function(eventData) { + assertEventData(eventData, expected); + }) + .then(_unhover) + .then(function(eventData) { + expect(eventData).toEqual('emitted plotly_unhover'); + }); + }; + } + beforeAll(function() { + jasmine.addMatchers(customMatchers); }); - describe('hover event is fired for other gl2d plot types', function() { - var futureData; - - it('pointcloud', function(done) { - - var modifiedMockCopy = Lib.extendDeep({}, mock2); - - Plotly.plot(gd, modifiedMockCopy.data, modifiedMockCopy.layout) - - .then(new Promise(function() { - - gd.on('plotly_hover', function(data) { - futureData = data; - }); - - hover(540, 150); - - window.setTimeout(function() { - - expect(futureData.points.length).toEqual(1); - - var pt = futureData.points[0]; - - expect(Object.keys(pt)).toEqual([ - 'x', 'y', 'curveNumber', 'pointNumber', 'data', 'fullData', 'xaxis', 'yaxis' - ]); - - expect(pt.x).toEqual(4.5); - expect(pt.y).toEqual(9); - expect(pt.curveNumber).toEqual(2); - expect(pt.pointNumber).toEqual(1); - expect(pt.fullData.length).toEqual(3); - expect(typeof pt.data.uid).toEqual('string'); - expect(pt.xaxis.domain.length).toEqual(2); - expect(pt.yaxis.domain.length).toEqual(2); - - done(); - }, 350); - })); + beforeEach(function() { + gd = createGraphDiv(); + }); + afterEach(function() { + Plotly.purge(gd); + destroyGraphDiv(); + }); + it('should output correct event data for scattergl', function(done) { + var _mock = Lib.extendDeep({}, mock1); + var run = makeRunner([655, 317], { + x: 15.772, + y: 0.387, + curveNumber: 0, + pointNumber: 33 }); - it('heatmapgl', function(done) { - - var modifiedMockCopy = Lib.extendDeep({}, mock3); - modifiedMockCopy.data[0].type = 'heatmapgl'; - - Plotly.plot(gd, modifiedMockCopy.data, modifiedMockCopy.layout) - - .then(new Promise(function() { - - gd.on('plotly_hover', function(data) { - futureData = data; - }); - - hover(540, 150); - - window.setTimeout(function() { - - expect(futureData.points.length).toEqual(1); - - var pt = futureData.points[0]; - - expect(Object.keys(pt)).toEqual([ - 'x', 'y', 'curveNumber', 'pointNumber', 'data', 'fullData', 'xaxis', 'yaxis' - ]); - - expect(pt.x).toEqual(2); - expect(pt.y).toEqual(3); - expect(pt.curveNumber).toEqual(0); - expect(pt.pointNumber).toEqual([2, 3]); - expect(pt.fullData.length).toEqual(1); - expect(typeof pt.data.uid).toEqual('string'); - expect(pt.xaxis.domain.length).toEqual(2); - expect(pt.yaxis.domain.length).toEqual(2); - - done(); - }, 350); - })); + Plotly.plot(gd, _mock) + .then(run) + .catch(fail) + .then(done); + }); + it('should output correct event data for scattergl with hoverinfo: \'none\'', function(done) { + var _mock = Lib.extendDeep({}, mock1); + _mock.data[0].hoverinfo = 'none'; + var run = makeRunner([655, 317], { + x: 15.772, + y: 0.387, + curveNumber: 0, + pointNumber: 33 }); - it('scattergl', function(done) { - - var modifiedMockCopy = Lib.extendDeep({}, mock4); - - function _hover() { - hover(435, 216); + Plotly.plot(gd, _mock) + .then(run) + .catch(fail) + .then(done); + }); - return new Promise(function(resolve) { - setTimeout(resolve, 350); - }); - } + it('should output correct event data for pointcloud', function(done) { + var _mock = Lib.extendDeep({}, mock2); - Plotly.plot(gd, modifiedMockCopy.data, modifiedMockCopy.layout).then(function() { - gd.on('plotly_hover', function(data) { - futureData = data; - }); - }) - .then(_hover) - .then(function() { - expect(futureData.points.length).toEqual(1); - - var pt = futureData.points[0]; - - expect(Object.keys(pt)).toEqual([ - 'x', 'y', 'curveNumber', 'pointNumber', 'data', 'fullData', 'xaxis', 'yaxis' - ]); - - expect(pt.x).toEqual(8); - expect(pt.y).toEqual(18); - expect(pt.curveNumber).toEqual(2); - expect(pt.pointNumber).toEqual(0); - expect(pt.fullData.length).toEqual(3); - expect(typeof pt.data.uid).toEqual('string'); - expect(pt.xaxis.domain.length).toEqual(2); - expect(pt.yaxis.domain.length).toEqual(2); - - return Plotly.restyle(gd, 'visible', false, [1, 2]); - }) - .then(_hover) - .then(function() { - var pt = futureData.points[0]; - - expect(pt.x).toEqual(8); - expect(pt.y).toEqual(18); - expect(pt.curveNumber).toEqual(2, 'matches input data index'); - expect(pt.pointNumber).toEqual(0); - }) - .then(done); + var run = makeRunner([540, 150], { + x: 4.5, + y: 9, + curveNumber: 2, + pointNumber: 1 }); - it('scattergl-fancy', function(done) { - - var modifiedMockCopy = Lib.extendDeep({}, mock4); - modifiedMockCopy.data[0].mode = 'markers+lines'; - modifiedMockCopy.data[1].mode = 'markers+lines'; - modifiedMockCopy.data[2].mode = 'markers+lines'; - - Plotly.plot(gd, modifiedMockCopy.data, modifiedMockCopy.layout) - - .then(new Promise(function() { - - gd.on('plotly_hover', function(data) { - futureData = data; - }); - - hover(435, 216); - - window.setTimeout(function() { - - expect(futureData.points.length).toEqual(1); - - var pt = futureData.points[0]; - - expect(Object.keys(pt)).toEqual([ - 'x', 'y', 'curveNumber', 'pointNumber', 'data', 'fullData', 'xaxis', 'yaxis' - ]); - - expect(pt.x).toEqual(8); - expect(pt.y).toEqual(18); - expect(pt.curveNumber).toEqual(2); - expect(pt.pointNumber).toEqual(0); - expect(pt.fullData.length).toEqual(3); - expect(typeof pt.data.uid).toEqual('string'); - expect(pt.xaxis.domain.length).toEqual(2); - expect(pt.yaxis.domain.length).toEqual(2); + Plotly.plot(gd, _mock) + .then(run) + .catch(fail) + .then(done); + }); - done(); - }, 350); - })); + it('should output correct event data for heatmapgl', function(done) { + var _mock = Lib.extendDeep({}, mock3); + _mock.data[0].type = 'heatmapgl'; + + var run = makeRunner([540, 150], { + x: 3, + y: 3, + curveNumber: 0, + pointNumber: [3, 3] + }, { + noUnHover: true }); - it('contourgl', function(done) { - - var modifiedMockCopy = Lib.extendDeep({}, mock3); - - Plotly.plot(gd, modifiedMockCopy.data, modifiedMockCopy.layout) - - .then(new Promise(function() { - - gd.on('plotly_hover', function(data) { - futureData = data; - }); - - hover(540, 150); - - window.setTimeout(function() { - - expect(futureData.points.length).toEqual(1); - - var pt = futureData.points[0]; - - expect(Object.keys(pt)).toEqual([ - 'x', 'y', 'curveNumber', 'pointNumber', 'data', 'fullData', 'xaxis', 'yaxis' - ]); - - expect(pt.x).toEqual(2); - expect(pt.y).toEqual(3); - expect(pt.curveNumber).toEqual(0); - expect(pt.pointNumber).toEqual([2, 3]); - expect(pt.fullData.length).toEqual(1); - expect(typeof pt.data.uid).toEqual('string'); - expect(pt.xaxis.domain.length).toEqual(2); - expect(pt.yaxis.domain.length).toEqual(2); - - done(); - }, 350); - })); - }); + Plotly.plot(gd, _mock) + .then(run) + .catch(fail) + .then(done); }); - describe('click event is fired on click', function() { - var futureData; - - it('in general', function(done) { - - var modifiedMockCopy = Lib.extendDeep({}, mockCopy); - - Plotly.plot(gd, modifiedMockCopy.data, modifiedMockCopy.layout) - - .then(new Promise(function() { - - gd.on('plotly_click', function(data) { - futureData = data; - }); - - click(654.7712871743302, 316.97670766680994); - - window.setTimeout(function() { - - var pt = futureData.points[0]; - - check(pt); - - done(); - - }, 350); - })); + it('should output correct event data for scattergl after visibility restyle', function(done) { + var _mock = Lib.extendDeep({}, mock4); + var run = makeRunner([435, 216], { + x: 8, + y: 18, + curveNumber: 2, + pointNumber: 0 }); - it('even when hoverinfo (== plotly tooltip) is set to none', function(done) { - - var modifiedMockCopy = Lib.extendDeep({}, mockCopy); - modifiedMockCopy.data[0].hoverinfo = 'none'; - - Plotly.plot(gd, modifiedMockCopy.data, modifiedMockCopy.layout) - - .then(new Promise(function() { - - gd.on('plotly_hover', function(data) { - futureData = data; - }); - - hover(654.7712871743302, 316.97670766680994); - - window.setTimeout(function() { - - expect(futureData.points.length).toEqual(1); - - var pt = futureData.points[0]; - - check(pt); - - done(); - }, 250); - })); - + Plotly.plot(gd, _mock) + .then(run) + .then(function() { + return Plotly.restyle(gd, 'visible', false, [1]); + }) + .then(run) + .catch(fail) + .then(done); + }); + it('should output correct event data for scattergl-fancy', function(done) { + var _mock = Lib.extendDeep({}, mock4); + _mock.data[0].mode = 'markers+lines'; + _mock.data[1].mode = 'markers+lines'; + _mock.data[2].mode = 'markers+lines'; + + var run = makeRunner([435, 216], { + x: 8, + y: 18, + curveNumber: 2, + pointNumber: 0 }); - it('unhover happens', function(done) { - - var modifiedMockCopy = Lib.extendDeep({}, mockCopy); - modifiedMockCopy.data[0].hoverinfo = 'none'; - - Plotly.plot(gd, modifiedMockCopy.data, modifiedMockCopy.layout) - - .then(new Promise(function() { - - futureData = undefined; - - gd.on('plotly_unhover', function() { - futureData = 'emitted plotly_unhover'; - }); - - hover(654.7712871743302, 316.97670766680994); - - // fairly realistic simulation of moving with the cursor - window.setTimeout(function() { - - var x = 654, y = 316; // we start here - var canceler = window.setInterval(function() { - hover(x--, y++); // move the cursor - }, 10); - - window.setTimeout(function() { - window.clearInterval(canceler); // stop the mouse at some point - }, 250); - - window.setTimeout(function() { - - expect(futureData).toEqual('emitted plotly_unhover'); - - done(); - - }, 250); + Plotly.plot(gd, _mock) + .then(run) + .then(function() { + return Plotly.restyle(gd, 'visible', false, [1]); + }) + .then(run) + .catch(fail) + .then(done); + }); - }, 250); - })); + it('should output correct event data contourgl', function(done) { + var _mock = Lib.extendDeep({}, mock3); + var run = makeRunner([540, 150], { + x: 3, + y: 3, + curveNumber: 0, + pointNumber: [3, 3] + }, { + noUnHover: true }); + Plotly.plot(gd, _mock) + .then(run) + .catch(fail) + .then(done); }); });