PageRenderTime 52ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/java/client/test/org/openqa/selenium/ExecutingJavascriptTest.java

https://bitbucket.org/abahdanovich/selenium
Java | 597 lines | 470 code | 106 blank | 21 comment | 32 complexity | 24c5a08995755a7114404966ad695c39 MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, AGPL-1.0, MIT, Apache-2.0, BSD-3-Clause, GPL-2.0
  1. /*
  2. Copyright 2007-2009 Selenium committers
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package org.openqa.selenium;
  14. import com.google.common.collect.ImmutableList;
  15. import com.google.common.collect.ImmutableMap;
  16. import com.google.common.io.Files;
  17. import org.junit.Test;
  18. import org.openqa.selenium.testing.Ignore;
  19. import org.openqa.selenium.testing.InProject;
  20. import org.openqa.selenium.testing.JUnit4TestBase;
  21. import org.openqa.selenium.testing.JavascriptEnabled;
  22. import java.io.File;
  23. import java.io.IOException;
  24. import java.nio.charset.Charset;
  25. import java.util.ArrayList;
  26. import java.util.Arrays;
  27. import java.util.Collection;
  28. import java.util.HashMap;
  29. import java.util.HashSet;
  30. import java.util.List;
  31. import java.util.Map;
  32. import static org.hamcrest.Matchers.greaterThanOrEqualTo;
  33. import static org.hamcrest.Matchers.instanceOf;
  34. import static org.junit.Assert.assertEquals;
  35. import static org.junit.Assert.assertFalse;
  36. import static org.junit.Assert.assertNotNull;
  37. import static org.junit.Assert.assertNull;
  38. import static org.junit.Assert.assertThat;
  39. import static org.junit.Assert.assertTrue;
  40. import static org.junit.Assert.fail;
  41. import static org.openqa.selenium.testing.Ignore.Driver.ANDROID;
  42. import static org.openqa.selenium.testing.Ignore.Driver.HTMLUNIT;
  43. import static org.openqa.selenium.testing.Ignore.Driver.IE;
  44. import static org.openqa.selenium.testing.Ignore.Driver.OPERA;
  45. import static org.openqa.selenium.testing.Ignore.Driver.OPERA_MOBILE;
  46. public class ExecutingJavascriptTest extends JUnit4TestBase {
  47. @JavascriptEnabled
  48. @Test
  49. public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnAString() {
  50. if (!(driver instanceof JavascriptExecutor)) {
  51. return;
  52. }
  53. driver.get(pages.xhtmlTestPage);
  54. Object result = executeScript("return document.title;");
  55. assertTrue(result instanceof String);
  56. assertEquals("XHTML Test Page", result);
  57. }
  58. @JavascriptEnabled
  59. @Test
  60. public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnALong() {
  61. if (!(driver instanceof JavascriptExecutor)) {
  62. return;
  63. }
  64. driver.get(pages.nestedPage);
  65. Object result = executeScript("return document.getElementsByName('checky').length;");
  66. assertTrue(result.getClass().getName(), result instanceof Long);
  67. assertTrue((Long) result > 1);
  68. }
  69. @JavascriptEnabled
  70. @Test
  71. public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnAWebElement() {
  72. if (!(driver instanceof JavascriptExecutor)) {
  73. return;
  74. }
  75. driver.get(pages.xhtmlTestPage);
  76. Object result = executeScript("return document.getElementById('id1');");
  77. assertNotNull(result);
  78. assertThat(result, instanceOf(WebElement.class));
  79. assertEquals("a", ((WebElement) result).getTagName().toLowerCase());
  80. }
  81. @JavascriptEnabled
  82. @Test
  83. public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnABoolean() {
  84. if (!(driver instanceof JavascriptExecutor)) {
  85. return;
  86. }
  87. driver.get(pages.xhtmlTestPage);
  88. Object result = executeScript("return true;");
  89. assertNotNull(result);
  90. assertTrue(result instanceof Boolean);
  91. assertTrue((Boolean) result);
  92. }
  93. @SuppressWarnings("unchecked")
  94. @JavascriptEnabled
  95. @Test
  96. public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnAStringsArray() {
  97. if (!(driver instanceof JavascriptExecutor)) {
  98. return;
  99. }
  100. driver.get(pages.javascriptPage);
  101. List<Object> expectedResult = new ArrayList<Object>();
  102. expectedResult.add("zero");
  103. expectedResult.add("one");
  104. expectedResult.add("two");
  105. Object result = ((JavascriptExecutor) driver).executeScript(
  106. "return ['zero', 'one', 'two'];");
  107. ExecutingJavascriptTest.compareLists(expectedResult, (List<Object>) result);
  108. }
  109. @SuppressWarnings("unchecked")
  110. @JavascriptEnabled
  111. @Test
  112. public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnAnArray() {
  113. if (!(driver instanceof JavascriptExecutor)) {
  114. return;
  115. }
  116. driver.get(pages.javascriptPage);
  117. List<Object> expectedResult = new ArrayList<Object>();
  118. expectedResult.add("zero");
  119. List<Object> subList = new ArrayList<Object>();
  120. subList.add(true);
  121. subList.add(false);
  122. expectedResult.add(subList);
  123. Object result = executeScript("return ['zero', [true, false]];");
  124. assertNotNull(result);
  125. assertTrue("result was: " + result + " (" + result.getClass() + ")", result instanceof List);
  126. List<Object> list = (List<Object>) result;
  127. assertTrue(compareLists(expectedResult, list));
  128. }
  129. @SuppressWarnings("unchecked")
  130. @JavascriptEnabled
  131. @Test
  132. public void testShouldBeAbleToExecuteJavascriptAndReturnABasicObjectLiteral() {
  133. if (!(driver instanceof JavascriptExecutor)) {
  134. return;
  135. }
  136. driver.get(pages.javascriptPage);
  137. Object result = executeScript("return {abc: '123', tired: false};");
  138. assertTrue("result was: " + result + " (" + result.getClass() + ")", result instanceof Map);
  139. Map<String, Object> map = (Map<String, Object>) result;
  140. Map<String, Object> expected = new HashMap<String, Object>();
  141. expected.put("abc", "123");
  142. expected.put("tired", false);
  143. // Cannot do an exact match; Firefox 4 inserts a few extra keys in our object; this is OK, as
  144. // long as the expected keys are there.
  145. assertThat("Expected:<" + expected + ">, but was:<" + map + ">",
  146. map.size(), greaterThanOrEqualTo(expected.size()));
  147. for (Map.Entry<String, Object> entry : expected.entrySet()) {
  148. assertEquals("Difference at key:<" + entry.getKey() + ">",
  149. entry.getValue(), map.get(entry.getKey()));
  150. }
  151. }
  152. @SuppressWarnings("unchecked")
  153. @JavascriptEnabled
  154. @Test
  155. public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnAnObjectLiteral() {
  156. if (!(driver instanceof JavascriptExecutor)) {
  157. return;
  158. }
  159. driver.get(pages.javascriptPage);
  160. Map<String, Object> expectedResult = new HashMap<String, Object>() {
  161. {
  162. put("foo", "bar");
  163. put("baz", Arrays.asList("a", "b", "c"));
  164. put("person", new HashMap<String, String>() {
  165. {
  166. put("first", "John");
  167. put("last", "Doe");
  168. }
  169. });
  170. }
  171. };
  172. Object result = executeScript(
  173. "return {foo:'bar', baz: ['a', 'b', 'c'], " +
  174. "person: {first: 'John',last: 'Doe'}};");
  175. assertTrue("result was: " + result + " (" + result.getClass() + ")", result instanceof Map);
  176. Map<String, Object> map = (Map<String, Object>) result;
  177. assertThat("Expected:<" + expectedResult + ">, but was:<" + map + ">",
  178. map.size(), greaterThanOrEqualTo(3));
  179. assertEquals("bar", map.get("foo"));
  180. assertTrue(compareLists((List<?>) expectedResult.get("baz"),
  181. (List<?>) map.get("baz")));
  182. Map<String, String> person = (Map<String, String>) map.get("person");
  183. assertThat("Expected:<{first:John, last:Doe}>, but was:<" + person + ">",
  184. person.size(), greaterThanOrEqualTo(2));
  185. assertEquals("John", person.get("first"));
  186. assertEquals("Doe", person.get("last"));
  187. }
  188. @SuppressWarnings("unchecked")
  189. @JavascriptEnabled
  190. @Ignore({IE, OPERA, OPERA_MOBILE})
  191. @Test
  192. public void testShouldBeAbleToExecuteSimpleJavascriptAndReturnAComplexObject() {
  193. if (!(driver instanceof JavascriptExecutor)) {
  194. return;
  195. }
  196. driver.get(pages.javascriptPage);
  197. Object result = executeScript("return window.location;");
  198. assertTrue("result was: " + result + " (" + result.getClass() + ")", result instanceof Map);
  199. Map<String, Object> map = (Map<String, Object>) result;
  200. assertEquals("http:", map.get("protocol"));
  201. assertEquals(pages.javascriptPage, map.get("href"));
  202. }
  203. private static boolean compareLists(List<?> first, List<?> second) {
  204. if (first.size() != second.size()) {
  205. return false;
  206. }
  207. for (int i = 0; i < first.size(); ++i) {
  208. if (first.get(i) instanceof List<?>) {
  209. if (!compareLists((List<?>) first.get(i), (List<?>) second.get(i))) {
  210. return false;
  211. }
  212. } else {
  213. if (!first.get(i).equals(second.get(i))) {
  214. return false;
  215. }
  216. }
  217. }
  218. return true;
  219. }
  220. @JavascriptEnabled
  221. @Test
  222. public void testPassingAndReturningALongShouldReturnAWholeNumber() {
  223. if (!(driver instanceof JavascriptExecutor)) {
  224. return;
  225. }
  226. driver.get(pages.javascriptPage);
  227. Long expectedResult = 1L;
  228. Object result = executeScript("return arguments[0];", expectedResult);
  229. assertTrue("Expected result to be an Integer or Long but was a " +
  230. result.getClass(), result instanceof Integer || result instanceof Long);
  231. assertEquals(expectedResult.longValue(), result);
  232. }
  233. @JavascriptEnabled
  234. @Test
  235. public void testPassingAndReturningADoubleShouldReturnADecimal() {
  236. if (!(driver instanceof JavascriptExecutor)) {
  237. return;
  238. }
  239. driver.get(pages.javascriptPage);
  240. Double expectedResult = 1.2;
  241. Object result = executeScript("return arguments[0];", expectedResult);
  242. assertTrue("Expected result to be a Double or Float but was a " +
  243. result.getClass(), result instanceof Float || result instanceof Double);
  244. assertEquals(expectedResult.doubleValue(), result);
  245. }
  246. @JavascriptEnabled
  247. @Test
  248. public void testShouldThrowAnExceptionWhenTheJavascriptIsBad() {
  249. if (!(driver instanceof JavascriptExecutor)) {
  250. return;
  251. }
  252. driver.get(pages.xhtmlTestPage);
  253. try {
  254. executeScript("return squiggle();");
  255. fail("Expected an exception");
  256. } catch (Exception e) {
  257. // This is expected
  258. assertFalse(e.getMessage(), e.getMessage().startsWith("null "));
  259. }
  260. }
  261. @JavascriptEnabled
  262. @Test
  263. public void testShouldBeAbleToCallFunctionsDefinedOnThePage() {
  264. if (!(driver instanceof JavascriptExecutor)) {
  265. return;
  266. }
  267. driver.get(pages.javascriptPage);
  268. executeScript("displayMessage('I like cheese');");
  269. String text = driver.findElement(By.id("result")).getText();
  270. assertEquals("I like cheese", text.trim());
  271. }
  272. private Object executeScript(String script, Object... args) {
  273. return ((JavascriptExecutor) driver).executeScript(script, args);
  274. }
  275. @JavascriptEnabled
  276. @Test
  277. public void testShouldBeAbleToPassAStringAnAsArgument() {
  278. if (!(driver instanceof JavascriptExecutor)) {
  279. return;
  280. }
  281. driver.get(pages.javascriptPage);
  282. String value =
  283. (String) executeScript("return arguments[0] == 'fish' ? 'fish' : 'not fish';", "fish");
  284. assertEquals("fish", value);
  285. }
  286. @JavascriptEnabled
  287. @Test
  288. public void testShouldBeAbleToPassABooleanAsArgument() {
  289. if (!(driver instanceof JavascriptExecutor)) {
  290. return;
  291. }
  292. driver.get(pages.javascriptPage);
  293. boolean value = (Boolean) executeScript("return arguments[0] == true;", true);
  294. assertTrue(value);
  295. }
  296. @JavascriptEnabled
  297. @Test
  298. public void testShouldBeAbleToPassANumberAnAsArgument() {
  299. if (!(driver instanceof JavascriptExecutor)) {
  300. return;
  301. }
  302. driver.get(pages.javascriptPage);
  303. boolean value = (Boolean) executeScript("return arguments[0] == 1 ? true : false;", 1);
  304. assertTrue(value);
  305. }
  306. @JavascriptEnabled
  307. @Test
  308. public void testShouldBeAbleToPassAWebElementAsArgument() {
  309. if (!(driver instanceof JavascriptExecutor)) {
  310. return;
  311. }
  312. driver.get(pages.javascriptPage);
  313. WebElement button = driver.findElement(By.id("plainButton"));
  314. String value =
  315. (String) executeScript(
  316. "arguments[0]['flibble'] = arguments[0].getAttribute('id'); return arguments[0]['flibble'];",
  317. button);
  318. assertEquals("plainButton", value);
  319. }
  320. @JavascriptEnabled
  321. @Test
  322. public void testPassingArrayAsOnlyArgumentFlattensArray() {
  323. if (!(driver instanceof JavascriptExecutor)) {
  324. return;
  325. }
  326. driver.get(pages.javascriptPage);
  327. Object[] array = new Object[]{"zero", 1, true, 3.14159, false};
  328. String value = (String) executeScript("return arguments[0]", array);
  329. assertEquals(array[0], value);
  330. }
  331. @JavascriptEnabled
  332. @Ignore({OPERA, OPERA_MOBILE})
  333. @Test
  334. public void testShouldBeAbleToPassAnArrayAsAdditionalArgument() {
  335. if (!(driver instanceof JavascriptExecutor)) {
  336. return;
  337. }
  338. driver.get(pages.javascriptPage);
  339. Object[] array = new Object[]{"zero", 1, true, 3.14159, false};
  340. long length = (Long) executeScript("return arguments[1].length", "string", array);
  341. assertEquals(array.length, length);
  342. }
  343. @JavascriptEnabled
  344. @Test
  345. public void testShouldBeAbleToPassACollectionAsArgument() {
  346. if (!(driver instanceof JavascriptExecutor)) {
  347. return;
  348. }
  349. driver.get(pages.javascriptPage);
  350. Collection<Object> collection = new ArrayList<Object>();
  351. collection.add("Cheddar");
  352. collection.add("Brie");
  353. collection.add(7);
  354. long length = (Long) executeScript("return arguments[0].length", collection);
  355. assertEquals(collection.size(), length);
  356. collection = new HashSet<Object>();
  357. collection.add("Gouda");
  358. collection.add("Stilton");
  359. collection.add("Stilton");
  360. collection.add(true);
  361. length = (Long) executeScript("return arguments[0].length", collection);
  362. assertEquals(collection.size(), length);
  363. }
  364. @JavascriptEnabled
  365. @Test
  366. public void testShouldThrowAnExceptionIfAnArgumentIsNotValid() {
  367. if (!(driver instanceof JavascriptExecutor)) {
  368. return;
  369. }
  370. driver.get(pages.javascriptPage);
  371. try {
  372. executeScript("return arguments[0];", driver);
  373. fail("Exception should have been thrown");
  374. } catch (IllegalArgumentException e) {
  375. // this is expected
  376. }
  377. }
  378. @JavascriptEnabled
  379. @Test
  380. public void testShouldBeAbleToPassInMoreThanOneArgument() {
  381. if (!(driver instanceof JavascriptExecutor)) {
  382. return;
  383. }
  384. driver.get(pages.javascriptPage);
  385. String result = (String) executeScript("return arguments[0] + arguments[1];", "one", "two");
  386. assertEquals("onetwo", result);
  387. }
  388. @JavascriptEnabled
  389. @Test
  390. @Ignore({OPERA, OPERA_MOBILE})
  391. public void testShouldBeAbleToGrabTheBodyOfFrameOnceSwitchedTo() {
  392. driver.get(pages.richTextPage);
  393. driver.switchTo().frame("editFrame");
  394. WebElement body =
  395. (WebElement) ((JavascriptExecutor) driver).executeScript("return document.body");
  396. String text = body.getText();
  397. driver.switchTo().defaultContent();
  398. assertEquals("", text);
  399. }
  400. @SuppressWarnings("unchecked")
  401. @JavascriptEnabled
  402. @Test
  403. public void testShouldBeAbleToReturnAnArrayOfWebElements() {
  404. driver.get(pages.formPage);
  405. List<WebElement> items = (List<WebElement>) ((JavascriptExecutor) driver)
  406. .executeScript("return document.getElementsByName('snack');");
  407. assertFalse(items.isEmpty());
  408. }
  409. @JavascriptEnabled
  410. @Test
  411. public void testJavascriptStringHandlingShouldWorkAsExpected() {
  412. driver.get(pages.javascriptPage);
  413. String value = (String) executeScript("return '';");
  414. assertEquals("", value);
  415. value = (String) executeScript("return undefined;");
  416. assertNull(value);
  417. value = (String) executeScript("return ' '");
  418. assertEquals(" ", value);
  419. }
  420. @JavascriptEnabled
  421. @Ignore(OPERA)
  422. @Test
  423. public void testShouldBeAbleToExecuteABigChunkOfJavascriptCode() throws IOException {
  424. driver.get(pages.javascriptPage);
  425. File jqueryFile = InProject.locate("common/src/web/jquery-1.3.2.js");
  426. String jquery = Files.toString(jqueryFile, Charset.forName("US-ASCII"));
  427. assertTrue("The javascript code should be at least 50 KB.", jquery.length() > 50000);
  428. // This should not throw an exception ...
  429. executeScript(jquery);
  430. }
  431. @SuppressWarnings("unchecked")
  432. @JavascriptEnabled
  433. @Test
  434. public void testShouldBeAbleToExecuteScriptAndReturnElementsList() {
  435. driver.get(pages.formPage);
  436. String scriptToExec = "return document.getElementsByName('snack');";
  437. List<WebElement> resultsList = (List<WebElement>) ((JavascriptExecutor) driver)
  438. .executeScript(scriptToExec);
  439. assertFalse(resultsList.isEmpty());
  440. }
  441. @JavascriptEnabled
  442. @NeedsFreshDriver
  443. @NoDriverAfterTest
  444. @Ignore(reason = "Failure indicates hang condition, which would break the" +
  445. " test suite. Really needs a timeout set.")
  446. @Test
  447. public void testShouldThrowExceptionIfExecutingOnNoPage() {
  448. try {
  449. ((JavascriptExecutor) driver).executeScript("return 1;");
  450. } catch (WebDriverException e) {
  451. // Expected
  452. return;
  453. }
  454. fail("Expected exception to be thrown");
  455. }
  456. @JavascriptEnabled
  457. @Ignore(OPERA)
  458. @Test
  459. public void testShouldBeAbleToCreateAPersistentValue() {
  460. driver.get(pages.formPage);
  461. executeScript("document.alerts = []");
  462. executeScript("document.alerts.push('hello world');");
  463. String text = (String) executeScript("return document.alerts.shift()");
  464. assertEquals("hello world", text);
  465. }
  466. @JavascriptEnabled
  467. @Ignore(OPERA)
  468. @Test
  469. public void testCanHandleAnArrayOfElementsAsAnObjectArray() {
  470. driver.get(pages.formPage);
  471. List<WebElement> forms = driver.findElements(By.tagName("form"));
  472. Object[] args = new Object[]{forms};
  473. String name = (String) ((JavascriptExecutor) driver).executeScript(
  474. "return arguments[0][0].tagName", args);
  475. assertEquals("form", name.toLowerCase());
  476. }
  477. @JavascriptEnabled
  478. @Ignore(value = {ANDROID, HTMLUNIT, OPERA, OPERA_MOBILE},
  479. reason = "Opera and HtmlUnit obey the method contract. Android not tested")
  480. @Test
  481. public void testCanPassAMapAsAParameter() {
  482. driver.get(pages.simpleTestPage);
  483. List<Integer> nums = ImmutableList.of(1, 2);
  484. Map<String, Object> args = ImmutableMap.of("bar", "test", "foo", nums);
  485. Object res = ((JavascriptExecutor) driver).executeScript("return arguments[0]['foo'][1]", args);
  486. assertEquals(2, ((Number) res).intValue());
  487. }
  488. }