<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">

<!--
Copyright 2004 ThoughtWorks, 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>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JsUnit Utility Tests</title>
<link rel="stylesheet" type="text/css" href="../../jsunit/css/jsUnitStyle.css">
<script language="JavaScript" type="text/javascript" src="../../jsunit/app/jsUnitCore.js"></script>
<script language="JavaScript" type="text/javascript" src="../jsmock/mock.js"></script>
<script language="JavaScript" type="text/javascript" src="../dummy-logging.js"></script>
<script language="JavaScript" type="text/javascript" src="../../core/scripts/htmlutils.js"></script>
<script language="JavaScript" type="text/javascript" src="../../core/scripts/selenium-browserdetect.js"></script>
<script language="JavaScript" type="text/javascript" src="../../core/scripts/selenium-browserbot.js"></script>
<script language="JavaScript" type="text/javascript">

var highlighter = new Object();
highlighter.highlight = function(){};

function highlight() {
    highlighter.highlight();
}

function setUp() {

    // To be realistic, the elements are located in a separate IFrame.
    var iframe = document.getElementById("testIframe");
    iWindow = iframe.contentWindow.window;
    frameDocument = iWindow.document;

    pageBot = BrowserBot.createForWindow(iWindow);

    element1 = iWindow.document.getElementById("id1");
    element2 = iWindow.document.getElementById("id2");
    element3 = iWindow.document.getElementById("id3");
    element4 = iWindow.document.getElementById("document.links[0]");

    toggleA = iWindow.document.getElementById("toggle-a");
    toggleB = iWindow.document.getElementById("toggle-b");
    toggleC = iWindow.document.getElementById("toggle-c");
}

function testShouldNotHighlightFoundElementIfHighlightFlagNotSetted() {
    highlighter = new Mock();
    pageBot.findElement('id1');
    highlighter.verify();
}


function testShouldBeAbleToHighlightFoundElement() {
    pageBot.browserbot.setShouldHighlightElement(true);
    highlighter = new Mock();
    
    highlighter.expects("highlight", element1);
    pageBot.findElement('id1');
    highlighter.verify();
}

function testShouldNotTryToHightlightIfNoElementFound() {
    pageBot.browserbot.setShouldHighlightElement(true);
    highlighter = new Mock();
    try {
        pageBot.findElement('IDontExist');
        fail("Should have failed for element not found");
    } catch(e) {
        //expects
    }
    highlighter.verify();
}

//
// Tests for "id" locator
//
function testIdLocatorReturnsNullIfElementNotPresent() {
    assertNull(pageBot.findElementBy('id', 'noSuchElement', frameDocument));
}

function testIdLocatorReturnsElementWithMatchingId() {
    assertEquals(element3, pageBot.findElementBy('id', 'id3', frameDocument));
}

function testIdLocatorDoesNotReturnElementWithMatchingName() {
    assertNull(pageBot.findElementBy('id', 'name1', frameDocument));
}

//
// Tests for "name" locator
//
function testNameLocatorReturnsNullIfElementNotPresent() {
    assertNull(pageBot.findElementBy('name', 'noSuchElement', frameDocument));
}

function testNameLocatorDoesNotReturnElementWithMatchingId() {
    assertNull(pageBot.findElementBy('name', 'id2', frameDocument));
}

function testNameLocatorReturnsElementWithMatchingName() {
    assertEquals(element2, pageBot.findElementBy('name', 'name1', frameDocument));
}

function testNameLocatorReturnsFirstMatch() {
    assertEquals(toggleA, pageBot.findElementBy('name', 'toggle', frameDocument));
}

function testNameLocatorCanRefineSelectionByElementValue() {
    assertEquals(toggleB, pageBot.findElementBy('name', 'toggle value=b', frameDocument));
    assertEquals(toggleB, pageBot.findElementBy('name', 'toggle b', frameDocument));
}

function testNameLocatorCanRefineSelectionByIndex() {
    assertEquals(toggleB, pageBot.findElementBy('name', 'toggle index=1', frameDocument));
}

//
// Tests for "identifier" locator
//
function testIdentifierLocatorReturnsNullIfElementNotPresent() {
    assertNull(pageBot.findElementBy('identifier', 'noSuchElement', frameDocument));
}

function testIdentifierLocatorReturnsHtmlElementWithMatchingId() {
    assertEquals(element3, pageBot.findElementBy('identifier', 'id3', frameDocument));
}

function testIdentifierLocatorReturnsFirstElementWithMatchingName() {
    assertEquals(element2, pageBot.findElementBy('identifier', 'name1', frameDocument));
}

//
// Tests for "dom" locator
//
function testLocateElementByDomTraversal() {
    assertEquals(element2,
            pageBot.findElementBy('dom', "document.links[1]", frameDocument, iWindow));
}

function testLocateElementByDomTraversalReturnsNullForNoMatchingElement() {
}

