mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Improve the explain plan details by showing popup instead of tooltip on clicking of the specified node. Fixes #5488
This commit is contained in:
committed by
Akshay Joshi
parent
3f089f31a3
commit
6589f82e77
Binary file not shown.
|
Before Width: | Height: | Size: 175 KiB After Width: | Height: | Size: 209 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 190 KiB |
@@ -186,11 +186,11 @@ under the Explain panel.
|
|||||||
|
|
||||||
* Graphical
|
* Graphical
|
||||||
|
|
||||||
Please note that *EXPLAIN VERBOSE* cannot be displayed graphically. Hover over
|
Please note that *EXPLAIN VERBOSE* cannot be displayed graphically. Click on
|
||||||
an icon on the *Graphical* tab to review information about that item; a popup
|
a node icon on the *Graphical* tab to review information about that item; a popup
|
||||||
window will display information about the selected object. For information on
|
window will display on the right side with the information about the selected
|
||||||
JIT statistics, triggers and a summary, hover over the icon on top-right
|
object. For information on JIT statistics, triggers and a summary, click on the
|
||||||
corner; a similar popup window will be displayed when appropriate.
|
button on top-right corner; a similar popup window will be displayed when appropriate.
|
||||||
|
|
||||||
Use the download button on top left corner of the *Explain* canvas to download
|
Use the download button on top left corner of the *Explain* canvas to download
|
||||||
the plan as an SVG file.
|
the plan as an SVG file.
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ Bug fixes
|
|||||||
|
|
||||||
| `Issue #4892 <https://redmine.postgresql.org/issues/4892>`_ - Fixed an issue where pressing the back button will show another instance of the main page inside of the Query Tool tab.
|
| `Issue #4892 <https://redmine.postgresql.org/issues/4892>`_ - Fixed an issue where pressing the back button will show another instance of the main page inside of the Query Tool tab.
|
||||||
| `Issue #5282 <https://redmine.postgresql.org/issues/5282>`_ - Added 'Count Rows' option to the partition sub tables.
|
| `Issue #5282 <https://redmine.postgresql.org/issues/5282>`_ - Added 'Count Rows' option to the partition sub tables.
|
||||||
|
| `Issue #5488 <https://redmine.postgresql.org/issues/5488>`_ - Improve the explain plan details by showing popup instead of tooltip on clicking of the specified node.
|
||||||
| `Issue #5571 <https://redmine.postgresql.org/issues/5571>`_ - Added support for expression in exclusion constraints.
|
| `Issue #5571 <https://redmine.postgresql.org/issues/5571>`_ - Added support for expression in exclusion constraints.
|
||||||
| `Issue #5875 <https://redmine.postgresql.org/issues/5875>`_ - Ensure that the 'template1' database should not be visible after pg_upgrade.
|
| `Issue #5875 <https://redmine.postgresql.org/issues/5875>`_ - Ensure that the 'template1' database should not be visible after pg_upgrade.
|
||||||
| `Issue #5965 <https://redmine.postgresql.org/issues/5965>`_ - Ensure that the macro query result should be download properly.
|
| `Issue #5965 <https://redmine.postgresql.org/issues/5965>`_ - Ensure that the macro query result should be download properly.
|
||||||
|
|||||||
@@ -753,6 +753,12 @@ define('pgadmin.misc.explain', [
|
|||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getLabel: function() {
|
||||||
|
return this.get('Schema') == undefined ?
|
||||||
|
this.get('image_text') :
|
||||||
|
(this.get('Schema') + '.' + this.get('image_text'));
|
||||||
|
},
|
||||||
|
|
||||||
// Draw image, its name and its tooltip
|
// Draw image, its name and its tooltip
|
||||||
draw: function(
|
draw: function(
|
||||||
s, xpos, ypos, pXpos, pYpos, graphContainer, toolTipContainer,
|
s, xpos, ypos, pXpos, pYpos, graphContainer, toolTipContainer,
|
||||||
@@ -802,9 +808,7 @@ define('pgadmin.misc.explain', [
|
|||||||
|
|
||||||
|
|
||||||
// Draw text below the node
|
// Draw text below the node
|
||||||
var node_label = this.get('Schema') == undefined ?
|
var node_label = this.getLabel();
|
||||||
this.get('image_text') :
|
|
||||||
(this.get('Schema') + '.' + this.get('image_text'));
|
|
||||||
g.multitext(
|
g.multitext(
|
||||||
currentXpos + (pWIDTH / 2) + TXT_ALIGN,
|
currentXpos + (pWIDTH / 2) + TXT_ALIGN,
|
||||||
currentYpos + pHEIGHT - TXT_ALIGN,
|
currentYpos + pHEIGHT - TXT_ALIGN,
|
||||||
@@ -943,34 +947,29 @@ define('pgadmin.misc.explain', [
|
|||||||
IMAGE_WIDTH,
|
IMAGE_WIDTH,
|
||||||
IMAGE_HEIGHT
|
IMAGE_HEIGHT
|
||||||
);
|
);
|
||||||
|
image.attr({style: 'cursor: pointer'});
|
||||||
|
|
||||||
// Draw tooltip
|
// Draw tooltip
|
||||||
var image_data = this.toJSON();
|
var image_data = this.toJSON(),
|
||||||
var title = '<title>';
|
nodeLabel = this.getLabel();
|
||||||
_.each(image_data, function(value, key) {
|
image.click(() => {
|
||||||
if (key !== 'image' && key !== 'Plans' &&
|
|
||||||
key !== 'level' && key !== 'image' &&
|
|
||||||
key !== 'image_text' && key !== 'xpos' &&
|
|
||||||
key !== 'ypos' && key !== 'width' &&
|
|
||||||
key !== 'height') {
|
|
||||||
title += `${key}: ${value}\n`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
title += '</title>';
|
|
||||||
|
|
||||||
image.append(Snap.parse(title));
|
|
||||||
|
|
||||||
image.mouseover(() => {
|
|
||||||
// Empty the tooltip content if it has any and add new data
|
// Empty the tooltip content if it has any and add new data
|
||||||
toolTipContainer.empty();
|
let toolTipBody = toolTipContainer.find('.details-body');
|
||||||
|
let toolTipTitle = toolTipContainer.find('.details-title');
|
||||||
|
toolTipTitle.text(nodeLabel);
|
||||||
|
|
||||||
|
toolTipBody.empty();
|
||||||
|
|
||||||
// Remove the title content so that we can show our custom build tooltips.
|
// Remove the title content so that we can show our custom build tooltips.
|
||||||
image.node.textContent = '';
|
image.node.textContent = '';
|
||||||
|
|
||||||
var tooltip = $('<table></table>', {
|
var tooltipTable = $(`
|
||||||
class: 'pgadmin-tooltip-table',
|
<table class='pgadmin-tooltip-table table table-bordered table-noouter-border table-bottom-border table-hover'>
|
||||||
}).appendTo(toolTipContainer);
|
<tbody></tbody>
|
||||||
|
</table>`
|
||||||
|
).appendTo(toolTipBody);
|
||||||
|
var tooltip = tooltipTable.find('tbody');
|
||||||
|
|
||||||
_.each(image_data, function(value, key) {
|
_.each(image_data, function(value, key) {
|
||||||
if (key !== 'image' && key !== 'Plans' &&
|
if (key !== 'image' && key !== 'Plans' &&
|
||||||
key !== 'level' && key !== 'image' &&
|
key !== 'level' && key !== 'image' &&
|
||||||
@@ -987,42 +986,8 @@ define('pgadmin.misc.explain', [
|
|||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
toolTipContainer.removeClass('d-none');
|
||||||
var zoomFactor = graphContainer.data('zoom-factor');
|
toolTipBody.scrollTop(0);
|
||||||
|
|
||||||
// Calculate co-ordinates for tooltip
|
|
||||||
var toolTipX = ((currentXpos + pWIDTH) * zoomFactor - graphContainer.scrollLeft());
|
|
||||||
var toolTipY = ((currentYpos) * zoomFactor - graphContainer.scrollTop());
|
|
||||||
|
|
||||||
toolTipX = toolTipX < 0 ? 0 : (toolTipX);
|
|
||||||
toolTipY = toolTipY < 0 ? 0 : (toolTipY);
|
|
||||||
|
|
||||||
toolTipX = toolTipX > graphContainer.width() - toolTipContainer[0].clientWidth ? toolTipX - (toolTipContainer[0].clientWidth+(pWIDTH* zoomFactor)) : toolTipX;
|
|
||||||
toolTipY = toolTipY > graphContainer.height() - toolTipContainer[0].clientHeight ? graphContainer.height() - toolTipContainer[0].clientHeight : toolTipY;
|
|
||||||
|
|
||||||
// Show toolTip at respective x,y coordinates
|
|
||||||
toolTipContainer.css({
|
|
||||||
'opacity': '0.8',
|
|
||||||
});
|
|
||||||
toolTipContainer.css('left', toolTipX);
|
|
||||||
toolTipContainer.css('top', toolTipY);
|
|
||||||
|
|
||||||
$('.pgadmin-explain-tooltip').css('padding', '5px');
|
|
||||||
$('.pgadmin-explain-tooltip').css('border', '1px solid white');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove tooltip when mouse is out from node's area
|
|
||||||
image.mouseout(() => {
|
|
||||||
/* Append the title again which we have removed on mouse over event, so
|
|
||||||
* that our custom tooltip should be visible.
|
|
||||||
*/
|
|
||||||
image.append(Snap.parse(title));
|
|
||||||
toolTipContainer.empty();
|
|
||||||
toolTipContainer.css({
|
|
||||||
'opacity': '0',
|
|
||||||
});
|
|
||||||
toolTipContainer.css('left', 0);
|
|
||||||
toolTipContainer.css('top', 0);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -1363,15 +1328,22 @@ define('pgadmin.misc.explain', [
|
|||||||
// Main div to be drawn all images on
|
// Main div to be drawn all images on
|
||||||
var planDiv = $('<div></div>', {
|
var planDiv = $('<div></div>', {
|
||||||
class: 'pgadmin-explain-container w-100 h-100 overflow-auto',
|
class: 'pgadmin-explain-container w-100 h-100 overflow-auto',
|
||||||
}).appendTo(graphicalContainer),
|
|
||||||
// Div to draw tool-tip on
|
|
||||||
toolTip = $('<div></div>', {
|
|
||||||
id: 'toolTip',
|
|
||||||
class: 'pgadmin-explain-tooltip',
|
|
||||||
}).appendTo(graphicalContainer);
|
}).appendTo(graphicalContainer);
|
||||||
toolTip.empty();
|
|
||||||
planDiv.data('zoom-factor', curr_zoom_factor);
|
planDiv.data('zoom-factor', curr_zoom_factor);
|
||||||
|
|
||||||
|
var explainDetails = $(
|
||||||
|
`<div class="pgadmin-explain-details card d-none" data-bs-backdrop="false" tabindex="-1" aria-hidden="true">
|
||||||
|
<div class="card-header details-header d-flex">
|
||||||
|
<div class="details-title my-auto"></div>
|
||||||
|
<div class="ml-auto"><button class="btn btn-sm fa fa-times ml-auto details-close"/></div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body details-body"></div>
|
||||||
|
</div>`
|
||||||
|
).appendTo(graphicalContainer);
|
||||||
|
explainDetails.find('.details-close').on('click', ()=>{
|
||||||
|
explainDetails.addClass('d-none');
|
||||||
|
});
|
||||||
|
|
||||||
var w = 0,
|
var w = 0,
|
||||||
h = yMargin;
|
h = yMargin;
|
||||||
|
|
||||||
@@ -1420,7 +1392,7 @@ define('pgadmin.misc.explain', [
|
|||||||
var s = Snap(w, h),
|
var s = Snap(w, h),
|
||||||
$svg = $(s.node).detach();
|
$svg = $(s.node).detach();
|
||||||
planDiv.append($svg);
|
planDiv.append($svg);
|
||||||
main_plan.draw(s, w - xMargin, yMargin, planDiv, toolTip, ctx);
|
main_plan.draw(s, w - xMargin, yMargin, planDiv, explainDetails, ctx);
|
||||||
|
|
||||||
var initPanelWidth = planDiv.width();
|
var initPanelWidth = planDiv.width();
|
||||||
|
|
||||||
|
|||||||
@@ -30,12 +30,15 @@ let StatisticsModel = Backbone.Model.extend({
|
|||||||
$('.pg-explain-stats-area').removeClass('d-none');
|
$('.pg-explain-stats-area').removeClass('d-none');
|
||||||
}
|
}
|
||||||
|
|
||||||
var tooltip = $('<table></table>', {
|
var tooltipTable = $(`
|
||||||
class: 'pgadmin-tooltip-table',
|
<table class='pgadmin-tooltip-table table table-bordered table-noouter-border table-bottom-border table-hover'>
|
||||||
});
|
<tbody></tbody>
|
||||||
|
</table>`
|
||||||
|
);
|
||||||
|
var tooltip = tooltipTable.find('tbody');
|
||||||
|
|
||||||
if (Object.keys(jit_stats).length > 0){
|
if (Object.keys(jit_stats).length > 0){
|
||||||
tooltip.append('<tr><td class="label explain-tooltip">' + gettext('JIT:') + '</td></tr>');
|
tooltip.append('<tr><td colspan="2" class="label explain-tooltip">' + gettext('JIT:') + '</td></tr>');
|
||||||
_.each(jit_stats, function(value, key) {
|
_.each(jit_stats, function(value, key) {
|
||||||
key = _.escape(key);
|
key = _.escape(key);
|
||||||
value = _.escape(value);
|
value = _.escape(value);
|
||||||
@@ -49,7 +52,7 @@ let StatisticsModel = Backbone.Model.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(triggers_stats).length > 0){
|
if (Object.keys(triggers_stats).length > 0){
|
||||||
tooltip.append('<tr><td class="label explain-tooltip">' + gettext('Triggers:') + '</td></tr>');
|
tooltip.append('<tr><td colspan="2" class="label explain-tooltip">' + gettext('Triggers:') + '</td></tr>');
|
||||||
_.each(triggers_stats, function(triggers, key_id) {
|
_.each(triggers_stats, function(triggers, key_id) {
|
||||||
if (triggers instanceof Object) {
|
if (triggers instanceof Object) {
|
||||||
_.each(triggers, function(value, key) {
|
_.each(triggers, function(value, key) {
|
||||||
@@ -88,7 +91,7 @@ let StatisticsModel = Backbone.Model.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Object.keys(summary).length > 0){
|
if (Object.keys(summary).length > 0){
|
||||||
tooltip.append('<tr><td class="label explain-tooltip">' + gettext('Summary:') + '</td></tr>');
|
tooltip.append('<tr><td colspan="2" class="label explain-tooltip">' + gettext('Summary:') + '</td></tr>');
|
||||||
_.each(summary, function(value, key) {
|
_.each(summary, function(value, key) {
|
||||||
key = _.escape(key);
|
key = _.escape(key);
|
||||||
value = _.escape(value);
|
value = _.escape(value);
|
||||||
@@ -101,7 +104,7 @@ let StatisticsModel = Backbone.Model.extend({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.pg-explain-stats-area').off('mouseover').on('mouseover', () => {
|
$('.pg-explain-stats-area').off('click').on('click', () => {
|
||||||
// Empty the tooltip content if it has any and add new data
|
// Empty the tooltip content if it has any and add new data
|
||||||
|
|
||||||
if (Object.keys(jit_stats).length == 0 &&
|
if (Object.keys(jit_stats).length == 0 &&
|
||||||
@@ -110,30 +113,15 @@ let StatisticsModel = Backbone.Model.extend({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
toolTipContainer.empty();
|
let toolTipBody = toolTipContainer.find('.details-body');
|
||||||
toolTipContainer.append(tooltip);
|
let toolTipTitle = toolTipContainer.find('.details-title');
|
||||||
|
toolTipTitle.text('Statistics');
|
||||||
|
|
||||||
// Show toolTip at respective x,y coordinates
|
toolTipBody.empty();
|
||||||
toolTipContainer.css({
|
toolTipBody.append(tooltipTable);
|
||||||
'opacity': '0.8',
|
|
||||||
'left': '',
|
|
||||||
'right': '65px',
|
|
||||||
'top': '15px',
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.pgadmin-explain-tooltip').css('padding', '5px');
|
toolTipContainer.removeClass('d-none');
|
||||||
$('.pgadmin-explain-tooltip').css('border', '1px solid white');
|
toolTipBody.scrollTop(0);
|
||||||
});
|
|
||||||
|
|
||||||
// Remove tooltip when mouse is out from node's area
|
|
||||||
$('.pg-explain-stats-area').off('mouseout').on('mouseout', () => {
|
|
||||||
toolTipContainer.empty();
|
|
||||||
toolTipContainer.css({
|
|
||||||
'opacity': '0',
|
|
||||||
'left': 0,
|
|
||||||
'top': 0,
|
|
||||||
'right': '',
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,12 +1,29 @@
|
|||||||
.pgadmin-explain-tooltip {
|
.pgadmin-explain-details {
|
||||||
|
min-width: 200px;
|
||||||
|
max-width: 300px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
opacity: 0;
|
top: 0.25rem;
|
||||||
color: $popover-body-color;
|
bottom: 0.25rem;
|
||||||
background-color: $popover-bg;
|
right: 0.25rem;
|
||||||
border-color: $popover-border-color;
|
border-color: $popover-border-color;
|
||||||
box-shadow: $popover-box-shadow;
|
box-shadow: $popover-box-shadow;
|
||||||
|
word-break: break-all;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
z-index: 99;
|
||||||
|
|
||||||
|
.details-header {
|
||||||
|
padding: 0.25rem;
|
||||||
|
font-weight: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.details-body {
|
||||||
|
overflow: auto;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.sql-editor-explain {
|
.sql-editor-explain {
|
||||||
.backform-tab {
|
.backform-tab {
|
||||||
.tab-content {
|
.tab-content {
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ legend {
|
|||||||
|
|
||||||
.table {
|
.table {
|
||||||
margin-bottom: 0rem;
|
margin-bottom: 0rem;
|
||||||
|
user-select: text;
|
||||||
th {
|
th {
|
||||||
padding: $table-header-cell-padding $table-cell-padding;
|
padding: $table-header-cell-padding $table-cell-padding;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,14 @@ describe('ExplainStatistics', () => {
|
|||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
statsModel = new StatisticsModel();
|
statsModel = new StatisticsModel();
|
||||||
statsDiv = '<div class="pg-explain-stats-area btn-group d-none"></div>';
|
statsDiv = '<div class="pg-explain-stats-area btn-group d-none"></div>';
|
||||||
tooltipContainer = $('<div></div>', {
|
tooltipContainer = $(
|
||||||
id: 'toolTip',
|
`<div class="pgadmin-explain-details d-none">
|
||||||
class: 'pgadmin-explain-tooltip',
|
<div class="details-header">
|
||||||
});
|
<div class="details-title"></div>
|
||||||
|
</div>
|
||||||
|
<div class="details-body"></div>
|
||||||
|
</div>`
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('No Statistics', () => {
|
describe('No Statistics', () => {
|
||||||
@@ -49,20 +53,12 @@ describe('ExplainStatistics', () => {
|
|||||||
expect($('.pg-explain-stats-area').hasClass('d-none')).toEqual(false);
|
expect($('.pg-explain-stats-area').hasClass('d-none')).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Mouse over event should be trigger', () => {
|
it('Mouse click event should be trigger', () => {
|
||||||
// Trigger mouse over event
|
// Trigger mouse over event
|
||||||
var hoverEvent = new $.Event('mouseover');
|
var clickEvent = new $.Event('click');
|
||||||
$('.pg-explain-stats-area').trigger(hoverEvent);
|
$('.pg-explain-stats-area').trigger(clickEvent);
|
||||||
|
|
||||||
expect(tooltipContainer.css('opacity')).toEqual('0.8');
|
expect(tooltipContainer.hasClass('d-none')).toBe(false);
|
||||||
});
|
|
||||||
|
|
||||||
it('Mouse out event should be trigger', () => {
|
|
||||||
// Trigger mouse out event
|
|
||||||
var hoverEvent = new $.Event('mouseout');
|
|
||||||
$('.pg-explain-stats-area').trigger(hoverEvent);
|
|
||||||
|
|
||||||
expect(tooltipContainer.css('opacity')).toEqual('0');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -78,20 +74,12 @@ describe('ExplainStatistics', () => {
|
|||||||
expect($('.pg-explain-stats-area').hasClass('d-none')).toEqual(false);
|
expect($('.pg-explain-stats-area').hasClass('d-none')).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Mouse over event should be trigger', () => {
|
it('Mouse click event should be trigger', () => {
|
||||||
// Trigger mouse over event
|
// Trigger mouse over event
|
||||||
var hoverEvent = new $.Event('mouseover');
|
var clickEvent = new $.Event('click');
|
||||||
$('.pg-explain-stats-area').trigger(hoverEvent);
|
$('.pg-explain-stats-area').trigger(clickEvent);
|
||||||
|
|
||||||
expect(tooltipContainer.css('opacity')).toEqual('0.8');
|
expect(tooltipContainer.hasClass('d-none')).toBe(false);
|
||||||
});
|
|
||||||
|
|
||||||
it('Mouse out event should be trigger', () => {
|
|
||||||
// Trigger mouse out event
|
|
||||||
var hoverEvent = new $.Event('mouseout');
|
|
||||||
$('.pg-explain-stats-area').trigger(hoverEvent);
|
|
||||||
|
|
||||||
expect(tooltipContainer.css('opacity')).toEqual('0');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -111,20 +99,12 @@ describe('ExplainStatistics', () => {
|
|||||||
expect($('.pg-explain-stats-area').hasClass('d-none')).toEqual(false);
|
expect($('.pg-explain-stats-area').hasClass('d-none')).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Mouse over event should be trigger', () => {
|
it('Mouse click event should be trigger', () => {
|
||||||
// Trigger mouse over event
|
// Trigger mouse over event
|
||||||
var hoverEvent = new $.Event('mouseover');
|
var clickEvent = new $.Event('click');
|
||||||
$('.pg-explain-stats-area').trigger(hoverEvent);
|
$('.pg-explain-stats-area').trigger(clickEvent);
|
||||||
|
|
||||||
expect(tooltipContainer.css('opacity')).toEqual('0.8');
|
expect(tooltipContainer.hasClass('d-none')).toBe(false);
|
||||||
});
|
|
||||||
|
|
||||||
it('Mouse out event should be trigger', () => {
|
|
||||||
// Trigger mouse out event
|
|
||||||
var hoverEvent = new $.Event('mouseout');
|
|
||||||
$('.pg-explain-stats-area').trigger(hoverEvent);
|
|
||||||
|
|
||||||
expect(tooltipContainer.css('opacity')).toEqual('0');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user