basic.html 13.8 KB
<!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;
  }

</style>

<body>

  <test-fixture id="basic">
    <template>
      <div>
        <div id="target"></div>
        <paper-tooltip for="target">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>

  <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 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));
        MockInteractions.focus(target);
        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.$.tooltip;
      });

      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');
      });
    });
  </script>
</body>
</html>