/**************************************************************************** * Copyright 2008-2011 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. * * Initial Contributors: * Håkan Råberg * Manish Chakravarty * Pavan K S ***************************************************************************/ package com.thoughtworks.krypton.driver.web.browser; import static org.junit.Assert.*; import java.awt.Point; import java.awt.Rectangle; import org.junit.Ignore; import org.junit.Test; import org.w3c.dom.Element; import com.thoughtworks.krypton.driver.web.browser.JavascriptException; public class BrowserSessionTest extends AbstractBaseBrowserSession { @Test public void shouldExecuteJavascriptAndReturnResult() throws Exception { assertEquals("Hello", session.evaluate("'Hello'")); } @Test public void shouldExecuteJavascriptAndReturnEvaluatedResult() throws Exception { assertEquals("2", session.evaluate("1 + 1")); } @Test public void shouldExecuteJavascriptAndThrowException() throws Exception { String reference = "Hello"; try { session.evaluate(reference); fail(); } catch (JavascriptException e) { assertEquals(referenceErrorMessage(reference), e.getMessage()); } } @Test public void shouldThrowExceptionWhenInjectingNonExistingJavascript() throws Exception { try { inject("test-does-not-exist.js"); fail(); } catch (IllegalArgumentException e) { } } @Test public void shouldInjectJavascriptFromResource() throws Exception { render("<html/>"); inject("test-hello-world.js"); assertEquals("world", session.evaluate("hello()")); } @Test public void shouldReadSimpleDomAsXml() throws Exception { render("<html/>"); assertEquals("html", session.dom().getDocumentElement().getTagName()); } @Test public void shouldReturnBoundingRectangleForElement() throws Exception { render(readResource("test-bounding-rectangle.html")); Element element = (Element) session.dom().getElementsByTagName("div").item(0); assertNotNull(element); Rectangle rectangle = session.boundingRectangle(element); assertEquals(new Rectangle(100, 200, 300, 400), rectangle); } @Test public void shouldReturnCenterForElement() throws Exception { render(readResource("test-bounding-rectangle.html")); Element element = (Element) session.dom().getElementsByTagName("div").item(0); assertNotNull(element); Point center = session.center(element); assertEquals(new Point(250, 400), center); } @Test public void shouldUseIdPropertyAfterChangeForElement() throws Exception { render("<html><head/><body><div id=\"1\"/></body></html>"); executeAndWaitForIdle(session.domExpression(session.dom().getElementById("1")) + ".id = '2'"); assertNull(session.dom().getElementById("1")); assertNotNull(session.dom().getElementById("2")); } @Test public void shouldUseNamePropertyAfterChangeForInputElement() throws Exception { render("<html><head/><body><input name=\"my-name\" id=\"1\"/></body></html>"); executeAndWaitForIdle(session.domExpression(session.dom().getElementById("1")) + ".name = 'my-new-name'"); assertEquals("my-new-name", session.dom().getElementById("1").getAttribute("name")); } @Test public void shouldUseCheckedPropertyFalseForNonExistingCheckedAttributeForCheckbox() throws Exception { render("<html><head/><body><input id=\"1\" type=\"checkbox\"/></body></html>"); Element checkbox = session.dom().getElementById("1"); assertEquals("checkbox", checkbox.getAttribute("type")); assertEquals(Boolean.FALSE.toString(), checkbox.getAttribute("checked")); } @Test public void shouldUseCheckedPropertyTrueForExisitingAttributeForCheckbox() throws Exception { render("<html><head/><body><input id=\"1\" type=\"checkbox\" checked/></body></html>"); Element checkbox = session.dom().getElementById("1"); assertEquals(Boolean.TRUE.toString(), checkbox.getAttribute("checked")); } @Test public void shouldUseCheckedPropertyAfterChangeForCheckbox() throws Exception { render("<html><head/><body><input id=\"1\" type=\"checkbox\" checked=\"true\"/></body></html>"); executeAndWaitForIdle(session.domExpression(session.dom().getElementById("1")) + ".checked = false"); Element checkbox = session.dom().getElementById("1"); assertEquals(Boolean.FALSE.toString(), checkbox.getAttribute("checked")); } @Test public void shouldUseCheckedPropertyFalseForNonExistingCheckedAttributeForRadioButton() throws Exception { render("<html><head/><body><input id=\"1\" type=\"radio\"/></body></html>"); Element radio = session.dom().getElementById("1"); assertEquals("radio", radio.getAttribute("type")); assertEquals(Boolean.FALSE.toString(), radio.getAttribute("checked")); } @Test public void shouldUseCheckedPropertyTrueForExisitingAttributeForRadioButton() throws Exception { render("<html><head/><body><input id=\"1\" type=\"radio\" checked/></body></html>"); Element radio = session.dom().getElementById("1"); assertEquals(Boolean.TRUE.toString(), radio.getAttribute("checked")); } @Test public void shouldUseCheckedPropertyAfterChangeForRadioButton() throws Exception { render("<html><head/><body><form><input name=\"theRadio\" id=\"1\" type=\"radio\" checked=\"true\"/><input id=\"2\" name=\"theRadio\" type=\"radio\"/></form></body></html>"); executeAndWaitForIdle(session.domExpression(session.dom().getElementById("2")) + ".checked = true"); Element radio = session.dom().getElementById("1"); assertEquals(Boolean.FALSE.toString(), radio.getAttribute("checked")); radio = session.dom().getElementById("2"); assertEquals(Boolean.TRUE.toString(), radio.getAttribute("checked")); } @Test public void shouldUseValueEmptyStringForNonExistingValueAttributeForTextField() throws Exception { render("<html><head/><body><input id=\"1\" type=\"text\"/></body></html>"); Element textfield = session.dom().getElementById("1"); assertEquals("text", textfield.getAttribute("type")); assertEquals("", textfield.getAttribute("value")); assertTrue(textfield.hasAttribute("value")); } @Test public void shouldUseValueForExistingValueAttributeForTextField() throws Exception { render("<html><head/><body><input id=\"1\" type=\"text\" value=\"hello\"/></body></html>"); Element textfield = session.dom().getElementById("1"); assertEquals("hello", textfield.getAttribute("value")); } @Test public void shouldUseValuePropertyAfterChangeForTextField() throws Exception { render("<html><head/><body><input id=\"1\" type=\"text\" value=\"hello\"/></body></html>"); executeAndWaitForIdle(session.domExpression(session.dom().getElementById("1")) + ".value = 'world'"); Element textfield = session.dom().getElementById("1"); assertEquals("world", textfield.getAttribute("value")); } @Test public void shouldUseValueForExistingValueAttributeForPasswordTextField() throws Exception { render("<html><head/><body><input id=\"1\" type=\"password\" value=\"hello\"/></body></html>"); Element textfield = session.dom().getElementById("1"); assertEquals("hello", textfield.getAttribute("value")); } @Test public void shouldUseValueEmptyStringForNonExistingValueAttributeForTextArea() throws Exception { render("<html><head/><body><textarea id=\"1\"></textarea></body></html>"); Element textarea = session.dom().getElementById("1"); assertEquals("", textarea.getAttribute("value")); assertTrue(textarea.hasAttribute("value")); } @Test public void shouldUseValueForExistingValueAttributeForTextArea() throws Exception { render("<html><head/><body><textarea id=\"1\">hello</textarea></body></html>"); Element textarea = session.dom().getElementById("1"); assertEquals("hello", textarea.getAttribute("value")); assertEquals("hello", textarea.getTextContent()); } @Test public void shouldUseValuePropertyAfterChangeForTextArea() throws Exception { render("<html><head/><body><textarea id=\"1\">hello</textarea></body></html>"); executeAndWaitForIdle(session.domExpression(session.dom().getElementById("1")) + ".value = 'world'"); Element textarea = session.dom().getElementById("1"); assertEquals("world", textarea.getAttribute("value")); assertEquals("world", textarea.getTextContent()); } @Test public void shouldUseSelectedPropertyTrueForNonExistingSelectedAttributeForSingleOption() throws Exception { render("<html><head/><body><select><option id=\"1\"/></select></body></html>"); Element option = session.dom().getElementById("1"); assertEquals(Boolean.TRUE.toString(), option.getAttribute("selected")); } @Test public void shouldUseMultiplePropertyFalseForSingleSelect() throws Exception { render("<html><head/><body><select id=\"1\"><option/></select></body></html>"); Element select = session.dom().getElementById("1"); assertEquals(Boolean.FALSE.toString(), select.getAttribute("multiple")); } @Test public void shouldUseMultiplePropertyTrueAfterChangedForSingleSelect() throws Exception { render("<html><head/><body><select id=\"1\"><option/></select></body></html>"); executeAndWaitForIdle(session.domExpression(session.dom().getElementById("1")) + ".multiple = true"); Element select = session.dom().getElementById("1"); assertEquals(Boolean.TRUE.toString(), select.getAttribute("multiple")); } @Test public void shouldUseMultiplePropertyTrueForMultipleSelect() throws Exception { render("<html><head/><body><select id=\"1\" multiple><option/></select></body></html>"); Element select = session.dom().getElementById("1"); assertEquals(Boolean.TRUE.toString(), select.getAttribute("multiple")); } @Test public void shouldUseSelectedPropertyFalseForNonExistingSelectedAttributeForOption() throws Exception { render("<html><head/><body><select><option/><option id=\"1\"/></select></body></html>"); Element option = session.dom().getElementById("1"); assertEquals(Boolean.FALSE.toString(), option.getAttribute("selected")); } @Test public void shouldUseSelectedPropertyTrueForExisitingAttributeForOption() throws Exception { render("<html><head/><body><select><option/><option id=\"1\" selected/></select></body></html>"); Element option = session.dom().getElementById("1"); assertEquals(Boolean.TRUE.toString(), option.getAttribute("selected")); } @Test public void shouldUseSelectedPropertyAfterChangeForOption() throws Exception { render("<html><head/><body><select><option id=\"0\"/><option id=\"1\" selected=\"true\"/></select></body></html>"); executeAndWaitForIdle(session.domExpression(session.dom().getElementById("0")) + ".selected = true"); Element option = session.dom().getElementById("1"); assertEquals(Boolean.FALSE.toString(), option.getAttribute("selected")); } @Test public void shouldUseFalseForNonExistingDisabledAttributeForTextField() throws Exception { render("<html><head/><body><input id=\"1\" type=\"text\"/></body></html>"); Element textfield = session.dom().getElementById("1"); assertEquals(Boolean.FALSE.toString(), textfield.getAttribute("disabled")); } @Test public void shouldUseExistingDisabledAttributeForTextField() throws Exception { render("<html><head/><body><input id=\"1\" type=\"text\" disabled=\"true\"/></body></html>"); Element textfield = session.dom().getElementById("1"); assertEquals(Boolean.TRUE.toString(), textfield.getAttribute("disabled")); } @Test public void shouldUseDisabledPropertyAfterChangeForTextField() throws Exception { render("<html><head/><body><input id=\"1\" type=\"text\" disabled=\"true\"/></body></html>"); executeAndWaitForIdle(session.domExpression(session.dom().getElementById("1")) + ".disabled = false"); Element textfield = session.dom().getElementById("1"); assertEquals(Boolean.FALSE.toString(), textfield.getAttribute("disabled")); } @Test public void shouldUseFalseForNonExistingReadonlyAttributeForTextField() throws Exception { render("<html><head/><body><input id=\"1\" type=\"text\"/></body></html>"); Element textfield = session.dom().getElementById("1"); assertEquals(Boolean.FALSE.toString(), textfield.getAttribute("readonly")); } @Test public void shouldUseExistingReadonlyAttributeForTextField() throws Exception { render("<html><head/><body><input id=\"1\" type=\"text\" readonly=\"true\"/></body></html>"); Element textfield = session.dom().getElementById("1"); assertEquals(Boolean.TRUE.toString(), textfield.getAttribute("readonly")); } @Test public void shouldUseReadonlyPropertyAfterChangeForTextField() throws Exception { render("<html><head/><body><input id=\"1\" type=\"text\" readonly=\"true\"/></body></html>"); executeAndWaitForIdle(session.domExpression(session.dom().getElementById("1")) + ".readOnly = false"); Element textfield = session.dom().getElementById("1"); assertEquals(Boolean.FALSE.toString(), textfield.getAttribute("readonly")); } @Test public void shouldUseForPropertyAfterHtmlForChangeForLabel() throws Exception { render("<html><head/><body><label id=\"1\" for=\"2\">My Label</label><input id=\"2\" type=\"text\" readonly=\"true\"/><input id=\"3\" type=\"text\" readonly=\"true\"/></body></html>"); executeAndWaitForIdle(session.domExpression(session.dom().getElementById("1")) + ".htmlFor = '3'"); Element label = session.dom().getElementById("1"); assertEquals("3", label.getAttribute("for")); } @Test public void shouldUseClassPropertyAfterClassNameChangeForElement() throws Exception { render("<html><head/><body><input id=\"1\" type=\"text\" class=\"text-box\"/></body></html>"); executeAndWaitForIdle(session.domExpression(session.dom().getElementById("1")) + ".className = 'my-text-box'"); Element label = session.dom().getElementById("1"); assertEquals("my-text-box", label.getAttribute("class")); } @Test public void shouldParseAndEscapeXmlText() throws Exception { render("<html><head/><body id=\"1\">& & & < < < > > > \" " " ' ' '</body></html>"); Element body = session.dom().getElementById("1"); assertEquals("& & & < < < > > > \" \" \" ' ' '", session.getText(body)); } @Test @Ignore("Not entirely sure about this one. Nekohtml won't unescape, so.") public void shouldParseAndEscapeXmlAttribute() throws Exception { render("<html><head/><body><a id=\"1\" href=\"" + "http://localhost/my%20image.gif?send=yes&make-it-large='true'%26beautiful=false&mine=%22true%22\">my link</a></body></html>"); Element link = session.dom().getElementById("1"); String encodedAttribute = link.getAttribute("href"); String expectedFullyUnencodedAndXmlUnescapedUrl = "http://localhost/my image.gif?send=yes&make-it-large='true'&beautiful=false&mine=\"true\""; assertEquals(expectedFullyUnencodedAndXmlUnescapedUrl, encodedAttribute); } @Test public void shouldAccessElementInFrame() throws Exception { render(readResource("test-frames.html")); assertNull(session.dom().getElementById("1")); session.setWindowExpression("window.frames[0]"); assertNotNull(session.dom().getElementById("1")); assertEquals("window.frames[0].document", session.getDocumentExpression()); } @Test public void shouldAccessElementInIFrame() throws Exception { render(readResource("test-iframe.html")); assertNull(session.dom().getElementById("1")); session.setWindowExpression("window.frames[0]"); assertNotNull(session.dom().getElementById("1")); assertEquals("window.frames[0].document", session.getDocumentExpression()); } @Test public void shouldChangeBackToTopFrame() throws Exception { render(readResource("test-iframe.html")); session.setWindowExpression("window.frames[0]"); assertEquals("window.frames[0].document", session.getDocumentExpression()); assertNotNull(session.dom().getElementById("1")); session.setWindowExpression("window"); assertNull(session.dom().getElementById("1")); } @Test public void shouldNormalizeExpressionForFrame() throws Exception { render(readResource("test-frames.html")); assertNull(session.dom().getElementById("1")); session.setWindowExpression("document.getElementsByTagName('frame')[0].contentWindow"); assertNotNull(session.dom().getElementById("1")); assertEquals("window.frames[0].document", session.getDocumentExpression()); } @Test public void shouldThrowExceptionWhenAccessingNonExistingFrame() throws Exception { render(readResource("test-iframe.html")); try { session.setWindowExpression("window.frames[1]"); fail(); } catch (JavascriptException e) { } } @Test @Ignore("Seems like nekohtml handles this.") public void shouldRemoveIllegalAttributes() throws Exception { render("<html><head/><body id=\"1\" -illegal=\"\"></body></html>"); Element body = session.dom().getElementById("1"); assertFalse(body.hasAttribute("-illegal")); } }