Carahue
Carahue integrates Mocha, SpookyJS, and node-resemble for automated layout and render testing of web-based projects.
describe('checkout', function() {
page('signin', 'signin', function() {
this
.thenClick('.continue')
.thenScreenshot('errors', '.info-header');
});
});
See example for complete examples.
BDD
Carahue extends the Mocha BDD API with the page and beforePage helpers. These may be used in conjuntion with normal Mocha BDD directives but the Carahue context is only available within these methods.
#page(name, route[, options, callback])
Defines a Carahue test.
nameName of the testrouteRoute/URL to execute the test. This is relative toroutePrefix, if defined.optionsOptional hash object with additional test options.beforeCallback executed before the screenshot but after allbeforePageinstancesselectorSelector to use when taking screenshot. Defaults to the entire page.ignoreElements to ignore when taking screenshots. This value is applied in addition toglobalIgnoreafterCallback to execute after the initial screenshot.
callbackCallback to execute after the initial screenshot. May be used to define additional tests. Superceedsoptions.after.
See Context for discussion of the APIs available in the callback.
#beforePage(callback)
Called before each page test. Allows for test setup after the page has loaded, but before any screenshots have been taken.
See Context for discussion of the APIs available in the callback.
Context
All callbacks in page and beforePage methods are run in the Carahue context. By default the context includes
thenCheck(query, check)Applies/removes thecheckedattribute for elements matchingquerythenWaitForImages()Pauses test execution until all images in the DOM have been loadedthenScreenshot(name[, selector, ignore])Takes a screenshot of the current page statenameName of the screenshot. This will be used to generate the output file name.selectorOptional selector to limit the screenshot toignoreOptional list of elements to remove from the screenshot
Additionally the following Spooky methods are exposed on the context:
thenthenClickthenEvaluatethenOpenthenOpenAndEvaluate
Discussion of these methods and the call structures can be found in the Spooky documentation and the Casper documentation.
Extending Context
The execution context may be extended using the carahue.context.extend(object) method.
carahue.context.extend({
thenViewScreenshot: function(name) {
return this.thenScreenshot(name, '[data-layout-cid]');
}
});
Any fields exposed on the object parameter will be applied to future contexts.
Configuration
Configuration may be set via the carahue.config.extend(object) method, which will augment the config with the passed object value.
carahue.config.extend({
casper: {
viewportSize: {
width: platform === 'ipad' ? 1024 : 320,
height: platform === 'ipad' ? 768 : 480
}
}
});
Supported configuration values are:
child: PhantomJS runtime options.Defaults to
{
'ignore-ssl-errors': 'yes',
'web-security': 'false'
}
Is augmented rather than replaced when passed to extend.
casper: Casper runtime optionsDefaults to
{
'pageSettings': {
'userAgent': env.USER_AGENT
},
'logLevel': 'info',
'verbose': true
}
Is augmented rather than replaced when passed to extend.
screencapturePath: Path containing comparison screenshots.Defaults to
env.SCREENCAPTURE_PATHor cwdfailurePath: Path to output comparison images from failed tests to.Defaults to
env.FAILURE_PATHor "failure"routePrefix: Prefix to apply to non-qualified routes.Defaults to empty.
globalIgnore: Selector of elements that are always to be ignored when taking screenshots.
Troubleshooting / Best Practices
Mocking
The image comparison is fairly intollerant of changes to the output, by design. Where possible data should be mocked with static test data to reduce the number of changes due to content. When this is not possible, sections of consistently changing data should be ignored in the screenshot output to prevent false positive test failures.
Screenshot Images
If using git for version control for the project it's advisable to not include screenshot images for the tests in a location outside of the immediate github repository as this can create a lot of overhead as the tests change over time. Projects such as git-media may help resolve this issue.
Logging
The Casper runtime by default generates a significant amount of logging but the majority of this is not output unless the log and verbosity levels are set appropriately:
carahue.config.extend({
casper: {
logLevel: 'debug',
verbose: true
}
});
When set as above this will enable any casper specific logging instructions. console.log statemements run by the page itself will log regardless of the values set here.
Often times timeout or missing selector errors are seen due to unexpected state of the page when the test is run. This snippet may be used as a base to log the page's HTML struture if errors are seen.
beforePage(function() {
this
.thenEvaluate(function() {
console.log('This always logs ' + $('.foo').html());
})
.then(function() {
// This logs if casper flags are set
this.echo('test');
this.debugHTML();
});
});
Phantom Wrappers
Spooky utilizes a stdio-based IPC layer that relies on the Casper instance having access to both stdout and stdin.
Occasionally packages will attempt to override the phantomjs executable on the path and not implement forwarding for both streams. When this occurs generally the carahue tests will all hang. If this behavior is seen then verify that the phantomjs process on the path is the cannonical binary.
Testing
Carahue's internal tests may be run via
grunt test