|
| 1 | +// Copyright 2014 Selenium committers |
| 2 | +// Copyright 2014 Software Freedom Conservancy |
| 3 | +// |
| 4 | +// Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | +// you may not use this file except in compliance with the License. |
| 6 | +// You may obtain a copy of the License at |
| 7 | +// |
| 8 | +// http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +// |
| 10 | +// Unless required by applicable law or agreed to in writing, software |
| 11 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | +// See the License for the specific language governing permissions and |
| 14 | +// limitations under the License. |
| 15 | + |
| 16 | +'use strict'; |
| 17 | + |
| 18 | +var path = require('path'); |
| 19 | + |
| 20 | +var webdriver = require('..'), |
| 21 | + By = webdriver.By, |
| 22 | + assert = require('../testing/assert'), |
| 23 | + test = require('../lib/test'); |
| 24 | + |
| 25 | + |
| 26 | +test.suite(function(env) { |
| 27 | + var driver; |
| 28 | + |
| 29 | + test.before(function() { |
| 30 | + driver = env.builder().build(); |
| 31 | + }); |
| 32 | + |
| 33 | + test.after(function() { |
| 34 | + driver.quit(); |
| 35 | + }); |
| 36 | + |
| 37 | + test.beforeEach(function() { |
| 38 | + driver.get('data:text/html,<html><h1>' + path.basename(__filename) + |
| 39 | + '</h1></html>'); |
| 40 | + }); |
| 41 | + |
| 42 | + describe('executeScript', function() { |
| 43 | + var shouldHaveFailed = new Error('Should have failed'); |
| 44 | + |
| 45 | + test.it('fails if script throws', function() { |
| 46 | + execute('throw new Error("boom")') |
| 47 | + .then(function() { throw shoudlHaveFailed; }) |
| 48 | + .thenCatch(function(e) { |
| 49 | + // The java WebDriver server adds a bunch of crap to error messages. |
| 50 | + assert(e.message).matches(/.*boom.*/); |
| 51 | + }); |
| 52 | + }); |
| 53 | + |
| 54 | + test.it('fails if script does not parse', function() { |
| 55 | + execute('throw function\\*') |
| 56 | + .then(function() { throw shoudlHaveFailed; }) |
| 57 | + .thenCatch(function(e) { |
| 58 | + assert(e).not.equalTo(shouldHaveFailed); |
| 59 | + }); |
| 60 | + }); |
| 61 | + |
| 62 | + describe('scripts', function() { |
| 63 | + test.it('do not pollute the global scope', function() { |
| 64 | + execute('var x = 1;'); |
| 65 | + assert(execute('return typeof x;')).equalTo('undefined'); |
| 66 | + }); |
| 67 | + |
| 68 | + test.it('can set global variables', function() { |
| 69 | + execute('window.x = 1234;'); |
| 70 | + assert(execute('return x;')).equalTo(1234); |
| 71 | + }); |
| 72 | + |
| 73 | + test.it('may be defined as a function expression', function() { |
| 74 | + assert(execute(function() { |
| 75 | + return 1234 + 'abc'; |
| 76 | + })).equalTo('1234abc'); |
| 77 | + }); |
| 78 | + }); |
| 79 | + |
| 80 | + describe('return values', function() { |
| 81 | + |
| 82 | + test.it('returns undefined as null', function() { |
| 83 | + assert(execute('var x; return x;')).isNull(); |
| 84 | + }); |
| 85 | + |
| 86 | + test.it('can return null', function() { |
| 87 | + assert(execute('return null;')).isNull(); |
| 88 | + }); |
| 89 | + |
| 90 | + test.it('can return numbers', function() { |
| 91 | + assert(execute('return 1234')).equalTo(1234); |
| 92 | + assert(execute('return 3.1456')).equalTo(3.1456); |
| 93 | + }); |
| 94 | + |
| 95 | + test.it('can return strings', function() { |
| 96 | + assert(execute('return "hello"')).equalTo('hello'); |
| 97 | + }); |
| 98 | + |
| 99 | + test.it('can return booleans', function() { |
| 100 | + assert(execute('return true')).equalTo(true); |
| 101 | + assert(execute('return false')).equalTo(false); |
| 102 | + }); |
| 103 | + |
| 104 | + test.it('can return an array of primitives', function() { |
| 105 | + execute('var x; return [1, false, null, 3.14, x]') |
| 106 | + .then(verifyJson([1, false, null, 3.14, null])); |
| 107 | + }); |
| 108 | + |
| 109 | + test.it('can return nested arrays', function() { |
| 110 | + execute('return [[1, 2, [3]]]') |
| 111 | + .then(verifyJson([[1, 2, [3]]])); |
| 112 | + }); |
| 113 | + |
| 114 | + test.it('can return object literals', function() { |
| 115 | + execute('return {}').then(verifyJson({})); |
| 116 | + execute('return {a: 1, b: false, c: null}').then(function(result) { |
| 117 | + verifyJson(['a', 'b', 'c'])(Object.keys(result).sort()); |
| 118 | + assert(result.a).equalTo(1); |
| 119 | + assert(result.b).equalTo(false); |
| 120 | + assert(result.c).isNull(); |
| 121 | + }); |
| 122 | + }); |
| 123 | + |
| 124 | + test.it('can return complex object literals', function() { |
| 125 | + execute('return {a:{b: "hello"}}').then(verifyJson({a:{b: 'hello'}})); |
| 126 | + }); |
| 127 | + |
| 128 | + test.it('can return dom elements as web elements', function() { |
| 129 | + execute('return document.getElementsByTagName("h1")[0]') |
| 130 | + .then(function(result) { |
| 131 | + assert(result).instanceOf(webdriver.WebElement); |
| 132 | + assert(result.getText()).equalTo(path.basename(__filename)); |
| 133 | + }); |
| 134 | + }); |
| 135 | + |
| 136 | + test.it('can return array of dom elements', function() { |
| 137 | + driver.get('data:text/html,<!DOCTYPE html>' + |
| 138 | + '<h1>' + path.basename(__filename) + '</h1>' + |
| 139 | + '<h1>Hello, world!</h1>'); |
| 140 | + execute('var nodes = document.getElementsByTagName("h1");' + |
| 141 | + 'return [nodes[0], nodes[1]];') |
| 142 | + .then(function(result) { |
| 143 | + assert(result.length).equalTo(2); |
| 144 | + |
| 145 | + assert(result[0]).instanceOf(webdriver.WebElement); |
| 146 | + assert(result[0].getText()).equalTo(path.basename(__filename)); |
| 147 | + |
| 148 | + assert(result[1]).instanceOf(webdriver.WebElement); |
| 149 | + assert(result[1].getText()).equalTo('Hello, world!'); |
| 150 | + }); |
| 151 | + }); |
| 152 | + |
| 153 | + test.it('can return a NodeList as an array of web elements', function() { |
| 154 | + driver.get('data:text/html,<!DOCTYPE html>' + |
| 155 | + '<h1>' + path.basename(__filename) + '</h1>' + |
| 156 | + '<h1>Hello, world!</h1>'); |
| 157 | + execute('return document.getElementsByTagName("h1");') |
| 158 | + .then(function(result) { |
| 159 | + assert(result.length).equalTo(2); |
| 160 | + |
| 161 | + assert(result[0]).instanceOf(webdriver.WebElement); |
| 162 | + assert(result[0].getText()).equalTo(path.basename(__filename)); |
| 163 | + |
| 164 | + assert(result[1]).instanceOf(webdriver.WebElement); |
| 165 | + assert(result[1].getText()).equalTo('Hello, world!'); |
| 166 | + }); |
| 167 | + }); |
| 168 | + |
| 169 | + test.it('can return object literal with element property', function() { |
| 170 | + execute('return {a: document.body}').then(function(result) { |
| 171 | + assert(result.a).instanceOf(webdriver.WebElement); |
| 172 | + assert(result.a.getTagName()).equalTo('body'); |
| 173 | + }); |
| 174 | + }); |
| 175 | + }); |
| 176 | + |
| 177 | + describe('parameters', function() { |
| 178 | + test.it('can pass numeric arguments', function() { |
| 179 | + assert(execute('return arguments[0]', 12)).equalTo(12); |
| 180 | + assert(execute('return arguments[0]', 3.14)).equalTo(3.14); |
| 181 | + }); |
| 182 | + |
| 183 | + test.it('can pass boolean arguments', function() { |
| 184 | + assert(execute('return arguments[0]', true)).equalTo(true); |
| 185 | + assert(execute('return arguments[0]', false)).equalTo(false); |
| 186 | + }); |
| 187 | + |
| 188 | + test.it('can pass string arguments', function() { |
| 189 | + assert(execute('return arguments[0]', 'hi')).equalTo('hi'); |
| 190 | + }); |
| 191 | + |
| 192 | + test.it('can pass null arguments', function() { |
| 193 | + assert(execute('return arguments[0] === null', null)).equalTo(true); |
| 194 | + assert(execute('return arguments[0]', null)).equalTo(null); |
| 195 | + }); |
| 196 | + |
| 197 | + test.it('passes undefined as a null argument', function() { |
| 198 | + var x; |
| 199 | + assert(execute('return arguments[0] === null', x)).equalTo(true); |
| 200 | + assert(execute('return arguments[0]', x)).equalTo(null); |
| 201 | + }); |
| 202 | + |
| 203 | + test.it('can pass multiple arguments', function() { |
| 204 | + assert(execute('return arguments.length')).equalTo(0); |
| 205 | + assert(execute('return arguments.length', 1, 'a', false)).equalTo(3); |
| 206 | + }); |
| 207 | + |
| 208 | + test.it('can return arguments object as array', function() { |
| 209 | + execute('return arguments', 1, 'a', false).then(function(val) { |
| 210 | + assert(val.length).equalTo(3); |
| 211 | + assert(val[0]).equalTo(1); |
| 212 | + assert(val[1]).equalTo('a'); |
| 213 | + assert(val[2]).equalTo(false); |
| 214 | + }); |
| 215 | + }); |
| 216 | + |
| 217 | + test.it('can pass object literal', function() { |
| 218 | + execute( |
| 219 | + 'return [typeof arguments[0], arguments[0].a]', {a: 'hello'}) |
| 220 | + .then(function(result) { |
| 221 | + assert(result[0]).equalTo('object'); |
| 222 | + assert(result[1]).equalTo('hello'); |
| 223 | + }); |
| 224 | + }); |
| 225 | + |
| 226 | + test.it('WebElement arguments are passed as DOM elements', function() { |
| 227 | + var el = driver.findElement(By.tagName('h1')); |
| 228 | + assert(execute('return arguments[0].tagName.toLowerCase();', el)) |
| 229 | + .equalTo('h1'); |
| 230 | + }); |
| 231 | + |
| 232 | + test.it('can pass array containing object literals', function() { |
| 233 | + execute('return arguments[0]', [{color: "red"}]).then(function(result) { |
| 234 | + assert(result.length).equalTo(1); |
| 235 | + assert(result[0].color).equalTo('red'); |
| 236 | + }); |
| 237 | + }); |
| 238 | + }); |
| 239 | + }); |
| 240 | + |
| 241 | + function verifyJson(expected) { |
| 242 | + return function(actual) { |
| 243 | + assert(JSON.stringify(actual)).equalTo(JSON.stringify(expected)); |
| 244 | + }; |
| 245 | + } |
| 246 | + |
| 247 | + function execute() { |
| 248 | + return driver.executeScript.apply(driver, arguments); |
| 249 | + } |
| 250 | +}); |
0 commit comments