mirror of
https://github.com/ariya/phantomjs.git
synced 2024-09-11 12:55:33 +03:00
Replace assert.js with a new test harness based on W3C testharness.js.
The principal value of this test harness is its support for asynchronous tests -- that is, tests where you have to wait for a callback to happen before you can continue testing. This applies to every test in our testsuite that uses WebPage.open(), and some others as well. With this harness, the test suite is significantly faster and can be made race-free. The API is not exactly the same as W3C testharness.js -- important differences include: test execution is serialized within a file; "file is test" mode has been removed, as we do not need it and it adds significant complexity; several additional assertions have been added; the ability to mark tests as expected to fail, or as to be skipped entirely, has been added. New-style tests can opt out of testharness.js with a "no-harness" directive at the top of the file; this is necessary for a small number of tests (e.g. basics/exit.js) that test functionality the harness reserves for its own use. All existing new-style tests have been converted to testharness.js; some groups of tests have been consolidated into fewer files. The naming convention for tests in regression/ is clarified. Part of issue #13478 (test suite overhaul).
This commit is contained in:
parent
0cc40ddefe
commit
2121b56d5b
126
test/assert.js
126
test/assert.js
@ -1,126 +0,0 @@
|
||||
|
||||
// After the given timeout (in seconds), the script automatically terminates.
|
||||
var timeout = 0.25;
|
||||
|
||||
var total = 0;
|
||||
|
||||
function resetExitTimer() {
|
||||
window.clearTimeout(window.autoExitTimer);
|
||||
window.autoExitTimer = window.setTimeout(function () {
|
||||
console.log(total, 'tests passed.');
|
||||
phantom.exit(0);
|
||||
}, timeout * 1000);
|
||||
}
|
||||
|
||||
function showError() {
|
||||
// Get the stack trace by throwing an exception and catching it.
|
||||
try {
|
||||
throw new Error();
|
||||
} catch (e) {
|
||||
var traces = e.stack.split('\n');
|
||||
// The first one is this showError() function, not useful.
|
||||
// The second is the assertion function, also superfluous.
|
||||
traces = traces.slice(3);
|
||||
console.log(traces.join('\n'));
|
||||
} finally {
|
||||
phantom.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
function showErrorEqual(actual, expected) {
|
||||
console.error('AssertionError: expected', actual, 'to be', expected);
|
||||
|
||||
showError();
|
||||
}
|
||||
|
||||
function showErrorNotEqual(actual, expected) {
|
||||
console.error('AssertionError: expected', actual,
|
||||
'to be different than', expected);
|
||||
|
||||
showError();
|
||||
}
|
||||
|
||||
function isTrue(value) {
|
||||
resetExitTimer();
|
||||
if (!value) {
|
||||
showErrorEqual(value, true);
|
||||
}
|
||||
++total;
|
||||
}
|
||||
|
||||
function equal(actual, expected) {
|
||||
resetExitTimer();
|
||||
if (actual != expected) {
|
||||
showErrorEqual(actual, expected);
|
||||
}
|
||||
++total;
|
||||
}
|
||||
|
||||
function jsonEqual(actual, expected) {
|
||||
resetExitTimer();
|
||||
var actualJson = JSON.stringify(actual);
|
||||
var expectedJson = JSON.stringify(expected);
|
||||
if (actualJson != expectedJson) {
|
||||
showErrorEqual(actualJson, expectedJson);
|
||||
}
|
||||
++total;
|
||||
}
|
||||
|
||||
function notEqual(actual, expected) {
|
||||
resetExitTimer();
|
||||
if (actual == expected) {
|
||||
showErrorNotEqual(actual, expected);
|
||||
}
|
||||
++total;
|
||||
}
|
||||
|
||||
function strictEqual(actual, expected) {
|
||||
resetExitTimer();
|
||||
if (actual !== expected) {
|
||||
showErrorEqual(actual, expected);
|
||||
}
|
||||
++total;
|
||||
}
|
||||
|
||||
function typeOf(object, expected) {
|
||||
resetExitTimer();
|
||||
if (typeof object !== expected) {
|
||||
showErrorEqual(typeof object, expected);
|
||||
}
|
||||
++total;
|
||||
}
|
||||
|
||||
function waitFor(condition, callback, options) {
|
||||
callback = callback || function() {};
|
||||
options = options || {};
|
||||
var poolMs = options.poolMs || 10;
|
||||
var timeoutMs = options.timeoutMs || 1000;
|
||||
var cutoffMs = timeoutMs + new Date().getTime();
|
||||
|
||||
var waitForInternal = function () {
|
||||
if (condition()) {
|
||||
++total;
|
||||
callback();
|
||||
} else {
|
||||
var now = new Date().getTime();
|
||||
if (now < cutoffMs) {
|
||||
window.setTimeout(waitForInternal, poolMs);
|
||||
} else {
|
||||
console.error("Timeout while waiting for ''",
|
||||
condition.toString(), "'");
|
||||
showError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
waitForInternal();
|
||||
}
|
||||
|
||||
exports.timeout = timeout;
|
||||
exports.isTrue = isTrue;
|
||||
exports.equal = equal;
|
||||
exports.jsonEqual = jsonEqual;
|
||||
exports.notEqual = notEqual;
|
||||
exports.strictEqual = strictEqual;
|
||||
exports.typeOf = typeOf;
|
||||
exports.waitFor = waitFor;
|
@ -1,4 +1,4 @@
|
||||
console.log('Hello, world!');
|
||||
//! no-harness
|
||||
console.log(' PASS we are alive');
|
||||
phantom.exit();
|
||||
|
||||
console.log('This should never appear');
|
||||
console.log(' FAIL this should never appear');
|
||||
|
@ -1,21 +0,0 @@
|
||||
var assert = require('../assert');
|
||||
|
||||
assert.typeOf(phantom, 'object');
|
||||
|
||||
assert.isTrue(phantom.hasOwnProperty('libraryPath'));
|
||||
assert.typeOf(phantom.libraryPath, 'string');
|
||||
assert.isTrue(phantom.libraryPath.length > 0);
|
||||
|
||||
assert.isTrue(phantom.hasOwnProperty('outputEncoding'));
|
||||
assert.typeOf(phantom.outputEncoding, 'string');
|
||||
assert.equal(phantom.outputEncoding.toLowerCase(), 'utf-8'); // default
|
||||
|
||||
assert.isTrue(phantom.hasOwnProperty('injectJs'));
|
||||
assert.typeOf(phantom.injectJs, 'function');
|
||||
|
||||
assert.isTrue(phantom.hasOwnProperty('exit'));
|
||||
assert.typeOf(phantom.exit, 'function');
|
||||
|
||||
assert.isTrue(phantom.hasOwnProperty('cookiesEnabled'));
|
||||
assert.typeOf(phantom.cookiesEnabled, 'boolean');
|
||||
assert.isTrue(phantom.cookiesEnabled);
|
39
test/basics/phantom-object.js
Normal file
39
test/basics/phantom-object.js
Normal file
@ -0,0 +1,39 @@
|
||||
test(function () {
|
||||
assert_type_of(phantom, 'object');
|
||||
}, "phantom object");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(phantom, 'libraryPath');
|
||||
assert_type_of(phantom.libraryPath, 'string');
|
||||
assert_greater_than(phantom.libraryPath.length, 0);
|
||||
}, "phantom.libraryPath");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(phantom, 'outputEncoding');
|
||||
assert_type_of(phantom.outputEncoding, 'string');
|
||||
assert_equals(phantom.outputEncoding.toLowerCase(), 'utf-8'); // default
|
||||
}, "phantom.outputEncoding");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(phantom, 'injectJs');
|
||||
assert_type_of(phantom.injectJs, 'function');
|
||||
}, "phantom.injectJs");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(phantom, 'exit');
|
||||
assert_type_of(phantom.exit, 'function');
|
||||
}, "phantom.exit");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(phantom, 'cookiesEnabled');
|
||||
assert_type_of(phantom.cookiesEnabled, 'boolean');
|
||||
assert_is_true(phantom.cookiesEnabled);
|
||||
}, "phantom.cookiesEnabled");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(phantom, 'version');
|
||||
assert_type_of(phantom.version, 'object');
|
||||
assert_type_of(phantom.version.major, 'number');
|
||||
assert_type_of(phantom.version.minor, 'number');
|
||||
assert_type_of(phantom.version.patch, 'number');
|
||||
}, "phantom.version");
|
@ -1,10 +1,13 @@
|
||||
var assert = require('../assert');
|
||||
|
||||
var stack;
|
||||
phantom.onError = function(message, s) { stack = s; };
|
||||
// A SyntaxError leaks to phantom.onError, despite the try-catch.
|
||||
setup({ allow_uncaught_exception: true });
|
||||
|
||||
var helperFile = "../fixtures/parse-error-helper.js";
|
||||
phantom.injectJs(helperFile);
|
||||
|
||||
assert.equal(stack[0].file, helperFile);
|
||||
assert.equal(stack[0].line, 2);
|
||||
test(function () {
|
||||
var helperFile = "../fixtures/parse-error-helper.js";
|
||||
try {
|
||||
phantom.injectJs(helperFile);
|
||||
} catch (e) {
|
||||
assert_equals(e.stack[0].file, helperFile);
|
||||
assert_equals(e.stack[0].line, 2);
|
||||
}
|
||||
}, "stack trace from syntax error in injected file");
|
||||
|
@ -1,28 +1,25 @@
|
||||
/* Test the test server itself. */
|
||||
|
||||
var assert = require('../assert');
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
|
||||
var urlsToTest = [
|
||||
function test_one_page(url) {
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
page.onResourceReceived = this.step_func(function (response) {
|
||||
assert_equals(response.status, 200);
|
||||
});
|
||||
page.onResourceError = this.unreached_func();
|
||||
page.onResourceTimeout = this.unreached_func();
|
||||
page.onLoadFinished = this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
});
|
||||
page.open(url);
|
||||
}, url);
|
||||
}
|
||||
|
||||
[
|
||||
'http://localhost:9180/hello.html',
|
||||
'http://localhost:9180/status?200',
|
||||
'http://localhost:9180/echo'
|
||||
];
|
||||
var i = 0;
|
||||
|
||||
page.onResourceReceived = function (response) {
|
||||
assert.equal(response.status, 200);
|
||||
};
|
||||
|
||||
page.onLoadFinished = function (status) {
|
||||
assert.equal(status, 'success');
|
||||
i++;
|
||||
if (i == urlsToTest.length) {
|
||||
phantom.exit(0);
|
||||
} else {
|
||||
page.open(urlsToTest[i]);
|
||||
}
|
||||
}
|
||||
|
||||
page.open(urlsToTest[i]);
|
||||
]
|
||||
.forEach(test_one_page);
|
||||
|
@ -1,12 +1,7 @@
|
||||
var assert = require('../assert');
|
||||
|
||||
assert.isTrue(phantom.hasOwnProperty('version'));
|
||||
|
||||
assert.typeOf(phantom.version, 'object');
|
||||
assert.typeOf(phantom.version.major, 'number');
|
||||
assert.typeOf(phantom.version.minor, 'number');
|
||||
assert.typeOf(phantom.version.patch, 'number');
|
||||
|
||||
assert.equal(phantom.version.major, 2);
|
||||
assert.equal(phantom.version.minor, 0);
|
||||
assert.equal(phantom.version.patch, 0);
|
||||
// This is separate from basics/phantom-object.js because it has to be
|
||||
// updated with every release.
|
||||
test(function () {
|
||||
assert_equals(phantom.version.major, 2);
|
||||
assert_equals(phantom.version.minor, 0);
|
||||
assert_equals(phantom.version.patch, 0);
|
||||
}, "PhantomJS version number is accurate");
|
||||
|
@ -1,20 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var cookiejar = require('cookiejar');
|
||||
|
||||
var jar = cookiejar.create();
|
||||
assert.equal(jar.cookies.length, 0);
|
||||
|
||||
var cookie = {
|
||||
'name' : 'Valid-Cookie-Name',
|
||||
'value' : 'Valid-Cookie-Value',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/foo',
|
||||
'httponly' : true,
|
||||
'secure' : false
|
||||
};
|
||||
|
||||
jar.addCookie(cookie);
|
||||
assert.equal(jar.cookies.length, 1);
|
||||
|
||||
jar.deleteCookie('Valid-Cookie-Name');
|
||||
assert.equal(jar.cookies.length, 0);
|
92
test/module/cookiejar/cookiejar.js
Normal file
92
test/module/cookiejar/cookiejar.js
Normal file
@ -0,0 +1,92 @@
|
||||
var cookie0 = {
|
||||
'name' : 'Valid-Cookie-Name',
|
||||
'value' : 'Valid-Cookie-Value',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/foo',
|
||||
'httponly' : true,
|
||||
'secure' : false
|
||||
};
|
||||
var cookie1 = {
|
||||
'name' : 'Valid-Cookie-Name-1',
|
||||
'value' : 'Valid-Cookie-Value',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/foo',
|
||||
'httponly' : true,
|
||||
'secure' : false
|
||||
};
|
||||
var cookie2 = {
|
||||
'name' : 'Valid-Cookie-Name-2',
|
||||
'value' : 'Valid-Cookie-Value',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/foo',
|
||||
'httponly' : true,
|
||||
'secure' : false
|
||||
};
|
||||
var cookies = [{
|
||||
'name' : 'Valid-Cookie-Name',
|
||||
'value' : 'Valid-Cookie-Value',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/foo',
|
||||
'httponly' : true,
|
||||
'secure' : false
|
||||
},{
|
||||
'name' : 'Valid-Cookie-Name-Sec',
|
||||
'value' : 'Valid-Cookie-Value-Sec',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/foo',
|
||||
'httponly' : true,
|
||||
'secure' : false,
|
||||
'expires' : new Date().getTime() + 3600 //< expires in 1h
|
||||
}];
|
||||
|
||||
var cookiejar, jar1, jar2;
|
||||
setup(function () {
|
||||
cookiejar = require('cookiejar');
|
||||
jar1 = cookiejar.create();
|
||||
jar2 = cookiejar.create();
|
||||
});
|
||||
|
||||
test(function () {
|
||||
assert_type_of(jar1, 'object');
|
||||
assert_not_equals(jar1, null);
|
||||
assert_type_of(jar1.cookies, 'object');
|
||||
|
||||
assert_type_of(jar1.addCookie, 'function');
|
||||
assert_type_of(jar1.deleteCookie, 'function');
|
||||
assert_type_of(jar1.clearCookies, 'function');
|
||||
}, "cookie jar properties");
|
||||
|
||||
test(function () {
|
||||
assert_equals(jar1.cookies.length, 0);
|
||||
|
||||
jar1.addCookie(cookie0);
|
||||
assert_equals(jar1.cookies.length, 1);
|
||||
|
||||
jar1.deleteCookie('Valid-Cookie-Name');
|
||||
assert_equals(jar1.cookies.length, 0);
|
||||
}, "adding and removing cookies");
|
||||
|
||||
test(function () {
|
||||
assert_equals(jar1.cookies.length, 0);
|
||||
|
||||
jar1.cookies = cookies;
|
||||
assert_equals(jar1.cookies.length, 2);
|
||||
|
||||
jar1.clearCookies();
|
||||
assert_equals(jar1.cookies.length, 0);
|
||||
}, "setting and clearing a cookie jar");
|
||||
|
||||
test(function () {
|
||||
jar1.addCookie(cookie1);
|
||||
assert_equals(jar1.cookies.length, 1);
|
||||
assert_equals(jar2.cookies.length, 0);
|
||||
|
||||
jar2.addCookie(cookie2);
|
||||
jar1.deleteCookie('Valid-Cookie-Name-1');
|
||||
assert_equals(jar1.cookies.length, 0);
|
||||
assert_equals(jar2.cookies.length, 1);
|
||||
|
||||
jar1.close();
|
||||
jar2.close();
|
||||
|
||||
}, "cookie jar isolation");
|
@ -1,8 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var cookiejar = require('cookiejar');
|
||||
|
||||
var jar = cookiejar.create();
|
||||
|
||||
assert.typeOf(jar.addCookie, 'function');
|
||||
assert.typeOf(jar.deleteCookie, 'function');
|
||||
assert.typeOf(jar.clearCookies, 'function');
|
@ -1,35 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var cookiejar = require('cookiejar');
|
||||
|
||||
var jar1 = cookiejar.create();
|
||||
var jar2 = cookiejar.create();
|
||||
|
||||
var cookie1 = {
|
||||
'name' : 'Valid-Cookie-Name-1',
|
||||
'value' : 'Valid-Cookie-Value',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/foo',
|
||||
'httponly' : true,
|
||||
'secure' : false
|
||||
};
|
||||
|
||||
var cookie2 = {
|
||||
'name' : 'Valid-Cookie-Name-2',
|
||||
'value' : 'Valid-Cookie-Value',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/foo',
|
||||
'httponly' : true,
|
||||
'secure' : false
|
||||
};
|
||||
|
||||
jar1.addCookie(cookie1);
|
||||
assert.equal(jar1.cookies.length, 1);
|
||||
assert.equal(jar2.cookies.length, 0);
|
||||
|
||||
jar2.addCookie(cookie2);
|
||||
jar1.deleteCookie('Valid-Cookie-Name-1');
|
||||
assert.equal(jar1.cookies.length, 0);
|
||||
assert.equal(jar2.cookies.length, 1);
|
||||
|
||||
jar1.close();
|
||||
jar2.close();
|
@ -1,8 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var cookiejar = require('cookiejar');
|
||||
|
||||
var jar = cookiejar.create();
|
||||
|
||||
assert.typeOf(jar, 'object');
|
||||
assert.isTrue(jar !== null);
|
||||
assert.typeOf(jar.cookies, 'object');
|
@ -1,28 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var cookiejar = require('cookiejar');
|
||||
|
||||
var jar = cookiejar.create();
|
||||
assert.equal(jar.cookies.length, 0);
|
||||
|
||||
var cookies = [{
|
||||
'name' : 'Valid-Cookie-Name',
|
||||
'value' : 'Valid-Cookie-Value',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/foo',
|
||||
'httponly' : true,
|
||||
'secure' : false
|
||||
},{
|
||||
'name' : 'Valid-Cookie-Name-Sec',
|
||||
'value' : 'Valid-Cookie-Value-Sec',
|
||||
'domain' : 'localhost',
|
||||
'path' : '/foo',
|
||||
'httponly' : true,
|
||||
'secure' : false,
|
||||
'expires' : new Date().getTime() + 3600 //< expires in 1h
|
||||
}];
|
||||
|
||||
jar.cookies = cookies;
|
||||
assert.equal(jar.cookies.length, 2);
|
||||
|
||||
jar.clearCookies();
|
||||
expect(jar.cookies.length).toEqual(0);
|
@ -1,10 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var system = require('system');
|
||||
|
||||
assert.isTrue(system.hasOwnProperty('args'));
|
||||
assert.typeOf(system.args, 'object');
|
||||
assert.isTrue(system.args instanceof Array);
|
||||
assert.isTrue(system.args.length >= 1);
|
||||
|
||||
// args[0] should be this script itself
|
||||
assert.isTrue(system.args[0].match(/args\.js$/));
|
@ -1,15 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var system = require('system');
|
||||
|
||||
assert.isTrue(system.hasOwnProperty('os'));
|
||||
assert.typeOf(system.os, 'object');
|
||||
|
||||
assert.typeOf(system.os.architecture, 'string');
|
||||
assert.typeOf(system.os.name, 'string');
|
||||
assert.typeOf(system.os.version, 'string');
|
||||
|
||||
if (system.os.name === 'mac') {
|
||||
// release is x.y.z with x = 10 for Snow Leopard and 14 for Yosemite
|
||||
assert.typeOf(system.os.release, 'string');
|
||||
assert.isTrue(parseInt(system.os.release, 10) >= 10);
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var system = require('system');
|
||||
|
||||
assert.isTrue(system.hasOwnProperty('pid'));
|
||||
|
||||
// pid must be a positive integer
|
||||
assert.typeOf(system.pid, 'number');
|
||||
assert.isTrue(system.pid > 0);
|
@ -1,8 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var system = require('system');
|
||||
|
||||
assert.typeOf(system.stderr, 'object');
|
||||
assert.typeOf(system.stderr.write, 'function');
|
||||
assert.typeOf(system.stderr.writeLine, 'function');
|
||||
assert.typeOf(system.stderr.flush, 'function');
|
||||
assert.typeOf(system.stderr.close, 'function');
|
@ -1,7 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var system = require('system');
|
||||
|
||||
assert.typeOf(system.stdin, 'object');
|
||||
assert.typeOf(system.stdin.read, 'function');
|
||||
assert.typeOf(system.stdin.readLine, 'function');
|
||||
assert.typeOf(system.stdin.close, 'function');
|
@ -1,8 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var system = require('system');
|
||||
|
||||
assert.typeOf(system.stdout, 'object');
|
||||
assert.typeOf(system.stdout.write, 'function');
|
||||
assert.typeOf(system.stdout.writeLine, 'function');
|
||||
assert.typeOf(system.stdout.flush, 'function');
|
||||
assert.typeOf(system.stdout.close, 'function');
|
@ -1,16 +1,77 @@
|
||||
var assert = require('../../assert');
|
||||
var system = require('system');
|
||||
|
||||
assert.typeOf(system, 'object');
|
||||
assert.isTrue(system !== null);
|
||||
test(function () {
|
||||
assert_type_of(system, 'object');
|
||||
assert_not_equals(system, null);
|
||||
}, "system object");
|
||||
|
||||
assert.isTrue(system.hasOwnProperty('platform'));
|
||||
assert.typeOf(system.platform, 'string');
|
||||
assert.equal(system.platform, 'phantomjs');
|
||||
test(function () {
|
||||
assert_own_property(system, 'pid');
|
||||
assert_type_of(system.pid, 'number');
|
||||
assert_greater_than(system.pid, 0);
|
||||
}, "system.pid");
|
||||
|
||||
assert.isTrue(system.hasOwnProperty('env'));
|
||||
assert.typeOf(system.env, 'object');
|
||||
test(function () {
|
||||
assert_own_property(system, 'isSSLSupported');
|
||||
assert_type_of(system.isSSLSupported, 'boolean');
|
||||
assert_equals(system.isSSLSupported, true);
|
||||
}, "system.isSSLSupported");
|
||||
|
||||
assert.isTrue(system.hasOwnProperty('isSSLSupported'));
|
||||
assert.typeOf(system.isSSLSupported, 'boolean');
|
||||
assert.equal(system.isSSLSupported, true);
|
||||
test(function () {
|
||||
assert_own_property(system, 'args');
|
||||
assert_type_of(system.args, 'object');
|
||||
assert_instance_of(system.args, Array);
|
||||
assert_greater_than_equal(system.args.length, 1);
|
||||
|
||||
// args[0] will be the test harness.
|
||||
assert_regexp_match(system.args[0], /\btestharness\.js$/);
|
||||
}, "system.args");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(system, 'env');
|
||||
assert_type_of(system.env, 'object');
|
||||
}, "system.env");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(system, 'platform');
|
||||
assert_type_of(system.platform, 'string');
|
||||
assert_equals(system.platform, 'phantomjs');
|
||||
}, "system.platform");
|
||||
|
||||
test(function () {
|
||||
assert_own_property(system, 'os');
|
||||
assert_type_of(system.os, 'object');
|
||||
|
||||
assert_type_of(system.os.architecture, 'string');
|
||||
assert_type_of(system.os.name, 'string');
|
||||
assert_type_of(system.os.version, 'string');
|
||||
|
||||
if (system.os.name === 'mac') {
|
||||
// release is x.y.z with x = 10 for Snow Leopard and 14 for Yosemite
|
||||
assert_type_of(system.os.release, 'string');
|
||||
assert_greater_than_equal(parseInt(system.os.release, 10), 10);
|
||||
}
|
||||
}, "system.os");
|
||||
|
||||
test(function () {
|
||||
assert_type_of(system.stdin, 'object');
|
||||
assert_type_of(system.stdin.read, 'function');
|
||||
assert_type_of(system.stdin.readLine, 'function');
|
||||
assert_type_of(system.stdin.close, 'function');
|
||||
}, "system.stdin");
|
||||
|
||||
test(function () {
|
||||
assert_type_of(system.stdout, 'object');
|
||||
assert_type_of(system.stdout.write, 'function');
|
||||
assert_type_of(system.stdout.writeLine, 'function');
|
||||
assert_type_of(system.stdout.flush, 'function');
|
||||
assert_type_of(system.stdout.close, 'function');
|
||||
}, "system.stdout");
|
||||
|
||||
test(function () {
|
||||
assert_type_of(system.stderr, 'object');
|
||||
assert_type_of(system.stderr.write, 'function');
|
||||
assert_type_of(system.stderr.writeLine, 'function');
|
||||
assert_type_of(system.stderr.flush, 'function');
|
||||
assert_type_of(system.stderr.close, 'function');
|
||||
}, "system.stderr");
|
||||
|
@ -1,21 +1,36 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var abortCount = 0;
|
||||
var errorCount = 0;
|
||||
var abortedIds = {};
|
||||
var urlToBlockRegExp = /logo\.png$/i;
|
||||
|
||||
var urlToBlockRexExp = /logo\.png$/i;
|
||||
var abortCount = 0;
|
||||
page.onResourceRequested = this.step_func(function(requestData, request) {
|
||||
assert_type_of(request, 'object');
|
||||
assert_type_of(request.abort, 'function');
|
||||
if (urlToBlockRegExp.test(requestData.url)) {
|
||||
request.abort();
|
||||
++abortCount;
|
||||
abortedIds[requestData.id] = 1;
|
||||
}
|
||||
});
|
||||
page.onResourceError = this.step_func(function(error) {
|
||||
// We can't match up errors to requests by URL because error.url will
|
||||
// be the empty string in this case. FIXME.
|
||||
assert_own_property(abortedIds, error.id);
|
||||
++errorCount;
|
||||
});
|
||||
page.onResourceReceived = this.step_func(function(response) {
|
||||
assert_regexp_not_match(response.url, urlToBlockRegExp);
|
||||
});
|
||||
|
||||
page.onResourceRequested = function(requestData, request) {
|
||||
if (urlToBlockRexExp.test(requestData.url)) {
|
||||
assert.typeOf(request, 'object');
|
||||
assert.typeOf(request.abort, 'function');
|
||||
request.abort();
|
||||
++abortCount;
|
||||
}
|
||||
};
|
||||
page.open('http://localhost:9180/logo.html',
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
assert_equals(abortCount, 1);
|
||||
assert_equals(errorCount, 1);
|
||||
}));
|
||||
|
||||
page.open('http://localhost:9180/logo.html', function (status) {
|
||||
assert.equal(status, 'success');
|
||||
assert.equal(abortCount, 1);
|
||||
});
|
||||
}, "can abort network requests");
|
||||
|
@ -1,23 +1,24 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
async_test(function () {
|
||||
var webpage = require('webpage');
|
||||
|
||||
// NOTE: HTTP header names are case-insensitive. Our test server
|
||||
// returns the name in lowercase.
|
||||
// NOTE: HTTP header names are case-insensitive. Our test server
|
||||
// returns the name in lowercase.
|
||||
|
||||
var page = webpage.create();
|
||||
assert.typeOf(page.customHeaders, 'object');
|
||||
assert.strictEqual(JSON.stringify(page.customHeaders), '{}');
|
||||
var page = webpage.create();
|
||||
assert_type_of(page.customHeaders, 'object');
|
||||
assert_deep_equals(page.customHeaders, {});
|
||||
|
||||
page.onResourceRequested = function(requestData, request) {
|
||||
assert.typeOf(request.setHeader, 'function');
|
||||
request.setHeader('CustomHeader', 'CustomValue');
|
||||
};
|
||||
page.open('http://localhost:9180/echo', function (status) {
|
||||
var json, headers;
|
||||
assert.equal(status, 'success');
|
||||
json = JSON.parse(page.plainText);
|
||||
headers = json.headers;
|
||||
assert.isTrue(headers.hasOwnProperty('customheader'));
|
||||
assert.equal(headers.customheader, 'CustomValue');
|
||||
});
|
||||
page.onResourceRequested = this.step_func(function(requestData, request) {
|
||||
assert_type_of(request.setHeader, 'function');
|
||||
request.setHeader('CustomHeader', 'CustomValue');
|
||||
});
|
||||
page.open('http://localhost:9180/echo', this.step_func_done(function (status) {
|
||||
var json, headers;
|
||||
assert_equals(status, 'success');
|
||||
json = JSON.parse(page.plainText);
|
||||
headers = json.headers;
|
||||
assert_own_property(headers, 'customheader');
|
||||
assert_equals(headers.customheader, 'CustomValue');
|
||||
}));
|
||||
|
||||
}, "add custom headers in onResourceRequested");
|
||||
|
@ -1,15 +1,16 @@
|
||||
var assert = require('../../assert');
|
||||
var page = require('webpage').create();
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
var msgA = "a",
|
||||
msgB = "b",
|
||||
result,
|
||||
expected = msgA + msgB;
|
||||
page.onCallback = function(a, b) {
|
||||
return a + b;
|
||||
};
|
||||
result = page.evaluate(function(a, b) {
|
||||
return callPhantom(a, b);
|
||||
}, msgA, msgB);
|
||||
var msgA = "a",
|
||||
msgB = "b",
|
||||
result,
|
||||
expected = msgA + msgB;
|
||||
page.onCallback = function(a, b) {
|
||||
return a + b;
|
||||
};
|
||||
result = page.evaluate(function(a, b) {
|
||||
return window.callPhantom(a, b);
|
||||
}, msgA, msgB);
|
||||
|
||||
assert.equal(result, expected);
|
||||
assert_equals(result, expected);
|
||||
}, "page.onCallback");
|
||||
|
@ -1,22 +1,26 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
|
||||
var url = "http://localhost:9180/cdn-cgi/pe/bag?r%5B%5D=http%3A%2F%2Fwww.example.org%2Fcdn-cgi%2Fnexp%2Fabv%3D927102467%2Fapps%2Fabetterbrowser.js";
|
||||
var receivedUrl;
|
||||
var url = "http://localhost:9180/cdn-cgi/pe/bag?r%5B%5D="+
|
||||
"http%3A%2F%2Fwww.example.org%2Fcdn-cgi%2Fnexp%2F"+
|
||||
"abv%3D927102467%2Fapps%2Fabetterbrowser.js";
|
||||
var receivedUrl;
|
||||
|
||||
page.onResourceRequested = function(requestData, request) {
|
||||
request.changeUrl(requestData.url);
|
||||
};
|
||||
page.onResourceRequested = this.step_func(function(requestData, request) {
|
||||
request.changeUrl(requestData.url);
|
||||
});
|
||||
|
||||
page.onResourceReceived = function(data) {
|
||||
if (data.stage === 'end') {
|
||||
receivedUrl = data.url;
|
||||
}
|
||||
};
|
||||
page.onResourceReceived = this.step_func(function(data) {
|
||||
if (data.stage === 'end') {
|
||||
receivedUrl = data.url;
|
||||
}
|
||||
});
|
||||
|
||||
page.open(url, function (status) {
|
||||
assert.equal(status, 'success');
|
||||
assert.equal(receivedUrl, url);
|
||||
});
|
||||
page.open(url, this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
assert_equals(receivedUrl, url);
|
||||
}));
|
||||
|
||||
}, "encoded URLs properly round-trip through request.changeUrl");
|
||||
|
@ -1,33 +1,39 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
async_test(function () {
|
||||
|
||||
var urlToChange = 'http://localhost:9180/logo.png';
|
||||
var alternativeUrl = 'http://localhost:9180/phantomjs-logo.gif';
|
||||
var startStage = 0;
|
||||
var endStage = 0;
|
||||
var page = webpage.create();
|
||||
var urlToChange = 'http://localhost:9180/logo.png';
|
||||
var alternativeUrl = 'http://localhost:9180/phantomjs-logo.gif';
|
||||
var startStage = 0;
|
||||
var endStage = 0;
|
||||
|
||||
page.onResourceRequested = function(requestData, request) {
|
||||
if (requestData.url === urlToChange) {
|
||||
assert.typeOf(request, 'object');
|
||||
assert.typeOf(request.changeUrl, 'function');
|
||||
request.changeUrl(alternativeUrl);
|
||||
}
|
||||
};
|
||||
page.onResourceRequested = this.step_func(function(requestData, request) {
|
||||
if (requestData.url === urlToChange) {
|
||||
assert_type_of(request, 'object');
|
||||
assert_type_of(request.changeUrl, 'function');
|
||||
request.changeUrl(alternativeUrl);
|
||||
}
|
||||
});
|
||||
|
||||
page.onResourceReceived = function(data) {
|
||||
if (data.url === alternativeUrl && data.stage === 'start') {
|
||||
++startStage;
|
||||
}
|
||||
if (data.url === alternativeUrl && data.stage === 'end') {
|
||||
++endStage;
|
||||
}
|
||||
};
|
||||
page.onResourceReceived = this.step_func(function(data) {
|
||||
if (data.url === alternativeUrl && data.stage === 'start') {
|
||||
++startStage;
|
||||
}
|
||||
if (data.url === alternativeUrl && data.stage === 'end') {
|
||||
++endStage;
|
||||
}
|
||||
});
|
||||
|
||||
page.open('http://localhost:9180/logo.html', function (status) {
|
||||
assert.equal(status, 'success');
|
||||
assert.equal(startStage, 1);
|
||||
assert.equal(endStage, 1);
|
||||
assert.equal(page.content.match('logo.png'), 'logo.png');
|
||||
});
|
||||
page.open('http://localhost:9180/logo.html',
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
assert_equals(startStage, 1);
|
||||
assert_equals(endStage, 1);
|
||||
|
||||
// The page HTML should still refer to the original image.
|
||||
assert_regexp_match(page.content, /logo\.png/);
|
||||
assert_regexp_not_match(page.content, /logo\.gif/);
|
||||
}));
|
||||
|
||||
}, "request.changeUrl");
|
||||
|
@ -1,30 +1,33 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
function test_one(text) {
|
||||
var t = async_test(text.codec);
|
||||
t.step(function () {
|
||||
var page = webpage.create();
|
||||
page.open(text.url, t.step_func_done(function () {
|
||||
var decodedText = page.evaluate(function() {
|
||||
return document.querySelector('pre').innerText;
|
||||
});
|
||||
var regex = '^' + text.reference + '$';
|
||||
assert_regexp_match(text.reference, new RegExp(regex));
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
function Text(codec, base64, reference) {
|
||||
this.codec = codec;
|
||||
this.base64 = base64;
|
||||
this.reference = reference;
|
||||
this.url = 'data:text/plain;charset=' + this.codec + ';base64,' + this.base64;
|
||||
this.url = 'data:text/plain;charset=' + this.codec +
|
||||
';base64,' + this.base64;
|
||||
}
|
||||
|
||||
var texts = [
|
||||
[
|
||||
new Text('Shift_JIS', 'g3SDQIOTg2eDgA==', 'ファントム'),
|
||||
new Text('EUC-JP', 'pdWloaXzpcil4A0K', 'ファントム'),
|
||||
new Text('ISO-2022-JP', 'GyRCJVUlISVzJUglYBsoQg0K', 'ファントム'),
|
||||
new Text('Big5', 'pNu2SA0K', '幻象'),
|
||||
new Text('GBK', 'u8PP8w0K', '幻象'),
|
||||
new Text('EUC-KR', 'yK+/tQ==', '환영'),
|
||||
];
|
||||
|
||||
texts.forEach(function (text) {
|
||||
var page = webpage.create();
|
||||
page.open(text.url, function() {
|
||||
var decodedText = page.evaluate(function() {
|
||||
return document.querySelector('pre').innerText;
|
||||
});
|
||||
var regex = '^' + text.reference;
|
||||
assert.equal(decodedText.match(regex), text.reference);
|
||||
});
|
||||
});
|
||||
|
||||
]
|
||||
.forEach(test_one);
|
||||
|
@ -1,16 +1,19 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
var defaultPage = webpage.create();
|
||||
assert.jsonEqual(defaultPage.clipRect, {height:0,left:0,top:0,width:0});
|
||||
test(function () {
|
||||
var defaultPage = webpage.create();
|
||||
assert_deep_equals(defaultPage.clipRect, {height:0,left:0,top:0,width:0});
|
||||
}, "default page.clipRect");
|
||||
|
||||
var options = {
|
||||
clipRect: {
|
||||
height: 100,
|
||||
left: 10,
|
||||
top: 20,
|
||||
width: 200
|
||||
}
|
||||
};
|
||||
var customPage = new WebPage(options);
|
||||
assert.jsonEqual(customPage.clipRect, options.clipRect);
|
||||
test(function () {
|
||||
var options = {
|
||||
clipRect: {
|
||||
height: 100,
|
||||
left: 10,
|
||||
top: 20,
|
||||
width: 200
|
||||
}
|
||||
};
|
||||
var customPage = webpage.create(options);
|
||||
assert_deep_equals(customPage.clipRect, options.clipRect);
|
||||
}, "custom page.clipRect");
|
||||
|
@ -1,30 +1,30 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
async_test(function () {
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
assert_type_of(page.customHeaders, 'object');
|
||||
assert_deep_equals(page.customHeaders, {});
|
||||
|
||||
var page = webpage.create();
|
||||
assert.typeOf(page.customHeaders, 'object');
|
||||
assert.strictEqual(JSON.stringify(page.customHeaders), '{}');
|
||||
// NOTE: HTTP header names are case-insensitive. Our test server
|
||||
// returns the name in lowercase.
|
||||
page.customHeaders = {
|
||||
'Custom-Key': 'Custom-Value',
|
||||
'User-Agent': 'Overriden-UA',
|
||||
'Referer': 'Overriden-Referer'
|
||||
};
|
||||
page.open('http://localhost:9180/echo', this.step_func_done(function (status) {
|
||||
var json, headers;
|
||||
assert_equals(status, 'success');
|
||||
json = JSON.parse(page.plainText);
|
||||
assert_type_of(json, 'object');
|
||||
headers = json.headers;
|
||||
assert_type_of(headers, 'object');
|
||||
|
||||
// NOTE: HTTP header names are case-insensitive. Our test server
|
||||
// returns the name in lowercase.
|
||||
assert_own_property(headers, 'custom-key');
|
||||
assert_own_property(headers, 'user-agent');
|
||||
assert_own_property(headers, 'referer');
|
||||
assert_equals(headers['custom-key'], 'Custom-Value');
|
||||
assert_equals(headers['user-agent'], 'Overriden-UA');
|
||||
assert_equals(headers['referer'], 'Overriden-Referer');
|
||||
}));
|
||||
|
||||
page.customHeaders = {
|
||||
'Custom-Key': 'Custom-Value',
|
||||
'User-Agent': 'Overriden-UA',
|
||||
'Referer': 'Overriden-Referer'
|
||||
};
|
||||
page.open('http://localhost:9180/echo', function (status) {
|
||||
var json, headers;
|
||||
assert.equal(status, 'success');
|
||||
json = JSON.parse(page.plainText);
|
||||
assert.typeOf(json, 'object');
|
||||
headers = json.headers;
|
||||
assert.typeOf(headers, 'object');
|
||||
|
||||
assert.isTrue(headers.hasOwnProperty('custom-key'));
|
||||
assert.isTrue(headers.hasOwnProperty('user-agent'));
|
||||
assert.isTrue(headers.hasOwnProperty('referer'));
|
||||
assert.equal(headers['custom-key'], 'Custom-Value');
|
||||
assert.equal(headers['user-agent'], 'Overriden-UA');
|
||||
assert.equal(headers['referer'], 'Overriden-Referer');
|
||||
});
|
||||
}, "adding custom headers with page.customHeaders");
|
||||
|
@ -1,13 +1,14 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
test(function () {
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
|
||||
var page = webpage.create();
|
||||
// Hijack JSON.parse to something completely useless.
|
||||
page.content = '<html><script>JSON.parse = function() {}</script></html>';
|
||||
|
||||
// Hijack JSON.parse to something completely useless.
|
||||
page.content = '<html><script>JSON.parse = function() {}</script></html>';
|
||||
var result = page.evaluate(function(obj) {
|
||||
return obj.value * obj.value;
|
||||
}, { value: 4 });
|
||||
|
||||
var result = page.evaluate(function(obj) {
|
||||
return obj.value * obj.value;
|
||||
}, { value: 4 });
|
||||
assert_equals(result, 16);
|
||||
|
||||
assert.equal(result, 16);
|
||||
}, "page script should not interfere with page.evaluate");
|
||||
|
@ -1,34 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
|
||||
assert.typeOf(page.childFramesCount, 'function');
|
||||
assert.typeOf(page.childFramesName, 'function');
|
||||
assert.typeOf(page.clearMemoryCache, 'function');
|
||||
assert.typeOf(page.close, 'function');
|
||||
assert.typeOf(page.currentFrameName, 'function');
|
||||
assert.typeOf(page.deleteLater, 'function');
|
||||
assert.typeOf(page.destroyed, 'function');
|
||||
assert.typeOf(page.evaluate, 'function');
|
||||
assert.typeOf(page.initialized, 'function');
|
||||
assert.typeOf(page.injectJs, 'function');
|
||||
assert.typeOf(page.javaScriptAlertSent, 'function');
|
||||
assert.typeOf(page.javaScriptConsoleMessageSent, 'function');
|
||||
assert.typeOf(page.loadFinished, 'function');
|
||||
assert.typeOf(page.loadStarted, 'function');
|
||||
assert.typeOf(page.openUrl, 'function');
|
||||
assert.typeOf(page.release, 'function');
|
||||
assert.typeOf(page.render, 'function');
|
||||
assert.typeOf(page.resourceError, 'function');
|
||||
assert.typeOf(page.resourceReceived, 'function');
|
||||
assert.typeOf(page.resourceRequested, 'function');
|
||||
assert.typeOf(page.uploadFile, 'function');
|
||||
assert.typeOf(page.sendEvent, 'function');
|
||||
assert.typeOf(page.setContent, 'function');
|
||||
assert.typeOf(page.switchToChildFrame, 'function');
|
||||
assert.typeOf(page.switchToMainFrame, 'function');
|
||||
assert.typeOf(page.switchToParentFrame, 'function');
|
||||
|
||||
assert.typeOf(page.addCookie, 'function');
|
||||
assert.typeOf(page.deleteCookie, 'function');
|
||||
assert.typeOf(page.clearCookies, 'function');
|
@ -1,19 +1,20 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
test(function () {
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
var page = webpage.create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('keydown', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('keydown', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
|
||||
page.sendEvent('keydown', page.event.key.A);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
page.sendEvent('keydown', page.event.key.A);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
|
||||
assert.equal(loggedEvent.length, 1);
|
||||
assert.equal(loggedEvent[0].which, page.event.key.A);
|
||||
assert_equals(loggedEvent.length, 1);
|
||||
assert_equals(loggedEvent[0].which, page.event.key.A);
|
||||
}, "key-down events");
|
||||
|
@ -1,64 +1,65 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
test(function () {
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
var page = webpage.create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('keypress', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
|
||||
page.sendEvent('keypress', page.event.key.C);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
|
||||
assert.equal(loggedEvent.length, 1);
|
||||
assert.equal(loggedEvent[0].which, page.event.key.C);
|
||||
|
||||
|
||||
// Send keypress events to an input element and observe the effect.
|
||||
|
||||
page.content = '<input type="text">';
|
||||
page.evaluate(function() {
|
||||
document.querySelector('input').focus();
|
||||
});
|
||||
|
||||
function getText() {
|
||||
return page.evaluate(function() {
|
||||
return document.querySelector('input').value;
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('keypress', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
}
|
||||
|
||||
page.sendEvent('keypress', page.event.key.A);
|
||||
assert.equal(getText(), 'A');
|
||||
page.sendEvent('keypress', page.event.key.B);
|
||||
assert.equal(getText(), 'AB');
|
||||
page.sendEvent('keypress', page.event.key.Backspace);
|
||||
assert.equal(getText(), 'A');
|
||||
page.sendEvent('keypress', page.event.key.Backspace);
|
||||
assert.equal(getText(), '');
|
||||
page.sendEvent('keypress', page.event.key.C);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
|
||||
page.sendEvent('keypress', 'XYZ');
|
||||
assert.equal(getText(), 'XYZ');
|
||||
assert_equals(loggedEvent.length, 1);
|
||||
assert_equals(loggedEvent[0].which, page.event.key.C);
|
||||
|
||||
// Special character: A with umlaut
|
||||
page.sendEvent('keypress', 'ä');
|
||||
assert.equal(getText(), 'XYZä');
|
||||
|
||||
// 0x02000000 is the Shift modifier.
|
||||
page.sendEvent('keypress', page.event.key.Home, null, null, 0x02000000);
|
||||
page.sendEvent('keypress', page.event.key.Delete);
|
||||
assert.equal(getText(), '');
|
||||
// Send keypress events to an input element and observe the effect.
|
||||
|
||||
// Cut and Paste
|
||||
// 0x04000000 is the Control modifier.
|
||||
page.sendEvent('keypress', 'ABCD');
|
||||
assert.equal(getText(), 'ABCD');
|
||||
page.sendEvent('keypress', page.event.key.Home, null, null, 0x02000000);
|
||||
page.sendEvent('keypress', 'x', null, null, 0x04000000);
|
||||
assert.equal(getText(), '');
|
||||
page.sendEvent('keypress', 'v', null, null, 0x04000000);
|
||||
assert.equal(getText(), 'ABCD');
|
||||
page.content = '<input type="text">';
|
||||
page.evaluate(function() {
|
||||
document.querySelector('input').focus();
|
||||
});
|
||||
|
||||
function getText() {
|
||||
return page.evaluate(function() {
|
||||
return document.querySelector('input').value;
|
||||
});
|
||||
}
|
||||
|
||||
page.sendEvent('keypress', page.event.key.A);
|
||||
assert_equals(getText(), 'A');
|
||||
page.sendEvent('keypress', page.event.key.B);
|
||||
assert_equals(getText(), 'AB');
|
||||
page.sendEvent('keypress', page.event.key.Backspace);
|
||||
assert_equals(getText(), 'A');
|
||||
page.sendEvent('keypress', page.event.key.Backspace);
|
||||
assert_equals(getText(), '');
|
||||
|
||||
page.sendEvent('keypress', 'XYZ');
|
||||
assert_equals(getText(), 'XYZ');
|
||||
|
||||
// Special character: A with umlaut
|
||||
page.sendEvent('keypress', 'ä');
|
||||
assert_equals(getText(), 'XYZä');
|
||||
|
||||
// 0x02000000 is the Shift modifier.
|
||||
page.sendEvent('keypress', page.event.key.Home, null, null, 0x02000000);
|
||||
page.sendEvent('keypress', page.event.key.Delete);
|
||||
assert_equals(getText(), '');
|
||||
|
||||
// Cut and Paste
|
||||
// 0x04000000 is the Control modifier.
|
||||
page.sendEvent('keypress', 'ABCD');
|
||||
assert_equals(getText(), 'ABCD');
|
||||
page.sendEvent('keypress', page.event.key.Home, null, null, 0x02000000);
|
||||
page.sendEvent('keypress', 'x', null, null, 0x04000000);
|
||||
assert_equals(getText(), '');
|
||||
page.sendEvent('keypress', 'v', null, null, 0x04000000);
|
||||
assert_equals(getText(), 'ABCD');
|
||||
}, "key press events");
|
||||
|
@ -1,19 +1,20 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
test(function () {
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
var page = webpage.create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('keyup', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('keyup', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
|
||||
page.sendEvent('keyup', page.event.key.B);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
page.sendEvent('keyup', page.event.key.B);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
|
||||
assert.equal(loggedEvent.length, 1);
|
||||
assert.equal(loggedEvent[0].which, page.event.key.B);
|
||||
assert_equals(loggedEvent.length, 1);
|
||||
assert_equals(loggedEvent[0].which, page.event.key.B);
|
||||
}, "key-up events");
|
||||
|
@ -1,23 +1,20 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
async_test(function () {
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
|
||||
var page = webpage.create();
|
||||
assert.typeOf(page, 'object');
|
||||
assert.typeOf(page.loading, 'boolean');
|
||||
assert.typeOf(page.loadingProgress, 'number');
|
||||
assert_type_of(page, 'object');
|
||||
assert_type_of(page.loading, 'boolean');
|
||||
assert_type_of(page.loadingProgress, 'number');
|
||||
|
||||
assert.equal(page.loading, false);
|
||||
assert.equal(page.loadingProgress, 0);
|
||||
page.open('http://localhost:9180/hello.html');
|
||||
assert.isTrue(page.loading);
|
||||
assert.isTrue(page.loadingProgress > 0);
|
||||
assert_is_false(page.loading);
|
||||
assert_equals(page.loadingProgress, 0);
|
||||
|
||||
// Another page
|
||||
page = webpage.create();
|
||||
assert.equal(page.loading, false);
|
||||
assert.equal(page.loadingProgress, 0);
|
||||
page.open('http://localhost:9180/hello.html', function (status) {
|
||||
assert.equal(status, 'success');
|
||||
assert.equal(page.loading, false);
|
||||
assert.equal(page.loadingProgress, 100);
|
||||
});
|
||||
page.open('http://localhost:9180/hello.html', this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
assert_equals(page.loading, false);
|
||||
assert_equals(page.loadingProgress, 100);
|
||||
}));
|
||||
|
||||
assert_is_true(page.loading);
|
||||
assert_greater_than(page.loadingProgress, 0);
|
||||
}, "page loading progress");
|
||||
|
@ -1,18 +1,22 @@
|
||||
//! phantomjs: --web-security=no --local-url-access=no
|
||||
|
||||
var assert = require("../../assert");
|
||||
var p = require("webpage").create();
|
||||
var webpage = require("webpage");
|
||||
|
||||
var url = "http://localhost:9180/iframe.html#file:///nonexistent";
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var url = "http://localhost:9180/iframe.html#file:///nonexistent";
|
||||
var rsErrorCalled = false;
|
||||
|
||||
var rsErrorCalled = false;
|
||||
p.onResourceError = function (error) {
|
||||
rsErrorCalled = true;
|
||||
assert.strictEqual(error.url, "file:///nonexistent");
|
||||
assert.strictEqual(error.errorCode, 301);
|
||||
assert.strictEqual(error.errorString, 'Protocol "file" is unknown');
|
||||
};
|
||||
page.onResourceError = this.step_func(function (error) {
|
||||
rsErrorCalled = true;
|
||||
assert_equals(error.url, "file:///nonexistent");
|
||||
assert_equals(error.errorCode, 301);
|
||||
assert_equals(error.errorString, 'Protocol "file" is unknown');
|
||||
});
|
||||
|
||||
p.open(url, function () {
|
||||
assert.isTrue(rsErrorCalled);
|
||||
});
|
||||
page.open(url, this.step_func_done(function () {
|
||||
assert_is_true(rsErrorCalled);
|
||||
}));
|
||||
|
||||
},
|
||||
"doesn't attempt to load a file: URL in an iframe with --local-url-access=no");
|
||||
|
@ -1,18 +1,21 @@
|
||||
//! phantomjs: --local-url-access=no
|
||||
|
||||
var assert = require("../../assert");
|
||||
var p = require("webpage").create();
|
||||
var webpage = require("webpage");
|
||||
|
||||
var url = "file:///nonexistent";
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var url = "file:///nonexistent";
|
||||
var rsErrorCalled = false;
|
||||
|
||||
var rsErrorCalled = false;
|
||||
p.onResourceError = function (error) {
|
||||
rsErrorCalled = true;
|
||||
assert.strictEqual(error.url, url);
|
||||
assert.strictEqual(error.errorCode, 301);
|
||||
assert.strictEqual(error.errorString, 'Protocol "file" is unknown');
|
||||
};
|
||||
page.onResourceError = this.step_func(function (error) {
|
||||
rsErrorCalled = true;
|
||||
assert_equals(error.url, url);
|
||||
assert_equals(error.errorCode, 301);
|
||||
assert_equals(error.errorString, 'Protocol "file" is unknown');
|
||||
});
|
||||
|
||||
p.open(url, function () {
|
||||
assert.isTrue(rsErrorCalled);
|
||||
});
|
||||
page.open(url, this.step_func_done(function () {
|
||||
assert_is_true(rsErrorCalled);
|
||||
}));
|
||||
|
||||
}, "doesn't attempt to load a file: URL with --local-url-access=no");
|
||||
|
@ -1,19 +1,22 @@
|
||||
//! phantomjs: --web-security=no --local-url-access=yes
|
||||
|
||||
var assert = require("../../assert");
|
||||
var p = require("webpage").create();
|
||||
var webpage = require("webpage");
|
||||
|
||||
var url = "http://localhost:9180/iframe.html#file:///nonexistent";
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var url = "http://localhost:9180/iframe.html#file:///nonexistent";
|
||||
var rsErrorCalled = false;
|
||||
|
||||
var rsErrorCalled = false;
|
||||
p.onResourceError = function (error) {
|
||||
rsErrorCalled = true;
|
||||
assert.strictEqual(error.url, "file:///nonexistent");
|
||||
assert.strictEqual(error.errorCode, 203);
|
||||
assert.strictEqual(/^Error opening\b.*?\bnonexistent:/.test(error.errorString),
|
||||
true);
|
||||
};
|
||||
page.onResourceError = this.step_func(function (error) {
|
||||
rsErrorCalled = true;
|
||||
assert_equals(error.url, "file:///nonexistent");
|
||||
assert_equals(error.errorCode, 203);
|
||||
assert_regexp_match(error.errorString,
|
||||
/^Error opening\b.*?\bnonexistent:/);
|
||||
});
|
||||
|
||||
p.open(url, function () {
|
||||
assert.isTrue(rsErrorCalled);
|
||||
});
|
||||
page.open(url, this.step_func_done(function () {
|
||||
assert_is_true(rsErrorCalled);
|
||||
}));
|
||||
|
||||
}, "attempts to load a file: URL in an iframe with --local-url-access=yes");
|
||||
|
@ -1,19 +1,22 @@
|
||||
//! phantomjs: --local-url-access=yes
|
||||
|
||||
var assert = require("../../assert");
|
||||
var p = require("webpage").create();
|
||||
var webpage = require("webpage");
|
||||
|
||||
var url = "file:///nonexistent";
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var url = "file:///nonexistent";
|
||||
var rsErrorCalled = false;
|
||||
|
||||
var rsErrorCalled = false;
|
||||
p.onResourceError = function (error) {
|
||||
rsErrorCalled = true;
|
||||
assert.strictEqual(error.url, url);
|
||||
assert.strictEqual(error.errorCode, 203);
|
||||
assert.strictEqual(/^Error opening\b.*?\bnonexistent:/.test(error.errorString),
|
||||
true);
|
||||
};
|
||||
page.onResourceError = this.step_func(function (error) {
|
||||
rsErrorCalled = true;
|
||||
assert_equals(error.url, url);
|
||||
assert_equals(error.errorCode, 203);
|
||||
assert_regexp_match(error.errorString,
|
||||
/^Error opening\b.*?\bnonexistent:/);
|
||||
});
|
||||
|
||||
p.open(url, function () {
|
||||
assert.isTrue(rsErrorCalled);
|
||||
});
|
||||
page.open(url, this.step_func_done(function () {
|
||||
assert_is_true(rsErrorCalled);
|
||||
}));
|
||||
|
||||
}, "attempts to load a file: URL with --local-url-access=yes");
|
||||
|
@ -1,25 +1,27 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
async_test(function () {
|
||||
var webpage = require('webpage');
|
||||
|
||||
// NOTE: HTTP header names are case-insensitive. Our test server
|
||||
// returns the name in lowercase.
|
||||
// NOTE: HTTP header names are case-insensitive. Our test server
|
||||
// returns the name in lowercase.
|
||||
|
||||
var page = webpage.create();
|
||||
assert.typeOf(page.customHeaders, 'object');
|
||||
assert.strictEqual(JSON.stringify(page.customHeaders), '{}');
|
||||
var page = webpage.create();
|
||||
assert_type_of(page.customHeaders, 'object');
|
||||
assert_deep_equals(page.customHeaders, {});
|
||||
|
||||
page.customHeaders = { 'CustomHeader': 'ModifiedCustomValue' };
|
||||
page.customHeaders = { 'CustomHeader': 'CustomValue' };
|
||||
|
||||
page.onResourceRequested = function(requestData, request) {
|
||||
assert.typeOf(request.setHeader, 'function');
|
||||
request.setHeader('CustomHeader', 'ModifiedCustomValue');
|
||||
};
|
||||
page.open('http://localhost:9180/echo', function (status) {
|
||||
var json, headers;
|
||||
assert.equal(status, 'success');
|
||||
json = JSON.parse(page.plainText);
|
||||
headers = json.headers;
|
||||
assert.isTrue(headers.hasOwnProperty('customheader'));
|
||||
assert.equal(headers.customheader, 'ModifiedCustomValue');
|
||||
});
|
||||
page.onResourceRequested = this.step_func(function(requestData, request) {
|
||||
assert_type_of(request.setHeader, 'function');
|
||||
request.setHeader('CustomHeader', 'ModifiedCustomValue');
|
||||
});
|
||||
|
||||
page.open('http://localhost:9180/echo', this.step_func_done(function (status) {
|
||||
var json, headers;
|
||||
assert_equals(status, 'success');
|
||||
json = JSON.parse(page.plainText);
|
||||
headers = json.headers;
|
||||
assert_own_property(headers, 'customheader');
|
||||
assert_equals(headers.customheader, 'ModifiedCustomValue');
|
||||
}));
|
||||
|
||||
}, "modifying HTTP headers");
|
||||
|
@ -1,36 +1,38 @@
|
||||
var assert = require('../../assert');
|
||||
var page = require('webpage').create();
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('mousedown', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.mousedown = event;
|
||||
}, false);
|
||||
window.addEventListener('mouseup', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.mouseup = event;
|
||||
}, false);
|
||||
});
|
||||
page.sendEvent('click', 42, 217);
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('mousedown', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.mousedown = event;
|
||||
}, false);
|
||||
window.addEventListener('mouseup', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.mouseup = event;
|
||||
}, false);
|
||||
});
|
||||
page.sendEvent('click', 42, 217);
|
||||
|
||||
var event = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert.equal(event.mouseup.clientX, 42);
|
||||
assert.equal(event.mouseup.clientY, 217);
|
||||
assert.equal(event.mousedown.clientX, 42);
|
||||
assert.equal(event.mousedown.clientY, 217);
|
||||
var event = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(event.mouseup.clientX, 42);
|
||||
assert_equals(event.mouseup.clientY, 217);
|
||||
assert_equals(event.mousedown.clientX, 42);
|
||||
assert_equals(event.mousedown.clientY, 217);
|
||||
|
||||
// click with modifier key
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('click', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.click = event;
|
||||
}, false);
|
||||
});
|
||||
page.sendEvent('click', 100, 100, 'left', page.event.modifier.shift);
|
||||
// click with modifier key
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('click', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.click = event;
|
||||
}, false);
|
||||
});
|
||||
page.sendEvent('click', 100, 100, 'left', page.event.modifier.shift);
|
||||
|
||||
var event = page.evaluate(function() {
|
||||
return window.loggedEvent.click;
|
||||
});
|
||||
assert.isTrue(event.shiftKey);
|
||||
var event = page.evaluate(function() {
|
||||
return window.loggedEvent.click;
|
||||
});
|
||||
assert_is_true(event.shiftKey);
|
||||
|
||||
}, "mouse click events");
|
||||
|
@ -1,29 +1,30 @@
|
||||
var assert = require('../../assert');
|
||||
var page = require('webpage').create();
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
page.content = '<input id="doubleClickField" type="text" onclick="document.getElementById(\'doubleClickField\').value=\'clicked\';" ondblclick="document.getElementById(\'doubleClickField\').value=\'doubleclicked\';" oncontextmenu="document.getElementById(\'doubleClickField\').value=\'rightclicked\'; return false;" value="hello"/>';
|
||||
var point = page.evaluate(function () {
|
||||
var el = document.querySelector('input');
|
||||
var rect = el.getBoundingClientRect();
|
||||
return { x: rect.left + Math.floor(rect.width / 2), y: rect.top + (rect.height / 2) };
|
||||
});
|
||||
page.sendEvent('doubleclick', point.x, point.y);
|
||||
page.content = '<input id="doubleClickField" type="text" onclick="document.getElementById(\'doubleClickField\').value=\'clicked\';" ondblclick="document.getElementById(\'doubleClickField\').value=\'doubleclicked\';" oncontextmenu="document.getElementById(\'doubleClickField\').value=\'rightclicked\'; return false;" value="hello"/>';
|
||||
var point = page.evaluate(function () {
|
||||
var el = document.querySelector('input');
|
||||
var rect = el.getBoundingClientRect();
|
||||
return { x: rect.left + Math.floor(rect.width / 2), y: rect.top + (rect.height / 2) };
|
||||
});
|
||||
page.sendEvent('doubleclick', point.x, point.y);
|
||||
|
||||
var text = page.evaluate(function () {
|
||||
return document.querySelector('input').value;
|
||||
});
|
||||
assert.equal(text, "doubleclicked");
|
||||
var text = page.evaluate(function () {
|
||||
return document.querySelector('input').value;
|
||||
});
|
||||
assert_equals(text, "doubleclicked");
|
||||
|
||||
// click with modifier key
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('dblclick', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.dblclick = event;
|
||||
}, false);
|
||||
});
|
||||
page.sendEvent('doubleclick', 100, 100, 'left', page.event.modifier.shift);
|
||||
// click with modifier key
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('dblclick', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || {};
|
||||
window.loggedEvent.dblclick = event;
|
||||
}, false);
|
||||
});
|
||||
page.sendEvent('doubleclick', 100, 100, 'left', page.event.modifier.shift);
|
||||
|
||||
var event = page.evaluate(function() {
|
||||
return window.loggedEvent.dblclick;
|
||||
});
|
||||
assert.isTrue(event.shiftKey);
|
||||
var event = page.evaluate(function() {
|
||||
return window.loggedEvent.dblclick;
|
||||
});
|
||||
assert_is_true(event.shiftKey);
|
||||
}, "mouse double-click events");
|
||||
|
@ -1,24 +1,26 @@
|
||||
var assert = require('../../assert');
|
||||
var page = require('webpage').create();
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('mousedown', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('mousedown', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
|
||||
page.sendEvent('mousedown', 42, 217);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert.equal(loggedEvent.length, 1);
|
||||
assert.equal(loggedEvent[0].clientX, 42);
|
||||
assert.equal(loggedEvent[0].clientY, 217);
|
||||
page.sendEvent('mousedown', 42, 217);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(loggedEvent.length, 1);
|
||||
assert_equals(loggedEvent[0].clientX, 42);
|
||||
assert_equals(loggedEvent[0].clientY, 217);
|
||||
|
||||
page.sendEvent('mousedown', 100, 100, 'left', page.event.modifier.shift);
|
||||
loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert.equal(loggedEvent.length, 2);
|
||||
assert.isTrue(loggedEvent[1].shiftKey);
|
||||
page.sendEvent('mousedown', 100, 100, 'left', page.event.modifier.shift);
|
||||
loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(loggedEvent.length, 2);
|
||||
assert_is_true(loggedEvent[1].shiftKey);
|
||||
|
||||
}, "mouse-down events");
|
||||
|
@ -1,17 +1,18 @@
|
||||
var assert = require('../../assert');
|
||||
var page = require('webpage').create();
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('mousemove', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('mousemove', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
|
||||
page.sendEvent('mousemove', 14, 3);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert.equal(loggedEvent.length, 1);
|
||||
assert.equal(loggedEvent[0].clientX, 14);
|
||||
assert.equal(loggedEvent[0].clientY, 3);
|
||||
page.sendEvent('mousemove', 14, 3);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(loggedEvent.length, 1);
|
||||
assert_equals(loggedEvent[0].clientX, 14);
|
||||
assert_equals(loggedEvent[0].clientY, 3);
|
||||
}, "mouse-move events");
|
||||
|
@ -1,26 +1,26 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
test(function () {
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
|
||||
var page = webpage.create();
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('mouseup', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
|
||||
page.evaluate(function() {
|
||||
window.addEventListener('mouseup', function(event) {
|
||||
window.loggedEvent = window.loggedEvent || [];
|
||||
window.loggedEvent.push(event);
|
||||
}, false);
|
||||
});
|
||||
page.sendEvent('mouseup', 42, 217);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(loggedEvent.length, 1);
|
||||
assert_equals(loggedEvent[0].clientX, 42);
|
||||
assert_equals(loggedEvent[0].clientY, 217);
|
||||
|
||||
page.sendEvent('mouseup', 42, 217);
|
||||
var loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert.equal(loggedEvent.length, 1);
|
||||
assert.equal(loggedEvent[0].clientX, 42);
|
||||
assert.equal(loggedEvent[0].clientY, 217);
|
||||
|
||||
page.sendEvent('mouseup', 100, 100, 'left', page.event.modifier.shift);
|
||||
loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert.equal(loggedEvent.length, 2);
|
||||
assert.isTrue(loggedEvent[1].shiftKey);
|
||||
page.sendEvent('mouseup', 100, 100, 'left', page.event.modifier.shift);
|
||||
loggedEvent = page.evaluate(function() {
|
||||
return window.loggedEvent;
|
||||
});
|
||||
assert_equals(loggedEvent.length, 2);
|
||||
assert_is_true(loggedEvent[1].shiftKey);
|
||||
}, "mouse-up events");
|
||||
|
@ -1,17 +1,19 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
async_test(function () {
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
|
||||
var page = webpage.create();
|
||||
|
||||
var pluginLength = page.evaluate(function() {
|
||||
return window.navigator.plugins.length;
|
||||
});
|
||||
assert.equal(pluginLength, 0);
|
||||
|
||||
page.open('http://localhost:9180/hello.html', function (status) {
|
||||
assert.equal(status, 'success');
|
||||
var pluginLength = page.evaluate(function() {
|
||||
return window.navigator.plugins.length;
|
||||
});
|
||||
assert.equal(pluginLength, 0);
|
||||
});
|
||||
assert_equals(pluginLength, 0);
|
||||
|
||||
page.open('http://localhost:9180/hello.html',
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
var pluginLength = page.evaluate(function() {
|
||||
return window.navigator.plugins.length;
|
||||
});
|
||||
assert_equals(pluginLength, 0);
|
||||
}));
|
||||
|
||||
}, "window.navigator.plugins is empty");
|
||||
|
@ -1,13 +1,70 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
var page = require("webpage").create();
|
||||
|
||||
var page = webpage.create();
|
||||
test(function () {
|
||||
assert_type_of(page, 'object');
|
||||
assert_not_equals(page, null);
|
||||
|
||||
assert.typeOf(page, 'object');
|
||||
assert.notEqual(page, null);
|
||||
assert_equals(page.objectName, 'WebPage');
|
||||
assert_deep_equals(page.paperSize, {});
|
||||
|
||||
assert.equal(page.objectName, 'WebPage');
|
||||
assert.jsonEqual(page.paperSize, {});
|
||||
assert_not_equals(page.settings, null);
|
||||
assert_not_equals(page.settings, {});
|
||||
|
||||
assert.notEqual(page.settings, null);
|
||||
assert.notEqual(page.settings, {});
|
||||
assert_type_of(page.canGoForward, 'boolean');
|
||||
assert_type_of(page.canGoBack, 'boolean');
|
||||
assert_type_of(page.clipRect, 'object');
|
||||
assert_type_of(page.content, 'string');
|
||||
assert_type_of(page.cookieJar, 'object');
|
||||
assert_type_of(page.cookies, 'object');
|
||||
assert_type_of(page.customHeaders, 'object');
|
||||
assert_type_of(page.event, 'object');
|
||||
assert_type_of(page.libraryPath, 'string');
|
||||
assert_type_of(page.loading, 'boolean');
|
||||
assert_type_of(page.loadingProgress, 'number');
|
||||
assert_type_of(page.navigationLocked, 'boolean');
|
||||
assert_type_of(page.offlineStoragePath, 'string');
|
||||
assert_type_of(page.offlineStorageQuota, 'number');
|
||||
assert_type_of(page.paperSize, 'object');
|
||||
assert_type_of(page.plainText, 'string');
|
||||
assert_type_of(page.scrollPosition, 'object');
|
||||
assert_type_of(page.settings, 'object');
|
||||
assert_type_of(page.title, 'string');
|
||||
assert_type_of(page.url, 'string');
|
||||
assert_type_of(page.viewportSize, 'object');
|
||||
assert_type_of(page.windowName, 'string');
|
||||
assert_type_of(page.zoomFactor, 'number');
|
||||
|
||||
}, "page object properties");
|
||||
|
||||
test(function () {
|
||||
assert_type_of(page.childFramesCount, 'function');
|
||||
assert_type_of(page.childFramesName, 'function');
|
||||
assert_type_of(page.clearMemoryCache, 'function');
|
||||
assert_type_of(page.close, 'function');
|
||||
assert_type_of(page.currentFrameName, 'function');
|
||||
assert_type_of(page.deleteLater, 'function');
|
||||
assert_type_of(page.destroyed, 'function');
|
||||
assert_type_of(page.evaluate, 'function');
|
||||
assert_type_of(page.initialized, 'function');
|
||||
assert_type_of(page.injectJs, 'function');
|
||||
assert_type_of(page.javaScriptAlertSent, 'function');
|
||||
assert_type_of(page.javaScriptConsoleMessageSent, 'function');
|
||||
assert_type_of(page.loadFinished, 'function');
|
||||
assert_type_of(page.loadStarted, 'function');
|
||||
assert_type_of(page.openUrl, 'function');
|
||||
assert_type_of(page.release, 'function');
|
||||
assert_type_of(page.render, 'function');
|
||||
assert_type_of(page.resourceError, 'function');
|
||||
assert_type_of(page.resourceReceived, 'function');
|
||||
assert_type_of(page.resourceRequested, 'function');
|
||||
assert_type_of(page.uploadFile, 'function');
|
||||
assert_type_of(page.sendEvent, 'function');
|
||||
assert_type_of(page.setContent, 'function');
|
||||
assert_type_of(page.switchToChildFrame, 'function');
|
||||
assert_type_of(page.switchToMainFrame, 'function');
|
||||
assert_type_of(page.switchToParentFrame, 'function');
|
||||
|
||||
assert_type_of(page.addCookie, 'function');
|
||||
assert_type_of(page.deleteCookie, 'function');
|
||||
assert_type_of(page.clearCookies, 'function');
|
||||
}, "page object methods");
|
||||
|
@ -1,31 +1,33 @@
|
||||
var assert = require('../../assert');
|
||||
var page = require('webpage').create();
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
var msg = "message body",
|
||||
result,
|
||||
expected = true;
|
||||
var msg = "message body",
|
||||
result,
|
||||
expected = true;
|
||||
|
||||
assert.equal(page.onConfirm, undefined);
|
||||
assert_equals(page.onConfirm, undefined);
|
||||
|
||||
var onConfirmTrue = function(msg) {
|
||||
return true;
|
||||
};
|
||||
page.onConfirm = onConfirmTrue;
|
||||
assert.equal(page.onConfirm, onConfirmTrue);
|
||||
var onConfirmTrue = function(msg) {
|
||||
return true;
|
||||
};
|
||||
page.onConfirm = onConfirmTrue;
|
||||
assert_equals(page.onConfirm, onConfirmTrue);
|
||||
|
||||
result = page.evaluate(function(m) {
|
||||
return window.confirm(m);
|
||||
}, msg);
|
||||
result = page.evaluate(function(m) {
|
||||
return window.confirm(m);
|
||||
}, msg);
|
||||
|
||||
assert.equal(result, expected);
|
||||
assert_equals(result, expected);
|
||||
|
||||
var onConfirmFunc = function() { return !!"y"; };
|
||||
page.onConfirm = onConfirmFunc2;
|
||||
assert.equal(page.onConfirm, onConfirmFunc);
|
||||
assert.notEqual(page.onConfirm, onConfirmTrue);
|
||||
var onConfirmFunc = function() { return !!"y"; };
|
||||
page.onConfirm = onConfirmFunc;
|
||||
assert_equals(page.onConfirm, onConfirmFunc);
|
||||
assert_not_equals(page.onConfirm, onConfirmTrue);
|
||||
|
||||
page.onConfirm = null;
|
||||
// Will only allow setting to a function value, so setting it to `null` returns `undefined`
|
||||
assert.equal(page.onConfirm, undefined);
|
||||
page.onConfirm = undefined;
|
||||
assert.equal(page.onConfirm, undefined);
|
||||
page.onConfirm = null;
|
||||
// Will only allow setting to a function value, so setting it to `null` returns `undefined`
|
||||
assert_equals(page.onConfirm, undefined);
|
||||
page.onConfirm = undefined;
|
||||
assert_equals(page.onConfirm, undefined);
|
||||
|
||||
}, "page.onConfirm");
|
||||
|
@ -1,59 +1,67 @@
|
||||
var assert = require('../../assert');
|
||||
var page = require('webpage').create();
|
||||
var webpage = require('webpage');
|
||||
|
||||
assert.notEqual(page.onError, undefined);
|
||||
test(function () {
|
||||
var page = webpage.create();
|
||||
assert_not_equals(page.onError, undefined);
|
||||
|
||||
var onErrorFunc1 = function() { return !"x"; };
|
||||
page.onError = onErrorFunc1;
|
||||
assert.equal(page.onError, onErrorFunc1);
|
||||
var onErrorFunc1 = function() { return !"x"; };
|
||||
page.onError = onErrorFunc1;
|
||||
assert_equals(page.onError, onErrorFunc1);
|
||||
|
||||
var onErrorFunc2 = function() { return !!"y"; };
|
||||
page.onError = onErrorFunc2;
|
||||
assert.equal(page.onError, onErrorFunc2);
|
||||
assert.notEqual(page.onError, onErrorFunc1);
|
||||
var onErrorFunc2 = function() { return !!"y"; };
|
||||
page.onError = onErrorFunc2;
|
||||
assert_equals(page.onError, onErrorFunc2);
|
||||
assert_not_equals(page.onError, onErrorFunc1);
|
||||
|
||||
page.onError = null;
|
||||
// Will only allow setting to a function value, so setting it to `null` returns `undefined`
|
||||
assert.equal(page.onError, undefined);
|
||||
page.onError = undefined;
|
||||
assert.equal(page.onError, undefined);
|
||||
page.onError = null;
|
||||
// Will only allow setting to a function value, so setting it to `null` returns `undefined`
|
||||
assert_equals(page.onError, undefined);
|
||||
page.onError = undefined;
|
||||
assert_equals(page.onError, undefined);
|
||||
}, "setting and clearing page.onError");
|
||||
|
||||
// reports error
|
||||
var lastError = null;
|
||||
page.onError = function(message) { lastError = message; };
|
||||
test(function () {
|
||||
var page = webpage.create();
|
||||
var lastError = null;
|
||||
page.onError = function(message) { lastError = message; };
|
||||
|
||||
page.evaluate(function() { referenceError2(); });
|
||||
assert.equal(lastError, "ReferenceError: Can't find variable: referenceError2");
|
||||
page.evaluate(function() { referenceError2(); });
|
||||
assert_equals(lastError, "ReferenceError: Can't find variable: referenceError2");
|
||||
|
||||
page.evaluate(function() { throw "foo"; });
|
||||
assert.equal(lastError, "foo");
|
||||
page.evaluate(function() { throw "foo"; });
|
||||
assert_equals(lastError, "foo");
|
||||
|
||||
page.evaluate(function() { throw Error("foo"); });
|
||||
assert.equal(lastError, "Error: foo");
|
||||
page.evaluate(function() { throw Error("foo"); });
|
||||
assert_equals(lastError, "Error: foo");
|
||||
}, "basic error reporting");
|
||||
|
||||
// don't report handled errors
|
||||
var hadError = false;
|
||||
var caughtError = false;
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var lastError = null;
|
||||
page.onError = this.step_func_done(function(message) {
|
||||
assert_equals(message, "ReferenceError: Can't find variable: referenceError");
|
||||
});
|
||||
|
||||
page.onError = function() { hadError = true; };
|
||||
page.evaluate(function() {
|
||||
caughtError = false;
|
||||
page.evaluate(function() {
|
||||
setTimeout(function() { referenceError(); }, 0);
|
||||
});
|
||||
|
||||
try {
|
||||
referenceError();
|
||||
} catch(e) {
|
||||
caughtError = true;
|
||||
}
|
||||
});
|
||||
}, "error reporting from async events");
|
||||
|
||||
assert.equal(hadError, false);
|
||||
assert.isTrue(page.evaluate(function() { return caughtError; }));
|
||||
test(function () {
|
||||
var page = webpage.create();
|
||||
var hadError = false;
|
||||
page.onError = function() { hadError = true; };
|
||||
page.evaluate(function() {
|
||||
window.caughtError = false;
|
||||
|
||||
// even with async
|
||||
page.evaluate(function() {
|
||||
setTimeout(function() { referenceError(); }, 0);
|
||||
});
|
||||
try {
|
||||
referenceError();
|
||||
} catch(e) {
|
||||
window.caughtError = true;
|
||||
}
|
||||
});
|
||||
|
||||
assert.waitFor(function() {
|
||||
return lastError == "ReferenceError: Can't find variable: referenceError";
|
||||
});
|
||||
assert_equals(hadError, false);
|
||||
assert_is_true(page.evaluate(function() { return window.caughtError; }));
|
||||
}, "should not report errors that were caught");
|
||||
|
@ -1,20 +1,21 @@
|
||||
var assert = require('../../assert');
|
||||
var page = require('webpage').create();
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
assert.equal(page.onInitialized, undefined);
|
||||
assert_equals(page.onInitialized, undefined);
|
||||
|
||||
var onInitialized1 = function() { var x = "x"; };
|
||||
page.onInitialized = onInitialized1;
|
||||
assert.equal(page.onInitialized, onInitialized1);
|
||||
var onInitialized1 = function() { var x = "x"; };
|
||||
page.onInitialized = onInitialized1;
|
||||
assert_equals(page.onInitialized, onInitialized1);
|
||||
|
||||
var onInitialized2 = function() { var y = "y"; };
|
||||
page.onInitialized = onInitialized2;
|
||||
assert.equal(page.onInitialized, onInitialized2);
|
||||
assert.notEqual(page.onInitialized, onInitialized1);
|
||||
var onInitialized2 = function() { var y = "y"; };
|
||||
page.onInitialized = onInitialized2;
|
||||
assert_equals(page.onInitialized, onInitialized2);
|
||||
assert_not_equals(page.onInitialized, onInitialized1);
|
||||
|
||||
page.onInitialized = null;
|
||||
// Will only allow setting to a function value, so setting it to `null` returns `undefined`
|
||||
assert.equal(page.onInitialized, undefined);
|
||||
page.onInitialized = null;
|
||||
// Will only allow setting to a function value, so setting it to `null` returns `undefined`
|
||||
assert_equals(page.onInitialized, undefined);
|
||||
|
||||
page.onInitialized = undefined;
|
||||
assert.equal(page.onInitialized, undefined);
|
||||
page.onInitialized = undefined;
|
||||
assert_equals(page.onInitialized, undefined);
|
||||
}, "page.onInitialized");
|
||||
|
@ -1,13 +1,14 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
async_test(function () {
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
assert_type_of(page, 'object');
|
||||
|
||||
var page = webpage.create();
|
||||
assert.typeOf(page, 'object');
|
||||
|
||||
page.open('http://localhost:9180/hello.html', function (status) {
|
||||
assert.equal(status, 'success');
|
||||
assert.typeOf(page.title, 'string');
|
||||
assert.equal(page.title, 'Hello');
|
||||
assert.typeOf(page.plainText, 'string');
|
||||
assert.equal(page.plainText, 'Hello, world!');
|
||||
});
|
||||
page.open('http://localhost:9180/hello.html',
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
assert_type_of(page.title, 'string');
|
||||
assert_equals(page.title, 'Hello');
|
||||
assert_type_of(page.plainText, 'string');
|
||||
assert_equals(page.plainText, 'Hello, world!');
|
||||
}));
|
||||
}, "page.open");
|
||||
|
@ -1,15 +1,16 @@
|
||||
var assert = require('../../assert');
|
||||
var page = require('webpage').create();
|
||||
test(function () {
|
||||
var page = require('webpage').create();
|
||||
|
||||
var msg = "message",
|
||||
value = "value",
|
||||
result,
|
||||
expected = "extra-value";
|
||||
page.onPrompt = function(msg, value) {
|
||||
return "extra-"+value;
|
||||
};
|
||||
result = page.evaluate(function(m, v) {
|
||||
return window.prompt(m, v);
|
||||
}, msg, value);
|
||||
var msg = "message",
|
||||
value = "value",
|
||||
result,
|
||||
expected = "extra-value";
|
||||
page.onPrompt = function(msg, value) {
|
||||
return "extra-"+value;
|
||||
};
|
||||
result = page.evaluate(function(m, v) {
|
||||
return window.prompt(m, v);
|
||||
}, msg, value);
|
||||
|
||||
assert.equal(result, expected);
|
||||
assert_equals(result, expected);
|
||||
}, "page.onPrompt");
|
||||
|
@ -1,27 +0,0 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
var page = webpage.create();
|
||||
|
||||
assert.typeOf(page.canGoForward, 'boolean');
|
||||
assert.typeOf(page.canGoBack, 'boolean');
|
||||
assert.typeOf(page.clipRect, 'object');
|
||||
assert.typeOf(page.content, 'string');
|
||||
assert.typeOf(page.cookieJar, 'object');
|
||||
assert.typeOf(page.cookies, 'object');
|
||||
assert.typeOf(page.customHeaders, 'object');
|
||||
assert.typeOf(page.event, 'object');
|
||||
assert.typeOf(page.libraryPath, 'string');
|
||||
assert.typeOf(page.loading, 'boolean');
|
||||
assert.typeOf(page.loadingProgress, 'number');
|
||||
assert.typeOf(page.navigationLocked, 'boolean');
|
||||
assert.typeOf(page.offlineStoragePath, 'string');
|
||||
assert.typeOf(page.offlineStorageQuota, 'number');
|
||||
assert.typeOf(page.paperSize, 'object');
|
||||
assert.typeOf(page.plainText, 'string');
|
||||
assert.typeOf(page.scrollPosition, 'object');
|
||||
assert.typeOf(page.settings, 'object');
|
||||
assert.typeOf(page.title, 'string');
|
||||
assert.typeOf(page.url, 'string');
|
||||
assert.typeOf(page.viewportSize, 'object');
|
||||
assert.typeOf(page.windowName, 'string');
|
||||
assert.typeOf(page.zoomFactor, 'number');
|
@ -1,25 +1,26 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
// NOTE: HTTP header names are case-insensitive. Our test server
|
||||
// returns the name in lowercase.
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
assert_type_of(page.customHeaders, 'object');
|
||||
assert_deep_equals(page.customHeaders, {});
|
||||
|
||||
var page = webpage.create();
|
||||
assert.typeOf(page.customHeaders, 'object');
|
||||
assert.strictEqual(JSON.stringify(page.customHeaders), '{}');
|
||||
page.customHeaders = { 'CustomHeader': 'ModifiedCustomValue' };
|
||||
|
||||
page.customHeaders = { 'CustomHeader': 'ModifiedCustomValue' };
|
||||
page.onResourceRequested = this.step_func(function(requestData, request) {
|
||||
assert_type_of(request.setHeader, 'function');
|
||||
request.setHeader('CustomHeader', null);
|
||||
});
|
||||
|
||||
page.onResourceRequested = function(requestData, request) {
|
||||
assert.typeOf(request.setHeader, 'function');
|
||||
request.setHeader('CustomHeader', null);
|
||||
};
|
||||
page.open('http://localhost:9180/echo', function (status) {
|
||||
var json, headers;
|
||||
assert.equal(status, 'success');
|
||||
json = JSON.parse(page.plainText);
|
||||
headers = json.headers;
|
||||
assert.isTrue(!headers.hasOwnProperty('customheader'));
|
||||
assert.isTrue(!headers.hasOwnProperty('CustomHeader'));
|
||||
page.open('http://localhost:9180/echo',
|
||||
this.step_func_done(function (status) {
|
||||
var json, headers;
|
||||
assert_equals(status, 'success');
|
||||
json = JSON.parse(page.plainText);
|
||||
headers = json.headers;
|
||||
assert_no_property(headers, 'customheader');
|
||||
assert_no_property(headers, 'CustomHeader');
|
||||
}));
|
||||
});
|
||||
|
||||
|
@ -1,16 +1,19 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var requestCount = 0;
|
||||
|
||||
var requestCount = 0;
|
||||
page.onRepaintRequested = this.step_func(function(x, y, w, h) {
|
||||
if ((w > 0) && (h > 0)) {
|
||||
++requestCount;
|
||||
}
|
||||
});
|
||||
|
||||
page.onRepaintRequested = function(x, y, w, h) {
|
||||
if ((w > 0) && (h > 0)) {
|
||||
++requestCount;
|
||||
}
|
||||
};
|
||||
page.open('http://localhost:9180/hello.html',
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
assert_greater_than(requestCount, 0);
|
||||
}));
|
||||
|
||||
page.open('http://localhost:9180/hello.html', function (status) {
|
||||
assert.isTrue(requestCount > 0);
|
||||
});
|
||||
}, "onRepaintRequested should be called at least once for each page load");
|
||||
|
@ -1,23 +1,32 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var url = 'http://localhost:9180/status?400';
|
||||
var startStage = 0;
|
||||
var endStage = 0;
|
||||
var errors = 0;
|
||||
|
||||
// It should still fire `onResourceReceived` callback twice
|
||||
// (for each start and end stage) when the resource error occured
|
||||
page.onResourceReceived = this.step_func(function (resource) {
|
||||
assert_equals(resource.url, url);
|
||||
if (resource.stage === 'start') {
|
||||
++startStage;
|
||||
}
|
||||
if (resource.stage === 'end') {
|
||||
++endStage;
|
||||
}
|
||||
});
|
||||
page.onResourceError = this.step_func(function (error) {
|
||||
assert_equals(error.url, url);
|
||||
assert_equals(error.status, 400);
|
||||
++errors;
|
||||
});
|
||||
|
||||
var startStage = 0;
|
||||
var endStage = 0;
|
||||
page.onResourceReceived = function (resource) {
|
||||
if (resource.stage === 'start') {
|
||||
++startStage;
|
||||
}
|
||||
if (resource.stage === 'end') {
|
||||
++endStage;
|
||||
}
|
||||
};
|
||||
page.open(url, this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
assert_equals(startStage, 1);
|
||||
assert_equals(endStage, 1);
|
||||
assert_equals(errors, 1);
|
||||
}));
|
||||
|
||||
page.open('http://localhost:9180/status?400', function (status) {
|
||||
assert.equal(startStage, 1);
|
||||
assert.equal(endStage, 1);
|
||||
});
|
||||
}, "onResourceReceived should still be called for failed requests");
|
||||
|
@ -1,17 +1,26 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
async_test(function () {
|
||||
var page = webpage.create();
|
||||
var resourceErrors = 0;
|
||||
|
||||
page.onResourceError = function(err) {
|
||||
assert.equal(err.status, 404);
|
||||
assert.equal(err.statusText, 'File not found');
|
||||
assert.equal(err.url, 'http://localhost:9180/notExist.png');
|
||||
assert.equal(err.errorCode, 203);
|
||||
assert.isTrue(err.errorString.match('Error downloading http://localhost:9180/notExist.png'));
|
||||
assert.isTrue(err.errorString.match('server replied: File not found'));
|
||||
};
|
||||
page.onResourceError = this.step_func(function(err) {
|
||||
++resourceErrors;
|
||||
|
||||
page.open('http://localhost:9180/missing-img.html', function (status) {
|
||||
assert.equal(status, 'success');
|
||||
});
|
||||
assert_equals(err.status, 404);
|
||||
assert_equals(err.statusText, 'File not found');
|
||||
assert_equals(err.url, 'http://localhost:9180/notExist.png');
|
||||
assert_equals(err.errorCode, 203);
|
||||
assert_regexp_match(err.errorString,
|
||||
/Error downloading http:\/\/localhost:9180\/notExist\.png/);
|
||||
assert_regexp_match(err.errorString,
|
||||
/server replied: File not found/);
|
||||
});
|
||||
|
||||
page.open('http://localhost:9180/missing-img.html',
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
assert_equals(resourceErrors, 1);
|
||||
}));
|
||||
|
||||
}, "resourceError basic functionality");
|
||||
|
@ -1,14 +1,17 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
var defaultPage = webpage.create();
|
||||
assert.jsonEqual(defaultPage.scrollPosition, {left:0,top:0});
|
||||
test(function () {
|
||||
var defaultPage = webpage.create();
|
||||
assert_deep_equals(defaultPage.scrollPosition, {left:0,top:0});
|
||||
}, "default scroll position");
|
||||
|
||||
var options = {
|
||||
scrollPosition: {
|
||||
left: 1,
|
||||
top: 2
|
||||
}
|
||||
};
|
||||
var customPage = webpage.create(options);
|
||||
assert.jsonEqual(customPage.scrollPosition, options.scrollPosition);
|
||||
test(function () {
|
||||
var options = {
|
||||
scrollPosition: {
|
||||
left: 1,
|
||||
top: 2
|
||||
}
|
||||
};
|
||||
var customPage = webpage.create(options);
|
||||
assert_deep_equals(customPage.scrollPosition, options.scrollPosition);
|
||||
}, "custom scroll position");
|
||||
|
@ -1,18 +1,19 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
var expectedContent = '<html><body><div>Test div</div></body></html>';
|
||||
var expectedLocation = 'http://www.phantomjs.org/';
|
||||
page.setContent(expectedContent, expectedLocation);
|
||||
test(function () {
|
||||
var page = webpage.create();
|
||||
var expectedContent = '<html><body><div>Test div</div></body></html>';
|
||||
var expectedLocation = 'http://www.phantomjs.org/';
|
||||
page.setContent(expectedContent, expectedLocation);
|
||||
|
||||
var actualContent = page.evaluate(function() {
|
||||
return document.documentElement.textContent;
|
||||
});
|
||||
assert.equal(actualContent, 'Test div');
|
||||
var actualContent = page.evaluate(function() {
|
||||
return document.documentElement.textContent;
|
||||
});
|
||||
assert_equals(actualContent, 'Test div');
|
||||
|
||||
var actualLocation = page.evaluate(function() {
|
||||
return window.location.href;
|
||||
});
|
||||
assert.equal(actualLocation, expectedLocation);
|
||||
var actualLocation = page.evaluate(function() {
|
||||
return window.location.href;
|
||||
});
|
||||
assert_equals(actualLocation, expectedLocation);
|
||||
|
||||
}, "manually set page content and location");
|
||||
|
@ -1,20 +1,22 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
|
||||
var ua = 'PHANTOMJS-TEST-USER-AGENT';
|
||||
var page = webpage.create({
|
||||
settings: {
|
||||
userAgent: ua
|
||||
}
|
||||
});
|
||||
|
||||
assert.equal(page.settings.userAgent, ua);
|
||||
|
||||
page.open('http://localhost:9180/user-agent.html', function (status) {
|
||||
assert.equal(status, 'success');
|
||||
var agent = page.evaluate(function() {
|
||||
return document.getElementById('ua').textContent;
|
||||
async_test(function () {
|
||||
var ua = 'PHANTOMJS-TEST-USER-AGENT';
|
||||
var page = webpage.create({
|
||||
settings: {
|
||||
userAgent: ua
|
||||
}
|
||||
});
|
||||
assert.equal(agent, ua);
|
||||
});
|
||||
|
||||
assert_equals(page.settings.userAgent, ua);
|
||||
|
||||
page.open('http://localhost:9180/user-agent.html',
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
var agent = page.evaluate(function() {
|
||||
return document.getElementById('ua').textContent;
|
||||
});
|
||||
assert_equals(agent, ua);
|
||||
}));
|
||||
|
||||
}, "load a page with a custom user agent");
|
||||
|
@ -1,14 +1,17 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
var defaultPage = webpage.create();
|
||||
assert.jsonEqual(defaultPage.viewportSize, {height:300,width:400});
|
||||
test(function () {
|
||||
var defaultPage = webpage.create();
|
||||
assert_deep_equals(defaultPage.viewportSize, {height:300,width:400});
|
||||
}, "default viewport size");
|
||||
|
||||
var options = {
|
||||
viewportSize: {
|
||||
height: 100,
|
||||
width: 200
|
||||
}
|
||||
};
|
||||
var customPage = webpage.create(options);
|
||||
assert.jsonEqual(customPage.viewportSize, options.viewportSize);
|
||||
test(function () {
|
||||
var options = {
|
||||
viewportSize: {
|
||||
height: 100,
|
||||
width: 200
|
||||
}
|
||||
};
|
||||
var customPage = webpage.create(options);
|
||||
assert_deep_equals(customPage.viewportSize, options.viewportSize);
|
||||
}, "custom viewport size");
|
||||
|
@ -1,4 +1,4 @@
|
||||
var assert = require('../../assert');
|
||||
|
||||
assert.isTrue(window.hasOwnProperty('WebPage'));
|
||||
assert.typeOf(window.WebPage, 'function');
|
||||
test(function () {
|
||||
assert_own_property(window, 'WebPage');
|
||||
assert_type_of(window.WebPage, 'function');
|
||||
}, "window.WebPage global property");
|
||||
|
@ -1,16 +1,17 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
assert.strictEqual(page.zoomFactor, 1.0);
|
||||
test(function () {
|
||||
var page = webpage.create();
|
||||
assert_equals(page.zoomFactor, 1.0);
|
||||
|
||||
page.zoomFactor = 1.5;
|
||||
assert.strictEqual(page.zoomFactor, 1.5);
|
||||
page.zoomFactor = 1.5;
|
||||
assert_equals(page.zoomFactor, 1.5);
|
||||
|
||||
page.zoomFactor = 2.0;
|
||||
assert.strictEqual(page.zoomFactor, 2.0);
|
||||
page.zoomFactor = 2.0;
|
||||
assert_equals(page.zoomFactor, 2.0);
|
||||
|
||||
page.zoomFactor = 0.5;
|
||||
assert.strictEqual(page.zoomFactor, 0.5);
|
||||
page.zoomFactor = 0.5;
|
||||
assert_equals(page.zoomFactor, 0.5);
|
||||
}, "page.zoomFactor");
|
||||
|
||||
// TODO: render using zoomFactor != 1 and check the result
|
||||
|
3
test/regression/README
Normal file
3
test/regression/README
Normal file
@ -0,0 +1,3 @@
|
||||
Tests in this directory are named for their bug number.
|
||||
pjs-NNNN corresponds to https://github.com/ariya/phantomjs/issues/NNNN.
|
||||
webkit-NNNN corresponds to https://bugs.webkit.org/show_bug.cgi?id=NNNN.
|
@ -1,3 +1,5 @@
|
||||
//! no-harness
|
||||
|
||||
// https://github.com/ariya/phantomjs/issues/12482
|
||||
// regression caused by fix for
|
||||
// https://github.com/ariya/phantomjs/issues/12431
|
@ -1,3 +1,5 @@
|
||||
//! no-harness
|
||||
|
||||
/*
|
||||
This file is part of the PhantomJS project from Ofi Labs.
|
||||
|
||||
@ -84,6 +86,9 @@ if (sys.args.length > 1) {
|
||||
if (sys.args[1] == "-v" || sys.args[1] == "--verbose") {
|
||||
verbose = true;
|
||||
rest = 2;
|
||||
} else if (sys.args[1].slice(0, "--verbose=".length) == "--verbose=") {
|
||||
verbose = parseInt(sys.args[1].slice("--verbose=".length)) > 0;
|
||||
rest = 2;
|
||||
}
|
||||
|
||||
if (sys.args.length > rest) {
|
||||
|
@ -30,6 +30,8 @@ TESTS = [
|
||||
]
|
||||
|
||||
TIMEOUT = 20 # Maximum duration of PhantomJS execution (in seconds).
|
||||
# This is a backstop; testharness.js imposes a shorter,
|
||||
# adjustable timeout.
|
||||
# There's currently no way to adjust this on a per-test
|
||||
# basis, so it has to be large.
|
||||
|
||||
@ -290,6 +292,7 @@ class TestRunner(object):
|
||||
def __init__(self, base_path, phantomjs_exe, options):
|
||||
self.base_path = base_path
|
||||
self.cert_path = os.path.join(base_path, 'certs')
|
||||
self.harness = os.path.join(base_path, 'testharness.js')
|
||||
self.phantomjs_exe = phantomjs_exe
|
||||
self.verbose = options.verbose
|
||||
self.debugger = options.debugger
|
||||
@ -339,6 +342,7 @@ class TestRunner(object):
|
||||
def run_test(self, script, name):
|
||||
script_args = []
|
||||
pjs_args = []
|
||||
use_harness = True
|
||||
use_snakeoil = True
|
||||
|
||||
# Parse any directives at the top of the script.
|
||||
@ -351,7 +355,9 @@ class TestRunner(object):
|
||||
|
||||
for i in range(len(tokens)):
|
||||
tok = tokens[i]
|
||||
if tok == "no-snakeoil":
|
||||
if tok == "no-harness":
|
||||
use_harness = False
|
||||
elif tok == "no-snakeoil":
|
||||
use_snakeoil = False
|
||||
elif tok == "phantomjs:":
|
||||
if i+1 == len(tokens):
|
||||
@ -377,6 +383,10 @@ class TestRunner(object):
|
||||
.format(name, script, str(e)))
|
||||
return 1
|
||||
|
||||
if use_harness:
|
||||
script_args.insert(0, script)
|
||||
script = self.harness
|
||||
|
||||
if use_snakeoil:
|
||||
pjs_args.insert(0, '--ssl-certificates-path=' + self.cert_path)
|
||||
|
||||
|
@ -1,16 +1,9 @@
|
||||
var assert = require('../../assert');
|
||||
var webpage = require('webpage');
|
||||
|
||||
var page = webpage.create();
|
||||
|
||||
var message;
|
||||
page.onConsoleMessage = function (msg) {
|
||||
message = msg;
|
||||
}
|
||||
|
||||
// console.log should support multiple arguments
|
||||
page.evaluate(function () {
|
||||
console.log('answer', 42);
|
||||
});
|
||||
|
||||
assert.equal(message, 'answer 42');
|
||||
async_test(function () {
|
||||
var page = require('webpage').create();
|
||||
page.onConsoleMessage = this.step_func_done(function (msg) {
|
||||
assert_equals(msg, "answer 42");
|
||||
});
|
||||
page.evaluate(function () {
|
||||
console.log('answer', 42);
|
||||
});
|
||||
}, "console.log should support multiple arguments");
|
||||
|
@ -1,12 +1,12 @@
|
||||
var assert = require('../../assert');
|
||||
test(function() {
|
||||
var date = new Date('2012-09-07');
|
||||
assert_not_equals(date.toString(), 'Invalid Date');
|
||||
assert_equals(date.getDate(), 6);
|
||||
assert_equals(date.getMonth(), 8);
|
||||
assert_equals(date.getYear(), 112);
|
||||
}, "new Date()");
|
||||
|
||||
// construct date in mm-dd-yyyy format
|
||||
var date = new Date('2012-09-07');
|
||||
assert.isTrue(date.toString() != 'Invalid Date');
|
||||
assert.equal(date.getDate(), 6);
|
||||
assert.equal(date.getMonth(), 8);
|
||||
assert.equal(date.getYear(), 112);
|
||||
|
||||
// parse date in ISO8601 format (yyyy-mm-dd)
|
||||
var date = Date.parse("2012-01-01");
|
||||
assert.equal(date, 1325376000000);
|
||||
test(function () {
|
||||
var date = Date.parse("2012-01-01");
|
||||
assert_equals(date, 1325376000000);
|
||||
}, "Date.parse()");
|
||||
|
@ -1,40 +1,46 @@
|
||||
var assert = require('../../assert');
|
||||
test(function () {
|
||||
assert_type_of(Function.length, 'number');
|
||||
assert_type_of(Function.prototype, 'function');
|
||||
assert_type_of(Function.prototype.apply, 'function');
|
||||
assert_type_of(Function.prototype.bind, 'function');
|
||||
assert_type_of(Function.prototype.call, 'function');
|
||||
assert_type_of(Function.prototype.name, 'string');
|
||||
assert_type_of(Function.prototype.toString, 'function');
|
||||
}, "Function properties");
|
||||
|
||||
assert.typeOf(Function.length, 'number');
|
||||
assert.typeOf(Function.prototype, 'function');
|
||||
assert.typeOf(Function.prototype.apply, 'function');
|
||||
assert.typeOf(Function.prototype.bind, 'function');
|
||||
assert.typeOf(Function.prototype.call, 'function');
|
||||
assert.typeOf(Function.prototype.name, 'string');
|
||||
assert.typeOf(Function.prototype.toString, 'function');
|
||||
test(function () {
|
||||
var f = function foo(){};
|
||||
assert_equals(f.name, 'foo');
|
||||
}, "<function>.name");
|
||||
|
||||
var f = function foo(){};
|
||||
assert.equal(f.name, 'foo');
|
||||
test(function () {
|
||||
assert_equals(Function.length, 1);
|
||||
assert_equals(function(){}.length, 0);
|
||||
assert_equals(function(x){}.length, 1);
|
||||
assert_equals(function(x, y){}.length, 2);
|
||||
assert_equals(function(x, y){}.length, 2);
|
||||
}, "<function>.length");
|
||||
|
||||
assert.equal(Function.length, 1);
|
||||
assert.equal(function(){}.length, 0);
|
||||
assert.equal(function(x){}.length, 1);
|
||||
assert.equal(function(x, y){}.length, 2);
|
||||
assert.equal(function(x, y){}.length, 2);
|
||||
test(function () {
|
||||
var args, keys, str, enumerable;
|
||||
(function() {
|
||||
args = arguments;
|
||||
keys = Object.keys(arguments);
|
||||
str = JSON.stringify(arguments);
|
||||
enumerable = false;
|
||||
for (var i in arguments) enumerable = true;
|
||||
})(14);
|
||||
|
||||
var args, keys, str, enumerable;
|
||||
(function() {
|
||||
args = arguments;
|
||||
keys = Object.keys(arguments);
|
||||
str = JSON.stringify(arguments);
|
||||
enumerable = false;
|
||||
for (var i in arguments) enumerable = true;
|
||||
})(14);
|
||||
assert_type_of(args, 'object');
|
||||
assert_type_of(args.length, 'number');
|
||||
assert_equals(args.toString(), '[object Arguments]');
|
||||
assert_equals(args.length, 1);
|
||||
assert_equals(args[0], 14);
|
||||
|
||||
assert.typeOf(args, 'object');
|
||||
assert.typeOf(args.length, 'number');
|
||||
assert.strictEqual(args.toString(), '[object Arguments]');
|
||||
assert.strictEqual(args.length, 1);
|
||||
assert.strictEqual(args[0], 14);
|
||||
assert_type_of(keys.length, 'number');
|
||||
assert_equals(keys.length, 1);
|
||||
assert_equals(keys[0], "0");
|
||||
|
||||
assert.typeOf(keys.length, 'number');
|
||||
assert.strictEqual(keys.length, 1);
|
||||
assert.equal(keys[0], 0);
|
||||
|
||||
assert.strictEqual(str, '{"0":14}');
|
||||
assert.isTrue(enumerable);
|
||||
assert_equals(str, '{"0":14}');
|
||||
assert_is_true(enumerable);
|
||||
}, "arguments object");
|
||||
|
1547
test/testharness.js
Normal file
1547
test/testharness.js
Normal file
File diff suppressed because it is too large
Load Diff
591
test/writing-tests.md
Normal file
591
test/writing-tests.md
Normal file
@ -0,0 +1,591 @@
|
||||
# How to Write Tests for PhantomJS
|
||||
|
||||
PhantomJS's automated tests are `.js` files located in subdirectories
|
||||
of this directory. The test runner, [`run-tests.py`](run-tests.py),
|
||||
executes each as a PhantomJS controller script. (Not all
|
||||
subdirectories of this directory contain tests; the authoritative list
|
||||
of test subdirectories is in
|
||||
[the `TESTS` variable in `run-tests.py`](run-tests.py#L26).)
|
||||
|
||||
In addition to all of the usual PhantomJS API, these scripts have
|
||||
access to a special testing API, loosely based on
|
||||
[W3C testharness.js](https://github.com/w3c/testharness.js) and
|
||||
defined in [`testharness.js`](testharness.js) in this directory. They
|
||||
also have access to HTTP and HTTPS servers on `localhost`, which serve
|
||||
the files in the [`www`](www) directory.
|
||||
|
||||
## The Structure of Test Scripts
|
||||
|
||||
Test scripts are divided into _subtests_. There are two kinds of
|
||||
subtest: synchronous and asynchronous. The only difference is that a
|
||||
synchronous subtest consists of a single JavaScript function (plus
|
||||
anything it calls) and is considered to be complete when that function
|
||||
returns. An asynchronous subtest, however, consists of many
|
||||
JavaScript functions; these functions are referred to as _steps_. One
|
||||
step will be invoked to start the subtest, and the others are called
|
||||
in response to events. Eventually one of the steps will indicate that
|
||||
the subtest is complete. (The single function used for a synchronous
|
||||
subtest is also referred to as a step, when the difference doesn't
|
||||
matter.)
|
||||
|
||||
All of the code in a test script should be part of a subtest, or part
|
||||
of a setup function (see below). You may define helper functions at
|
||||
top level, so long as they are only ever _called_ from subtests. You
|
||||
may also initialize global variables at top level if this
|
||||
initialization cannot possibly fail, e.g. with constant data or with
|
||||
`require` calls for core PhantomJS modules.
|
||||
|
||||
The testing API is visible to a test script as a collection of global
|
||||
functions and variables, documented below.
|
||||
|
||||
A subtest is considered to have failed if any of its steps throws a
|
||||
JavaScript exception, if an `unreached_func` is called, if the
|
||||
per-test timeout expires, or if `done` is called before all of its
|
||||
steps have run. It is considered to succeed if `done` is called
|
||||
(explicitly or implicitly) after all of its steps have run to
|
||||
completion. Normally, you should use the assertion functions to detect
|
||||
failure conditions; these ensure that clear diagnostic information is
|
||||
printed when a test fails.
|
||||
|
||||
Subtests are executed strictly in the order they appear in the file,
|
||||
even if some of them are synchronous and some are asynchronous. The
|
||||
order of steps *within* an asynchronous subtest, however, may be
|
||||
unpredictable. Also, subtests do not begin to execute until after all
|
||||
top-level code in the file has been evaluated.
|
||||
|
||||
Some anomalous conditions are reported not as a failure, but as an
|
||||
"error". For instance, if PhantomJS crashes during a test run, or if
|
||||
an exception is thrown from outside a step, that is an error, and the
|
||||
entire test will be abandoned.
|
||||
|
||||
**WARNING:** The harness will become confused if any function passed
|
||||
as the `func` argument to `test`, `async_test`, `generate_tests`,
|
||||
`Test.step`, `Test.step_func`, `Test.step_func_done`, or
|
||||
`Test.add_cleanup` has a name that ends with `_step`.
|
||||
|
||||
### Accessing the HTTP and HTTPS Test Servers
|
||||
|
||||
The global variables `TEST_HTTP_BASE` and `TEST_HTTPS_BASE` are the
|
||||
base URLs of the test HTTP and HTTPS servers, respectively. Their
|
||||
values are guaranteed to match the regex `/https?:\/\/localhost:[0-9]+\//`,
|
||||
but the port number is dynamically assigned for each test run, so you
|
||||
must not hardwire it.
|
||||
|
||||
### Synchronous Subtests
|
||||
|
||||
There are two functions for defining synchronous subtests.
|
||||
|
||||
* `test(func, name, properties)`
|
||||
|
||||
Run `func` as a subtest; the subtest is considered to be complete as
|
||||
soon as it returns. `name` is an optional descriptive name for the
|
||||
subtest. `func` will be called with no arguments, and `this` set to
|
||||
a `Test` object (see below). `properties` is an optional object
|
||||
containing properties to apply to the test. Currently there are
|
||||
three meaningful properties; any other keys in the `properties`
|
||||
object are ignored:
|
||||
|
||||
* `timeout` - Maximum amount of time the subtest is allowed to run, in
|
||||
milliseconds. If the timeout expires, the subtest will be
|
||||
considered to have failed.
|
||||
|
||||
* `expected_fail`: If truthy, this subtest is expected to fail. It will
|
||||
still be run, but a failure will be considered "normal" and the
|
||||
overall test will be reported as successful. Conversely, if the
|
||||
subtest *succeeds* that is considered "abnormal" and the overall
|
||||
test will be reported as failing.
|
||||
|
||||
* `skip`: If truthy, this subtest will not be run at all, will be
|
||||
reported as "skipped" rather than "succeeded" or "failed", and
|
||||
will not affect the overall outcome of the test. Use `skip` only
|
||||
when `expected_fail` will not do—for instance, when a test
|
||||
provokes a PhantomJS crash (there currently being no way to label
|
||||
a crash as "expected").
|
||||
|
||||
`test` returns the same `Test` object that is available as `this`
|
||||
within `func`.
|
||||
|
||||
* `generate_tests(func, args, properties)`
|
||||
|
||||
Define a group of synchronous subtests, each of which will call
|
||||
`func`, but with different arguments. This is easiest to explain by
|
||||
example:
|
||||
|
||||
generate_tests(assert_equals, [
|
||||
["Sum one and one", 1 + 1, 2],
|
||||
["Sum one and zero", 1 + 0, 1]
|
||||
]);
|
||||
|
||||
... is equivalent to ...
|
||||
|
||||
test(function() {assert_equals(1+1, 2)}, "Sum one and one");
|
||||
test(function() {assert_equals(1+0, 1)}, "Sum one and zero");
|
||||
|
||||
Of course `func` may be as complicated as you like, and there is no
|
||||
limit either to the number of arguments passed to each subtest, or
|
||||
to the number of subtests.
|
||||
|
||||
The `properties` argument may be a single properties object, which
|
||||
will be applied uniformly to all the subtests, or an array of the
|
||||
same length as `args`, containing appropriate property objects for
|
||||
each subtest.
|
||||
|
||||
`generate_tests` returns no value.
|
||||
|
||||
### Asynchronous Subtests
|
||||
|
||||
An asynchronous subtest consists of one or more _step_ functions, and
|
||||
unlike a synchronous subtest, it is not considered to be complete until
|
||||
the `done` method is called on its `Test` object. When this happens,
|
||||
if any of the step functions have not been executed, the subtest is a
|
||||
failure.
|
||||
|
||||
Asynchronous subtests are defined with the `async_test` function, which
|
||||
is almost the same as `test`:
|
||||
|
||||
* `async_test(func, name, properties)`
|
||||
|
||||
Define an asynchronous subtest. The arguments and their
|
||||
interpretation are the same as for `test`, except that `func` is
|
||||
optional, and the subtest is *not* considered to be complete after
|
||||
`func` returns; `func` (if present) is only the first step of the
|
||||
subtest. Additional steps may be defined, either within `func` or
|
||||
outside the call to `async_test`, by use of methods on the `Test`
|
||||
object that is returned (and available as `this` within `func`).
|
||||
|
||||
Normally, an asynchronous subtest's first step will set up whatever
|
||||
is being tested, and define the remainder of the steps, which will
|
||||
be run in response to events.
|
||||
|
||||
### Test Object Methods
|
||||
|
||||
These methods are provided by the `Test` object which is returned by
|
||||
`test` and `async_test`, and available as `this` within step
|
||||
functions.
|
||||
|
||||
* `Test.step(func[, this_obj, ...])`
|
||||
|
||||
Queue one step of a subtest. `func` will eventually be called, with
|
||||
`this` set to `this_obj`, or (if `this_obj` is null or absent) to
|
||||
the `Test` object. Any further arguments will be passed down to
|
||||
`func`. `func` will _not_ be called if a previous step has failed.
|
||||
|
||||
Do not use this function to define steps that should run in response
|
||||
to event callbacks; only steps that should be automatically run by
|
||||
the test harness.
|
||||
|
||||
The object returned by this function is private. Please let us know
|
||||
if you think you need to use it.
|
||||
|
||||
* `Test.done()`
|
||||
|
||||
Indicate that this subtest is complete. One, and only one, step of
|
||||
an asynchronous subtest must call this function, or the subtest will
|
||||
never complete (and eventually it will time out).
|
||||
|
||||
If an asynchronous subtest has several steps, but not all of them
|
||||
have run when `done` is called, the subtest is considered to have
|
||||
failed.
|
||||
|
||||
* `Test.step_func(func[, this_obj])`
|
||||
|
||||
Register `func` as a step that will *not* be run automatically by
|
||||
the test harness. Instead, the function *returned* by this function
|
||||
(the "callback") will run `func`'s step when it is called.
|
||||
(`func`'s step must still somehow get run before `done` is called,
|
||||
or the subtest will be considered to have failed.)
|
||||
|
||||
`this_obj` will be supplied as `this` to `func`; if omitted, it
|
||||
defaults to the `Test` object. Further arguments are ignored.
|
||||
However, `func` will receive all of the arguments passed to the
|
||||
callback, and the callback will return whatever `func` returns.
|
||||
|
||||
This is the normal way to register a step that should run in
|
||||
response to an event. For instance, here is a minimal test of a
|
||||
page load:
|
||||
|
||||
async_test(function () {
|
||||
var p = require('webpage').create();
|
||||
p.open(TEST_HTTP_BASE + 'hello.html',
|
||||
this.step_func(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
this.done();
|
||||
}));
|
||||
});
|
||||
|
||||
This also serves to illustrate why asynchronous subtests may be
|
||||
necessary: this subtest is not complete when its first step returns,
|
||||
only when the `onLoadFinished` event fires.
|
||||
|
||||
* `Test.step_func_done([func[, this_obj]])`
|
||||
|
||||
Same as `Test.step_func`, but the callback additionally calls `done`
|
||||
after `func` returns. `func` may be omitted, in which case the
|
||||
callback just calls `done`.
|
||||
|
||||
The example above can be shortened to
|
||||
|
||||
async_test(function () {
|
||||
var p = require('webpage').create();
|
||||
p.open(TEST_HTTP_BASE + 'hello.html',
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
}));
|
||||
});
|
||||
|
||||
* `Test.unreached_func([description])`
|
||||
|
||||
Returns a function that, if called, will call
|
||||
`assert_unreached(description)` inside a step. Use this to set
|
||||
event handlers for events that should _not_ happen. You need to use
|
||||
this method instead of `step_func(function () { assert_unreached(); })`
|
||||
so the step is properly marked as expected _not_ to run; otherwise
|
||||
the test will fail whether or not the event happens.
|
||||
|
||||
A slightly more thorough test of a page load might read
|
||||
|
||||
async_test(function () {
|
||||
var p = require('webpage').create();
|
||||
p.onResourceError = this.unreached_func("onResourceError");
|
||||
p.open(TEST_HTTP_BASE + 'hello.html',
|
||||
this.step_func_done(function (status) {
|
||||
assert_equals(status, 'success');
|
||||
}));
|
||||
});
|
||||
|
||||
* `Test.add_cleanup(func)`
|
||||
|
||||
Register `func` to be called (with no arguments, and `this` set to
|
||||
the `Test` object) when `done` is called, whether or not the subtest
|
||||
has failed. Use this to deallocate persistent resources or undo
|
||||
changes to global state. For example, a subtest that uses a scratch
|
||||
file might read
|
||||
|
||||
test(function () {
|
||||
var fs = require('fs');
|
||||
var f = fs.open('scratch_file', 'w');
|
||||
this.add_cleanup(function () {
|
||||
f.close();
|
||||
fs.remove('scratch_file');
|
||||
});
|
||||
|
||||
// ... more test logic here ...
|
||||
});
|
||||
|
||||
If the step function had simply deleted the file at its end, the
|
||||
file would only get deleted when the test succeeds. This example
|
||||
could be rewritten using `try ... finally ...`, but that will not
|
||||
work for asynchronous tests.
|
||||
|
||||
* `Test.fail(message)`
|
||||
|
||||
Explicitly mark this subtest has having failed, with failure message
|
||||
`message`. You should not normally need to call this function yourself.
|
||||
|
||||
* `Test.force_timeout()`
|
||||
|
||||
Explicitly mark this subtest as having failed because its timeout has
|
||||
expired. You should not normally need to call this function yourself.
|
||||
|
||||
### Test Script-Wide Setup
|
||||
|
||||
All of the subtests of a test script are normally run, even if one of
|
||||
them fails. Complex tests may involve complex initialization actions
|
||||
that may fail, in which case the entire test script should be aborted.
|
||||
There is also a small amount of harness-wide configuration that is
|
||||
possible. Both these tasks are handled by the global function
|
||||
`setup`.
|
||||
|
||||
* `setup([func], [properties])`
|
||||
|
||||
One may specify either `func` or `properties` or both, but if both
|
||||
are specified, `func` must be first.
|
||||
|
||||
`func` is called immediately, with no arguments. If it throws an
|
||||
exception, the entire test script is considered to have failed and
|
||||
none of the subtests are run.
|
||||
|
||||
`properties` is an object containing one or more of the following
|
||||
keys:
|
||||
|
||||
* `explicit_done`: Wait for the global function `done` (not to be
|
||||
confused with `Test.done` to be called, before declaring the test
|
||||
script complete.
|
||||
|
||||
* `allow_uncaught_exception`: Don't treat an uncaught exception from
|
||||
non-test code as an error. (Exceptions thrown out of test steps
|
||||
are still errors.)
|
||||
|
||||
* `timeout`: Overall timeout for the test script, in milliseconds.
|
||||
The default is five seconds. Note that `run-tests.py` imposes a
|
||||
"backstop" timeout itself; if you raise this timeout you may also
|
||||
need to raise that one.
|
||||
|
||||
* `test_timeout`: Default timeout for individual subtests. This may
|
||||
be overridden by the `timeout` property on a specific subtest.
|
||||
The default is not to have a timeout for individual subtests.
|
||||
|
||||
|
||||
### Assertions
|
||||
|
||||
Whenever possible, use these functions to detect failure conditions.
|
||||
All of them either throw a JavaScript exception (when the test fails)
|
||||
or return no value (when the test succeeds). All take one or more
|
||||
values to be tested, and an optional _description_. If present, the
|
||||
description should be a string to be printed to clarify why the test
|
||||
has failed. (The assertions all go to some length to print out values
|
||||
that were not as expected in a clear format, so descriptions will
|
||||
often not be necessary.)
|
||||
|
||||
* `assert_is_true(value[, description])`
|
||||
|
||||
`value` must be strictly equal to `true`.
|
||||
|
||||
* `assert_is_false(value[, description])`
|
||||
|
||||
`value` must be strictly equal to `false`.
|
||||
|
||||
* `assert_equals(actual, expected[, description])`
|
||||
|
||||
`actual` and `expected` must be shallowly, strictly equal. The
|
||||
criterion used is `===` with the following exceptions:
|
||||
|
||||
* If `x === y`, but one of them is `+0` and the other is `-0`, they
|
||||
are *not* considered equal.
|
||||
|
||||
* If `x !== y`, but one of the following cases holds, they *are*
|
||||
considered equal:
|
||||
* both are `NaN`
|
||||
* both are `Date` objects and `x.getTime() === y.getTime()`
|
||||
* both are `RegExp` objects and `x.toString() === y.toString()`
|
||||
|
||||
* `assert_not_equals(actual, expected[, description])`
|
||||
|
||||
`actual` and `expected` must *not* be shallowly, strictly equal,
|
||||
using the same criterion as `assert_equals`.
|
||||
|
||||
* `assert_deep_equals(actual, expected[, description])`
|
||||
|
||||
If `actual` and `expected` are not objects, or if they are
|
||||
`Date` or `RegExp` objects, this is the same as `assert_equals`.
|
||||
|
||||
Objects that are not `Date` or `RegExp` must have the same set of
|
||||
own-properties (including non-enumerable own-properties), and each
|
||||
pair of values for with each own-property must be `deep_equals`,
|
||||
recursively. Prototype chains are ignored. Back-references are
|
||||
detected and ignored; they will not cause an infinite recursion.
|
||||
|
||||
* `assert_approx_equals(actual, expected, epsilon[, description])`
|
||||
|
||||
The absolute value of the difference between `actual` and `expected`
|
||||
must be no greater than `epsilon`. All three arguments must be
|
||||
primitive numbers.
|
||||
|
||||
* `assert_less_than(actual, expected[, description])`
|
||||
* `assert_less_than_equal(actual, expected[, description])`
|
||||
* `assert_greater_than(actual, expected[, description])`
|
||||
* `assert_greater_than_equal(actual, expected[, description])`
|
||||
|
||||
`actual` and `expected` must be primitive numbers, and `actual` must
|
||||
be, respectively: less than, less than or equal to, greater than,
|
||||
greater than or equal to `expected`.
|
||||
|
||||
* `assert_in_array(value, array[, description])`
|
||||
|
||||
`array` must contain `value` according to `Array.indexOf`.
|
||||
|
||||
* `assert_regexp_match(string, regexp[, description])`
|
||||
|
||||
The regular expression `regexp` must match the string `string`,
|
||||
according to `RegExp.test()`.
|
||||
|
||||
* `assert_regexp_not_match(string, regexp[, description])`
|
||||
|
||||
The regular expression `regexp` must *not* match the string `string`,
|
||||
according to `RegExp.test()`.
|
||||
|
||||
* `assert_type_of(object, type[, description])`
|
||||
|
||||
`typeof object` must be strictly equal to `type`.
|
||||
|
||||
* `assert_instance_of(object, type[, description])`
|
||||
|
||||
`object instanceof type` must be true.
|
||||
|
||||
* `assert_class_string(object, expected[, description])`
|
||||
|
||||
`object` must have the class string `expected`. The class string is
|
||||
the second word in the string returned by `Object.prototype.toString`:
|
||||
for instance, `({}).toString.call([])` returns `[object Array]`, so
|
||||
`[]`'s class string is `Array`.
|
||||
|
||||
* `assert_own_property(object, name[, description])`
|
||||
|
||||
`object` must have an own-property named `name`.
|
||||
|
||||
* `assert_inherits(object, name[, description])`
|
||||
|
||||
`object` must inherit a property named `name`; that is,
|
||||
`name in object` must be true but `object.hasOwnProperty(name)`
|
||||
must be false.
|
||||
|
||||
* `assert_no_property(object, name[, description])`
|
||||
|
||||
`object` must neither have nor inherit a property named `name`.
|
||||
|
||||
* `assert_readonly(object, name[, description])`
|
||||
|
||||
`object` must have an own-property named `name` which is marked
|
||||
read-only (according to `Object.getOwnPropertyDescriptor`).
|
||||
|
||||
* `assert_throws(code, func[, description])`
|
||||
|
||||
`func` must throw an exception described by `code`. `func` is
|
||||
called with no arguments and no `this` (you can supply arguments
|
||||
using `bind`). `code` can take one of two forms. If it is a
|
||||
string, the thrown exception must either stringify to that string,
|
||||
or it must be a DOMException whose `name` property is that string.
|
||||
Otherwise, `code` must be an object with one or more of the
|
||||
properties `code`, `name`, and `message`; whichever properties are
|
||||
present must be `===` to the corresponding properties of the
|
||||
exception. As a special case, if `message` is present in the
|
||||
`code` object but *not* on the exception object, and the exception
|
||||
stringifies to the same string as `message`, that's also considered
|
||||
valid.
|
||||
|
||||
`assert_throws` cannot be used to catch the exception thrown by any
|
||||
of the other `assert_*` functions when they fail. (You might be
|
||||
looking for the `expected_fail` property on a subtest.)
|
||||
|
||||
* `assert_unreached([description])`
|
||||
|
||||
Control flow must not reach the point where this assertion appears.
|
||||
(In other words, this assertion fails unconditionally.)
|
||||
|
||||
## Test Annotations
|
||||
|
||||
Some tests need to be run in a special way. You can indicate this to
|
||||
the test runner with _annotations_. Annotations are lines in the test
|
||||
script that begin with the three characters '`//!`'. They must be all
|
||||
together at the very top of the script; `run-tests.py` stops parsing
|
||||
at the first line that does _not_ begin with the annotation marker.
|
||||
|
||||
Annotation lines are split into _tokens_ in a shell-like fashion,
|
||||
which means they are normally separated by whitespace, but you can use
|
||||
backslashes or quotes to put whitespace inside a token. Backslashes
|
||||
are significant inside double quotes, but not inside single quotes.
|
||||
There can be any number of tokens on a line. Everything following an
|
||||
unquoted, un-backslashed `#` is discarded. (The exact algorithm is
|
||||
[`shlex.split`](https://docs.python.org/2/library/shlex.html), in
|
||||
`comments=True`, `posix=True` mode.)
|
||||
|
||||
These are the recognized tokens:
|
||||
|
||||
* `no-harness`: Run this test script directly; the testing API
|
||||
described above will not be available. This is necessary to
|
||||
test PhantomJS features that `testharness.js` reserves for its
|
||||
own use, such as `phantom.onError` and `phantom.exit`. No-harness
|
||||
tests will usually also be output-expectations tests (see below)
|
||||
but this is not required.
|
||||
|
||||
* `no-snakeoil`: Do not instruct PhantomJS to accept the self-signed
|
||||
certificate presented by the HTTPS test server.
|
||||
|
||||
* `timeout:` The next token on the line must be a positive
|
||||
floating-point number. `run-tests.py` will kill the PhantomJS
|
||||
process, and consider the test to have failed, if it runs for longer
|
||||
than that many seconds. The default timeout is seven seconds.
|
||||
|
||||
This timeout is separate from the per-subtest and global timeouts
|
||||
enforced by the testing API. It is intended as a backstop against
|
||||
bugs which cause PhantomJS to stop executing the controller script.
|
||||
(In no-harness mode, it's the only timeout, unless you implement
|
||||
your own.)
|
||||
|
||||
* `phantomjs:` All subsequent tokens on the line will be passed as
|
||||
command-line arguments to PhantomJS, before the controller script.
|
||||
Note that `run-tests.py` sets several PhantomJS command line options
|
||||
itself; you must take care not to do something contradictory.
|
||||
|
||||
* `script:` All subsequent tokens on the line will be passed as
|
||||
command-line arguments to the *controller script*; that is, they
|
||||
will be available in
|
||||
[`system.args`](http://phantomjs.org/api/system/property/args.html).
|
||||
Note that your controller script will only be `system.args[0]` if
|
||||
you are using no-harness mode, and that `run-tests.py` may pass
|
||||
additional script arguments of its own.
|
||||
|
||||
* `stdin:` All subsequent tokens on the line will be concatenated
|
||||
(separated by a single space) and fed to PhantomJS's standard input,
|
||||
with a trailing newline. If this token is used more than once,
|
||||
that produces several lines of input. If this token is not used at
|
||||
all, standard input will read as empty.
|
||||
|
||||
## Output-Expectations Tests
|
||||
|
||||
Normally, `run-tests.py` expects each test to produce parseable output
|
||||
in the [TAP](http://testanything.org/tap-specification.html) format.
|
||||
This is too inflexible for testing things like `system.stdout.write`,
|
||||
so there is also a mode in which you specify exactly what output the
|
||||
test should produce, with additional annotations. Output-expectations
|
||||
tests are not *required* to be no-harness tests, but the only reason
|
||||
to use this mode for harness tests would be to test the harness
|
||||
itself, and it's not sophisticated enough for that.
|
||||
|
||||
Using any of the following annotations makes a test an
|
||||
output-expectations test:
|
||||
|
||||
* `expect-exit:` The next token on the line must be an integer. If it
|
||||
is nonnegative, the PhantomJS process is expected to exit with that
|
||||
exit code. If it is negative, the process is expected to be
|
||||
terminated by the signal whose number is the absolute value of the
|
||||
token. (For instance, `expect-exit: -15` for a test that is
|
||||
expected to hit the backstop timeout.)
|
||||
|
||||
* `expect-stdout:` All subsequent tokens on the line are concatenated,
|
||||
with spaces in between, and a newline is appeneded. The PhantomJS
|
||||
process is expected to emit that text, verbatim, on its standard
|
||||
output. If used more than once, that produces multiple lines of
|
||||
expected output.
|
||||
|
||||
* `expect-stderr:` Same as `expect-stdout`, but the output is expected
|
||||
to appear on standard error.
|
||||
|
||||
* `expect-exit-fails`, `expect-stdout-fails`, `expect-stderr-fails`:
|
||||
The corresponding test (of the exit code, stdout, or stderr) is
|
||||
expected to fail.
|
||||
|
||||
If some but not all of these annotations are used in a test, the
|
||||
omitted ones default to exit code 0 (success) and no output on their
|
||||
respective streams.
|
||||
|
||||
## Test Server Modules
|
||||
|
||||
The HTTP and HTTPS servers exposed to the test suite serve the static
|
||||
files in the `www` subdirectory with URLs corresponding to their paths
|
||||
relative to that directory. If you need more complicated server
|
||||
behavior than that, you can write custom Python code that executes
|
||||
when the server receives a request. Any `.py` file below the `www`
|
||||
directory will be invoked to provide the response for that path
|
||||
*without* the `.py` suffix. (For instance, `www/echo.py` provides
|
||||
responses for `TEST_HTTP_BASE + 'echo'`.) Such files must define a
|
||||
top-level function named `handle_request`. This function receives a
|
||||
single argument, which is an instance of a subclass of
|
||||
[`BaseHTTPServer.BaseHTTPRequestHandler`](https://docs.python.org/2/library/basehttpserver.html#BaseHTTPServer.BaseHTTPRequestHandler).
|
||||
The request headers and body (if any) may be retrieved from this
|
||||
object. The function must use the `send_response`, `send_header`, and
|
||||
`end_headers` methods of this object to generate HTTP response
|
||||
headers, and then return a *file-like object* (**not** a string)
|
||||
containing the response body. The function is responsible for
|
||||
generating appropriate `Content-Type` and `Content-Length` headers;
|
||||
the server framework does not do this automatically.
|
||||
|
||||
Test server modules cannot directly cause a test to fail; the server
|
||||
does not know which test is responsible for any given request. If
|
||||
there is something wrong with a request, generate an HTTP error
|
||||
response; then write your test to fail if it receives an error
|
||||
response.
|
||||
|
||||
Python exceptions thrown by test server modules are treated as
|
||||
failures *of the testsuite*, but they are all attributed to a virtual
|
||||
"HTTP server errors" test.
|
Loading…
Reference in New Issue
Block a user