blob: 1fe6f6f8c9dca5450cf308b4431b0c756036ecce [file] [log] [blame]
<!doctype html>
<!--
@license
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>
<meta charset="UTF-8">
<title>paper-tooltip tests</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
<script src="../../web-component-tester/browser.js"></script>
<script src="../../test-fixture/test-fixture-mocha.js"></script>
<script src="../../iron-test-helpers/mock-interactions.js"></script>
<link rel="import" href="../../test-fixture/test-fixture.html">
<link rel="import" href="../paper-tooltip.html">
<link rel="import" href="test-button.html">
</head>
<style>
body {
margin: 0;
padding: 0;
}
#target {
width: 100px;
height: 20px;
background-color: red;
}
paper-tooltip {
width: 70px;
height: 30px;
}
.wide {
width: 200px;
}
[hidden] {
display: none;
}
</style>
<body>
<test-fixture id="basic">
<template>
<div>
<div id="target"></div>
<paper-tooltip for="target" animation-delay="0">Tooltip text</paper-tooltip>
</div>
</template>
</test-fixture>
<test-fixture id="fitted">
<template>
<div>
<div id="target" style="position:absolute"></div>
<paper-tooltip for="target" class="wide" fit-to-visible-bounds>Tooltip text</paper-tooltip>
</div>
</template>
</test-fixture>
<test-fixture id="no-text">
<template>
<div>
<div id="target"></div>
<paper-tooltip for="target"></paper-tooltip>
</div>
</template>
</test-fixture>
<test-fixture id="dynamic">
<template>
<div>
<div id="target"></div>
<paper-tooltip>Tooltip text</paper-tooltip>
</div>
</template>
</test-fixture>
<test-fixture id="custom">
<template>
<test-button></test-button>
</template>
</test-fixture>
<test-fixture id="no-offset-parent">
<template>
<div>
<div id="target"></div>
<paper-tooltip for="target" animation-delay="0" hidden></paper-tooltip>
</div>
</template>
</test-fixture>
<script>
function isHidden(element) {
var rect = element.getBoundingClientRect();
return (rect.width == 0 && rect.height == 0);
}
suite('basic', function() {
test('tooltip is shown when target is focused', function() {
var f = fixture('no-text');
var target = f.querySelector('#target');
var tooltip = f.querySelector('paper-tooltip');
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));
MockInteractions.focus(target);
assert.isTrue(isHidden(actualTooltip));
});
test('tooltip is not shown if empty', function() {
var f = fixture('basic');
var target = f.querySelector('#target');
var tooltip = f.querySelector('paper-tooltip');
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));
MockInteractions.focus(target);
assert.isFalse(isHidden(actualTooltip));
});
test('tooltip doesn\'t throw an exception if it has no offsetParent', function() {
var f = fixture('no-offset-parent');
var target = f.querySelector('#target');
var tooltip = f.querySelector('paper-tooltip');
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));
tooltip.updatePosition();
tooltip.show();
// Doesn't get shown since there's no position computed.
assert.isTrue(isHidden(actualTooltip));
});
test('tooltip is positioned correctly (bottom)', function() {
var f = fixture('basic');
var target = f.querySelector('#target');
var tooltip = f.querySelector('paper-tooltip');
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));
MockInteractions.focus(target);
assert.isFalse(isHidden(actualTooltip));
var divRect = target.getBoundingClientRect();
expect(divRect.width).to.be.equal(100);
expect(divRect.height).to.be.equal(20);
var contentRect = tooltip.getBoundingClientRect();
expect(contentRect.width).to.be.equal(70);
expect(contentRect.height).to.be.equal(30);
// The target div width is 100, and the tooltip width is 70, and
// it's centered. The height of the target div is 20, and the
// tooltip is 14px below.
expect(contentRect.left).to.be.equal((100 - 70)/2);
expect(contentRect.top).to.be.equal(20 + 14);
// Also check the math, just in case.
expect(contentRect.left).to.be.equal((divRect.width - contentRect.width)/2);
expect(contentRect.top).to.be.equal(divRect.height + tooltip.offset);
});
test('tooltip is positioned correctly (top)', function() {
var f = fixture('basic');
var target = f.querySelector('#target');
var tooltip = f.querySelector('paper-tooltip');
tooltip.position = 'top';
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));
MockInteractions.focus(target);
assert.isFalse(isHidden(actualTooltip));
var divRect = target.getBoundingClientRect();
expect(divRect.width).to.be.equal(100);
expect(divRect.height).to.be.equal(20);
var contentRect = tooltip.getBoundingClientRect();
expect(contentRect.width).to.be.equal(70);
expect(contentRect.height).to.be.equal(30);
// The target div width is 100, and the tooltip width is 70, and
// it's centered. The height of the tooltip is 30, and the
// tooltip is 14px above the target.
expect(contentRect.left).to.be.equal((100 - 70)/2);
expect(contentRect.top).to.be.equal(0 - 30 - 14);
// Also check the math, just in case.
expect(contentRect.left).to.be.equal((divRect.width - contentRect.width)/2);
expect(contentRect.top).to.be.equal(0 - contentRect.height - tooltip.offset);
});
test('tooltip is positioned correctly (right)', function() {
var f = fixture('basic');
var target = f.querySelector('#target');
var tooltip = f.querySelector('paper-tooltip');
tooltip.position = 'right';
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));
MockInteractions.focus(target);
assert.isFalse(isHidden(actualTooltip));
var divRect = target.getBoundingClientRect();
expect(divRect.width).to.be.equal(100);
expect(divRect.height).to.be.equal(20);
var contentRect = tooltip.getBoundingClientRect();
expect(contentRect.width).to.be.equal(70);
expect(contentRect.height).to.be.equal(30);
// The target div width is 100, and the tooltip is 14px to the right.
// The target div height is 20, the height of the tooltip is 20px, and
// the tooltip is centered.
expect(contentRect.left).to.be.equal(100 + 14);
expect(contentRect.top).to.be.equal((20 - 30)/2);
// Also check the math, just in case.
expect(contentRect.left).to.be.equal(divRect.width + tooltip.offset);
expect(contentRect.top).to.be.equal((divRect.height - contentRect.height)/2);
});
test('tooltip is positioned correctly (left)', function() {
var f = fixture('basic');
var target = f.querySelector('#target');
var tooltip = f.querySelector('paper-tooltip');
tooltip.position = 'left';
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));
MockInteractions.focus(target);
assert.isFalse(isHidden(actualTooltip));
var divRect = target.getBoundingClientRect();
expect(divRect.width).to.be.equal(100);
expect(divRect.height).to.be.equal(20);
var contentRect = tooltip.getBoundingClientRect();
expect(contentRect.width).to.be.equal(70);
expect(contentRect.height).to.be.equal(30);
// The tooltip width is 70px, and the tooltip is 14px to the left of the target.
// The target div height is 20, the height of the tooltip is 20px, and
// the tooltip is centered.
expect(contentRect.left).to.be.equal(0 - 70 - 14);
expect(contentRect.top).to.be.equal((20 - 30)/2);
// Also check the math, just in case.
expect(contentRect.left).to.be.equal(0 - contentRect.width - tooltip.offset);
expect(contentRect.top).to.be.equal((divRect.height - contentRect.height)/2);
});
test('tooltip is fitted correctly if out of bounds', function() {
var f = fixture('fitted');
var target = f.querySelector('#target');
var tooltip = f.querySelector('paper-tooltip');
target.style.top = 0;
target.style.left = 0;
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));
MockInteractions.focus(target);
assert.isFalse(isHidden(actualTooltip));
var contentRect = tooltip.getBoundingClientRect();
var divRect = target.getBoundingClientRect();
// Should be fitted on the left side.
expect(contentRect.left).to.be.equal(0);
expect(contentRect.top).to.be.equal(divRect.height + tooltip.offset);
});
test('tooltip is positioned correctly after being dynamically set', function() {
var f = fixture('dynamic');
var target = f.querySelector('#target');
var tooltip = f.querySelector('paper-tooltip');
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));
// Skip animations in this test, which means we'll show and hide
// the tooltip manually, instead of calling focus and blur.
// The tooltip is shown because it's a sibling of the target,
// but it's positioned incorrectly
tooltip.toggleClass('hidden', false, actualTooltip);
assert.isFalse(isHidden(actualTooltip));
var contentRect = tooltip.getBoundingClientRect();
expect(contentRect.left).to.not.be.equal((100 - 70)/2);
tooltip.for = 'target';
// The tooltip needs to hide before it gets repositioned.
tooltip.toggleClass('hidden', true, actualTooltip);
tooltip.updatePosition();
tooltip.toggleClass('hidden', false, actualTooltip);
assert.isFalse(isHidden(actualTooltip));
// The target div width is 100, and the tooltip width is 70, and
// it's centered. The height of the target div is 20, and the
// tooltip is 14px below.
contentRect = tooltip.getBoundingClientRect();
expect(contentRect.left).to.be.equal((100 - 70)/2);
expect(contentRect.top).to.be.equal(20 + 14);
});
test('tooltip is hidden after target is blurred', function(done) {
var f = fixture('basic');
var target = f.querySelector('#target');
var tooltip = f.querySelector('paper-tooltip');
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));
// Simulate but don't actually run the entry animation.
tooltip.toggleClass('hidden', false, actualTooltip);
tooltip._showing = true;
assert.isFalse(isHidden(actualTooltip));
tooltip.addEventListener('neon-animation-finish', function() {
assert.isTrue(isHidden(actualTooltip));
done();
});
MockInteractions.blur(target);
});
test('tooltip unlistens to target on detach', function(done) {
var f = fixture('basic');
var target = f.querySelector('#target');
var tooltip = f.querySelector('paper-tooltip');
sinon.spy(tooltip, 'show');
MockInteractions.focus(target);
expect(tooltip.show.callCount).to.be.equal(1);
MockInteractions.focus(target);
expect(tooltip.show.callCount).to.be.equal(2);
f.removeChild(tooltip);
setTimeout(function() {
// No more listener means no more calling show.
MockInteractions.focus(target);
expect(tooltip.show.callCount).to.be.equal(2);
done();
}, 200);
});
});
suite('tooltip is inside a custom element', function() {
var f, tooltip, target;
setup(function() {
f = fixture('custom');
target = f.$.button;
tooltip = f.$.buttonTooltip;
});
test('tooltip is shown when target is focused', function() {
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));
MockInteractions.focus(target);
assert.isFalse(isHidden(actualTooltip));
});
test('tooltip is positioned correctly', function() {
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
assert.isTrue(isHidden(actualTooltip));
MockInteractions.focus(target);
assert.isFalse(isHidden(actualTooltip));
var divRect = target.getBoundingClientRect();
expect(divRect.width).to.be.equal(100);
expect(divRect.height).to.be.equal(20);
var contentRect = tooltip.getBoundingClientRect();
expect(contentRect.width).to.be.equal(70);
expect(contentRect.height).to.be.equal(30);
// The target div width is 100, and the tooltip width is 70, and
// it's centered. The height of the target div is 20, and the
// tooltip is 14px below.
expect(contentRect.left).to.be.equal((100 - 70)/2);
expect(contentRect.top).to.be.equal(20 + 14);
// Also check the math, just in case.
expect(contentRect.left).to.be.equal((divRect.width - contentRect.width)/2);
expect(contentRect.top).to.be.equal(divRect.height + tooltip.offset);
});
});
suite('a11y', function() {
test('has aria role "tooltip"', function() {
var f = fixture('basic');
var tooltip = f.querySelector('paper-tooltip');
assert.isTrue(tooltip.getAttribute('role') == 'tooltip');
});
var ignoredRules = ['roleTooltipRequiresDescribedby'];
a11ySuite('basic', ignoredRules);
a11ySuite('fitted', ignoredRules);
a11ySuite('no-text', ignoredRules);
a11ySuite('dynamic', ignoredRules);
a11ySuite('custom', ignoredRules);
});
</script>
</body>
</html>