4
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
5
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
6
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
7
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
8
Code distributed by Google as part of the polymer project is also
9
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
13
<meta charset="UTF-8">
14
<title>paper-tooltip tests</title>
15
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
17
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
18
<script src="../../web-component-tester/browser.js"></script>
19
<script src="../../test-fixture/test-fixture-mocha.js"></script>
20
<script src="../../iron-test-helpers/mock-interactions.js"></script>
22
<link rel="import" href="../../test-fixture/test-fixture.html">
23
<link rel="import" href="../paper-tooltip.html">
24
<link rel="import" href="test-button.html">
35
background-color: red;
53
<test-fixture id="basic">
56
<div id="target"></div>
57
<paper-tooltip for="target" animation-delay="0">Tooltip text</paper-tooltip>
62
<test-fixture id="fitted">
65
<div id="target" style="position:absolute"></div>
66
<paper-tooltip for="target" class="wide" fit-to-visible-bounds>Tooltip text</paper-tooltip>
71
<test-fixture id="no-text">
74
<div id="target"></div>
75
<paper-tooltip for="target"></paper-tooltip>
80
<test-fixture id="dynamic">
83
<div id="target"></div>
84
<paper-tooltip>Tooltip text</paper-tooltip>
89
<test-fixture id="custom">
91
<test-button></test-button>
95
<test-fixture id="no-offset-parent">
98
<div id="target"></div>
99
<paper-tooltip for="target" animation-delay="0" hidden></paper-tooltip>
105
function isHidden(element) {
106
var rect = element.getBoundingClientRect();
107
return (rect.width == 0 && rect.height == 0);
110
suite('basic', function() {
111
test('tooltip is shown when target is focused', function() {
112
var f = fixture('no-text');
113
var target = f.querySelector('#target');
114
var tooltip = f.querySelector('paper-tooltip');
116
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
117
assert.isTrue(isHidden(actualTooltip));
119
MockInteractions.focus(target);
120
assert.isTrue(isHidden(actualTooltip));
123
test('tooltip is not shown if empty', function() {
124
var f = fixture('basic');
125
var target = f.querySelector('#target');
126
var tooltip = f.querySelector('paper-tooltip');
128
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
129
assert.isTrue(isHidden(actualTooltip));
131
MockInteractions.focus(target);
132
assert.isFalse(isHidden(actualTooltip));
135
test('tooltip doesn\'t throw an exception if it has no offsetParent', function() {
136
var f = fixture('no-offset-parent');
137
var target = f.querySelector('#target');
138
var tooltip = f.querySelector('paper-tooltip');
140
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
141
assert.isTrue(isHidden(actualTooltip));
142
tooltip.updatePosition();
145
// Doesn't get shown since there's no position computed.
146
assert.isTrue(isHidden(actualTooltip));
149
test('tooltip is positioned correctly (bottom)', function() {
150
var f = fixture('basic');
151
var target = f.querySelector('#target');
152
var tooltip = f.querySelector('paper-tooltip');
154
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
155
assert.isTrue(isHidden(actualTooltip));
157
MockInteractions.focus(target);
158
assert.isFalse(isHidden(actualTooltip));
160
var divRect = target.getBoundingClientRect();
161
expect(divRect.width).to.be.equal(100);
162
expect(divRect.height).to.be.equal(20);
164
var contentRect = tooltip.getBoundingClientRect();
165
expect(contentRect.width).to.be.equal(70);
166
expect(contentRect.height).to.be.equal(30);
168
// The target div width is 100, and the tooltip width is 70, and
169
// it's centered. The height of the target div is 20, and the
170
// tooltip is 14px below.
171
expect(contentRect.left).to.be.equal((100 - 70)/2);
172
expect(contentRect.top).to.be.equal(20 + 14);
174
// Also check the math, just in case.
175
expect(contentRect.left).to.be.equal((divRect.width - contentRect.width)/2);
176
expect(contentRect.top).to.be.equal(divRect.height + tooltip.offset);
179
test('tooltip is positioned correctly (top)', function() {
180
var f = fixture('basic');
181
var target = f.querySelector('#target');
182
var tooltip = f.querySelector('paper-tooltip');
183
tooltip.position = 'top';
185
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
186
assert.isTrue(isHidden(actualTooltip));
188
MockInteractions.focus(target);
189
assert.isFalse(isHidden(actualTooltip));
191
var divRect = target.getBoundingClientRect();
192
expect(divRect.width).to.be.equal(100);
193
expect(divRect.height).to.be.equal(20);
195
var contentRect = tooltip.getBoundingClientRect();
196
expect(contentRect.width).to.be.equal(70);
197
expect(contentRect.height).to.be.equal(30);
199
// The target div width is 100, and the tooltip width is 70, and
200
// it's centered. The height of the tooltip is 30, and the
201
// tooltip is 14px above the target.
202
expect(contentRect.left).to.be.equal((100 - 70)/2);
203
expect(contentRect.top).to.be.equal(0 - 30 - 14);
205
// Also check the math, just in case.
206
expect(contentRect.left).to.be.equal((divRect.width - contentRect.width)/2);
207
expect(contentRect.top).to.be.equal(0 - contentRect.height - tooltip.offset);
210
test('tooltip is positioned correctly (right)', function() {
211
var f = fixture('basic');
212
var target = f.querySelector('#target');
213
var tooltip = f.querySelector('paper-tooltip');
214
tooltip.position = 'right';
216
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
217
assert.isTrue(isHidden(actualTooltip));
219
MockInteractions.focus(target);
220
assert.isFalse(isHidden(actualTooltip));
222
var divRect = target.getBoundingClientRect();
223
expect(divRect.width).to.be.equal(100);
224
expect(divRect.height).to.be.equal(20);
226
var contentRect = tooltip.getBoundingClientRect();
227
expect(contentRect.width).to.be.equal(70);
228
expect(contentRect.height).to.be.equal(30);
230
// The target div width is 100, and the tooltip is 14px to the right.
231
// The target div height is 20, the height of the tooltip is 20px, and
232
// the tooltip is centered.
233
expect(contentRect.left).to.be.equal(100 + 14);
234
expect(contentRect.top).to.be.equal((20 - 30)/2);
236
// Also check the math, just in case.
237
expect(contentRect.left).to.be.equal(divRect.width + tooltip.offset);
238
expect(contentRect.top).to.be.equal((divRect.height - contentRect.height)/2);
241
test('tooltip is positioned correctly (left)', function() {
242
var f = fixture('basic');
243
var target = f.querySelector('#target');
244
var tooltip = f.querySelector('paper-tooltip');
245
tooltip.position = 'left';
247
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
248
assert.isTrue(isHidden(actualTooltip));
250
MockInteractions.focus(target);
251
assert.isFalse(isHidden(actualTooltip));
253
var divRect = target.getBoundingClientRect();
254
expect(divRect.width).to.be.equal(100);
255
expect(divRect.height).to.be.equal(20);
257
var contentRect = tooltip.getBoundingClientRect();
258
expect(contentRect.width).to.be.equal(70);
259
expect(contentRect.height).to.be.equal(30);
261
// The tooltip width is 70px, and the tooltip is 14px to the left of the target.
262
// The target div height is 20, the height of the tooltip is 20px, and
263
// the tooltip is centered.
264
expect(contentRect.left).to.be.equal(0 - 70 - 14);
265
expect(contentRect.top).to.be.equal((20 - 30)/2);
267
// Also check the math, just in case.
268
expect(contentRect.left).to.be.equal(0 - contentRect.width - tooltip.offset);
269
expect(contentRect.top).to.be.equal((divRect.height - contentRect.height)/2);
272
test('tooltip is fitted correctly if out of bounds', function() {
273
var f = fixture('fitted');
274
var target = f.querySelector('#target');
275
var tooltip = f.querySelector('paper-tooltip');
276
target.style.top = 0;
277
target.style.left = 0;
279
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
280
assert.isTrue(isHidden(actualTooltip));
282
MockInteractions.focus(target);
283
assert.isFalse(isHidden(actualTooltip));
285
var contentRect = tooltip.getBoundingClientRect();
286
var divRect = target.getBoundingClientRect();
288
// Should be fitted on the left side.
289
expect(contentRect.left).to.be.equal(0);
290
expect(contentRect.top).to.be.equal(divRect.height + tooltip.offset);
293
test('tooltip is positioned correctly after being dynamically set', function() {
294
var f = fixture('dynamic');
295
var target = f.querySelector('#target');
296
var tooltip = f.querySelector('paper-tooltip');
298
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
299
assert.isTrue(isHidden(actualTooltip));
301
// Skip animations in this test, which means we'll show and hide
302
// the tooltip manually, instead of calling focus and blur.
304
// The tooltip is shown because it's a sibling of the target,
305
// but it's positioned incorrectly
306
tooltip.toggleClass('hidden', false, actualTooltip);
307
assert.isFalse(isHidden(actualTooltip));
309
var contentRect = tooltip.getBoundingClientRect();
310
expect(contentRect.left).to.not.be.equal((100 - 70)/2);
312
tooltip.for = 'target';
314
// The tooltip needs to hide before it gets repositioned.
315
tooltip.toggleClass('hidden', true, actualTooltip);
316
tooltip.updatePosition();
317
tooltip.toggleClass('hidden', false, actualTooltip);
318
assert.isFalse(isHidden(actualTooltip));
320
// The target div width is 100, and the tooltip width is 70, and
321
// it's centered. The height of the target div is 20, and the
322
// tooltip is 14px below.
323
contentRect = tooltip.getBoundingClientRect();
324
expect(contentRect.left).to.be.equal((100 - 70)/2);
325
expect(contentRect.top).to.be.equal(20 + 14);
328
test('tooltip is hidden after target is blurred', function(done) {
329
var f = fixture('basic');
330
var target = f.querySelector('#target');
331
var tooltip = f.querySelector('paper-tooltip');
333
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
334
assert.isTrue(isHidden(actualTooltip));
335
// Simulate but don't actually run the entry animation.
336
tooltip.toggleClass('hidden', false, actualTooltip);
337
tooltip._showing = true;
338
assert.isFalse(isHidden(actualTooltip));
340
tooltip.addEventListener('neon-animation-finish', function() {
341
assert.isTrue(isHidden(actualTooltip));
344
MockInteractions.blur(target);
347
test('tooltip unlistens to target on detach', function(done) {
348
var f = fixture('basic');
349
var target = f.querySelector('#target');
350
var tooltip = f.querySelector('paper-tooltip');
352
sinon.spy(tooltip, 'show');
354
MockInteractions.focus(target);
355
expect(tooltip.show.callCount).to.be.equal(1);
357
MockInteractions.focus(target);
358
expect(tooltip.show.callCount).to.be.equal(2);
360
f.removeChild(tooltip);
362
setTimeout(function() {
363
// No more listener means no more calling show.
364
MockInteractions.focus(target);
365
expect(tooltip.show.callCount).to.be.equal(2);
371
suite('tooltip is inside a custom element', function() {
372
var f, tooltip, target;
375
f = fixture('custom');
377
tooltip = f.$.buttonTooltip;
380
test('tooltip is shown when target is focused', function() {
381
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
382
assert.isTrue(isHidden(actualTooltip));
384
MockInteractions.focus(target);
385
assert.isFalse(isHidden(actualTooltip));
388
test('tooltip is positioned correctly', function() {
389
var actualTooltip = Polymer.dom(tooltip.root).querySelector('#tooltip');
390
assert.isTrue(isHidden(actualTooltip));
392
MockInteractions.focus(target);
393
assert.isFalse(isHidden(actualTooltip));
395
var divRect = target.getBoundingClientRect();
396
expect(divRect.width).to.be.equal(100);
397
expect(divRect.height).to.be.equal(20);
399
var contentRect = tooltip.getBoundingClientRect();
400
expect(contentRect.width).to.be.equal(70);
401
expect(contentRect.height).to.be.equal(30);
403
// The target div width is 100, and the tooltip width is 70, and
404
// it's centered. The height of the target div is 20, and the
405
// tooltip is 14px below.
406
expect(contentRect.left).to.be.equal((100 - 70)/2);
407
expect(contentRect.top).to.be.equal(20 + 14);
409
// Also check the math, just in case.
410
expect(contentRect.left).to.be.equal((divRect.width - contentRect.width)/2);
411
expect(contentRect.top).to.be.equal(divRect.height + tooltip.offset);
415
suite('a11y', function() {
416
test('has aria role "tooltip"', function() {
417
var f = fixture('basic');
418
var tooltip = f.querySelector('paper-tooltip');
420
assert.isTrue(tooltip.getAttribute('role') == 'tooltip');
423
var ignoredRules = ['roleTooltipRequiresDescribedby'];
425
a11ySuite('basic', ignoredRules);
426
a11ySuite('fitted', ignoredRules);
427
a11ySuite('no-text', ignoredRules);
428
a11ySuite('dynamic', ignoredRules);
429
a11ySuite('custom', ignoredRules);