Commit 3bf3df38 3bf3df38dab43ca3092f61617fd2c25ed218bb8a by Laurent Jouanneau

Merge branch 'master' into geckofix1

2 parents 90646423 c878b2b3
......@@ -3,15 +3,18 @@ branches:
- "master"
before_install:
- if [[ $ENGINE == 'phantomjs' ]]; then export ENGINE_DOWNLOAD='http://phantomjs.googlecode.com/files'; fi
- if [[ $ENGINE == 'slimerjs' ]]; then export ENGINE_DOWNLOAD='http://download.slimerjs.org/v0.8'; fi
- echo "Installing $ENGINE $ENGINE_VERSION"
- wget $(echo $ENGINE_DOWNLOAD)/$(echo $ENGINE)-$(echo $ENGINE_VERSION)-linux-x86_64.tar.bz2 --output-document=engine.tar.bz2
- echo "Installing $ENGINE $ENGINE_VERSION from $ENGINE_ARCHIVE_URL"
- wget $ENGINE_ARCHIVE_URL --output-document=engine.tar.bz2
- mkdir engine && tar --strip-components=1 -xvf engine.tar.bz2 -C engine
- if [[ $ENGINE == 'phantomjs' ]]; then ls -la engine/bin/phantomjs && engine/bin/phantomjs --version; fi
- if [[ $ENGINE == 'slimerjs' ]]; then ls -la engine/slimerjs && engine/slimerjs --version; fi
- if [[ $ENGINE == 'phantomjs' ]]; then
ENGINE_EXECUTABLE="engine/bin/phantomjs";
elif [[ $ENGINE == 'slimerjs' ]]; then
ENGINE_EXECUTABLE="engine/slimerjs";
else
echo "Unsupported engine $ENGINE";
fi
- ls -la $ENGINE_EXECUTABLE && $ENGINE_EXECUTABLE --version;
- export ENGINE_EXECUTABLE="$ENGINE_EXECUTABLE $ENGINE_FLAGS"
install:
- sudo apt-get install -qq mono-devel mono-mcs
......@@ -20,18 +23,32 @@ before_script:
- "npm install -g jshint@2.0.1"
script:
- make test
- make test-dotNET
- "make $MAKE_TEST_COMMAND"
env:
matrix:
- ENGINE="phantomjs" ENGINE_VERSION="1.8.2"
- ENGINE="phantomjs" ENGINE_VERSION="1.9.0"
- ENGINE="phantomjs" ENGINE_VERSION="1.9.1"
- ENGINE="phantomjs" ENGINE_VERSION="1.9.2"
global:
- PHANTOMJS_EXECUTABLE="engine/bin/phantomjs --local-to-remote-url-access=yes --ignore-ssl-errors=yes"
- SLIMERJS_EXECUTABLE="engine/slimerjs --local-to-remote-url-access=yes --ignore-ssl-errors=yes"
- ENGINE_FLAGS="--local-to-remote-url-access=yes --ignore-ssl-errors=yes"
matrix:
- ENGINE="phantomjs" ENGINE_VERSION="1.8.2" MAKE_TEST_COMMAND="test-dotNET"
ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.8.2-linux-x86_64.tar.bz2"
- ENGINE="phantomjs" ENGINE_VERSION="1.8.2" MAKE_TEST_COMMAND="test"
ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.8.2-linux-x86_64.tar.bz2"
- ENGINE="phantomjs" ENGINE_VERSION="1.9.0" MAKE_TEST_COMMAND="test-dotNET"
ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.9.0-linux-x86_64.tar.bz2"
- ENGINE="phantomjs" ENGINE_VERSION="1.9.0" MAKE_TEST_COMMAND="test"
ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.9.0-linux-x86_64.tar.bz2"
- ENGINE="phantomjs" ENGINE_VERSION="1.9.1" MAKE_TEST_COMMAND="test-dotNET"
ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.9.1-linux-x86_64.tar.bz2"
- ENGINE="phantomjs" ENGINE_VERSION="1.9.1" MAKE_TEST_COMMAND="test"
ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.9.1-linux-x86_64.tar.bz2"
- ENGINE="phantomjs" ENGINE_VERSION="1.9.2" MAKE_TEST_COMMAND="test-dotNET"
ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.9.2-linux-x86_64.tar.bz2"
- ENGINE="phantomjs" ENGINE_VERSION="1.9.2" MAKE_TEST_COMMAND="test"
ENGINE_ARCHIVE_URL="https://phantomjs.googlecode.com/files/phantomjs-1.9.2-linux-x86_64.tar.bz2"
- ENGINE="slimerjs" ENGINE_VERSION="0.8.4" MAKE_TEST_COMMAND="test-dotNET"
ENGINE_ARCHIVE_URL="http://download.slimerjs.org/v0.8/0.8.4/slimerjs-0.8.4-linux-x86_64.tar.bz2"
- ENGINE="slimerjs" ENGINE_VERSION="0.8.4" MAKE_TEST_COMMAND="test"
ENGINE_ARCHIVE_URL="http://download.slimerjs.org/v0.8/0.8.4/slimerjs-0.8.4-linux-x86_64.tar.bz2"
notifications:
irc:
......
......@@ -19,20 +19,20 @@ and [SlimerJS](http://slimerjs.org/). It eases the process of defining a full na
scenario and provides useful high-level functions, methods & syntaxic sugar for doing common
tasks such as:
- defining & ordering [navigation steps](http://casperjs.org/quickstart.html)
- [filling forms](http://casperjs.org/api.html#casper.fill)
- [clicking links](http://casperjs.org/api.html#casper.click)
- [capturing screenshots](http://casperjs.org/api.html#casper.captureSelector) of a page (or an area)
- [making assertions on remote DOM](http://casperjs.org/api.html#tester)
- [logging](http://casperjs.org/logging.html) & [events](http://casperjs.org/events-filters.html)
- [downloading base64](http://casperjs.org/api.html#casper.download) encoded resources, even binary ones
- defining & ordering [navigation steps](http://docs.casperjs.org/en/latest/quickstart.html)
- [filling forms](http://docs.casperjs.org/en/latest/modules/casper.html#fill)
- [clicking links](http://docs.casperjs.org/en/latest/modules/casper.html#click)
- [capturing screenshots](http://docs.casperjs.org/en/latest/modules/casper.html#captureselector) of a page (or an area)
- [making assertions on remote DOM](http://docs.casperjs.org/en/latest/modules/tester.html)
- [logging](http://docs.casperjs.org/en/latest/logging.html) & [events](http://docs.casperjs.org/en/latest/events-filters.html)
- [downloading](http://docs.casperjs.org/en/latest/modules/casper.html#download) resources, even binary ones
- catching errors and react accordingly
- writing [functional test suites](http://casperjs.org/testing.html), exporting results as JUnit XML (xUnit)
- writing [functional test suites](http://docs.casperjs.org/en/latest/testing.html), exporting results as JUnit XML (xUnit)
Browse the [sample examples repository](https://github.com/n1k0/casperjs/tree/master/samples).
Don't hesitate to pull request for any cool example of yours as well!
**Read the [full documentation](http://casperjs.org/) on casperjs dedicated website.**
**Read the [full documentation](http://docs.casperjs.org/) on casperjs documentation website.**
Subscribe to the [project mailing-list](https://groups.google.com/forum/#!forum/casperjs)
......@@ -45,7 +45,7 @@ First [install CasperJS](http://docs.casperjs.org/en/latest/installation.html),
Sample test to see if some dropdown can be opened:
```javascript
casper.test.begin('a twitter bootsrap dropdown can be opened', 2, function(test) {
casper.test.begin('a twitter bootstrap dropdown can be opened', 2, function(test) {
casper.start('http://twitter.github.com/bootstrap/javascript.html#dropdowns', function() {
test.assertExists('#navbar-example');
this.click('#dropdowns .nav-pills .dropdown:last-of-type a.dropdown-toggle');
......@@ -64,7 +64,7 @@ Run the script:
##Support
Need help with getting CasperJS up and running? Got a time-consuming problem you want to get solved quickly?
Need help with getting CasperJS up and running? Got a time-consuming problem you want to get solved quickly?
Get <a href="http://codersclan.net/?repo_id=32">CasperJS support on CodersClan.</a>
......
......@@ -89,7 +89,8 @@ ENGINE_NATIVE_ARGS = []
ENGINE_EXECUTABLE = ''
CASPER_ARGS = []
CASPER_PATH = os.path.abspath(os.path.join(os.path.dirname(resolve(__file__)), '..'))
CASPER_PATH = os.path.abspath(os.path.join(os.path.dirname(resolve(__file__)),
'..'))
SYS_ARGS = sys.argv[1:]
# retrieve the engine name
......@@ -98,23 +99,30 @@ for arg in SYS_ARGS:
ENGINE = arg[9:].lower()
break
if ENGINE in SUPPORTED_ENGINES:
ENGINE_NATIVE_ARGS = SUPPORTED_ENGINES[ENGINE]['native_args']
ENGINE_EXECUTABLE = os.environ.get(SUPPORTED_ENGINES[ENGINE]['env_varname'], SUPPORTED_ENGINES[ENGINE]['default_exec'])
else:
if not ENGINE in SUPPORTED_ENGINES:
print('Bad engine name. Only phantomjs and slimerjs are supported')
sys.exit(1)
ENGINE_NATIVE_ARGS = SUPPORTED_ENGINES[ENGINE]['native_args']
ENGINE_EXECUTABLE = os.environ.get(SUPPORTED_ENGINES[ENGINE]['env_varname'],
SUPPORTED_ENGINES[ENGINE]['default_exec'])
def extract_arg_name(arg):
"parse out any option name"
try:
return arg.split('=', 1)[0].replace('--', '', 1)
except IndexError:
return arg
for arg in SYS_ARGS:
arg_name = extract_arg_name(arg)
found = False
for native in ENGINE_NATIVE_ARGS:
if arg.startswith('--%s' % native):
if arg_name == native:
ENGINE_ARGS.append(arg)
found = True
if not found:
if arg.startswith('--engine=') == False:
CASPER_ARGS.append(arg)
if not found and arg_name != 'engine':
CASPER_ARGS.append(arg)
CASPER_COMMAND = ENGINE_EXECUTABLE.split(' ')
CASPER_COMMAND.extend(ENGINE_ARGS)
......
......@@ -6,7 +6,11 @@
The ``clientutils`` module
==========================
Casper ships with a few client-side utilities which are injected in the remote DOM environment, and accessible from there through the ``__utils__`` object instance of the ``ClientUtils`` class from the ``clientutils`` module.
Casper ships with a few client-side utilities which are injected in the remote DOM environment, and accessible from there through the ``__utils__`` object instance of the ``ClientUtils`` class from the ``clientutils`` module::
casper.evaluate(function() {
__utils__.echo("Hello World!");
});
.. note::
......@@ -21,7 +25,7 @@ Bookmarklet
A bookmarklet is also available to help injecting Casper's client-side utilities in the DOM of your favorite browser.
Just drag the link above onto your favorites toobar; when clicking, a ``__utils__`` object will be available within the console of your browser:
Just drag the following link onto your favorites toobar; when clicking it, a ``__utils__`` object will be available within the console of your browser:
.. raw:: html
......@@ -292,6 +296,19 @@ To get the form values::
__utils__.getFormValues('form#login'); // {username: 'foo', password: 'bar'}
.. index:: log
``log()``
-------------------------------------------------------------------------------
**Signature:** ``log(String message[, String level])``
Logs a message with an optional level. Will format the message a way CasperJS will be able to log phantomjs side. Default level is ``debug``::
casper.start('http://foo.ner/').thenEvaluate(function() {
__utils__.log("We've got a problem on client side", 'error');
});
``mouseEvent()``
-------------------------------------------------------------------------------
......
......@@ -160,9 +160,9 @@ Asserts that a given subject is `falsy <http://11heavens.com/falsy-and-truthy-in
``assertField()``
-------------------------------------------------------------------------------
**Signature:** ``assertField(String inputName, String expected[, String message, Object options])``
**Signature:** ``assertField(String|Object input, String expected[, String message, Object options])``
Asserts that a given form field has the provided value::
Asserts that a given form field has the provided value with input name or :ref:`selector expression <selectors>`::
casper.test.begin('assertField() tests', 1, function(test) {
casper.start('http://www.google.fr/', function() {
......@@ -173,6 +173,16 @@ Asserts that a given form field has the provided value::
});
});
// Path usage with type 'css'
casper.test.begin('assertField() tests', 1, function(test) {
casper.start('http://www.google.fr/', function() {
this.fill('form[name="gs"]', { q: 'plop' }, false);
test.assertField({type: 'css', path: '.q.foo'}, 'plop');
}).run(function() {
test.done();
});
});
.. versionadded:: 1.0
This also works with any input type: ``select``, ``textarea``, etc.
......@@ -182,6 +192,63 @@ This also works with any input type: ``select``, ``textarea``, etc.
The `options` parameter allows to set the options to use with
:ref:`ClientUtils#getFieldValue() <clientutils_getfieldvalue>`.
`input` parameter introspects whether or not a `type` key is passed in with `xpath` or `css` and a property `path` specified along with it.
``assertFieldName()``
-------------------------------------------------------------------------------
**Signature:** ``assertFieldName(String inputName, String expected[, String message, Object options])``
.. versionadded:: 1.1-beta3
Asserts that a given form field has the provided value::
casper.test.begin('assertField() tests', 1, function(test) {
casper.start('http://www.google.fr/', function() {
this.fill('form[name="gs"]', { q: 'plop' }, false);
test.assertField('q', 'plop', 'did not plop', {formSelector: 'plopper'});
}).run(function() {
test.done();
});
});
``assertFieldCSS()``
-------------------------------------------------------------------------------
**Signature:** ``assertFieldCSS(String cssSelector, String expected, String message)``
.. versionadded:: 1.1
Asserts that a given form field has the provided value given a CSS selector::
casper.test.begin('assertField() tests', 1, function(test) {
casper.start('http://www.google.fr/', function() {
this.fill('form[name="gs"]', { q: 'plop' }, false);
test.assertField('q', 'plop', 'did not plop', 'input.plop');
}).run(function() {
test.done();
});
});
``assertFieldXPath()``
-------------------------------------------------------------------------------
**Signature:** ``assertFieldXPath(String xpathSelector, String expected, String message)``
.. versionadded:: 1.1
Asserts that a given form field has the provided value given a XPath selector::
casper.test.begin('assertField() tests', 1, function(test) {
casper.start('http://www.google.fr/', function() {
this.fill('form[name="gs"]', { q: 'plop' }, false);
test.assertField('q', 'plop', 'did not plop', '/html/body/form[0]/input[1]');
}).run(function() {
test.done();
});
});
.. index:: HTTP, HTTP Status Code
``assertHttpStatus()``
......@@ -455,12 +522,12 @@ Asserts that the provided input is of the given type::
.. versionadded:: 1.1
Asserts that the provided input is of the given constructor::
function Cow() {
this.moo = function moo() {
return 'moo!';
};
}
}
casper.test.begin('assertInstanceOf() tests', 2, function suite(test) {
var daisy = new Cow();
test.assertInstanceOf(daisy, Cow, "Ok, daisy is a cow.");
......@@ -716,6 +783,16 @@ That will give something like this:
In c.js:0
assertEquals: Subject equals the expected value
.. note::
In CasperJS 1.1, you can store test successes by recording them listening to the tester ``pass`` event::
var failures = [];
casper.test.on("fail", function(failure) {
failures.push(failure);
});
``getPasses()``
-------------------------------------------------------------------------------
......@@ -723,6 +800,8 @@ That will give something like this:
.. versionadded:: 1.0
.. deprecated:: 1.1
Retrieves a report for successful test cases in the current test suite::
casper.test.assertEquals(true, true);
......@@ -751,6 +830,16 @@ That will give something like this::
}
PASS 1 tests executed, 1 passed, 0 failed.
.. note::
In CasperJS 1.1, you can store test successes by recording them listening to the tester ``pass`` event::
var successes = [];
casper.test.on("pass", function(success) {
successes.push(success);
});
``info()``
-------------------------------------------------------------------------------
......
......@@ -159,6 +159,15 @@ Options are prefixed with a double-dash (``--``):
- ``--xunit=<filename>`` will export test suite results in a :ref:`XUnit XML file <xunit_report>`
- ``--direct`` will print :doc:`log messages <logging>` directly to the console
- ``--log-level=<logLevel>`` sets the logging level (see the :doc:`related section <logging>`)
- ``--auto-exit=no`` prevents the test runner to exit when all the tests have been executed; this usually allows performing supplementary operations, though implies to exit casper manually listening to the ``exit`` tester event::
// $ casperjs test --auto-exit=no
casper.test.on("exit", function() {
someTediousAsyncProcess(function() {
casper.exit();
});
});
.. versionadded:: 1.0
......
......@@ -94,11 +94,13 @@ CasperJS 1.1 now internally uses PhantomJS' native ``require()`` function, but i
As of 1.1, CasperJS now uses native PhantomJS' ``require()`` function which doesn't support the ``__file__`` builtin variable within custom modules like 1.0 allowed.
``Tester#getFailures()`` and ``Tester#getSuccesses()`` methods removed
----------------------------------------------------------------------
``Tester#getFailures()`` and ``Tester#getPasses()`` methods removed
-------------------------------------------------------------------
These two methods have been removed from the :doc:`Tester <../modules/tester>` API.
You can retrieve test failure and success records by simply accessing `tester.currentSuite.failures` and `tester.currentSuite.passes` instead.
Step and run completion callbacks don't throw anymore
-----------------------------------------------------
......
......@@ -130,19 +130,24 @@
/**
* Checks if a given DOM element is visible in remove page.
*
* @param Object element DOM element
* @param Object element DOM element
* @return Boolean
*/
this.elementVisible = function elementVisible(elem) {
var style;
try {
var comp = window.getComputedStyle(elem, null);
return comp.visibility !== 'hidden' &&
comp.display !== 'none' &&
elem.offsetHeight > 0 &&
elem.offsetWidth > 0;
style = window.getComputedStyle(elem, null);
} catch (e) {
return false;
}
var hidden = style.visibility === 'hidden' || style.display === 'none';
if (hidden) {
return false;
}
if (style.display === "inline") {
return true;
}
return elem.clientHeight > 0 && elem.clientWidth > 0;
}
/**
......@@ -290,7 +295,7 @@
*
* @param String selector CSS3 selector
* @param HTMLElement|null scope Element to search child elements within
* @return NodeList|undefined
* @return Array|undefined
*/
this.findAll = function findAll(selector, scope) {
scope = scope || this.options.scope;
......@@ -299,7 +304,7 @@
if (pSelector.type === 'xpath') {
return this.getElementsByXPath(pSelector.path, scope);
} else {
return scope.querySelectorAll(pSelector.path);
return Array.prototype.slice.call(scope.querySelectorAll(pSelector.path));
}
} catch (e) {
this.log('findAll(): invalid selector provided "' + selector + '":' + e, "error");
......@@ -560,10 +565,19 @@
}
}
var formSelector = '';
if (options && options.formSelector) {
if (options.formSelector) {
formSelector = options.formSelector + ' ';
}
var inputs = this.findAll(formSelector + '[name="' + inputName + '"]');
if (options.inputSelector) {
inputs = inputs.concat(this.findAll(options.inputSelector));
}
if (options.inputXPath) {
inputs = inputs.concat(this.getElementsByXPath(options.inputXPath));
}
switch (inputs.length) {
case 0: return undefined;
case 1: return getSingleValue(inputs[0]);
......
......@@ -449,6 +449,21 @@ Tester.prototype.assertEvalEqual = function assertEvalEquals(fn, expected, messa
});
};
function baseFieldAssert(inputName, expected, actual, message) {
/*jshint validthis:true */
"use strict";
return this.assert(utils.equals(actual, expected), message, {
type: 'assertField',
standard: f('"%s" input field has the value "%s"', inputName, expected),
values: {
inputName: inputName,
actual: actual,
expected: expected
}
});
}
/**
* Asserts that the provided assertion fails (used for internal testing).
*
......@@ -473,26 +488,67 @@ Tester.prototype.assertFail = function assertFail(fn, message) {
/**
* Asserts that a given input field has the provided value.
*
* @param String inputName The name attribute of the input element
* @param String expected The expected value of the input element
* @param String message Test description
* @param Object options ClientUtils#getFieldValue options (optional)
* @return Object An assertion result object
*/
Tester.prototype.assertField = function assertField(inputName, expected, message, options) {
"use strict";
* @param String|Object input The name attribute of the input element
* or an object with the selector
* @param String expected The expected value of the input element
* @param String message Test description
* @param Object options ClientUtils#getFieldValue options (optional)
* @return Object An assertion result object
*/
Tester.prototype.assertField = function assertField(input, expected, message, options) {
"use strict";
if (typeof input === 'object') {
switch (input.type) {
case 'css':
return this.assertFieldCSS(input.path, expected, message);
case 'xpath':
return this.assertFieldXPath(input.path, expected, message);
default:
throw new CasperError('Invalid regexp.');
// no default
}
}
var actual = this.casper.evaluate(function(inputName, options) {
return __utils__.getFieldValue(inputName, options);
}, inputName, options);
return this.assert(utils.equals(actual, expected), message, {
type: 'assertField',
standard: f('"%s" input field has the value "%s"', inputName, expected),
values: {
inputName: inputName,
actual: actual,
expected: expected
}
});
}, input, options);
return baseFieldAssert.call(this, input, expected, actual, message);
};
/**
* Asserts that a given input field by CSS selector has the provided value.
*
* @param Object cssSelector The CSS selector to use for the assert field value
* @param String expected The expected value of the input element
* @param String message Test description
* @return Object An assertion result object
*/
Tester.prototype.assertFieldCSS = function assertFieldCSS(cssSelector, expected, message) {
"use strict";
var actual = this.casper.evaluate(function(inputName, cssSelector) {
return __utils__.getFieldValue(inputName, {inputSelector: cssSelector});
}, null, cssSelector);
return baseFieldAssert.call(this, null, expected, actual, message);
};
/**
* Asserts that a given input field by XPath selector has the provided value.
*
* @param Object xPathSelector The XPath selector to use for the assert field value
* @param String expected The expected value of the input element
* @param String message Test description
* @return Object An assertion result object
*/
Tester.prototype.assertFieldXPath = function assertFieldXPath(xPathSelector, expected, message) {
"use strict";
var actual = this.casper.evaluate(function(inputName, xPathSelector) {
return __utils__.getFieldValue(inputName, {inputXPath: xPathSelector});
}, null, xPathSelector);
return baseFieldAssert.call(this, null, expected, actual, message);
};
/**
......@@ -1426,11 +1482,13 @@ Tester.prototype.renderFailureDetails = function renderFailureDetails() {
/**
* Render tests results, an optionally exit phantomjs.
*
* @param Boolean exit
* @param Boolean exit Exit casper after results have been rendered?
* @param Number status Exit status code (default: 0)
* @param String save Optional path to file where to save the results log
*/
Tester.prototype.renderResults = function renderResults(exit, status, save) {
"use strict";
/*jshint maxstatements:20*/
/*jshint maxstatements:25*/
save = save || this.options.save;
var exitStatus = 0,
failed = this.suiteResults.countFailed(),
......@@ -1468,6 +1526,7 @@ Tester.prototype.renderResults = function renderResults(exit, status, save) {
this.saveResults(save);
}
if (exit === true) {
this.emit("exit");
this.casper.exit(status ? ~~status : exitStatus);
}
};
......
#!/bin/bash
#
# A little helper script to build the RPM.
if [ ! -f "../package.json" ]; then
echo "Execute rpm build script in rpm directory"
exit 1
fi
name="casperjs"
name=${name%.spec}
topdir=$(mktemp -d)
# Get version from package.json
version=$(grep '"version"' ../package.json | sed 's/.*"\(.*\)": "\(.*\)".*/\2/' | sed 's/[-]//')
builddir=${TMPDIR:-/tmp}/${name}-${version}
sourcedir="${topdir}/SOURCES"
buildroot="${topdir}/BUILD/${name}-${version}-root"
mkdir -p ${topdir}/{RPMS,SRPMS,SOURCES,BUILD}
mkdir -p ${buildroot} ${builddir}
echo "=> Copying sources..."
( cd .. && tar cf - ./[A-Z]* ./package.json ./bin ./samples ./tests ./modules | tar xf - -C ${builddir} )
echo "=> Creating source tarball under ${sourcedir}..."
( cd ${builddir}/.. && tar zcf ${sourcedir}/${name}-${version}.tar.gz ${name}-${version} )
echo "=> Building RPM..."
rpm=$(rpmbuild --define "_topdir ${topdir}" --define "_version ${version}" --buildroot ${buildroot} --clean -bb ${name}.spec | awk '/\/RPMS\// { print $2; }')
if [ $? -ne 0 ]; then
echo "Failed to build RPM package."
exit 1
fi
echo ${rpm}
cp ${rpm} ${TMPDIR:-/tmp}/
rm -fr ${topdir}
echo "RPM package build finished."
echo ${TMPDIR:-/tmp}/${rpm##*/}
%define name casperjs
%if "%{_version}"
%define version %{_version}
%else
%define version 1.0
%endif
%define release 1
%define prefix /usr
%define mybuilddir %{_builddir}/%{name}-%{version}-root
Summary: open source navigation scripting & testing utility written in Javascript
Name: %{name}
Version: %{version}
License: BSD
Release: %{release}
Packager: Jan Schaumann <jschauma@etsy.com>
Group: Utilities/Misc
Source: %{name}-%{version}.tar.gz
BuildRoot: /tmp/%{name}-%{version}-root
Requires: phantomjs
%description
CasperJS is an open source navigation scripting & testing utility written
in Javascript and based on PhantomJS. It eases the process of defining a
full navigation scenario and provides useful high-level functions, methods
& syntactic sugar for doing common tasks
%prep
%setup -q
%install
mkdir -p %{mybuilddir}%{prefix}/bin
mkdir -p %{mybuilddir}%{prefix}/share/%{name}/bin
mkdir -p %{mybuilddir}%{prefix}/share/%{name}/modules
mkdir -p %{mybuilddir}%{prefix}/share/%{name}/samples
mkdir -p %{mybuilddir}%{prefix}/share/%{name}/tests
cp bin/%{name} %{mybuilddir}%{prefix}/share/%{name}/bin/
ln -s %{prefix}/share/%{name}/bin/%{name} %{mybuilddir}%{prefix}/bin/%{name}
cp bin/bootstrap.js %{mybuilddir}%{prefix}/share/%{name}/bin/
# Yes, this tool needs this file in the 'bin' directory.
cp bin/usage.txt %{mybuilddir}%{prefix}/share/%{name}/bin/
cp CHANGELOG.md %{mybuilddir}%{prefix}/share/%{name}/
cp CONTRIBUTING.md %{mybuilddir}%{prefix}/share/%{name}/
cp CONTRIBUTORS.md %{mybuilddir}%{prefix}/share/%{name}/
cp LICENSE.md %{mybuilddir}%{prefix}/share/%{name}/
cp README.md %{mybuilddir}%{prefix}/share/%{name}/
cp package.json %{mybuilddir}%{prefix}/share/%{name}/
cp -R modules/* %{mybuilddir}%{prefix}/share/%{name}/modules/
cp -R samples/* %{mybuilddir}%{prefix}/share/%{name}/samples/
cp -R tests/* %{mybuilddir}%{prefix}/share/%{name}/tests/
%files
%defattr(0444,root,root)
%attr(0555,root,root)%{prefix}/bin/%{name}
%attr(0555,root,root)%{prefix}/share/%{name}/bin/%{name}
%attr(0555,root,root)%{prefix}/share/%{name}/bin/bootstrap.js
%{prefix}/share/%{name}/bin/usage.txt
%{prefix}/share/%{name}/CHANGELOG.md
%{prefix}/share/%{name}/CONTRIBUTING.md
%{prefix}/share/%{name}/CONTRIBUTORS.md
%{prefix}/share/%{name}/LICENSE.md
%{prefix}/share/%{name}/README.md
%{prefix}/share/%{name}/package.json
%{prefix}/share/%{name}/modules/*
%{prefix}/share/%{name}/samples/*
%{prefix}/share/%{name}/tests/*
%changelog
* Fri Nov 15 2013 Yasuo Ohgaki <yohgaki@ohgaki.net>
- update spec for master and other branches
* Mon Dec 24 2012 Nicolas Perriault <nicolas@perriault.net>
- removed 'injector.js' module
* Mon Dec 10 2012 Jan Schaumann <jschauma@etsy.com>
- include 'tests'
* Mon Nov 26 2012 Jan Schaumann <jschauma@etsy.com>
- first rpm version
......@@ -9,12 +9,13 @@ import unittest
TEST_ROOT = os.path.abspath(os.path.dirname(__file__))
CASPERJS_ROOT = os.path.abspath(os.path.join(TEST_ROOT, '..', '..'))
CASPER_EXEC = os.path.join(CASPERJS_ROOT, 'bin', 'casperjs')
PHANTOMJS_EXEC = os.environ['PHANTOMJS_EXECUTABLE']
ENGINE_EXEC = os.environ.get('ENGINE_EXECUTABLE',
os.environ.get('PHANTOMJS_EXECUTABLE',
"phantomjs"))
# make it to an absolute path, because some test change the working directory
# and relative path to phantomjs would be invalid
if not os.path.isabs(PHANTOMJS_EXEC):
os.environ['PHANTOMJS_EXECUTABLE'] = os.path.join(CASPERJS_ROOT,
PHANTOMJS_EXEC)
if not os.path.isabs(ENGINE_EXEC):
os.environ['ENGINE_EXECUTABLE'] = os.path.join(CASPERJS_ROOT, ENGINE_EXEC)
class TimeoutException(Exception):
pass
......@@ -316,6 +317,21 @@ class TestCommandOutputTest(CasperExecTestBase):
], failing=True)
@timeout(20)
def test_exit_test(self):
script_path = os.path.join(TEST_ROOT, 'tester', 'exit.js')
self.assertCommandOutputContains('test ' + script_path, [
script_path,
'# sample',
'PASS Subject is strictly true',
'PASS 1 test executed',
'1 passed',
'0 failed',
'0 dubious',
'0 skipped.',
'exited'
])
@timeout(20)
def test_skipped_test(self):
script_path = os.path.join(TEST_ROOT, 'tester', 'skipped.js')
self.assertCommandOutputContains('test ' + script_path, [
......
casper.test.on("exit", function() {
console.log("exited");
})
casper.test.begin("sample", function(test) {
test.assert(true);
test.done();
});
......@@ -59,8 +59,9 @@ function checkArgs() {
casper.options.colorizerType = cls;
casper.colorizer = colorizer.create(cls);
}
casper.test.options.concise = casper.cli.get('concise') || false;
casper.test.options.failFast = casper.cli.get('fail-fast') || false;
casper.test.options.concise = casper.cli.get('concise', false);
casper.test.options.failFast = casper.cli.get('fail-fast', false);
casper.test.options.autoExit = casper.cli.get('auto-exit') !== "no";
// test paths are passed as args
if (casper.cli.args.length) {
......@@ -99,7 +100,7 @@ function initRunner() {
// test suites completion listener
casper.test.on('tests.complete', function() {
this.renderResults(true, undefined, casper.cli.get('xunit') || undefined);
this.renderResults(this.options.autoExit, undefined, casper.cli.get('xunit') || undefined);
if (this.options.failFast && this.testResults.failures.length > 0) {
casper.warn('Test suite failed fast, all tests may not have been executed.');
}
......
......@@ -6,7 +6,7 @@
</head>
<body>
<form action="result.html" enctype="multipart/form-data">
<input type="text" name="email" placeholder="email">
<input type="text" name="email" placeholder="email" id="email">
<input type="password" name="password" placeholder="password">
<input type="text" name="language" placeholder="language">
<input type="whatever" name="strange">
......
......@@ -14,4 +14,4 @@
<img src="images/phantom.png" id="img2">
<img src="images/phantom.png" id="img3" style="visibility:hidden">
</body>
</html>
\ No newline at end of file
</html>
......
......@@ -51,17 +51,17 @@ casper.test.begin('ClientUtils.exists() tests', 5, function(test) {
casper.test.begin('ClientUtils.findAll() tests', 7, function(test) {
var clientutils = require('clientutils').create();
fakeDocument('<ul class="foo"><li>bar</li><li>baz</li></ul>');
test.assertType(clientutils.findAll('li'), 'nodelist',
test.assertType(clientutils.findAll('li'), 'array',
'ClientUtils.findAll() can find matching DOM elements');
test.assertEquals(clientutils.findAll('li').length, 2,
'ClientUtils.findAll() can find matching DOM elements');
test.assertType(clientutils.findAll('ol'), 'nodelist',
test.assertType(clientutils.findAll('ol'), 'array',
'ClientUtils.findAll() can find matching DOM elements');
test.assertEquals(clientutils.findAll('ol').length, 0,
'ClientUtils.findAll() can find matching DOM elements');
// scoped
var scope = clientutils.findOne('ul');
test.assertType(clientutils.findAll('li', scope), 'nodelist',
test.assertType(clientutils.findAll('li', scope), 'array',
'ClientUtils.findAll() can find matching DOM elements within a given scope');
test.assertEquals(clientutils.findAll('li', scope).length, 2,
'ClientUtils.findAll() can find matching DOM elements within a given scope');
......
......@@ -129,8 +129,94 @@ casper.test.begin('Tester.assertField(): nonexistent fields', 2, function(test)
test.assertFail(function() {
test.assertField('nonexistent', '');
}, 'Tester.assertField() only checks for existing fields');
}).run(function() {
test.done();
});
});
casper.test.begin('Tester.assertField(): CSS selectors', 1, function(test) {
casper.start('tests/site/form.html', function() {
this.fill('form[action="result.html"]', {
'email': 'albert@camus.com'
});
test.assertField({
type: 'css',
path: '#email'
},
'albert@camus.com',
'Tester.assertField() works as expected with CSS selectors'
);
}).run(function() {
test.done();
});
casper.run(function() {
});
casper.test.begin('Tester.assertField(): XPath selectors', 1, function(test) {
casper.start('tests/site/form.html', function() {
this.fill('form[action="result.html"]', {
'email': 'albert@camus.com'
});
test.assertField({
type: 'xpath',
path: '/html/body/form[1]/input[1]'
},
'albert@camus.com',
'Tester.assertField() works as expected with XPath selectors'
);
}).run(function() {
test.done();
})
});
});
casper.test.begin('Tester.assertField(): invalid selectors', 1, function(test) {
casper.start('tests/site/form.html', function() {
this.fill('form[action="result.html"]', {
'email': 'albert@camus.com'
});
test.assertRaise(function() {
test.assertField({
type: 'albert'
},
'albert@camus.com',
'Tester.assertField() works as expected with XPath selectors'
);
}, [], 'should throw an error for an invalid selector');
}).run(function() {
test.done();
});
});
casper.test.begin('Tester.assertFieldCSS(): CSS selectors', 1, function(test) {
casper.start('tests/site/form.html', function() {
this.fill('form[action="result.html"]', {
'email': 'albert@camus.com'
});
test.assertFieldCSS(
'#email',
'albert@camus.com',
'Tester.assertFieldCSS() works as expected with CSS selectors'
);
}).run(function() {
test.done();
});
});
casper.test.begin('Tester.assertFieldXPath(): XPath selectors', 1, function(test) {
casper.start('tests/site/form.html', function() {
this.fill('form[action="result.html"]', {
'email': 'albert@camus.com'
});
test.assertFieldXPath(
'/html/body/form[1]/input[1]',
'albert@camus.com',
'Tester.assertFieldXPath() works as expected with XPath selectors'
);
}).run(function() {
test.done();
});
});
......