1
1
mirror of https://github.com/ariya/phantomjs.git synced 2024-09-11 12:55:33 +03:00

Test directory reorganization.

The `certs`, `fixtures`, `node_modules`, and `www` directories, and
`testharness.js`, are moved into a new `lib` directory to reduce
clutter; the long-term plan is that all other subdirectories will
contain tests.  (Right now, we still have `ghostdriver-tests` as an
exception.)  Adjust `writing-tests.md`, `run-tests.py`, `testharness.js`,
and a couple of tests accordingly.

Also fix a bug in `run-tests.py` where ERROR conditions that happened
before the first test were not being reported accurately.
This commit is contained in:
Zack Weinberg 2015-12-22 12:30:58 -05:00
parent 482b91d124
commit c5db190f39
52 changed files with 54 additions and 31 deletions

View File

@ -1461,6 +1461,13 @@ if (args.test_script === "") {
// process_command_line has already issued an error message. // process_command_line has already issued an error message.
phantom.exit(2); phantom.exit(2);
} else { } else {
// run-tests.py sets this environment variable to the root of the
// test directory.
expose(sys.env['TEST_DIR'], 'TEST_DIR');
// The JS modules in TEST_DIR/lib/node_modules are always available.
require.paths.push(fs.join(sys.env['TEST_DIR'], 'lib', 'node_modules'));
// Reset the library paths for injectJs and require to the // Reset the library paths for injectJs and require to the
// directory containing the test script, so relative imports work // directory containing the test script, so relative imports work
// as expected. Unfortunately, phantom.libraryPath is not a // as expected. Unfortunately, phantom.libraryPath is not a

View File

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

View File

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -1,9 +1,7 @@
var content; var content;
setup(function () { setup(function () {
var fs = require('fs'); var fs = require('fs');
// libraryPath is test/module/webpage content = fs.read(fs.join(TEST_DIR, "lib/www/hello.html"));
content = fs.read(fs.join(phantom.libraryPath,
"../../www/hello.html"));
}); });
// XFAIL: This feature had to be backed out for breaking WebSockets. // XFAIL: This feature had to be backed out for breaking WebSockets.

View File

@ -1,4 +1,5 @@
var webpage = require('webpage'); var webpage = require('webpage');
var fs = require('fs');
test(function () { test(function () {
var page = webpage.create(); var page = webpage.create();
@ -66,6 +67,9 @@ test(function () {
assert_is_true(page.evaluate(function() { return window.caughtError; })); assert_is_true(page.evaluate(function() { return window.caughtError; }));
}, "should not report errors that were caught"); }, "should not report errors that were caught");
var helperBase = "error-helper.js";
var helperFile = fs.join(TEST_DIR, "lib", "fixtures", helperBase);
function check_stack(message, stack) { function check_stack(message, stack) {
assert_equals(message, assert_equals(message,
"ReferenceError: Can't find variable: referenceError"); "ReferenceError: Can't find variable: referenceError");
@ -85,11 +89,8 @@ function check_stack(message, stack) {
} }
} }
var helperBase = "error-helper.js";
var helperFile = "../../fixtures/" + helperBase;
assert_is_true(phantom.injectJs(helperFile));
test(function () { test(function () {
assert_is_true(phantom.injectJs(helperFile));
try { try {
ErrorHelper.foo(); ErrorHelper.foo();
} catch (e) { } catch (e) {
@ -99,7 +100,6 @@ test(function () {
async_test(function () { async_test(function () {
var page = webpage.create(); var page = webpage.create();
page.libraryPath = phantom.libraryPath;
assert_is_true(page.injectJs(helperFile)); assert_is_true(page.injectJs(helperFile));
page.onError = this.step_func_done(check_stack); page.onError = this.step_func_done(check_stack);

View File

@ -6,7 +6,7 @@ var webpage = require('webpage');
function test_template(parent, action) { function test_template(parent, action) {
var page; var page;
var url = TEST_HTTP_BASE + var url = TEST_HTTP_BASE +
"/regression/pjs-13551/" + parent + "-parent.html"; "regression/pjs-13551/" + parent + "-parent.html";
var s_callback0, s_callback1, s_callback2; var s_callback0, s_callback1, s_callback2;
function callback0 (n) { function callback0 (n) {

View File

@ -109,8 +109,8 @@ CIPHERLIST_2_7_9 = (
'!eNULL:!MD5:!DSS:!RC4' '!eNULL:!MD5:!DSS:!RC4'
) )
def wrap_socket_ssl(sock, base_path): def wrap_socket_ssl(sock, base_path):
crtfile = os.path.join(base_path, 'certs/https-snakeoil.crt') crtfile = os.path.join(base_path, 'lib/certs/https-snakeoil.crt')
keyfile = os.path.join(base_path, 'certs/https-snakeoil.key') keyfile = os.path.join(base_path, 'lib/certs/https-snakeoil.key')
try: try:
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
@ -367,7 +367,7 @@ class HTTPTestServer(object):
self.httpd = None self.httpd = None
self.httpsd = None self.httpsd = None
self.base_path = base_path self.base_path = base_path
self.www_path = os.path.join(base_path, 'www') self.www_path = os.path.join(base_path, 'lib/www')
self.signal_error = signal_error self.signal_error = signal_error
self.verbose = verbose self.verbose = verbose
@ -669,6 +669,13 @@ class TAPTestGroup(TestGroup):
self.add_skip(out[(i+1):], "All further output ignored") self.add_skip(out[(i+1):], "All further output ignored")
return return
if any(msg.startswith("ERROR:") for msg in messages):
self.add_error(messages, "Before tests")
messages = []
elif messages:
self.add_error(messages, "Stray diagnostic")
messages = []
prev_point = 0 prev_point = 0
for i in range(i+1, len(out)): for i in range(i+1, len(out)):
@ -743,8 +750,8 @@ class TAPTestGroup(TestGroup):
class TestRunner(object): class TestRunner(object):
def __init__(self, base_path, phantomjs_exe, options): def __init__(self, base_path, phantomjs_exe, options):
self.base_path = base_path self.base_path = base_path
self.cert_path = os.path.join(base_path, 'certs') self.cert_path = os.path.join(base_path, 'lib/certs')
self.harness = os.path.join(base_path, 'testharness.js') self.harness = os.path.join(base_path, 'lib/testharness.js')
self.phantomjs_exe = phantomjs_exe self.phantomjs_exe = phantomjs_exe
self.verbose = options.verbose self.verbose = options.verbose
self.debugger = options.debugger self.debugger = options.debugger
@ -960,6 +967,8 @@ class TestRunner(object):
def init(): def init():
base_path = os.path.normpath(os.path.dirname(os.path.abspath(__file__))) base_path = os.path.normpath(os.path.dirname(os.path.abspath(__file__)))
os.environ["TEST_DIR"] = base_path
phantomjs_exe = os.path.normpath(base_path + '/../bin/phantomjs') phantomjs_exe = os.path.normpath(base_path + '/../bin/phantomjs')
if sys.platform in ('win32', 'cygwin'): if sys.platform in ('win32', 'cygwin'):
phantomjs_exe += '.exe' phantomjs_exe += '.exe'
@ -1009,6 +1018,15 @@ def init():
# usually written, e.g. UTC+1 would be xxx-1:00. # usually written, e.g. UTC+1 would be xxx-1:00.
os.environ["TZ"] = "CIST-12:45:00" os.environ["TZ"] = "CIST-12:45:00"
# Run all the tests in the "C" locale. (A UTF-8-based locale
# which is thoroughly different from "C" would flush out more
# bugs, but we have no way of knowing if such a locale exists.)
for var in list(os.environ.keys()):
if var[:3] == 'LC_' or var[:4] == 'LANG':
del os.environ[var]
os.environ["LANG"] = "C"
return runner return runner
def main(): def main():

View File

@ -8,11 +8,11 @@ of test subdirectories is in
[the `TESTS` variable in `run-tests.py`](run-tests.py#L26).) [the `TESTS` variable in `run-tests.py`](run-tests.py#L26).)
In addition to all of the usual PhantomJS API, these scripts have In addition to all of the usual PhantomJS API, these scripts have
access to a special testing API, loosely based on access to a special testing API, loosely based on [W3C
[W3C testharness.js](https://github.com/w3c/testharness.js) and testharness.js](https://github.com/w3c/testharness.js) and defined
defined in [`testharness.js`](testharness.js) in this directory. They in [`lib/testharness.js`](lib/testharness.js). They also have
also have access to HTTP and HTTPS servers on `localhost`, which serve access to HTTP and HTTPS servers on `localhost`, which serve the
the files in the [`www`](www) directory. files in the [`lib/www`](lib/www) directory.
## The Structure of Test Scripts ## The Structure of Test Scripts
@ -561,20 +561,20 @@ respective streams.
## Test Server Modules ## Test Server Modules
The HTTP and HTTPS servers exposed to the test suite serve the static The HTTP and HTTPS servers exposed to the test suite serve the
files in the `www` subdirectory with URLs corresponding to their paths static files in the `lib/www` subdirectory, with URLs corresponding
relative to that directory. If you need more complicated server to their paths relative to that directory. If you need more
behavior than that, you can write custom Python code that executes complicated server behavior than that, you can write custom Python
when the server receives a request. Any `.py` file below the `www` code that executes when the server receives a request. Any `.py`
directory will be invoked to provide the response for that path file below `lib/www` will be invoked to provide the response for
*without* the `.py` suffix. (For instance, `www/echo.py` provides that path *without* the `.py` suffix. (For instance, `lib/www/echo.py`
responses for `TEST_HTTP_BASE + 'echo'`.) Such files must define a provides responses for `TEST_HTTP_BASE + 'echo'`.) Such files must
top-level function named `handle_request`. This function receives a define a top-level function named `handle_request`. This function
single argument, which is an instance of a subclass of receives a single argument, which is an instance of a subclass of
[`BaseHTTPServer.BaseHTTPRequestHandler`](https://docs.python.org/2/library/basehttpserver.html#BaseHTTPServer.BaseHTTPRequestHandler). [`BaseHTTPServer.BaseHTTPRequestHandler`](https://docs.python.org/2/library/basehttpserver.html#BaseHTTPServer.BaseHTTPRequestHandler).
The request headers and body (if any) may be retrieved from this The request headers and body (if any) may be retrieved from this
object. The function must use the `send_response`, `send_header`, and object. The function must use the `send_response`, `send_header`,
`end_headers` methods of this object to generate HTTP response and `end_headers` methods of this object to generate HTTP response
headers, and then return a *file-like object* (**not** a string) headers, and then return a *file-like object* (**not** a string)
containing the response body. The function is responsible for containing the response body. The function is responsible for
generating appropriate `Content-Type` and `Content-Length` headers; generating appropriate `Content-Type` and `Content-Length` headers;