Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

testcafe

Package Overview
Dependencies
Maintainers
1
Versions
464
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

testcafe - npm Package Compare versions

Comparing version 13.1.2 to 13.1.3

lib/_compiled_/control_panel_ui/assets/images/preloader.gif

2

index.js

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

exports.TestCafe = require("./lib/server/test_cafe").TestCafe;
exports.TestCafe = require('./lib/server/test_cafe').TestCafe;

@@ -33,6 +33,6 @@ var fs = require("fs"), util = require("util"), javascriptParser = require("uglify-js").parser, astProcessor = require("uglify-js").uglify, url = require("url"), Const = require("./const"), Ast = require("./ast"), ErrCodes = require("./err_codes");

stepsInfo.forEach(function(info) {
var stepFuncBodyAst = [], actionArgsAst = [];
if (info.elemIdentifier && info.selector) {
var stepFuncBodyAst = [], actionArgsAst = [], selector = info.selectors && info.selectors[info.currentSelectorIndex] && info.selectors[info.currentSelectorIndex].selector;
if (info.elemIdentifier && selector) {
try {
var selectorAst = javascriptParser.parse(info.selector);
var selectorAst = javascriptParser.parse(selector);
} catch (parserErr) {

@@ -39,0 +39,0 @@ throw {

var fs = require("fs"), path = require("path"), javascriptParser = require("uglify-js").parser, astProcessor = require("uglify-js").uglify, async = require("async"), Const = require("./const"), Ast = require("./ast"), FuncCallValidator = require("./func_call_validator"), ErrCodes = require("./err_codes");
var Compiler = exports.Compiler = function(filename, modules, requiresCodeCache) {
var Compiler = module.exports = function(filename, modules, requiresCodeCache) {
requiresCodeCache = requiresCodeCache || {};

@@ -5,0 +5,0 @@ this.walker = astProcessor.ast_walker();

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

exports.Compiler = require("./compiler").Compiler;
exports.Compiler = require("./compiler");

@@ -3,0 +3,0 @@ exports.CodeGenerator = require("./code_generator");

@@ -160,3 +160,3 @@ var util = require("util"), EventEmitter = require("events").EventEmitter, vfs = require("./vfs"), VirtualFS = vfs.VirtualFS, errMsgBuilder = require("./err_msg_builder"), ERR = require("./server_errs");

vfsPath = vfs.getPlatformDependentPath(vfsPath);
vfsPath = vfsPath.split(VirtualFS.PLATFORM_PATH_SEPARATOR);
vfsPath = vfsPath.split(path.sep);
}

@@ -169,3 +169,3 @@ this.vfs.getPathInfo(vfsPath, function(err, pathInfo) {

Api.prototype.runTests = function(options, callback) {
var source = options.source || null, sourceType = options.sourceType || "dir", workers = options.workers || [], browsers = options.browsers || [], emulateCursor = options.emulateCursor || false;
var source = options.source || null, sourceType = options.sourceType || "dir", workers = options.workers || [], browsers = options.browsers || [], emulateCursor = options.emulateCursor || false, quarantineMode = options.quarantineMode || false;
var api = this, testRunner = this.testRunner, callbackExists = typeof callback === "function";

@@ -188,3 +188,3 @@ if (!workers.length && !browsers.length) {

if (actualWorkers.length) {
taskUid = testRunner.addTask(taskName, suite, testUids, actualWorkers, emulateCursor);
taskUid = testRunner.addTask(taskName, suite, testUids, actualWorkers, emulateCursor, quarantineMode);
callbackExists ? callback(errs, taskUid, actualWorkers) : true;

@@ -191,0 +191,0 @@ } else {

@@ -100,2 +100,6 @@ var path = require("path"), util = require("util"), http = require("http"), EventEmitter = require("events").EventEmitter, express = require("express"), io = require("socket.io"), ejs = require("ejs"), WorkerPool = require("./worker_pool").WorkerPool, errMsgBuilder = require("./err_msg_builder"), ERR = require("./server_errs");

POST("/delete_test", this._deleteTest);
POST("/dirs_by_path/", this._getDirsByPath);
POST("/dirs_by_path", this._getDirsByPath);
POST("/set_tests_dir/", this._setTestsDir);
POST("/set_tests_dir", this._setTestsDir);
POST("/recording/start/", this._record);

@@ -185,5 +189,7 @@ POST("/recording/start", this._record);

}
var testsDir = vfs.getBasePath();
if (slide) {
res.render("partial/tests_browser", {
testsBrowser: testsBrowser
testsBrowser: testsBrowser,
testsDir: testsDir
});

@@ -194,2 +200,3 @@ } else {

testsBrowser: testsBrowser,
testsDir: testsDir,
errMsgs: errs.length ? errs : null

@@ -200,2 +207,3 @@ });

testsBrowser: testsBrowser,
testsDir: testsDir,
expandRowFilename: expandRowFilename,

@@ -486,2 +494,35 @@ errMsgs: errs.length ? errs : null,

ControlPanel.prototype._getDirsByPath = function(req, res) {
var fsPath = req.param("path");
if (fsPath) {
this.vfs.getDirsByPath(decodeURIComponent(fsPath), function(err, dirs) {
res.status(200);
res.send(dirs);
});
} else {
this.vfs.getLocalDrives(function(err, devicesList) {
if (!err) {
res.status(200);
res.send(devicesList);
} else {
res.status(304);
res.send(errMsgBuilder.build(err));
}
});
}
};
ControlPanel.prototype._setTestsDir = function(req, res) {
var fsPath = decodeURIComponent(req.param("testsDir"));
this.vfs.setTestsDir(fsPath, function(err) {
if (!err) {
res.status(200);
res.end();
} else {
res.status(403);
res.send(errMsgBuilder.build(err));
}
});
};
ControlPanel.prototype._page404Handler = function(req, res) {

@@ -488,0 +529,0 @@ res.status(404);

@@ -187,3 +187,3 @@ var url = require("url"), util = require("util"), FixtureCode = require("../fixture_code"), ERR = require("./server_errs"), CLIENT_ERR = require("./../shared/client_errs");

case ERR.INJECTOR_DOCUMENT_PARSING_FAILED:
m("Failed to parse test page HTML-markup. %s", err.msgs && err.msgs.join(" "));
m("Failed to parse test page HTML-markup. %s", err.msg && err.msg.toString());
break;

@@ -319,2 +319,10 @@

case ERR.VIRTUAL_FILE_SYSTEM_DIR_DOESNT_READ:
m('The "%s" directory can\'t be read. It might have been deleted.', err.fsPath);
break;
case ERR.VIRTUAL_FILE_SYSTEM_NODEJS_CANT_GET_DRIVE_LIST:
m("It is impossible to get the list of local directories.");
break;
case ERR.WORKER_POOL_WORKER_NAME_IS_EMPTY:

@@ -434,7 +442,7 @@ m("Worker name is empty. The name should contain at least one character which cannot be a blank space.");

case CLIENT_ERR.API_INCORRECT_SELECT_ACTION_ARGUMENTS:
m('Error on step "%s": select action parameters contains incorrect value.', err.stepName);
m('Error on step "%s": select action\'s parameters contain an incorrect value.', err.stepName);
break;
case CLIENT_ERR.API_INCORRECT_WAIT_ACTION_FIRST_ARGUMENT:
m('Error on step "%s": wait action first parameter contains incorrect value.', err.stepName);
m('Error on step "%s": wait action\'s first parameter contains an incorrect value.', err.stepName);
break;

@@ -441,0 +449,0 @@ }

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

var zlib = require("zlib"), whacko = require("whacko"), iconv = require("iconv-lite"), sharedConst = require("./../shared/const"), urlUtil = require("./../shared/url_util"), pageProc = require("./../shared/page_processor"), ERR = require("./server_errs");
var zlib = require("zlib"), util = require("util"), whacko = require("whacko"), iconv = require("iconv-lite"), sharedConst = require("./../shared/const"), urlUtil = require("./../shared/url_util"), pageProc = require("./../shared/page_processor"), ERR = require("./server_errs");

@@ -33,3 +33,3 @@ var ZLIB_INFLATE_INVALID_ENCODING_ERR_CODE = "Z_DATA_ERROR", CHARSET_LIST = [ "iso-8859-1", "iso-8859-2", "iso-8859-3", "iso-8859-4", "iso-8859-5", "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-9", "iso-8859-10", "iso-8859-11", "iso-8859-12", "iso-8859-13", "iso-8859-14", "iso-8859-15", "iso-8859-16", "windows-1250", "windows-1251", "windows-1252", "windows-1253", "windows-1254", "windows-1255", "windows-1256", "windows-1257", "windows-1258", "windows-874", "windows-866", "koi8-r", "koi8-u", "utf-8", "utf-16", "utf-32", "shift-jis", "x-euc", "big5", "euc-kr" ];

var encodedData = concatChunks(chunks), decodingCallback = function(err, decodingRes) {
if (err || !(decodingRes && decodingRes.length)) {
if (err && !decodingRes) {
callback({

@@ -96,6 +96,2 @@ code: ERR.INJECTOR_RESOURCE_DECODING_FAILED,

}
if (!rawData) {
callback(null, "");
return;
}
try {

@@ -148,3 +144,3 @@ var processedData = processor(rawData, charset);

code: ERR.INJECTOR_DOCUMENT_PARSING_FAILED,
msgs: parseErrs
msg: parseErrs
};

@@ -163,18 +159,17 @@ }

var injection = [];
if (injectionOptions.startupScript) {
if (injectionOptions.styleUrl) {
injection.push('<link rel="stylesheet" type="text/css" class="');
injection.push(sharedConst.TEST_CAFE_UI_STYLESHEET_CLASSNAME);
injection.push('"href = "');
injection.push(injectionOptions.styleUrl);
injection.push('">');
}
if (injectionOptions.scriptUrl) {
injection.push('<script type="text/javascript" class="');
injection.push(sharedConst.TEST_CAFE_SCRIPT_CLASSNAME);
injection.push('" charset="UTF-8" src="');
injection.push(injectionOptions.scriptUrl);
injection.push('">');
injection.push("//<![CDATA[\n");
injection.push(injectionOptions.startupScript);
injection.push("//]]>\n");
injection.push("</script>");
}
if (injectionOptions.uiCss) {
injection.push('<style type="text/css" class="');
injection.push(sharedConst.TEST_CAFE_UI_STYLESHEET_CLASSNAME);
injection.push('">');
injection.push(injectionOptions.uiCss);
injection.push("</style>");
}
if (injection.length) {

@@ -181,0 +176,0 @@ $("head").prepend(injection.join(""));

@@ -1,19 +0,20 @@

var fs = require("fs"), path = require("path"), url = require("url"), util = require("util"), uuid = require("node-uuid"), assets = require("./assets"), cmd = require("../shared/service_msg_cmd"), ERR = require("./server_errs"), errMsgBuilder = require("./err_msg_builder"), FixtureCode = require("../fixture_code/"), injector = require("./injector"), urlUtil = require("../shared/url_util");
var fs = require("fs"), path = require("path"), url = require("url"), util = require("util"), uuid = require("node-uuid"), cmd = require("../shared/service_msg_cmd"), ERR = require("./server_errs"), errMsgBuilder = require("./err_msg_builder"), FixtureCode = require("../fixture_code/"), injector = require("./injector"), urlUtil = require("../shared/url_util");
var RECORDER_PAGE_HTML_TEMPLATE = "<!DOCTYPE html>" + "<html>" + "<head>" + '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' + "<title></title>" + '<style type="text/css">%s</style> ' + '<script type="text/javascript">%s</script>' + "</head>" + "<body></body>" + "</html>";
var RECORDER_PAGE_HTML_TEMPLATE = "<!DOCTYPE html>" + "<html>" + "<head>" + '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' + "<title></title>" + '<link href="%s" rel="stylesheet" type="text/css">' + '<script type="text/javascript">%s</script> ' + "</head>" + "<body></body>" + "</html>";
var Recorder = exports.Recorder = function(proxy, vfs, cookieShelf) {
var Recorder = exports.Recorder = function(proxy, vfs, cookieShelf, assetsManager) {
this.proxy = proxy;
this.vfs = vfs;
this.cookieShelf = cookieShelf;
this.assetsManager = assetsManager;
this.silentMode = false;
this.disableTooltip = false;
this.recordings = {};
this.recordingJsTmpl = new assets.JsTemplate(path.join(__dirname, "../_compiled_/client_runtime/recording.jstmpl"));
this.serverErrorPageJsTmpl = new assets.JsTemplate(path.join(__dirname, "../_compiled_/client_runtime/recorder_server_err_page.jstmpl"));
this.authenticationPageJsTmpl = new assets.JsTemplate(path.join(__dirname, "../_compiled_/client_runtime/authentication_page.jstmpl"));
this.proxy.addEventListener(Recorder.JOB_OWNER_TOKEN, this);
this.proxy.addOwnerDependentEventListener("beforeProxyResponse", Recorder.JOB_OWNER_TOKEN, this._onBeforeProxyResponse.bind(this));
this.proxy.addOwnerDependentEventListener("error", Recorder.JOB_OWNER_TOKEN, this._onProxyError.bind(this));
this.proxy.addOwnerDependentEventListener("serviceMsg", Recorder.JOB_OWNER_TOKEN, this._onServiceMsg.bind(this));
var proxyEvents = this.proxy.events.for(Recorder.JOB_OWNER_TOKEN);
proxyEvents.listen("authCredentialsRequested", this._onAuthCredentialsRequested.bind(this));
proxyEvents.listen("beforeProxyResponse", this._onBeforeProxyResponse.bind(this));
proxyEvents.listen("error", this._onProxyError.bind(this));
var serviceChannelEvents = this.proxy.serviceChannel.events.for(Recorder.JOB_OWNER_TOKEN);
serviceChannelEvents.listen("serviceMsg", this._onServiceMsg.bind(this));
serviceChannelEvents.listen("testCafeScriptRequested", this._onTestCafeScriptRequested.bind(this));
};

@@ -23,29 +24,7 @@

Recorder.prototype._redirectToServerErrorPage = function(proxyCtx, returnUrl) {
var parsedProxyUrl = urlUtil.parseProxyUrl(proxyCtx.req.url), serverErrorPageJs = this.serverErrorPageJsTmpl.getJs({
returnUrl: returnUrl,
errorCode: proxyCtx.originRes ? proxyCtx.originRes.statusCode : 500,
originUrl: parsedProxyUrl ? url.format(parsedProxyUrl.originResourceInfo) : ""
});
proxyCtx.res.statusCode = 500;
proxyCtx.res.setHeader("content-type", "text/html");
proxyCtx.res.end(util.format(RECORDER_PAGE_HTML_TEMPLATE, assets.getClientUICss(), serverErrorPageJs));
Recorder.prototype._onAuthCredentialsRequested = function(proxyCtx, callback) {
var recording = this.recordings[proxyCtx.jobInfo.uid];
callback(recording ? recording.authCredentials : null);
};
Recorder.prototype._redirectToAuthenticationPage = function(proxyCtx, returnUrl, currentCredentials) {
var parsedProxyUrl = urlUtil.parseProxyUrl(proxyCtx.req.url), authenticationPageJs = this.authenticationPageJsTmpl.getJs({
credentials: currentCredentials ? currentCredentials.username + ":" + currentCredentials.password : "",
returnUrl: returnUrl,
originUrl: parsedProxyUrl ? url.format(parsedProxyUrl.originResourceInfo) : ""
});
proxyCtx.res.statusCode = 401;
proxyCtx.res.setHeader("content-type", "text/html");
proxyCtx.res.end(util.format(RECORDER_PAGE_HTML_TEMPLATE, assets.getClientUICss(), authenticationPageJs));
};
Recorder.prototype.getAuthCredentials = function(jobUID) {
var recording = this.recordings[jobUID];
return recording ? recording.authCredentials : null;
};
Recorder.prototype._onBeforeProxyResponse = function(ctx, callback) {

@@ -59,3 +38,3 @@ var recording = this.recordings[ctx.jobInfo.uid];

if (ctx.originRes.statusCode === 401 && ctx.originResContentInfo.isPage) {
this._redirectToAuthenticationPage(ctx, recording.returnUrl, recording.authCredentials);
this._redirectToAuthenticationPage(ctx, recording);
return;

@@ -81,4 +60,4 @@ }

Recorder.prototype._onServiceMsg = function(msg, proxyCtx, callback) {
var recording = this.recordings[proxyCtx.jobInfo.uid], res = null;
Recorder.prototype._onServiceMsg = function(msg, callback) {
var recording = this.recordings[msg.jobUid], res = null;
if (recording) {

@@ -94,6 +73,2 @@ switch (msg.cmd) {

case cmd.SILENT_MODE_GET:
res = this.silentMode;
break;
case cmd.SILENT_MODE_SET:

@@ -103,6 +78,2 @@ this.silentMode = msg.silentMode;

case cmd.TOOLBAR_POSITION_GET:
res = recording.toolbarPosition;
break;
case cmd.TOOLBAR_POSITION_SET:

@@ -112,6 +83,2 @@ recording.toolbarPosition = msg.toolbarPosition;

case cmd.DISABLE_TOOLTIP_GET:
res = this.disableTooltip;
break;
case cmd.DISABLE_TOOLTIP_SET:

@@ -134,3 +101,3 @@ this.disableTooltip = msg.disableTooltip;

case cmd.ADD_TEST_CODE:
this.completeRecording(proxyCtx.jobInfo.uid, msg.testName, function(res) {
this.completeRecording(msg.jobUid, msg.testName, function(res) {
var err = res.err, fixtureFilename = res.fixtureFileName;

@@ -147,4 +114,5 @@ callback({

vfs.getRealPath(recording.fixturePath, recording.fixtureFileName, function(fileName) {
var username = msg.username, password = msg.password;
FixtureCode.CodeGenerator.editDirectives(fileName, {
auth: msg.credentials
auth: username + ":" + password
}, function(err) {

@@ -155,2 +123,6 @@ if (err) {

}
recording.authCredentials = {
username: username,
password: password
};
vfs.forceBuild(callback);

@@ -168,31 +140,68 @@ });

Recorder.prototype._injectRecording = function(proxyCtx, recording, callback) {
var recorder = this;
this.cookieShelf.getClientCookieString(proxyCtx.jobInfo, proxyCtx.originResourceInfo.url, function(cookie) {
var opt = {
startupScript: recorder.recordingJsTmpl.getJs({
returnUrl: recording.returnUrl,
jobUid: recording.uid,
jobOwnerToken: Recorder.JOB_OWNER_TOKEN,
cookie: cookie.replace(/'/g, "\\'"),
originHost: proxyCtx.originResourceInfo.host,
originProtocol: proxyCtx.originResourceInfo.protocol,
originHostname: proxyCtx.originResourceInfo.hostname,
originPort: proxyCtx.originResourceInfo.port || ""
}),
urlReplacer: recorder.proxy.getResourceUrlReplacer(proxyCtx),
uiCss: assets.getClientUICss()
};
injector.injectInPage(proxyCtx.originResBodyChunks, proxyCtx.originResContentInfo.encoding, proxyCtx.originResContentInfo.charset, opt, function(err, html) {
if (err) {
proxyCtx.originRes.statusCode = 500;
recorder._redirectToServerErrorPage(proxyCtx, recording.returnUrl);
} else {
proxyCtx.originResBodyChunks = [ html ];
callback();
}
Recorder.prototype._onTestCafeScriptRequested = function(refererInfo, callback) {
var recorder = this, recording = this.recordings[refererInfo.jobInfo.uid];
this.cookieShelf.getClientCookieString(refererInfo.jobInfo, refererInfo.originResourceInfo.url, function(cookie) {
var recordingScript = recorder.assetsManager.compileTemplate(recorder.assetsManager.TEMPLATES.RECORDING, {
returnUrl: recording.returnUrl,
jobUid: recording.uid,
jobOwnerToken: Recorder.JOB_OWNER_TOKEN,
serviceMsgUrl: recorder.proxy.serviceChannel.serviceMsgUrl,
cookie: cookie.replace(/'/g, "\\'"),
originHost: refererInfo.originResourceInfo.host,
originProtocol: refererInfo.originResourceInfo.protocol,
originHostname: refererInfo.originResourceInfo.hostname,
originPort: refererInfo.originResourceInfo.port || "",
silentMode: recorder.silentMode,
disableTooltip: recorder.disableTooltip,
toolbarPosLeft: recording.toolbarPosition.left,
toolbarPosTop: recording.toolbarPosition.top
});
callback(recordingScript);
});
};
Recorder.prototype._redirectToServerErrorPage = function(proxyCtx, returnUrl) {
var parsedProxyUrl = urlUtil.parseProxyUrl(proxyCtx.req.url), errorPageScript = this.assetsManager.compileTemplate(this.assetsManager.TEMPLATES.RECORDING_ERR_PAGE, {
returnUrl: returnUrl,
errorCode: proxyCtx.originRes ? proxyCtx.originRes.statusCode : 500,
originUrl: parsedProxyUrl ? url.format(parsedProxyUrl.originResourceInfo) : ""
});
proxyCtx.res.statusCode = 500;
proxyCtx.res.setHeader("content-type", "text/html");
proxyCtx.res.end(util.format(RECORDER_PAGE_HTML_TEMPLATE, this.assetsManager.uiStyleUrl, errorPageScript));
};
Recorder.prototype._redirectToAuthenticationPage = function(proxyCtx, recording) {
var parsedProxyUrl = urlUtil.parseProxyUrl(proxyCtx.req.url), authenticationPageScript = this.assetsManager.compileTemplate(this.assetsManager.TEMPLATES.RECORDING_AUTHENTICATION_PAGE, {
jobUid: recording.uid,
jobOwnerToken: Recorder.JOB_OWNER_TOKEN,
serviceMsgUrl: this.proxy.serviceChannel.serviceMsgUrl,
credentials: recording.authCredentials ? recording.authCredentials.username + ":" + recording.authCredentials.password : "",
returnUrl: recording.returnUrl,
targetUrl: proxyCtx.req.url,
originUrl: parsedProxyUrl ? url.format(parsedProxyUrl.originResourceInfo) : ""
});
var html = util.format(RECORDER_PAGE_HTML_TEMPLATE, this.assetsManager.uiStyleUrl, authenticationPageScript);
proxyCtx.res.statusCode = 401;
proxyCtx.res.setHeader("content-type", "text/html");
proxyCtx.res.end(html);
};
Recorder.prototype._injectRecording = function(proxyCtx, recording, callback) {
var recorder = this, opt = {
urlReplacer: this.proxy.getResourceUrlReplacer(proxyCtx),
styleUrl: this.assetsManager.uiStyleUrl,
scriptUrl: this.proxy.serviceChannel.testCafeScriptUrl
};
injector.injectInPage(proxyCtx.originResBodyChunks, proxyCtx.originResContentInfo.encoding, proxyCtx.originResContentInfo.charset, opt, function(err, html) {
if (err) {
proxyCtx.originRes.statusCode = 500;
recorder._redirectToServerErrorPage(proxyCtx, recording.returnUrl);
} else {
proxyCtx.originResBodyChunks = [ html ];
callback();
}
});
};
Recorder.prototype.startRecording = function(fixtureUid, returnUrl, callback) {

@@ -215,3 +224,7 @@ var recorder = this;

stepsInfo: [],
uid: recordingUid
uid: recordingUid,
toolbarPosition: {
left: null,
top: null
}
};

@@ -218,0 +231,0 @@ try {

@@ -26,3 +26,3 @@ var url = require("url"), util = require("util"), errMsgBuilder = require("./err_msg_builder"), moment = require("moment"), EventEmitter = require("events").EventEmitter;

Reporter.prototype.taskAdded = function(taskUid, name, testCount, workerNames) {
Reporter.prototype.taskAdded = function(taskUid, name, testCount, workerNames, reportUnstable) {
var taskReport = {

@@ -38,5 +38,8 @@ uid: taskUid,

passed: 0,
testErrReports: {},
completeTestRunCounters: {}
testErrReports: {}
};
if (reportUnstable) {
taskReport.unstableTests = {};
}
this.completedRunsPerTest = {};
this.taskReports.push(taskReport);

@@ -80,9 +83,23 @@ this.emit("taskUpdated", {

}
if (taskReport.unstableTests && testRun.quarantine.failed && testRun.quarantine.succeeded) {
if (!taskReport.unstableTests[testUid]) {
taskReport.unstableTests[testUid] = {
name: testRun.test.name,
fixtureName: testRun.fixture.name,
fixturePath: testRun.fixture.path.join("/"),
workerNames: []
};
}
taskReport.unstableTests[testUid].workerNames.push(testRun.workerName);
}
if (taskReport.testErrReports[testUid]) {
return;
}
taskReport.completeTestRunCounters[testUid] = taskReport.completeTestRunCounters[testUid] || 0;
if (++taskReport.completeTestRunCounters[testUid] === taskReport.workerNames.length) {
if (!this.completedRunsPerTest[testRun.taskUid]) {
this.completedRunsPerTest[testRun.taskUid] = {};
}
this.completedRunsPerTest[testRun.taskUid][testUid] = this.completedRunsPerTest[testRun.taskUid][testUid] || 0;
if (++this.completedRunsPerTest[testRun.taskUid][testUid] === taskReport.workerNames.length) {
taskReport.passed++;
if (Object.keys(taskReport.completeTestRunCounters).length < taskReport.testCount) {
if (taskReport.passed + taskReport.failed < taskReport.testCount) {
this.emit("taskUpdated", {

@@ -89,0 +106,0 @@ id: testRun.taskUid

@@ -101,2 +101,6 @@ exports.API_TESTS_TARGET_NOT_EXIST = "API_TESTS_TARGET_NOT_EXIST";

exports.VIRTUAL_FILE_SYSTEM_DIR_DOESNT_READ = "VIRTUAL_FILE_SYSTEM_DIR_DOESNT_READ";
exports.VIRTUAL_FILE_SYSTEM_NODEJS_CANT_GET_DRIVE_LIST = "VIRTUAL_FILE_SYSTEM_NODEJS_CANT_GET_DRIVE_LIST";
exports.WORKER_POOL_FAILED_TO_START_BROWSER = "WORKER_POOL_FAILED_TO_START_BROWSER";

@@ -103,0 +107,0 @@

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

var fs = require("fs"), util = require("util"), os = require("os"), path = require("path"), EventEmitter = require("events").EventEmitter, moment = require("moment"), errMsgBuilder = require("./err_msg_builder"), Reporter = require("./reporter").Reporter, Proxy = require("./proxy").Proxy, CookieShelf = require("./cookie_shelf").CookieShelf, TestRunner = require("./test_runner").TestRunner, Recorder = require("./recorder").Recorder, VirtualFS = require("./vfs").VirtualFS, WorkerPool = require("./worker_pool").WorkerPool, Api = require("./api").Api, Config = require("./config").Config, ControlPanel = require("./control_panel").ControlPanel;
var EventEmitter = require("events").EventEmitter, exec = require("child_process").exec, fs = require("fs"), moment = require("moment"), os = require("os"), path = require("path"), util = require("util"), Api = require("./api").Api, AssetsManager = require("./assets_manager"), Config = require("./../config").Config, ControlPanel = require("./control_panel").ControlPanel, CookieShelf = require("./cookie_shelf").CookieShelf, errMsgBuilder = require("./err_msg_builder"), Proxy = require("../proxy/"), Recorder = require("./recorder").Recorder, Reporter = require("./reporter").Reporter, TestRunner = require("./test_runner").TestRunner, VirtualFS = require("./vfs").VirtualFS, WorkerPool = require("./worker_pool").WorkerPool;

@@ -12,2 +12,3 @@ var GREETING = "DevExpress TestCafe - functional testing for the web.\n" + "Copyright (C) 2012 - %s Developer Express Inc.\n" + "-----------------------------------------------\n", CONTROL_PANEL_URL_INFO_PATTERN = "Control Panel URL - http://%s\n\n", SHUTDOWN_MSG_PATTERN = "%s - Initialization Error:\n%s\n";

this.workerPool = null;
this.assetsManager = null;
this._init(startupCfg, standalone);

@@ -49,36 +50,57 @@ };

TestCafe.prototype._init = function(startupCfg, standalone) {
var testCafe = this;
if (standalone) {
util.print(util.format(GREETING, new Date().getFullYear()));
}
try {
var config = new Config(startupCfg);
} catch (err) {
var messages = errMsgBuilder.build(util.isArray(err) ? err : [ err ]);
this._fatalError(messages.join("\n"), standalone);
}
var reporter = new Reporter(), cookieShelf = new CookieShelf();
this.proxy = new Proxy(config.servicePort, config.hostname, cookieShelf);
var testCafe = this;
this.proxy.on("fatalError", function(err) {
testCafe._fatalError(errMsgBuilder.build(err), standalone);
testCafe.config = new Config();
testCafe._initConfig(startupCfg, function(config, err) {
if (err) {
var messages = errMsgBuilder.build(util.isArray(err) ? err : [ err ]);
testCafe._fatalError(messages.join("\n"), standalone);
}
var reporter = new Reporter(), cookieShelf = new CookieShelf();
testCafe.proxy = new Proxy(config.servicePort, config.hostname, cookieShelf);
testCafe.proxy.events.broadcast.listen("fatalError", function(err) {
testCafe._fatalError(errMsgBuilder.build(err), standalone);
});
testCafe.assetsManager = new AssetsManager(testCafe.proxy.serviceChannel);
try {
testCafe.vfs = new VirtualFS(config.testsDir, testCafe.config);
} catch (err) {
testCafe._fatalError(errMsgBuilder.build(err), standalone);
}
testCafe.workerPool = new WorkerPool(config);
testCafe.testRunner = new TestRunner(testCafe.proxy, reporter, testCafe.workerPool, cookieShelf, testCafe.assetsManager, config.controlPanelHost);
var recorder = new Recorder(testCafe.proxy, testCafe.vfs, cookieShelf, testCafe.assetsManager);
Api.call(testCafe, testCafe.testRunner, testCafe.workerPool, reporter, testCafe.vfs, config, standalone);
testCafe.controlPanel = new ControlPanel(config.controlPanelPort, testCafe.testRunner, testCafe.vfs, testCafe.workerPool, reporter, testCafe, recorder);
testCafe.controlPanel.on("fatalError", function(err) {
testCafe._fatalError(errMsgBuilder.build(err), standalone);
});
testCafe.proxy.start();
testCafe.controlPanel.start();
if (standalone) {
var controlPanelHost = config.hostname === "127.0.0.1" ? "localhost:" + config.controlPanelPort : config.controlPanelHost;
util.print(util.format(CONTROL_PANEL_URL_INFO_PATTERN, controlPanelHost));
var controlPanelUrl = "http://" + controlPanelHost.replace(/"/, '\\"'), platform = os.platform();
if (platform.match(/^win/)) {
exec('start "" "' + controlPanelUrl + '"');
} else {
if (platform === "darwin") {
exec("open " + controlPanelUrl);
} else {
exec("xdg-open " + controlPanelUrl);
}
}
}
});
try {
this.vfs = new VirtualFS(config.testsDir);
} catch (err) {
this._fatalError(errMsgBuilder.build(err), standalone);
};
TestCafe.prototype._initConfig = function(startupCfg, callback) {
if (startupCfg) {
var result = this.config.initFromObj(startupCfg);
callback(result.cfg, result.errs);
} else {
this.config.initFromFile(callback);
}
this.workerPool = new WorkerPool(config);
this.testRunner = new TestRunner(this.proxy, reporter, this.workerPool, cookieShelf, config.controlPanelHost);
var recorder = new Recorder(this.proxy, this.vfs, cookieShelf);
Api.call(this, this.testRunner, this.workerPool, reporter, this.vfs, config, standalone);
this.controlPanel = new ControlPanel(config.controlPanelPort, this.testRunner, this.vfs, this.workerPool, reporter, this, recorder);
this.controlPanel.on("fatalError", function(err) {
testCafe._fatalError(errMsgBuilder.build(err), standalone);
});
this.proxy.start();
this.controlPanel.start();
if (standalone) {
var controlPanelHost = config.hostname === "127.0.0.1" ? "localhost:" + config.controlPanelPort : config.controlPanelHost;
util.print(util.format(CONTROL_PANEL_URL_INFO_PATTERN, controlPanelHost));
}
};

@@ -1,4 +0,4 @@

var EventEmitter = require("events").EventEmitter, path = require("path"), url = require("url"), util = require("util"), uuid = require("node-uuid"), assets = require("./assets"), CLIENT_ERR = require("../shared/client_errs"), cmd = require("../shared/service_msg_cmd"), ERR = require("./server_errs"), injector = require("./injector");
var EventEmitter = require("events").EventEmitter, path = require("path"), url = require("url"), util = require("util"), uuid = require("node-uuid"), CLIENT_ERR = require("../shared/client_errs"), cmd = require("../shared/service_msg_cmd"), ERR = require("./server_errs"), injector = require("./injector");
var PAGE_ERROR_VERIFICATION_HTML_TEMPLATE = "/*" + "<!DOCTYPE html>" + "<html>" + "<head>" + "<title></title>" + '<script type="text/javascript">%s</script>' + "</head>" + "<body></body>" + "</html>" + "*/";
var PAGE_ERROR_VERIFICATION_HTML_TEMPLATE = "/*" + "<!DOCTYPE html>" + "<html>" + "<head>" + "<title></title>" + '<script type="text/javascript">%s</script>' + "</head>" + "<body></body>" + "</html>" + "*/", QUARANTINE_TEST_RUN_COUNT = 3;

@@ -15,3 +15,3 @@ function proxyErrRes(proxyCtx, resBody) {

var TestRunner = exports.TestRunner = function(proxy, reporter, workerPool, cookieShelf, controlPanelHost) {
var TestRunner = exports.TestRunner = function(proxy, reporter, workerPool, cookieShelf, assetsManager, controlPanelHost) {
EventEmitter.call(this);

@@ -23,11 +23,13 @@ this.controlPanelHost = controlPanelHost;

this.cookieShelf = cookieShelf;
this.testRunJsTmpl = new assets.JsTemplate(path.join(__dirname, "../_compiled_/client_runtime/test_run.jstmpl"));
this.errHandlerJsTmpl = new assets.JsTemplate(path.join(__dirname, "../_compiled_/client_runtime/test_run_err_handler.jstmpl"));
this.assetsManager = assetsManager;
this.tasks = {};
this.testRuns = {};
this.workerPool.on("workerDisconnected", this._onWorkerDisconnected.bind(this));
this.proxy.addEventListener(TestRunner.JOB_OWNER_TOKEN, this);
this.proxy.addOwnerDependentEventListener("beforeProxyResponse", TestRunner.JOB_OWNER_TOKEN, this._onBeforeProxyResponse.bind(this));
this.proxy.addOwnerDependentEventListener("error", TestRunner.JOB_OWNER_TOKEN, this._onProxyError.bind(this));
this.proxy.addOwnerDependentEventListener("serviceMsg", TestRunner.JOB_OWNER_TOKEN, this._onServiceMsg.bind(this));
var proxyEvents = this.proxy.events.for(TestRunner.JOB_OWNER_TOKEN);
proxyEvents.listen("authCredentialsRequested", this._onAuthCredentialsRequested.bind(this));
proxyEvents.listen("beforeProxyResponse", this._onBeforeProxyResponse.bind(this));
proxyEvents.listen("error", this._onProxyError.bind(this));
var serviceChannelEvents = this.proxy.serviceChannel.events.for(TestRunner.JOB_OWNER_TOKEN);
serviceChannelEvents.listen("serviceMsg", this._onServiceMsg.bind(this));
serviceChannelEvents.listen("testCafeScriptRequested", this._onTestCafeScriptRequested.bind(this));
};

@@ -46,5 +48,5 @@

TestRunner.prototype.getAuthCredentials = function(jobUID) {
var testRun = this.testRuns[jobUID];
return testRun ? testRun.authCredentials : null;
TestRunner.prototype._onAuthCredentialsRequested = function(proxyCtx, callback) {
var testRun = this.testRuns[proxyCtx.jobInfo.uid];
callback(testRun ? testRun.authCredentials : null);
};

@@ -79,5 +81,5 @@

}
return;
} else {
callback();
}
callback();
};

@@ -95,10 +97,11 @@

var causeUid = this._addPossibleTestFailCause(testRun, err);
var verificationJs = this.errHandlerJsTmpl.getJs({
var errHandlerScript = this.assetsManager.compileTemplate(this.assetsManager.TEMPLATES.TEST_RUN_ERR_HANDLER, {
workerIdleUrl: this.workerPool.getWorkerIdleUrl(testRun.workerName),
jobUid: testRun.uid,
jobOwnerToken: TestRunner.JOB_OWNER_TOKEN,
serviceMsgUrl: this.proxy.serviceChannel.serviceMsgUrl,
error: JSON.stringify(err),
removeFailCauseUid: causeUid
});
proxyErrRes(proxyCtx, util.format(PAGE_ERROR_VERIFICATION_HTML_TEMPLATE, verificationJs));
proxyErrRes(proxyCtx, util.format(PAGE_ERROR_VERIFICATION_HTML_TEMPLATE, errHandlerScript));
} else {

@@ -112,4 +115,29 @@ this._addPossibleTestFailCause(testRun, err);

TestRunner.prototype._onServiceMsg = function(msg, proxyCtx, callback) {
var res = null, expectedInactivityDuration = null, testRun = this.testRuns[proxyCtx.jobInfo.uid];
TestRunner.prototype._onTestCafeScriptRequested = function(refererInfo, callback) {
var runner = this, testRun = this.testRuns[refererInfo.jobInfo.uid];
this.cookieShelf.getClientCookieString(refererInfo.jobInfo, refererInfo.originResourceInfo.url, function(cookie) {
var testRunScript = runner.assetsManager.compileTemplate(runner.assetsManager.TEMPLATES.TEST_RUN, {
stepNames: refererInfo.isIFrame ? "null" : JSON.stringify(testRun.test.stepData.names),
testSteps: refererInfo.isIFrame ? "null" : testRun.test.stepData.js,
sharedJs: refererInfo.isIFrame ? "null" : testRun.fixture.sharedJs,
nextStep: testRun.nextStep,
workerIdleUrl: runner.workerPool.getWorkerIdleUrl(testRun.workerName),
restartTestRunUrl: runner.workerPool.getRestartTestRunUrl(testRun.workerName),
halted: testRun.halted,
jobUid: testRun.uid,
jobOwnerToken: TestRunner.JOB_OWNER_TOKEN,
serviceMsgUrl: runner.proxy.serviceChannel.serviceMsgUrl,
cookie: cookie.replace(/'/g, "\\'"),
originHost: refererInfo.originResourceInfo.host,
originProtocol: refererInfo.originResourceInfo.protocol,
originHostname: refererInfo.originResourceInfo.hostname,
originPort: refererInfo.originResourceInfo.port || "",
emulateCursor: testRun.emulateCursor
});
callback(testRunScript);
});
};
TestRunner.prototype._onServiceMsg = function(msg, callback) {
var res = null, expectedInactivityDuration = null, testRun = this.testRuns[msg.jobUid];
if (testRun && !testRun.halted) {

@@ -134,6 +162,2 @@ switch (msg.cmd) {

case cmd.RESET_ALL_POSSIBLE_FAIL_CAUSES:
testRun.possibleFailCauses = [];
break;
case cmd.TEST_COMPLETE:

@@ -151,14 +175,2 @@ testRun.halted = true;

case cmd.GET_CURSOR_POS:
res = testRun.cursorPos;
break;
case cmd.SET_CURSOR_POS:
testRun.cursorPos = msg.cursorPos;
break;
case cmd.GET_NEXT_STEP:
res = testRun.nextStep;
break;
case cmd.SET_NEXT_STEP:

@@ -212,33 +224,19 @@ testRun.nextStep = msg.nextStep;

var runner = this;
this.cookieShelf.getClientCookieString(proxyCtx.jobInfo, proxyCtx.originResourceInfo.url, function(cookie) {
var opt = {
startupScript: runner.testRunJsTmpl.getJs({
testSteps: testRun.test.stepData.js,
stepNames: JSON.stringify(testRun.test.stepData.names),
workerIdleUrl: runner.workerPool.getWorkerIdleUrl(testRun.workerName),
restartTestRunUrl: runner.workerPool.getRestartTestRunUrl(testRun.workerName),
sharedJs: testRun.fixture.sharedJs,
halted: testRun.halted,
jobUid: testRun.uid,
jobOwnerToken: TestRunner.JOB_OWNER_TOKEN,
cookie: cookie.replace(/'/g, "\\'"),
originHost: proxyCtx.originResourceInfo.host,
originProtocol: proxyCtx.originResourceInfo.protocol,
originHostname: proxyCtx.originResourceInfo.hostname,
originPort: proxyCtx.originResourceInfo.port || "",
emulateCursor: testRun.emulateCursor
}),
urlReplacer: runner.proxy.getResourceUrlReplacer(proxyCtx),
uiCss: assets.getClientUICss()
};
injector.injectInPage(proxyCtx.originResBodyChunks, proxyCtx.originResContentInfo.encoding, proxyCtx.originResContentInfo.charset, opt, function(err, html) {
if (err) {
testRun.halted = true;
runner._addTestError(testRun, err);
runner.workerPool.redirectToWorkerIdle(proxyCtx, testRun.workerName);
} else {
proxyCtx.originResBodyChunks = [ html ];
callback();
}
});
if (!proxyCtx.isIFrame) {
testRun.possibleFailCauses = [];
}
var opt = {
urlReplacer: this.proxy.getResourceUrlReplacer(proxyCtx),
styleUrl: this.assetsManager.uiStyleUrl,
scriptUrl: this.proxy.serviceChannel.testCafeScriptUrl
};
injector.injectInPage(proxyCtx.originResBodyChunks, proxyCtx.originResContentInfo.encoding, proxyCtx.originResContentInfo.charset, opt, function(err, html) {
if (err) {
testRun.halted = true;
runner._addTestError(testRun, err);
runner.workerPool.redirectToWorkerIdle(proxyCtx, testRun.workerName);
} else {
proxyCtx.originResBodyChunks = [ html ];
callback();
}
});

@@ -280,6 +278,7 @@ };

TestRunner.prototype.addTask = function(name, suite, testUids, workerNames, emulateCursor) {
TestRunner.prototype.addTask = function(name, suite, testUids, workerNames, emulateCursor, quarantineMode) {
var runner = this, taskUid = uuid.v4(), task = {
pendingTestRunCount: 0,
started: false
started: false,
quarantineMode: quarantineMode
};

@@ -292,3 +291,2 @@ workerNames.forEach(function(workerName) {

authCredentials: fixture.authCredentials,
cursorPos: null,
emulateCursor: emulateCursor,

@@ -298,3 +296,3 @@ errs: [],

halted: false,
nextStep: null,
nextStep: 0,
possibleFailCauses: [],

@@ -306,3 +304,8 @@ restartCount: 0,

uid: testRunUid,
workerName: workerName
workerName: workerName,
quarantine: {
succeeded: 0,
failed: 0,
lastFailedRunErrs: []
}
};

@@ -314,3 +317,3 @@ worker.testRuns.push(testRunUid);

this.tasks[taskUid] = task;
this.reporter.taskAdded(taskUid, name, testUids.length, workerNames);
this.reporter.taskAdded(taskUid, name, testUids.length, workerNames, quarantineMode);
var taskReport = runner.reporter.getTaskReportByUid(taskUid);

@@ -335,4 +338,25 @@ workerNames.forEach(function(workerName) {

TestRunner.prototype._quarantine = function(testRun) {
if (testRun.errs.length) {
testRun.quarantine.lastFailedRunErrs = testRun.errs;
testRun.quarantine.failed++;
} else {
testRun.quarantine.succeeded++;
}
if (testRun.quarantine.failed > 0) {
if (testRun.quarantine.succeeded + testRun.quarantine.failed < QUARANTINE_TEST_RUN_COUNT) {
this._resetTestRun(testRun);
return true;
} else {
testRun.errs = testRun.quarantine.failed > testRun.quarantine.succeeded ? testRun.quarantine.lastFailedRunErrs : [];
}
}
return false;
};
TestRunner.prototype._completeTestRun = function(testRun) {
var task = this.tasks[testRun.taskUid], workerName = testRun.workerName, worker = this.workerPool.get(workerName);
if (task.quarantineMode && this._quarantine(testRun)) {
return;
}
this.cookieShelf.removeCookies({

@@ -366,2 +390,13 @@ ownerToken: TestRunner.JOB_OWNER_TOKEN,

TestRunner.prototype._resetTestRun = function(testRun) {
testRun.errs = [];
testRun.halted = false;
testRun.nextStep = 0;
testRun.stepsSharedData = null;
this.cookieShelf.removeCookies({
ownerToken: TestRunner.JOB_OWNER_TOKEN,
uid: testRun.uid
});
};
TestRunner.prototype.restartCurrentTestRun = function(workerName) {

@@ -376,12 +411,5 @@ var worker = this.workerPool.get(workerName), testRunUid = worker.testRuns.length && worker.testRuns[0], testRun = this.testRuns[testRunUid];

} else {
testRun.errs = [];
testRun.halted = false;
testRun.nextStep = 0;
testRun.stepsSharedData = null;
this.cookieShelf.removeCookies({
ownerToken: TestRunner.JOB_OWNER_TOKEN,
uid: testRunUid
});
this._resetTestRun(testRun);
}
}
};

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

var fs = require("fs"), path = require("path"), util = require("util"), uuid = require("node-uuid"), EventEmitter = require("events").EventEmitter, async = require("async"), suite = require("./suite"), FixtureCode = require("../fixture_code/"), ERR = require("./server_errs");
var fs = require("fs"), path = require("path"), util = require("util"), uuid = require("node-uuid"), EventEmitter = require("events").EventEmitter, Process = require("child_process"), async = require("async"), suite = require("./suite"), FixtureCode = require("../fixture_code/"), ERR = require("./server_errs");

@@ -25,3 +25,3 @@ function validateBasePath(basePath) {

var getPlatformDependentPath = function(universalPath) {
return universalPath.replace(new RegExp(VirtualFS.PATH_UNIVERSAL_SEPARATOR, "g"), VirtualFS.PLATFORM_PATH_SEPARATOR);
return universalPath.replace(new RegExp(VirtualFS.PATH_UNIVERSAL_SEPARATOR, "g"), path.sep);
};

@@ -79,7 +79,6 @@

var VirtualFS = exports.VirtualFS = function(basePath) {
var VirtualFS = exports.VirtualFS = function(basePath, config) {
EventEmitter.call(this);
basePath = preparePath(basePath);
validateBasePath(basePath);
this.basePath = basePath;
this.basePath = null;
this.config = config;
this.requireRebuild = true;

@@ -90,2 +89,3 @@ this.suiteCache = null;

this.rebuildLock = false;
this.setBasePath(basePath);
};

@@ -107,4 +107,10 @@

VirtualFS.PLATFORM_PATH_SEPARATOR = VirtualFS.WIN_PLATFORM ? "\\" : VirtualFS.PATH_UNIVERSAL_SEPARATOR;
VirtualFS.GET_LOCAL_DRIVES_CMD = "wmic logicaldisk get name, description";
VirtualFS.GET_LOCAL_DRIVES_DESC = "Local Fixed Disk";
VirtualFS.CMD_OUTPUT_NEWLINE_CHARACTER = "\r\r\n";
VirtualFS.CFG_FILE_PATH = path.join(__dirname, "../../config.json");
VirtualFS.getTestUidsByPath = function(suite, dirPath) {

@@ -118,2 +124,8 @@ var testUids = [], fixtures = getFixturesByPath(suite, dirPath, false);

VirtualFS.prototype.setBasePath = function(basePath) {
var newBasePath = preparePath(basePath);
validateBasePath(newBasePath);
this.basePath = newBasePath;
};
VirtualFS.prototype.watchRevisionChanges = function() {

@@ -197,3 +209,3 @@ var vfs = this;

VirtualFS.prototype.getPathInfo = function(dirPath, callback) {
var vfs = this, fsPath = path.join(vfs.basePath, dirPath.join(VirtualFS.PLATFORM_PATH_SEPARATOR));
var vfs = this, fsPath = path.join(vfs.basePath, dirPath.join(path.sep));
var getInfoFromSuite = function() {

@@ -637,2 +649,84 @@ vfs.getSuite(function(suite) {

VirtualFS.prototype.getLocalDrives = function(callback) {
if (VirtualFS.WIN_PLATFORM) {
Process.exec(VirtualFS.GET_LOCAL_DRIVES_CMD, function(err, stdout) {
var stdoutLines = stdout.split(VirtualFS.CMD_OUTPUT_NEWLINE_CHARACTER), drives = stdoutLines.splice(1, stdoutLines.length - 3), result = [];
if (err) {
err = ERR.VIRTUAL_FILE_SYSTEM_NODEJS_CANT_GET_DRIVE_LIST;
}
for (var i = 0, length = drives.length; i < length; i++) {
if (drives[i].indexOf(VirtualFS.GET_LOCAL_DRIVES_DESC) === -1) {
continue;
}
var driveName = drives[i].replace(VirtualFS.GET_LOCAL_DRIVES_DESC, "").replace(/\s*/g, "") + path.sep;
result.push({
text: driveName,
id: encodeURIComponent(driveName)
});
}
callback(err, result);
});
} else {
callback(null, [ {
text: VirtualFS.PATH_UNIVERSAL_SEPARATOR,
id: encodeURIComponent(VirtualFS.PATH_UNIVERSAL_SEPARATOR)
} ]);
}
};
VirtualFS.prototype.getDirsByPath = function(fsPath, callback) {
var dirs = [], fsPath = getPlatformDependentPath(fsPath);
fs.readdir(fsPath, function(err, items) {
if (err) {
err = {
code: ERR.VIRTUAL_FILE_SYSTEM_DIR_DOESNT_READ,
fsPath: fsPath
};
}
if (items) {
async.forEachSeries(items, function(elm, elmListCallback) {
var elmPath = path.join(fsPath, elm);
fs.stat(elmPath, function(err, stats) {
if (!err && stats.isDirectory()) {
dirs.push({
text: elm,
id: encodeURIComponent(elmPath)
});
}
elmListCallback();
});
}, function() {
callback(err, dirs);
});
} else {
callback(err, dirs);
}
});
};
VirtualFS.prototype.setTestsDir = function(fsPath, callback) {
var vfs = this, basePath = vfs.basePath, dirNotExistsErr = {
code: ERR.VIRTUAL_FILE_SYSTEM_DIR_DOESNT_READ,
fsPath: fsPath
};
vfs.removeFSWatchers();
try {
vfs.setBasePath(fsPath);
} catch (err) {
vfs._setupFSWatchers(basePath);
callback(err && dirNotExistsErr);
return;
}
vfs.suiteCache = null;
this.forceBuild(function() {
vfs.config.setTestsDir(fsPath, function(err) {
callback(err && dirNotExistsErr);
});
});
};
VirtualFS.prototype.getBasePath = function() {
return getPlatformDependentPath(this.basePath);
};
exports.getPlatformDependentPath = getPlatformDependentPath;
var async = require("async"), EventEmitter = require("events").EventEmitter, execFile = require("child_process").execFile, fs = require("fs"), path = require("path"), url = require("url"), util = require("util"), userAgentParser = require("useragent"), uuid = require("node-uuid"), ERR = require("./server_errs");
var ADD_WORKER_URL_PATHNAME_PATTERN = "/worker/add/%s/", WORKER_IDLE_URL_PATHNAME_PATTERN = "/worker/idle/%s/", CREATE_WORKER_ON_LOCAL_BROWSER_TIMEOUT = 1e4;
var ADD_WORKER_URL_PATHNAME_PATTERN = "/worker/add/%s/", WORKER_IDLE_URL_PATHNAME_PATTERN = "/worker/idle/%s/", CREATE_WORKER_ON_LOCAL_BROWSER_TIMEOUT = 3e4;

@@ -18,3 +18,3 @@ function sanitizeWorkerName(name) {

WorkerPool.WORKER_HEARTBEAT_TIMEOUT = 6e4;
WorkerPool.WORKER_HEARTBEAT_TIMEOUT = 24e4;

@@ -21,0 +21,0 @@ var WORKER_TYPE = WorkerPool.WORKER_TYPE = {

@@ -6,3 +6,2 @@ TestCafeClient = typeof TestCafeClient === "undefined" ? {} : TestCafeClient;

root.PROXY_SERVICE_MSG_REQUEST_HEADER = "x-tc-sm-c8f5bd4f";
root.XHR_IS_TESTCAFE_REQUEST = "is_tc_req-c8f5bd4f";
root.XHR_REQUEST_MARKER_HEADER = "x-tc-xm-cd46977f";

@@ -24,4 +23,5 @@ root.XHR_CORS_SUPPORTED_FLAG = "cors";

root.TEST_CAFE_PROPERTY_PREFIX = "tc-1b082a6cec-51966-";
root.OLD_ATTR_VALUES = root.TEST_CAFE_PROPERTY_PREFIX + "oldAttrValues";
root.ACTION_FUNC_NAMES = [ "click", "rclick", "dblclick", "drag", "type", "wait", "hover", "press", "select" ];
root.PROPERTIES_FOR_WRAPPING = [ "innerHTML", "src", "href", "action", "location", "domain", "cookie", "referrer", "URL", "onbeforeunload" ];
})();

@@ -21,9 +21,12 @@ TestCafeClient = typeof TestCafeClient === "undefined" ? {} : TestCafeClient;

var getAttr = function($el, attr) {
return isNode ? $el[0].attribs[attr] : TCC.domSandbox.nativeMethods.getAttribute.call($el[0], attr);
return isNode ? $el[0].attribs[attr] : TCC.sandboxes.dom.nativeMethods.getAttribute.call($el[0], attr);
};
var getTagName = function($el) {
return isNode ? $el[0].name : $el[0].tagName;
};
var setAttr = function($el, attr, value) {
return isNode ? $el[0].attribs[attr] = value : TCC.domSandbox.nativeMethods.setAttribute.call($el[0], attr, value);
return isNode ? $el[0].attribs[attr] = value : TCC.sandboxes.dom.nativeMethods.setAttribute.call($el[0], attr, value);
};
var removeAttr = function($el, attr) {
return isNode ? $el.removeAttr(attr) : $el[0].removeAttribute(attr);
return isNode ? $el.removeAttr(attr) : TCC.sandboxes.dom.nativeMethods.removeAttribute.call($el[0], attr);
};

@@ -52,19 +55,22 @@ var syncWrapProps = function($el, urlAttr) {

};
var enumAttrs = function($el, attrRegEx, action) {
var attributes = $el[0].attributes || [];
var attrNameWrappingRequired = function($el, attr) {
var tagName = getTagName($el).toLowerCase();
return (attr !== "action" || tagName !== "form") && (attr !== "href" || tagName !== "a" && tagName !== "area" && tagName !== "link" && tagName !== "base") && (attr !== "hreflang" || tagName !== "a" && tagName !== "link") && (attr !== "nohref" || tagName !== "area") && (attr !== "src" || tagName !== "script" && tagName !== "input" && tagName !== "frame" && tagName !== "iframe" && tagName !== "img" && tagName !== "embed");
};
var enumAttrs = function($el, action) {
if (isNode) {
for (var attr in $el[0].attribs) {
if (Object.prototype.hasOwnProperty.call($el[0].attribs, attr)) {
attributes.push({
nodeName: attr
});
Object.keys($el[0].attribs).forEach(function(attr) {
if (attr.indexOf(consts.DOM_SANDBOX_STORED_ATTR_KEY_PREFIX) === -1) {
action(attr);
}
});
} else {
var attributes = $el[0].attributes || [];
for (var i = 0; i < attributes.length; i++) {
var attr = attributes[i].nodeName;
if (attr.indexOf(consts.DOM_SANDBOX_STORED_ATTR_KEY_PREFIX) === -1) {
action(attr);
}
}
}
for (var i = 0; i < attributes.length; i++) {
var attr = attributes[i].nodeName;
if (attrRegEx.test(attr) && attr.indexOf(consts.DOM_SANDBOX_STORED_ATTR_KEY_PREFIX) === -1) {
action(attr);
}
}
};

@@ -83,2 +89,7 @@ var processTargetBlank = function($el) {

}
}, processStyleAttr = function($el, urlReplacer) {
var style = getAttr($el, "style");
if (style) {
setAttr($el, "style", root.processStylesheet(style, urlReplacer));
}
}, processScript = function($script) {

@@ -95,12 +106,2 @@ if (isNode) {

}
}, processForm = function($form) {
var method = getAttr($form, "METHOD");
if (!isNode && (!method || method.toLowerCase() === "get")) {
var action = getAttr($form, "action"), desc = urlUtil.parseUrl(action).query[urlUtil.REQUEST_DESCRIPTOR_QUERY_KEY];
$("<input>", {
type: "hidden",
name: urlUtil.REQUEST_DESCRIPTOR_QUERY_KEY,
value: desc
}).appendTo($form);
}
}, processEvtHandlers = function($el) {

@@ -154,12 +155,16 @@ if (isNode) {

}
}, processAttrValue = function($el, urlReplacer, pattern) {
enumAttrs($el, pattern.attrRegEx, function(attr) {
setAttr($el, attr, root.wrapProps(getAttr($el, attr)));
}, processAttrValue = function($el) {
enumAttrs($el, function(attr) {
if (attr === "id" || attr === "class" || attr.indexOf("data-") === 0) {
setAttr($el, attr, root.wrapProps(getAttr($el, attr)));
}
});
}, processCustomAttr = function($el, urlReplacer, pattern) {
enumAttrs($el, pattern.attrRegEx, function(attr) {
var replacedAttr = root.wrapProps(attr);
if (replacedAttr !== attr) {
setAttr($el, replacedAttr, getAttr($el, attr));
removeAttr($el, attr);
}, processCustomAttr = function($el) {
enumAttrs($el, function(attr) {
if (attrNameWrappingRequired($el, attr)) {
var replacedAttr = root.wrapProps(attr);
if (replacedAttr !== attr) {
setAttr($el, replacedAttr, getAttr($el, attr));
removeAttr($el, attr);
}
}

@@ -179,3 +184,3 @@ });

urlAttr: "action",
elementProcessors: [ processTargetBlank, processUrlAttrs, processForm ]
elementProcessors: [ processTargetBlank, processUrlAttrs ]
}, {

@@ -196,9 +201,4 @@ selector: "iframe",

selector: "*",
attrRegEx: /^(data-|id$|class$)/i,
elementProcessors: [ processAttrValue ]
elementProcessors: [ processAttrValue, processCustomAttr, processStyleAttr ]
}, {
selector: "*",
attrRegEx: /^data-/i,
elementProcessors: [ processCustomAttr ]
}, {
selector: "script",

@@ -218,3 +218,3 @@ elementProcessors: [ processScript ]

if (!isNode && $.browser.msie && parseInt($.browser.version, 10) === 9 && $el[0].tagName.toLowerCase() === "script") {
var $clone = $(TCC.domSandbox.nativeMethods.cloneNode.call($el[0], false));
var $clone = $(TCC.sandboxes.dom.nativeMethods.cloneNode.call($el[0], false));
$clone[0].src = $clone[0].innerHTML = "";

@@ -225,2 +225,6 @@ return $clone;

};
var isTestCafeElement = function($el) {
var el = $el[0];
return typeof el.className === "string" && el.className.indexOf(consts.TEST_CAFE_UI_CLASSNAME_POSTFIX) > -1;
};
root.processPage = function($, urlReplacer) {

@@ -242,3 +246,3 @@ for (var i = 0; i < ELEMENT_PROCESSOR_PATTERNS.length; i++) {

var pattern = ELEMENT_PROCESSOR_PATTERNS[i];
if ($elementForSelectorCheck.is(pattern.selector)) {
if ($elementForSelectorCheck.is(pattern.selector) && !isTestCafeElement($el)) {
for (var j = 0; j < pattern.elementProcessors.length; j++) {

@@ -261,4 +265,7 @@ pattern.elementProcessors[j]($el, urlReplacer, pattern);

root.isJSON = function(text) {
return /^\s*\{[\s\S]*\}\s*$/.test(text);
return /^\s*\{.*\}\s*$/.test(text);
};
root.isDataScript = function(text) {
return root.isJSON(text) || /^\s*\[.*\]\s*$/.test(text);
};
root.getWrapper = function(name) {

@@ -268,7 +275,7 @@ return name.slice(0, -1) + consts.DOM_SANDBOX_WRAPPER_SYMBOL;

root.processScript = function(text, wrappersOnly) {
var bom = getBOM(text), isJson = root.isJSON(text);
var bom = getBOM(text), isDataScript = root.isDataScript(text);
if (bom) {
text.replace(bom, "");
}
if (!isJson && !wrappersOnly && text.indexOf(consts.DOM_SANDBOX_OVERRIDE_DOM_METHOD_NAME) === -1) {
if (!isDataScript && !wrappersOnly && text.indexOf(consts.DOM_SANDBOX_OVERRIDE_DOM_METHOD_NAME) === -1) {
var overrideDomMeth = "window['" + consts.DOM_SANDBOX_OVERRIDE_DOM_METHOD_NAME + "']";

@@ -275,0 +282,0 @@ text = "\r\ntypeof window !== 'undefined' && " + overrideDomMeth + " && " + overrideDomMeth + "();\r\n" + text;

@@ -11,3 +11,2 @@ TestCafeClient = typeof TestCafeClient === "undefined" ? {} : TestCafeClient;

root.REMOVE_POSSIBLE_FAIL_CAUSE = "CMD_REMOVE_POSSIBLE_FAIL_CAUSE";
root.RESET_ALL_POSSIBLE_FAIL_CAUSES = "CMD_RESET_ALL_POSSIBLE_FAIL_CAUSES";
root.TEST_COMPLETE = "CMD_TEST_COMPLETE";

@@ -20,12 +19,6 @@ root.INACTIVITY_EXPECTED = "CMD_INACTIVITY_EXPECTED";

root.SET_COOKIE = "CMD_SET_COOKIE";
root.GET_CURSOR_POS = "CMD_GET_CURSOR_POS";
root.SET_CURSOR_POS = "CMD_SET_CURSOR_POS";
root.GET_NEXT_STEP = "CMD_GET_NEXT_STEP";
root.SET_NEXT_STEP = "CMD_SET_NEXT_STEP";
root.SILENT_MODE_SET = "CMD_SILENT_MODE_SET";
root.SILENT_MODE_GET = "CMD_SILENT_MODE_GET";
root.TOOLBAR_POSITION_SET = "CMD_TOOLBAR_POSITION_SET";
root.TOOLBAR_POSITION_GET = "CMD_TOOLBAR_POSITION_GET";
root.DISABLE_TOOLTIP_SET = "CMD_DISABLE_TOOLTIP_SET";
root.DISABLE_TOOLTIP_GET = "CMD_DISABLE_TOOLTIP_GET";
root.ADD_TEST_CODE = "CMD_ADD_TEST_CODE";

@@ -32,0 +25,0 @@ root.RESTART_RECORD = "CMD_RESTART_RECORD";

@@ -64,3 +64,7 @@ TestCafeClient = typeof TestCafeClient === "undefined" ? {} : TestCafeClient;

var urlResolver = (doc || document)[root.DOCUMENT_URL_RESOLVER];
urlResolver.href = url;
if (url === null) {
urlResolver.removeAttribute("href");
} else {
urlResolver.href = url;
}
return urlResolver.href;

@@ -81,3 +85,3 @@ };

for (var i = 0; i < queryKeyValueStrs.length; i++) {
var keyValue = queryKeyValueStrs[i].split("="), key = keyValue[0], val = keyValue[1];
var keyValue = queryKeyValueStrs[i].split("="), key = keyValue[0], val = queryKeyValueStrs[i].substr(key.length + 1);
if (key) {

@@ -184,3 +188,3 @@ if (key === root.REQUEST_DESCRIPTOR_QUERY_KEY) {

var parsedCheckedUrl = root.parseUrl(checkedUrl), parsedLocation = root.parseUrl(location), parsedProxyLocation = root.parseProxyUrl(location), parsedOriginUrl = parsedProxyLocation ? parsedProxyLocation.originResourceInfo : null;
isSubDomain = function(domain, subDomain) {
var isSubDomain = function(domain, subDomain) {
var index = subDomain.lastIndexOf(domain);

@@ -348,3 +352,3 @@ return subDomain[index - 1] === "." && subDomain.length === index + domain.length;

hostname: originHostParts[0],
port: parseInt(originHostParts[1], 10),
port: originHostParts[1] || "",
pathname: parsedProxyUrl.pathname,

@@ -351,0 +355,0 @@ query: proxyQuery,

{
"name": "testcafe",
"description": "Functional testing for the web",
"version": "13.1.2",
"version": "13.1.3",
"dependencies": {

@@ -10,3 +10,3 @@ "async": "0.2.6",

"iconv-lite": "0.2.7",
"whacko": "0.12.7",
"whacko": "0.12.9",
"moment": "1.7.0",

@@ -16,3 +16,3 @@ "node-uuid": "1.3.3",

"uglify-js": "1.2.6",
"tough-cookie" : "0.9.14",
"tough-cookie": "0.9.14",
"revalidator": "0.1.5",

@@ -26,2 +26,2 @@ "useragent": "2.0.6",

}
}
}

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

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc