Deployed the page to Github Pages.
This commit is contained in:
parent
1d79754e93
commit
2c89899458
62797 changed files with 6551425 additions and 15279 deletions
52
node_modules/selenium-webdriver/test/actions_test.js
generated
vendored
Normal file
52
node_modules/selenium-webdriver/test/actions_test.js
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var Browser = require('..').Browser,
|
||||
By = require('..').By,
|
||||
until = require('..').until,
|
||||
test = require('../lib/test'),
|
||||
fileServer = require('../lib/test/fileserver');
|
||||
|
||||
|
||||
test.suite(function(env) {
|
||||
var driver;
|
||||
test.beforeEach(function*() { driver = yield env.builder().build(); });
|
||||
test.afterEach(function() { return driver.quit(); });
|
||||
|
||||
test.ignore(
|
||||
env.browsers(Browser.FIREFOX, Browser.PHANTOM_JS, Browser.SAFARI)).
|
||||
describe('WebDriver.actions()', function() {
|
||||
|
||||
test.it('can move to and click element in an iframe', function*() {
|
||||
yield driver.get(fileServer.whereIs('click_tests/click_in_iframe.html'));
|
||||
|
||||
yield driver.wait(until.elementLocated(By.id('ifr')), 5000)
|
||||
.then(frame => driver.switchTo().frame(frame));
|
||||
|
||||
let link = yield driver.findElement(By.id('link'));
|
||||
yield driver.actions()
|
||||
.mouseMove(link)
|
||||
.click()
|
||||
.perform();
|
||||
|
||||
return driver.wait(until.titleIs('Submitted Successfully!'), 5000);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
227
node_modules/selenium-webdriver/test/chrome/options_test.js
generated
vendored
Normal file
227
node_modules/selenium-webdriver/test/chrome/options_test.js
generated
vendored
Normal file
|
@ -0,0 +1,227 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
var webdriver = require('../..'),
|
||||
chrome = require('../../chrome'),
|
||||
symbols = require('../../lib/symbols'),
|
||||
proxy = require('../../proxy'),
|
||||
assert = require('../../testing/assert');
|
||||
|
||||
var test = require('../../lib/test');
|
||||
|
||||
|
||||
describe('chrome.Options', function() {
|
||||
describe('fromCapabilities', function() {
|
||||
|
||||
it('should return a new Options instance if none were defined',
|
||||
function() {
|
||||
var options = chrome.Options.fromCapabilities(
|
||||
new webdriver.Capabilities());
|
||||
assert(options).instanceOf(chrome.Options);
|
||||
});
|
||||
|
||||
it('should return options instance if present', function() {
|
||||
var options = new chrome.Options();
|
||||
var caps = options.toCapabilities();
|
||||
assert(caps).instanceOf(webdriver.Capabilities);
|
||||
assert(chrome.Options.fromCapabilities(caps)).equalTo(options);
|
||||
});
|
||||
|
||||
it('should rebuild options from wire representation', function() {
|
||||
var expectedExtension = fs.readFileSync(__filename, 'base64');
|
||||
var caps = webdriver.Capabilities.chrome().set('chromeOptions', {
|
||||
args: ['a', 'b'],
|
||||
extensions: [__filename],
|
||||
binary: 'binaryPath',
|
||||
logPath: 'logFilePath',
|
||||
detach: true,
|
||||
localState: 'localStateValue',
|
||||
prefs: 'prefsValue'
|
||||
});
|
||||
|
||||
var options = chrome.Options.fromCapabilities(caps);
|
||||
var json = options[symbols.serialize]();
|
||||
|
||||
assert(json.args.length).equalTo(2);
|
||||
assert(json.args[0]).equalTo('a');
|
||||
assert(json.args[1]).equalTo('b');
|
||||
assert(json.extensions.length).equalTo(1);
|
||||
assert(json.extensions[0]).equalTo(expectedExtension);
|
||||
assert(json.binary).equalTo('binaryPath');
|
||||
assert(json.logPath).equalTo('logFilePath');
|
||||
assert(json.detach).equalTo(true);
|
||||
assert(json.localState).equalTo('localStateValue');
|
||||
assert(json.prefs).equalTo('prefsValue');
|
||||
});
|
||||
|
||||
it('should rebuild options from incomplete wire representation',
|
||||
function() {
|
||||
var caps = webdriver.Capabilities.chrome().set('chromeOptions', {
|
||||
logPath: 'logFilePath'
|
||||
});
|
||||
|
||||
var options = chrome.Options.fromCapabilities(caps);
|
||||
var json = options[symbols.serialize]();
|
||||
assert(json.args).isUndefined();
|
||||
assert(json.binary).isUndefined();
|
||||
assert(json.detach).isUndefined();
|
||||
assert(json.excludeSwitches).isUndefined();
|
||||
assert(json.extensions).isUndefined();
|
||||
assert(json.localState).isUndefined();
|
||||
assert(json.logPath).equalTo('logFilePath');
|
||||
assert(json.prefs).isUndefined();
|
||||
assert(json.minidumpPath).isUndefined();
|
||||
assert(json.mobileEmulation).isUndefined();
|
||||
assert(json.perfLoggingPrefs).isUndefined();
|
||||
});
|
||||
|
||||
it('should extract supported WebDriver capabilities', function() {
|
||||
var proxyPrefs = proxy.direct();
|
||||
var logPrefs = {};
|
||||
var caps = webdriver.Capabilities.chrome().
|
||||
set(webdriver.Capability.PROXY, proxyPrefs).
|
||||
set(webdriver.Capability.LOGGING_PREFS, logPrefs);
|
||||
|
||||
var options = chrome.Options.fromCapabilities(caps);
|
||||
assert(options.proxy_).equalTo(proxyPrefs);
|
||||
assert(options.logPrefs_).equalTo(logPrefs);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addArguments', function() {
|
||||
it('takes var_args', function() {
|
||||
var options = new chrome.Options();
|
||||
assert(options[symbols.serialize]().args).isUndefined();
|
||||
|
||||
options.addArguments('a', 'b');
|
||||
var json = options[symbols.serialize]();
|
||||
assert(json.args.length).equalTo(2);
|
||||
assert(json.args[0]).equalTo('a');
|
||||
assert(json.args[1]).equalTo('b');
|
||||
});
|
||||
|
||||
it('flattens input arrays', function() {
|
||||
var options = new chrome.Options();
|
||||
assert(options[symbols.serialize]().args).isUndefined();
|
||||
|
||||
options.addArguments(['a', 'b'], 'c', [1, 2], 3);
|
||||
var json = options[symbols.serialize]();
|
||||
assert(json.args.length).equalTo(6);
|
||||
assert(json.args[0]).equalTo('a');
|
||||
assert(json.args[1]).equalTo('b');
|
||||
assert(json.args[2]).equalTo('c');
|
||||
assert(json.args[3]).equalTo(1);
|
||||
assert(json.args[4]).equalTo(2);
|
||||
assert(json.args[5]).equalTo(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('addExtensions', function() {
|
||||
it('takes var_args', function() {
|
||||
var options = new chrome.Options();
|
||||
assert(options.extensions_.length).equalTo(0);
|
||||
|
||||
options.addExtensions('a', 'b');
|
||||
assert(options.extensions_.length).equalTo(2);
|
||||
assert(options.extensions_[0]).equalTo('a');
|
||||
assert(options.extensions_[1]).equalTo('b');
|
||||
});
|
||||
|
||||
it('flattens input arrays', function() {
|
||||
var options = new chrome.Options();
|
||||
assert(options.extensions_.length).equalTo(0);
|
||||
|
||||
options.addExtensions(['a', 'b'], 'c', [1, 2], 3);
|
||||
assert(options.extensions_.length).equalTo(6);
|
||||
assert(options.extensions_[0]).equalTo('a');
|
||||
assert(options.extensions_[1]).equalTo('b');
|
||||
assert(options.extensions_[2]).equalTo('c');
|
||||
assert(options.extensions_[3]).equalTo(1);
|
||||
assert(options.extensions_[4]).equalTo(2);
|
||||
assert(options.extensions_[5]).equalTo(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('serialize', function() {
|
||||
it('base64 encodes extensions', function() {
|
||||
var expected = fs.readFileSync(__filename, 'base64');
|
||||
var wire = new chrome.Options()
|
||||
.addExtensions(__filename)
|
||||
[symbols.serialize]();
|
||||
assert(wire.extensions.length).equalTo(1);
|
||||
assert(wire.extensions[0]).equalTo(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('toCapabilities', function() {
|
||||
it('returns a new capabilities object if one is not provided', function() {
|
||||
var options = new chrome.Options();
|
||||
var caps = options.toCapabilities();
|
||||
assert(caps.get('browserName')).equalTo('chrome');
|
||||
assert(caps.get('chromeOptions')).equalTo(options);
|
||||
});
|
||||
|
||||
it('adds to input capabilities object', function() {
|
||||
var caps = webdriver.Capabilities.firefox();
|
||||
var options = new chrome.Options();
|
||||
assert(options.toCapabilities(caps)).equalTo(caps);
|
||||
assert(caps.get('browserName')).equalTo('firefox');
|
||||
assert(caps.get('chromeOptions')).equalTo(options);
|
||||
});
|
||||
|
||||
it('sets generic driver capabilities', function() {
|
||||
var proxyPrefs = {};
|
||||
var loggingPrefs = {};
|
||||
var options = new chrome.Options().
|
||||
setLoggingPrefs(loggingPrefs).
|
||||
setProxy(proxyPrefs);
|
||||
|
||||
var caps = options.toCapabilities();
|
||||
assert(caps.get('proxy')).equalTo(proxyPrefs);
|
||||
assert(caps.get('loggingPrefs')).equalTo(loggingPrefs);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.suite(function(env) {
|
||||
var driver;
|
||||
|
||||
test.afterEach(function() {
|
||||
return driver.quit();
|
||||
});
|
||||
|
||||
describe('Chrome options', function() {
|
||||
test.it('can start Chrome with custom args', function*() {
|
||||
var options = new chrome.Options().
|
||||
addArguments('user-agent=foo;bar');
|
||||
|
||||
driver = yield env.builder()
|
||||
.setChromeOptions(options)
|
||||
.build();
|
||||
|
||||
yield driver.get(test.Pages.ajaxyPage);
|
||||
|
||||
var userAgent =
|
||||
yield driver.executeScript('return window.navigator.userAgent');
|
||||
assert(userAgent).equalTo('foo;bar');
|
||||
});
|
||||
});
|
||||
}, {browsers: ['chrome']});
|
45
node_modules/selenium-webdriver/test/chrome/service_test.js
generated
vendored
Normal file
45
node_modules/selenium-webdriver/test/chrome/service_test.js
generated
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var webdriver = require('../..'),
|
||||
chrome = require('../../chrome'),
|
||||
assert = require('../../testing/assert');
|
||||
|
||||
var test = require('../../lib/test');
|
||||
|
||||
|
||||
test.suite(function(env) {
|
||||
describe('chromedriver', function() {
|
||||
var service;
|
||||
test.afterEach(function() {
|
||||
if (service) {
|
||||
return service.kill();
|
||||
}
|
||||
});
|
||||
|
||||
test.it('can be started on a custom path', function() {
|
||||
service = new chrome.ServiceBuilder()
|
||||
.setPath('/foo/bar/baz')
|
||||
.build();
|
||||
return service.start().then(function(url) {
|
||||
assert(url).endsWith('/foo/bar/baz');
|
||||
});
|
||||
});
|
||||
});
|
||||
}, {browsers: ['chrome']});
|
214
node_modules/selenium-webdriver/test/cookie_test.js
generated
vendored
Normal file
214
node_modules/selenium-webdriver/test/cookie_test.js
generated
vendored
Normal file
|
@ -0,0 +1,214 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert'),
|
||||
url = require('url');
|
||||
|
||||
var test = require('../lib/test'),
|
||||
fileserver = require('../lib/test/fileserver'),
|
||||
Browser = require('..').Browser,
|
||||
Pages = test.Pages;
|
||||
|
||||
|
||||
test.suite(function(env) {
|
||||
var driver;
|
||||
|
||||
test.before(function*() {
|
||||
driver = yield env.builder().build();
|
||||
});
|
||||
|
||||
test.after(function() {
|
||||
return driver.quit();
|
||||
});
|
||||
|
||||
// Cookie handling is broken.
|
||||
test.ignore(env.browsers(Browser.PHANTOM_JS, Browser.SAFARI)).
|
||||
describe('Cookie Management;', function() {
|
||||
|
||||
test.beforeEach(function*() {
|
||||
yield driver.get(fileserver.Pages.ajaxyPage);
|
||||
yield driver.manage().deleteAllCookies();
|
||||
return assertHasCookies();
|
||||
});
|
||||
|
||||
test.it('can add new cookies', function*() {
|
||||
var cookie = createCookieSpec();
|
||||
|
||||
yield driver.manage().addCookie(cookie);
|
||||
yield driver.manage().getCookie(cookie.name).then(function(actual) {
|
||||
assert.equal(actual.value, cookie.value);
|
||||
});
|
||||
});
|
||||
|
||||
test.it('can get all cookies', function*() {
|
||||
var cookie1 = createCookieSpec();
|
||||
var cookie2 = createCookieSpec();
|
||||
|
||||
yield driver.manage().addCookie(cookie1);
|
||||
yield driver.manage().addCookie(cookie2);
|
||||
|
||||
return assertHasCookies(cookie1, cookie2);
|
||||
});
|
||||
|
||||
test.ignore(env.browsers(Browser.IE)).
|
||||
it('only returns cookies visible to the current page', function*() {
|
||||
var cookie1 = createCookieSpec();
|
||||
|
||||
yield driver.manage().addCookie(cookie1);
|
||||
|
||||
var pageUrl = fileserver.whereIs('page/1');
|
||||
var cookie2 = createCookieSpec({
|
||||
path: url.parse(pageUrl).pathname
|
||||
});
|
||||
yield driver.get(pageUrl);
|
||||
yield driver.manage().addCookie(cookie2);
|
||||
yield assertHasCookies(cookie1, cookie2);
|
||||
|
||||
yield driver.get(fileserver.Pages.ajaxyPage);
|
||||
yield assertHasCookies(cookie1);
|
||||
|
||||
yield driver.get(pageUrl);
|
||||
yield assertHasCookies(cookie1, cookie2);
|
||||
});
|
||||
|
||||
test.it('can delete all cookies', function*() {
|
||||
var cookie1 = createCookieSpec();
|
||||
var cookie2 = createCookieSpec();
|
||||
|
||||
yield driver.executeScript(
|
||||
'document.cookie = arguments[0] + "=" + arguments[1];' +
|
||||
'document.cookie = arguments[2] + "=" + arguments[3];',
|
||||
cookie1.name, cookie1.value, cookie2.name, cookie2.value);
|
||||
yield assertHasCookies(cookie1, cookie2);
|
||||
|
||||
yield driver.manage().deleteAllCookies();
|
||||
yield assertHasCookies();
|
||||
});
|
||||
|
||||
test.it('can delete cookies by name', function*() {
|
||||
var cookie1 = createCookieSpec();
|
||||
var cookie2 = createCookieSpec();
|
||||
|
||||
yield driver.executeScript(
|
||||
'document.cookie = arguments[0] + "=" + arguments[1];' +
|
||||
'document.cookie = arguments[2] + "=" + arguments[3];',
|
||||
cookie1.name, cookie1.value, cookie2.name, cookie2.value);
|
||||
yield assertHasCookies(cookie1, cookie2);
|
||||
|
||||
yield driver.manage().deleteCookie(cookie1.name);
|
||||
yield assertHasCookies(cookie2);
|
||||
});
|
||||
|
||||
test.it('should only delete cookie with exact name', function*() {
|
||||
var cookie1 = createCookieSpec();
|
||||
var cookie2 = createCookieSpec();
|
||||
var cookie3 = {name: cookie1.name + 'xx', value: cookie1.value};
|
||||
|
||||
yield driver.executeScript(
|
||||
'document.cookie = arguments[0] + "=" + arguments[1];' +
|
||||
'document.cookie = arguments[2] + "=" + arguments[3];' +
|
||||
'document.cookie = arguments[4] + "=" + arguments[5];',
|
||||
cookie1.name, cookie1.value, cookie2.name, cookie2.value,
|
||||
cookie3.name, cookie3.value);
|
||||
yield assertHasCookies(cookie1, cookie2, cookie3);
|
||||
|
||||
yield driver.manage().deleteCookie(cookie1.name);
|
||||
yield assertHasCookies(cookie2, cookie3);
|
||||
});
|
||||
|
||||
test.it('can delete cookies set higher in the path', function*() {
|
||||
var cookie = createCookieSpec();
|
||||
var childUrl = fileserver.whereIs('child/childPage.html');
|
||||
var grandchildUrl = fileserver.whereIs(
|
||||
'child/grandchild/grandchildPage.html');
|
||||
|
||||
yield driver.get(childUrl);
|
||||
yield driver.manage().addCookie(cookie);
|
||||
yield assertHasCookies(cookie);
|
||||
|
||||
yield driver.get(grandchildUrl);
|
||||
yield assertHasCookies(cookie);
|
||||
|
||||
yield driver.manage().deleteCookie(cookie.name);
|
||||
yield assertHasCookies();
|
||||
|
||||
yield driver.get(childUrl);
|
||||
yield assertHasCookies();
|
||||
});
|
||||
|
||||
test.ignore(env.browsers(
|
||||
Browser.ANDROID,
|
||||
Browser.FIREFOX,
|
||||
'legacy-' + Browser.FIREFOX,
|
||||
Browser.IE)).
|
||||
it('should retain cookie expiry', function*() {
|
||||
let expirationDelay = 5 * 1000;
|
||||
let expiry = new Date(Date.now() + expirationDelay);
|
||||
let cookie = createCookieSpec({expiry});
|
||||
|
||||
yield driver.manage().addCookie(cookie);
|
||||
yield driver.manage().getCookie(cookie.name).then(function(actual) {
|
||||
assert.equal(actual.value, cookie.value);
|
||||
// expiry times are exchanged in seconds since January 1, 1970 UTC.
|
||||
assert.equal(actual.expiry, Math.floor(expiry.getTime() / 1000));
|
||||
});
|
||||
|
||||
yield driver.sleep(expirationDelay);
|
||||
yield assertHasCookies();
|
||||
});
|
||||
});
|
||||
|
||||
function createCookieSpec(opt_options) {
|
||||
let spec = {
|
||||
name: getRandomString(),
|
||||
value: getRandomString()
|
||||
};
|
||||
if (opt_options) {
|
||||
spec = Object.assign(spec, opt_options);
|
||||
}
|
||||
return spec;
|
||||
}
|
||||
|
||||
function buildCookieMap(cookies) {
|
||||
var map = {};
|
||||
cookies.forEach(function(cookie) {
|
||||
map[cookie.name] = cookie;
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
function assertHasCookies(...expected) {
|
||||
return driver.manage().getCookies().then(function(cookies) {
|
||||
assert.equal(cookies.length, expected.length,
|
||||
'Wrong # of cookies.' +
|
||||
'\n Expected: ' + JSON.stringify(expected) +
|
||||
'\n Was : ' + JSON.stringify(cookies));
|
||||
|
||||
var map = buildCookieMap(cookies);
|
||||
for (var i = 0; i < expected.length; ++i) {
|
||||
assert.equal(expected[i].value, map[expected[i].name].value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getRandomString() {
|
||||
var x = 1234567890;
|
||||
return Math.floor(Math.random() * x).toString(36);
|
||||
}
|
||||
});
|
426
node_modules/selenium-webdriver/test/element_finding_test.js
generated
vendored
Normal file
426
node_modules/selenium-webdriver/test/element_finding_test.js
generated
vendored
Normal file
|
@ -0,0 +1,426 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var fail = require('assert').fail;
|
||||
|
||||
var Browser = require('..').Browser,
|
||||
By = require('..').By,
|
||||
error = require('..').error,
|
||||
until = require('..').until,
|
||||
promise = require('../lib/promise'),
|
||||
test = require('../lib/test'),
|
||||
assert = require('../testing/assert'),
|
||||
Pages = test.Pages;
|
||||
|
||||
|
||||
test.suite(function(env) {
|
||||
var browsers = env.browsers;
|
||||
|
||||
var driver;
|
||||
|
||||
test.before(function*() {
|
||||
driver = yield env.builder().build();
|
||||
});
|
||||
|
||||
after(function() {
|
||||
return driver.quit();
|
||||
});
|
||||
|
||||
describe('finding elements', function() {
|
||||
test.it(
|
||||
'should work after loading multiple pages in a row',
|
||||
function*() {
|
||||
yield driver.get(Pages.formPage);
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
yield driver.findElement(By.linkText('click me')).click();
|
||||
yield driver.wait(until.titleIs('We Arrive Here'), 5000);
|
||||
});
|
||||
|
||||
describe('By.id()', function() {
|
||||
test.it('should work', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
yield driver.findElement(By.id('linkId')).click();
|
||||
yield driver.wait(until.titleIs('We Arrive Here'), 5000);
|
||||
});
|
||||
|
||||
test.it('should fail if ID not present on page', function*() {
|
||||
yield driver.get(Pages.formPage);
|
||||
return driver.findElement(By.id('nonExistantButton')).
|
||||
then(fail, function(e) {
|
||||
assert(e).instanceOf(error.NoSuchElementError);
|
||||
});
|
||||
});
|
||||
|
||||
test.it(
|
||||
'should find multiple elements by ID even though that is ' +
|
||||
'malformed HTML',
|
||||
function*() {
|
||||
yield driver.get(Pages.nestedPage);
|
||||
|
||||
let elements = yield driver.findElements(By.id('2'));
|
||||
assert(elements.length).equalTo(8);
|
||||
});
|
||||
});
|
||||
|
||||
describe('By.linkText()', function() {
|
||||
test.it('should be able to click on link identified by text', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
yield driver.findElement(By.linkText('click me')).click();
|
||||
yield driver.wait(until.titleIs('We Arrive Here'), 5000);
|
||||
});
|
||||
|
||||
test.it(
|
||||
'should be able to find elements by partial link text',
|
||||
function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
yield driver.findElement(By.partialLinkText('ick me')).click();
|
||||
yield driver.wait(until.titleIs('We Arrive Here'), 5000);
|
||||
});
|
||||
|
||||
test.it('should work when link text contains equals sign', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
let el = yield driver.findElement(By.linkText('Link=equalssign'));
|
||||
|
||||
let id = yield el.getAttribute('id');
|
||||
assert(id).equalTo('linkWithEqualsSign');
|
||||
});
|
||||
|
||||
test.it('matches by partial text when containing equals sign',
|
||||
function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
let link = yield driver.findElement(By.partialLinkText('Link='));
|
||||
|
||||
let id = yield link.getAttribute('id');
|
||||
assert(id).equalTo('linkWithEqualsSign');
|
||||
});
|
||||
|
||||
test.it('works when searching for multiple and text contains =',
|
||||
function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
let elements =
|
||||
yield driver.findElements(By.linkText('Link=equalssign'));
|
||||
|
||||
assert(elements.length).equalTo(1);
|
||||
|
||||
let id = yield elements[0].getAttribute('id');
|
||||
assert(id).equalTo('linkWithEqualsSign');
|
||||
});
|
||||
|
||||
test.it(
|
||||
'works when searching for multiple with partial text containing =',
|
||||
function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
let elements =
|
||||
yield driver.findElements(By.partialLinkText('Link='));
|
||||
|
||||
assert(elements.length).equalTo(1);
|
||||
|
||||
let id = yield elements[0].getAttribute('id');
|
||||
assert(id).equalTo('linkWithEqualsSign');
|
||||
});
|
||||
|
||||
test.it('should be able to find multiple exact matches',
|
||||
function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
let elements = yield driver.findElements(By.linkText('click me'));
|
||||
assert(elements.length).equalTo(2);
|
||||
});
|
||||
|
||||
test.it('should be able to find multiple partial matches',
|
||||
function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
let elements =
|
||||
yield driver.findElements(By.partialLinkText('ick me'));
|
||||
assert(elements.length).equalTo(2);
|
||||
});
|
||||
|
||||
test.ignore(browsers(Browser.SAFARI)).
|
||||
it('works on XHTML pages', function*() {
|
||||
yield driver.get(test.whereIs('actualXhtmlPage.xhtml'));
|
||||
|
||||
let el = yield driver.findElement(By.linkText('Foo'));
|
||||
return assert(el.getText()).equalTo('Foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('By.name()', function() {
|
||||
test.it('should work', function*() {
|
||||
yield driver.get(Pages.formPage);
|
||||
|
||||
let el = yield driver.findElement(By.name('checky'));
|
||||
yield assert(el.getAttribute('value')).equalTo('furrfu');
|
||||
});
|
||||
|
||||
test.it('should find multiple elements with same name', function*() {
|
||||
yield driver.get(Pages.nestedPage);
|
||||
|
||||
let elements = yield driver.findElements(By.name('checky'));
|
||||
assert(elements.length).greaterThan(1);
|
||||
});
|
||||
|
||||
test.it(
|
||||
'should be able to find elements that do not support name property',
|
||||
function*() {
|
||||
yield driver.get(Pages.nestedPage);
|
||||
yield driver.findElement(By.name('div1'));
|
||||
// Pass if this does not return an error.
|
||||
});
|
||||
|
||||
test.it('shoudl be able to find hidden elements by name', function*() {
|
||||
yield driver.get(Pages.formPage);
|
||||
yield driver.findElement(By.name('hidden'));
|
||||
// Pass if this does not return an error.
|
||||
});
|
||||
});
|
||||
|
||||
describe('By.className()', function() {
|
||||
test.it('should work', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
|
||||
let el = yield driver.findElement(By.className('extraDiv'));
|
||||
yield assert(el.getText()).startsWith('Another div starts here.');
|
||||
});
|
||||
|
||||
test.it('should work when name is first name among many', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
|
||||
let el = yield driver.findElement(By.className('nameA'));
|
||||
yield assert(el.getText()).equalTo('An H2 title');
|
||||
});
|
||||
|
||||
test.it('should work when name is last name among many', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
|
||||
let el = yield driver.findElement(By.className('nameC'));
|
||||
yield assert(el.getText()).equalTo('An H2 title');
|
||||
});
|
||||
|
||||
test.it('should work when name is middle of many', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
|
||||
let el = yield driver.findElement(By.className('nameBnoise'));
|
||||
yield assert(el.getText()).equalTo('An H2 title');
|
||||
});
|
||||
|
||||
test.it('should work when name surrounded by whitespace', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
|
||||
let el = yield driver.findElement(By.className('spaceAround'));
|
||||
yield assert(el.getText()).equalTo('Spaced out');
|
||||
});
|
||||
|
||||
test.it('should fail if queried name only partially matches', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
return driver.findElement(By.className('nameB')).
|
||||
then(fail, function(e) {
|
||||
assert(e).instanceOf(error.NoSuchElementError);
|
||||
});
|
||||
});
|
||||
|
||||
test.it('should implicitly wait', function*() {
|
||||
var TIMEOUT_IN_MS = 1000;
|
||||
var EPSILON = TIMEOUT_IN_MS / 2;
|
||||
|
||||
yield driver.manage().timeouts().implicitlyWait(TIMEOUT_IN_MS);
|
||||
yield driver.get(Pages.formPage);
|
||||
|
||||
var start = new Date();
|
||||
return driver.findElement(By.id('nonExistantButton')).
|
||||
then(fail, function(e) {
|
||||
var end = new Date();
|
||||
assert(e).instanceOf(error.NoSuchElementError);
|
||||
assert(end - start).closeTo(TIMEOUT_IN_MS, EPSILON);
|
||||
});
|
||||
});
|
||||
|
||||
test.it('should be able to find multiple matches', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
|
||||
let elements = yield driver.findElements(By.className('nameC'));
|
||||
assert(elements.length).greaterThan(1);
|
||||
});
|
||||
|
||||
test.it('permits compound class names', function() {
|
||||
return driver.get(Pages.xhtmlTestPage)
|
||||
.then(() => driver.findElement(By.className('nameA nameC')))
|
||||
.then(el => el.getText())
|
||||
.then(text => assert(text).equalTo('An H2 title'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('By.xpath()', function() {
|
||||
test.it('should work with multiple matches', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
let elements = yield driver.findElements(By.xpath('//div'));
|
||||
assert(elements.length).greaterThan(1);
|
||||
});
|
||||
|
||||
test.it('should work for selectors using contains keyword', function*() {
|
||||
yield driver.get(Pages.nestedPage);
|
||||
yield driver.findElement(By.xpath('//a[contains(., "hello world")]'));
|
||||
// Pass if no error.
|
||||
});
|
||||
});
|
||||
|
||||
describe('By.tagName()', function() {
|
||||
test.it('works', function*() {
|
||||
yield driver.get(Pages.formPage);
|
||||
|
||||
let el = yield driver.findElement(By.tagName('input'));
|
||||
yield assert(el.getTagName()).equalTo('input');
|
||||
});
|
||||
|
||||
test.it('can find multiple elements', function*() {
|
||||
yield driver.get(Pages.formPage);
|
||||
|
||||
let elements = yield driver.findElements(By.tagName('input'));
|
||||
assert(elements.length).greaterThan(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('By.css()', function() {
|
||||
test.it('works', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
yield driver.findElement(By.css('div.content'));
|
||||
// Pass if no error.
|
||||
});
|
||||
|
||||
test.it('can find multiple elements', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
|
||||
let elements = yield driver.findElements(By.css('p'));
|
||||
assert(elements.length).greaterThan(1);
|
||||
// Pass if no error.
|
||||
});
|
||||
|
||||
test.it(
|
||||
'should find first matching element when searching by ' +
|
||||
'compound CSS selector',
|
||||
function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
|
||||
let el =
|
||||
yield driver.findElement(By.css('div.extraDiv, div.content'));
|
||||
yield assert(el.getAttribute('class')).equalTo('content');
|
||||
});
|
||||
|
||||
test.it('should be able to find multiple elements by compound selector',
|
||||
function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
let elements =
|
||||
yield driver.findElements(By.css('div.extraDiv, div.content'));
|
||||
|
||||
return Promise.all([
|
||||
assertClassIs(elements[0], 'content'),
|
||||
assertClassIs(elements[1], 'extraDiv')
|
||||
]);
|
||||
|
||||
function assertClassIs(el, expected) {
|
||||
return assert(el.getAttribute('class')).equalTo(expected);
|
||||
}
|
||||
});
|
||||
|
||||
// IE only supports short version option[selected].
|
||||
test.ignore(browsers(Browser.IE)).
|
||||
it('should be able to find element by boolean attribute', function*() {
|
||||
yield driver.get(test.whereIs(
|
||||
'locators_tests/boolean_attribute_selected.html'));
|
||||
|
||||
let el = yield driver.findElement(By.css('option[selected="selected"]'));
|
||||
yield assert(el.getAttribute('value')).equalTo('two');
|
||||
});
|
||||
|
||||
test.it(
|
||||
'should be able to find element with short ' +
|
||||
'boolean attribute selector',
|
||||
function*() {
|
||||
yield driver.get(test.whereIs(
|
||||
'locators_tests/boolean_attribute_selected.html'));
|
||||
|
||||
let el = yield driver.findElement(By.css('option[selected]'));
|
||||
yield assert(el.getAttribute('value')).equalTo('two');
|
||||
});
|
||||
|
||||
test.it(
|
||||
'should be able to find element with short boolean attribute ' +
|
||||
'selector on HTML4 page',
|
||||
function*() {
|
||||
yield driver.get(test.whereIs(
|
||||
'locators_tests/boolean_attribute_selected_html4.html'));
|
||||
|
||||
let el = yield driver.findElement(By.css('option[selected]'));
|
||||
yield assert(el.getAttribute('value')).equalTo('two');
|
||||
});
|
||||
});
|
||||
|
||||
describe('by custom locator', function() {
|
||||
test.it('handles single element result', function*() {
|
||||
yield driver.get(Pages.javascriptPage);
|
||||
|
||||
let link = yield driver.findElement(function(driver) {
|
||||
let links = driver.findElements(By.tagName('a'));
|
||||
return promise.filter(links, function(link) {
|
||||
return link.getAttribute('id').then(id => id === 'updatediv');
|
||||
}).then(links => links[0]);
|
||||
});
|
||||
|
||||
yield assert(link.getText()).matches(/Update\s+a\s+div/);
|
||||
});
|
||||
|
||||
test.it('uses first element if locator resolves to list', function*() {
|
||||
yield driver.get(Pages.javascriptPage);
|
||||
|
||||
let link = yield driver.findElement(function() {
|
||||
return driver.findElements(By.tagName('a'));
|
||||
});
|
||||
|
||||
yield assert(link.getText()).isEqualTo('Change the page title!');
|
||||
});
|
||||
|
||||
test.it('fails if locator returns non-webelement value', function*() {
|
||||
yield driver.get(Pages.javascriptPage);
|
||||
|
||||
let link = driver.findElement(function() {
|
||||
return driver.getTitle();
|
||||
});
|
||||
|
||||
return link.then(
|
||||
() => fail('Should have failed'),
|
||||
(e) => assert(e).instanceOf(TypeError));
|
||||
});
|
||||
});
|
||||
|
||||
describe('switchTo().activeElement()', function() {
|
||||
// SAFARI's new session response does not identify it as a W3C browser,
|
||||
// so the command is sent in the unsupported wire protocol format.
|
||||
test.ignore(browsers(Browser.SAFARI)).
|
||||
it('returns document.activeElement', function*() {
|
||||
yield driver.get(Pages.formPage);
|
||||
|
||||
let email = yield driver.findElement(By.css('#email'));
|
||||
yield driver.executeScript('arguments[0].focus()', email);
|
||||
|
||||
let ae = yield driver.switchTo().activeElement();
|
||||
let equal = yield driver.executeScript(
|
||||
'return arguments[0] === arguments[1]', email, ae);
|
||||
assert(equal).isTrue();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
350
node_modules/selenium-webdriver/test/execute_script_test.js
generated
vendored
Normal file
350
node_modules/selenium-webdriver/test/execute_script_test.js
generated
vendored
Normal file
|
@ -0,0 +1,350 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var fail = require('assert').fail;
|
||||
|
||||
var webdriver = require('..'),
|
||||
Browser = webdriver.Browser,
|
||||
By = webdriver.By,
|
||||
assert = require('../testing/assert'),
|
||||
test = require('../lib/test');
|
||||
|
||||
|
||||
test.suite(function(env) {
|
||||
var driver;
|
||||
|
||||
test.before(function*() {
|
||||
driver = yield env.builder().build();
|
||||
});
|
||||
|
||||
test.after(function() {
|
||||
return driver.quit();
|
||||
});
|
||||
|
||||
test.beforeEach(function() {
|
||||
return driver.get(test.Pages.echoPage);
|
||||
});
|
||||
|
||||
describe('executeScript;', function() {
|
||||
var shouldHaveFailed = new Error('Should have failed');
|
||||
|
||||
test.it('fails if script throws', function() {
|
||||
return execute('throw new Error("boom")')
|
||||
.then(function() { throw shouldHaveFailed; })
|
||||
.catch(function(e) {
|
||||
// The java WebDriver server adds a bunch of crap to error messages.
|
||||
// Error message will just be "JavaScript error" for IE.
|
||||
assert(e.message).matches(/.*(JavaScript error|boom).*/);
|
||||
});
|
||||
});
|
||||
|
||||
test.it('fails if script does not parse', function() {
|
||||
return execute('throw function\\*')
|
||||
.then(function() { throw shouldHaveFailed; })
|
||||
.catch(function(e) {
|
||||
assert(e).notEqualTo(shouldHaveFailed);
|
||||
});
|
||||
});
|
||||
|
||||
describe('scripts;', function() {
|
||||
test.it('do not pollute the global scope', function*() {
|
||||
yield execute('var x = 1;');
|
||||
yield assert(execute('return typeof x;')).equalTo('undefined');
|
||||
});
|
||||
|
||||
test.it('can set global variables', function*() {
|
||||
yield execute('window.x = 1234;');
|
||||
yield assert(execute('return x;')).equalTo(1234);
|
||||
});
|
||||
|
||||
test.it('may be defined as a function expression', function*() {
|
||||
let result = yield execute(function() {
|
||||
return 1234 + 'abc';
|
||||
});
|
||||
assert(result).equalTo('1234abc');
|
||||
});
|
||||
});
|
||||
|
||||
describe('return values;', function() {
|
||||
|
||||
test.it('returns undefined as null', function() {
|
||||
return assert(execute('var x; return x;')).isNull();
|
||||
});
|
||||
|
||||
test.it('can return null', function() {
|
||||
return assert(execute('return null;')).isNull();
|
||||
});
|
||||
|
||||
test.it('can return numbers', function*() {
|
||||
yield assert(execute('return 1234')).equalTo(1234);
|
||||
yield assert(execute('return 3.1456')).equalTo(3.1456);
|
||||
});
|
||||
|
||||
test.it('can return strings', function() {
|
||||
return assert(execute('return "hello"')).equalTo('hello');
|
||||
});
|
||||
|
||||
test.it('can return booleans', function*() {
|
||||
yield assert(execute('return true')).equalTo(true);
|
||||
yield assert(execute('return false')).equalTo(false);
|
||||
});
|
||||
|
||||
test.it('can return an array of primitives', function() {
|
||||
return execute('var x; return [1, false, null, 3.14, x]')
|
||||
.then(verifyJson([1, false, null, 3.14, null]));
|
||||
});
|
||||
|
||||
test.it('can return nested arrays', function() {
|
||||
return execute('return [[1, 2, [3]]]').then(verifyJson([[1, 2, [3]]]));
|
||||
});
|
||||
|
||||
test.ignore(env.browsers(Browser.IE)).
|
||||
it('can return empty object literal', function() {
|
||||
return execute('return {}').then(verifyJson({}));
|
||||
});
|
||||
|
||||
test.it('can return object literals', function() {
|
||||
return execute('return {a: 1, b: false, c: null}').then(result => {
|
||||
verifyJson(['a', 'b', 'c'])(Object.keys(result).sort());
|
||||
assert(result.a).equalTo(1);
|
||||
assert(result.b).equalTo(false);
|
||||
assert(result.c).isNull();
|
||||
});
|
||||
});
|
||||
|
||||
test.it('can return complex object literals', function() {
|
||||
return execute('return {a:{b: "hello"}}')
|
||||
.then(verifyJson({a:{b: 'hello'}}));
|
||||
});
|
||||
|
||||
test.it('can return dom elements as web elements', function*() {
|
||||
let result =
|
||||
yield execute('return document.querySelector(".header.host")');
|
||||
assert(result).instanceOf(webdriver.WebElement);
|
||||
|
||||
return assert(result.getText()).startsWith('host: ');
|
||||
});
|
||||
|
||||
test.it('can return array of dom elements', function*() {
|
||||
let result = yield execute(
|
||||
'var nodes = document.querySelectorAll(".request,.host");' +
|
||||
'return [nodes[0], nodes[1]];');
|
||||
assert(result.length).equalTo(2);
|
||||
|
||||
assert(result[0]).instanceOf(webdriver.WebElement);
|
||||
yield assert(result[0].getText()).startsWith('GET ');
|
||||
|
||||
assert(result[1]).instanceOf(webdriver.WebElement);
|
||||
yield assert(result[1].getText()).startsWith('host: ');
|
||||
});
|
||||
|
||||
test.it('can return a NodeList as an array of web elements', function*() {
|
||||
let result =
|
||||
yield execute('return document.querySelectorAll(".request,.host");')
|
||||
|
||||
assert(result.length).equalTo(2);
|
||||
|
||||
assert(result[0]).instanceOf(webdriver.WebElement);
|
||||
yield assert(result[0].getText()).startsWith('GET ');
|
||||
|
||||
assert(result[1]).instanceOf(webdriver.WebElement);
|
||||
yield assert(result[1].getText()).startsWith('host: ');
|
||||
});
|
||||
|
||||
test.it('can return object literal with element property', function*() {
|
||||
let result = yield execute('return {a: document.body}');
|
||||
|
||||
assert(result.a).instanceOf(webdriver.WebElement);
|
||||
yield assert(result.a.getTagName()).equalTo('body');
|
||||
});
|
||||
});
|
||||
|
||||
describe('parameters;', function() {
|
||||
test.it('can pass numeric arguments', function*() {
|
||||
yield assert(execute('return arguments[0]', 12)).equalTo(12);
|
||||
yield assert(execute('return arguments[0]', 3.14)).equalTo(3.14);
|
||||
});
|
||||
|
||||
test.it('can pass boolean arguments', function*() {
|
||||
yield assert(execute('return arguments[0]', true)).equalTo(true);
|
||||
yield assert(execute('return arguments[0]', false)).equalTo(false);
|
||||
});
|
||||
|
||||
test.it('can pass string arguments', function*() {
|
||||
yield assert(execute('return arguments[0]', 'hi')).equalTo('hi');
|
||||
});
|
||||
|
||||
test.it('can pass null arguments', function*() {
|
||||
yield assert(execute('return arguments[0] === null', null)).equalTo(true);
|
||||
yield assert(execute('return arguments[0]', null)).equalTo(null);
|
||||
});
|
||||
|
||||
test.it('passes undefined as a null argument', function*() {
|
||||
var x;
|
||||
yield assert(execute('return arguments[0] === null', x)).equalTo(true);
|
||||
yield assert(execute('return arguments[0]', x)).equalTo(null);
|
||||
});
|
||||
|
||||
test.it('can pass multiple arguments', function*() {
|
||||
yield assert(execute('return arguments.length')).equalTo(0);
|
||||
yield assert(execute('return arguments.length', 1, 'a', false)).equalTo(3);
|
||||
});
|
||||
|
||||
test.ignore(env.browsers(Browser.FIREFOX, Browser.SAFARI)).
|
||||
it('can return arguments object as array', function*() {
|
||||
let val = yield execute('return arguments', 1, 'a', false);
|
||||
|
||||
assert(val.length).equalTo(3);
|
||||
assert(val[0]).equalTo(1);
|
||||
assert(val[1]).equalTo('a');
|
||||
assert(val[2]).equalTo(false);
|
||||
});
|
||||
|
||||
test.it('can pass object literal', function*() {
|
||||
let result = yield execute(
|
||||
'return [typeof arguments[0], arguments[0].a]', {a: 'hello'})
|
||||
assert(result[0]).equalTo('object');
|
||||
assert(result[1]).equalTo('hello');
|
||||
});
|
||||
|
||||
test.it('WebElement arguments are passed as DOM elements', function*() {
|
||||
let el = yield driver.findElement(By.tagName('div'));
|
||||
let result =
|
||||
yield execute('return arguments[0].tagName.toLowerCase();', el);
|
||||
assert(result).equalTo('div');
|
||||
});
|
||||
|
||||
test.it('can pass array containing object literals', function*() {
|
||||
let result = yield execute('return arguments[0]', [{color: "red"}]);
|
||||
assert(result.length).equalTo(1);
|
||||
assert(result[0].color).equalTo('red');
|
||||
});
|
||||
|
||||
test.it('does not modify object literal parameters', function() {
|
||||
var input = {color: 'red'};
|
||||
return execute('return arguments[0];', input).then(verifyJson(input));
|
||||
});
|
||||
});
|
||||
|
||||
// See https://code.google.com/p/selenium/issues/detail?id=8223.
|
||||
describe('issue 8223;', function() {
|
||||
describe('using for..in loops;', function() {
|
||||
test.it('can return array built from for-loop index', function() {
|
||||
return execute(function() {
|
||||
var ret = [];
|
||||
for (var i = 0; i < 3; i++) {
|
||||
ret.push(i);
|
||||
}
|
||||
return ret;
|
||||
}).then(verifyJson[0, 1, 2]);
|
||||
});
|
||||
|
||||
test.it('can copy input array contents', function() {
|
||||
return execute(function(input) {
|
||||
var ret = [];
|
||||
for (var i in input) {
|
||||
ret.push(input[i]);
|
||||
}
|
||||
return ret;
|
||||
}, ['fa', 'fe', 'fi']).then(verifyJson(['fa', 'fe', 'fi']));
|
||||
});
|
||||
|
||||
test.it('can iterate over input object keys', function() {
|
||||
return execute(function(thing) {
|
||||
var ret = [];
|
||||
for (var w in thing.words) {
|
||||
ret.push(thing.words[w].word);
|
||||
}
|
||||
return ret;
|
||||
}, {words: [{word: 'fa'}, {word: 'fe'}, {word: 'fi'}]})
|
||||
.then(verifyJson(['fa', 'fe', 'fi']));
|
||||
});
|
||||
|
||||
describe('recursive functions;', function() {
|
||||
test.it('can build array from input', function() {
|
||||
var input = ['fa', 'fe', 'fi'];
|
||||
return execute(function(thearray) {
|
||||
var ret = [];
|
||||
function build_response(thearray, ret) {
|
||||
ret.push(thearray.shift());
|
||||
return (!thearray.length && ret
|
||||
|| build_response(thearray, ret));
|
||||
}
|
||||
return build_response(thearray, ret);
|
||||
}, input).then(verifyJson(input));
|
||||
});
|
||||
|
||||
test.it('can build array from elements in object', function() {
|
||||
var input = {words: [{word: 'fa'}, {word: 'fe'}, {word: 'fi'}]};
|
||||
return execute(function(thing) {
|
||||
var ret = [];
|
||||
function build_response(thing, ret) {
|
||||
var item = thing.words.shift();
|
||||
ret.push(item.word);
|
||||
return (!thing.words.length && ret
|
||||
|| build_response(thing, ret));
|
||||
}
|
||||
return build_response(thing, ret);
|
||||
}, input).then(verifyJson(['fa', 'fe', 'fi']));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('async timeouts', function() {
|
||||
var TIMEOUT_IN_MS = 200;
|
||||
var ACCEPTABLE_WAIT = TIMEOUT_IN_MS / 10;
|
||||
var TOO_LONG_WAIT = TIMEOUT_IN_MS * 10;
|
||||
|
||||
before(function() {
|
||||
return driver.manage().timeouts().setScriptTimeout(TIMEOUT_IN_MS)
|
||||
});
|
||||
|
||||
test.it('does not fail if script execute in time', function() {
|
||||
return executeTimeOutScript(ACCEPTABLE_WAIT);
|
||||
});
|
||||
|
||||
test.it('fails if script took too long', function() {
|
||||
return executeTimeOutScript(TOO_LONG_WAIT)
|
||||
.then(function() {
|
||||
fail('it should have timed out');
|
||||
}).catch(function(e) {
|
||||
assert(e.name).equalTo('ScriptTimeoutError');
|
||||
});
|
||||
});
|
||||
|
||||
function executeTimeOutScript(sleepTime) {
|
||||
return driver.executeAsyncScript(function(sleepTime) {
|
||||
var callback = arguments[arguments.length - 1];
|
||||
setTimeout(callback, sleepTime)
|
||||
}, sleepTime);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
function verifyJson(expected) {
|
||||
return function(actual) {
|
||||
return assert(JSON.stringify(actual)).equalTo(JSON.stringify(expected));
|
||||
};
|
||||
}
|
||||
|
||||
function execute() {
|
||||
return driver.executeScript.apply(driver, arguments);
|
||||
}
|
||||
});
|
62
node_modules/selenium-webdriver/test/fingerprint_test.js
generated
vendored
Normal file
62
node_modules/selenium-webdriver/test/fingerprint_test.js
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('../testing/assert'),
|
||||
test = require('../lib/test'),
|
||||
Pages = test.Pages;
|
||||
|
||||
|
||||
test.suite(function(env) {
|
||||
var browsers = env.browsers;
|
||||
|
||||
var driver;
|
||||
test.before(function() {
|
||||
driver = env.builder().build();
|
||||
});
|
||||
|
||||
test.after(function() {
|
||||
driver.quit();
|
||||
});
|
||||
|
||||
describe('fingerprinting', function() {
|
||||
test.it('it should fingerprint the navigator object', function*() {
|
||||
yield driver.get(Pages.simpleTestPage);
|
||||
|
||||
let wd = yield driver.executeScript('return navigator.webdriver');
|
||||
assert(wd).equalTo(true);
|
||||
});
|
||||
|
||||
test.it('fingerprint must not be writable', function*() {
|
||||
yield driver.get(Pages.simpleTestPage);
|
||||
|
||||
let wd = yield driver.executeScript(
|
||||
'navigator.webdriver = "ohai"; return navigator.webdriver');
|
||||
assert(wd).equalTo(true);
|
||||
});
|
||||
|
||||
test.it('leaves fingerprint on svg pages', function*() {
|
||||
yield driver.get(Pages.svgPage);
|
||||
|
||||
let wd = yield driver.executeScript('return navigator.webdriver');
|
||||
assert(wd).equalTo(true);
|
||||
});
|
||||
});
|
||||
|
||||
// Currently only implemented in legacy firefox.
|
||||
}, {browsers: ['legacy-firefox']});
|
120
node_modules/selenium-webdriver/test/firefox/extension_test.js
generated
vendored
Normal file
120
node_modules/selenium-webdriver/test/firefox/extension_test.js
generated
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert'),
|
||||
crypto = require('crypto'),
|
||||
fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
var extension = require('../../firefox/extension'),
|
||||
io = require('../../io'),
|
||||
zip = require('../../io/zip'),
|
||||
it = require('../../testing').it;
|
||||
|
||||
|
||||
var JETPACK_EXTENSION = path.join(__dirname,
|
||||
'../../lib/test/data/firefox/jetpack-sample.xpi');
|
||||
var NORMAL_EXTENSION = path.join(__dirname,
|
||||
'../../lib/test/data/firefox/sample.xpi');
|
||||
var WEBEXTENSION_EXTENSION = path.join(__dirname,
|
||||
'../../lib/test/data/firefox/webextension.xpi');
|
||||
|
||||
var JETPACK_EXTENSION_ID = 'jid1-EaXX7k0wwiZR7w@jetpack';
|
||||
var NORMAL_EXTENSION_ID = 'sample@seleniumhq.org';
|
||||
var WEBEXTENSION_EXTENSION_ID = 'webextensions-selenium-example@example.com';
|
||||
|
||||
|
||||
describe('extension', function() {
|
||||
it('can install a jetpack xpi file', function() {
|
||||
return io.tmpDir().then(function(dir) {
|
||||
return extension.install(JETPACK_EXTENSION, dir).then(function(id) {
|
||||
assert.equal(JETPACK_EXTENSION_ID, id);
|
||||
var file = path.join(dir, id + '.xpi');
|
||||
assert.ok(fs.existsSync(file), 'no such file: ' + file);
|
||||
assert.ok(!fs.statSync(file).isDirectory());
|
||||
|
||||
var copiedSha1 = crypto.createHash('sha1')
|
||||
.update(fs.readFileSync(file))
|
||||
.digest('hex');
|
||||
|
||||
var goldenSha1 = crypto.createHash('sha1')
|
||||
.update(fs.readFileSync(JETPACK_EXTENSION))
|
||||
.digest('hex');
|
||||
|
||||
assert.equal(copiedSha1, goldenSha1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can install a normal xpi file', function() {
|
||||
return io.tmpDir().then(function(dir) {
|
||||
return extension.install(NORMAL_EXTENSION, dir).then(function(id) {
|
||||
assert.equal(NORMAL_EXTENSION_ID, id);
|
||||
|
||||
var file = path.join(dir, NORMAL_EXTENSION_ID);
|
||||
assert.ok(fs.statSync(file).isDirectory());
|
||||
|
||||
assert.ok(fs.existsSync(path.join(file, 'chrome.manifest')));
|
||||
assert.ok(fs.existsSync(path.join(file, 'content/overlay.xul')));
|
||||
assert.ok(fs.existsSync(path.join(file, 'content/overlay.js')));
|
||||
assert.ok(fs.existsSync(path.join(file, 'install.rdf')));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can install a webextension xpi file', function() {
|
||||
return io.tmpDir().then(function(dir) {
|
||||
return extension.install(WEBEXTENSION_EXTENSION, dir).then(function(id) {
|
||||
assert.equal(WEBEXTENSION_EXTENSION_ID, id);
|
||||
var file = path.join(dir, id + '.xpi');
|
||||
assert.ok(fs.existsSync(file), 'no such file: ' + file);
|
||||
assert.ok(!fs.statSync(file).isDirectory());
|
||||
|
||||
var copiedSha1 = crypto.createHash('sha1')
|
||||
.update(fs.readFileSync(file))
|
||||
.digest('hex');
|
||||
|
||||
var goldenSha1 = crypto.createHash('sha1')
|
||||
.update(fs.readFileSync(WEBEXTENSION_EXTENSION))
|
||||
.digest('hex');
|
||||
|
||||
assert.equal(copiedSha1, goldenSha1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can install an extension from a directory', function() {
|
||||
return io.tmpDir().then(function(srcDir) {
|
||||
return zip.unzip(NORMAL_EXTENSION, srcDir)
|
||||
.then(() => io.tmpDir())
|
||||
.then(dstDir => {
|
||||
return extension.install(srcDir, dstDir).then(function(id) {
|
||||
assert.equal(NORMAL_EXTENSION_ID, id);
|
||||
|
||||
var dir = path.join(dstDir, NORMAL_EXTENSION_ID);
|
||||
|
||||
assert.ok(fs.existsSync(path.join(dir, 'chrome.manifest')));
|
||||
assert.ok(fs.existsSync(path.join(dir, 'content/overlay.xul')));
|
||||
assert.ok(fs.existsSync(path.join(dir, 'content/overlay.js')));
|
||||
assert.ok(fs.existsSync(path.join(dir, 'install.rdf')));
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
244
node_modules/selenium-webdriver/test/firefox/firefox_test.js
generated
vendored
Normal file
244
node_modules/selenium-webdriver/test/firefox/firefox_test.js
generated
vendored
Normal file
|
@ -0,0 +1,244 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
|
||||
var firefox = require('../../firefox'),
|
||||
io = require('../../io'),
|
||||
test = require('../../lib/test'),
|
||||
assert = require('../../testing/assert'),
|
||||
Context = require('../../firefox').Context,
|
||||
error = require('../..').error;
|
||||
|
||||
var {consume} = require('../../lib/promise');
|
||||
|
||||
|
||||
var JETPACK_EXTENSION = path.join(__dirname,
|
||||
'../../lib/test/data/firefox/jetpack-sample.xpi');
|
||||
var NORMAL_EXTENSION = path.join(__dirname,
|
||||
'../../lib/test/data/firefox/sample.xpi');
|
||||
var WEBEXTENSION_EXTENSION = path.join(__dirname,
|
||||
'../../lib/test/data/firefox/webextension.xpi');
|
||||
|
||||
|
||||
test.suite(function(env) {
|
||||
describe('firefox', function() {
|
||||
describe('Options', function() {
|
||||
let driver;
|
||||
|
||||
beforeEach(function() {
|
||||
driver = null;
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
if (driver) {
|
||||
return driver.quit();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {...string} extensions the extensions to install.
|
||||
* @return {!firefox.Profile} a new profile.
|
||||
*/
|
||||
function profileWithExtensions(...extensions) {
|
||||
let profile = new firefox.Profile();
|
||||
profile.setPreference('xpinstall.signatures.required', false);
|
||||
extensions.forEach(ext => profile.addExtension(ext));
|
||||
return profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs a test that requires Firefox Developer Edition. The test will be
|
||||
* skipped if dev cannot be found on the current system.
|
||||
*/
|
||||
function runWithFirefoxDev(options, testFn) {
|
||||
return firefox.Channel.AURORA.locate().then(exe => {
|
||||
options.setBinary(exe);
|
||||
driver = env.builder()
|
||||
.setFirefoxOptions(options)
|
||||
.build();
|
||||
return driver.call(testFn);
|
||||
}, err => {
|
||||
console.warn(
|
||||
'Skipping test: could not find Firefox Dev Edition: ' + err);
|
||||
});
|
||||
}
|
||||
|
||||
describe('can start Firefox with custom preferences', function() {
|
||||
function runTest(opt_dir) {
|
||||
return consume(function*() {
|
||||
let profile = new firefox.Profile(opt_dir);
|
||||
profile.setPreference('general.useragent.override', 'foo;bar');
|
||||
|
||||
let options = new firefox.Options().setProfile(profile);
|
||||
|
||||
driver = env.builder().
|
||||
setFirefoxOptions(options).
|
||||
build();
|
||||
|
||||
yield driver.get('data:text/html,<html><div>content</div></html>');
|
||||
|
||||
var userAgent = yield driver.executeScript(
|
||||
'return window.navigator.userAgent');
|
||||
assert(userAgent).equalTo('foo;bar');
|
||||
});
|
||||
}
|
||||
|
||||
test.it('profile created from scratch', function() {
|
||||
return runTest();
|
||||
});
|
||||
|
||||
test.it('profile created from template', function() {
|
||||
return io.tmpDir().then(runTest);
|
||||
});
|
||||
});
|
||||
|
||||
test.it('can start Firefox with a jetpack extension', function() {
|
||||
let profile = profileWithExtensions(JETPACK_EXTENSION);
|
||||
let options = new firefox.Options().setProfile(profile);
|
||||
|
||||
return runWithFirefoxDev(options, function*() {
|
||||
yield loadJetpackPage(driver,
|
||||
'data:text/html;charset=UTF-8,<html><div>content</div></html>');
|
||||
|
||||
let text =
|
||||
yield driver.findElement({id: 'jetpack-sample-banner'}).getText();
|
||||
assert(text).equalTo('Hello, world!');
|
||||
});
|
||||
});
|
||||
|
||||
test.it('can start Firefox with a normal extension', function() {
|
||||
let profile = profileWithExtensions(NORMAL_EXTENSION);
|
||||
let options = new firefox.Options().setProfile(profile);
|
||||
|
||||
return runWithFirefoxDev(options, function*() {
|
||||
yield driver.get('data:text/html,<html><div>content</div></html>');
|
||||
|
||||
let footer =
|
||||
yield driver.findElement({id: 'sample-extension-footer'});
|
||||
let text = yield footer.getText();
|
||||
assert(text).equalTo('Goodbye');
|
||||
});
|
||||
});
|
||||
|
||||
test.it('can start Firefox with a webextension extension', function() {
|
||||
let profile = profileWithExtensions(WEBEXTENSION_EXTENSION);
|
||||
let options = new firefox.Options().setProfile(profile);
|
||||
|
||||
return runWithFirefoxDev(options, function*() {
|
||||
yield driver.get(test.Pages.echoPage);
|
||||
|
||||
let footer =
|
||||
yield driver.findElement({id: 'webextensions-selenium-example'});
|
||||
let text = yield footer.getText();
|
||||
assert(text).equalTo('Content injected by webextensions-selenium-example');
|
||||
});
|
||||
});
|
||||
|
||||
test.it('can start Firefox with multiple extensions', function() {
|
||||
let profile =
|
||||
profileWithExtensions(JETPACK_EXTENSION, NORMAL_EXTENSION);
|
||||
let options = new firefox.Options().setProfile(profile);
|
||||
|
||||
return runWithFirefoxDev(options, function*() {
|
||||
yield loadJetpackPage(driver,
|
||||
'data:text/html;charset=UTF-8,<html><div>content</div></html>');
|
||||
|
||||
let banner =
|
||||
yield driver.findElement({id: 'jetpack-sample-banner'}).getText();
|
||||
assert(banner).equalTo('Hello, world!');
|
||||
|
||||
let footer =
|
||||
yield driver.findElement({id: 'sample-extension-footer'})
|
||||
.getText();
|
||||
assert(footer).equalTo('Goodbye');
|
||||
});
|
||||
});
|
||||
|
||||
function loadJetpackPage(driver, url) {
|
||||
// On linux the jetpack extension does not always run the first time
|
||||
// we load a page. If this happens, just reload the page (a simple
|
||||
// refresh doesn't appear to work).
|
||||
return driver.wait(function() {
|
||||
driver.get(url);
|
||||
return driver.findElements({id: 'jetpack-sample-banner'})
|
||||
.then(found => found.length > 0);
|
||||
}, 3000);
|
||||
}
|
||||
});
|
||||
|
||||
describe('binary management', function() {
|
||||
var driver1, driver2;
|
||||
|
||||
test.ignore(env.isRemote).
|
||||
it('can start multiple sessions with single binary instance', function*() {
|
||||
var options = new firefox.Options().setBinary(new firefox.Binary);
|
||||
env.builder().setFirefoxOptions(options);
|
||||
driver1 = yield env.builder().build();
|
||||
driver2 = yield env.builder().build();
|
||||
// Ok if this doesn't fail.
|
||||
});
|
||||
|
||||
test.afterEach(function*() {
|
||||
if (driver1) {
|
||||
yield driver1.quit();
|
||||
}
|
||||
|
||||
if (driver2) {
|
||||
yield driver2.quit();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('context switching', function() {
|
||||
var driver;
|
||||
|
||||
test.beforeEach(function*() {
|
||||
driver = yield env.builder().build();
|
||||
});
|
||||
|
||||
test.afterEach(function() {
|
||||
if (driver) {
|
||||
return driver.quit();
|
||||
}
|
||||
});
|
||||
|
||||
test.it('can get context', function() {
|
||||
return assert(driver.getContext()).equalTo(Context.CONTENT);
|
||||
});
|
||||
|
||||
test.it('can set context', function*() {
|
||||
yield driver.setContext(Context.CHROME);
|
||||
let ctxt = yield driver.getContext();
|
||||
assert(ctxt).equalTo(Context.CHROME);
|
||||
|
||||
yield driver.setContext(Context.CONTENT);
|
||||
ctxt = yield driver.getContext();
|
||||
assert(ctxt).equalTo(Context.CONTENT);
|
||||
});
|
||||
|
||||
test.it('throws on unknown context', function() {
|
||||
return driver.setContext("foo").then(assert.fail, function(e) {
|
||||
assert(e).instanceOf(error.InvalidArgumentError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}, {browsers: ['firefox']});
|
140
node_modules/selenium-webdriver/test/firefox/profile_test.js
generated
vendored
Normal file
140
node_modules/selenium-webdriver/test/firefox/profile_test.js
generated
vendored
Normal file
|
@ -0,0 +1,140 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert'),
|
||||
fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
var promise = require('../..').promise,
|
||||
Profile = require('../../firefox/profile').Profile,
|
||||
decode = require('../../firefox/profile').decode,
|
||||
loadUserPrefs = require('../../firefox/profile').loadUserPrefs,
|
||||
io = require('../../io');
|
||||
|
||||
|
||||
var JETPACK_EXTENSION = path.join(__dirname,
|
||||
'../../lib/test/data/firefox/jetpack-sample.xpi');
|
||||
var NORMAL_EXTENSION = path.join(__dirname,
|
||||
'../../lib/test/data/firefox/sample.xpi');
|
||||
var WEBEXTENSION_EXTENSION = path.join(__dirname,
|
||||
'../../lib/test/data/firefox/webextension.xpi');
|
||||
|
||||
var JETPACK_EXTENSION_ID = 'jid1-EaXX7k0wwiZR7w@jetpack.xpi';
|
||||
var NORMAL_EXTENSION_ID = 'sample@seleniumhq.org';
|
||||
var WEBEXTENSION_EXTENSION_ID = 'webextensions-selenium-example@example.com';
|
||||
|
||||
|
||||
|
||||
describe('Profile', function() {
|
||||
describe('setPreference', function() {
|
||||
it('allows setting custom properties', function() {
|
||||
var profile = new Profile();
|
||||
assert.equal(undefined, profile.getPreference('foo'));
|
||||
|
||||
profile.setPreference('foo', 'bar');
|
||||
assert.equal('bar', profile.getPreference('foo'));
|
||||
});
|
||||
|
||||
it('allows overriding mutable properties', function() {
|
||||
var profile = new Profile();
|
||||
|
||||
profile.setPreference('browser.newtab.url', 'http://www.example.com');
|
||||
assert.equal('http://www.example.com',
|
||||
profile.getPreference('browser.newtab.url'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('writeToDisk', function() {
|
||||
it('copies template directory recursively', function() {
|
||||
var templateDir;
|
||||
return io.tmpDir().then(function(td) {
|
||||
templateDir = td;
|
||||
var foo = path.join(templateDir, 'foo');
|
||||
fs.writeFileSync(foo, 'Hello, world');
|
||||
|
||||
var bar = path.join(templateDir, 'subfolder/bar');
|
||||
fs.mkdirSync(path.dirname(bar));
|
||||
fs.writeFileSync(bar, 'Goodbye, world!');
|
||||
|
||||
return new Profile(templateDir).writeToDisk();
|
||||
}).then(function(profileDir) {
|
||||
assert.notEqual(profileDir, templateDir);
|
||||
|
||||
assert.equal('Hello, world',
|
||||
fs.readFileSync(path.join(profileDir, 'foo')));
|
||||
assert.equal('Goodbye, world!',
|
||||
fs.readFileSync(path.join(profileDir, 'subfolder/bar')));
|
||||
});
|
||||
});
|
||||
|
||||
it('does not copy lock files', function() {
|
||||
return io.tmpDir().then(function(dir) {
|
||||
fs.writeFileSync(path.join(dir, 'parent.lock'), 'lock');
|
||||
fs.writeFileSync(path.join(dir, 'lock'), 'lock');
|
||||
fs.writeFileSync(path.join(dir, '.parentlock'), 'lock');
|
||||
return new Profile(dir).writeToDisk();
|
||||
}).then(function(dir) {
|
||||
assert.ok(fs.existsSync(dir));
|
||||
assert.ok(!fs.existsSync(path.join(dir, 'parent.lock')));
|
||||
assert.ok(!fs.existsSync(path.join(dir, 'lock')));
|
||||
assert.ok(!fs.existsSync(path.join(dir, '.parentlock')));
|
||||
});
|
||||
});
|
||||
|
||||
describe('user.js', function() {
|
||||
it('merges template user.js into preferences', function() {
|
||||
return io.tmpDir().then(function(dir) {
|
||||
fs.writeFileSync(path.join(dir, 'user.js'), [
|
||||
'user_pref("browser.newtab.url", "http://www.example.com")',
|
||||
'user_pref("dom.max_script_run_time", 1234)'
|
||||
].join('\n'));
|
||||
|
||||
return new Profile(dir).writeToDisk();
|
||||
}).then(function(profile) {
|
||||
return loadUserPrefs(path.join(profile, 'user.js'));
|
||||
}).then(function(prefs) {
|
||||
assert.equal('http://www.example.com', prefs['browser.newtab.url']);
|
||||
assert.equal(1234, prefs['dom.max_script_run_time']);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('extensions', function() {
|
||||
it('are copied into new profile directory', function() {
|
||||
var profile = new Profile();
|
||||
profile.addExtension(JETPACK_EXTENSION);
|
||||
profile.addExtension(NORMAL_EXTENSION);
|
||||
profile.addExtension(WEBEXTENSION_EXTENSION);
|
||||
|
||||
return profile.writeToDisk().then(function(dir) {
|
||||
dir = path.join(dir, 'extensions');
|
||||
assertExists(JETPACK_EXTENSION_ID);
|
||||
assertExists(NORMAL_EXTENSION_ID);
|
||||
assertExists(WEBEXTENSION_EXTENSION_ID + '.xpi');
|
||||
|
||||
function assertExists(file) {
|
||||
assert.ok(
|
||||
fs.existsSync(path.join(dir, file)),
|
||||
`expected ${file} to exist`);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
223
node_modules/selenium-webdriver/test/http/http_test.js
generated
vendored
Normal file
223
node_modules/selenium-webdriver/test/http/http_test.js
generated
vendored
Normal file
|
@ -0,0 +1,223 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert'),
|
||||
http = require('http'),
|
||||
url = require('url');
|
||||
|
||||
var HttpClient = require('../../http').HttpClient,
|
||||
HttpRequest = require('../../lib/http').Request,
|
||||
HttpResponse = require('../../lib/http').Response,
|
||||
Server = require('../../lib/test/httpserver').Server;
|
||||
|
||||
describe('HttpClient', function() {
|
||||
this.timeout(4 * 1000);
|
||||
|
||||
var server = new Server(function(req, res) {
|
||||
let parsedUrl = url.parse(req.url);
|
||||
|
||||
if (req.method == 'GET' && req.url == '/echo') {
|
||||
res.writeHead(200, req.headers);
|
||||
res.end();
|
||||
|
||||
} else if (req.method == 'GET' && req.url == '/redirect') {
|
||||
res.writeHead(303, {'Location': server.url('/hello')});
|
||||
res.end();
|
||||
|
||||
} else if (req.method == 'GET' && req.url == '/hello') {
|
||||
res.writeHead(200, {'content-type': 'text/plain'});
|
||||
res.end('hello, world!');
|
||||
|
||||
} else if (req.method == 'GET' && req.url == '/chunked') {
|
||||
res.writeHead(200, {
|
||||
'content-type': 'text/html; charset=utf-8',
|
||||
'transfer-encoding': 'chunked'
|
||||
});
|
||||
res.write('<!DOCTYPE html>');
|
||||
setTimeout(() => res.end('<h1>Hello, world!</h1>'), 20);
|
||||
|
||||
} else if (req.method == 'GET' && req.url == '/badredirect') {
|
||||
res.writeHead(303, {});
|
||||
res.end();
|
||||
|
||||
} else if (req.method == 'GET' && req.url == '/protected') {
|
||||
var denyAccess = function() {
|
||||
res.writeHead(401, {'WWW-Authenticate': 'Basic realm="test"'});
|
||||
res.end('Access denied');
|
||||
};
|
||||
|
||||
var basicAuthRegExp = /^\s*basic\s+([a-z0-9\-\._~\+\/]+)=*\s*$/i
|
||||
var auth = req.headers.authorization;
|
||||
var match = basicAuthRegExp.exec(auth || '');
|
||||
if (!match) {
|
||||
denyAccess();
|
||||
return;
|
||||
}
|
||||
|
||||
var userNameAndPass = new Buffer(match[1], 'base64').toString();
|
||||
var parts = userNameAndPass.split(':', 2);
|
||||
if (parts[0] !== 'genie' && parts[1] !== 'bottle') {
|
||||
denyAccess();
|
||||
return;
|
||||
}
|
||||
|
||||
res.writeHead(200, {'content-type': 'text/plain'});
|
||||
res.end('Access granted!');
|
||||
|
||||
} else if (req.method == 'GET'
|
||||
&& parsedUrl.pathname
|
||||
&& parsedUrl.pathname.endsWith('/proxy')) {
|
||||
let headers = Object.assign({}, req.headers);
|
||||
headers['x-proxy-request-uri'] = req.url;
|
||||
res.writeHead(200, headers);
|
||||
res.end();
|
||||
|
||||
} else if (req.method == 'GET'
|
||||
&& parsedUrl.pathname
|
||||
&& parsedUrl.pathname.endsWith('/proxy/redirect')) {
|
||||
let path = `/proxy${parsedUrl.search || ''}${parsedUrl.hash || ''}`;
|
||||
res.writeHead(303, {'Location': path});
|
||||
res.end();
|
||||
|
||||
} else {
|
||||
res.writeHead(404, {});
|
||||
res.end();
|
||||
}
|
||||
});
|
||||
|
||||
before(function() {
|
||||
return server.start();
|
||||
});
|
||||
|
||||
after(function() {
|
||||
return server.stop();
|
||||
});
|
||||
|
||||
it('can send a basic HTTP request', function() {
|
||||
var request = new HttpRequest('GET', '/echo');
|
||||
request.headers.set('Foo', 'Bar');
|
||||
|
||||
var agent = new http.Agent();
|
||||
agent.maxSockets = 1; // Only making 1 request.
|
||||
|
||||
var client = new HttpClient(server.url(), agent);
|
||||
return client.send(request).then(function(response) {
|
||||
assert.equal(200, response.status);
|
||||
assert.equal(response.headers.get('content-length'), '0');
|
||||
assert.equal(response.headers.get('connection'), 'keep-alive');
|
||||
assert.equal(response.headers.get('host'), server.host());
|
||||
|
||||
assert.equal(request.headers.get('Foo'), 'Bar');
|
||||
assert.equal(
|
||||
request.headers.get('Accept'), 'application/json; charset=utf-8');
|
||||
});
|
||||
});
|
||||
|
||||
it('handles chunked responses', function() {
|
||||
let request = new HttpRequest('GET', '/chunked');
|
||||
|
||||
let client = new HttpClient(server.url());
|
||||
return client.send(request).then(response => {
|
||||
assert.equal(200, response.status);
|
||||
assert.equal(response.body, '<!DOCTYPE html><h1>Hello, world!</h1>');
|
||||
});
|
||||
});
|
||||
|
||||
it('can use basic auth', function() {
|
||||
var parsed = url.parse(server.url());
|
||||
parsed.auth = 'genie:bottle';
|
||||
|
||||
var client = new HttpClient(url.format(parsed));
|
||||
var request = new HttpRequest('GET', '/protected');
|
||||
return client.send(request).then(function(response) {
|
||||
assert.equal(200, response.status);
|
||||
assert.equal(response.headers.get('content-type'), 'text/plain');
|
||||
assert.equal(response.body, 'Access granted!');
|
||||
});
|
||||
});
|
||||
|
||||
it('fails requests missing required basic auth', function() {
|
||||
var client = new HttpClient(server.url());
|
||||
var request = new HttpRequest('GET', '/protected');
|
||||
return client.send(request).then(function(response) {
|
||||
assert.equal(401, response.status);
|
||||
assert.equal(response.body, 'Access denied');
|
||||
});
|
||||
});
|
||||
|
||||
it('automatically follows redirects', function() {
|
||||
var request = new HttpRequest('GET', '/redirect');
|
||||
var client = new HttpClient(server.url());
|
||||
return client.send(request).then(function(response) {
|
||||
assert.equal(200, response.status);
|
||||
assert.equal(response.headers.get('content-type'), 'text/plain');
|
||||
assert.equal(response.body, 'hello, world!');
|
||||
});
|
||||
});
|
||||
|
||||
it('handles malformed redirect responses', function() {
|
||||
var request = new HttpRequest('GET', '/badredirect');
|
||||
var client = new HttpClient(server.url());
|
||||
return client.send(request).then(assert.fail, function(err) {
|
||||
assert.ok(/Failed to parse "Location"/.test(err.message),
|
||||
'Not the expected error: ' + err.message);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with proxy', function() {
|
||||
it('sends request to proxy with absolute URI', function() {
|
||||
var request = new HttpRequest('GET', '/proxy');
|
||||
var client = new HttpClient(
|
||||
'http://another.server.com', undefined, server.url());
|
||||
return client.send(request).then(function(response) {
|
||||
assert.equal(200, response.status);
|
||||
assert.equal(response.headers.get('host'), 'another.server.com');
|
||||
assert.equal(
|
||||
response.headers.get('x-proxy-request-uri'),
|
||||
'http://another.server.com/proxy');
|
||||
});
|
||||
});
|
||||
|
||||
it('uses proxy when following redirects', function() {
|
||||
var request = new HttpRequest('GET', '/proxy/redirect');
|
||||
var client = new HttpClient(
|
||||
'http://another.server.com', undefined, server.url());
|
||||
return client.send(request).then(function(response) {
|
||||
assert.equal(200, response.status);
|
||||
assert.equal(response.headers.get('host'), 'another.server.com');
|
||||
assert.equal(
|
||||
response.headers.get('x-proxy-request-uri'),
|
||||
'http://another.server.com/proxy');
|
||||
});
|
||||
});
|
||||
|
||||
it('includes search and hash in redirect URI', function() {
|
||||
var request = new HttpRequest('GET', '/proxy/redirect?foo#bar');
|
||||
var client = new HttpClient(
|
||||
'http://another.server.com', undefined, server.url());
|
||||
return client.send(request).then(function(response) {
|
||||
assert.equal(200, response.status);
|
||||
assert.equal(response.headers.get('host'), 'another.server.com');
|
||||
assert.equal(
|
||||
response.headers.get('x-proxy-request-uri'),
|
||||
'http://another.server.com/proxy?foo#bar');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
178
node_modules/selenium-webdriver/test/http/util_test.js
generated
vendored
Normal file
178
node_modules/selenium-webdriver/test/http/util_test.js
generated
vendored
Normal file
|
@ -0,0 +1,178 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const http = require('http');
|
||||
|
||||
const error = require('../../lib/error');
|
||||
const util = require('../../http/util');
|
||||
const promise = require('../../lib/promise');
|
||||
|
||||
describe('selenium-webdriver/http/util', function() {
|
||||
|
||||
var server, baseUrl;
|
||||
|
||||
var status, value, responseCode;
|
||||
|
||||
function startServer(done) {
|
||||
if (server) return done();
|
||||
|
||||
server = http.createServer(function(req, res) {
|
||||
var data = JSON.stringify({status: status, value: value});
|
||||
res.writeHead(responseCode, {
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
'Content-Length': Buffer.byteLength(data, 'utf8')
|
||||
});
|
||||
res.end(data);
|
||||
});
|
||||
|
||||
server.listen(0, '127.0.0.1', function(e) {
|
||||
if (e) return done(e);
|
||||
|
||||
var addr = server.address();
|
||||
baseUrl = 'http://' + addr.address + ':' + addr.port;
|
||||
done();
|
||||
});
|
||||
}
|
||||
|
||||
function killServer(done) {
|
||||
if (!server) return done();
|
||||
server.close(done);
|
||||
server = null;
|
||||
}
|
||||
|
||||
after(killServer);
|
||||
|
||||
beforeEach(function(done) {
|
||||
status = 0;
|
||||
value = 'abc123';
|
||||
responseCode = 200;
|
||||
startServer(done);
|
||||
});
|
||||
|
||||
describe('#getStatus', function() {
|
||||
it('should return value field on success', function() {
|
||||
return util.getStatus(baseUrl).then(function(response) {
|
||||
assert.equal('abc123', response);
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if response object is not success', function() {
|
||||
status = 1;
|
||||
return util.getStatus(baseUrl).then(function() {
|
||||
throw Error('expected a failure');
|
||||
}, function(err) {
|
||||
assert.ok(err instanceof error.WebDriverError);
|
||||
assert.equal(err.code, error.WebDriverError.code);
|
||||
assert.equal(err.message, value);
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if the server is not listening', function(done) {
|
||||
killServer(function(e) {
|
||||
if(e) return done(e);
|
||||
|
||||
util.getStatus(baseUrl).then(function() {
|
||||
done(Error('expected a failure'));
|
||||
}, function() {
|
||||
// Expected.
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail if HTTP status is not 200', function() {
|
||||
status = 1;
|
||||
responseCode = 404;
|
||||
return util.getStatus(baseUrl).then(function() {
|
||||
throw Error('expected a failure');
|
||||
}, function(err) {
|
||||
assert.ok(err instanceof error.WebDriverError);
|
||||
assert.equal(err.code, error.WebDriverError.code);
|
||||
assert.equal(err.message, value);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#waitForServer', function() {
|
||||
it('resolves when server is ready', function() {
|
||||
status = 1;
|
||||
setTimeout(function() { status = 0; }, 50);
|
||||
return util.waitForServer(baseUrl, 100);
|
||||
});
|
||||
|
||||
it('should fail if server does not become ready', function() {
|
||||
status = 1;
|
||||
return util.waitForServer(baseUrl, 50).
|
||||
then(function() {throw Error('Expected to time out')},
|
||||
function() {});
|
||||
});
|
||||
|
||||
it('can cancel wait', function() {
|
||||
status = 1;
|
||||
let cancel = new Promise(resolve => {
|
||||
setTimeout(_ => resolve(), 50)
|
||||
});
|
||||
return util.waitForServer(baseUrl, 200, cancel)
|
||||
.then(
|
||||
() => { throw Error('Did not expect to succeed!'); },
|
||||
(e) => assert.ok(e instanceof promise.CancellationError));
|
||||
});
|
||||
});
|
||||
|
||||
describe('#waitForUrl', function() {
|
||||
it('succeeds when URL returns 2xx', function() {
|
||||
responseCode = 404;
|
||||
setTimeout(function() { responseCode = 200; }, 50);
|
||||
|
||||
return util.waitForUrl(baseUrl, 200);
|
||||
});
|
||||
|
||||
it('fails if URL always returns 4xx', function() {
|
||||
responseCode = 404;
|
||||
|
||||
return util.waitForUrl(baseUrl, 50)
|
||||
.then(() => assert.fail('Expected to time out'),
|
||||
() => true);
|
||||
});
|
||||
|
||||
it('fails if cannot connect to server', function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
killServer(function(e) {
|
||||
if (e) return reject(e);
|
||||
|
||||
util.waitForUrl(baseUrl, 50).
|
||||
then(function() { reject(Error('Expected to time out')); },
|
||||
function() { resolve(); });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('can cancel wait', function() {
|
||||
responseCode = 404;
|
||||
let cancel = new Promise(resolve => {
|
||||
setTimeout(_ => resolve(), 50);
|
||||
});
|
||||
return util.waitForUrl(baseUrl, 200, cancel)
|
||||
.then(
|
||||
() => { throw Error('Did not expect to succeed!'); },
|
||||
(e) => assert.ok(e instanceof promise.CancellationError));
|
||||
});
|
||||
});
|
||||
});
|
160
node_modules/selenium-webdriver/test/lib/by_test.js
generated
vendored
Normal file
160
node_modules/selenium-webdriver/test/lib/by_test.js
generated
vendored
Normal file
|
@ -0,0 +1,160 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var by = require('../../lib/by');
|
||||
|
||||
describe('by', function() {
|
||||
describe('By', function() {
|
||||
describe('className', function() {
|
||||
it('delegates to By.css', function() {
|
||||
let locator = by.By.className('foo');
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('.foo', locator.value);
|
||||
});
|
||||
|
||||
it('escapes class name', function() {
|
||||
let locator = by.By.className('foo#bar');
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('.foo\\#bar', locator.value);
|
||||
});
|
||||
|
||||
it('translates compound class names', function() {
|
||||
let locator = by.By.className('a b');
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('.a.b', locator.value);
|
||||
|
||||
locator = by.By.className(' x y z-1 "g" ');
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('.x.y.z-1.\\"g\\"', locator.value);
|
||||
});
|
||||
});
|
||||
|
||||
describe('id', function() {
|
||||
it('delegates to By.css', function() {
|
||||
let locator = by.By.id('foo');
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('*[id="foo"]', locator.value);
|
||||
});
|
||||
|
||||
it('escapes the ID', function() {
|
||||
let locator = by.By.id('foo#bar');
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('*[id="foo\\#bar"]', locator.value);
|
||||
});
|
||||
});
|
||||
|
||||
describe('name', function() {
|
||||
it('delegates to By.css', function() {
|
||||
let locator = by.By.name('foo')
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('*[name="foo"]', locator.value);
|
||||
});
|
||||
|
||||
it('escapes the name', function() {
|
||||
let locator = by.By.name('foo"bar"')
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('*[name="foo\\"bar\\""]', locator.value);
|
||||
});
|
||||
|
||||
it('escapes the name when it starts with a number', function() {
|
||||
let locator = by.By.name('123foo"bar"')
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('*[name="\\31 23foo\\"bar\\""]', locator.value);
|
||||
});
|
||||
|
||||
it('escapes the name when it starts with a negative number', function() {
|
||||
let locator = by.By.name('-123foo"bar"')
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('*[name="-\\31 23foo\\"bar\\""]', locator.value);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkedLocator', function() {
|
||||
it('accepts a By instance', function() {
|
||||
let original = by.By.name('foo');
|
||||
let locator = by.checkedLocator(original);
|
||||
assert.strictEqual(locator, original);
|
||||
});
|
||||
|
||||
it('accepts custom locator functions', function() {
|
||||
let original = function() {};
|
||||
let locator = by.checkedLocator(original);
|
||||
assert.strictEqual(locator, original);
|
||||
});
|
||||
|
||||
// See https://github.com/SeleniumHQ/selenium/issues/3056
|
||||
it('accepts By-like objects', function() {
|
||||
let fakeBy = {using: 'id', value: 'foo'};
|
||||
let locator = by.checkedLocator(fakeBy);
|
||||
assert.strictEqual(locator.constructor, by.By);
|
||||
assert.equal(locator.using, 'id');
|
||||
assert.equal(locator.value, 'foo');
|
||||
});
|
||||
|
||||
it('accepts class name', function() {
|
||||
let locator = by.checkedLocator({className: 'foo'});
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('.foo', locator.value);
|
||||
});
|
||||
|
||||
it('accepts css', function() {
|
||||
let locator = by.checkedLocator({css: 'a > b'});
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('a > b', locator.value);
|
||||
});
|
||||
|
||||
it('accepts id', function() {
|
||||
let locator = by.checkedLocator({id: 'foobar'});
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('*[id="foobar"]', locator.value);
|
||||
});
|
||||
|
||||
it('accepts linkText', function() {
|
||||
let locator = by.checkedLocator({linkText: 'hello'});
|
||||
assert.equal('link text', locator.using);
|
||||
assert.equal('hello', locator.value);
|
||||
});
|
||||
|
||||
it('accepts name', function() {
|
||||
let locator = by.checkedLocator({name: 'foobar'});
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('*[name="foobar"]', locator.value);
|
||||
});
|
||||
|
||||
it('accepts partialLinkText', function() {
|
||||
let locator = by.checkedLocator({partialLinkText: 'hello'});
|
||||
assert.equal('partial link text', locator.using);
|
||||
assert.equal('hello', locator.value);
|
||||
});
|
||||
|
||||
it('accepts tagName', function() {
|
||||
let locator = by.checkedLocator({tagName: 'div'});
|
||||
assert.equal('css selector', locator.using);
|
||||
assert.equal('div', locator.value);
|
||||
});
|
||||
|
||||
it('accepts xpath', function() {
|
||||
let locator = by.checkedLocator({xpath: '//div[1]'});
|
||||
assert.equal('xpath', locator.using);
|
||||
assert.equal('//div[1]', locator.value);
|
||||
});
|
||||
});
|
||||
});
|
111
node_modules/selenium-webdriver/test/lib/capabilities_test.js
generated
vendored
Normal file
111
node_modules/selenium-webdriver/test/lib/capabilities_test.js
generated
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
const Capabilities = require('../../lib/capabilities').Capabilities;
|
||||
const Symbols = require('../../lib/symbols');
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
describe('Capabilities', function() {
|
||||
it('can set and unset a capability', function() {
|
||||
let caps = new Capabilities();
|
||||
assert.equal(undefined, caps.get('foo'));
|
||||
assert.ok(!caps.has('foo'));
|
||||
|
||||
caps.set('foo', 'bar');
|
||||
assert.equal('bar', caps.get('foo'));
|
||||
assert.ok(caps.has('foo'));
|
||||
|
||||
caps.set('foo', null);
|
||||
assert.equal(null, caps.get('foo'));
|
||||
assert.ok(caps.has('foo'));
|
||||
});
|
||||
|
||||
it('requires string capability keys', function() {
|
||||
let caps = new Capabilities();
|
||||
assert.throws(() => caps.set({}, 'hi'));
|
||||
});
|
||||
|
||||
it('can merge capabilities', function() {
|
||||
let caps1 = new Capabilities()
|
||||
.set('foo', 'bar')
|
||||
.set('color', 'red');
|
||||
|
||||
let caps2 = new Capabilities()
|
||||
.set('color', 'green');
|
||||
|
||||
assert.equal('bar', caps1.get('foo'));
|
||||
assert.equal('red', caps1.get('color'));
|
||||
assert.equal('green', caps2.get('color'));
|
||||
assert.equal(undefined, caps2.get('foo'));
|
||||
|
||||
caps2.merge(caps1);
|
||||
assert.equal('bar', caps1.get('foo'));
|
||||
assert.equal('red', caps1.get('color'));
|
||||
assert.equal('red', caps2.get('color'));
|
||||
assert.equal('bar', caps2.get('foo'));
|
||||
});
|
||||
|
||||
it('can be initialized from a hash object', function() {
|
||||
let caps = new Capabilities({'one': 123, 'abc': 'def'});
|
||||
assert.equal(123, caps.get('one'));
|
||||
assert.equal('def', caps.get('abc'));
|
||||
});
|
||||
|
||||
it('can be initialized from a map', function() {
|
||||
let m = new Map([['one', 123], ['abc', 'def']]);
|
||||
|
||||
let caps = new Capabilities(m);
|
||||
assert.equal(123, caps.get('one'));
|
||||
assert.equal('def', caps.get('abc'));
|
||||
});
|
||||
|
||||
describe('serialize', function() {
|
||||
it('works for simple capabilities', function() {
|
||||
let m = new Map([['one', 123], ['abc', 'def']]);
|
||||
let caps = new Capabilities(m);
|
||||
assert.deepEqual({one: 123, abc: 'def'}, caps[Symbols.serialize]());
|
||||
});
|
||||
|
||||
it('does not omit capabilities set to a false-like value', function() {
|
||||
let caps = new Capabilities;
|
||||
caps.set('bool', false);
|
||||
caps.set('number', 0);
|
||||
caps.set('string', '');
|
||||
|
||||
assert.deepEqual(
|
||||
{bool: false, number: 0, string: ''},
|
||||
caps[Symbols.serialize]());
|
||||
});
|
||||
|
||||
it('omits capabilities with a null value', function() {
|
||||
let caps = new Capabilities;
|
||||
caps.set('foo', null);
|
||||
caps.set('bar', 123);
|
||||
assert.deepEqual({bar: 123}, caps[Symbols.serialize]());
|
||||
});
|
||||
|
||||
it('omits capabilities with an undefined value', function() {
|
||||
let caps = new Capabilities;
|
||||
caps.set('foo', undefined);
|
||||
caps.set('bar', 123);
|
||||
assert.deepEqual({bar: 123}, caps[Symbols.serialize]());
|
||||
});
|
||||
});
|
||||
});
|
177
node_modules/selenium-webdriver/test/lib/events_test.js
generated
vendored
Normal file
177
node_modules/selenium-webdriver/test/lib/events_test.js
generated
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
const EventEmitter = require('../../lib/events').EventEmitter;
|
||||
|
||||
const assert = require('assert');
|
||||
const sinon = require('sinon');
|
||||
|
||||
describe('EventEmitter', function() {
|
||||
describe('#emit()', function() {
|
||||
it('can emit events when nothing is registered', function() {
|
||||
let emitter = new EventEmitter;
|
||||
emitter.emit('foo');
|
||||
// Ok if no errors are thrown.
|
||||
});
|
||||
|
||||
it('can pass args to listeners on emit', function() {
|
||||
let emitter = new EventEmitter;
|
||||
let now = Date.now();
|
||||
|
||||
let messages = [];
|
||||
emitter.on('foo', (arg) => messages.push(arg));
|
||||
|
||||
emitter.emit('foo', now);
|
||||
assert.deepEqual([now], messages);
|
||||
|
||||
emitter.emit('foo', now + 15);
|
||||
assert.deepEqual([now, now + 15], messages);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#addListener()', function() {
|
||||
it('can add multiple listeners for one event', function() {
|
||||
let emitter = new EventEmitter;
|
||||
let count = 0;
|
||||
emitter.addListener('foo', () => count++);
|
||||
emitter.addListener('foo', () => count++);
|
||||
emitter.addListener('foo', () => count++);
|
||||
emitter.emit('foo');
|
||||
assert.equal(3, count);
|
||||
});
|
||||
|
||||
it('only registers each listener function once', function() {
|
||||
let emitter = new EventEmitter;
|
||||
let count = 0;
|
||||
let onFoo = () => count++;
|
||||
emitter.addListener('foo', onFoo);
|
||||
emitter.addListener('foo', onFoo);
|
||||
emitter.addListener('foo', onFoo);
|
||||
|
||||
emitter.emit('foo');
|
||||
assert.equal(1, count);
|
||||
|
||||
emitter.emit('foo');
|
||||
assert.equal(2, count);
|
||||
});
|
||||
|
||||
it('allows users to specify a custom scope', function() {
|
||||
let obj = {
|
||||
count: 0,
|
||||
inc: function() {
|
||||
this.count++;
|
||||
}
|
||||
};
|
||||
let emitter = new EventEmitter;
|
||||
emitter.addListener('foo', obj.inc, obj);
|
||||
|
||||
emitter.emit('foo');
|
||||
assert.equal(1, obj.count);
|
||||
|
||||
emitter.emit('foo');
|
||||
assert.equal(2, obj.count);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#once()', function() {
|
||||
it('only calls registered callback once', function() {
|
||||
let emitter = new EventEmitter;
|
||||
let count = 0;
|
||||
emitter.once('foo', () => count++);
|
||||
emitter.once('foo', () => count++);
|
||||
emitter.once('foo', () => count++);
|
||||
|
||||
emitter.emit('foo');
|
||||
assert.equal(3, count);
|
||||
|
||||
emitter.emit('foo');
|
||||
assert.equal(3, count);
|
||||
|
||||
emitter.emit('foo');
|
||||
assert.equal(3, count);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#removeListeners()', function() {
|
||||
it('only removes the given listener function', function() {
|
||||
let emitter = new EventEmitter;
|
||||
let count = 0;
|
||||
emitter.addListener('foo', () => count++);
|
||||
emitter.addListener('foo', () => count++);
|
||||
|
||||
let toRemove = () => count++;
|
||||
emitter.addListener('foo', toRemove);
|
||||
|
||||
emitter.emit('foo');
|
||||
assert.equal(3, count);
|
||||
|
||||
emitter.removeListener('foo', toRemove);
|
||||
emitter.emit('foo');
|
||||
assert.equal(5, count);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#removeAllListeners()', function() {
|
||||
it('only removes listeners for type if specified', function() {
|
||||
let emitter = new EventEmitter;
|
||||
let count = 0;
|
||||
emitter.addListener('foo', () => count++);
|
||||
emitter.addListener('foo', () => count++);
|
||||
emitter.addListener('foo', () => count++);
|
||||
emitter.addListener('bar', () => count++);
|
||||
|
||||
emitter.emit('foo');
|
||||
assert.equal(3, count);
|
||||
|
||||
emitter.removeAllListeners('foo');
|
||||
|
||||
emitter.emit('foo');
|
||||
assert.equal(3, count);
|
||||
|
||||
emitter.emit('bar');
|
||||
assert.equal(4, count);
|
||||
});
|
||||
|
||||
it('removes absolutely all listeners if no type specified', function() {
|
||||
let emitter = new EventEmitter;
|
||||
let count = 0;
|
||||
emitter.addListener('foo', () => count++);
|
||||
emitter.addListener('bar', () => count++);
|
||||
emitter.addListener('baz', () => count++);
|
||||
emitter.addListener('baz', () => count++);
|
||||
|
||||
emitter.emit('foo');
|
||||
assert.equal(1, count);
|
||||
|
||||
emitter.emit('baz');
|
||||
assert.equal(3, count);
|
||||
|
||||
emitter.removeAllListeners();
|
||||
|
||||
emitter.emit('foo');
|
||||
assert.equal(3, count);
|
||||
|
||||
emitter.emit('bar');
|
||||
assert.equal(3, count);
|
||||
|
||||
emitter.emit('baz');
|
||||
assert.equal(3, count);
|
||||
});
|
||||
});
|
||||
});
|
272
node_modules/selenium-webdriver/test/lib/logging_test.js
generated
vendored
Normal file
272
node_modules/selenium-webdriver/test/lib/logging_test.js
generated
vendored
Normal file
|
@ -0,0 +1,272 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const sinon = require('sinon');
|
||||
const logging = require('../../lib/logging');
|
||||
|
||||
describe('logging', function() {
|
||||
let mgr, root, clock;
|
||||
|
||||
beforeEach(function setUp() {
|
||||
mgr = new logging.LogManager;
|
||||
root = mgr.getLogger('');
|
||||
|
||||
clock = sinon.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(function tearDown() {
|
||||
clock.restore();
|
||||
});
|
||||
|
||||
describe('LogManager', function() {
|
||||
describe('getLogger()', function() {
|
||||
it('handles falsey input', function() {
|
||||
assert.strictEqual(root, mgr.getLogger());
|
||||
assert.strictEqual(root, mgr.getLogger(''));
|
||||
assert.strictEqual(root, mgr.getLogger(null));
|
||||
assert.strictEqual(root, mgr.getLogger(0));
|
||||
});
|
||||
|
||||
it('creates parent loggers', function() {
|
||||
let logger = mgr.getLogger('foo.bar.baz');
|
||||
assert.strictEqual(logger.parent_, mgr.getLogger('foo.bar'));
|
||||
|
||||
logger = logger.parent_;
|
||||
assert.strictEqual(logger.parent_, mgr.getLogger('foo'));
|
||||
|
||||
logger = logger.parent_;
|
||||
assert.strictEqual(logger.parent_, mgr.getLogger(''));
|
||||
|
||||
assert.strictEqual(logger.parent_.parent_, null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Logger', function() {
|
||||
describe('getEffectiveLevel()', function() {
|
||||
it('defaults to OFF', function() {
|
||||
assert.strictEqual(root.getLevel(), logging.Level.OFF);
|
||||
assert.strictEqual(root.getEffectiveLevel(), logging.Level.OFF);
|
||||
|
||||
root.setLevel(null);
|
||||
assert.strictEqual(root.getLevel(), null);
|
||||
assert.strictEqual(root.getEffectiveLevel(), logging.Level.OFF);
|
||||
});
|
||||
|
||||
it('uses own level if set', function() {
|
||||
let logger = mgr.getLogger('foo.bar.baz');
|
||||
assert.strictEqual(logger.getLevel(), null);
|
||||
assert.strictEqual(logger.getEffectiveLevel(), logging.Level.OFF);
|
||||
|
||||
logger.setLevel(logging.Level.INFO);
|
||||
assert.strictEqual(logger.getLevel(), logging.Level.INFO);
|
||||
assert.strictEqual(logger.getEffectiveLevel(), logging.Level.INFO);
|
||||
});
|
||||
|
||||
it('uses level from set on nearest parent', function() {
|
||||
let ancestor = mgr.getLogger('foo');
|
||||
ancestor.setLevel(logging.Level.SEVERE);
|
||||
|
||||
let logger = mgr.getLogger('foo.bar.baz');
|
||||
assert.strictEqual(logger.getLevel(), null);
|
||||
assert.strictEqual(logger.getEffectiveLevel(), logging.Level.SEVERE);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isLoggable()', function() {
|
||||
it('compares level against logger\'s effective level', function() {
|
||||
const log1 = mgr.getLogger('foo');
|
||||
log1.setLevel(logging.Level.WARNING);
|
||||
|
||||
const log2 = mgr.getLogger('foo.bar.baz');
|
||||
|
||||
assert(!log2.isLoggable(logging.Level.FINEST));
|
||||
assert(!log2.isLoggable(logging.Level.INFO));
|
||||
assert(log2.isLoggable(logging.Level.WARNING));
|
||||
assert(log2.isLoggable(logging.Level.SEVERE));
|
||||
|
||||
log2.setLevel(logging.Level.INFO);
|
||||
|
||||
assert(!log2.isLoggable(logging.Level.FINEST));
|
||||
assert(log2.isLoggable(logging.Level.INFO));
|
||||
assert(log2.isLoggable(logging.Level.WARNING));
|
||||
assert(log2.isLoggable(logging.Level.SEVERE));
|
||||
|
||||
log2.setLevel(logging.Level.ALL);
|
||||
|
||||
assert(log2.isLoggable(logging.Level.FINEST));
|
||||
assert(log2.isLoggable(logging.Level.INFO));
|
||||
assert(log2.isLoggable(logging.Level.WARNING));
|
||||
assert(log2.isLoggable(logging.Level.SEVERE));
|
||||
});
|
||||
|
||||
it('Level.OFF is never loggable', function() {
|
||||
function test(level) {
|
||||
root.setLevel(level);
|
||||
assert(!root.isLoggable(logging.Level.OFF),
|
||||
'OFF should not be loggable at ' + level);
|
||||
}
|
||||
|
||||
test(logging.Level.ALL);
|
||||
test(logging.Level.INFO);
|
||||
test(logging.Level.OFF);
|
||||
});
|
||||
});
|
||||
|
||||
describe('log()', function() {
|
||||
it('does not invoke loggable if message is not loggable', function() {
|
||||
const log = mgr.getLogger('foo');
|
||||
log.setLevel(logging.Level.OFF);
|
||||
|
||||
let callback = sinon.spy();
|
||||
log.addHandler(callback);
|
||||
root.addHandler(callback);
|
||||
|
||||
assert(!callback.called);
|
||||
});
|
||||
|
||||
it('invokes handlers for each parent logger', function() {
|
||||
const cb1 = sinon.spy();
|
||||
const cb2 = sinon.spy();
|
||||
const cb3 = sinon.spy();
|
||||
const cb4 = sinon.spy();
|
||||
|
||||
const log1 = mgr.getLogger('foo');
|
||||
const log2 = mgr.getLogger('foo.bar');
|
||||
const log3 = mgr.getLogger('foo.bar.baz');
|
||||
const log4 = mgr.getLogger('foo.bar.baz.quot');
|
||||
|
||||
log1.addHandler(cb1);
|
||||
log1.setLevel(logging.Level.INFO);
|
||||
|
||||
log2.addHandler(cb2);
|
||||
log2.setLevel(logging.Level.WARNING);
|
||||
|
||||
log3.addHandler(cb3);
|
||||
log3.setLevel(logging.Level.FINER);
|
||||
|
||||
clock.tick(123456);
|
||||
|
||||
log4.finest('this is the finest message');
|
||||
log4.finer('this is a finer message');
|
||||
log4.info('this is an info message');
|
||||
log4.warning('this is a warning message');
|
||||
log4.severe('this is a severe message');
|
||||
|
||||
assert.equal(4, cb1.callCount);
|
||||
assert.equal(4, cb2.callCount);
|
||||
assert.equal(4, cb3.callCount);
|
||||
|
||||
const entry1 = new logging.Entry(
|
||||
logging.Level.FINER,
|
||||
'[foo.bar.baz.quot] this is a finer message',
|
||||
123456);
|
||||
const entry2 = new logging.Entry(
|
||||
logging.Level.INFO,
|
||||
'[foo.bar.baz.quot] this is an info message',
|
||||
123456);
|
||||
const entry3 = new logging.Entry(
|
||||
logging.Level.WARNING,
|
||||
'[foo.bar.baz.quot] this is a warning message',
|
||||
123456);
|
||||
const entry4 = new logging.Entry(
|
||||
logging.Level.SEVERE,
|
||||
'[foo.bar.baz.quot] this is a severe message',
|
||||
123456);
|
||||
|
||||
check(cb1.getCall(0).args[0], entry1);
|
||||
check(cb1.getCall(1).args[0], entry2);
|
||||
check(cb1.getCall(2).args[0], entry3);
|
||||
check(cb1.getCall(3).args[0], entry4);
|
||||
|
||||
check(cb2.getCall(0).args[0], entry1);
|
||||
check(cb2.getCall(1).args[0], entry2);
|
||||
check(cb2.getCall(2).args[0], entry3);
|
||||
check(cb2.getCall(3).args[0], entry4);
|
||||
|
||||
check(cb3.getCall(0).args[0], entry1);
|
||||
check(cb3.getCall(1).args[0], entry2);
|
||||
check(cb3.getCall(2).args[0], entry3);
|
||||
check(cb3.getCall(3).args[0], entry4);
|
||||
|
||||
function check(entry, expected) {
|
||||
assert.equal(entry.level, expected.level, 'wrong level');
|
||||
assert.equal(entry.message, expected.message, 'wrong message');
|
||||
assert.equal(entry.timestamp, expected.timestamp, 'wrong time');
|
||||
}
|
||||
});
|
||||
|
||||
it('does not invoke removed handler', function() {
|
||||
root.setLevel(logging.Level.INFO);
|
||||
const cb = sinon.spy();
|
||||
|
||||
root.addHandler(cb);
|
||||
root.info('hi');
|
||||
assert.equal(1, cb.callCount);
|
||||
|
||||
assert(root.removeHandler(cb));
|
||||
root.info('bye');
|
||||
assert.equal(1, cb.callCount);
|
||||
|
||||
assert(!root.removeHandler(cb));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getLevel()', function() {
|
||||
it('converts named levels', function() {
|
||||
assert.strictEqual(logging.Level.DEBUG, logging.getLevel('DEBUG'));
|
||||
assert.strictEqual(logging.Level.ALL, logging.getLevel('FAKE'));
|
||||
});
|
||||
|
||||
it('converts numeric levels', function() {
|
||||
assert.strictEqual(
|
||||
logging.Level.DEBUG,
|
||||
logging.getLevel(logging.Level.DEBUG.value));
|
||||
});
|
||||
|
||||
it('normalizes numeric levels', function() {
|
||||
assert.strictEqual(
|
||||
logging.Level.OFF,
|
||||
logging.getLevel(logging.Level.OFF.value * 2));
|
||||
|
||||
let diff = logging.Level.SEVERE.value - logging.Level.WARNING.value;
|
||||
assert.strictEqual(
|
||||
logging.Level.WARNING,
|
||||
logging.getLevel(logging.Level.WARNING.value + (diff * .5)));
|
||||
|
||||
assert.strictEqual(logging.Level.ALL, logging.getLevel(0));
|
||||
assert.strictEqual(logging.Level.ALL, logging.getLevel(-1));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Preferences', function() {
|
||||
it('can be converted to JSON', function() {
|
||||
let prefs = new logging.Preferences;
|
||||
assert.equal('{}', JSON.stringify(prefs));
|
||||
|
||||
prefs.setLevel('foo', logging.Level.DEBUG);
|
||||
assert.equal('{"foo":"DEBUG"}', JSON.stringify(prefs));
|
||||
|
||||
prefs.setLevel(logging.Type.BROWSER, logging.Level.FINE);
|
||||
assert.equal('{"foo":"DEBUG","browser":"FINE"}', JSON.stringify(prefs));
|
||||
});
|
||||
});
|
||||
});
|
78
node_modules/selenium-webdriver/test/lib/promise_aplus_test.js
generated
vendored
Normal file
78
node_modules/selenium-webdriver/test/lib/promise_aplus_test.js
generated
vendored
Normal file
|
@ -0,0 +1,78 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
const promise = require('../../lib/promise');
|
||||
const {enablePromiseManager} = require('../../lib/test/promise');
|
||||
|
||||
describe('Promises/A+ Compliance Tests', function() {
|
||||
enablePromiseManager(() => {
|
||||
// The promise spec does not define behavior for unhandled rejections and
|
||||
// assumes they are effectively swallowed. This is not the case with our
|
||||
// implementation, so we have to disable error propagation to test that the
|
||||
// rest of our behavior is compliant.
|
||||
// We run the tests with a separate instance of the control flow to ensure
|
||||
// disablign error propagation does not impact other tests.
|
||||
var flow = new promise.ControlFlow();
|
||||
flow.setPropagateUnhandledRejections(false);
|
||||
|
||||
// Skip the tests in 2.2.6.1/2. We are not compliant in these scenarios.
|
||||
var realDescribe = global.describe;
|
||||
global.describe = function(name, fn) {
|
||||
realDescribe(name, function() {
|
||||
var prefix = 'Promises/A+ Compliance Tests '
|
||||
+ 'SELENIUM_PROMISE_MANAGER=true 2.2.6: '
|
||||
+ '`then` may be called multiple times on the same promise.';
|
||||
var suffix = 'even when one handler is added inside another handler';
|
||||
if (this.fullTitle().startsWith(prefix)
|
||||
&& this.fullTitle().endsWith(suffix)) {
|
||||
var realSpecify = global.specify;
|
||||
try {
|
||||
global.specify = function(name) {
|
||||
realSpecify(name);
|
||||
};
|
||||
fn();
|
||||
} finally {
|
||||
global.specify = realSpecify;
|
||||
}
|
||||
} else {
|
||||
fn();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
require('promises-aplus-tests').mocha({
|
||||
resolved: function(value) {
|
||||
return new promise.Promise((fulfill) => fulfill(value), flow);
|
||||
},
|
||||
rejected: function(error) {
|
||||
return new promise.Promise((_, reject) => reject(error), flow);
|
||||
},
|
||||
deferred: function() {
|
||||
var d = new promise.Deferred(flow);
|
||||
return {
|
||||
resolve: d.fulfill,
|
||||
reject: d.reject,
|
||||
promise: d.promise
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
global.describe = realDescribe;
|
||||
});
|
||||
});
|
884
node_modules/selenium-webdriver/test/lib/promise_error_test.js
generated
vendored
Normal file
884
node_modules/selenium-webdriver/test/lib/promise_error_test.js
generated
vendored
Normal file
|
@ -0,0 +1,884 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
/**
|
||||
* @fileoverview Contains tests against promise error handling. Many tests use
|
||||
* NativePromise to control test termination independent of promise
|
||||
* (and notably promise.ControlFlow).
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const testutil = require('./testutil');
|
||||
|
||||
const assert = require('assert');
|
||||
const promise = require('../../lib/promise');
|
||||
const {enablePromiseManager} = require('../../lib/test/promise');
|
||||
|
||||
const NativePromise = Promise;
|
||||
const StubError = testutil.StubError;
|
||||
const throwStubError = testutil.throwStubError;
|
||||
const assertIsStubError = testutil.assertIsStubError;
|
||||
|
||||
describe('promise error handling', function() {
|
||||
enablePromiseManager(() => {
|
||||
var flow, uncaughtExceptions;
|
||||
|
||||
beforeEach(function setUp() {
|
||||
if (promise.USE_PROMISE_MANAGER) {
|
||||
flow = promise.controlFlow();
|
||||
uncaughtExceptions = [];
|
||||
flow.on('uncaughtException', onUncaughtException);
|
||||
}
|
||||
});
|
||||
|
||||
afterEach(function tearDown() {
|
||||
if (promise.USE_PROMISE_MANAGER) {
|
||||
return waitForIdle(flow).then(function() {
|
||||
assert.deepEqual(
|
||||
[], uncaughtExceptions, 'There were uncaught exceptions');
|
||||
flow.reset();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function onUncaughtException(e) {
|
||||
uncaughtExceptions.push(e);
|
||||
}
|
||||
|
||||
function waitForAbort(opt_flow, opt_n) {
|
||||
var n = opt_n || 1;
|
||||
var theFlow = opt_flow || flow;
|
||||
theFlow.removeAllListeners(
|
||||
promise.ControlFlow.EventType.UNCAUGHT_EXCEPTION);
|
||||
return new NativePromise(function(fulfill, reject) {
|
||||
theFlow.once('idle', function() {
|
||||
reject(Error('expected flow to report an unhandled error'));
|
||||
});
|
||||
|
||||
var errors = [];
|
||||
theFlow.on('uncaughtException', onError);
|
||||
function onError(e) {
|
||||
errors.push(e);
|
||||
if (errors.length === n) {
|
||||
theFlow.removeListener('uncaughtException', onError);
|
||||
fulfill(n === 1 ? errors[0] : errors);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function waitForIdle(opt_flow) {
|
||||
var theFlow = opt_flow || flow;
|
||||
return new NativePromise(function(fulfill, reject) {
|
||||
if (theFlow.isIdle()) {
|
||||
fulfill();
|
||||
return;
|
||||
}
|
||||
theFlow.once('idle', fulfill);
|
||||
theFlow.once('uncaughtException', reject);
|
||||
});
|
||||
}
|
||||
|
||||
it('testRejectedPromiseTriggersErrorCallback', function() {
|
||||
return promise.rejected(new StubError).
|
||||
then(assert.fail, assertIsStubError);
|
||||
});
|
||||
|
||||
describe('callback throws trigger subsequent error callback', function() {
|
||||
it('fulfilled promise', function() {
|
||||
return promise.fulfilled().
|
||||
then(throwStubError).
|
||||
then(assert.fail, assertIsStubError);
|
||||
});
|
||||
|
||||
it('rejected promise', function() {
|
||||
var e = Error('not the droids you are looking for');
|
||||
return promise.rejected(e).
|
||||
then(assert.fail, throwStubError).
|
||||
then(assert.fail, assertIsStubError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('callback returns rejected promise triggers subsequent errback', function() {
|
||||
it('from fulfilled callback', function() {
|
||||
return promise.fulfilled().then(function() {
|
||||
return promise.rejected(new StubError);
|
||||
}).then(assert.fail, assertIsStubError);
|
||||
});
|
||||
|
||||
it('from rejected callback', function() {
|
||||
var e = Error('not the droids you are looking for');
|
||||
return promise.rejected(e).
|
||||
then(assert.fail, function() {
|
||||
return promise.rejected(new StubError);
|
||||
}).
|
||||
then(assert.fail, assertIsStubError);
|
||||
});
|
||||
});
|
||||
|
||||
it('testReportsUnhandledRejectionsThroughTheControlFlow', function() {
|
||||
promise.rejected(new StubError);
|
||||
return waitForAbort().then(assertIsStubError);
|
||||
});
|
||||
|
||||
describe('multiple unhandled rejections outside a task', function() {
|
||||
it('are reported in order they occurred', function() {
|
||||
var e1 = Error('error 1');
|
||||
var e2 = Error('error 2');
|
||||
|
||||
promise.rejected(e1);
|
||||
promise.rejected(e2);
|
||||
|
||||
return waitForAbort(flow).then(function(error) {
|
||||
assert.ok(
|
||||
error instanceof promise.MultipleUnhandledRejectionError);
|
||||
// TODO: switch to Array.from when we drop node 0.12.x
|
||||
var errors = [];
|
||||
for (var e of error.errors) {
|
||||
errors.push(e);
|
||||
}
|
||||
assert.deepEqual([e1, e2], errors);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('does not report unhandled rejection when', function() {
|
||||
it('handler added before next tick', function() {
|
||||
promise.rejected(new StubError).then(assert.fail, assertIsStubError);
|
||||
return waitForIdle();
|
||||
});
|
||||
|
||||
it('added async but before next tick', function() {
|
||||
var called = false;
|
||||
return new NativePromise(function(fulfill, reject) {
|
||||
var aPromise;
|
||||
NativePromise.resolve().then(function() {
|
||||
aPromise.then(assert.fail, function(e) {
|
||||
called = true;
|
||||
assertIsStubError(e);
|
||||
});
|
||||
waitForIdle().then(fulfill, reject);
|
||||
});
|
||||
aPromise = promise.rejected(new StubError);
|
||||
}).then(function() {
|
||||
assert.ok(called);
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
it('testTaskThrows', function() {
|
||||
return flow.execute(throwStubError).then(assert.fail, assertIsStubError);
|
||||
});
|
||||
|
||||
it('testTaskReturnsRejectedPromise', function() {
|
||||
return flow.execute(function() {
|
||||
return promise.rejected(new StubError)
|
||||
}).then(assert.fail, assertIsStubError);
|
||||
});
|
||||
|
||||
it('testTaskHasUnhandledRejection', function() {
|
||||
return flow.execute(function() {
|
||||
promise.rejected(new StubError)
|
||||
}).then(assert.fail, assertIsStubError);
|
||||
});
|
||||
|
||||
it('testTaskfails_returnedPromiseIsUnhandled', function() {
|
||||
flow.execute(throwStubError);
|
||||
return waitForAbort().then(assertIsStubError);
|
||||
});
|
||||
|
||||
it('testTaskHasUnhandledRejection_cancelsRemainingSubTasks', function() {
|
||||
var seen = [];
|
||||
flow.execute(function() {
|
||||
promise.rejected(new StubError);
|
||||
|
||||
flow.execute(() => seen.push('a'))
|
||||
.then(() => seen.push('b'), (e) => seen.push(e));
|
||||
flow.execute(() => seen.push('c'))
|
||||
.then(() => seen.push('b'), (e) => seen.push(e));
|
||||
});
|
||||
|
||||
return waitForAbort()
|
||||
.then(assertIsStubError)
|
||||
.then(() => assert.deepEqual([], seen));
|
||||
});
|
||||
|
||||
describe('nested task failures', function() {
|
||||
it('returns up to paren', function() {
|
||||
return flow.execute(function() {
|
||||
return flow.execute(function() {
|
||||
return flow.execute(throwStubError);
|
||||
});
|
||||
}).then(assert.fail, assertIsStubError);
|
||||
});
|
||||
|
||||
it('task throws; uncaught error bubbles up', function() {
|
||||
flow.execute(function() {
|
||||
flow.execute(function() {
|
||||
flow.execute(throwStubError);
|
||||
});
|
||||
});
|
||||
return waitForAbort().then(assertIsStubError);
|
||||
});
|
||||
|
||||
it('task throws; uncaught error bubbles up; is caught at root', function() {
|
||||
flow.execute(function() {
|
||||
flow.execute(function() {
|
||||
flow.execute(throwStubError);
|
||||
});
|
||||
}).then(assert.fail, assertIsStubError);
|
||||
return waitForIdle();
|
||||
});
|
||||
|
||||
it('unhandled rejection bubbles up', function() {
|
||||
flow.execute(function() {
|
||||
flow.execute(function() {
|
||||
flow.execute(function() {
|
||||
promise.rejected(new StubError);
|
||||
});
|
||||
});
|
||||
});
|
||||
return waitForAbort().then(assertIsStubError);
|
||||
});
|
||||
|
||||
it('unhandled rejection bubbles up; caught at root', function() {
|
||||
flow.execute(function() {
|
||||
flow.execute(function() {
|
||||
promise.rejected(new StubError);
|
||||
});
|
||||
}).then(assert.fail, assertIsStubError);
|
||||
return waitForIdle();
|
||||
});
|
||||
|
||||
it('mixtureof hanging and free subtasks', function() {
|
||||
flow.execute(function() {
|
||||
return flow.execute(function() {
|
||||
flow.execute(throwStubError);
|
||||
});
|
||||
});
|
||||
return waitForAbort().then(assertIsStubError);
|
||||
});
|
||||
|
||||
it('cancels remaining tasks', function() {
|
||||
var seen = [];
|
||||
flow.execute(function() {
|
||||
flow.execute(() => promise.rejected(new StubError));
|
||||
flow.execute(() => seen.push('a'))
|
||||
.then(() => seen.push('b'), (e) => seen.push(e));
|
||||
flow.execute(() => seen.push('c'))
|
||||
.then(() => seen.push('b'), (e) => seen.push(e));
|
||||
});
|
||||
|
||||
return waitForAbort()
|
||||
.then(assertIsStubError)
|
||||
.then(() => assert.deepEqual([], seen));
|
||||
});
|
||||
});
|
||||
|
||||
it('testTaskReturnsPromiseLikeObjectThatInvokesErrback', function() {
|
||||
return flow.execute(function() {
|
||||
return {
|
||||
'then': function(_, errback) {
|
||||
errback('abc123');
|
||||
}
|
||||
};
|
||||
}).then(assert.fail, function(value) {
|
||||
assert.equal('abc123', value);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ControlFlow#wait();', function() {
|
||||
describe('condition throws;', function() {
|
||||
it('failure is caught', function() {
|
||||
return flow.wait(throwStubError, 50).then(assert.fail, assertIsStubError);
|
||||
});
|
||||
|
||||
it('failure is not caught', function() {
|
||||
flow.wait(throwStubError, 50);
|
||||
return waitForAbort().then(assertIsStubError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('condition returns promise', function() {
|
||||
it('failure is caught', function() {
|
||||
return flow.wait(function() {
|
||||
return promise.rejected(new StubError);
|
||||
}, 50).then(assert.fail, assertIsStubError);
|
||||
});
|
||||
|
||||
it('failure is not caught', function() {
|
||||
flow.wait(function() {
|
||||
return promise.rejected(new StubError);
|
||||
}, 50);
|
||||
return waitForAbort().then(assertIsStubError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('condition has unhandled promise rejection', function() {
|
||||
it('failure is caught', function() {
|
||||
return flow.wait(function() {
|
||||
promise.rejected(new StubError);
|
||||
}, 50).then(assert.fail, assertIsStubError);
|
||||
});
|
||||
|
||||
it('failure is not caught', function() {
|
||||
flow.wait(function() {
|
||||
promise.rejected(new StubError);
|
||||
}, 50);
|
||||
return waitForAbort().then(assertIsStubError);
|
||||
});
|
||||
});
|
||||
|
||||
describe('condition has subtask failure', function() {
|
||||
it('failure is caught', function() {
|
||||
return flow.wait(function() {
|
||||
flow.execute(function() {
|
||||
flow.execute(throwStubError);
|
||||
});
|
||||
}, 50).then(assert.fail, assertIsStubError);
|
||||
});
|
||||
|
||||
it('failure is not caught', function() {
|
||||
flow.wait(function() {
|
||||
flow.execute(function() {
|
||||
flow.execute(throwStubError);
|
||||
});
|
||||
}, 50);
|
||||
return waitForAbort().then(assertIsStubError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('errback throws a new error', function() {
|
||||
it('start with normal promise', function() {
|
||||
var error = Error('an error');
|
||||
return promise.rejected(error).
|
||||
catch(function(e) {
|
||||
assert.equal(e, error);
|
||||
throw new StubError;
|
||||
}).
|
||||
catch(assertIsStubError);
|
||||
});
|
||||
|
||||
it('start with task result', function() {
|
||||
var error = Error('an error');
|
||||
return flow.execute(function() {
|
||||
throw error;
|
||||
}).
|
||||
catch(function(e) {
|
||||
assert.equal(e, error);
|
||||
throw new StubError;
|
||||
}).
|
||||
catch(assertIsStubError);
|
||||
});
|
||||
|
||||
it('start with normal promise; uncaught error', function() {
|
||||
var error = Error('an error');
|
||||
promise.rejected(error).
|
||||
catch(function(e) {
|
||||
assert.equal(e, error);
|
||||
throw new StubError;
|
||||
});
|
||||
return waitForAbort().then(assertIsStubError);
|
||||
});
|
||||
|
||||
it('start with task result; uncaught error', function() {
|
||||
var error = Error('an error');
|
||||
flow.execute(function() {
|
||||
throw error;
|
||||
}).
|
||||
catch(function(e) {
|
||||
assert.equal(e, error);
|
||||
throw new StubError;
|
||||
});
|
||||
return waitForAbort().then(assertIsStubError);
|
||||
});
|
||||
});
|
||||
|
||||
it('thrownPromiseCausesCallbackRejection', function() {
|
||||
let p = promise.fulfilled(1234);
|
||||
return promise.fulfilled().then(function() {
|
||||
throw p;
|
||||
}).then(assert.fail, function(value) {
|
||||
assert.strictEqual(p, value);
|
||||
});
|
||||
});
|
||||
|
||||
describe('task throws promise', function() {
|
||||
it('promise was fulfilled', function() {
|
||||
var toThrow = promise.fulfilled(1234);
|
||||
flow.execute(function() {
|
||||
throw toThrow;
|
||||
}).then(assert.fail, function(value) {
|
||||
assert.equal(toThrow, value);
|
||||
return toThrow;
|
||||
}).then(function(value) {
|
||||
assert.equal(1234, value);
|
||||
});
|
||||
return waitForIdle();
|
||||
});
|
||||
|
||||
it('promise was rejected', function() {
|
||||
var toThrow = promise.rejected(new StubError);
|
||||
toThrow.catch(function() {}); // For tearDown.
|
||||
flow.execute(function() {
|
||||
throw toThrow;
|
||||
}).then(assert.fail, function(e) {
|
||||
assert.equal(toThrow, e);
|
||||
return e;
|
||||
}).then(assert.fail, assertIsStubError);
|
||||
return waitForIdle();
|
||||
});
|
||||
});
|
||||
|
||||
it('testFailsTaskIfThereIsAnUnhandledErrorWhileWaitingOnTaskResult', function() {
|
||||
var d = promise.defer();
|
||||
flow.execute(function() {
|
||||
promise.rejected(new StubError);
|
||||
return d.promise;
|
||||
}).then(assert.fail, assertIsStubError);
|
||||
|
||||
return waitForIdle().then(function() {
|
||||
return d.promise;
|
||||
}).then(assert.fail, function(e) {
|
||||
assert.equal('CancellationError: StubError', e.toString());
|
||||
});
|
||||
});
|
||||
|
||||
it('testFailsParentTaskIfAsyncScheduledTaskFails', function() {
|
||||
var d = promise.defer();
|
||||
flow.execute(function() {
|
||||
flow.execute(throwStubError);
|
||||
return d.promise;
|
||||
}).then(assert.fail, assertIsStubError);
|
||||
|
||||
return waitForIdle().then(function() {
|
||||
return d.promise;
|
||||
}).then(assert.fail, function(e) {
|
||||
assert.equal('CancellationError: StubError', e.toString());
|
||||
});
|
||||
});
|
||||
|
||||
describe('long stack traces', function() {
|
||||
afterEach(() => promise.LONG_STACK_TRACES = false);
|
||||
|
||||
it('always includes task stacks in failures', function() {
|
||||
promise.LONG_STACK_TRACES = false;
|
||||
flow.execute(function() {
|
||||
flow.execute(function() {
|
||||
flow.execute(throwStubError, 'throw error');
|
||||
}, 'two');
|
||||
}, 'three').
|
||||
then(assert.fail, function(e) {
|
||||
assertIsStubError(e);
|
||||
if (typeof e.stack !== 'string') {
|
||||
return;
|
||||
}
|
||||
var messages = e.stack.split(/\n/).filter(function(line, index) {
|
||||
return /^From: /.test(line);
|
||||
});
|
||||
assert.deepEqual([
|
||||
'From: Task: throw error',
|
||||
'From: Task: two',
|
||||
'From: Task: three'
|
||||
], messages);
|
||||
});
|
||||
return waitForIdle();
|
||||
});
|
||||
|
||||
it('does not include completed tasks', function () {
|
||||
flow.execute(function() {}, 'succeeds');
|
||||
flow.execute(throwStubError, 'kaboom').then(assert.fail, function(e) {
|
||||
assertIsStubError(e);
|
||||
if (typeof e.stack !== 'string') {
|
||||
return;
|
||||
}
|
||||
var messages = e.stack.split(/\n/).filter(function(line, index) {
|
||||
return /^From: /.test(line);
|
||||
});
|
||||
assert.deepEqual(['From: Task: kaboom'], messages);
|
||||
});
|
||||
return waitForIdle();
|
||||
});
|
||||
|
||||
it('does not include promise chain when disabled', function() {
|
||||
promise.LONG_STACK_TRACES = false;
|
||||
flow.execute(function() {
|
||||
flow.execute(function() {
|
||||
return promise.fulfilled().
|
||||
then(function() {}).
|
||||
then(function() {}).
|
||||
then(throwStubError);
|
||||
}, 'eventually assert.fails');
|
||||
}, 'start').
|
||||
then(assert.fail, function(e) {
|
||||
assertIsStubError(e);
|
||||
if (typeof e.stack !== 'string') {
|
||||
return;
|
||||
}
|
||||
var messages = e.stack.split(/\n/).filter(function(line, index) {
|
||||
return /^From: /.test(line);
|
||||
});
|
||||
assert.deepEqual([
|
||||
'From: Task: eventually assert.fails',
|
||||
'From: Task: start'
|
||||
], messages);
|
||||
});
|
||||
return waitForIdle();
|
||||
});
|
||||
|
||||
it('includes promise chain when enabled', function() {
|
||||
promise.LONG_STACK_TRACES = true;
|
||||
flow.execute(function() {
|
||||
flow.execute(function() {
|
||||
return promise.fulfilled().
|
||||
then(function() {}).
|
||||
then(function() {}).
|
||||
then(throwStubError);
|
||||
}, 'eventually assert.fails');
|
||||
}, 'start').
|
||||
then(assert.fail, function(e) {
|
||||
assertIsStubError(e);
|
||||
if (typeof e.stack !== 'string') {
|
||||
return;
|
||||
}
|
||||
var messages = e.stack.split(/\n/).filter(function(line, index) {
|
||||
return /^From: /.test(line);
|
||||
});
|
||||
assert.deepEqual([
|
||||
'From: Promise: then',
|
||||
'From: Task: eventually assert.fails',
|
||||
'From: Task: start'
|
||||
], messages);
|
||||
});
|
||||
return waitForIdle();
|
||||
});
|
||||
});
|
||||
|
||||
describe('frame cancels remaining tasks', function() {
|
||||
it('on unhandled task failure', function() {
|
||||
var run = false;
|
||||
return flow.execute(function() {
|
||||
flow.execute(throwStubError);
|
||||
flow.execute(function() { run = true; });
|
||||
}).then(assert.fail, function(e) {
|
||||
assertIsStubError(e);
|
||||
assert.ok(!run);
|
||||
});
|
||||
});
|
||||
|
||||
it('on unhandled promise rejection', function() {
|
||||
var run = false;
|
||||
return flow.execute(function() {
|
||||
promise.rejected(new StubError);
|
||||
flow.execute(function() { run = true; });
|
||||
}).then(assert.fail, function(e) {
|
||||
assertIsStubError(e);
|
||||
assert.ok(!run);
|
||||
});
|
||||
});
|
||||
|
||||
it('if task throws', function() {
|
||||
var run = false;
|
||||
return flow.execute(function() {
|
||||
flow.execute(function() { run = true; });
|
||||
throw new StubError;
|
||||
}).then(assert.fail, function(e) {
|
||||
assertIsStubError(e);
|
||||
assert.ok(!run);
|
||||
});
|
||||
});
|
||||
|
||||
describe('task callbacks scheduled in another frame', function() {
|
||||
flow = promise.controlFlow();
|
||||
function noop() {}
|
||||
|
||||
let subTask;
|
||||
|
||||
before(function() {
|
||||
flow.execute(function() {
|
||||
// This task will be discarded and never run because of the error below.
|
||||
subTask = flow.execute(() => 'abc');
|
||||
throw new StubError('stub');
|
||||
}).catch(noop);
|
||||
});
|
||||
|
||||
function assertCancellation(e) {
|
||||
assert.ok(e instanceof promise.CancellationError);
|
||||
assert.equal(
|
||||
'Task was discarded due to a previous failure: stub', e.message);
|
||||
}
|
||||
|
||||
it('are rejected with cancellation error', function() {
|
||||
let result;
|
||||
return Promise.resolve().then(function() {
|
||||
return flow.execute(function() {
|
||||
result = subTask.then(assert.fail);
|
||||
});
|
||||
})
|
||||
.then(() => result)
|
||||
.then(assert.fail, assertCancellation);
|
||||
});
|
||||
|
||||
it('cancellation errors propagate through callbacks (1)', function() {
|
||||
let result;
|
||||
return Promise.resolve().then(function() {
|
||||
return flow.execute(function() {
|
||||
result = subTask
|
||||
.then(assert.fail, assertCancellation)
|
||||
.then(() => 'abc123');
|
||||
});
|
||||
})
|
||||
.then(() => result)
|
||||
.then(value => assert.equal('abc123', value));
|
||||
});
|
||||
|
||||
it('cancellation errors propagate through callbacks (2)', function() {
|
||||
let result;
|
||||
return Promise.resolve().then(function() {
|
||||
return flow.execute(function() {
|
||||
result = subTask.then(assert.fail)
|
||||
.then(noop, assertCancellation)
|
||||
.then(() => 'fin');
|
||||
});
|
||||
})
|
||||
// Verify result actually computed successfully all the way through.
|
||||
.then(() => result)
|
||||
.then(value => assert.equal('fin', value));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('testRegisteredTaskCallbacksAreDroppedWhenTaskIsCancelled_return', function() {
|
||||
var seen = [];
|
||||
return flow.execute(function() {
|
||||
flow.execute(throwStubError);
|
||||
|
||||
flow.execute(function() {
|
||||
seen.push(1);
|
||||
}).then(function() {
|
||||
seen.push(2);
|
||||
}, function() {
|
||||
seen.push(3);
|
||||
});
|
||||
}).then(assert.fail, function(e) {
|
||||
assertIsStubError(e);
|
||||
assert.deepEqual([], seen);
|
||||
});
|
||||
});
|
||||
|
||||
it('testRegisteredTaskCallbacksAreDroppedWhenTaskIsCancelled_withReturn', function() {
|
||||
var seen = [];
|
||||
return flow.execute(function() {
|
||||
flow.execute(throwStubError);
|
||||
|
||||
return flow.execute(function() {
|
||||
seen.push(1);
|
||||
}).then(function() {
|
||||
seen.push(2);
|
||||
}, function() {
|
||||
seen.push(3);
|
||||
});
|
||||
}).then(assert.fail, function(e) {
|
||||
assertIsStubError(e);
|
||||
assert.deepEqual([], seen);
|
||||
});
|
||||
});
|
||||
|
||||
it('testTasksWithinACallbackAreDroppedIfContainingTaskIsAborted', function() {
|
||||
var seen = [];
|
||||
return flow.execute(function() {
|
||||
flow.execute(throwStubError);
|
||||
|
||||
// None of the callbacks on this promise should execute because the
|
||||
// task assert.failure above is never handled, causing the containing task to
|
||||
// abort.
|
||||
promise.fulfilled().then(function() {
|
||||
seen.push(1);
|
||||
return flow.execute(function() {
|
||||
seen.push(2);
|
||||
});
|
||||
}).finally(function() {
|
||||
seen.push(3);
|
||||
});
|
||||
|
||||
}).then(assert.fail, function(e) {
|
||||
assertIsStubError(e);
|
||||
assert.deepEqual([], seen);
|
||||
});
|
||||
});
|
||||
|
||||
it('testTaskIsCancelledAfterWaitTimeout', function() {
|
||||
var seen = [];
|
||||
return flow.execute(function() {
|
||||
flow.wait(function() {
|
||||
return promise.delayed(50);
|
||||
}, 5);
|
||||
|
||||
return flow.execute(function() {
|
||||
seen.push(1);
|
||||
}).then(function() {
|
||||
seen.push(2);
|
||||
}, function() {
|
||||
seen.push(3);
|
||||
});
|
||||
}).then(assert.fail, function() {
|
||||
assert.deepEqual([], seen);
|
||||
});
|
||||
});
|
||||
|
||||
describe('task callbacks get cancellation error if registered after task was cancelled', function() {
|
||||
it('(a)', function() {
|
||||
var task;
|
||||
flow.execute(function() {
|
||||
flow.execute(throwStubError);
|
||||
task = flow.execute(function() {});
|
||||
}).then(assert.fail, assertIsStubError);
|
||||
return waitForIdle().then(function() {
|
||||
return task.then(assert.fail, function(e) {
|
||||
assert.ok(e instanceof promise.CancellationError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('(b)', function() {
|
||||
var seen = [];
|
||||
|
||||
var task;
|
||||
flow.execute(function() {
|
||||
flow.execute(throwStubError);
|
||||
task = flow.execute(function() {});
|
||||
|
||||
task.then(() => seen.push(1))
|
||||
.then(() => seen.push(2));
|
||||
task.then(() => seen.push(3))
|
||||
.then(() => seen.push(4));
|
||||
|
||||
}).then(assert.fail, assertIsStubError);
|
||||
|
||||
return waitForIdle().then(function() {
|
||||
return task.then(assert.fail, function(e) {
|
||||
seen.push(5);
|
||||
assert.ok(e instanceof promise.CancellationError);
|
||||
});
|
||||
}).then(() => assert.deepEqual([5], seen));
|
||||
});
|
||||
});
|
||||
|
||||
it('unhandledRejectionInParallelTaskQueue', function() {
|
||||
var seen = [];
|
||||
function schedule(name) {
|
||||
return flow.execute(() => seen.push(name), name);
|
||||
}
|
||||
|
||||
flow.async(function() {
|
||||
schedule('a.1');
|
||||
flow.execute(throwStubError, 'a.2 (throws)');
|
||||
});
|
||||
|
||||
var b3;
|
||||
flow.async(function() {
|
||||
schedule('b.1');
|
||||
schedule('b.2');
|
||||
b3 = schedule('b.3');
|
||||
});
|
||||
|
||||
var c3;
|
||||
flow.async(function() {
|
||||
schedule('c.1');
|
||||
schedule('c.2');
|
||||
c3 = schedule('c.3');
|
||||
});
|
||||
|
||||
function assertWasCancelled(p) {
|
||||
return p.then(assert.fail, function(e) {
|
||||
assert.ok(e instanceof promise.CancellationError);
|
||||
});
|
||||
}
|
||||
|
||||
return waitForAbort()
|
||||
.then(function() {
|
||||
assert.deepEqual(['a.1', 'b.1', 'c.1', 'b.2', 'c.2'], seen);
|
||||
})
|
||||
.then(() => assertWasCancelled(b3))
|
||||
.then(() => assertWasCancelled(c3));
|
||||
});
|
||||
|
||||
it('errorsInAsyncFunctionsAreReportedAsUnhandledRejection', function() {
|
||||
flow.removeAllListeners(); // For tearDown.
|
||||
|
||||
var task;
|
||||
return new Promise(function(fulfill) {
|
||||
flow.once('uncaughtException', fulfill);
|
||||
flow.async(function() {
|
||||
task = flow.execute(function() {});
|
||||
throw Error('boom');
|
||||
});
|
||||
}).then(function(error) {
|
||||
assert.ok(error instanceof promise.CancellationError);
|
||||
return task.catch(function(error) {
|
||||
assert.ok(error instanceof promise.CancellationError);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('does not wait for values thrown from callbacks to be resolved', function() {
|
||||
it('(a)', function() {
|
||||
var p1 = promise.fulfilled();
|
||||
var reason = promise.fulfilled('should not see me');
|
||||
return p1.then(function() {
|
||||
throw reason;
|
||||
}).then(assert.fail, function(e) {
|
||||
assert.equal(reason, e);
|
||||
});
|
||||
});
|
||||
|
||||
it('(b)', function() {
|
||||
var p1 = promise.fulfilled();
|
||||
var reason = promise.rejected('should not see me');
|
||||
reason.catch(function() {}); // For tearDown.
|
||||
return p1.then(function() {
|
||||
throw reason;
|
||||
}).then(assert.fail, function(e) {
|
||||
assert.equal(reason, e);
|
||||
});
|
||||
});
|
||||
|
||||
it('(c)', function() {
|
||||
var p1 = promise.fulfilled();
|
||||
var reason = promise.defer();
|
||||
setTimeout(() => reason.fulfill('should not see me'), 100);
|
||||
return p1.then(function() {
|
||||
throw reason.promise;
|
||||
}).then(assert.fail, function(e) {
|
||||
assert.equal(reason.promise, e);
|
||||
});
|
||||
});
|
||||
|
||||
it('(d)', function() {
|
||||
var p1 = promise.fulfilled();
|
||||
var reason = {then: function() {}}; // A thenable like object.
|
||||
return p1.then(function() {
|
||||
throw reason;
|
||||
}).then(assert.fail, function(e) {
|
||||
assert.equal(reason, e);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
2288
node_modules/selenium-webdriver/test/lib/promise_flow_test.js
generated
vendored
Normal file
2288
node_modules/selenium-webdriver/test/lib/promise_flow_test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
310
node_modules/selenium-webdriver/test/lib/promise_generator_test.js
generated
vendored
Normal file
310
node_modules/selenium-webdriver/test/lib/promise_generator_test.js
generated
vendored
Normal file
|
@ -0,0 +1,310 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const promise = require('../../lib/promise');
|
||||
const {enablePromiseManager, promiseManagerSuite} = require('../../lib/test/promise');
|
||||
|
||||
describe('promise.consume()', function() {
|
||||
promiseManagerSuite(() => {
|
||||
it('requires inputs to be generator functions', function() {
|
||||
assert.throws(function() {
|
||||
promise.consume(function() {});
|
||||
});
|
||||
});
|
||||
|
||||
it('handles a basic generator with no yielded promises', function() {
|
||||
var values = [];
|
||||
return promise.consume(function* () {
|
||||
var i = 0;
|
||||
while (i < 4) {
|
||||
i = yield i + 1;
|
||||
values.push(i);
|
||||
}
|
||||
}).then(function() {
|
||||
assert.deepEqual([1, 2, 3, 4], values);
|
||||
});
|
||||
});
|
||||
|
||||
it('handles a promise yielding generator', function() {
|
||||
var values = [];
|
||||
return promise.consume(function* () {
|
||||
var i = 0;
|
||||
while (i < 4) {
|
||||
// Test that things are actually async here.
|
||||
setTimeout(function() {
|
||||
values.push(i * 2);
|
||||
}, 10);
|
||||
|
||||
yield promise.delayed(10).then(function() {
|
||||
values.push(i++);
|
||||
});
|
||||
}
|
||||
}).then(function() {
|
||||
assert.deepEqual([0, 0, 2, 1, 4, 2, 6, 3], values);
|
||||
});
|
||||
});
|
||||
|
||||
it('assignments to yielded promises get fulfilled value', function() {
|
||||
return promise.consume(function* () {
|
||||
let x = yield Promise.resolve(2);
|
||||
assert.equal(2, x);
|
||||
});
|
||||
});
|
||||
|
||||
it('uses final return value as fulfillment value', function() {
|
||||
return promise.consume(function* () {
|
||||
yield 1;
|
||||
yield 2;
|
||||
return 3;
|
||||
}).then(function(value) {
|
||||
assert.equal(3, value);
|
||||
});
|
||||
});
|
||||
|
||||
it('throws rejected promise errors within the generator', function() {
|
||||
var values = [];
|
||||
return promise.consume(function* () {
|
||||
values.push('a');
|
||||
var e = Error('stub error');
|
||||
try {
|
||||
yield Promise.reject(e);
|
||||
values.push('b');
|
||||
} catch (ex) {
|
||||
assert.equal(e, ex);
|
||||
values.push('c');
|
||||
}
|
||||
values.push('d');
|
||||
}).then(function() {
|
||||
assert.deepEqual(['a', 'c', 'd'], values);
|
||||
});
|
||||
});
|
||||
|
||||
it('aborts the generator if there is an unhandled rejection', function() {
|
||||
var values = [];
|
||||
var e = Error('stub error');
|
||||
return promise.consume(function* () {
|
||||
values.push(1);
|
||||
yield promise.rejected(e);
|
||||
values.push(2);
|
||||
}).catch(function() {
|
||||
assert.deepEqual([1], values);
|
||||
});
|
||||
});
|
||||
|
||||
it('yield waits for promises', function() {
|
||||
let values = [];
|
||||
let blocker = promise.delayed(100).then(() => {
|
||||
assert.deepEqual([1], values);
|
||||
return 2;
|
||||
});
|
||||
|
||||
return promise.consume(function* () {
|
||||
values.push(1);
|
||||
values.push(yield blocker, 3);
|
||||
}).then(function() {
|
||||
assert.deepEqual([1, 2, 3], values);
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts custom scopes', function() {
|
||||
return promise.consume(function* () {
|
||||
return this.name;
|
||||
}, {name: 'Bob'}).then(function(value) {
|
||||
assert.equal('Bob', value);
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts initial generator arguments', function() {
|
||||
return promise.consume(function* (a, b) {
|
||||
assert.equal('red', a);
|
||||
assert.equal('apples', b);
|
||||
}, null, 'red', 'apples');
|
||||
});
|
||||
});
|
||||
|
||||
enablePromiseManager(() => {
|
||||
it('is possible to cancel promise generators', function() {
|
||||
var values = [];
|
||||
var p = promise.consume(function* () {
|
||||
var i = 0;
|
||||
while (i < 3) {
|
||||
yield promise.delayed(100).then(function() {
|
||||
values.push(i++);
|
||||
});
|
||||
}
|
||||
});
|
||||
return promise.delayed(75).then(function() {
|
||||
p.cancel();
|
||||
return p.catch(function() {
|
||||
return promise.delayed(300);
|
||||
});
|
||||
}).then(function() {
|
||||
assert.deepEqual([0], values);
|
||||
});
|
||||
});
|
||||
|
||||
it('executes generator within the control flow', function() {
|
||||
var promises = [
|
||||
promise.defer(),
|
||||
promise.defer()
|
||||
];
|
||||
var values = [];
|
||||
|
||||
setTimeout(function() {
|
||||
assert.deepEqual([], values);
|
||||
promises[0].fulfill(1);
|
||||
}, 100);
|
||||
|
||||
setTimeout(function() {
|
||||
assert.deepEqual([1], values);
|
||||
promises[1].fulfill(2);
|
||||
}, 200);
|
||||
|
||||
return promise.controlFlow().execute(function* () {
|
||||
values.push(yield promises[0].promise);
|
||||
values.push(yield promises[1].promise);
|
||||
values.push('fin');
|
||||
}).then(function() {
|
||||
assert.deepEqual([1, 2, 'fin'], values);
|
||||
});
|
||||
});
|
||||
|
||||
it('handles tasks scheduled in generator', function() {
|
||||
var flow = promise.controlFlow();
|
||||
return flow.execute(function* () {
|
||||
var x = yield flow.execute(function() {
|
||||
return promise.delayed(10).then(function() {
|
||||
return 1;
|
||||
});
|
||||
});
|
||||
|
||||
var y = yield flow.execute(function() {
|
||||
return 2;
|
||||
});
|
||||
|
||||
return x + y;
|
||||
}).then(function(value) {
|
||||
assert.equal(3, value);
|
||||
});
|
||||
});
|
||||
|
||||
it('blocks the control flow while processing generator', function() {
|
||||
var values = [];
|
||||
return promise.controlFlow().wait(function* () {
|
||||
yield values.push(1);
|
||||
values.push(yield promise.delayed(10).then(function() {
|
||||
return 2;
|
||||
}));
|
||||
yield values.push(3);
|
||||
return values.length === 6;
|
||||
}, 250).then(function() {
|
||||
assert.deepEqual([1, 2, 3, 1, 2, 3], values);
|
||||
});
|
||||
});
|
||||
|
||||
it('ControlFlow.wait() will timeout on long generator', function() {
|
||||
var values = [];
|
||||
return promise.controlFlow().wait(function* () {
|
||||
var i = 0;
|
||||
while (i < 3) {
|
||||
yield promise.delayed(100).then(function() {
|
||||
values.push(i++);
|
||||
});
|
||||
}
|
||||
}, 75).catch(function() {
|
||||
assert.deepEqual(
|
||||
[0, 1, 2], values, 'Should complete one loop of wait condition');
|
||||
});
|
||||
});
|
||||
|
||||
describe('generators in promise callbacks', function() {
|
||||
it('works with no initial value', function() {
|
||||
var promises = [
|
||||
promise.defer(),
|
||||
promise.defer()
|
||||
];
|
||||
var values = [];
|
||||
|
||||
setTimeout(function() {
|
||||
promises[0].fulfill(1);
|
||||
}, 50);
|
||||
|
||||
setTimeout(function() {
|
||||
promises[1].fulfill(2);
|
||||
}, 100);
|
||||
|
||||
return promise.fulfilled().then(function*() {
|
||||
values.push(yield promises[0].promise);
|
||||
values.push(yield promises[1].promise);
|
||||
values.push('fin');
|
||||
}).then(function() {
|
||||
assert.deepEqual([1, 2, 'fin'], values);
|
||||
});
|
||||
});
|
||||
|
||||
it('starts the generator with promised value', function() {
|
||||
var promises = [
|
||||
promise.defer(),
|
||||
promise.defer()
|
||||
];
|
||||
var values = [];
|
||||
|
||||
setTimeout(function() {
|
||||
promises[0].fulfill(1);
|
||||
}, 50);
|
||||
|
||||
setTimeout(function() {
|
||||
promises[1].fulfill(2);
|
||||
}, 100);
|
||||
|
||||
return promise.fulfilled(3).then(function*(value) {
|
||||
var p1 = yield promises[0].promise;
|
||||
var p2 = yield promises[1].promise;
|
||||
values.push(value + p1);
|
||||
values.push(value + p2);
|
||||
values.push('fin');
|
||||
}).then(function() {
|
||||
assert.deepEqual([4, 5, 'fin'], values);
|
||||
});
|
||||
});
|
||||
|
||||
it('throws yielded rejections within the generator callback', function() {
|
||||
var d = promise.defer();
|
||||
var e = Error('stub');
|
||||
|
||||
setTimeout(function() {
|
||||
d.reject(e);
|
||||
}, 50);
|
||||
|
||||
return promise.fulfilled().then(function*() {
|
||||
var threw = false;
|
||||
try {
|
||||
yield d.promise;
|
||||
} catch (ex) {
|
||||
threw = true;
|
||||
assert.equal(e, ex);
|
||||
}
|
||||
assert.ok(threw);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
1109
node_modules/selenium-webdriver/test/lib/promise_test.js
generated
vendored
Normal file
1109
node_modules/selenium-webdriver/test/lib/promise_test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
90
node_modules/selenium-webdriver/test/lib/testutil.js
generated
vendored
Normal file
90
node_modules/selenium-webdriver/test/lib/testutil.js
generated
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const sinon = require('sinon');
|
||||
|
||||
|
||||
class StubError extends Error {
|
||||
constructor(opt_msg) {
|
||||
super(opt_msg);
|
||||
this.name = this.constructor.name;
|
||||
}
|
||||
}
|
||||
exports.StubError = StubError;
|
||||
|
||||
exports.throwStubError = function() {
|
||||
throw new StubError;
|
||||
};
|
||||
|
||||
exports.assertIsStubError = function(value) {
|
||||
assert.ok(value instanceof StubError, value + ' is not a ' + StubError.name);
|
||||
};
|
||||
|
||||
exports.assertIsInstance = function(ctor, value) {
|
||||
assert.ok(value instanceof ctor, 'Not a ' + ctor.name + ': ' + value);
|
||||
};
|
||||
|
||||
function callbackPair(cb, eb) {
|
||||
if (cb && eb) {
|
||||
throw new TypeError('can only specify one of callback or errback');
|
||||
}
|
||||
|
||||
let callback = cb ? sinon.spy(cb) : sinon.spy();
|
||||
let errback = eb ? sinon.spy(eb) : sinon.spy();
|
||||
|
||||
function assertCallback() {
|
||||
assert.ok(callback.called, 'callback not called');
|
||||
assert.ok(!errback.called, 'errback called');
|
||||
if (callback.threw()) {
|
||||
throw callback.exceptions[0];
|
||||
}
|
||||
}
|
||||
|
||||
function assertErrback() {
|
||||
assert.ok(!callback.called, 'callback called');
|
||||
assert.ok(errback.called, 'errback not called');
|
||||
if (errback.threw()) {
|
||||
throw errback.exceptions[0];
|
||||
}
|
||||
}
|
||||
|
||||
function assertNeither() {
|
||||
assert.ok(!callback.called, 'callback called');
|
||||
assert.ok(!errback.called, 'errback called');
|
||||
}
|
||||
|
||||
return {
|
||||
callback,
|
||||
errback,
|
||||
assertCallback,
|
||||
assertErrback,
|
||||
assertNeither
|
||||
};
|
||||
}
|
||||
exports.callbackPair = callbackPair;
|
||||
|
||||
|
||||
exports.callbackHelper = function(cb) {
|
||||
let pair = callbackPair(cb);
|
||||
let wrapped = pair.callback.bind(null);
|
||||
wrapped.assertCalled = () => pair.assertCallback();
|
||||
wrapped.assertNotCalled = () => pair.assertNeither();
|
||||
return wrapped;
|
||||
};
|
478
node_modules/selenium-webdriver/test/lib/until_test.js
generated
vendored
Normal file
478
node_modules/selenium-webdriver/test/lib/until_test.js
generated
vendored
Normal file
|
@ -0,0 +1,478 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
const By = require('../../lib/by').By;
|
||||
const CommandName = require('../../lib/command').Name;
|
||||
const error = require('../../lib/error');
|
||||
const promise = require('../../lib/promise');
|
||||
const until = require('../../lib/until');
|
||||
const webdriver = require('../../lib/webdriver'),
|
||||
WebElement = webdriver.WebElement;
|
||||
|
||||
describe('until', function() {
|
||||
let driver, executor;
|
||||
|
||||
class TestExecutor {
|
||||
constructor() {
|
||||
this.handlers_ = {};
|
||||
}
|
||||
|
||||
on(cmd, handler) {
|
||||
this.handlers_[cmd] = handler;
|
||||
return this;
|
||||
}
|
||||
|
||||
execute(cmd) {
|
||||
let self = this;
|
||||
return Promise.resolve().then(function() {
|
||||
if (!self.handlers_[cmd.getName()]) {
|
||||
throw new error.UnknownCommandError(cmd.getName());
|
||||
}
|
||||
return self.handlers_[cmd.getName()](cmd);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function fail(opt_msg) {
|
||||
throw new assert.AssertionError({message: opt_msg});
|
||||
}
|
||||
|
||||
beforeEach(function setUp() {
|
||||
executor = new TestExecutor();
|
||||
driver = new webdriver.WebDriver('session-id', executor);
|
||||
});
|
||||
|
||||
describe('ableToSwitchToFrame', function() {
|
||||
it('failsFastForNonSwitchErrors', function() {
|
||||
let e = Error('boom');
|
||||
executor.on(CommandName.SWITCH_TO_FRAME, function() {
|
||||
throw e;
|
||||
});
|
||||
return driver.wait(until.ableToSwitchToFrame(0), 100)
|
||||
.then(fail, (e2) => assert.strictEqual(e2, e));
|
||||
});
|
||||
|
||||
const ELEMENT_ID = 'some-element-id';
|
||||
const ELEMENT_INDEX = 1234;
|
||||
|
||||
function onSwitchFrame(expectedId) {
|
||||
if (typeof expectedId === 'string') {
|
||||
expectedId = WebElement.buildId(expectedId);
|
||||
} else {
|
||||
assert.equal(typeof expectedId, 'number', 'must be string or number');
|
||||
}
|
||||
return cmd => {
|
||||
assert.deepEqual(
|
||||
cmd.getParameter('id'), expectedId, 'frame ID not specified');
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
it('byIndex', function() {
|
||||
executor.on(CommandName.SWITCH_TO_FRAME, onSwitchFrame(ELEMENT_INDEX));
|
||||
return driver.wait(until.ableToSwitchToFrame(ELEMENT_INDEX), 100);
|
||||
});
|
||||
|
||||
it('byWebElement', function() {
|
||||
executor.on(CommandName.SWITCH_TO_FRAME, onSwitchFrame(ELEMENT_ID));
|
||||
|
||||
var el = new webdriver.WebElement(driver, ELEMENT_ID);
|
||||
return driver.wait(until.ableToSwitchToFrame(el), 100);
|
||||
});
|
||||
|
||||
it('byWebElementPromise', function() {
|
||||
executor.on(CommandName.SWITCH_TO_FRAME, onSwitchFrame(ELEMENT_ID));
|
||||
var el = new webdriver.WebElementPromise(driver,
|
||||
Promise.resolve(new webdriver.WebElement(driver, ELEMENT_ID)));
|
||||
return driver.wait(until.ableToSwitchToFrame(el), 100);
|
||||
});
|
||||
|
||||
it('byLocator', function() {
|
||||
executor.on(CommandName.FIND_ELEMENTS, () => [WebElement.buildId(ELEMENT_ID)]);
|
||||
executor.on(CommandName.SWITCH_TO_FRAME, onSwitchFrame(ELEMENT_ID));
|
||||
return driver.wait(until.ableToSwitchToFrame(By.id('foo')), 100);
|
||||
});
|
||||
|
||||
it('byLocator_elementNotInitiallyFound', function() {
|
||||
let foundResponses = [[], [], [WebElement.buildId(ELEMENT_ID)]];
|
||||
executor.on(CommandName.FIND_ELEMENTS, () => foundResponses.shift());
|
||||
executor.on(CommandName.SWITCH_TO_FRAME, onSwitchFrame(ELEMENT_ID));
|
||||
|
||||
return driver.wait(until.ableToSwitchToFrame(By.id('foo')), 2000)
|
||||
.then(() => assert.deepEqual(foundResponses, []));
|
||||
});
|
||||
|
||||
it('timesOutIfNeverAbletoSwitchFrames', function() {
|
||||
var count = 0;
|
||||
executor.on(CommandName.SWITCH_TO_FRAME, function() {
|
||||
count += 1;
|
||||
throw new error.NoSuchFrameError;
|
||||
});
|
||||
|
||||
return driver.wait(until.ableToSwitchToFrame(0), 100)
|
||||
.then(fail, function(e) {
|
||||
assert.ok(count > 0);
|
||||
assert.ok(
|
||||
e.message.startsWith('Waiting to be able to switch to frame'),
|
||||
'Wrong message: ' + e.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('alertIsPresent', function() {
|
||||
it('failsFastForNonAlertSwitchErrors', function() {
|
||||
return driver.wait(until.alertIsPresent(), 100).then(fail, function(e) {
|
||||
assert.ok(e instanceof error.UnknownCommandError);
|
||||
assert.equal(e.message, CommandName.GET_ALERT_TEXT);
|
||||
});
|
||||
});
|
||||
|
||||
it('waitsForAlert', function() {
|
||||
var count = 0;
|
||||
executor.on(CommandName.GET_ALERT_TEXT, function() {
|
||||
if (count++ < 3) {
|
||||
throw new error.NoSuchAlertError;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}).on(CommandName.DISMISS_ALERT, () => true);
|
||||
|
||||
return driver.wait(until.alertIsPresent(), 1000).then(function(alert) {
|
||||
assert.equal(count, 4);
|
||||
return alert.dismiss();
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: Remove once GeckoDriver doesn't throw this unwanted error.
|
||||
// See https://github.com/SeleniumHQ/selenium/pull/2137
|
||||
describe('workaround for GeckoDriver', function() {
|
||||
it('doesNotFailWhenCannotConvertNullToObject', function() {
|
||||
var count = 0;
|
||||
executor.on(CommandName.GET_ALERT_TEXT, function() {
|
||||
if (count++ < 3) {
|
||||
throw new error.WebDriverError(`can't convert null to object`);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}).on(CommandName.DISMISS_ALERT, () => true);
|
||||
|
||||
return driver.wait(until.alertIsPresent(), 1000).then(function(alert) {
|
||||
assert.equal(count, 4);
|
||||
return alert.dismiss();
|
||||
});
|
||||
});
|
||||
|
||||
it('keepsRaisingRegularWebdriverError', function() {
|
||||
var webDriverError = new error.WebDriverError;
|
||||
|
||||
executor.on(CommandName.GET_ALERT_TEXT, function() {
|
||||
throw webDriverError;
|
||||
});
|
||||
|
||||
return driver.wait(until.alertIsPresent(), 1000).then(function() {
|
||||
throw new Error('driver did not fail against WebDriverError');
|
||||
}, function(error) {
|
||||
assert.equal(error, webDriverError);
|
||||
});
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
it('testUntilTitleIs', function() {
|
||||
var titles = ['foo', 'bar', 'baz'];
|
||||
executor.on(CommandName.GET_TITLE, () => titles.shift());
|
||||
|
||||
return driver.wait(until.titleIs('bar'), 3000).then(function() {
|
||||
assert.deepStrictEqual(titles, ['baz']);
|
||||
});
|
||||
});
|
||||
|
||||
it('testUntilTitleContains', function() {
|
||||
var titles = ['foo', 'froogle', 'google'];
|
||||
executor.on(CommandName.GET_TITLE, () => titles.shift());
|
||||
|
||||
return driver.wait(until.titleContains('oogle'), 3000).then(function() {
|
||||
assert.deepStrictEqual(titles, ['google']);
|
||||
});
|
||||
});
|
||||
|
||||
it('testUntilTitleMatches', function() {
|
||||
var titles = ['foo', 'froogle', 'aaaabc', 'aabbbc', 'google'];
|
||||
executor.on(CommandName.GET_TITLE, () => titles.shift());
|
||||
|
||||
return driver.wait(until.titleMatches(/^a{2,3}b+c$/), 3000)
|
||||
.then(function() {
|
||||
assert.deepStrictEqual(titles, ['google']);
|
||||
});
|
||||
});
|
||||
|
||||
it('testUntilUrlIs', function() {
|
||||
var urls = ['http://www.foo.com', 'https://boo.com', 'http://docs.yes.com'];
|
||||
executor.on(CommandName.GET_CURRENT_URL, () => urls.shift());
|
||||
|
||||
return driver.wait(until.urlIs('https://boo.com'), 3000).then(function() {
|
||||
assert.deepStrictEqual(urls, ['http://docs.yes.com']);
|
||||
});
|
||||
});
|
||||
|
||||
it('testUntilUrlContains', function() {
|
||||
var urls =
|
||||
['http://foo.com', 'https://groups.froogle.com', 'http://google.com'];
|
||||
executor.on(CommandName.GET_CURRENT_URL, () => urls.shift());
|
||||
|
||||
return driver.wait(until.urlContains('oogle.com'), 3000).then(function() {
|
||||
assert.deepStrictEqual(urls, ['http://google.com']);
|
||||
});
|
||||
});
|
||||
|
||||
it('testUntilUrlMatches', function() {
|
||||
var urls = ['foo', 'froogle', 'aaaabc', 'aabbbc', 'google'];
|
||||
executor.on(CommandName.GET_CURRENT_URL, () => urls.shift());
|
||||
|
||||
return driver.wait(until.urlMatches(/^a{2,3}b+c$/), 3000)
|
||||
.then(function() {
|
||||
assert.deepStrictEqual(urls, ['google']);
|
||||
});
|
||||
});
|
||||
|
||||
it('testUntilElementLocated', function() {
|
||||
var responses = [
|
||||
[],
|
||||
[WebElement.buildId('abc123'), WebElement.buildId('foo')],
|
||||
['end']
|
||||
];
|
||||
executor.on(CommandName.FIND_ELEMENTS, () => responses.shift());
|
||||
|
||||
let element = driver.wait(until.elementLocated(By.id('quux')), 2000);
|
||||
assert.ok(element instanceof webdriver.WebElementPromise);
|
||||
return element.getId().then(function(id) {
|
||||
assert.deepStrictEqual(responses, [['end']]);
|
||||
assert.equal(id, 'abc123');
|
||||
});
|
||||
});
|
||||
|
||||
describe('untilElementLocated, elementNeverFound', function() {
|
||||
function runNoElementFoundTest(locator, locatorStr) {
|
||||
executor.on(CommandName.FIND_ELEMENTS, () => []);
|
||||
|
||||
function expectedFailure() {
|
||||
fail('expected condition to timeout');
|
||||
}
|
||||
|
||||
return driver.wait(until.elementLocated(locator), 100)
|
||||
.then(expectedFailure, function(error) {
|
||||
var expected = 'Waiting for element to be located ' + locatorStr;
|
||||
var lines = error.message.split(/\n/, 2);
|
||||
assert.equal(lines[0], expected);
|
||||
|
||||
let regex = /^Wait timed out after \d+ms$/;
|
||||
assert.ok(regex.test(lines[1]),
|
||||
`Lines <${lines[1]}> does not match ${regex}`);
|
||||
});
|
||||
}
|
||||
|
||||
it('byLocator', function() {
|
||||
return runNoElementFoundTest(
|
||||
By.id('quux'), 'By(css selector, *[id="quux"])');
|
||||
});
|
||||
|
||||
it('byHash', function() {
|
||||
return runNoElementFoundTest(
|
||||
{id: 'quux'}, 'By(css selector, *[id="quux"])');
|
||||
});
|
||||
|
||||
it('byFunction', function() {
|
||||
return runNoElementFoundTest(function() {}, 'by function()');
|
||||
});
|
||||
});
|
||||
|
||||
it('testUntilElementsLocated', function() {
|
||||
var responses = [
|
||||
[],
|
||||
[WebElement.buildId('abc123'), WebElement.buildId('foo')],
|
||||
['end']
|
||||
];
|
||||
executor.on(CommandName.FIND_ELEMENTS, () => responses.shift());
|
||||
|
||||
return driver.wait(until.elementsLocated(By.id('quux')), 2000)
|
||||
.then(function(els) {
|
||||
return Promise.all(els.map(e => e.getId()));
|
||||
}).then(function(ids) {
|
||||
assert.deepStrictEqual(responses, [['end']]);
|
||||
assert.equal(ids.length, 2);
|
||||
assert.equal(ids[0], 'abc123');
|
||||
assert.equal(ids[1], 'foo');
|
||||
});
|
||||
});
|
||||
|
||||
describe('untilElementsLocated, noElementsFound', function() {
|
||||
function runNoElementsFoundTest(locator, locatorStr) {
|
||||
executor.on(CommandName.FIND_ELEMENTS, () => []);
|
||||
|
||||
function expectedFailure() {
|
||||
fail('expected condition to timeout');
|
||||
}
|
||||
|
||||
return driver.wait(until.elementsLocated(locator), 100)
|
||||
.then(expectedFailure, function(error) {
|
||||
var expected =
|
||||
'Waiting for at least one element to be located ' + locatorStr;
|
||||
var lines = error.message.split(/\n/, 2);
|
||||
assert.equal(lines[0], expected);
|
||||
|
||||
let regex = /^Wait timed out after \d+ms$/;
|
||||
assert.ok(regex.test(lines[1]),
|
||||
`Lines <${lines[1]}> does not match ${regex}`);
|
||||
});
|
||||
}
|
||||
|
||||
it('byLocator', function() {
|
||||
return runNoElementsFoundTest(
|
||||
By.id('quux'), 'By(css selector, *[id="quux"])');
|
||||
});
|
||||
|
||||
it('byHash', function() {
|
||||
return runNoElementsFoundTest(
|
||||
{id: 'quux'}, 'By(css selector, *[id="quux"])');
|
||||
});
|
||||
|
||||
it('byFunction', function() {
|
||||
return runNoElementsFoundTest(function() {}, 'by function()');
|
||||
});
|
||||
});
|
||||
|
||||
it('testUntilStalenessOf', function() {
|
||||
let count = 0;
|
||||
executor.on(CommandName.GET_ELEMENT_TAG_NAME, function() {
|
||||
while (count < 3) {
|
||||
count += 1;
|
||||
return 'body';
|
||||
}
|
||||
throw new error.StaleElementReferenceError('now stale');
|
||||
});
|
||||
|
||||
var el = new webdriver.WebElement(driver, {ELEMENT: 'foo'});
|
||||
return driver.wait(until.stalenessOf(el), 2000)
|
||||
.then(() => assert.equal(count, 3));
|
||||
});
|
||||
|
||||
describe('element state conditions', function() {
|
||||
function runElementStateTest(predicate, command, responses, var_args) {
|
||||
let original = new webdriver.WebElement(driver, 'foo');
|
||||
let predicateArgs = [original];
|
||||
if (arguments.length > 3) {
|
||||
predicateArgs = predicateArgs.concat(arguments[1]);
|
||||
command = arguments[2];
|
||||
responses = arguments[3];
|
||||
}
|
||||
|
||||
assert.ok(responses.length > 1);
|
||||
|
||||
responses = responses.concat(['end']);
|
||||
executor.on(command, () => responses.shift());
|
||||
|
||||
let result = driver.wait(predicate.apply(null, predicateArgs), 2000);
|
||||
assert.ok(result instanceof webdriver.WebElementPromise);
|
||||
return result.then(function(value) {
|
||||
assert.ok(value instanceof webdriver.WebElement);
|
||||
assert.ok(!(value instanceof webdriver.WebElementPromise));
|
||||
return value.getId();
|
||||
}).then(function(id) {
|
||||
assert.equal('foo', id);
|
||||
assert.deepStrictEqual(responses, ['end']);
|
||||
});
|
||||
}
|
||||
|
||||
it('elementIsVisible', function() {
|
||||
return runElementStateTest(
|
||||
until.elementIsVisible,
|
||||
CommandName.IS_ELEMENT_DISPLAYED, [false, false, true]);
|
||||
});
|
||||
|
||||
it('elementIsNotVisible', function() {
|
||||
return runElementStateTest(
|
||||
until.elementIsNotVisible,
|
||||
CommandName.IS_ELEMENT_DISPLAYED, [true, true, false]);
|
||||
});
|
||||
|
||||
it('elementIsEnabled', function() {
|
||||
return runElementStateTest(
|
||||
until.elementIsEnabled,
|
||||
CommandName.IS_ELEMENT_ENABLED, [false, false, true]);
|
||||
});
|
||||
|
||||
it('elementIsDisabled', function() {
|
||||
return runElementStateTest(
|
||||
until.elementIsDisabled,
|
||||
CommandName.IS_ELEMENT_ENABLED, [true, true, false]);
|
||||
});
|
||||
|
||||
it('elementIsSelected', function() {
|
||||
return runElementStateTest(
|
||||
until.elementIsSelected,
|
||||
CommandName.IS_ELEMENT_SELECTED, [false, false, true]);
|
||||
});
|
||||
|
||||
it('elementIsNotSelected', function() {
|
||||
return runElementStateTest(
|
||||
until.elementIsNotSelected,
|
||||
CommandName.IS_ELEMENT_SELECTED, [true, true, false]);
|
||||
});
|
||||
|
||||
it('elementTextIs', function() {
|
||||
return runElementStateTest(
|
||||
until.elementTextIs, 'foobar',
|
||||
CommandName.GET_ELEMENT_TEXT,
|
||||
['foo', 'fooba', 'foobar']);
|
||||
});
|
||||
|
||||
it('elementTextContains', function() {
|
||||
return runElementStateTest(
|
||||
until.elementTextContains, 'bar',
|
||||
CommandName.GET_ELEMENT_TEXT,
|
||||
['foo', 'foobaz', 'foobarbaz']);
|
||||
});
|
||||
|
||||
it('elementTextMatches', function() {
|
||||
return runElementStateTest(
|
||||
until.elementTextMatches, /fo+bar{3}/,
|
||||
CommandName.GET_ELEMENT_TEXT,
|
||||
['foo', 'foobar', 'fooobarrr']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('WebElementCondition', function() {
|
||||
it('fails if wait completes with a non-WebElement value', function() {
|
||||
let result = driver.wait(
|
||||
new webdriver.WebElementCondition('testing', () => 123), 1000);
|
||||
|
||||
return result.then(
|
||||
() => assert.fail('expected to fail'),
|
||||
function(e) {
|
||||
assert.ok(e instanceof TypeError);
|
||||
assert.equal(
|
||||
'WebElementCondition did not resolve to a WebElement: '
|
||||
+ '[object Number]',
|
||||
e.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
2311
node_modules/selenium-webdriver/test/lib/webdriver_test.js
generated
vendored
Normal file
2311
node_modules/selenium-webdriver/test/lib/webdriver_test.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
167
node_modules/selenium-webdriver/test/logging_test.js
generated
vendored
Normal file
167
node_modules/selenium-webdriver/test/logging_test.js
generated
vendored
Normal file
|
@ -0,0 +1,167 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var Browser = require('..').Browser,
|
||||
By = require('..').By,
|
||||
logging = require('..').logging,
|
||||
assert = require('../testing/assert'),
|
||||
test = require('../lib/test');
|
||||
|
||||
test.suite(function(env) {
|
||||
// Logging API has numerous issues with PhantomJS:
|
||||
// - does not support adjusting log levels for type "browser".
|
||||
// - does not return proper log level for "browser" messages.
|
||||
// - does not delete logs after retrieval
|
||||
// Logging API is not supported in IE.
|
||||
// Logging API not supported in Marionette.
|
||||
// Tests depend on opening data URLs, which is broken in Safari (issue 7586)
|
||||
test.ignore(env.browsers(
|
||||
Browser.PHANTOM_JS, Browser.IE, Browser.SAFARI, Browser.FIREFOX)).
|
||||
describe('logging', function() {
|
||||
var driver;
|
||||
|
||||
test.beforeEach(function() {
|
||||
driver = null;
|
||||
});
|
||||
|
||||
test.afterEach(function*() {
|
||||
if (driver) {
|
||||
return driver.quit();
|
||||
}
|
||||
});
|
||||
|
||||
test.it('can be disabled', function*() {
|
||||
var prefs = new logging.Preferences();
|
||||
prefs.setLevel(logging.Type.BROWSER, logging.Level.OFF);
|
||||
|
||||
driver = yield env.builder()
|
||||
.setLoggingPrefs(prefs)
|
||||
.build();
|
||||
|
||||
yield driver.get(dataUrl(
|
||||
'<!DOCTYPE html><script>',
|
||||
'console.info("hello");',
|
||||
'console.warn("this is a warning");',
|
||||
'console.error("and this is an error");',
|
||||
'</script>'));
|
||||
return driver.manage().logs().get(logging.Type.BROWSER)
|
||||
.then(entries => assert(entries.length).equalTo(0));
|
||||
});
|
||||
|
||||
// Firefox does not capture JS error console log messages.
|
||||
test.ignore(env.browsers(Browser.FIREFOX, 'legacy-firefox')).
|
||||
it('can be turned down', function*() {
|
||||
var prefs = new logging.Preferences();
|
||||
prefs.setLevel(logging.Type.BROWSER, logging.Level.SEVERE);
|
||||
|
||||
driver = yield env.builder()
|
||||
.setLoggingPrefs(prefs)
|
||||
.build();
|
||||
|
||||
yield driver.get(dataUrl(
|
||||
'<!DOCTYPE html><script>',
|
||||
'console.info("hello");',
|
||||
'console.warn("this is a warning");',
|
||||
'console.error("and this is an error");',
|
||||
'</script>'));
|
||||
return driver.manage().logs().get(logging.Type.BROWSER)
|
||||
.then(function(entries) {
|
||||
assert(entries.length).equalTo(1);
|
||||
assert(entries[0].level.name).equalTo('SEVERE');
|
||||
assert(entries[0].message).matches(/.*\"?and this is an error\"?/);
|
||||
});
|
||||
});
|
||||
|
||||
// Firefox does not capture JS error console log messages.
|
||||
test.ignore(env.browsers(Browser.FIREFOX, 'legacy-firefox')).
|
||||
it('can be made verbose', function*() {
|
||||
var prefs = new logging.Preferences();
|
||||
prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG);
|
||||
|
||||
driver = yield env.builder()
|
||||
.setLoggingPrefs(prefs)
|
||||
.build();
|
||||
|
||||
yield driver.get(dataUrl(
|
||||
'<!DOCTYPE html><script>',
|
||||
'console.debug("hello");',
|
||||
'console.warn("this is a warning");',
|
||||
'console.error("and this is an error");',
|
||||
'</script>'));
|
||||
return driver.manage().logs().get(logging.Type.BROWSER)
|
||||
.then(function(entries) {
|
||||
assert(entries.length).equalTo(3);
|
||||
assert(entries[0].level.name).equalTo('DEBUG');
|
||||
assert(entries[0].message).matches(/.*\"?hello\"?/);
|
||||
|
||||
assert(entries[1].level.name).equalTo('WARNING');
|
||||
assert(entries[1].message).matches(/.*\"?this is a warning\"?/);
|
||||
|
||||
assert(entries[2].level.name).equalTo('SEVERE');
|
||||
assert(entries[2].message).matches(/.*\"?and this is an error\"?/);
|
||||
});
|
||||
});
|
||||
|
||||
// Firefox does not capture JS error console log messages.
|
||||
test.ignore(env.browsers(Browser.FIREFOX, 'legacy-firefox')).
|
||||
it('clears records after retrieval', function*() {
|
||||
var prefs = new logging.Preferences();
|
||||
prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG);
|
||||
|
||||
driver = yield env.builder()
|
||||
.setLoggingPrefs(prefs)
|
||||
.build();
|
||||
|
||||
yield driver.get(dataUrl(
|
||||
'<!DOCTYPE html><script>',
|
||||
'console.debug("hello");',
|
||||
'console.warn("this is a warning");',
|
||||
'console.error("and this is an error");',
|
||||
'</script>'));
|
||||
yield driver.manage().logs().get(logging.Type.BROWSER)
|
||||
.then(entries => assert(entries.length).equalTo(3));
|
||||
return driver.manage().logs().get(logging.Type.BROWSER)
|
||||
.then(entries => assert(entries.length).equalTo(0));
|
||||
});
|
||||
|
||||
test.it('does not mix log types', function*() {
|
||||
var prefs = new logging.Preferences();
|
||||
prefs.setLevel(logging.Type.BROWSER, logging.Level.DEBUG);
|
||||
prefs.setLevel(logging.Type.DRIVER, logging.Level.SEVERE);
|
||||
|
||||
driver = yield env.builder()
|
||||
.setLoggingPrefs(prefs)
|
||||
.build();
|
||||
|
||||
yield driver.get(dataUrl(
|
||||
'<!DOCTYPE html><script>',
|
||||
'console.debug("hello");',
|
||||
'console.warn("this is a warning");',
|
||||
'console.error("and this is an error");',
|
||||
'</script>'));
|
||||
return driver.manage().logs().get(logging.Type.DRIVER)
|
||||
.then(entries => assert(entries.length).equalTo(0));
|
||||
});
|
||||
});
|
||||
|
||||
function dataUrl(var_args) {
|
||||
return 'data:text/html,'
|
||||
+ Array.prototype.slice.call(arguments, 0).join('');
|
||||
}
|
||||
});
|
128
node_modules/selenium-webdriver/test/net/portprober_test.js
generated
vendored
Normal file
128
node_modules/selenium-webdriver/test/net/portprober_test.js
generated
vendored
Normal file
|
@ -0,0 +1,128 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const net = require('net');
|
||||
|
||||
const portprober = require('../../net/portprober');
|
||||
|
||||
describe('isFree', function() {
|
||||
|
||||
var server;
|
||||
|
||||
beforeEach(function() {
|
||||
server = net.createServer(function(){});
|
||||
})
|
||||
|
||||
afterEach(function(done) {
|
||||
if (!server) return done();
|
||||
server.close(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should work for INADDR_ANY', function(done) {
|
||||
server.listen(0, function() {
|
||||
var port = server.address().port;
|
||||
assertPortNotfree(port).then(function() {
|
||||
return new Promise(resolve => {
|
||||
server.close(function() {
|
||||
server = null;
|
||||
resolve(assertPortIsFree(port));
|
||||
});
|
||||
});
|
||||
}).then(function() { done(); }, done);
|
||||
});
|
||||
});
|
||||
|
||||
it('should work for a specific host', function(done) {
|
||||
var host = '127.0.0.1';
|
||||
server.listen(0, host, function() {
|
||||
var port = server.address().port;
|
||||
assertPortNotfree(port, host).then(function() {
|
||||
return new Promise(resolve => {
|
||||
server.close(function() {
|
||||
server = null;
|
||||
resolve(assertPortIsFree(port, host));
|
||||
});
|
||||
});
|
||||
}).then(function() { done(); }, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('findFreePort', function() {
|
||||
var server;
|
||||
|
||||
beforeEach(function() {
|
||||
server = net.createServer(function(){});
|
||||
})
|
||||
|
||||
afterEach(function(done) {
|
||||
if (!server) return done();
|
||||
server.close(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should work for INADDR_ANY', function(done) {
|
||||
portprober.findFreePort().then(function(port) {
|
||||
server.listen(port, function() {
|
||||
assertPortNotfree(port).then(function() {
|
||||
return new Promise(resolve => {
|
||||
server.close(function() {
|
||||
server = null;
|
||||
resolve(assertPortIsFree(port));
|
||||
});
|
||||
});
|
||||
}).then(function() { done(); }, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should work for a specific host', function(done) {
|
||||
var host = '127.0.0.1';
|
||||
portprober.findFreePort(host).then(function(port) {
|
||||
server.listen(port, host, function() {
|
||||
assertPortNotfree(port, host).then(function() {
|
||||
return new Promise(resolve => {
|
||||
server.close(function() {
|
||||
server = null;
|
||||
resolve(assertPortIsFree(port, host));
|
||||
});
|
||||
});
|
||||
}).then(function() { done(); }, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function assertPortIsFree(port, opt_host) {
|
||||
return portprober.isFree(port, opt_host).then(function(free) {
|
||||
assert.ok(free, 'port should be free');
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function assertPortNotfree(port, opt_host) {
|
||||
return portprober.isFree(port, opt_host).then(function(free) {
|
||||
assert.ok(!free, 'port should is not free');
|
||||
});
|
||||
}
|
166
node_modules/selenium-webdriver/test/page_loading_test.js
generated
vendored
Normal file
166
node_modules/selenium-webdriver/test/page_loading_test.js
generated
vendored
Normal file
|
@ -0,0 +1,166 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var Browser = require('..').Browser,
|
||||
By = require('..').By,
|
||||
until = require('..').until,
|
||||
assert = require('../testing/assert'),
|
||||
error = require('../lib/error'),
|
||||
test = require('../lib/test'),
|
||||
Pages = test.Pages;
|
||||
|
||||
|
||||
test.suite(function(env) {
|
||||
var browsers = env.browsers;
|
||||
|
||||
var driver;
|
||||
test.before(function*() {
|
||||
driver = yield env.builder().build();
|
||||
});
|
||||
|
||||
test.beforeEach(function*() {
|
||||
if (!driver) {
|
||||
driver = yield env.builder().build();
|
||||
}
|
||||
});
|
||||
|
||||
test.after(function() {
|
||||
if (driver) {
|
||||
return driver.quit();
|
||||
}
|
||||
});
|
||||
|
||||
test.it('should wait for document to be loaded', function*() {
|
||||
yield driver.get(Pages.simpleTestPage);
|
||||
return assert(driver.getTitle()).equalTo('Hello WebDriver');
|
||||
});
|
||||
|
||||
test.it('should follow redirects sent in the http response headers',
|
||||
function*() {
|
||||
yield driver.get(Pages.redirectPage);
|
||||
return assert(driver.getTitle()).equalTo('We Arrive Here');
|
||||
});
|
||||
|
||||
// Skip Firefox; see https://bugzilla.mozilla.org/show_bug.cgi?id=1280300
|
||||
test.ignore(browsers(Browser.FIREFOX)).
|
||||
it('should be able to get a fragment on the current page', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
yield driver.get(Pages.xhtmlTestPage + '#text');
|
||||
yield driver.findElement(By.id('id1'));
|
||||
});
|
||||
|
||||
test.ignore(browsers(Browser.IPAD, Browser.IPHONE)).
|
||||
it('should wait for all frames to load in a frameset', function*() {
|
||||
yield driver.get(Pages.framesetPage);
|
||||
yield driver.switchTo().frame(0);
|
||||
|
||||
let txt = yield driver.findElement(By.css('span#pageNumber')).getText();
|
||||
assert(txt.trim()).equalTo('1');
|
||||
|
||||
yield driver.switchTo().defaultContent();
|
||||
yield driver.switchTo().frame(1);
|
||||
txt = yield driver.findElement(By.css('span#pageNumber')).getText();
|
||||
|
||||
assert(txt.trim()).equalTo('2');
|
||||
});
|
||||
|
||||
test.ignore(browsers(Browser.SAFARI)).
|
||||
it('should be able to navigate back in browser history', function*() {
|
||||
yield driver.get(Pages.formPage);
|
||||
|
||||
yield driver.findElement(By.id('imageButton')).click();
|
||||
yield driver.wait(until.titleIs('We Arrive Here'), 2500);
|
||||
|
||||
yield driver.navigate().back();
|
||||
yield driver.wait(until.titleIs('We Leave From Here'), 2500);
|
||||
});
|
||||
|
||||
test.ignore(browsers(Browser.SAFARI)).
|
||||
it('should be able to navigate back in presence of iframes', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
|
||||
yield driver.findElement(By.name('sameWindow')).click();
|
||||
yield driver.wait(until.titleIs('This page has iframes'), 2500);
|
||||
|
||||
yield driver.navigate().back();
|
||||
yield driver.wait(until.titleIs('XHTML Test Page'), 2500);
|
||||
});
|
||||
|
||||
test.ignore(browsers(Browser.SAFARI)).
|
||||
it('should be able to navigate forwards in browser history', function*() {
|
||||
yield driver.get(Pages.formPage);
|
||||
|
||||
yield driver.findElement(By.id('imageButton')).click();
|
||||
yield driver.wait(until.titleIs('We Arrive Here'), 5000);
|
||||
|
||||
yield driver.navigate().back();
|
||||
yield driver.wait(until.titleIs('We Leave From Here'), 5000);
|
||||
|
||||
yield driver.navigate().forward();
|
||||
yield driver.wait(until.titleIs('We Arrive Here'), 5000);
|
||||
});
|
||||
|
||||
// PhantomJS 2.0 does not properly reload pages on refresh.
|
||||
test.ignore(browsers(Browser.PHANTOM_JS)).
|
||||
it('should be able to refresh a page', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
|
||||
yield driver.navigate().refresh();
|
||||
|
||||
yield assert(driver.getTitle()).equalTo('XHTML Test Page');
|
||||
});
|
||||
|
||||
test.it('should return title of page if set', function*() {
|
||||
yield driver.get(Pages.xhtmlTestPage);
|
||||
yield assert(driver.getTitle()).equalTo('XHTML Test Page');
|
||||
|
||||
yield driver.get(Pages.simpleTestPage);
|
||||
yield assert(driver.getTitle()).equalTo('Hello WebDriver');
|
||||
});
|
||||
|
||||
describe('timeouts', function() {
|
||||
test.afterEach(function() {
|
||||
let nullDriver = () => driver = null;
|
||||
if (driver) {
|
||||
return driver.quit().then(nullDriver, nullDriver);
|
||||
}
|
||||
});
|
||||
|
||||
// Only implemented in Firefox.
|
||||
test.ignore(browsers(
|
||||
Browser.CHROME,
|
||||
Browser.IE,
|
||||
Browser.IPAD,
|
||||
Browser.IPHONE,
|
||||
Browser.OPERA,
|
||||
Browser.PHANTOM_JS)).
|
||||
it('should timeout if page load timeout is set', function*() {
|
||||
yield driver.manage().timeouts().pageLoadTimeout(1);
|
||||
return driver.get(Pages.sleepingPage + '?time=3')
|
||||
.then(function() {
|
||||
throw Error('Should have timed out on page load');
|
||||
}, function(e) {
|
||||
if (!(e instanceof error.ScriptTimeoutError)
|
||||
&& !(e instanceof error.TimeoutError)) {
|
||||
throw Error('Unexpected error response: ' + e);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
59
node_modules/selenium-webdriver/test/phantomjs/execute_phantomjs_test.js
generated
vendored
Normal file
59
node_modules/selenium-webdriver/test/phantomjs/execute_phantomjs_test.js
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
var path = require('path');
|
||||
var test = require('../../lib/test');
|
||||
|
||||
test.suite(function(env) {
|
||||
var driver;
|
||||
|
||||
test.before(function*() {
|
||||
driver = yield env.builder().build();
|
||||
});
|
||||
|
||||
test.after(function() {
|
||||
return driver.quit();
|
||||
});
|
||||
|
||||
var testPageUrl =
|
||||
'data:text/html,<html><h1>' + path.basename(__filename) + '</h1></html>';
|
||||
|
||||
test.beforeEach(function() {
|
||||
return driver.get(testPageUrl);
|
||||
});
|
||||
|
||||
describe('phantomjs.Driver', function() {
|
||||
describe('#executePhantomJS()', function() {
|
||||
|
||||
test.it('can execute scripts using PhantomJS API', function*() {
|
||||
let url = yield driver.executePhantomJS('return this.url;');
|
||||
assert.equal(testPageUrl, decodeURIComponent(url));
|
||||
});
|
||||
|
||||
test.it('can execute scripts as functions', function*() {
|
||||
let result = yield driver.executePhantomJS(function(a, b) {
|
||||
return a + b;
|
||||
}, 1, 2);
|
||||
|
||||
assert.equal(3, result);
|
||||
});
|
||||
});
|
||||
});
|
||||
}, {browsers: ['phantomjs']});
|
180
node_modules/selenium-webdriver/test/proxy_test.js
generated
vendored
Normal file
180
node_modules/selenium-webdriver/test/proxy_test.js
generated
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var http = require('http'),
|
||||
url = require('url');
|
||||
|
||||
var Browser = require('..').Browser,
|
||||
promise = require('..').promise,
|
||||
firefox = require('../firefox'),
|
||||
proxy = require('../proxy'),
|
||||
assert = require('../testing/assert'),
|
||||
test = require('../lib/test'),
|
||||
Server = require('../lib/test/httpserver').Server,
|
||||
Pages = test.Pages;
|
||||
|
||||
test.suite(function(env) {
|
||||
function writeResponse(res, body, encoding, contentType) {
|
||||
res.writeHead(200, {
|
||||
'Content-Length': Buffer.byteLength(body, encoding),
|
||||
'Content-Type': contentType
|
||||
});
|
||||
res.end(body);
|
||||
}
|
||||
|
||||
function writePacFile(res) {
|
||||
writeResponse(res, [
|
||||
'function FindProxyForURL(url, host) {',
|
||||
' if (shExpMatch(url, "' + goodbyeServer.url('*') + '")) {',
|
||||
' return "DIRECT";',
|
||||
' }',
|
||||
' return "PROXY ' + proxyServer.host() + '";',
|
||||
'}'
|
||||
].join('\n'), 'ascii', 'application/x-javascript-config');
|
||||
}
|
||||
|
||||
var proxyServer = new Server(function(req, res) {
|
||||
var pathname = url.parse(req.url).pathname;
|
||||
if (pathname === '/proxy.pac') {
|
||||
return writePacFile(res);
|
||||
}
|
||||
|
||||
writeResponse(res, [
|
||||
'<!DOCTYPE html>',
|
||||
'<title>Proxy page</title>',
|
||||
'<h3>This is the proxy landing page</h3>'
|
||||
].join(''), 'utf8', 'text/html; charset=UTF-8');
|
||||
});
|
||||
|
||||
var helloServer = new Server(function(req, res) {
|
||||
writeResponse(res, [
|
||||
'<!DOCTYPE html>',
|
||||
'<title>Hello</title>',
|
||||
'<h3>Hello, world!</h3>'
|
||||
].join(''), 'utf8', 'text/html; charset=UTF-8');
|
||||
});
|
||||
|
||||
var goodbyeServer = new Server(function(req, res) {
|
||||
writeResponse(res, [
|
||||
'<!DOCTYPE html>',
|
||||
'<title>Goodbye</title>',
|
||||
'<h3>Goodbye, world!</h3>'
|
||||
].join(''), 'utf8', 'text/html; charset=UTF-8');
|
||||
});
|
||||
|
||||
// Cannot pass start directly to mocha's before, as mocha will interpret the optional
|
||||
// port parameter as an async callback parameter.
|
||||
function mkStartFunc(server) {
|
||||
return function() {
|
||||
return server.start();
|
||||
};
|
||||
}
|
||||
|
||||
test.before(mkStartFunc(proxyServer));
|
||||
test.before(mkStartFunc(helloServer));
|
||||
test.before(mkStartFunc(goodbyeServer));
|
||||
|
||||
test.after(proxyServer.stop.bind(proxyServer));
|
||||
test.after(helloServer.stop.bind(helloServer));
|
||||
test.after(goodbyeServer.stop.bind(goodbyeServer));
|
||||
|
||||
var driver;
|
||||
test.beforeEach(function() { driver = null; });
|
||||
test.afterEach(function() { return driver && driver.quit(); });
|
||||
|
||||
function createDriver(proxy) {
|
||||
// For Firefox we need to explicitly enable proxies for localhost by
|
||||
// clearing the network.proxy.no_proxies_on preference.
|
||||
let profile = new firefox.Profile();
|
||||
profile.setPreference('network.proxy.no_proxies_on', '');
|
||||
|
||||
return driver = env.builder()
|
||||
.setFirefoxOptions(new firefox.Options().setProfile(profile))
|
||||
.setProxy(proxy)
|
||||
.build();
|
||||
}
|
||||
|
||||
// Proxy support not implemented.
|
||||
test.ignore(env.browsers(Browser.IE, Browser.OPERA, Browser.SAFARI)).
|
||||
describe('manual proxy settings', function() {
|
||||
// phantomjs 1.9.1 in webdriver mode does not appear to respect proxy
|
||||
// settings.
|
||||
test.ignore(env.browsers(Browser.PHANTOM_JS)).
|
||||
it('can configure HTTP proxy host', function*() {
|
||||
yield createDriver(proxy.manual({
|
||||
http: proxyServer.host()
|
||||
}));
|
||||
|
||||
yield driver.get(helloServer.url());
|
||||
yield assert(driver.getTitle()).equalTo('Proxy page');
|
||||
yield assert(driver.findElement({tagName: 'h3'}).getText()).
|
||||
equalTo('This is the proxy landing page');
|
||||
});
|
||||
|
||||
// PhantomJS does not support bypassing the proxy for individual hosts.
|
||||
// geckodriver does not support the bypass option, this must be configured
|
||||
// through profile preferences.
|
||||
test.ignore(env.browsers(
|
||||
Browser.FIREFOX,
|
||||
'legacy-' + Browser.FIREFOX,
|
||||
Browser.PHANTOM_JS)).
|
||||
it('can bypass proxy for specific hosts', function*() {
|
||||
yield createDriver(proxy.manual({
|
||||
http: proxyServer.host(),
|
||||
bypass: helloServer.host()
|
||||
}));
|
||||
|
||||
yield driver.get(helloServer.url());
|
||||
yield assert(driver.getTitle()).equalTo('Hello');
|
||||
yield assert(driver.findElement({tagName: 'h3'}).getText()).
|
||||
equalTo('Hello, world!');
|
||||
|
||||
yield driver.get(goodbyeServer.url());
|
||||
yield assert(driver.getTitle()).equalTo('Proxy page');
|
||||
yield assert(driver.findElement({tagName: 'h3'}).getText()).
|
||||
equalTo('This is the proxy landing page');
|
||||
});
|
||||
|
||||
// TODO: test ftp and https proxies.
|
||||
});
|
||||
|
||||
// PhantomJS does not support PAC file proxy configuration.
|
||||
// Safari does not support proxies.
|
||||
test.ignore(env.browsers(
|
||||
Browser.IE, Browser.OPERA, Browser.PHANTOM_JS, Browser.SAFARI)).
|
||||
describe('pac proxy settings', function() {
|
||||
test.it('can configure proxy through PAC file', function*() {
|
||||
yield createDriver(proxy.pac(proxyServer.url('/proxy.pac')));
|
||||
|
||||
yield driver.get(helloServer.url());
|
||||
yield assert(driver.getTitle()).equalTo('Proxy page');
|
||||
yield assert(driver.findElement({tagName: 'h3'}).getText()).
|
||||
equalTo('This is the proxy landing page');
|
||||
|
||||
yield driver.get(goodbyeServer.url());
|
||||
yield assert(driver.getTitle()).equalTo('Goodbye');
|
||||
yield assert(driver.findElement({tagName: 'h3'}).getText()).
|
||||
equalTo('Goodbye, world!');
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: figure out how to test direct and system proxy settings.
|
||||
describe.skip('direct proxy settings', function() {});
|
||||
describe.skip('system proxy settings', function() {});
|
||||
});
|
117
node_modules/selenium-webdriver/test/remote_test.js
generated
vendored
Normal file
117
node_modules/selenium-webdriver/test/remote_test.js
generated
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var assert = require('assert'),
|
||||
fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
var promise = require('../').promise,
|
||||
io = require('../io'),
|
||||
cmd = require('../lib/command'),
|
||||
remote = require('../remote');
|
||||
|
||||
const {enablePromiseManager} = require('../lib/test/promise');
|
||||
|
||||
describe('DriverService', function() {
|
||||
describe('start()', function() {
|
||||
var service;
|
||||
|
||||
beforeEach(function() {
|
||||
service = new remote.DriverService(process.execPath, {
|
||||
port: 1234,
|
||||
args: ['-e', 'process.exit(1)']
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
return service.kill();
|
||||
});
|
||||
|
||||
it('fails if child-process dies', function() {
|
||||
this.timeout(1000);
|
||||
return service.start(500).then(expectFailure, verifyFailure);
|
||||
});
|
||||
|
||||
enablePromiseManager(function() {
|
||||
describe(
|
||||
'failures propagate through control flow if child-process dies',
|
||||
function() {
|
||||
it('', function() {
|
||||
this.timeout(1000);
|
||||
|
||||
return promise.controlFlow().execute(function() {
|
||||
promise.controlFlow().execute(function() {
|
||||
return service.start(500);
|
||||
});
|
||||
}).then(expectFailure, verifyFailure);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function verifyFailure(e) {
|
||||
assert.ok(!(e instanceof promise.CancellationError));
|
||||
assert.equal('Server terminated early with status 1', e.message);
|
||||
}
|
||||
|
||||
function expectFailure() {
|
||||
throw Error('expected to fail');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('FileDetector', function() {
|
||||
class ExplodingDriver {
|
||||
schedule() {
|
||||
throw Error('unexpected call');
|
||||
}
|
||||
}
|
||||
|
||||
it('returns the original path if the file does not exist', function() {
|
||||
return io.tmpDir().then(dir => {
|
||||
let theFile = path.join(dir, 'not-there');
|
||||
return (new remote.FileDetector)
|
||||
.handleFile(new ExplodingDriver, theFile)
|
||||
.then(f => assert.equal(f, theFile));
|
||||
});
|
||||
});
|
||||
|
||||
it('returns the original path if it is a directory', function() {
|
||||
return io.tmpDir().then(dir => {
|
||||
return (new remote.FileDetector)
|
||||
.handleFile(new ExplodingDriver, dir)
|
||||
.then(f => assert.equal(f, dir));
|
||||
});
|
||||
});
|
||||
|
||||
it('attempts to upload valid files', function() {
|
||||
return io.tmpFile().then(theFile => {
|
||||
return (new remote.FileDetector)
|
||||
.handleFile(
|
||||
new (class FakeDriver {
|
||||
schedule(command) {
|
||||
assert.equal(command.getName(), cmd.Name.UPLOAD_FILE);
|
||||
assert.equal(typeof command.getParameters()['file'], 'string');
|
||||
return Promise.resolve('success!');
|
||||
}
|
||||
}),
|
||||
theFile)
|
||||
.then(f => assert.equal(f, 'success!'));
|
||||
});
|
||||
});
|
||||
});
|
63
node_modules/selenium-webdriver/test/stale_element_test.js
generated
vendored
Normal file
63
node_modules/selenium-webdriver/test/stale_element_test.js
generated
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var fail = require('assert').fail;
|
||||
|
||||
var Browser = require('..').Browser,
|
||||
By = require('..').By,
|
||||
error = require('..').error,
|
||||
until = require('..').until,
|
||||
assert = require('../testing/assert'),
|
||||
test = require('../lib/test'),
|
||||
Pages = test.Pages;
|
||||
|
||||
|
||||
test.suite(function(env) {
|
||||
var driver;
|
||||
test.before(function*() { driver = yield env.builder().build(); });
|
||||
test.after(function() { return driver.quit(); });
|
||||
|
||||
// Element never goes stale in Safari.
|
||||
test.ignore(env.browsers(Browser.SAFARI)).
|
||||
it(
|
||||
'dynamically removing elements from the DOM trigger a ' +
|
||||
'StaleElementReferenceError',
|
||||
function*() {
|
||||
yield driver.get(Pages.javascriptPage);
|
||||
|
||||
var toBeDeleted = yield driver.findElement(By.id('deleted'));
|
||||
yield assert(toBeDeleted.getTagName()).isEqualTo('p');
|
||||
|
||||
yield driver.findElement(By.id('delete')).click();
|
||||
yield driver.wait(until.stalenessOf(toBeDeleted), 5000);
|
||||
});
|
||||
|
||||
test.it('an element found in a different frame is stale', function*() {
|
||||
yield driver.get(Pages.missedJsReferencePage);
|
||||
|
||||
var frame = yield driver.findElement(By.css('iframe[name="inner"]'));
|
||||
yield driver.switchTo().frame(frame);
|
||||
|
||||
var el = yield driver.findElement(By.id('oneline'));
|
||||
yield driver.switchTo().defaultContent();
|
||||
return el.getText().then(fail, function(e) {
|
||||
assert(e).instanceOf(error.StaleElementReferenceError);
|
||||
});
|
||||
});
|
||||
});
|
36
node_modules/selenium-webdriver/test/tag_name_test.js
generated
vendored
Normal file
36
node_modules/selenium-webdriver/test/tag_name_test.js
generated
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var By = require('..').By,
|
||||
assert = require('../testing/assert'),
|
||||
test = require('../lib/test');
|
||||
|
||||
|
||||
test.suite(function(env) {
|
||||
var driver;
|
||||
test.after(function() { return driver.quit(); });
|
||||
|
||||
test.it('should return lower case tag name', function*() {
|
||||
driver = yield env.builder().build();
|
||||
yield driver.get(test.Pages.formPage);
|
||||
|
||||
let el = yield driver.findElement(By.id('cheese'));
|
||||
return assert(el.getTagName()).equalTo('input');
|
||||
});
|
||||
});
|
373
node_modules/selenium-webdriver/test/testing/assert_test.js
generated
vendored
Normal file
373
node_modules/selenium-webdriver/test/testing/assert_test.js
generated
vendored
Normal file
|
@ -0,0 +1,373 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('../../testing/assert');
|
||||
|
||||
const AssertionError = require('assert').AssertionError;
|
||||
const assertTrue = require('assert').ok;
|
||||
const assertEqual = require('assert').equal;
|
||||
const assertThrows = require('assert').throws;
|
||||
const fail = require('assert').fail;
|
||||
|
||||
|
||||
describe('assert', function() {
|
||||
describe('atLeast', function() {
|
||||
it('compares subject >= value', function() {
|
||||
assert(1).atLeast(0);
|
||||
assert(1).atLeast(1);
|
||||
assertThrows(() => assert(1).atLeast(2));
|
||||
});
|
||||
|
||||
it('accepts failure message', function() {
|
||||
assertThrows(
|
||||
() => assert(1).atLeast(2, 'hi there!'),
|
||||
(error) => error.message.indexOf('hi there') != -1);
|
||||
});
|
||||
|
||||
it('fails if given a non-numeric subject', function() {
|
||||
assertThrows(() => assert('a').atLeast(1));
|
||||
});
|
||||
|
||||
it('fails if given a non-numeric bound', function() {
|
||||
assertThrows(() => assert(1).atLeast('a'));
|
||||
});
|
||||
|
||||
it('waits for promised subject', function() {
|
||||
return assert(Promise.resolve(123)).atLeast(100);
|
||||
});
|
||||
|
||||
it('waits for promised subject (with failure)', function() {
|
||||
return assert(Promise.resolve(100))
|
||||
.atLeast(123)
|
||||
.then(() => fail('should have failed'), function(e) {
|
||||
assertInstanceOf(AssertionError, e);
|
||||
assertEqual('100 >= 123', e.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('atMost', function() {
|
||||
it('compares subject <= value', function() {
|
||||
assertThrows(() => assert(1).atMost(0));
|
||||
assert(1).atMost(1);
|
||||
assert(1).atMost(2);
|
||||
});
|
||||
|
||||
it('accepts failure message', function() {
|
||||
assertThrows(
|
||||
() => assert(1).atMost(0, 'hi there!'),
|
||||
(error) => error.message.indexOf('hi there!') != -1);
|
||||
});
|
||||
|
||||
it('fails if given a non-numeric subject', function() {
|
||||
assertThrows(() => assert(1).atMost('a'));
|
||||
});
|
||||
|
||||
it('fails if given a non-numeric bound', function() {
|
||||
assertThrows(() => assert('a').atMost(1));
|
||||
});
|
||||
|
||||
it('waits for promised subject', function() {
|
||||
return assert(Promise.resolve(100)).atMost(123);
|
||||
});
|
||||
|
||||
it('waits for promised subject (with failure)', function() {
|
||||
return assert(Promise.resolve(123))
|
||||
.atMost(100)
|
||||
.then(() => fail('should have failed'), function(e) {
|
||||
assertInstanceOf(AssertionError, e);
|
||||
assertEqual('123 <= 100', e.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('greaterThan', function() {
|
||||
it('compares subject > value', function() {
|
||||
assertThrows(() => assert(1).greaterThan(1));
|
||||
assertThrows(() => assert(1).greaterThan(2));
|
||||
assert(2).greaterThan(1);
|
||||
});
|
||||
|
||||
it('accepts failure message', function() {
|
||||
assertThrows(
|
||||
() => assert(0).greaterThan(1, 'hi there!'),
|
||||
(error) => error.message.indexOf('hi there!') != -1);
|
||||
});
|
||||
|
||||
it('fails if given a non-numeric subject', function() {
|
||||
assertThrows(() => assert('a').atMost(1));
|
||||
});
|
||||
|
||||
it('fails if given a non-numeric bound', function() {
|
||||
assertThrows(() => assert(1).atMost('a'));
|
||||
});
|
||||
|
||||
it('waits for promised subject', function() {
|
||||
return assert(Promise.resolve(123)).greaterThan(100);
|
||||
});
|
||||
|
||||
it('waits for promised subject (with failure)', function() {
|
||||
return assert(Promise.resolve(100))
|
||||
.greaterThan(123)
|
||||
.then(() => fail('should have failed'), function(e) {
|
||||
assertInstanceOf(AssertionError, e);
|
||||
assertEqual('100 > 123', e.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('lessThan', function() {
|
||||
it('compares subject < value', function() {
|
||||
assertThrows(() => assert(1).lessThan(0));
|
||||
assertThrows(() => assert(1).lessThan(1));
|
||||
assert(1).lessThan(2);
|
||||
});
|
||||
|
||||
it('accepts failure message', function() {
|
||||
assertThrows(
|
||||
() => assert(1).lessThan(0, 'hi there!'),
|
||||
(error) => error.message.indexOf('hi there!') != -1);
|
||||
});
|
||||
|
||||
it('fails if given a non-numeric subject', function() {
|
||||
assertThrows(() => assert('a').lessThan(1));
|
||||
});
|
||||
|
||||
it('fails if given a non-numeric bound', function() {
|
||||
assertThrows(() => assert(1).lessThan('a'));
|
||||
});
|
||||
|
||||
it('waits for promised subject', function() {
|
||||
return assert(Promise.resolve(100)).lessThan(123);
|
||||
});
|
||||
|
||||
it('waits for promised subject (with failure)', function() {
|
||||
return assert(Promise.resolve(123))
|
||||
.lessThan(100)
|
||||
.then(() => fail('should have failed'), function(e) {
|
||||
assertInstanceOf(AssertionError, e);
|
||||
assertEqual('123 < 100', e.message);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('closeTo', function() {
|
||||
it('accepts values within epislon of target', function() {
|
||||
assert(123).closeTo(123, 0);
|
||||
assert(123).closeTo(124, 1);
|
||||
assert(125).closeTo(124, 1);
|
||||
|
||||
assertThrows(() => assert(123).closeTo(125, .1));
|
||||
assertThrows(() => assert(1./3).closeTo(.8, .01));
|
||||
});
|
||||
|
||||
it('waits for promised values', function() {
|
||||
let p = new Promise(resolve => setTimeout(() => resolve(123), 10));
|
||||
return assert(p).closeTo(124, 1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('instanceOf', function() {
|
||||
it('works with direct instances', function() {
|
||||
assert(Error('foo')).instanceOf(Error);
|
||||
});
|
||||
|
||||
it('works with sub-types', function() {
|
||||
assert(TypeError('foo')).instanceOf(Error);
|
||||
});
|
||||
|
||||
it('parent types are not instances of sub-types', function() {
|
||||
assertThrows(() => assert(Error('foo')).instanceOf(TypeError));
|
||||
});
|
||||
});
|
||||
|
||||
describe('isNull', function() {
|
||||
it('normal case', function() {
|
||||
assert(null).isNull();
|
||||
assertThrows(() => assert(1).isNull());
|
||||
});
|
||||
|
||||
it('handles promised values', function() {
|
||||
let p = new Promise(function(f) {
|
||||
setTimeout(() => f(null), 10);
|
||||
});
|
||||
return assert(p).isNull();
|
||||
});
|
||||
|
||||
it('does not match on undefined', function() {
|
||||
assertThrows(() => assert(void(0)).isNull());
|
||||
})
|
||||
});
|
||||
|
||||
describe('isUndefined', function() {
|
||||
it('normal case', function() {
|
||||
assert(void(0)).isUndefined();
|
||||
assertThrows(() => assert(1).isUndefined());
|
||||
});
|
||||
|
||||
it('handles promised values', function() {
|
||||
let p = new Promise(function(f) {
|
||||
setTimeout(() => f(void(0)), 10);
|
||||
});
|
||||
return assert(p).isUndefined();
|
||||
});
|
||||
|
||||
it('does not match on null', function() {
|
||||
assertThrows(() => assert(null).isUndefined());
|
||||
})
|
||||
});
|
||||
|
||||
describe('contains', function() {
|
||||
it('works with strings', function() {
|
||||
assert('abc').contains('a');
|
||||
assert('abc').contains('ab');
|
||||
assert('abc').contains('abc');
|
||||
assert('abc').contains('bc');
|
||||
assert('abc').contains('c');
|
||||
assertThrows(() => assert('abc').contains('d'));
|
||||
});
|
||||
|
||||
it('works with arrays', function() {
|
||||
assert([1, 2, 3]).contains(1);
|
||||
assert([1, 2, 3]).contains(2);
|
||||
assert([1, 2, 3]).contains(3);
|
||||
assertThrows(() => assert([1, 2]).contains(3));
|
||||
});
|
||||
|
||||
it('works with maps', function() {
|
||||
let m = new Map;
|
||||
m.set(1, 2);
|
||||
assert(m).contains(1);
|
||||
assertThrows(() => assert(m).contains(2));
|
||||
});
|
||||
|
||||
it('works with sets', function() {
|
||||
let s = new Set;
|
||||
s.add(1);
|
||||
assert(s).contains(1);
|
||||
assertThrows(() => assert(s).contains(2));
|
||||
});
|
||||
|
||||
it('requires an array, string, map, or set subject', function() {
|
||||
assertThrows(() => assert(123).contains('a'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('endsWith', function() {
|
||||
it('works', function() {
|
||||
assert('abc').endsWith('abc');
|
||||
assert('abc').endsWith('bc');
|
||||
assert('abc').endsWith('c');
|
||||
assertThrows(() => assert('abc').endsWith('d'));
|
||||
})
|
||||
});
|
||||
|
||||
describe('startsWith', function() {
|
||||
it('works', function() {
|
||||
assert('abc').startsWith('abc');
|
||||
assert('abc').startsWith('ab');
|
||||
assert('abc').startsWith('a');
|
||||
assertThrows(() => assert('abc').startsWith('d'));
|
||||
})
|
||||
});
|
||||
|
||||
describe('matches', function() {
|
||||
it('requires a regex value', function() {
|
||||
assertThrows(() => assert('abc').matches(1234));
|
||||
});
|
||||
|
||||
it('requires a string value', function() {
|
||||
assertThrows(() => assert(1234).matches(/abc/));
|
||||
});
|
||||
|
||||
it('requires a string value (promise case)', function() {
|
||||
return assert(Promise.resolve(1234))
|
||||
.matches(/abc/)
|
||||
.then(fail, function(error) {
|
||||
assertEqual(
|
||||
'Expected a string matching /abc/, got <1234> (number)',
|
||||
error.message);
|
||||
});
|
||||
});
|
||||
|
||||
it('applies regex', function() {
|
||||
assert('abc').matches(/abc/);
|
||||
assertThrows(() => assert('def').matches(/abc/));
|
||||
});
|
||||
});
|
||||
|
||||
describe('isTrue', function() {
|
||||
it('only accepts booleans', function() {
|
||||
assertThrows(() => assert(123).isTrue());
|
||||
});
|
||||
|
||||
it('accepts true values', function() {
|
||||
assert(true).isTrue();
|
||||
assert(Boolean('abc')).isTrue();
|
||||
return assert(Promise.resolve(true)).isTrue();
|
||||
});
|
||||
|
||||
it('rejects false values', function() {
|
||||
assertThrows(() => assert(false).isTrue());
|
||||
assertThrows(() => assert(Boolean(0)).isTrue());
|
||||
return assert(Promise.resolve(false)).isTrue()
|
||||
.then(fail, function() {/*no-op, ok*/});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isFalse', function() {
|
||||
it('only accepts booleans', function() {
|
||||
assertThrows(() => assert(123).isFalse());
|
||||
})
|
||||
|
||||
it('accepts false values', function() {
|
||||
assert(false).isFalse();
|
||||
assert(Boolean('')).isFalse();
|
||||
return assert(Promise.resolve(false)).isFalse();
|
||||
});
|
||||
|
||||
it('rejects true values', function() {
|
||||
assertThrows(() => assert(true).isFalse());
|
||||
assertThrows(() => assert(Boolean(1)).isFalse());
|
||||
return assert(Promise.resolve(true)).isFalse()
|
||||
.then(fail, function() {/*no-op, ok*/});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isEqualTo', function() {
|
||||
it('is strict equality', function() {
|
||||
assert('abc').isEqualTo('abc');
|
||||
assert('abc').equals('abc');
|
||||
assert('abc').equalTo('abc');
|
||||
assertThrows(() => assert('1').isEqualTo(1));
|
||||
});
|
||||
});
|
||||
|
||||
describe('notEqualTo', function() {
|
||||
it('tests strict equality', function() {
|
||||
assert('1').notEqualTo(1);
|
||||
assert(1).notEqualTo('1');
|
||||
assertThrows(() => assert('abc').notEqualTo('abc'));
|
||||
});
|
||||
});
|
||||
|
||||
function assertInstanceOf(ctor, value) {
|
||||
assertTrue(value instanceof ctor);
|
||||
}
|
||||
});
|
224
node_modules/selenium-webdriver/test/testing/index_test.js
generated
vendored
Normal file
224
node_modules/selenium-webdriver/test/testing/index_test.js
generated
vendored
Normal file
|
@ -0,0 +1,224 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const promise = require('../..').promise;
|
||||
const {enablePromiseManager} = require('../../lib/test/promise');
|
||||
|
||||
|
||||
var test = require('../../testing');
|
||||
|
||||
describe('Mocha Integration', function() {
|
||||
|
||||
describe('beforeEach properly binds "this"', function() {
|
||||
beforeEach(function() { this.x = 1; });
|
||||
test.beforeEach(function() { this.x = 2; });
|
||||
it('', function() { assert.equal(this.x, 2); });
|
||||
});
|
||||
|
||||
describe('afterEach properly binds "this"', function() {
|
||||
it('', function() { this.x = 1; });
|
||||
test.afterEach(function() { this.x = 2; });
|
||||
afterEach(function() { assert.equal(this.x, 2); });
|
||||
});
|
||||
|
||||
describe('it properly binds "this"', function() {
|
||||
beforeEach(function() { this.x = 1; });
|
||||
test.it('', function() { this.x = 2; });
|
||||
afterEach(function() { assert.equal(this.x, 2); });
|
||||
});
|
||||
|
||||
enablePromiseManager(function() {
|
||||
describe('timeout handling', function() {
|
||||
describe('it does not reset the control flow on a non-timeout', function() {
|
||||
var flowReset = false;
|
||||
|
||||
beforeEach(function() {
|
||||
flowReset = false;
|
||||
test.controlFlow().once(promise.ControlFlow.EventType.RESET, onreset);
|
||||
});
|
||||
|
||||
test.it('', function() {
|
||||
this.timeout(100);
|
||||
return promise.delayed(50);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
assert.ok(!flowReset);
|
||||
test.controlFlow().removeListener(
|
||||
promise.ControlFlow.EventType.RESET, onreset);
|
||||
});
|
||||
|
||||
function onreset() {
|
||||
flowReset = true;
|
||||
}
|
||||
});
|
||||
|
||||
describe('it resets the control flow after a timeout' ,function() {
|
||||
var timeoutErr, flowReset;
|
||||
|
||||
beforeEach(function() {
|
||||
flowReset = false;
|
||||
test.controlFlow().once(promise.ControlFlow.EventType.RESET, onreset);
|
||||
});
|
||||
|
||||
test.it('', function() {
|
||||
var callback = this.runnable().callback;
|
||||
var test = this;
|
||||
this.runnable().callback = function(err) {
|
||||
timeoutErr = err;
|
||||
// Reset our timeout to 0 so Mocha does not fail the test.
|
||||
test.timeout(0);
|
||||
// When we invoke the real callback, do not pass along the error so
|
||||
// Mocha does not fail the test.
|
||||
return callback.call(this);
|
||||
};
|
||||
|
||||
test.timeout(50);
|
||||
return promise.defer().promise;
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
return Promise.resolve().then(function() {
|
||||
test.controlFlow().removeListener(
|
||||
promise.ControlFlow.EventType.RESET, onreset);
|
||||
assert.ok(flowReset, 'control flow was not reset after a timeout');
|
||||
});
|
||||
});
|
||||
|
||||
function onreset() {
|
||||
flowReset = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('async "done" support', function() {
|
||||
this.timeout(2*1000);
|
||||
|
||||
var waited = false;
|
||||
var DELAY = 100; // ms enough to notice
|
||||
|
||||
// Each test asynchronously sets waited to true, so clear/check waited
|
||||
// before/after:
|
||||
beforeEach(function() {
|
||||
waited = false;
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
assert.strictEqual(waited, true);
|
||||
});
|
||||
|
||||
// --- First, vanilla mocha "it" should support the "done" callback correctly.
|
||||
|
||||
// This 'it' should block until 'done' is invoked
|
||||
it('vanilla delayed', function(done) {
|
||||
setTimeout(function delayedVanillaTimeout() {
|
||||
waited = true;
|
||||
done();
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
// --- Now with the webdriver wrappers for 'it' should support the "done" callback:
|
||||
|
||||
test.it('delayed', function(done) {
|
||||
assert(done);
|
||||
assert.strictEqual(typeof done, 'function');
|
||||
setTimeout(function delayedTimeoutCallback() {
|
||||
waited = true;
|
||||
done();
|
||||
}, DELAY);
|
||||
});
|
||||
|
||||
// --- And test that the webdriver wrapper for 'it' works with a returned promise, too:
|
||||
|
||||
test.it('delayed by promise', function() {
|
||||
var defer = promise.defer();
|
||||
setTimeout(function delayedPromiseCallback() {
|
||||
waited = true;
|
||||
defer.fulfill('ignored');
|
||||
});
|
||||
return defer.promise;
|
||||
});
|
||||
});
|
||||
|
||||
describe('ControlFlow and "done" work together', function() {
|
||||
var flow, order;
|
||||
before(function() {
|
||||
order = [];
|
||||
flow = test.controlFlow();
|
||||
flow.execute(function() { order.push(1); });
|
||||
});
|
||||
|
||||
test.it('control flow updates and async done', function(done) {
|
||||
flow.execute(function() { order.push(2); });
|
||||
flow.execute(function() { order.push(3); }).then(function() {
|
||||
order.push(4);
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
after(function() {
|
||||
assert.deepEqual([1, 2, 3, 4], order);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('generator support', function() {
|
||||
let arr;
|
||||
|
||||
beforeEach(() => arr = []);
|
||||
afterEach(() => assert.deepEqual(arr, [0, 1, 2, 3]));
|
||||
|
||||
test.it('sync generator', function* () {
|
||||
arr.push(yield arr.length);
|
||||
arr.push(yield arr.length);
|
||||
arr.push(yield arr.length);
|
||||
arr.push(yield arr.length);
|
||||
});
|
||||
|
||||
test.it('async generator', function* () {
|
||||
arr.push(yield Promise.resolve(arr.length));
|
||||
arr.push(yield Promise.resolve(arr.length));
|
||||
arr.push(yield Promise.resolve(arr.length));
|
||||
arr.push(yield Promise.resolve(arr.length));
|
||||
});
|
||||
|
||||
test.it('generator returns promise', function*() {
|
||||
arr.push(yield Promise.resolve(arr.length));
|
||||
arr.push(yield Promise.resolve(arr.length));
|
||||
arr.push(yield Promise.resolve(arr.length));
|
||||
setTimeout(_ => arr.push(arr.length), 10);
|
||||
return new Promise((resolve) => setTimeout(_ => resolve(), 25));
|
||||
});
|
||||
|
||||
describe('generator runs with proper "this" context', () => {
|
||||
before(function() { this.values = [0, 1, 2, 3]; });
|
||||
test.it('', function*() {
|
||||
arr = this.values;
|
||||
});
|
||||
});
|
||||
|
||||
it('generator function must not take a callback', function() {
|
||||
arr = [0, 1, 2, 3]; // For teardown hook.
|
||||
assert.throws(_ => {
|
||||
test.it('', function*(done){});
|
||||
}, TypeError);
|
||||
});
|
||||
});
|
||||
});
|
86
node_modules/selenium-webdriver/test/upload_test.js
generated
vendored
Normal file
86
node_modules/selenium-webdriver/test/upload_test.js
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
var Browser = require('..').Browser,
|
||||
By = require('..').By,
|
||||
until = require('..').until,
|
||||
io = require('../io'),
|
||||
remote = require('../remote'),
|
||||
assert = require('../testing/assert'),
|
||||
test = require('../lib/test'),
|
||||
Pages = test.Pages;
|
||||
|
||||
test.suite(function(env) {
|
||||
var LOREM_IPSUM_TEXT = 'lorem ipsum dolor sit amet';
|
||||
var FILE_HTML = '<!DOCTYPE html><div>' + LOREM_IPSUM_TEXT + '</div>';
|
||||
|
||||
var fp;
|
||||
test.before(function() {
|
||||
return fp = io.tmpFile().then(function(fp) {
|
||||
fs.writeFileSync(fp, FILE_HTML);
|
||||
return fp;
|
||||
});
|
||||
})
|
||||
|
||||
var driver;
|
||||
test.before(function*() {
|
||||
driver = yield env.builder().build();
|
||||
});
|
||||
|
||||
test.after(function() {
|
||||
if (driver) {
|
||||
return driver.quit();
|
||||
}
|
||||
});
|
||||
|
||||
test.ignore(env.browsers(
|
||||
Browser.IPAD,
|
||||
Browser.IPHONE,
|
||||
// Uploads broken in PhantomJS 2.0.
|
||||
// See https://github.com/ariya/phantomjs/issues/12506
|
||||
Browser.PHANTOM_JS,
|
||||
Browser.SAFARI)).
|
||||
it('can upload files', function*() {
|
||||
driver.setFileDetector(new remote.FileDetector);
|
||||
|
||||
yield driver.get(Pages.uploadPage);
|
||||
|
||||
var fp = yield driver.call(function() {
|
||||
return io.tmpFile().then(function(fp) {
|
||||
fs.writeFileSync(fp, FILE_HTML);
|
||||
return fp;
|
||||
});
|
||||
});
|
||||
|
||||
yield driver.findElement(By.id('upload')).sendKeys(fp);
|
||||
yield driver.findElement(By.id('go')).click();
|
||||
|
||||
// Uploading files across a network may take a while, even if they're small.
|
||||
var label = yield driver.findElement(By.id('upload_label'));
|
||||
yield driver.wait(until.elementIsNotVisible(label),
|
||||
10 * 1000, 'File took longer than 10 seconds to upload!');
|
||||
|
||||
var frame = yield driver.findElement(By.id('upload_target'));
|
||||
yield driver.switchTo().frame(frame);
|
||||
yield assert(driver.findElement(By.css('body')).getText())
|
||||
.equalTo(LOREM_IPSUM_TEXT);
|
||||
});
|
||||
});
|
161
node_modules/selenium-webdriver/test/window_test.js
generated
vendored
Normal file
161
node_modules/selenium-webdriver/test/window_test.js
generated
vendored
Normal file
|
@ -0,0 +1,161 @@
|
|||
// Licensed to the Software Freedom Conservancy (SFC) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The SFC licenses this file
|
||||
// to you 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.
|
||||
|
||||
'use strict';
|
||||
|
||||
var Browser = require('..').Browser,
|
||||
By = require('..').By,
|
||||
assert = require('../testing/assert'),
|
||||
test = require('../lib/test');
|
||||
|
||||
|
||||
test.suite(function(env) {
|
||||
var driver;
|
||||
|
||||
test.before(function*() { driver = yield env.builder().build(); });
|
||||
test.after(function() { return driver.quit(); });
|
||||
|
||||
test.beforeEach(function() {
|
||||
return driver.switchTo().defaultContent();
|
||||
});
|
||||
|
||||
test.it('can set size of the current window', function*() {
|
||||
yield driver.get(test.Pages.echoPage);
|
||||
yield changeSizeBy(-20, -20);
|
||||
});
|
||||
|
||||
test.it('can set size of the current window from frame', function*() {
|
||||
yield driver.get(test.Pages.framesetPage);
|
||||
|
||||
var frame = yield driver.findElement({css: 'frame[name="fourth"]'});
|
||||
yield driver.switchTo().frame(frame);
|
||||
yield changeSizeBy(-20, -20);
|
||||
});
|
||||
|
||||
test.it('can set size of the current window from iframe', function*() {
|
||||
yield driver.get(test.Pages.iframePage);
|
||||
|
||||
var frame = yield driver.findElement({css: 'iframe[name="iframe1-name"]'});
|
||||
yield driver.switchTo().frame(frame);
|
||||
yield changeSizeBy(-20, -20);
|
||||
});
|
||||
|
||||
test.it('can switch to a new window', function*() {
|
||||
yield driver.get(test.Pages.xhtmlTestPage);
|
||||
|
||||
let handle = yield driver.getWindowHandle();
|
||||
let originalHandles = yield driver.getAllWindowHandles();
|
||||
|
||||
yield driver.findElement(By.linkText("Open new window")).click();
|
||||
yield driver.wait(forNewWindowToBeOpened(originalHandles), 2000);
|
||||
yield assert(driver.getTitle()).equalTo("XHTML Test Page");
|
||||
|
||||
let newHandle = yield getNewWindowHandle(originalHandles);
|
||||
|
||||
yield driver.switchTo().window(newHandle);
|
||||
yield assert(driver.getTitle()).equalTo("We Arrive Here");
|
||||
});
|
||||
|
||||
test.it('can set the window position of the current window', function*() {
|
||||
let position = yield driver.manage().window().getPosition();
|
||||
|
||||
yield driver.manage().window().setSize(640, 480);
|
||||
yield driver.manage().window().setPosition(position.x + 10, position.y + 10);
|
||||
|
||||
// For phantomjs, setPosition is a no-op and the "window" stays at (0, 0)
|
||||
if (env.currentBrowser() === Browser.PHANTOM_JS) {
|
||||
position = yield driver.manage().window().getPosition();
|
||||
assert(position.x).equalTo(0);
|
||||
assert(position.y).equalTo(0);
|
||||
} else {
|
||||
var dx = position.x + 10;
|
||||
var dy = position.y + 10;
|
||||
return driver.wait(forPositionToBe(dx, dy), 1000);
|
||||
}
|
||||
});
|
||||
|
||||
test.it('can set the window position from a frame', function*() {
|
||||
yield driver.get(test.Pages.iframePage);
|
||||
|
||||
let frame = yield driver.findElement(By.name('iframe1-name'));
|
||||
yield driver.switchTo().frame(frame);
|
||||
|
||||
let position = yield driver.manage().window().getPosition();
|
||||
yield driver.manage().window().setSize(640, 480);
|
||||
yield driver.manage().window().setPosition(position.x + 10, position.y + 10);
|
||||
|
||||
// For phantomjs, setPosition is a no-op and the "window" stays at (0, 0)
|
||||
if (env.currentBrowser() === Browser.PHANTOM_JS) {
|
||||
return driver.manage().window().getPosition().then(function(position) {
|
||||
assert(position.x).equalTo(0);
|
||||
assert(position.y).equalTo(0);
|
||||
});
|
||||
} else {
|
||||
var dx = position.x + 10;
|
||||
var dy = position.y + 10;
|
||||
return driver.wait(forPositionToBe(dx, dy), 1000);
|
||||
}
|
||||
});
|
||||
|
||||
function changeSizeBy(dx, dy) {
|
||||
return driver.manage().window().getSize().then(function(size) {
|
||||
return driver.manage().window()
|
||||
.setSize(size.width + dx, size.height + dy)
|
||||
.then(_ => {
|
||||
return driver.wait(
|
||||
forSizeToBe(size.width + dx, size.height + dy), 1000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function forSizeToBe(w, h) {
|
||||
return function() {
|
||||
return driver.manage().window().getSize().then(function(size) {
|
||||
return size.width === w && size.height === h;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function forPositionToBe(x, y) {
|
||||
return function() {
|
||||
return driver.manage().window().getPosition().then(function(position) {
|
||||
return position.x === x &&
|
||||
// On OSX, the window height may be bumped down 22px for the top
|
||||
// status bar.
|
||||
// On Linux, Opera's window position will be off by 28px.
|
||||
(position.y >= y && position.y <= (y + 28));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function forNewWindowToBeOpened(originalHandles) {
|
||||
return function() {
|
||||
return driver.getAllWindowHandles().then(function(currentHandles) {
|
||||
return currentHandles.length > originalHandles.length;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function getNewWindowHandle(originalHandles) {
|
||||
// Note: this assumes there's just one new window.
|
||||
return driver.getAllWindowHandles().then(function(currentHandles) {
|
||||
return currentHandles.filter(function(i) {
|
||||
return originalHandles.indexOf(i) < 0;
|
||||
})[0];
|
||||
});
|
||||
}
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue