package org.uiautomation.ios.selenium;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.testng.annotations.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
@Test
public class ExecutingJavascriptTests extends BaseSeleniumTest {
////@JavascriptEnabled
@Test
public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnAString() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.xhtmlTestPage);
Object result = executeScript("return document.title;");
assertTrue(result instanceof String);
assertEquals("XHTML Test Page", result);
}
//@JavascriptEnabled
@Test
public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnALong() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.nestedPage);
Object result = executeScript("return document.getElementsByName('checky').length;");
assertTrue(result instanceof Long, result.getClass().getName());
assertTrue((Long) result > 1);
}
//@JavascriptEnabled
@Test
public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnAWebElement() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.xhtmlTestPage);
Object result = executeScript("return document.getElementById('id1');");
assertNotNull(result);
assertTrue(result instanceof WebElement);
assertEquals("a", ((WebElement) result).getTagName().toLowerCase());
}
//@JavascriptEnabled
@Test
public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnABoolean() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.xhtmlTestPage);
Object result = executeScript("return true;");
assertNotNull(result);
assertTrue(result instanceof Boolean);
assertTrue((Boolean) result);
}
@SuppressWarnings("unchecked")
//@JavascriptEnabled
@Test
public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnAStringsArray() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
List<Object> expectedResult = new ArrayList<Object>();
expectedResult.add("zero");
expectedResult.add("one");
expectedResult.add("two");
Object result = ((JavascriptExecutor) driver).executeScript("return ['zero', 'one', 'two'];");
ExecutingJavascriptTests.compareLists(expectedResult, (List<Object>) result);
}
@SuppressWarnings("unchecked")
//@JavascriptEnabled
@Test
public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnAnArray() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
List<Object> expectedResult = new ArrayList<Object>();
expectedResult.add("zero");
List<Object> subList = new ArrayList<Object>();
subList.add(true);
subList.add(false);
expectedResult.add(subList);
Object result = executeScript("return ['zero', [true, false]];");
assertNotNull(result);
assertTrue(result instanceof List, "result was: " + result + " (" + result.getClass() + ")");
List<Object> list = (List<Object>) result;
assertTrue(compareLists(expectedResult, list));
}
@SuppressWarnings("unchecked")
//@JavascriptEnabled
@Test
public void testShouldBeAbleToExecuteJavascriptAndReturnABasicObjectLiteral() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
Object result = executeScript("return {abc: '123', tired: false};");
assertTrue(result instanceof Map, "result was: " + result + " (" + result.getClass() + ")");
Map<String, Object> map = (Map<String, Object>) result;
Map<String, Object> expected = new HashMap<String, Object>();
expected.put("abc", "123");
expected.put("tired", false);
// Cannot do an exact match; Firefox 4 inserts a few extra keys in our
// object; this is OK, as
// long as the expected keys are there.
assertTrue(map.size() >= expected.size(), "Expected:<" + expected + ">, but was:<" + map + ">");
for (Map.Entry<String, Object> entry : expected.entrySet()) {
assertEquals(entry.getValue(), map.get(entry.getKey()),
"Difference at key:<" + entry.getKey() + ">");
}
}
@SuppressWarnings("unchecked")
//@JavascriptEnabled
@Test
public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnAnObjectLiteral() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
Map<String, Object> expectedResult = new HashMap<String, Object>() {
{
put("foo", "bar");
put("baz", Arrays.asList("a", "b", "c"));
put("person", new HashMap<String, String>() {
{
put("first", "John");
put("last", "Doe");
}
});
}
};
Object
result =
executeScript(
"return {foo:'bar', baz: ['a', 'b', 'c'], person: {first: 'John',last: 'Doe'}};");
assertTrue(result instanceof Map, "result was: " + result + " (" + result.getClass() + ")");
Map<String, Object> map = (Map<String, Object>) result;
assertTrue(map.size() == 3, "Expected:<" + expectedResult + ">, but was:<" + map + ">");
assertEquals("bar", map.get("foo"));
assertTrue(compareLists((List<?>) expectedResult.get("baz"), (List<?>) map.get("baz")));
Map<String, String> person = (Map<String, String>) map.get("person");
assertTrue(person.size() == (2), "Expected:<{first:John, last:Doe}>, but was:<" + person + ">");
assertEquals("John", person.get("first"));
assertEquals("Doe", person.get("last"));
}
@SuppressWarnings("unchecked")
//@JavascriptEnabled
//@Ignore({ IE, HTMLUNIT, OPERA, OPERA_MOBILE })
@Test
public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnAComplexObject() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
Object result = executeScript("return window.location;");
assertTrue(result instanceof Map, "result was: " + result + " (" + result.getClass() + ")");
Map<String, Object> map = (Map<String, Object>) result;
assertEquals("http:", map.get("protocol"));
assertEquals(pages.javascriptPage, map.get("href"));
}
private static boolean compareLists(List<?> first, List<?> second) {
if (first.size() != second.size()) {
return false;
}
for (int i = 0; i < first.size(); ++i) {
if (first.get(i) instanceof List<?>) {
if (!compareLists((List<?>) first.get(i), (List<?>) second.get(i))) {
return false;
}
} else {
if (!first.get(i).equals(second.get(i))) {
return false;
}
}
}
return true;
}
//@JavascriptEnabled
@Test
public void testPassingAndReturningALongShouldReturnAWholeNumber() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
Long expectedResult = 1L;
Object result = executeScript("return arguments[0];", expectedResult);
assertTrue((result instanceof Integer || result instanceof Long),
"Expected result to be an Integer or Long but was a " + result.getClass());
assertEquals(expectedResult.longValue(), result);
}
//@JavascriptEnabled
@Test
public void testPassingAndReturningADoubleShouldReturnADecimal() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
Double expectedResult = 1.2;
Object result = executeScript("return arguments[0];", expectedResult);
assertTrue(result instanceof Float || result instanceof Double,
"Expected result to be a Double or Float but was a " + result.getClass());
assertEquals(expectedResult.doubleValue(), result);
}
//@JavascriptEnabled
@Test
public void testShouldThrowAnExceptionWhenTheJavascriptIsBad() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.xhtmlTestPage);
try {
executeScript("return squiggle();");
fail("Expected an exception");
} catch (Exception e) {
// This is expected
assertFalse(e.getMessage().startsWith("null "), e.getMessage());
}
}
//@JavascriptEnabled
@Test
public void testShouldBeAbleToCallFunctionsDefinedOnThePage() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
executeScript("displayMessage('I like cheese');");
String text = driver.findElement(By.id("result")).getText();
assertEquals("I like cheese", text.trim());
}
private Object executeScript(String script, Object... args) {
return ((JavascriptExecutor) driver).executeScript(script, args);
}
//@JavascriptEnabled
@Test
public void testShouldBeAbleToPassAStringAnAsArgument() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
String
value =
(String) executeScript("return arguments[0] == 'fish' ? 'fish' : 'not fish';", "fish");
assertEquals("fish", value);
}
//@JavascriptEnabled
@Test
public void testShouldBeAbleToPassABooleanAnAsArgument() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
boolean value = (Boolean) executeScript("return arguments[0] == true;", true);
assertTrue(value);
}
//@JavascriptEnabled
@Test
public void testShouldBeAbleToPassANumberAnAsArgument() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
boolean value = (Boolean) executeScript("return arguments[0] == 1 ? true : false;", 1);
assertTrue(value);
}
//@JavascriptEnabled
@Test
public void testShouldBeAbleToPassAWebElementAsArgument() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
WebElement button = driver.findElement(By.id("plainButton"));
String value = (String) executeScript(
"arguments[0]['flibble'] = arguments[0].getAttribute('id'); return arguments[0]['flibble'];",
button);
assertEquals("plainButton", value);
}
//@JavascriptEnabled
@Test
public void testPassingArrayAsOnlyArgumentFlattensArray() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
Object[] array = new Object[]{"zero", 1, true, 3.14159, false};
String value = (String) executeScript("return arguments[0]", array);
assertEquals(array[0], value);
}
//@JavascriptEnabled
//@Ignore({ OPERA, OPERA_MOBILE })
@Test(enabled = false)
public void testShouldBeAbleToPassAnArrayAsAdditionalArgument() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
Object[] array = new Object[]{"zero", 1, true, 3.14159, false};
long length = (Long) executeScript("return arguments[1].length", "string", array);
assertEquals(array.length, length);
}
//@JavascriptEnabled
@Test(enabled = false)
// TODO
public void testShouldBeAbleToPassACollectionAsArgument() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
Collection<Object> collection = new ArrayList<Object>();
collection.add("Cheddar");
collection.add("Brie");
collection.add(7);
long length = (Long) executeScript("return arguments[0].length", collection);
assertEquals(collection.size(), length);
collection = new HashSet<Object>();
collection.add("Gouda");
collection.add("Stilton");
collection.add("Stilton");
collection.add(true);
length = (Long) executeScript("return arguments[0].length", collection);
assertEquals(collection.size(), length);
}
//@JavascriptEnabled
@Test
public void testShouldThrowAnExceptionIfAnArgumentIsNotValid() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
try {
executeScript("return arguments[0];", driver);
fail("Exception should have been thrown");
} catch (IllegalArgumentException e) {
// this is expected
}
}
//@JavascriptEnabled
@Test
public void testShouldBeAbleToPassInMoreThanOneArgument() {
if (!(driver instanceof JavascriptExecutor)) {
return;
}
driver.get(pages.javascriptPage);
String result = (String) executeScript("return arguments[0] + arguments[1];", "one", "two");
assertEquals("onetwo", result);
}
//@JavascriptEnabled
@Test
//@Ignore({ OPERA, OPERA_MOBILE })
public void testShouldBeAbleToGrabTheBodyOfFrameOnceSwitchedTo() {
driver.get(pages.richTextPage);
driver.switchTo().frame("editFrame");
WebElement
body =
(WebElement) ((JavascriptExecutor) driver).executeScript("return document.body");
String text = body.getText();
driver.switchTo().defaultContent();
assertEquals("", text);
}
@SuppressWarnings("unchecked")
//@JavascriptEnabled
@Test
public void testShouldBeAbleToReturnAnArrayOfWebElements() {
driver.get(pages.formPage);
List<WebElement> items = (List<WebElement>) ((JavascriptExecutor) driver)
.executeScript("return document.getElementsByName('snack');");
assertFalse(items.isEmpty());
}
//@JavascriptEnabled
@Test
public void testJavascriptStringHandlingShouldWorkAsExpected() {
driver.get(pages.javascriptPage);
String value = (String) executeScript("return '';");
assertEquals("", value);
value = (String) executeScript("return undefined;");
assertNull(value);
value = (String) executeScript("return ' '");
assertEquals(" ", value);
}
//@JavascriptEnabled
//@Ignore(OPERA)
@Test(enabled = false)
public void testShouldBeAbleToExecuteABigChunkOfJavascriptCode() throws IOException {
driver.get(pages.javascriptPage);
//File jqueryFile = InProject.locate("common/src/web/jquery-1.3.2.js");
//String jquery = Files.toString(jqueryFile, Charset.forName("US-ASCII"));
//assertTrue(jquery.length() > 50000, "The javascript code should be at least 50 KB.");
// This should not throw an exception ...
//executeScript(jquery);
}
//@SuppressWarnings("unchecked")
//@JavascriptEnabled
@Test
public void testShouldBeAbleToExecuteScriptAndReturnElementsList() {
driver.get(pages.formPage);
String scriptToExec = "return document.getElementsByName('snack');";
List<WebElement>
resultsList =
(List<WebElement>) ((JavascriptExecutor) driver).executeScript(scriptToExec);
assertFalse(resultsList.isEmpty());
}
//@JavascriptEnabled
//@NeedsFreshDriver
//@NoDriverAfterTest
//@Ignore(reason = "Failure indicates hang condition, which would break the"
// + " test suite. Really needs a timeout set.")
@Test(enabled = false)
public void testShouldThrowExceptionIfExecutingOnNoPage() {
try {
((JavascriptExecutor) driver).executeScript("return 1;");
} catch (WebDriverException e) {
// Expected
return;
}
fail("Expected exception to be thrown");
}
//@JavascriptEnabled
//@Ignore(OPERA)
@Test
public void testShouldBeAbleToCreateAPersistentValue() {
driver.get(pages.formPage);
executeScript("document.alerts = []");
executeScript("document.alerts.push('hello world');");
String text = (String) executeScript("return document.alerts.shift()");
assertEquals("hello world", text);
}
//@JavascriptEnabled
//@Ignore(OPERA)
@Test(enabled = false)
// freynaud TODO
public void testCanHandleAnArrayOfElementsAsAnObjectArray() {
driver.get(pages.formPage);
List<WebElement> forms = driver.findElements(By.tagName("form"));
Object[] args = new Object[]{forms};
String
name =
(String) ((JavascriptExecutor) driver)
.executeScript("return arguments[0][0].tagName", args);
assertEquals("form", name.toLowerCase());
}
//@JavascriptEnabled
//@Ignore(value = { ANDROID, HTMLUNIT, OPERA, OPERA_MOBILE }, reason = "Opera and HtmlUnit obey the method contract. Android not tested")
@Test(enabled = false)
// TODO freynaud
public void testCanPassAMapAsAParameter() {
driver.get(pages.simpleTestPage);
List<Integer> nums = ImmutableList.of(1, 2);
Map<String, Object> args = ImmutableMap.of("bar", "test", "foo", nums);
Object res = ((JavascriptExecutor) driver).executeScript("return arguments[0]['foo'][1]", args);
assertEquals(2, ((Number) res).intValue());
}
@Test
public void testCanAccessDocumentAndWindowObjectForFrames() {
driver.get(pages.framesetPage);
driver.switchTo().frame("third");
String actualFrameTitle = "We Leave From Here";
assertEquals(actualFrameTitle, executeScript("return document.title;"));
assertEquals(actualFrameTitle, executeScript("return window.document.title;"));
// We used to replace " document" in script - ensure we properly inject global scope, rather than performing string
// replacement.
assertEquals(actualFrameTitle, executeScript("return (document.title);"));
assertEquals(actualFrameTitle, executeScript("return (window.document.title);"));
}
}