<!DOCTYPE html>
<!--
Copyright 2011 WebDriver committers
Copyright 2011 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html>
<head>
  <title>atoms_test.html</title>
  <script type="text/javascript" src="../../webdriver-bootstrap.js">
  </script>
  <script type="text/javascript">
    goog.require('goog.math.Coordinate');
    goog.require('goog.math.Rect');
    goog.require('goog.math.Size');
    goog.require('goog.testing.jsunit');
    goog.require('webdriver.chrome');
  </script>

  <script type="text/javascript">
    function testComputeScrollOffsets() {
      function computeX(left, right, center) {
        var offsets = webdriver.chrome.computeScrollOffsets_(
            new goog.math.Size(10, 10),
            new goog.math.Rect(left, 1, right - left, 2),
            center);
        return offsets.x;
      }
      // In bounds
      assertEquals(0, computeX(1, 5, false));
      // On left edge
      assertEquals(0, computeX(0, 5, false));
      // Overlap left edge
      assertEquals(-1, computeX(-1, 5, false));
      // Past left edge
      assertEquals(-5, computeX(-5, -1, false));
      // On right edge
      assertEquals(0, computeX(5, 10, false));
      // Overlap right edge
      assertEquals(1, computeX(5, 11, false));
      // Past right edge
      assertEquals(4, computeX(12, 14, false));
      // Too big
      assertEquals(-1, computeX(-1, 11, false));
      assertEquals(2, computeX(-1, 15, true));

      function computeY(top, bottom, center) {
        var offsets = webdriver.chrome.computeScrollOffsets_(
            new goog.math.Size(10, 10),
            new goog.math.Rect(1, top, 2, bottom - top),
            center);
        return offsets.y;
      }
      // Above top edge
      assertEquals(-3, computeY(-3, -1, false));
      // Below bottom edge
      assertEquals(5, computeY(13, 15, false));
      // Too big
      assertEquals(-1, computeY(-1, 11, false));
      assertEquals(2, computeY(-1, 15, true));
    }

    function testComputeOffsetInContainer() {
      function computeY(container, elem) {
        return webdriver.chrome.computeOffsetInContainer_(
            document.getElementById(container),
            document.getElementById(elem)).y;
      }
      // Padding/margins/borders
      assertEquals(17, computeY('c1', 'e1'));

      // Absolute positioning
      assertEquals(50, computeY('c2', 'e2'));

      // Container hidden
      assertEquals(0, computeY('c3', 'e3'));

      // Element hidden
      assertEquals(0, computeY('c4', 'e4'));

      // Not displayed
      assertEquals(0, computeY('c5', 'e5'));
    }

    function testGetLocationInView() {
      var elem = frames[0].document.getElementById('elem');
      var coord = webdriver.chrome.getLocationInView(
          elem, false, new goog.math.Rect(0,0,4,4));
      assertEquals(281, coord.x);
      assertEquals(281, coord.y);
      assertEquals(408, frames[0].document.body.scrollLeft);
      assertEquals(408, frames[0].document.body.scrollTop);
    }

    function testGetFirstClientRect() {
      var rect = webdriver.chrome.getFirstClientRect(
          document.getElementById('span'));
      assertEquals(0, rect.left);
      assertEquals(0, rect.top);
      assertTrue(rect.width > 0);
      assertTrue(rect.height > 0);
    }

    function testGetFirstClientRectThrows() {
      assertThrows(function() {
            webdriver.chrome.getFirstClientRect(
              document.getElementById('e5'));
          });
    }
  </script>
</head>
<style>
  body {
    padding: 0px;
    margin: 0px;
  }
  #c1 {
    padding-top: 1px;
    margin-top: 2px;
    border: 0px solid blue;
    border-top-width: 4px;
  }
  #e1 {
    padding-top: 8px;
    margin-top: 16px;
    border: 0px solid red;
    border-top-width: 32px;
  }
</style>
<body id='body'>
  <div id='c1'>
    <div id='e1'>1</div>
  </div>
  <div id='c2' style='position:fixed; top:50px'>
    <div id='e2' style='position:absolute; top:50px'>2</div>
  </div>
  <div id='c3' style='visibility:hidden'>
    <div id='e3'>3</div>
  </div>
  <div id='c4'>
    <div id='e4' style='visibility:hidden'>4</div>
  </div>
  <div id='c5' style='display:none'>
    <div id='e5'>5</div>
  </div>
  <div style='width:1px'>
    <span id='span'>a b</span>
  </div>
  <iframe width=300 height=300 src='location_in_view.html'>
</body>
</html>

