Socket
Socket
Sign inDemoInstall

casperjs

Package Overview
Dependencies
Maintainers
3
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

casperjs - npm Package Compare versions

Comparing version 1.1.3 to 1.1.4

bin/casperjs.js

85

bin/bootstrap.js

@@ -45,36 +45,39 @@ /*!

// Common polyfills
void function() {
// cujos bind shim instead of MDN shim, see #1396
var isFunction = function(o) {
return 'function' === typeof o;
};
var bind;
var slice = [].slice;
var proto = Function.prototype;
var featureMap = {
'function-bind': 'bind'
};
function has(feature) {
var prop = featureMap[feature];
return isFunction(proto[prop]);
}
// check for missing features
if (!has('function-bind')) {
// adapted from Mozilla Developer Network example at
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
bind = function bind(obj) {
var args = slice.call(arguments, 1),
self = this,
nop = function() {
},
bound = function() {
return self.apply(this instanceof nop ? this : (obj || {}), args.concat(slice.call(arguments)));
// cujos bind shim instead of MDN shim, see #1396
var isFunction = function(o) {
return 'function' === typeof o;
};
var bind;
var slice = [].slice;
var proto = Function.prototype;
var featureMap = {
'function-bind': 'bind'
};
function has(feature) {
var prop = featureMap[feature];
return isFunction(proto[prop]);
}
// check for missing features
if (!has('function-bind')) {
// adapted from Mozilla Developer Network example at
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
bind = function bind(obj) {
var args = slice.call(arguments, 1),
self = this,
nop = function() {
},
bound = function() {
return self.apply(this instanceof nop ? this : (obj || {}), args.concat(slice.call(arguments)));
};
nop.prototype = this.prototype || {}; // Firefox cries sometimes if prototype is undefined
bound.prototype = new nop();
return bound;
};
nop.prototype = this.prototype || {}; // Firefox cries sometimes if prototype is undefined
bound.prototype = new nop();
return bound;
};
proto.bind = bind;
}
proto.bind = bind;
}
}();
// Custom base error

@@ -182,2 +185,9 @@ var CasperError = function CasperError(msg) {

}
if (phantom.casperEngine === 'slimerjs' && slimer.version.major === 0 && slimer.version.minor <= 9){
fs.size = function (filename){
var t = fs.read(filename, "rt");
return t.length;
};
}
return fs;

@@ -424,3 +434,14 @@ })(require('fs'));

}
require.paths.push(fs.pathJoin(require.paths[require.paths.length-1], 'node_modules'));
(function nodeModulePath(path) {
var resolved = false, prevBaseDir;
var baseDir = path;
do {
path = fs.pathJoin(baseDir, 'node_modules');
resolved = fs.exists(path) && fs.isDirectory(path);
prevBaseDir = baseDir;
baseDir = fs.absolute(fs.pathJoin(prevBaseDir, '..'));
} while (!resolved && baseDir !== '/' && prevBaseDir !== '/' && baseDir !== prevBaseDir);
if (!resolved) return;
require.paths.push(fs.pathJoin(prevBaseDir, 'node_modules'));
})(fs.pathJoin(fs.workingDirectory, phantom.casperScriptBaseDir));
}

@@ -427,0 +448,0 @@

@@ -1,2 +0,2 @@

Copyright (c) 2011-2015 Nicolas Perriault
Copyright (c) 2011-2017 Nicolas Perriault

@@ -3,0 +3,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

@@ -33,3 +33,3 @@ /*!

var require = patchRequire(require);
require = patchRequire(require);
var utils = require('utils');

@@ -36,0 +36,0 @@ var system = require('system');

@@ -58,3 +58,15 @@ /*!

var SUPPORTED_SELECTOR_TYPES = ['css', 'xpath'];
var XPATH_NAMESPACE = {
svg: 'http://www.w3.org/2000/svg',
mathml: 'http://www.w3.org/1998/Math/MathML'
};
function form_urlencoded(str) {
return encodeURIComponent(str)
.replace(/%20/g, '+')
.replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16);
});
}
// public members

@@ -155,3 +167,3 @@ this.options = options || {};

/**
* Checks if a given DOM element is visible in remove page.
* Checks if a given DOM element is visible in remote page.
*

@@ -162,16 +174,11 @@ * @param Object element DOM element

this.elementVisible = function elementVisible(elem) {
var style;
try {
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" || style.display === "inline-block") {
return true;
}
return elem.clientHeight > 0 && elem.clientWidth > 0;
var style;
try {
style = window.getComputedStyle(elem, null);
} catch (e) {
return false;
}
if(style.visibility === 'hidden' || style.display === 'none') return false;
var cr = elem.getBoundingClientRect();
return cr.width > 0 && cr.height > 0;
};

@@ -404,3 +411,28 @@

/**
* Convert a Xpath or a css Selector into absolute css3 selector
*
* @param String|Object selector CSS3/XPath selector
* @param HTMLElement|null scope Element to search child elements within
* @param String limit Parent limit NodeName
* @return String
*/
this.getCssSelector = function getCssSelector(selector, scope, limit) {
scope = scope || this.options.scope;
limit = limit || 'BODY';
var elem = (selector instanceof Node) ? selector : this.findOne(selector, scope);
if (!!elem && elem.nodeName !== "#document") {
var str = "";
while (elem.nodeName.toUpperCase() !== limit.toUpperCase()) {
str = "> " + elem.nodeName + ':nth-child(' + ([].indexOf.call(elem.parentNode.children, elem) + 1) + ') ' + str;
elem = elem.parentNode;
}
return str.substring(2);
}
return "";
};
/**
* Retrieves total document height.

@@ -549,3 +581,3 @@ * http://james.padolsey.com/javascript/get-document-height-cross-browser/

scope = scope || this.options.scope;
var a = document.evaluate(expression, scope, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var a = document.evaluate(expression, scope, this.xpathNamespaceResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (a.snapshotLength > 0) {

@@ -566,3 +598,3 @@ return a.snapshotItem(0);

var nodes = [];
var a = document.evaluate(expression, scope, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var a = document.evaluate(expression, scope, this.xpathNamespaceResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
for (var i = 0; i < a.snapshotLength; i++) {

@@ -575,2 +607,12 @@ nodes.push(a.snapshotItem(i));

/**
* Build the xpath namespace resolver to evaluate on document
*
* @param String prefix The namespace prefix
* @return the resolve namespace or null
*/
this.xpathNamespaceResolver = function xpathNamespaceResolver(prefix) {
return XPATH_NAMESPACE[prefix] || null;
};
/**
* Retrieves the value of an element

@@ -756,3 +798,3 @@ *

var elem = this.findOne(selector);
if (!elem || !this.elementVisible(elem)) {
if (!elem || ( !this.elementVisible(elem) && elem.nodeName.toUpperCase() !== "AREA")) {
this.log("mouseEvent(): Couldn't find any element matching '" +

@@ -873,3 +915,5 @@ selector + "' selector", "error");

* @param Boolean async Asynchroneous request? (default: false)
* @param Object settings Other settings when perform the ajax request
* @param Object settings Other settings when perform the ajax request like some undocumented
* Request Headers.
* WARNING: an invalid header here may make the request fail silently.
* @return String Response text.

@@ -881,4 +925,5 @@ */

dataList = [];
var CONTENT_TYPE_HEADER = "Content-Type";
method = method && method.toUpperCase() || "GET";
var contentType = settings && settings.contentType || "application/x-www-form-urlencoded";
var contentTypeValue = settings && settings.contentType || "application/x-www-form-urlencoded";
xhr.open(method, url, !!async);

@@ -889,2 +934,15 @@ this.log("sendAJAX(): Using HTTP method: '" + method + "'", "debug");

}
if (settings && settings.headers) {
for (var header in settings.headers) {
if (header === CONTENT_TYPE_HEADER) {
// this way Content-Type is correctly overriden,
// otherwise it is concatenated by xhr.setRequestHeader()
// see https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader
// If the header was already set, the value will be augmented.
contentTypeValue = settings.headers[header];
} else {
xhr.setRequestHeader(header, settings.headers[header]);
}
}
}
if (method === "POST") {

@@ -894,4 +952,4 @@ if (typeof data === "object") {

if (data.hasOwnProperty(k)) {
dataList.push(encodeURIComponent(k) + "=" +
encodeURIComponent(data[k].toString()));
dataList.push(form_urlencoded(k) + "=" +
form_urlencoded(data[k].toString()));
}

@@ -904,3 +962,3 @@ }

}
xhr.setRequestHeader("Content-Type", contentType);
xhr.setRequestHeader(CONTENT_TYPE_HEADER, contentTypeValue);
}

@@ -1041,2 +1099,14 @@ xhr.send(method === "POST" ? dataString : null);

