diff --git a/.circleci/test.sh b/.circleci/test.sh index 8094323e6d5..050cb809b31 100755 --- a/.circleci/test.sh +++ b/.circleci/test.sh @@ -54,7 +54,6 @@ case $1 in set_tz SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --tag=gl | circleci tests split)) - for s in ${SHARDS[@]}; do retry npm run test-jasmine -- "$s" --tags=gl --skip-tags=noCI --showSkipped done @@ -65,7 +64,7 @@ case $1 in jasmine3) set_tz - SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --tag=flaky | circleci tests split)) + SHARDS=($(node $ROOT/tasks/shard_jasmine_tests.js --limit=1 --tag=flaky | circleci tests split)) for s in ${SHARDS[@]}; do retry npm run test-jasmine -- "$s" --tags=flaky --skip-tags=noCI --showSkipped diff --git a/test/jasmine/tests/gl2d_click_test.js b/test/jasmine/tests/gl2d_click_test.js index 7854dc85dbe..9d59f00eb53 100644 --- a/test/jasmine/tests/gl2d_click_test.js +++ b/test/jasmine/tests/gl2d_click_test.js @@ -14,11 +14,9 @@ var assertHoverLabelContent = customAssertions.assertHoverLabelContent; // from the mousemove events and then simulate // a click event on mouseup var click = require('../assets/timed_click'); -var doubleClick = require('../assets/double_click'); var hover = require('../assets/hover'); var delay = require('../assets/delay'); var mouseEvent = require('../assets/mouse_event'); -var readPixel = require('../assets/read_pixel'); // contourgl is not part of the dist plotly.js bundle initially Plotly.register([ @@ -560,620 +558,3 @@ describe('Test hover and click interactions', function() { .then(done); }); }); - -describe('@noCI Test gl2d lasso/select:', function() { - var mockFancy = require('@mocks/gl2d_14.json'); - delete mockFancy.layout.xaxis.autorange; - delete mockFancy.layout.yaxis.autorange; - mockFancy.layout.xaxis.range = [-2.951309064136961, 2.0954721318818916]; - mockFancy.layout.yaxis.range = [-0.9248866483012275, 1.3232607344525835]; - - var mockFast = Lib.extendDeep({}, mockFancy, { - data: [{mode: 'markers'}], - layout: { - xaxis: { - type: 'linear', - range: [-3.869222222222223, 73.55522222222223] - }, - yaxis: { - type: 'linear', - range: [-0.7402222222222222, 17.144222222222222] - } - } - }); - - var gd; - var selectPath = [[98, 193], [108, 193]]; - var selectPath2 = [[118, 193], [128, 193]]; - var lassoPath = [[316, 171], [318, 239], [335, 243], [328, 169]]; - var lassoPath2 = [[98, 193], [108, 193], [108, 500], [98, 500], [98, 193]]; - - afterEach(function() { - Plotly.purge(gd); - destroyGraphDiv(); - }); - - function drag(path) { - var len = path.length; - var el = d3.select(gd).select('rect.nsewdrag').node(); - var opts = {element: el}; - - Lib.clearThrottle(); - mouseEvent('mousemove', path[0][0], path[0][1], opts); - mouseEvent('mousedown', path[0][0], path[0][1], opts); - - path.slice(1, len).forEach(function(pt) { - Lib.clearThrottle(); - mouseEvent('mousemove', pt[0], pt[1], opts); - }); - - mouseEvent('mouseup', path[len - 1][0], path[len - 1][1], opts); - } - - function select(path) { - return new Promise(function(resolve, reject) { - gd.once('plotly_selected', resolve); - setTimeout(function() { reject('did not trigger *plotly_selected*');}, 200); - drag(path); - }); - } - - function assertEventData(actual, expected) { - expect(actual.points.length).toBe(expected.points.length); - - expected.points.forEach(function(e, i) { - var a = actual.points[i]; - if(a) { - expect(a.x).toBe(e.x, 'x'); - expect(a.y).toBe(e.y, 'y'); - } - }); - } - - - it('@gl should work under fast mode with *select* dragmode', function(done) { - var _mock = Lib.extendDeep({}, mockFast); - _mock.layout.dragmode = 'select'; - gd = createGraphDiv(); - - Plotly.plot(gd, _mock) - .then(delay(100)) - .then(function() { - expect(gd._fullLayout._plots.xy._scene.select2d).not.toBe(undefined, 'scatter2d renderer'); - - return select(selectPath); - }) - .then(delay(100)) - .then(function(eventData) { - assertEventData(eventData, { - points: [ - {pointNumber: 25, x: 1.425, y: 0.538}, - {pointNumber: 26, x: 1.753, y: 0.5}, - {pointNumber: 27, x: 2.22, y: 0.45} - ] - }); - }) - .catch(failTest) - .then(done); - }); - - it('@gl should work under fast mode with *lasso* dragmode', function(done) { - var _mock = Lib.extendDeep({}, mockFast); - _mock.layout.dragmode = 'lasso'; - gd = createGraphDiv(); - - Plotly.plot(gd, _mock) - .then(delay(100)) - .then(function() { - return select(lassoPath2); - }) - .then(delay(100)) - .then(function(eventData) { - assertEventData(eventData, { - points: [ - {pointNumber: 25, x: 1.425, y: 0.538}, - {pointNumber: 26, x: 1.753, y: 0.5}, - {pointNumber: 27, x: 2.22, y: 0.45} - ] - }); - }) - .catch(failTest) - .then(done); - }); - - it('@gl should work under fancy mode with *select* dragmode', function(done) { - var _mock = Lib.extendDeep({}, mockFancy); - _mock.layout.dragmode = 'select'; - gd = createGraphDiv(); - - Plotly.plot(gd, _mock) - .then(delay(100)) - .then(function() { - return select(selectPath2); - }) - .then(delay(100)) - .then(function(eventData) { - assertEventData(eventData, { - points: [{x: 0.004, y: 12.5}] - }); - }) - .catch(failTest) - .then(done); - }); - - it('@gl should work under fancy mode with *lasso* dragmode', function(done) { - var _mock = Lib.extendDeep({}, mockFancy); - _mock.layout.dragmode = 'lasso'; - gd = createGraphDiv(); - - Plotly.plot(gd, _mock) - .then(delay(100)) - .then(function() { - return select(lassoPath); - }) - .then(function(eventData) { - assertEventData(eventData, { - points: [{ x: 0.099, y: 2.75 }] - }); - }) - .catch(failTest) - .then(done); - }); - - it('@gl should work on trace with enabled transforms', function(done) { - var fig = Lib.extendDeep({}, require('@mocks/gl2d_transforms.json')); - fig.layout.dragmode = 'select'; - fig.layout.margin = {t: 0, b: 0, l: 0, r: 0}; - fig.layout.height = 500; - fig.layout.width = 500; - gd = createGraphDiv(); - - Plotly.plot(gd, fig) - .then(delay(100)) - .then(function() { return select([[100, 100], [250, 250]]); }) - .then(function(eventData) { - assertEventData(eventData, { - points: [ - { x: 3, y: 4 }, - { x: 2, y: 4 } - ] - }); - }) - .catch(failTest) - .then(done); - }); - - it('@gl should work on gl text charts', function(done) { - var fig = Lib.extendDeep({}, require('@mocks/gl2d_text_chart_basic.json')); - fig.layout.dragmode = 'select'; - fig.layout.margin = {t: 0, b: 0, l: 0, r: 0}; - fig.layout.height = 500; - fig.layout.width = 500; - gd = createGraphDiv(); - - function _assertGlTextOpts(msg, exp) { - var scene = gd.calcdata[0][0].t._scene; - scene.glText.forEach(function(opts, i) { - expect(Array.from(opts.color)) - .toBeCloseToArray(exp.rgba[i], 2, 'item ' + i + ' - ' + msg); - }); - } - - Plotly.plot(gd, fig) - .then(delay(100)) - .then(function() { - _assertGlTextOpts('base', { - rgba: [ - [68, 68, 68, 255], - [68, 68, 68, 255], - [68, 68, 68, 255] - ] - }); - }) - .then(function() { return select([[100, 100], [250, 250]]); }) - .then(function(eventData) { - assertEventData(eventData, { - points: [{x: 1, y: 2}] - }); - _assertGlTextOpts('after selection', { - rgba: [ - [ - 68, 68, 68, 51, - 68, 68, 68, 51, - 68, 68, 68, 51, - ], - [ - 68, 68, 68, 51, - // this is the selected pt! - 68, 68, 68, 255, - 68, 68, 68, 51 - ], - [ - 68, 68, 68, 51, - 68, 68, 68, 51, - 68, 68, 68, 51 - ] - ] - }); - }) - .then(function() { - return Plotly.restyle(gd, 'selected.textfont.color', 'red'); - }) - .then(function() { return select([[100, 100], [250, 250]]); }) - .then(function() { - _assertGlTextOpts('after selection - with set selected.textfont.color', { - rgba: [ - [ - 68, 68, 68, 255, - 68, 68, 68, 255, - 68, 68, 68, 255, - ], - [ - 68, 68, 68, 255, - // this is the selected pt! - 255, 0, 0, 255, - 68, 68, 68, 255 - ], - [ - 68, 68, 68, 255, - 68, 68, 68, 255, - 68, 68, 68, 255 - ] - ] - }); - }) - .catch(failTest) - .then(done); - }); - - it('@gl should work on gl text charts with array textfont.color', function(done) { - var fig = Lib.extendDeep({}, require('@mocks/gl2d_text_chart_arrays.json')); - fig.layout.dragmode = 'select'; - fig.layout.margin = {t: 0, b: 0, l: 0, r: 0}; - fig.layout.height = 500; - fig.layout.width = 500; - gd = createGraphDiv(); - - function _assertGlTextOpts(msg, exp) { - var scene = gd.calcdata[0][0].t._scene; - scene.glText.forEach(function(opts, i) { - expect(Array.from(opts.color)) - .toBeCloseToArray(exp.rgba[i], 2, 'item ' + i + ' - ' + msg); - }); - } - - Plotly.plot(gd, fig) - .then(delay(100)) - .then(function() { - _assertGlTextOpts('base', { - rgba: [ - [ - 255, 0, 0, 255, - 0, 0, 255, 255, - 0, 128, 0, 255 - ], - [ - 0, 0, 0, 255, - 211, 211, 210, 255, - 237, 97, 0, 255 - ] - ] - }); - }) - .then(function() { return select([[100, 10], [250, 100]]); }) - .then(function(eventData) { - assertEventData(eventData, { - points: [{x: 1, y: 2}] - }); - _assertGlTextOpts('after selection', { - rgba: [ - [ - 255, 0, 0, 51, - 0, 0, 255, 51, - 0, 128, 0, 51 - ], - [ - 0, 0, 0, 51, - // this is the selected pt! - 211, 211, 210, 255, - 237, 97, 0, 51 - ] - ] - }); - }) - .then(function() { - return Plotly.restyle(gd, 'selected.textfont.color', 'red'); - }) - .then(function() { return select([[100, 10], [250, 100]]); }) - .then(function() { - _assertGlTextOpts('after selection - with set selected.textfont.color', { - rgba: [ - [ - 255, 0, 0, 255, - 0, 0, 255, 255, - 0, 128, 0, 255 - ], - [ - 0, 0, 0, 255, - // this is the selected pt! - 255, 0, 0, 255, - 237, 97, 0, 255 - ] - ] - }); - }) - .catch(failTest) - .then(done); - }); - - it('@gl should work after a width/height relayout', function(done) { - gd = createGraphDiv(); - - var w = 500; - var h = 500; - var w2 = 800; - var h2 = 600; - var pad = 20; - - function _read(query) { - var canvas = gd.querySelector(query); - return readPixel(canvas, 0, 0, gd.layout.width, gd.layout.height) - .reduce(function(acc, v) { return acc + v; }, 0); - } - - function readContext() { return _read('.gl-canvas-context'); } - - function readFocus() { return _read('.gl-canvas-focus'); } - - Plotly.plot(gd, [{ - type: 'scattergl', - mode: 'markers', - y: [2, 1, 2] - }], { - dragmode: 'select', - margin: {t: 0, b: 0, l: 0, r: 0}, - width: w, height: h - }) - .then(delay(100)) - .then(function() { - expect(readContext()).toBeGreaterThan(1e4, 'base context'); - expect(readFocus()).toBe(0, 'base focus'); - }) - .then(function() { return select([[pad, pad], [w - pad, h - pad]]); }) - .then(function() { - expect(readContext()).toBe(0, 'select context'); - expect(readFocus()).toBeGreaterThan(1e4, 'select focus'); - }) - .then(function() { - return Plotly.update(gd, - {selectedpoints: null}, - {width: w2, height: h2} - ); - }) - .then(function() { - expect(readContext()).toBeGreaterThan(1e4, 'update context'); - expect(readFocus()).toBe(0, 'update focus'); - }) - .then(function() { return select([[pad, pad], [w2 - pad, h2 - pad]]); }) - .then(function() { - // make sure full w2/h2 context canvas is cleared! - // from https://github.com/plotly/plotly.js/issues/2731 - expect(readContext()).toBe(0, 'update+select context'); - expect(readFocus()).toBeGreaterThan(1e4, 'update+select focus'); - }) - .catch(failTest) - .then(done); - }); - - it('@gl should behave correctly during select+doubleclick+pan scenarios', function(done) { - gd = createGraphDiv(); - - // See https://github.com/plotly/plotly.js/issues/2767 - - function grabScene() { - return gd.calcdata[0][0].t._scene; - } - - function _assert(msg, exp) { - var scene = grabScene(); - var scatter2d = scene.scatter2d; - - expect((scene.markerOptions || [])[0].opacity) - .toBe(1, 'marker.opacity - ' + msg); - expect((scene.markerSelectedOptions || [])[0].opacity) - .toBe(1, 'selected.marker.opacity - ' + msg); - expect((scene.markerUnselectedOptions || [])[0].opacity) - .toBe(0.2, 'unselected.marker.opacity - ' + msg); - - expect(scene.selectBatch).toEqual(exp.selectBatch); - expect(scene.unselectBatch).toEqual(exp.unselectBatch); - - var updateCalls = scatter2d.update.calls.all(); - var drawCalls = scatter2d.draw.calls.all(); - - expect(updateCalls.length).toBe( - exp.updateArgs.length, - 'scatter2d.update has been called the correct number of times - ' + msg - ); - updateCalls.forEach(function(d, i) { - d.args.forEach(function(arg, j) { - if('range' in arg[0]) { - // no need to assert range value in detail - expect(exp.updateArgs[i][j]).toBe( - 'range', - 'scatter.update range update - ' + msg - ); - } else { - expect(arg).toBe( - exp.updateArgs[i][j], - 'scatter.update call' + i + ' arg' + j + ' - ' + msg - ); - } - }); - }); - - expect(drawCalls.length).toBe( - exp.drawArgs.length, - 'scatter2d.draw has been called the correct number of times - ' + msg - ); - drawCalls.forEach(function(d, i) { - d.args.forEach(function(arg, j) { - expect(arg).toBe( - exp.drawArgs[i][j], - 'scatter.draw call' + i + ' arg' + j + ' - ' + msg - ); - }); - }); - - scene.scatter2d.update.calls.reset(); - scene.scatter2d.draw.calls.reset(); - } - - var unselectBatchOld; - - Plotly.newPlot('graph', [{ - type: 'scattergl', - mode: 'markers', - y: [1, 2, 1], - marker: {size: 30} - }], { - dragmode: 'select', - margin: {t: 0, b: 0, l: 0, r: 0}, - width: 500, - height: 500 - }) - .then(delay(100)) - .then(function() { - var scene = grabScene(); - spyOn(scene.scatter2d, 'update').and.callThrough(); - spyOn(scene.scatter2d, 'draw').and.callThrough(); - }) - .then(function() { - _assert('base', { - selectBatch: [], - unselectBatch: [], - updateArgs: [], - drawArgs: [] - }); - }) - .then(function() { return select([[20, 20], [480, 250]]); }) - .then(function() { - var scene = grabScene(); - _assert('after select', { - selectBatch: [[1]], - unselectBatch: [[0, 2]], - updateArgs: [ - // N.B. scatter2d now draws unselected options - [scene.markerUnselectedOptions], - ], - drawArgs: [ - [scene.unselectBatch] - ] - }); - }) - .then(function() { return doubleClick(250, 250); }) - .then(function() { - var scene = grabScene(); - _assert('after doubleclick', { - selectBatch: [null], - unselectBatch: [[0, 1, 2]], - updateArgs: [], - drawArgs: [ - // call in no-selection loop (can we get rid of this?) - [0], - // call with unselectBatch - [scene.unselectBatch] - ] - }); - }) - .then(function() { return Plotly.relayout(gd, 'dragmode', 'pan'); }) - .then(function() { - _assert('after relayout to *pan*', { - selectBatch: [null], - unselectBatch: [[0, 1, 2]], - // nothing to do when relayouting to 'pan' - updateArgs: [], - drawArgs: [] - }); - - // keep ref for next _assert() - var scene = grabScene(); - unselectBatchOld = scene.unselectBatch; - }) - .then(function() { return drag([[200, 200], [250, 250]]); }) - .then(function() { - var scene = grabScene(); - _assert('after pan', { - selectBatch: null, - unselectBatch: null, - // drag triggers: - // - 2 scene.update() calls, which each invoke - // + 1 scatter2d.update (updating viewport) - // + 2 scatter2d.draw (same as after double-click) - // - // replot on mouseup triggers: - // - 1 scatter2d.update updating viewport - // - 1 scatter2d.update resetting markerOptions - // - 1 (full) scene.draw() - updateArgs: [ - ['range'], - ['range'], - // N.B. bring scatter2d back to 'base' marker options - [scene.markerOptions], - ['range'] - ], - drawArgs: [ - [0], - [unselectBatchOld], - [0], - [unselectBatchOld], - [0] - ] - }); - }) - .catch(failTest) - .then(done); - }); - - it('@gl should work on overlaid subplots', function(done) { - gd = createGraphDiv(); - - var scene, scene2; - - Plotly.plot(gd, [{ - x: [1, 2, 3], - y: [40, 50, 60], - type: 'scattergl', - mode: 'markers' - }, { - x: [2, 3, 4], - y: [4, 5, 6], - yaxis: 'y2', - type: 'scattergl', - mode: 'markers' - }], { - xaxis: {domain: [0.2, 1]}, - yaxis2: {overlaying: 'y', side: 'left', position: 0}, - showlegend: false, - margin: {l: 0, t: 0, b: 0, r: 0}, - width: 400, - height: 400, - dragmode: 'select' - }) - .then(delay(100)) - .then(function() { - scene = gd._fullLayout._plots.xy._scene; - scene2 = gd._fullLayout._plots.xy2._scene; - - spyOn(scene.scatter2d, 'draw'); - spyOn(scene2.scatter2d, 'draw'); - }) - .then(function() { return select([[20, 20], [380, 250]]); }) - .then(function() { - expect(scene.scatter2d.draw).toHaveBeenCalledTimes(1); - expect(scene2.scatter2d.draw).toHaveBeenCalledTimes(1); - }) - .catch(failTest) - .then(done); - }); -}); diff --git a/test/jasmine/tests/gl2d_double_click_test.js b/test/jasmine/tests/gl2d_double_click_test.js new file mode 100644 index 00000000000..a9ed24461de --- /dev/null +++ b/test/jasmine/tests/gl2d_double_click_test.js @@ -0,0 +1,636 @@ +var Plotly = require('@lib/index'); +var Lib = require('@src/lib'); + +var d3 = require('d3'); +var createGraphDiv = require('../assets/create_graph_div'); +var destroyGraphDiv = require('../assets/destroy_graph_div'); +var failTest = require('../assets/fail_test.js'); + +// cartesian click events events use the hover data +// from the mousemove events and then simulate +// a click event on mouseup +var doubleClick = require('../assets/double_click'); +var delay = require('../assets/delay'); +var mouseEvent = require('../assets/mouse_event'); +var readPixel = require('../assets/read_pixel'); + +// contourgl is not part of the dist plotly.js bundle initially +Plotly.register([ + require('@lib/contourgl') +]); + +describe('Test gl2d lasso/select:', function() { + var mockFancy = require('@mocks/gl2d_14.json'); + delete mockFancy.layout.xaxis.autorange; + delete mockFancy.layout.yaxis.autorange; + mockFancy.layout.xaxis.range = [-2.951309064136961, 2.0954721318818916]; + mockFancy.layout.yaxis.range = [-0.9248866483012275, 1.3232607344525835]; + + var mockFast = Lib.extendDeep({}, mockFancy, { + data: [{mode: 'markers'}], + layout: { + xaxis: { + type: 'linear', + range: [-3.869222222222223, 73.55522222222223] + }, + yaxis: { + type: 'linear', + range: [-0.7402222222222222, 17.144222222222222] + } + } + }); + + var gd; + var selectPath = [[98, 193], [108, 193]]; + var selectPath2 = [[118, 193], [128, 193]]; + var lassoPath = [[316, 171], [318, 239], [335, 243], [328, 169]]; + var lassoPath2 = [[98, 193], [108, 193], [108, 500], [98, 500], [98, 193]]; + + afterEach(function() { + Plotly.purge(gd); + destroyGraphDiv(); + }); + + function drag(path) { + var len = path.length; + var el = d3.select(gd).select('rect.nsewdrag').node(); + var opts = {element: el}; + + Lib.clearThrottle(); + mouseEvent('mousemove', path[0][0], path[0][1], opts); + mouseEvent('mousedown', path[0][0], path[0][1], opts); + + path.slice(1, len).forEach(function(pt) { + Lib.clearThrottle(); + mouseEvent('mousemove', pt[0], pt[1], opts); + }); + + mouseEvent('mouseup', path[len - 1][0], path[len - 1][1], opts); + } + + function select(path) { + return new Promise(function(resolve, reject) { + gd.once('plotly_selected', resolve); + setTimeout(function() { reject('did not trigger *plotly_selected*');}, 200); + drag(path); + }); + } + + function assertEventData(actual, expected) { + expect(actual.points.length).toBe(expected.points.length); + + expected.points.forEach(function(e, i) { + var a = actual.points[i]; + if(a) { + expect(a.x).toBe(e.x, 'x'); + expect(a.y).toBe(e.y, 'y'); + } + }); + } + + it('@gl should work under fast mode with *select* dragmode', function(done) { + var _mock = Lib.extendDeep({}, mockFast); + _mock.layout.dragmode = 'select'; + gd = createGraphDiv(); + + Plotly.plot(gd, _mock) + .then(delay(20)) + .then(function() { + expect(gd._fullLayout._plots.xy._scene.select2d).not.toBe(undefined, 'scatter2d renderer'); + + return select(selectPath); + }) + .then(delay(20)) + .then(function(eventData) { + assertEventData(eventData, { + points: [ + {pointNumber: 25, x: 1.425, y: 0.538}, + {pointNumber: 26, x: 1.753, y: 0.5}, + {pointNumber: 27, x: 2.22, y: 0.45} + ] + }); + }) + .catch(failTest) + .then(done); + }); + + it('@gl should work under fast mode with *lasso* dragmode', function(done) { + var _mock = Lib.extendDeep({}, mockFast); + _mock.layout.dragmode = 'lasso'; + gd = createGraphDiv(); + + Plotly.plot(gd, _mock) + .then(delay(20)) + .then(function() { + return select(lassoPath2); + }) + .then(delay(20)) + .then(function(eventData) { + assertEventData(eventData, { + points: [ + {pointNumber: 25, x: 1.425, y: 0.538}, + {pointNumber: 26, x: 1.753, y: 0.5}, + {pointNumber: 27, x: 2.22, y: 0.45} + ] + }); + }) + .catch(failTest) + .then(done); + }); + + it('@gl should work under fancy mode with *select* dragmode', function(done) { + var _mock = Lib.extendDeep({}, mockFancy); + _mock.layout.dragmode = 'select'; + gd = createGraphDiv(); + + Plotly.plot(gd, _mock) + .then(delay(20)) + .then(function() { + return select(selectPath2); + }) + .then(delay(20)) + .then(function(eventData) { + assertEventData(eventData, { + points: [{x: 0.004, y: 12.5}] + }); + }) + .catch(failTest) + .then(done); + }); + + it('@gl should work under fancy mode with *lasso* dragmode', function(done) { + var _mock = Lib.extendDeep({}, mockFancy); + _mock.layout.dragmode = 'lasso'; + gd = createGraphDiv(); + + Plotly.plot(gd, _mock) + .then(delay(20)) + .then(function() { + return select(lassoPath); + }) + .then(function(eventData) { + assertEventData(eventData, { + points: [{ x: 0.099, y: 2.75 }] + }); + }) + .catch(failTest) + .then(done); + }); + + it('@gl should work on trace with enabled transforms', function(done) { + var fig = Lib.extendDeep({}, require('@mocks/gl2d_transforms.json')); + fig.layout.dragmode = 'select'; + fig.layout.margin = {t: 0, b: 0, l: 0, r: 0}; + fig.layout.height = 500; + fig.layout.width = 500; + gd = createGraphDiv(); + + Plotly.plot(gd, fig) + .then(delay(20)) + .then(function() { return select([[100, 100], [250, 250]]); }) + .then(function(eventData) { + assertEventData(eventData, { + points: [ + { x: 3, y: 4 }, + { x: 2, y: 4 } + ] + }); + }) + .catch(failTest) + .then(done); + }); + + it('@gl should work on gl text charts', function(done) { + var fig = Lib.extendDeep({}, require('@mocks/gl2d_text_chart_basic.json')); + fig.layout.dragmode = 'select'; + fig.layout.margin = {t: 0, b: 0, l: 0, r: 0}; + fig.layout.height = 500; + fig.layout.width = 500; + gd = createGraphDiv(); + + function _assertGlTextOpts(msg, exp) { + var scene = gd.calcdata[0][0].t._scene; + scene.glText.forEach(function(opts, i) { + expect(Array.from(opts.color)) + .toBeCloseToArray(exp.rgba[i], 2, 'item ' + i + ' - ' + msg); + }); + } + + Plotly.plot(gd, fig) + .then(delay(20)) + .then(function() { + _assertGlTextOpts('base', { + rgba: [ + [68, 68, 68, 255], + [68, 68, 68, 255], + [68, 68, 68, 255] + ] + }); + }) + .then(function() { return select([[100, 100], [250, 250]]); }) + .then(function(eventData) { + assertEventData(eventData, { + points: [{x: 1, y: 2}] + }); + _assertGlTextOpts('after selection', { + rgba: [ + [ + 68, 68, 68, 51, + 68, 68, 68, 51, + 68, 68, 68, 51, + ], + [ + 68, 68, 68, 51, + // this is the selected pt! + 68, 68, 68, 255, + 68, 68, 68, 51 + ], + [ + 68, 68, 68, 51, + 68, 68, 68, 51, + 68, 68, 68, 51 + ] + ] + }); + }) + .then(function() { + return Plotly.restyle(gd, 'selected.textfont.color', 'red'); + }) + .then(function() { return select([[100, 100], [250, 250]]); }) + .then(function() { + _assertGlTextOpts('after selection - with set selected.textfont.color', { + rgba: [ + [ + 68, 68, 68, 255, + 68, 68, 68, 255, + 68, 68, 68, 255, + ], + [ + 68, 68, 68, 255, + // this is the selected pt! + 255, 0, 0, 255, + 68, 68, 68, 255 + ], + [ + 68, 68, 68, 255, + 68, 68, 68, 255, + 68, 68, 68, 255 + ] + ] + }); + }) + .catch(failTest) + .then(done); + }); + + it('@gl should work on gl text charts with array textfont.color', function(done) { + var fig = Lib.extendDeep({}, require('@mocks/gl2d_text_chart_arrays.json')); + fig.layout.dragmode = 'select'; + fig.layout.margin = {t: 0, b: 0, l: 0, r: 0}; + fig.layout.height = 500; + fig.layout.width = 500; + gd = createGraphDiv(); + + function _assertGlTextOpts(msg, exp) { + var scene = gd.calcdata[0][0].t._scene; + scene.glText.forEach(function(opts, i) { + expect(Array.from(opts.color)) + .toBeCloseToArray(exp.rgba[i], 2, 'item ' + i + ' - ' + msg); + }); + } + + Plotly.plot(gd, fig) + .then(delay(20)) + .then(function() { + _assertGlTextOpts('base', { + rgba: [ + [ + 255, 0, 0, 255, + 0, 0, 255, 255, + 0, 128, 0, 255 + ], + [ + 0, 0, 0, 255, + 211, 211, 210, 255, + 237, 97, 0, 255 + ] + ] + }); + }) + .then(function() { return select([[100, 10], [250, 100]]); }) + .then(function(eventData) { + assertEventData(eventData, { + points: [{x: 1, y: 2}] + }); + _assertGlTextOpts('after selection', { + rgba: [ + [ + 255, 0, 0, 51, + 0, 0, 255, 51, + 0, 128, 0, 51 + ], + [ + 0, 0, 0, 51, + // this is the selected pt! + 211, 211, 210, 255, + 237, 97, 0, 51 + ] + ] + }); + }) + .then(function() { + return Plotly.restyle(gd, 'selected.textfont.color', 'red'); + }) + .then(function() { return select([[100, 10], [250, 100]]); }) + .then(function() { + _assertGlTextOpts('after selection - with set selected.textfont.color', { + rgba: [ + [ + 255, 0, 0, 255, + 0, 0, 255, 255, + 0, 128, 0, 255 + ], + [ + 0, 0, 0, 255, + // this is the selected pt! + 255, 0, 0, 255, + 237, 97, 0, 255 + ] + ] + }); + }) + .catch(failTest) + .then(done); + }); + + it('@gl should work after a width/height relayout', function(done) { + gd = createGraphDiv(); + + var w = 500; + var h = 500; + var w2 = 800; + var h2 = 600; + var pad = 20; + + function _read(query) { + var canvas = gd.querySelector(query); + return readPixel(canvas, 0, 0, gd.layout.width, gd.layout.height) + .reduce(function(acc, v) { return acc + v; }, 0); + } + + function readContext() { return _read('.gl-canvas-context'); } + + function readFocus() { return _read('.gl-canvas-focus'); } + + Plotly.plot(gd, [{ + type: 'scattergl', + mode: 'markers', + y: [2, 1, 2] + }], { + dragmode: 'select', + margin: {t: 0, b: 0, l: 0, r: 0}, + width: w, height: h + }) + .then(delay(20)) + .then(function() { + expect(readContext()).toBeGreaterThan(1e4, 'base context'); + expect(readFocus()).toBe(0, 'base focus'); + }) + .then(function() { return select([[pad, pad], [w - pad, h - pad]]); }) + .then(function() { + expect(readContext()).toBe(0, 'select context'); + expect(readFocus()).toBeGreaterThan(1e4, 'select focus'); + }) + .then(function() { + return Plotly.update(gd, + {selectedpoints: null}, + {width: w2, height: h2} + ); + }) + .then(function() { + expect(readContext()).toBeGreaterThan(1e4, 'update context'); + expect(readFocus()).toBe(0, 'update focus'); + }) + .then(function() { return select([[pad, pad], [w2 - pad, h2 - pad]]); }) + .then(function() { + // make sure full w2/h2 context canvas is cleared! + // from https://github.com/plotly/plotly.js/issues/2731 + expect(readContext()).toBe(0, 'update+select context'); + expect(readFocus()).toBeGreaterThan(1e4, 'update+select focus'); + }) + .catch(failTest) + .then(done); + }); + + it('@gl should behave correctly during select+doubleclick+pan scenarios', function(done) { + gd = createGraphDiv(); + + // See https://github.com/plotly/plotly.js/issues/2767 + + function grabScene() { + return gd.calcdata[0][0].t._scene; + } + + function _assert(msg, exp) { + var scene = grabScene(); + var scatter2d = scene.scatter2d; + + expect((scene.markerOptions || [])[0].opacity) + .toBe(1, 'marker.opacity - ' + msg); + expect((scene.markerSelectedOptions || [])[0].opacity) + .toBe(1, 'selected.marker.opacity - ' + msg); + expect((scene.markerUnselectedOptions || [])[0].opacity) + .toBe(0.2, 'unselected.marker.opacity - ' + msg); + + expect(scene.selectBatch).toEqual(exp.selectBatch); + expect(scene.unselectBatch).toEqual(exp.unselectBatch); + + var updateCalls = scatter2d.update.calls.all(); + var drawCalls = scatter2d.draw.calls.all(); + + expect(updateCalls.length).toBe( + exp.updateArgs.length, + 'scatter2d.update has been called the correct number of times - ' + msg + ); + updateCalls.forEach(function(d, i) { + d.args.forEach(function(arg, j) { + if('range' in arg[0]) { + // no need to assert range value in detail + expect(exp.updateArgs[i][j]).toBe( + 'range', + 'scatter.update range update - ' + msg + ); + } else { + expect(arg).toBe( + exp.updateArgs[i][j], + 'scatter.update call' + i + ' arg' + j + ' - ' + msg + ); + } + }); + }); + + expect(drawCalls.length).toBe( + exp.drawArgs.length, + 'scatter2d.draw has been called the correct number of times - ' + msg + ); + drawCalls.forEach(function(d, i) { + d.args.forEach(function(arg, j) { + expect(arg).toBe( + exp.drawArgs[i][j], + 'scatter.draw call' + i + ' arg' + j + ' - ' + msg + ); + }); + }); + + scene.scatter2d.update.calls.reset(); + scene.scatter2d.draw.calls.reset(); + } + + var unselectBatchOld; + + Plotly.newPlot('graph', [{ + type: 'scattergl', + mode: 'markers', + y: [1, 2, 1], + marker: {size: 30} + }], { + dragmode: 'select', + margin: {t: 0, b: 0, l: 0, r: 0}, + width: 500, + height: 500 + }) + .then(delay(20)) + .then(function() { + var scene = grabScene(); + spyOn(scene.scatter2d, 'update').and.callThrough(); + spyOn(scene.scatter2d, 'draw').and.callThrough(); + }) + .then(function() { + _assert('base', { + selectBatch: [], + unselectBatch: [], + updateArgs: [], + drawArgs: [] + }); + }) + .then(function() { return select([[20, 20], [480, 250]]); }) + .then(function() { + var scene = grabScene(); + _assert('after select', { + selectBatch: [[1]], + unselectBatch: [[0, 2]], + updateArgs: [ + // N.B. scatter2d now draws unselected options + [scene.markerUnselectedOptions], + ], + drawArgs: [ + [scene.unselectBatch] + ] + }); + }) + .then(function() { return doubleClick(250, 250); }) + .then(function() { + var scene = grabScene(); + _assert('after doubleclick', { + selectBatch: [null], + unselectBatch: [[0, 1, 2]], + updateArgs: [], + drawArgs: [ + // call in no-selection loop (can we get rid of this?) + [0], + // call with unselectBatch + [scene.unselectBatch] + ] + }); + }) + .then(function() { return Plotly.relayout(gd, 'dragmode', 'pan'); }) + .then(function() { + _assert('after relayout to *pan*', { + selectBatch: [null], + unselectBatch: [[0, 1, 2]], + // nothing to do when relayouting to 'pan' + updateArgs: [], + drawArgs: [] + }); + + // keep ref for next _assert() + var scene = grabScene(); + unselectBatchOld = scene.unselectBatch; + }) + .then(function() { return drag([[200, 200], [250, 250]]); }) + .then(function() { + var scene = grabScene(); + _assert('after pan', { + selectBatch: null, + unselectBatch: null, + // drag triggers: + // - 2 scene.update() calls, which each invoke + // + 1 scatter2d.update (updating viewport) + // + 2 scatter2d.draw (same as after double-click) + // + // replot on mouseup triggers: + // - 1 scatter2d.update updating viewport + // - 1 scatter2d.update resetting markerOptions + // - 1 (full) scene.draw() + updateArgs: [ + ['range'], + ['range'], + // N.B. bring scatter2d back to 'base' marker options + [scene.markerOptions], + ['range'] + ], + drawArgs: [ + [0], + [unselectBatchOld], + [0], + [unselectBatchOld], + [0] + ] + }); + }) + .catch(failTest) + .then(done); + }); + + it('@gl should work on overlaid subplots', function(done) { + gd = createGraphDiv(); + + var scene, scene2; + + Plotly.plot(gd, [{ + x: [1, 2, 3], + y: [40, 50, 60], + type: 'scattergl', + mode: 'markers' + }, { + x: [2, 3, 4], + y: [4, 5, 6], + yaxis: 'y2', + type: 'scattergl', + mode: 'markers' + }], { + xaxis: {domain: [0.2, 1]}, + yaxis2: {overlaying: 'y', side: 'left', position: 0}, + showlegend: false, + margin: {l: 0, t: 0, b: 0, r: 0}, + width: 400, + height: 400, + dragmode: 'select' + }) + .then(delay(20)) + .then(function() { + scene = gd._fullLayout._plots.xy._scene; + scene2 = gd._fullLayout._plots.xy2._scene; + + spyOn(scene.scatter2d, 'draw'); + spyOn(scene2.scatter2d, 'draw'); + }) + .then(function() { return select([[20, 20], [380, 250]]); }) + .then(function() { + expect(scene.scatter2d.draw).toHaveBeenCalledTimes(1); + expect(scene2.scatter2d.draw).toHaveBeenCalledTimes(1); + }) + .catch(failTest) + .then(done); + }); +}); diff --git a/test/jasmine/tests/gl2d_plot_interact_test.js b/test/jasmine/tests/gl2d_plot_interact_test.js index 5895a8b8dfe..5ee7b040dc8 100644 --- a/test/jasmine/tests/gl2d_plot_interact_test.js +++ b/test/jasmine/tests/gl2d_plot_interact_test.js @@ -24,6 +24,7 @@ describe('Test removal of gl contexts', function() { var gd; beforeEach(function() { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; gd = createGraphDiv(); }); @@ -96,6 +97,7 @@ describe('Test gl plot side effects', function() { var gd; beforeEach(function() { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; gd = createGraphDiv(); }); @@ -214,7 +216,7 @@ describe('Test gl plot side effects', function() { .then(done); }); - it('@noCI @gl should fire *plotly_webglcontextlost* when on webgl context lost', function(done) { + it('@gl should fire *plotly_webglcontextlost* when on webgl context lost', function(done) { var _mock = Lib.extendDeep({}, require('@mocks/gl2d_12.json')); function _trigger(name) { @@ -550,7 +552,7 @@ describe('Test gl2d plots', function() { .then(done); }); - it('@noCI @gl should display selection of big number of regular points', function(done) { + it('@gl should display selection of big number of regular points', function(done) { // generate large number of points var x = []; var y = []; @@ -581,7 +583,7 @@ describe('Test gl2d plots', function() { .then(done); }); - it('@noCI @gl should display selection of big number of miscellaneous points', function(done) { + it('@gl should display selection of big number of miscellaneous points', function(done) { var colorList = [ '#006385', '#F06E75', '#90ed7d', '#f7a35c', '#8085e9', '#f15c80', '#e4d354', '#2b908f', '#f45b5b', '#91e8e1', @@ -1273,9 +1275,19 @@ describe('Test gl2d plots', function() { }); describe('Test scattergl autorange:', function() { - afterEach(destroyGraphDiv); - describe('should return the same value as SVG scatter for ~small~ data', function() { + var gd; + + beforeEach(function() { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; + gd = createGraphDiv(); + }); + + afterEach(function() { + Plotly.purge(gd); + destroyGraphDiv(); + }); + var specs = [ {name: 'lines+markers', fig: require('@mocks/gl2d_10.json')}, {name: 'bubbles', fig: require('@mocks/gl2d_12.json')}, @@ -1286,7 +1298,6 @@ describe('Test scattergl autorange:', function() { specs.forEach(function(s) { it('@gl - case ' + s.name, function(done) { - var gd = createGraphDiv(); var glRangeX; var glRangeY; @@ -1319,6 +1330,7 @@ describe('Test scattergl autorange:', function() { var gd; beforeEach(function() { + jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; gd = createGraphDiv(); // to avoid expansive draw calls (which could be problematic on CI) spyOn(ScatterGl, 'plot').and.callFake(function(gd) { @@ -1327,6 +1339,11 @@ describe('Test scattergl autorange:', function() { }); }); + afterEach(function() { + Plotly.purge(gd); + destroyGraphDiv(); + }); + // threshold for 'fast' axis expansion routine var N = 1e5; var x = new Array(N); diff --git a/test/jasmine/tests/gl2d_pointcloud_test.js b/test/jasmine/tests/gl2d_pointcloud_test.js index 5106709ef05..73a4b6eb664 100644 --- a/test/jasmine/tests/gl2d_pointcloud_test.js +++ b/test/jasmine/tests/gl2d_pointcloud_test.js @@ -195,7 +195,7 @@ describe('pointcloud traces', function() { it('@gl should not change other traces colors', function(done) { var _mock = Lib.extendDeep({}, multipleScatter2dMock); Plotly.plot(gd, _mock) - .then(delay(40)) + .then(delay(20)) .then(function() { var canvas = d3.select('.gl-canvas-context').node(); @@ -225,13 +225,13 @@ describe('pointcloud traces', function() { } Plotly.plot(gd, Lib.extendDeep({}, plotData)) - .then(delay(40)) + .then(delay(20)) .then(function() { _assertRange('base', [-0.548, 9.548], [-1.415, 10.415]); }) - .then(delay(40)) + .then(delay(20)) .then(function() { _drag([200, 200], [350, 350]); }) - .then(delay(40)) + .then(delay(20)) .then(function() { _assertRange('after zoombox drag', [0.768, 1.591], [5.462, 7.584]); }) @@ -247,9 +247,9 @@ describe('pointcloud traces', function() { .then(function() { return Plotly.relayout(gd, 'dragmode', 'pan'); }) - .then(delay(40)) + .then(delay(20)) .then(function() { _drag([200, 200], [350, 350]); }) - .then(delay(40)) + .then(delay(20)) .then(function() { _assertRange('after pan drag', [0.2743, 10.3719], [-3.537, 8.292]); }) diff --git a/test/jasmine/tests/parcoords_test.js b/test/jasmine/tests/parcoords_test.js index 7137e9f4dc7..40de35e4954 100644 --- a/test/jasmine/tests/parcoords_test.js +++ b/test/jasmine/tests/parcoords_test.js @@ -488,7 +488,7 @@ describe('parcoords edge cases', function() { .then(done); }); - it('@noCI @gl Works with 60 dimensions', function(done) { + it('@gl Works with 60 dimensions', function(done) { var mockCopy = Lib.extendDeep({}, mock1); var newDimension, i, j; @@ -516,7 +516,7 @@ describe('parcoords edge cases', function() { .then(done); }); - it('@noCI @gl Truncates 60+ dimensions to 60', function(done) { + it('@gl Truncates 60+ dimensions to 60', function(done) { var mockCopy = Lib.extendDeep({}, mock1); var newDimension, i, j; @@ -542,7 +542,7 @@ describe('parcoords edge cases', function() { .then(done); }); - it('@noCI @gl Truncates dimension values to the shortest array, retaining only 3 lines', function(done) { + it('@gl Truncates dimension values to the shortest array, retaining only 3 lines', function(done) { var mockCopy = Lib.extendDeep({}, mock1); var newDimension, i, j; @@ -1156,7 +1156,7 @@ describe('parcoords basic use', function() { }); }); -describe('@noCI parcoords constraint interactions', function() { +describe('parcoords constraint interactions', function() { var gd, initialDashArray0, initialDashArray1; function initialFigure() { @@ -1240,7 +1240,7 @@ describe('@noCI parcoords constraint interactions', function() { expect(dashArray.length).toBe(segmentCount, dashArray); } - it('@gl snaps ordinal constraints', function(done) { + it('@noCI @gl snaps ordinal constraints', function(done) { // first: drag almost to 2 but not quite - constraint will snap back to [2.75, 4] mostOfDrag(105, 165, 105, 190); var newDashArray = getDashArray(0); @@ -1318,7 +1318,7 @@ describe('@noCI parcoords constraint interactions', function() { .then(done); }); - it('@gl updates continuous constraints with no snap', function(done) { + it('@noCI @gl updates continuous constraints with no snap', function(done) { // first: extend 7 to 5 mostOfDrag(295, 160, 295, 200); var newDashArray = getDashArray(1); diff --git a/test/jasmine/tests/plot_api_react_test.js b/test/jasmine/tests/plot_api_react_test.js index a1c864498e1..8399803ff9c 100644 --- a/test/jasmine/tests/plot_api_react_test.js +++ b/test/jasmine/tests/plot_api_react_test.js @@ -700,7 +700,7 @@ describe('@noCIdep Plotly.react', function() { .then(done); }); - it('can change parcoords aggregations', function(done) { + it('@gl can change parcoords aggregations', function(done) { Plotly.newPlot(gd, aggregatedParcoords(0)) .then(checkValues(aggParcoords0Vals)) @@ -717,7 +717,7 @@ describe('@noCIdep Plotly.react', function() { .then(done); }); - it('can change type with aggregations', function(done) { + it('@gl can change type with aggregations', function(done) { Plotly.newPlot(gd, aggregatedScatter(1)) .then(checkCalcData(aggScatter1CD)) @@ -1766,7 +1766,7 @@ describe('Plotly.react and uirevision attributes', function() { _run(fig, editEditable, checkAttrs(true), checkAttrs).then(done); }); - it('preserves editable: true name, colorbar title and parcoords constraint range via trace.uirevision', function(done) { + it('@gl preserves editable: true name, colorbar title and parcoords constraint range via trace.uirevision', function(done) { function fig(mainRev, traceRev) { return { data: [{ diff --git a/test/jasmine/tests/polar_test.js b/test/jasmine/tests/polar_test.js index 5e78ae92c12..1896ad949dd 100644 --- a/test/jasmine/tests/polar_test.js +++ b/test/jasmine/tests/polar_test.js @@ -899,16 +899,12 @@ describe('Test polar interactions:', function() { } function _reset() { - return delay(100)() - .then(function() { return _doubleClick(mid); }) - .then(function() { - relayoutNumber++; - resetNumber++; + relayoutNumber++; + resetNumber++; - var extra = '(reset ' + resetNumber + ')'; - _assertBase(extra); - expect(eventCnts.plotly_doubleclick).toBe(resetNumber, 'doubleclick event #' + extra); - }); + var extra = '(reset ' + resetNumber + ')'; + _assertBase(extra); + expect(eventCnts.plotly_doubleclick).toBe(resetNumber, 'doubleclick event #' + extra); } _plot(fig) @@ -917,21 +913,33 @@ describe('Test polar interactions:', function() { .then(function() { _assertDrag([0, 5.24], 'from center move toward bottom-right'); }) + .then(delay(20)) + .then(function() { return _doubleClick(mid); }) + .then(delay(20)) .then(_reset) .then(function() { return _drag(mid, [-50, -50]); }) .then(function() { _assertDrag([0, 5.24], 'from center move toward top-left'); }) + .then(delay(20)) + .then(function() { return _doubleClick(mid); }) + .then(delay(20)) .then(_reset) .then(function() { return _drag([mid[0] + 30, mid[0] - 30], [50, -50]); }) .then(function() { _assertDrag([3.1, 8.4], 'from quadrant #1 move top-right'); }) + .then(delay(20)) + .then(function() { return _doubleClick(mid); }) + .then(delay(20)) .then(_reset) .then(function() { return _drag([345, 200], [-50, 0]); }) .then(function() { _assertDrag([7.0, 11.1], 'from right edge move left'); }) + .then(delay(20)) + .then(function() { return _doubleClick(mid); }) + .then(delay(20)) .then(_reset) .then(function() { return _drag(mid, [10, 10]);}) .then(function() { _assertBase('from center to not far enough'); }) @@ -943,6 +951,9 @@ describe('Test polar interactions:', function() { expect(eventCnts.plotly_relayout) .toBe(relayoutNumber, 'no new relayout events after *not far enough* cases'); }) + .then(delay(20)) + .then(function() { return _doubleClick(mid); }) + .then(delay(20)) .then(_reset) .then(function() { return Plotly.relayout(gd, 'polar.hole', 0.2); }) .then(function() { relayoutNumber++; }) diff --git a/test/jasmine/tests/sankey_test.js b/test/jasmine/tests/sankey_test.js index 892eb950bf7..5780a72cdec 100644 --- a/test/jasmine/tests/sankey_test.js +++ b/test/jasmine/tests/sankey_test.js @@ -1034,16 +1034,24 @@ describe('sankey tests', function() { .then(done); }); - ['node', 'link'].forEach(function(obj) { - it('@flaky should not output hover/unhover event data when ' + obj + '.hoverinfo is skip', function(done) { - var fig = Lib.extendDeep({}, mock); + it('should not output hover/unhover event data when link.hoverinfo is skip', function(done) { + var fig = Lib.extendDeep({}, mock); - Plotly.plot(gd, fig) - .then(function() { return Plotly.restyle(gd, obj + '.hoverinfo', 'skip'); }) - .then(assertNoHoverEvents(obj)) - .catch(failTest) - .then(done); - }); + Plotly.plot(gd, fig) + .then(function() { return Plotly.restyle(gd, 'link.hoverinfo', 'skip'); }) + .then(assertNoHoverEvents('link')) + .catch(failTest) + .then(done); + }); + + it('should not output hover/unhover event data when node.hoverinfo is skip', function(done) { + var fig = Lib.extendDeep({}, mock); + + Plotly.plot(gd, fig) + .then(function() { return Plotly.restyle(gd, 'node.hoverinfo', 'skip'); }) + .then(assertNoHoverEvents('node')) + .catch(failTest) + .then(done); }); }); @@ -1109,7 +1117,7 @@ describe('sankey tests', function() { .then(done); }); - it('should persist the position of every nodes after drag in attributes nodes.(x|y)', function(done) { + it('@noCI should persist the position of every nodes after drag in attributes nodes.(x|y)', function(done) { mockCopy.data[0].arrangement = arrangement; var move = [50, -50]; var nodes; diff --git a/test/jasmine/tests/select_test.js b/test/jasmine/tests/select_test.js index d3c1bd2e15f..3b4977b252b 100644 --- a/test/jasmine/tests/select_test.js +++ b/test/jasmine/tests/select_test.js @@ -658,7 +658,7 @@ describe('Click-to-select', function() { { mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN }) ] .forEach(function(testCase) { - it('@noCI @gl trace type ' + testCase.label, function(done) { + it('@gl trace type ' + testCase.label, function(done) { _run(testCase, done); }); }); diff --git a/test/jasmine/tests/splom_test.js b/test/jasmine/tests/splom_test.js index 4df71226d61..20535070488 100644 --- a/test/jasmine/tests/splom_test.js +++ b/test/jasmine/tests/splom_test.js @@ -943,7 +943,7 @@ describe('Test splom interactions:', function() { .then(done); }); - it('@noCI @gl should clear graph and replot when canvas and WebGL context dimensions do not match', function(done) { + it('@gl should clear graph and replot when canvas and WebGL context dimensions do not match', function(done) { var fig = Lib.extendDeep({}, require('@mocks/splom_iris.json')); function assertDims(msg, w, h) { @@ -1737,7 +1737,7 @@ describe('Test splom select:', function() { .then(done); }); - it('@noCI @gl should behave correctly during select->dblclick->pan scenarios', function(done) { + it('@gl should behave correctly during select->dblclick->pan scenarios', function(done) { var fig = Lib.extendDeep({}, require('@mocks/splom_0.json')); fig.layout = { width: 400,