function testLocateElementByDomTraversalFailsWithInvalidDomString() {
    try {
        pageBot.findElementBy('dom', "document.foo.bar", frameDocument);
        fail("Should have thrown exception");
    }
    catch (e) {
        // Expected
    }
}

//
// Tests for "xpath" locator
//
function testLocateElementByXPathWithTagNameOnly() {
    assertEquals(element4,
            pageBot.findElementBy('xpath', "//p", frameDocument));
}

function testLocateElementByXPathWithAttributeOnly() {
    assertEquals(element4,
            pageBot.findElementBy('xpath', "//*[@class='pstyle']", frameDocument));
}

function testLocateElementByXPathWithTagNameAndAttribute() {
    assertEquals(element4,
            pageBot.findElementBy('xpath', "//p[@name='name1']", frameDocument));
}

function testLocateElementByXPathReturnsFirstMatchingElement() {
    assertEquals(element2,
            pageBot.findElementBy('xpath', "//*[@name='name1']", frameDocument));
}

//
// Tests for "link" locator
//
function testLocateLinkReturnsNullIfLocatorIsNotLinkLocator() {
    assertNull(pageBot.findElementBy('link', '//NotALinkLocator', frameDocument));
}

function testLocateLinkReturnsNullIfLinkNotPresent() {
    assertNull(pageBot.findElementBy('link', 'No Such Link', frameDocument));
}

function testLinkElementReturnsLinkWithMatchingText() {
    assertEquals(element3, pageBot.findElementBy('link', 'this is the third element', frameDocument));
}

function testLinkElementWithGlob() {
    assertEquals(element3, pageBot.findElementBy('link', 'this * third element', frameDocument));
}

function testLinkElementWithRegex() {
    assertEquals(element3, pageBot.findElementBy('link', 'regexp:this [aeiou]s the third element', frameDocument));
}

//
// Tests for PageBot.findElement()
//
function testFindElementWithNoLocatorPrefixUsesImplicitStrategy() {
    var calls = new Array();
    pageBot.locationStrategies['implicit'] = function(locator) {
        calls.push(locator);
        return "bar";
    };

    var element = pageBot.findElement("foo");
    assertEquals("bar", element);
    assertEquals("foo", calls.join());
}

function testFindElementThrowsExceptionIfNoElementFound() {
    var calls = new Array();
    pageBot.locationStrategies['implicit'] = function(locator) {
        calls.push(locator);
        return null;
    };

    var element = null;
    var failureMessage = null;
    try {
        element = pageBot.findElement("foo");
    } catch (e) {
        failureMessage = e.message;
    }

    assertNull(element);
    assertEquals("Element foo not found", failureMessage);
    assertEquals("foo", calls.join());
}

function testFindElementWithLocatorPrefixUsesSpecifiedStrategy() {
    var calls = new Array();
    pageBot.locationStrategies["anotherlocator"] = function(locator) {
        calls.push(locator);
        return "bar";
    };

    element = pageBot.findElement("anotherlocator=foo");
    assertEquals("bar", element);
    assertEquals("foo", calls.join());
}

function testFindElementWithUnknownLocatorPrefixThrowsException() {
    var calls = new Array();
    pageBot.locationStrategies['implicit'] = function(locator) {
        calls.push(locator);
        return "bar";
    };

    var element = null;
    var failureMessage = null;
    try {
        element = pageBot.findElement("bogus=foo");
    } catch (e) {
        failureMessage = e.message;
    }

    assertNull(element);
    assertEquals("Unrecognised locator type: 'bogus'", failureMessage);
    assertEquals("", calls.join());
}

function testFindElementReturnsElementWithMatchingIdentifier() {
    assertEquals(element2, pageBot.findElement("id2"));
}

function testFindElementReturnsMatchingName() {
    assertEquals(element2, pageBot.findElement("name1"));
}

function testFindElementTriesDomTraversalBeforeId() {
    assertEquals(element1, pageBot.findElement("document.links[0]"));
    assertEquals(element4, pageBot.findElement("id=document.links[0]"));
}

function testFindElementHandlesLinkLocators() {
    assertEquals(element3, pageBot.findElement('link=this is the third element'));
}

function testUnknownElementWithoutDomTraversal() {
    try {
        pageBot.findElement("unknownElement");
        fail("Should have failed for element not found");
    }
    catch (e) {
        // expected
    }
}

function testUnknownElementWithDomTraversal() {
    try {
        pageBot.findElement("document.foo");
        fail("Should have failed for element not found");
    }
    catch (e) {
        // expected
    }
}

function testFindElementHandlesDomTraversal() {
    assertEquals(element3, pageBot.findElement("document.links[2]"));
}
</script>
</head>

<body>
<iframe id="testIframe" src="./pagebot-locator-tests-include.html"/>
</body>
</html>