/**
* set the default scope selector
*
* @param String selector CSS3 selector
* @return String
*/
this.setScope = function setScope(selector) {
var scope = !(this.options.scope instanceof HTMLElement) ? this.getCssSelector(this.options.scope) : "";
this.options.scope = (selector !== "") ? this.findOne(selector) : document;
return scope;
};
/**
* Checks if any element matching a given selector is visible in remote page.

@@ -1043,0 +1113,0 @@ *

@@ -33,3 +33,3 @@ /*!

var require = patchRequire(require);
require = patchRequire(require);
var fs = require('fs');

@@ -36,0 +36,0 @@ var utils = require('utils');

@@ -35,284 +35,401 @@ /*!

function EventEmitter() {
this._filters = {};
}
var EventEmitter = function EventEmitter() {
"use strict";
this._filters = {};
};
exports.EventEmitter = EventEmitter;
var defaultMaxListeners = 10;
// By default EventEmitters will print a warning if more than
// 10 listeners are added to it. This is a useful default which
// helps finding memory leaks.
//
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
var defaultMaxListeners = 10;
EventEmitter.prototype.setMaxListeners = function(n) {
if (!this._events) this._events = {};
this._maxListeners = n;
/**
* By default EventEmitters will print a warning if more than 10 listeners
* are added for a particular event. This is a useful default that helps finding memory leaks.
* Obviously, not all events should be limited to just 10 listeners.
* The emitter.setMaxListeners() method allows the limit to be modified for
* this specific EventEmitter instance. The value can be set to Infinity (or 0)
* to indicate an unlimited number of listeners.
*
* @param Integer nb Max Number of Listeners
*/
EventEmitter.prototype.setMaxListeners = function(nb) {
"use strict";
if (!this._events) {
this._events = {};
}
this._maxListeners = nb;
};
/**
* Synchronously calls each of the listeners registered for event,
* in the order they were registered, passing the supplied arguments to each.
* Returns true if event had listeners, false otherwise
*
* @param Array args... The rest of arguments passed to fn
* @return Boolean
* @throws {Error} If invokation failed.
*/
EventEmitter.prototype.emit = function emit() {
var type = arguments[0];
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events || !this._events.error ||
(isArray(this._events.error) && !this._events.error.length))
{
if (arguments[1] instanceof Error) {
throw arguments[1]; // Unhandled 'error' event
} else {
throw new CasperError("Uncaught, unspecified 'error' event.");
}
"use strict";
var type = arguments[0];
// If there is no 'error' event listener then throw.
if (type === 'error') {
if (!this._events || !this._events.error ||
isArray(this._events.error) && !this._events.error.length) {
if (arguments[1] instanceof Error) {
throw arguments[1]; // Unhandled 'error' event
} else {
throw new CasperError("Uncaught, unspecified 'error' event.");
}
}
}
}
if (!this._events) return false;
var handler = this._events[type];
if (!handler) return false;
if (typeof handler === 'function') {
try {
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
var l = arguments.length;
var args = new Array(l - 1);
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
handler.apply(this, args);
}
} catch (err) {
this.emit('event.error', err);
if (!this._events) {
return false;
}
return true;
var handler = this._events[type];
if (!handler) {
return false;
}
} else if (isArray(handler)) {
var l = arguments.length;
var args = new Array(l - 1);
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
if (typeof handler === 'function') {
try {
switch (arguments.length) {
// fast cases
case 1:
handler.call(this);
break;
case 2:
handler.call(this, arguments[1]);
break;
case 3:
handler.call(this, arguments[1], arguments[2]);
break;
// slower
default:
var l = arguments.length;
var args = new Array(l - 1);
for (var i = 1; i < l; i++) {
args[i - 1] = arguments[i];
}
handler.apply(this, args);
}
} catch (err) {
this.emit('event.error', err);
}
return true;
var listeners = handler.slice();
for (var i = 0, l = listeners.length; i < l; i++) {
listeners[i].apply(this, args);
} else if (isArray(handler)) {
var l = arguments.length;
var args = new Array(l - 1);
for (var i = 1; i < l; i++) {
args[i - 1] = arguments[i];
}
var listeners = handler.slice();
for (var i = 0, l = listeners.length; i < l; i++) {
listeners[i].apply(this, args);
}
return true;
} else {
return false;
}
return true;
} else {
return false;
}
};
// EventEmitter is defined in src/node_events.cc
// EventEmitter.prototype.emit() is also defined there.
/**
* Adds the listener function to the end of the listeners array for the specified event.
* No checks are made to see if the listener has already been added.
* Multiple calls passing the same combination of event and listener
* will result in the listener being added, and called, multiple times.
* EventEmitter is defined in src/node_events.cc
* EventEmitter.prototype.emit() is also defined there.
*
* @param String type An event name.
* @param function filterFn An options callback to apply on event.
* @return EventEmitter A reference to the EventEmitter so calls can be chained
* @throws {CasperError} If invokation failed.
*/
EventEmitter.prototype.addListener = function addListener(type, listener) {
if ('function' !== typeof listener) {
throw new CasperError('addListener only takes instances of Function');
}
"use strict";
if (typeof listener !== 'function') {
throw new CasperError('addListener only takes instances of Function');
}
if (!this._events) this._events = {};
if (!this._events) {
this._events = {};
}
// To avoid recursion in the case that type == "newListeners"! Before
// adding it to the listeners, first emit "newListeners".
this.emit('newListener', type, listener);
// To avoid recursion in the case that type == "newListeners"! Before
// adding it to the listeners, first emit "newListeners".
this.emit('newListener', type, listener);
if (!this._events[type]) {
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
} else if (isArray(this._events[type])) {
if (!this._events[type]) {
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
} else if (isArray(this._events[type])) {
// If we've already got an array, just append.
this._events[type][ type === 'fail' ? 'unshift' : 'push'](listener);
// If we've already got an array, just append.
this._events[type]['fail' === type ? 'unshift' : 'push'](listener);
// Check for listener leak
if (!this._events[type].warned) {
var m;
if (typeof this._maxListeners !== 'undefined') {
m = this._maxListeners;
} else {
m = defaultMaxListeners;
}
// Check for listener leak
if (!this._events[type].warned) {
var m;
if (this._maxListeners !== undefined) {
m = this._maxListeners;
} else {
m = defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
console.trace();
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
console.trace();
}
}
} else {
// Adding the second element, need to change to array.
this._events[type] = type === 'fail' ? [listener, this._events[type]] : [this._events[type], listener];
}
} else {
// Adding the second element, need to change to array.
this._events[type] = 'fail' === type ? [listener, this._events[type]] : [this._events[type], listener];
}
return this;
return this;
};
/**
* Alias for emitter.addListener(type, listener).
*
* @param String type An event name.
* @param function filterFn An options callback to apply on event.
* @return EventEmitter A reference to the EventEmitter so calls can be chained
* @throws {CasperError} If invokation failed.
*/
EventEmitter.prototype.prependListener = function prependListener(type, listener) {
if ('function' !== typeof listener) {
throw new CasperError('addListener only takes instances of Function');
}
"use strict";
if (typeof listener !== 'function') {
throw new CasperError('addListener only takes instances of Function');
}
if (!this._events) this._events = {};
if (!this._events) {
this._events = {};
}
// To avoid recursion in the case that type == "newListeners"! Before
// adding it to the listeners, first emit "newListeners".
this.emit('newListener', type, listener);
// To avoid recursion in the case that type == "newListeners"! Before
// adding it to the listeners, first emit "newListeners".
this.emit('newListener', type, listener);
if (!this._events[type]) {
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
} else if (isArray(this._events[type])) {
if (!this._events[type]) {
// Optimize the case of one listener. Don't need the extra array object.
this._events[type] = listener;
} else if (isArray(this._events[type])) {
// If we've already got an array, just append.
this._events[type].unshift(listener);
// If we've already got an array, just append.
this._events[type].unshift(listener);
// Check for listener leak
if (!this._events[type].warned) {
var m;
if (this._maxListeners !== undefined) {
m = this._maxListeners;
} else {
m = defaultMaxListeners;
}
// Check for listener leak
if (!this._events[type].warned) {
var m;
if (typeof this._maxListeners !== 'undefined') {
m = this._maxListeners;
} else {
m = defaultMaxListeners;
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
console.trace();
}
if (m && m > 0 && this._events[type].length > m) {
this._events[type].warned = true;
console.error('(node) warning: possible EventEmitter memory ' +
'leak detected. %d listeners added. ' +
'Use emitter.setMaxListeners() to increase limit.',
this._events[type].length);
console.trace();
}
}
} else {
// Adding the second element, need to change to array.
this._events[type] = [listener, this._events[type]];
}
} else {
// Adding the second element, need to change to array.
this._events[type] = [listener, this._events[type]];
}
return this;
return this;
};
/**
* Alias for emitter.addListener(type, listener).
*
* @param String type An event name.
* @param function filterFn An options callback to apply on event.
* @return EventEmitter A reference to the EventEmitter so calls can be chained
*/
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
/**
* Adds a one time listener function for the event.
* This listener is invoked only the next time event is triggered, after which it is removed.
*
* @param String type An event name.
* @param function filterFn An options callback to apply on event.
* @return EventEmitter A reference to the EventEmitter so calls can be chained
* @throws {CasperError} If invokation failed.
*/
EventEmitter.prototype.once = function once(type, listener) {
if ('function' !== typeof listener) {
throw new CasperError('.once only takes instances of Function');
}
"use strict";
if (typeof listener !== 'function') {
throw new CasperError('.once only takes instances of Function');
}
var self = this;
function g() {
self.removeListener(type, g);
listener.apply(this, arguments);
}
var self = this;
var g = function g() {
self.removeListener(type, g);
listener.apply(this, arguments);
};
g.listener = listener;
self.on(type, g);
g.listener = listener;
self.on(type, g);
return this;
return this;
};
/**
* Removes the specified listener from the listener array for the specified event.
*
* @param String type An event name
* @param function filterFn An options callback to apply on event
* @return EventEmitter A reference to the EventEmitter so calls can be chained
* @throws {CasperError} If invokation failed.
*/
EventEmitter.prototype.removeListener = function removeListener(type, listener) {
if ('function' !== typeof listener) {
throw new CasperError('removeListener only takes instances of Function');
}
"use strict";
if (typeof listener !== 'function') {
throw new CasperError('removeListener only takes instances of Function');
}
// does not use listeners(), so no side effect of creating _events[type]
if (!this._events || !this._events[type]) return this;
// does not use listeners(), so no side effect of creating _events[type]
if (!this._events || !this._events[type]) {
return this;
}
var list = this._events[type];
var list = this._events[type];
if (isArray(list)) {
var position = -1;
for (var i = 0, length = list.length; i < length; i++) {
if (list[i] === listener ||
(list[i].listener && list[i].listener === listener))
{
position = i;
break;
}
if (isArray(list)) {
var position = -1;
for (var i = 0, length = list.length; i < length; i++) {
if (list[i] === listener ||
list[i].listener && list[i].listener === listener) {
position = i;
break;
}
}
if (position < 0) {
return this;
}
list.splice(position, 1);
if (list.length === 0) {
delete this._events[type];
}
} else if (list === listener ||
list.listener && list.listener === listener) {
delete this._events[type];
}
if (position < 0) return this;
list.splice(position, 1);
if (list.length === 0)
delete this._events[type];
} else if (list === listener ||
(list.listener && list.listener === listener))
{
delete this._events[type];
}
return this;
return this;
};
/**
* Removes all listeners, or those of the specified event.
*
* @param String type An event name
* @return EventEmitter A reference to the EventEmitter so calls can be chained
*/
EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) {
if (arguments.length === 0) {
this._events = {};
"use strict";
if (arguments.length === 0) {
this._events = {};
return this;
}
// does not use listeners(), so no side effect of creating _events[type]
if (type && this._events && this._events[type]) {
this._events[type] = null;
}
return this;
}
// does not use listeners(), so no side effect of creating _events[type]
if (type && this._events && this._events[type]) this._events[type] = null;
return this;
};
/**
* get callbacks listener.
*
* @param String type An event name
* @return mixed
*/
EventEmitter.prototype.listeners = function listeners(type) {
if (!this._events) this._events = {};
if (!this._events[type]) this._events[type] = [];
if (!isArray(this._events[type])) {
this._events[type] = [this._events[type]];
}
return this._events[type];
"use strict";
if (!this._events) {
this._events = {};
}
if (!this._events[type]) {
this._events[type] = [];
}
if (!isArray(this._events[type])) {
this._events[type] = [this._events[type]];
}
return this._events[type];
};
// Added for CasperJS: filters a value attached to an event
/**
* Trigger filter attached to an event and return value(s).
*
* @param String type An event name
* @param Array args... The rest of arguments passed to fn
* @return mixed
*/
EventEmitter.prototype.filter = function filter() {
var type = arguments[0];
if (!this._filters) {
this._filters = {};
return;
}
var _filter = this._filters[type];
if (typeof _filter !== 'function') {
return;
}
return _filter.apply(this, Array.prototype.splice.call(arguments, 1));
"use strict";
var type = arguments[0], res;
if (!this._filters) {
this._filters = {};
}
var _filter = this._filters[type];
if (typeof _filter === 'function') {
res = _filter.apply(this, Array.prototype.slice.call(arguments, 1));
}
this.emit(Array.prototype.slice.call(arguments, 0).concat([res]));
return res;
};
/**
* Remove all filters attached to events or only filters attached to a specific event.
*
* @param String type An event name
* @return EventEmitter A reference to the EventEmitter so calls can be chained
*/
EventEmitter.prototype.removeAllFilters = function removeAllFilters(type) {
if (arguments.length === 0) {
this._filters = {};
"use strict";
if (arguments.length === 0) {
this._filters = {};
return this;
}
if (type && this._filters && this._filters[type]) {
this._filters[type] = null;
}
return this;
}
if (type && this._filters && this._filters[type]) {
this._filters[type] = null;
}
return this;
};
/**
* attaches a filter to an event.
*
* @param String type An event name
* @param function filterFn An options callback to apply on event
* @return Boolean
* @throws {CasperError} If invokation failed
*/
EventEmitter.prototype.setFilter = function setFilter(type, filterFn) {
if (!this._filters) {
this._filters = {};
}
if ('function' !== typeof filterFn) {
throw new CasperError('setFilter only takes instances of Function');
}
if (!this._filters[type]) {
this._filters[type] = filterFn;
return true;
}
// TODO: process multiple filters? in which order? disallow?
return false;
"use strict";
if (!this._filters) {
this._filters = {};
}
if (typeof filterFn !== 'function') {
throw new CasperError('setFilter only takes instances of Function');
}
if (!this._filters[type]) {
this._filters[type] = filterFn;
return true;
}
// TODO: process multiple filters? in which order? disallow?
return false;
};

@@ -31,3 +31,3 @@ /*!

var require = patchRequire(require);
require = patchRequire(require);
var utils = require('utils');

@@ -71,4 +71,12 @@

}
response.headers.__proto__ = responseHeaders.prototype;
// response.headers.__proto__ = responseHeaders.prototype;
Object.setPrototypeOf = Object.setPrototypeOf || function(obj, proto) {
obj.__proto__ = proto;
return obj;
};
Object.setPrototypeOf(response.headers, responseHeaders.prototype);
return response;
};

@@ -33,3 +33,3 @@ /*!

var require = patchRequire(require);
require = patchRequire(require);
var utils = require('utils');

@@ -56,3 +56,3 @@

var computeCenter = function computeCenter(selector) {
var bounds = casper.getElementBounds(selector);
var bounds = casper.getElementBounds(selector, true);
if (utils.isClipRect(bounds)) {

@@ -89,3 +89,3 @@ var x = Math.round(bounds.left + bounds.width / 2),

};
var bounds = casper.getElementBounds(selector),
var bounds = casper.getElementBounds(selector, true),
px = convertNumberToIntAndPercentToFloat(clientX, 0.5),

@@ -92,0 +92,0 @@ py = convertNumberToIntAndPercentToFloat(clientY, 0.5);

@@ -33,3 +33,3 @@ /*!

var require = patchRequire(require);
require = patchRequire(require);
var utils = require('utils');

@@ -91,2 +91,8 @@ var f = utils.format;

break;
case "object":
popup = this.findByUrlNameTitle(popupInfo);
break;
case "number":
popup = this.findByIndex(popupInfo);
break;
case "qtruntimeobject": // WebPage

@@ -127,2 +133,19 @@ popup = popupInfo;

/**
* Finds the first popup matching a given title.
*
* @param String url The child WebPage title
* @return WebPage
*/
Stack.prototype.findByTitle = function findByTitle(string) {
"use strict";
var popup = this.filter(function(popupPage) {
return popupPage.title.indexOf(string) !== -1;
})[0];
if (!popup) {
throw new CasperError(f("Couldn't find popup with title containing '%s'", string));
}
return popup;
};
/**
* Finds the first popup matching a given url.

@@ -145,2 +168,62 @@ *

/**
* Finds the first popup matching a given url or name or title.
*
* @param String url The child WebPage url or name or title
* @return WebPage
*/
Stack.prototype.findByUrlNameTitle = function findByUrlNameTitle(object) {
"use strict";
var popup = null;
try {
if (typeof object.url !== "undefined") {
popup = this.findByUrl(object.url);
}
if (!popup && typeof object.title !== "undefined") {
popup = this.findByTitle(object.title);
}
if (!popup && typeof object.windowName !== "undefined") {
popup = this.findByWindowName(object.windowName);
}
} catch(e){}
if (!popup) {
throw new CasperError(f("Couldn't find popup with object '%s'", JSON.stringify(object)));
}
return popup;
};
/**
* Finds the first popup matching a given window name.
*
* @param String url The child WebPage window name
* @return WebPage
*/
Stack.prototype.findByWindowName = function findByWindowName(string) {
"use strict";
var popup = this.filter(function(popupPage) {
return popupPage.windowName.indexOf(string) !== -1 || popupPage.windowNameBackUp.indexOf(string) !== -1;
})[0];
if (!popup) {
throw new CasperError(f("Couldn't find popup with name containing '%s'", string));
}
return popup;
};
/**
* Finds the first popup matching a given index.
*
* @param Number index The child WebPage index
* @return WebPage
*/
Stack.prototype.findByIndex = function findByIndex(index) {
"use strict";
var popup = this[index];
if (!popup) {
throw new CasperError(f("Couldn't find popup with index containing '%d'", index));
}
return popup;
};
/**
* Returns a human readable list of current active popup urls.

@@ -147,0 +230,0 @@ *

@@ -31,3 +31,3 @@ /*!

var require = patchRequire(require);
require = patchRequire(require);
var fs = require('fs');

@@ -118,2 +118,3 @@ var events = require('events');

skipText: "SKIP", // text to use for a skipped test
save: false, // false to not save
pad: 80 , // maximum number of chars for a result line

@@ -1133,11 +1134,2 @@ warnText: "WARN" // text to use for a dubious test

config.test(this, this.casper);
if (!this.options.concise) {
this.casper.echo([
this.colorize('PASS', 'INFO'),
this.formatMessage(description),
this.colorize(f('(%d test%s)',
config.planned,
config.planned > 1 ? 's' : ''), 'INFO')
].join(' '));
}
}.bind(this);

@@ -1232,2 +1224,20 @@

this.suiteResults.push(this.currentSuite);
if (!this.options.concise) {
var message = [
this.colorize('PASS', 'INFO'),
this.formatMessage(this.currentSuite.name)
];
if (config.planned) {
message.push([
this.colorize(f('(%d test%s)',
config.planned,
config.planned > 1 ? 's' : ''), 'INFO')
]);
}
this.casper.echo(message.join(' '));
}
this.currentSuite = undefined;

@@ -1234,0 +1244,0 @@ this.executed = 0;

@@ -32,3 +32,3 @@ /*!

var require = patchRequire(require);
require = patchRequire(require);

@@ -802,3 +802,3 @@ /**

var d = array[i];
if (o[d] !== 1) {
if (typeof o[d] === "undefined") {
o[d] = 1;

@@ -805,0 +805,0 @@ r[r.length] = d;

@@ -33,3 +33,3 @@ /*!

var require = patchRequire(require);
require = patchRequire(require);
var utils = require('utils');

@@ -36,0 +36,0 @@ var fs = require('fs');

{
"name": "casperjs",
"description": "A navigation scripting & testing utility for PhantomJS and SlimerJS",
"version": "1.1.3",
"version": "1.1.4",
"keywords": [

@@ -6,0 +6,0 @@ "phantomjs",

@@ -64,3 +64,3 @@ # CasperJS

##Support
## Support

@@ -67,0 +67,0 @@ **Help request**. If you're stuck using CasperJS and don't understand how to achieve something, please [ask on the mailing-list](https://groups.google.com/forum/#!forum/casperjs) first. If the discussion reveals that you have found a real issue that might need a change within CasperJS, file an issue.

/*eslint strict:0*/
/*global CasperError, console, phantom, require*/
require = patchRequire(require);
var casper = require("casper").create();

@@ -5,0 +6,0 @@

@@ -55,2 +55,3 @@

if (binMode) {
response.setEncoding("binary");
response.write(fs.read(pageFile, 'b'));

@@ -57,0 +58,0 @@ }

@@ -38,3 +38,45 @@ /*eslint strict:0*/

casper.test.begin('Casper.captureBase64() tests', 3, function(test) {
casper.test.begin('Casper.captureSelector() tests', 2, {
testFile: '/tmp/__casper_test_capture.png',
setUp: function(test) {
if (fs.exists(this.testFile) && fs.isFile(this.testFile)) {
try {
fs.remove(this.testFile);
} catch (e) {
}
}
},
tearDown: function(test) {
try {
fs.remove(this.testFile);
} catch(e) {
}
},
test: function(test) {
var self = this;
casper.start('tests/site/index.html', function() {
this.viewport(300, 200);
this.captureSelector(self.testFile, 'ul');
test.assert(fs.isFile(self.testFile),
'Casper.captureSelector() captured from a selector');
var sizeBeforeScroll = fs.size(self.testFile);
this.scrollTo(10, 20);
this.captureSelector(self.testFile, 'ul');
var sizeAfterScroll = fs.size(self.testFile);
test.assert(sizeBeforeScroll === sizeAfterScroll,
'Casper.captureSelector() captured from a selector after scrolling');
});
casper.run(function() {
test.done();
});
}
});
casper.test.begin('Casper.captureBase64() tests', 4, function(test) {
casper.start('tests/site/index.html', function() {

@@ -47,2 +89,8 @@ test.assert(this.captureBase64('png').length > 0,

'Casper.captureBase64() rendered a capture from a clipRect as base64');
this.viewport(300, 200);
var sizeBeforeScroll = this.captureBase64('png', 'ul').length;
this.scrollTo(10, 20);
var sizeAfterScroll = this.captureBase64('png', 'ul').length;
test.assert(sizeBeforeScroll === sizeAfterScroll,
'Casper.captureBase64() rendered from a selector must be the same before and after scrolling');
}).run(function() {

@@ -49,0 +97,0 @@ test.done();

@@ -17,2 +17,12 @@ /*global casper*/

casper.test.begin('click() tests', 1, function(test) {
casper.start('tests/site/index.html', function() {
this.click('area');
}).then(function() {
test.assertTitle('CasperJS test form', 'Casper.thenClick() can click on an area tag');
}).run(function() {
test.done();
});
});
casper.test.begin('onclick variants tests', 8, function(test) {

@@ -19,0 +29,0 @@ casper.start('tests/site/click.html', function() {

/*eslint strict:0*/
var fs = require('fs');
casper.test.begin('base64encode() and download() tests', 2, function(test) {
casper.test.begin('base64encode() and download() tests', 8, function(test) {
// FIXME: https://github.com/ariya/phantomjs/pull/364 has been merged, update scheme

@@ -15,2 +15,25 @@ casper.start('file://' + phantom.casperPath + '/tests/site/index.html', function() {

}
})
.then(function() {
var csvFile = 'file://' + phantom.casperPath + '/tests/site/csv/base64encode.csv';
this.download(csvFile, '__base64encode.csv');
test.assert(fs.exists('__base64encode.csv'), 'Casper.download() downloads a file');
var stream = fs.open('__base64encode.csv', 'r'),
expectedValues = [
'إختبار,',
'آزمایشی,',
'测试',
'испытание',
'परीकi'
],
i = 0,
lines = stream.read().split(/[\n]/);
expectedValues.forEach(function(value) {
test.assertEquals(lines[i], value, 'Casper.base64encode() can retrieve base64 complex strings');
i++;
});
if (fs.exists('__base64encode.csv')) {
fs.remove('__base64encode.csv');
}
}).run(function() {

@@ -17,0 +40,0 @@ test.done();

@@ -53,3 +53,3 @@ /*eslint strict:0, max-params:0*/

test.assertEquals(casper.evaluate(function(a) {
return [a];
return a;
}, ["foo"]), ["foo"], 'Casper.evaluate() accepts an array as arguments context');

@@ -56,0 +56,0 @@ test.assertEquals(casper.evaluate(function(a, b) {

/*eslint strict:0*/
var fs = require('fs');
var selectXPath = require('casper').selectXPath;
var exp = false;
/**
* Known regression in 2.0.0, will be fixed in 2.0.1
* https://github.com/ariya/phantomjs/issues/12506
*/
function skipPhantom200 (test, nb) {
return test.skipIfEngine(nb, {
name: 'phantomjs',
version: {
min: '2.0.0',
max: '2.0.0'
},
message: 'form regression 12506'
});
}
function skipSlimer095 (test, nb) {
return test.skipIfEngine(nb, {
name: 'slimerjs',
version: {
min: '0.8.0',
max: '0.9.4'
},
message: 'filePicker method missing'
});
}
function testFormValues(test) {

@@ -29,2 +56,12 @@ test.assertField('email', 'chuck@norris.com',

}, true, 'can fill a list of checkboxes');
if (!skipPhantom200(test, 2)) {
test.assertEvalEquals(function() {
return __utils__.findOne('input[name="file"]').files.length === 1;
}, true, 'can select a file to upload');
if (!skipSlimer095(test,1)) {
test.assertEvalEquals(function() {
return __utils__.findOne('input[name="file"]').value.indexOf('README.md') !== -1;
}, true, 'can check a form file value');
}
}
}

@@ -45,18 +82,5 @@

/**
* Known regression in 2.0.0, will be fixed in 2.0.1
* https://github.com/ariya/phantomjs/issues/12506
*/
function skipPhantom200 (test, nb) {
return test.skipIfEngine(nb, {
name: 'phantomjs',
version: {
min: '2.0.0',
max: '2.0.0'
},
message: 'form regression 12506'
});
}
casper.test.begin('fill() & fillNames() tests', 18, function(test) {
casper.test.begin('fill() & fillNames() tests', 19, function(test) {
var fpath = fs.pathJoin(phantom.casperPath, 'README.md');

@@ -78,7 +102,2 @@

testFormValues(test);
if (!skipPhantom200(test, 1)) {
test.assertEvalEquals(function() {
return __utils__.findOne('input[name="file"]').files.length === 1;
}, true, 'can select a file to upload');
}
});

@@ -93,3 +112,3 @@ casper.thenClick('input[type="submit"]', function() {

casper.test.begin('fillLabels() tests', 18, function(test) {
casper.test.begin('fillLabels() tests', 19, function(test) {
var fpath = fs.pathJoin(phantom.casperPath, 'README.md');

@@ -112,7 +131,2 @@

testFormValues(test);
if (!skipPhantom200(test, 1)) {
test.assertEvalEquals(function() {
return __utils__.findOne('input[name="file"]').files.length === 1;
}, true, 'can select a file to upload');
}
});

@@ -127,3 +141,3 @@ casper.thenClick('input[type="submit"]', function() {

casper.test.begin('fillSelectors() tests', 18, function(test) {
casper.test.begin('fillSelectors() tests', 19, function(test) {
var fpath = fs.pathJoin(phantom.casperPath, 'README.md');

@@ -145,7 +159,2 @@

testFormValues(test);
if (!skipPhantom200(test, 1)) {
test.assertEvalEquals(function() {
return __utils__.findOne('input[name="file"]').files.length === 1;
}, true, 'can select a file to upload');
}
});

@@ -160,24 +169,44 @@ casper.thenClick('input[type="submit"]', function() {

casper.test.begin('fillXPath() tests', 17, function(test) {
casper.start('tests/site/form.html', function() {
this.fillXPath('form[action="result.html"]', {
'//input[@name="email"]': 'chuck@norris.com',
'//input[@name="password"]': 42,
'//textarea[@name="content"]': 'Am watching thou',
'//input[@name="check"]': true,
'//input[@name="choice"]': 'no',
'//select[@name="topic"]': 'bar',
'//select[@name="multitopic"]': ['bar', 'car'],
'//input[@name="checklist[]"]': ['1', '3'],
'//input[@name="strange"]': "very"
casper.test.begin('fillXPath() tests', 19, {
setUp: function(test) {
var self = this;
var fpath = fs.pathJoin(phantom.casperPath, 'README.md');
casper.removeAllFilters('page.filePicker');
casper.setFilter('page.filePicker', function() {
exp = true;
return fpath;
});
testFormValues(test);
// note: file inputs cannot be filled using XPath
});
casper.thenClick('input[type="submit"]', function() {
testUrl(test);
});
casper.run(function() {
test.done();
});
},
tearDown: function(test) {
casper.removeAllFilters('page.filePicker');
},
test: function(test) {
var fpath = fs.pathJoin(phantom.casperPath, 'README.md');
casper.start('tests/site/form.html', function() {
this.fillXPath('form[action="result.html"]', {
'//input[@name="email"]': 'chuck@norris.com',
'//input[@name="password"]': 42,
'//textarea[@name="content"]': 'Am watching thou',
'//input[@name="check"]': true,
'//input[@name="choice"]': 'no',
'//select[@name="topic"]': 'bar',
'//input[@name="file"]': fpath,
'//select[@name="multitopic"]': ['bar', 'car'],
'//input[@name="checklist[]"]': ['1', '3'],
'//input[@name="strange"]': "very"
});
});
casper.thenClick(selectXPath('//input[@name="file"]'), function() {
testFormValues(test);
});
casper.thenClick('input[type="submit"]', function() {
testUrl(test);
});
casper.run(function() {
test.done();
});
}
});

@@ -350,3 +379,4 @@

//
casper.test.begin('setFieldValue() tests with css3 selector and form', 9, function(test) {
casper.test.begin('setFieldValue() tests with css3 selector and form', 11, function(test) {
var fpath = fs.pathJoin(phantom.casperPath, 'README.md');
casper.start('tests/site/form.html', function() {

@@ -360,2 +390,3 @@ var data = {

"select[name='topic']": 'bar',
"input[name='file']": fpath,
"select[name='multitopic']": ['bar', 'car'],

@@ -377,3 +408,4 @@ "input[name='checklist[]']": ['1', '3'],

casper.test.begin('setFieldValue() tests with XPath selector', 9, function(test) {
casper.test.begin('setFieldValue() tests with XPath selector', 11, function(test) {
var fpath = fs.pathJoin(phantom.casperPath, 'README.md');
casper.start('tests/site/form.html', function() {

@@ -387,2 +419,3 @@ var data = {

'//select[@name="topic"]': 'bar',
'//input[@name="file"]': fpath,
'//select[@name="multitopic"]': ['bar', 'car'],

@@ -404,3 +437,4 @@ '//input[@name="checklist[]"]': ['1', '3'],

casper.test.begin('setFieldValueName() tests', 9, function(test) {
casper.test.begin('setFieldValueName() tests', 11, function(test) {
var fpath = fs.pathJoin(phantom.casperPath, 'README.md');
casper.start('tests/site/form.html', function() {

@@ -414,2 +448,3 @@ var data = {

topic: 'bar',
file: fpath,
multitopic: ['bar', 'car'],

@@ -431,3 +466,4 @@ 'checklist[]': ['1', '3'],

casper.test.begin('setFieldValueLabel() tests', 9, function(test) {
casper.test.begin('setFieldValueLabel() tests', 11, function(test) {
var fpath = fs.pathJoin(phantom.casperPath, 'README.md');
casper.start('tests/site/form.html', function() {

@@ -441,2 +477,3 @@ var data = {

Topic: 'bar',
File: fpath,
Multitopic: ['bar', 'car'],

@@ -447,3 +484,2 @@ "1": true,

};
for (var selector in data){

@@ -450,0 +486,0 @@ this.setFieldValueLabel(selector, data[selector]);

/*eslint strict:0*/
casper.test.begin('handling frames', 16, function(test) {
casper.test.begin('handling frames', 37, function(test) {
casper.start('tests/site/frames.html');
casper.withFrame('frame1', function() {
test.assertTitle('CasperJS frame 1');
test.assertExists("#f1");
test.assertDoesntExist("#f2");
test.assertEval(function() {
return '__utils__' in window && 'getBinary' in __utils__;
}, '__utils__ object is available in child frame');
test.assertMatches(this.page.frameContent, /This is frame 1/);
test.assertMatches(this.getHTML(), /This is frame 1/);
casper.on("frame.reset", function(frameInfos) {
// console.log(frameInfos.join('-'), 'forceReloaded');
});
casper.viewport(800,600);
casper.then( function(){
casper.withFrame('frame1', function() {
test.assertTitle('CasperJS frame 1');
test.assertExists("#f1");
test.assertDoesntExist("#f2");
test.assertEval(function() {
return '__utils__' in window && 'getBinary' in __utils__;
}, '__utils__ object is available in child frame');
test.assertMatches(this.page.frameContent, /This is frame 1/);
test.assertMatches(this.getHTML(), /This is frame 1/);
});
casper.withFrame('frame2', function() {
test.assertTitle('CasperJS frame 2');
test.assertExists("#f2");
test.assertDoesntExist("#f1");
test.assertEval(function() {
return '__utils__' in window && 'getBinary' in __utils__;
}, '__utils__ object is available in other child frame');
this.clickLabel('frame 3');
casper.withFrame('frame2', function() {
test.assertTitle('CasperJS frame 2');
test.assertExists("#f2");
test.assertDoesntExist("#f1");
test.assertEval(function() {
return '__utils__' in window && 'getBinary' in __utils__;
}, '__utils__ object is available in other child frame');
this.clickLabel('frame 3');
});
casper.withFrame('frame2', function() {
test.assertTitle('CasperJS frame 3');
});
casper.withFrame(0, function() {
test.assertTitle('CasperJS frame 1');
test.assertExists("#f1");
test.assertDoesntExist("#f2");
});
casper.withFrame(1, function() {
test.assertTitle('CasperJS frame 3');
test.assertEquals( casper.getElementInfo('a').width,100,'read tag a position');
casper.mouse.move('a');
test.assertEquals( casper.getElementInfo('a').width,200,'read tag a position hovered');
});
casper.withFrame('frame4', function() {
casper.then(function(){
casper.withFrame('frame5', function() {
casper.clickLabel('_self');
// message three is unpresent on frame 5 but as frame 5 was clean
// casperJS search on its parent frame
casper.waitForText("three",function(){
test.assertMatches( this.getHTML(),/three/,'go on self frame');
});
});
});
});
});
casper.thenOpen("tests/site/frames.html", function(){
casper.withFrame('frame4', function() {
casper.then(function(){
casper.withFrame('frame5', function() {
casper.clickLabel('_parent');
});
casper.waitForText("three",function(){
test.assertMatches( this.getHTML(),/three/,'go on parent frame');
});
});
});
});
casper.withFrame('frame2', function() {
test.assertTitle('CasperJS frame 3');
casper.thenOpen("tests/site/frames.html", function(){
casper.withFrame('frame4', function() {
casper.then(function(){
casper.withFrame('frame5', function() {
casper.clickLabel('_top');
// message three is unpresent on frame 5 but as frame 5 was clean
// casperJS search on its parent frame
});
});
});
casper.waitForText("three",function(){
test.assertMatches( this.getHTML(),/three/,'go on top frame');
});
});
casper.withFrame(0, function() {
casper.thenOpen("tests/site/frames.html", function() {
var expected = ['frame1','frame1', 'frame2', 'frame2'];
casper.page.switchToMainFrame();
casper.on('frame.changed', function (name, status) {
test.assertEquals(name, expected.shift());
});
casper.switchToFrame("frame1");
test.assertTitle('CasperJS frame 1');
test.assertExists("#f1");
test.assertDoesntExist("#f2");
casper.then(function() {
// Same frame in next step
test.assertTitle('CasperJS frame 1');
casper.switchToParentFrame();
test.assertTitle("CasperJS test frames");
casper.switchToFrame("frame2");
test.assertTitle('CasperJS frame 2');
casper.switchToMainFrame();
test.assertTitle("CasperJS test frames");
this.removeAllListeners('frame.changed');
});
});
casper.withFrame(1, function() {
test.assertTitle('CasperJS frame 3');
casper.thenOpen("tests/site/frames.html", function(){
var expected = ['frame4','frame5', 'frame5','frame4'];
casper.page.switchToMainFrame();
casper.on('frame.changed', function (name , status) {
test.assertEquals(name, expected.shift());
});
casper.switchToFrame("frame4");
test.assertTitle('CasperJS frame 4');
casper.switchToFrame("frame5");
test.assertTitle('CasperJS frame 1');
casper.clickLabel('_top');
});
casper.then(function() {
casper.switchToParentFrame();
casper.switchToParentFrame();
casper.waitForText("three",function(){
test.assertMatches( this.getHTML(),/three/,'go on top frame');
});
casper.switchToParentFrame();
casper.switchToParentFrame();
casper.switchToParentFrame();
casper.switchToParentFrame();
casper.switchToParentFrame();
this.removeAllListeners('frame.changed');
});
casper.run(function() {
test.assertTitle('CasperJS test frames');
test.assertTitle('CasperJS test index');
test.done();
});
});

@@ -10,3 +10,25 @@ /*eslint strict:0*/

};
response.write("ok");
if (request.url.indexOf('popup') === -1) {
response.write("ok " + request.headers["User-Agent"] );
} else {
response.write('<!DOCTYPE html>' +
'<html>' +
' <head>' +
' <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' +
' <title>CasperJS test popup</title>' +
' </head>' +
' <body>' +
' <a href="/tests/site/redirect.html" target="form">new window</a>' +
' <a href="#" class="close", onclick="w && w.close();return false">close</a>' +
' <script>' +
' var w;' +
' setTimeout(function() {' +
' w = window.open("index.html",' +
' "popup", "menubar=no, status=no, scrollbars=no, menubar=no, width=400, height=300");' +
' }, 200);' +
' </script>' +
' </body>' +
'</html>');
}
response.close();

@@ -30,2 +52,15 @@ });

}).run(function() {
test.done();
});
});
casper.test.begin('Casper.headers.check() checks useraagent in popup', 1, function(test) {
casper.userAgent('ploop').start('http://localhost:8090/popup', function(response) {
var headers = response.headers;
casper.waitForPopup('index.html', function() {
casper.withPopup('index.html', function(){
test.assertMatch(casper.getPlainText(),/ploop/,'user-agent updated in popup request');
});
});
}).run(function() {
server.close();

@@ -32,0 +67,0 @@ test.done();

@@ -47,4 +47,4 @@ /*eslint strict:0*/

casper.options.logLevel = oldLevel;
casper.options.verbose = true;
casper.options.verbose = false;
});
});
/*eslint strict:0, max-statements:0*/
casper.on('remote.message',function(e){
console.log(e);
});
casper.test.begin('mouseEvent() tests', 20, function(test) {

@@ -7,0 +3,0 @@ casper.start('tests/site/mouse-events.html', function() {

/*eslint strict:0*/
var server = require('webserver').create();
var service = server.listen(8090, function(request, response) {
var service = server.listen(8092, function(request, response) {
var path = request.url.split('/');
response.statusCode = 200;
response.setHeader('Content-type', 'text/html');
response.write('<a href="/link">a link</a>');
response.write('<form action="/form" method="POST"><input type="submit" /></form>');
response.close();
switch (path[1]){
case "indexscript":
response.setHeader('Content-type', 'text/html');
response.write('<a href="/link">a link</a>');
response.write('<form action="/form" method="POST"><input type="submit" /></form>');
response.write('<script src="/script"></script>');
response.close();
break;
case "indexscript2":
response.setHeader('Content-type', 'text/html');
response.write('<a href="/link">a link</a>');
response.write('<form action="/form" method="POST"><input type="submit" /></form>');
response.write('<script src="/script2"></script>');
response.close();
break;
case "form": case "link": case "":
response.setHeader('Content-type', 'text/html');
response.write('<a href="/link">a link</a>');
response.write('<form action="/form" method="POST"><input type="submit" /></form>');
response.close();
break;
case "script": //never close connexion
break;
case "script2": //partial response never close connexion
response.setHeader('Content-type', 'text/javascript');
response.write('var a=2;');
break;
case "longScript":
response.setHeader('Content-type', 'text/html');
response.write('<html><body><script>for(;;);</script></body></html>');
response.close();
break;
}
});
var resourceTimeout = function resourceTimeout (request) {
casper.test.pass('resource.timeout matched');
};
var stopScript = function stopScript (webpage, message) {
webpage.stopJavaScript();
casper.test.pass('remote.longRunningScript matched ' + message);
return true;
};
var closeService = function closeService(message) {
casper.test.begin(message, 0, function(test) {
casper.start('http://localhost:8092/').run(function() {
test.done();
server.close();
});
});
};
casper.test.begin('Link Navigation updates response', 2, function(test) {
casper.start('http://localhost:8090', function(response) {
casper.start('http://localhost:8092/', function(response) {
casper.click('a');

@@ -24,3 +74,2 @@ casper.then(function(response) {

);
});

@@ -33,3 +82,3 @@ }).run(function() {

casper.test.begin('Form Submittal updates the response', 2, function(test) {
casper.start('http://localhost:8090', function(response) {
casper.start('http://localhost:8092/', function(response) {
casper.fill('form', {}, true);

@@ -49,4 +98,49 @@ casper.then(function(response) {

test.done();
server.close();
});
});
if (phantom.casperEngine === 'slimerjs' && utils.ltVersion(slimer.version, '0.10.0')){
closeService('No resourceTimeout and longRunningScript functionality');
} else {
casper.test.begin('Catch resourceTimeout on partial response', 2, function(test) {
casper.on("resource.timeout",resourceTimeout);
casper.page.settings.resourceTimeout = 1000;
casper.start('http://localhost:8092/indexscript2', function(response) {
delete casper.page.settings.resourceTimeout;
test.pass('unable to load page on time');
casper.removeListener("resource.timeout", resourceTimeout);
}).run(function() {
test.done();
});
});
casper.test.begin('Catch resourceTimeout on No response', 2, function(test) {
casper.on("resource.timeout",resourceTimeout);
casper.page.settings.resourceTimeout = 1000;
casper.start('http://localhost:8092/indexscript', function(response) {
delete casper.page.settings.resourceTimeout;
test.pass('unable to load page on time');
casper.removeListener("resource.timeout", resourceTimeout);
}).run(function() {
test.done();
});
});
if (phantom.casperEngine === 'phantomjs') {
closeService('No longRunningScript functionality');
} else {
casper.test.begin('Catch longRunningScript', 2, function(test) {
casper.on("remote.longRunningScript", stopScript);
casper.start('http://localhost:8092/longScript', function(response) {
test.pass('unable to load page on time because of script');
casper.removeListener("remote.longRunningScript", stopScript);
}).run(function() {
test.done();
server.close();
});
});
}
}

@@ -6,3 +6,3 @@ /*eslint strict:0, max-statements:0*/

casper.test.begin('popup tests', 22, function(test) {
casper.test.begin('popup tests', 30, function(test) {
casper.once('popup.created', function(popup) {

@@ -26,5 +26,14 @@ test.pass('"popup.created" event is fired');

casper.start('tests/site/popup.html');
casper.start('tests/site/popup.html',function(){
casper.once('resource.requested', function(resource) {
test.pass('"resource.requested" event is fired');
test.assertMatch(resource.url,/index\.html/, 'resource.requested event works on popup');
});
casper.once('resource.received', function(resource) {
test.pass('"resource.received" event is fired');
test.assertMatch(resource.url,/index\.html/, 'resource.received event works on popup');
});
});
casper.waitForPopup('index.html', function() {
casper.waitForPopup("index.html", function() {
test.pass('Casper.waitForPopup() waits for a popup being created');

@@ -34,6 +43,10 @@ test.assertEquals(this.popups.length, 1, 'A popup has been added');

});
casper.waitForPopup({windowName:"popup"}, function() {
test.pass('Casper.waitForPopup() waits for a popup being created');
test.assertEquals(this.popups.length, 1, 'A popup has been added');
test.assert(utils.isWebPage(this.popups[0]), 'A popup is a WebPage');
});
casper.withPopup('index.html', function() {
test.assertTitle('CasperJS test index',
'Casper.withPopup() found a popup with expected title');
test.assertTextExists('three',

@@ -51,2 +64,7 @@ 'Casper.withPopup() found a popup with expected text');

});
casper.withPopup({'title': 'CasperJS test index'}, function() {
test.assertTitle('CasperJS test index',
'Casper.withPopup() found a popup with expected title');
});

@@ -60,15 +78,14 @@ casper.then(function() {

test.assertEquals(this.popups.length, 0, 'Popup is removed when closed');
});
});
casper.thenOpen('tests/site/popup.html');
casper.waitForPopup(/index\.html$/, function() {
casper.waitForPopup(0, function() {
test.pass('Casper.waitForPopup() waits for a popup being created');
casper.withPopup(0, function() {
test.assertTitle('CasperJS test index',
'Casper.withPopup() can use a regexp to identify popup');
});
});
casper.withPopup(/index\.html$/, function() {
test.assertTitle('CasperJS test index',
'Casper.withPopup() can use a regexp to identify popup');
});
casper.thenClick('.close', function() {

@@ -83,6 +100,8 @@ test.assertUrlMatches(/popup\.html$/,

casper.thenClick('a[target="_blank"]');
casper.waitForPopup('form.html', function() {
test.pass('Casper.waitForPopup() waits when clicked on a link with target=_blank');
casper.thenClick('a[target="form"]');
casper.then(function(){
casper.waitForPopup(/form\.html/, function() {
test.pass('Casper.waitForPopup() waits when clicked on a link with target=form');
});
});

@@ -94,2 +113,6 @@

casper.withPopup(0, function() {
test.assertTitle('CasperJS test form');
});
casper.run(function() {

@@ -96,0 +119,0 @@ test.done();

@@ -16,3 +16,3 @@ /*eslint strict:0*/

casper.test.begin('viewport() asynchronous tests', 2, function(test) {
casper.test.begin('viewport() asynchronous tests', 4, function(test) {
var screenshotData;

@@ -34,4 +34,6 @@

// and the image is not still ready: :-/
if (!test.skipIfEngine(2, {
name: 'slimerjs',
version : { max: '1.9.0'},
message: 'Casper.viewport() change test'

@@ -44,2 +46,11 @@ })) {

casper.thenOpen('tests/site/popup.html',function() {
casper.waitForPopup("index.html", function() {
casper.withPopup('index.html', function() {
test.assertEquals(casper.page.viewportSize.width, 800, 'Casper.viewport() popup changes width asynchronously');
test.assertEquals(casper.page.viewportSize.height, 600, 'Casper.viewport() popup changes height asynchronously');
});
});
});
casper.run(function() {

@@ -46,0 +57,0 @@ test.done();

/*eslint strict:0*/
casper.test.begin('visibility tests', 5, function(test) {
casper.test.begin('visibility tests', 11, function(test) {
casper.start('tests/site/visible.html', function() {

@@ -7,4 +7,9 @@ test.assert(!this.visible('#img1'), 'Casper.visible() can detect if an element is invisible');

test.assert(!this.visible('#img3'), 'Casper.visible() can detect if an element is invisible');
test.assert(this.visible('#img4'), 'Casper.visible() can detect if an element with display:flex is visible');
test.assert(this.visible('img'), 'Casper.visible() can detect if an element is visible');
this.waitWhileVisible('#img1', function() {
test.assert(!this.visible('#button1'), 'Casper.visible() can detect if an element is invisible when parent has display none');
test.assert(this.visible('#button2'), 'Casper.visible() can detect if an element is visible when parent is visible');
test.assert(this.visible('#circle1'), 'Casper.visible() can detect if an element inside svg is visible');
test.assert(!this.visible('#circle2'), 'Casper.visible() can detect if an element inside svg is invisible when parent has display none');
this.waitWhileVisible('#img5', function() {
test.pass('Casper.waitWhileVisible() can wait while an element is visible');

@@ -14,2 +19,7 @@ }, function() {

}, 2000);
this.waitWhileVisible('#button4', function() {
test.pass('Casper.waitWhileVisible() can wait while an element is visible until parent is hidden');
}, function() {
test.fail('Casper.waitWhileVisible() can wait while an element is visible until parent is hidden');
}, 2000);
});

@@ -16,0 +26,0 @@

@@ -19,3 +19,3 @@ /*eslint strict:0*/

casper.test.begin('waitFor() tests', 2, function(test) {
casper.test.begin('waitFor() tests', 4, function(test) {
casper.start('tests/site/waitFor.html');

@@ -40,3 +40,21 @@

}, 1000);
casper.reload().waitFor(function(){
return true;
}, function() {
test.pass('waitFor() can run test function when timeout is set to 1');
}, function() {
test.fail('waitFor() can not run test function when timeout is set to 1');
}, 1);
var testArray = [false,true];
var i = 0;
casper.reload().waitFor(function(){
return testArray[i++];
}, function() {
test.pass('waitFor() can run a last test function after timeout');
}, function() {
test.fail('waitFor() can not run a last test function after timeout');
}, (1.5*casper.options.retryTimeout));
casper.run(function() {

@@ -172,1 +190,147 @@ test.done();

});
casper.test.begin('waitForExec() tests', 24, function(test) {
if (phantom.casperEngine === 'slimerjs') {
test.skip(24, 'SlimerJS DOES NOT HAVE A child_process MODULE');
} else {
var system = require('system');
var fs = require('fs');
var lsExecutable;
var shExecutable;
if (system.os.name != "windows") {
// Seems to be crashing here in slimerJs 0.10.x, added fs.exists before fs.isExecutable for testing
lsExecutable = system.env.PATH.split(':').filter(function (path) {
var fileString = path + fs.separator + 'ls';
return (fs.exists(fileString) && fs.isExecutable(fileString));
})[0] + fs.separator + 'ls';
shExecutable = system.env.PATH.split(':').filter(function (path) {
var fileString = path + fs.separator + 'sh';
return (fs.exists(fileString) && fs.isExecutable(fileString));
})[0] + fs.separator + 'sh';
};
var notExecutable = '';
var k = 0;
while (!notExecutable) {
notExecutable = (!fs.exists(fs.workingDirectory + fs.separator + 'run' + k + '.exe')) ? fs.workingDirectory + fs.separator + 'run' + k + '.exe' : '';
k++;
};
casper.start('');
casper.waitForExec(null, [],
// Add success1 because on some systems the default system shell maybe exits by itself after being called(?)
null,
/*
function success1(details) {
test.assert((utils.isObject(details.data.command) && utils.isString(details.data.command.program) && utils.isArray(details.data.command.parameters)), 'Casper.waitForExec() can call the default system shell and it exits before timeout: "' + JSON.stringify(details.data.command) + '"');
test.assertEquals(details.data.isChildNotFinished, 0,'Default system shell returned "isChildNotFinished" 0 before timeout');
test.assert(utils.isNumber(details.data.exitCode), 'Default system shell "' + JSON.stringify(details.data.command) + '" exited before timeout with exit code ' + details.data.exitCode);
},
*/
function timeout1(timeout, details) {
// exit code value seems to be 0 when phantom kills the process before 2.1.1(?)
var valueOfExitCode = (utils.matchEngine({name: 'phantomjs', version: {min: '1.9.0', max: '2.1.0'}})) ? 0 : 15;
test.assert((utils.isString(details.data.command) && utils.isArray(details.data.parameters)), 'Casper.waitForExec() can call the default system shell and kills it on timeout: ' + JSON.stringify(details.data));
test.assert( (utils.isNumber(details.data.pid) && ( details.data.pid > 0) ), 'Default system shell exited on timeout (TERM signal) and used PID ' + details.data.pid);
test.assertEquals(details.data.isChildNotFinished, 0,'Default system shell returned "isChildNotFinished" 0 on timeout');
test.assertEquals(details.data.exitCode, valueOfExitCode, 'Default system shell exited on timeout (TERM signal) with exit code ' + details.data.exitCode);
}, 2000);
casper.reload().waitForExec(notExecutable, [],
function success2(details) {
test.assert((utils.isString(details.data.command) && utils.isArray(details.data.parameters)), 'Casper.waitForExec() tried to call non existing executable: ' + JSON.stringify(details.data));
test.assertEquals(details.data.pid, 0,'Non existing executable returned "pid" 0');
test.assertEquals(details.data.isChildNotFinished, 0,'Non existing executable returned "isChildNotFinished" 0');
test.assertEquals(details.data.exitCode, null, 'Non existing executable returned exitCode null');
test.assertEquals(details.data.elapsedTime, null, 'Non existing executable returned elapsedTime null');
});
if (system.os.name != "windows") {
if (lsExecutable) {
casper.reload().waitForExec(lsExecutable, ['-a',fs.workingDirectory],
function success3(details) {
test.assert((utils.isString(details.data.command) && utils.isArray(details.data.parameters)), 'Casper.waitForExec() can call "lsExecutable" on "workingDirectory": ' + JSON.stringify(details.data));
test.assert( (utils.isNumber(details.data.pid) && ( details.data.pid > 0) ), '"lsExecutable" on "workingDirectory" used PID ' + details.data.pid);
test.assertEquals(details.data.isChildNotFinished, 0,'"lsExecutable" on "workingDirectory" returned "isChildNotFinished" 0');
test.assertEquals(details.data.exitCode, 0, '"lsExecutable" on "workingDirectory" returned exitCode 0');
test.assertTruthy(details.data.stdout, '"lsExecutable" on "workingDirectory" returned stdout ' + JSON.stringify(details.data.stdout));
});
casper.reload().waitForExec(lsExecutable, [notExecutable],
function success4(details) {
test.assert((utils.isString(details.data.command) && utils.isArray(details.data.parameters)), 'Casper.waitForExec() can call "lsExecutable" on "notExecutable": ' + JSON.stringify(details.data));
test.assert( (utils.isNumber(details.data.pid) && ( details.data.pid > 0) ), '"lsExecutable" on "notExecutable" used PID ' + details.data.pid);
test.assertEquals(details.data.isChildNotFinished, 0,'"lsExecutable" on "notExecutable" returned "isChildNotFinished" 0');
test.assertTruthy(details.data.exitCode, '"lsExecutable" on "notExecutable" returned exitCode ' + details.data.exitCode);
test.assertTruthy(details.data.stderr, '"lsExecutable" on "notExecutable" returned stderr ' + JSON.stringify(details.data.stderr));
});
} else {
casper.reload().then( function() {
test.skip(10, 'ls EXECUTABLE NOT FOUND');
});
};
if (shExecutable) {
// vars used to measure if 'shell script to trap TERM signal' is waiting enough and being killed faster enough
var shellTrapTimeout = 500;
var shellTrapTermTimeout = 1000;
var timeLapseAfterKillSignal = 300;
var minTimeLapse = shellTrapTimeout + shellTrapTermTimeout;
var maxTimeLapse = minTimeLapse + timeLapseAfterKillSignal;
casper.then( function() { // inside then for elapsedTime don't be added with other tests elapsedTime
// on my tests 'TERM trapped!' will not be on stdout because 'shExecutable' is killed with SIGKILL
casper.reload().waitForExec(shExecutable + ' -c', ['trap "echo TERM trapped!" TERM ; sleep 60'], null,
function timeout5(timeout,details) {
// exit code value seems to be 0 when phantom kills the process before 2.1.1(?)
var valueOfExitCode = (utils.matchEngine({name: 'phantomjs', version: {min: '1.9.0', max: '2.1.0'}})) ? 0 : 9;
test.assert((utils.isString(details.data.command) && utils.isArray(details.data.parameters)), 'Casper.waitForExec() can call shell script to trap TERM signal and then kills it: ' + JSON.stringify(details.data));
test.assert( (utils.isNumber(details.data.pid) && ( details.data.pid > 0) ), 'shell script to trap TERM signal used PID ' + details.data.pid);
test.assertEquals(details.data.isChildNotFinished, 0, 'shell script to trap TERM signal returned "isChildNotFinished" 0');
test.assertEquals(details.data.exitCode, valueOfExitCode, 'shell script to trap TERM signal returned exitCode ' + details.data.exitCode);
// test if it first waited for shellTrapTimeout ms, then waited for shellTrapTermTimeout ms after TERM signal, then exited faster (timeLapseAfterKillSignal ms or less) with KILL signal
test.assert( (utils.isNumber(details.data.elapsedTime) && (details.data.elapsedTime <= maxTimeLapse) && (details.data.elapsedTime > minTimeLapse) ), 'shell script to trap TERM signal run and killed in more than ' + minTimeLapse + 'ms and in less than or equal to ' + maxTimeLapse + 'ms: ' + details.data.elapsedTime);
}, [shellTrapTimeout, shellTrapTermTimeout]);
});
} else {
casper.reload().then( function() {
test.skip(5, 'sh EXECUTABLE NOT FOUND');
});
};
} else {
casper.reload().waitForExec(null, ['/c', 'dir', fs.workingDirectory],
function(details) {
test.assert((utils.isString(details.data.command) && utils.isArray(details.data.parameters)), 'Casper.waitForExec() can call dir on "workingDirectory": ' + JSON.stringify(details.data));
test.assert( (utils.isNumber(details.data.pid) && ( details.data.pid > 0) ), 'dir on "workingDirectory" used PID ' + details.data.pid);
test.assertEquals(details.data.isChildNotFinished, 0,'dir on "workingDirectory" returned "isChildNotFinished" 0');
test.assertEquals(details.data.exitCode, 0, 'dir on "workingDirectory" returned exitCode 0');
test.assertTruthy(details.data.stdout, 'dir on "workingDirectory" returned stdout ' + JSON.stringify(details.data.stdout));
});
casper.reload().waitForExec(null, ['/c', 'dir', notExecutable],
function(details) {
test.assert((utils.isString(details.data.command) && utils.isArray(details.data.parameters)), 'Casper.waitForExec() can dir on "notExecutable": ' + JSON.stringify(details.data));
test.assert( (utils.isNumber(details.data.pid) && ( details.data.pid > 0) ), 'dir on "notExecutable" used PID ' + details.data.pid);
test.assertEquals(details.data.isChildNotFinished, 0, 'dir on "notExecutable" returned "isChildNotFinished" 0');
test.assertTruthy(details.data.exitCode, 'dir on "notExecutable" returned exitCode ' + details.data.exitCode);
test.assertTruthy(details.data.stderr, 'dir on "notExecutable" returned stderr ' + JSON.stringify(details.data.stderr));
});
casper.reload().then( function() {
test.skip(5, 'WINDOWS SYSTEM, CAN NOT EASILY TRAP TERM SIGNAL ON SHELL SCRIPT');
});
};
};
casper.run(function() {
test.done();
});
});

@@ -20,3 +20,3 @@ /*eslint strict:0*/

casper.thenClick(x('/html/body/a[2]'), function() {
casper.thenClick(x('/html/body/a[1]'), function() {
test.assertTitle('CasperJS test form', 'Clicking XPath works as expected');

@@ -23,0 +23,0 @@ this.fill(x('/html/body/form'), {

@@ -50,2 +50,35 @@ /*eslint strict:0*/

casper.test.begin('ClientUtils.exists() with svg tests', 3, function(test) {
var clientutils = require('clientutils').create();
fakeDocument('<div class="foo"><svg><text>SVG</text></svg></div>');
test.assert(clientutils.exists('div.foo svg'),
'ClientUtils.exists() checks that an svg element exist');
test.assert(clientutils.exists(selectXPath('//div/svg:svg')),
'ClientUtils.exists() checks that an svg element exist using XPath');
test.assert(clientutils.exists(selectXPath('//div/svg:svg/svg:text')),
'ClientUtils.exists() checks that an svg element exist using XPath');
fakeDocument(null);
test.done();
});
casper.test.begin('ClientUtils.exists() with mathml tests', 3, function(test) {
var clientutils = require('clientutils').create();
var html = "<div class='foo'>We will now prove the Pythogorian theorem:";
html += "<math> <mrow>"
html += "<msup><mi> a </mi><mn>2</mn></msup> <mo> + </mo>";
html += "<msup><mi> b </mi><mn>2</mn></msup>";
html += "<mo> = </mo> <msup><mi> c </mi><mn>2</mn></msup>";
html += "</mrow> </math>";
html += "</div>";
fakeDocument(html);
test.assert(clientutils.exists('div.foo math'),
'ClientUtils.exists() checks that an math element exist');
test.assert(clientutils.exists(selectXPath('//div/mathml:math')),
'ClientUtils.exists() checks that an math element exist using XPath');
test.assert(clientutils.exists(selectXPath('//div/mathml:math/mathml:mrow/mathml:msup[1]')),
'ClientUtils.exists() checks that an math element exist using XPath');
fakeDocument(null);
test.done();
});
casper.test.begin('ClientUtils.findAll() tests', 7, function(test) {

@@ -234,3 +267,3 @@ var clientutils = require('clientutils').create();

casper.test.begin('ClientUtils.getElementInfo() visibility tests', 4, function(test) {
casper.test.begin('ClientUtils.getElementInfo() visibility tests', 7, function(test) {
casper.page.content = '<a href="plop" class="plip plup" style="display: inline"><i>paf</i></a>';

@@ -252,2 +285,15 @@ var info = casper.getElementInfo('a.plip');

casper.page.content = '<a href="plop" class="plip plup" style="display: inline-flex"><i>paf</i></a>';
info = casper.getElementInfo('a.plip');
test.assert(info.visible, 'ClientUtils.getElementInfo() retrieves element visibility with display inline-flex');
casper.page.content = '<a href="plop" class="plip plup" style="display: flex"><i>paf</i></a>';
info = casper.getElementInfo('a.plip');
test.assert(info.visible, 'ClientUtils.getElementInfo() retrieves element visibility with display flex');
casper.page.content = '<div style="display: none"><a href="plop" class="plip plup"><i>paf</i></a></div>';
info = casper.getElementInfo('a.plip');
test.assertNot(info.visible, 'ClientUtils.getElementInfo() retrieves element visibility when parent\'s display is set to none');
test.done();

@@ -258,3 +304,3 @@ });

var clientutils = require('clientutils').create();
// CSS selector

@@ -265,3 +311,3 @@ var cssSelector = clientutils.makeSelector('#css3selector', 'css');

// XPath selector
// XPath selector
var xpathSelector = clientutils.makeSelector('//li[text()="blah"]', 'xpath');

@@ -291,2 +337,1 @@ test.assertType(xpathSelector, 'object',

});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc