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

codeceptjs

Package Overview
Dependencies
Maintainers
1
Versions
235
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

codeceptjs - npm Package Compare versions

Comparing version 0.5.1 to 0.6.0

lib/command/run-multiple.js

24

bin/codecept.js

@@ -53,3 +53,3 @@ #!/usr/bin/env node

program.command('run [suite] [test]')
program.command('run [test]')
.description('Executes tests')

@@ -63,7 +63,7 @@

.option('--profile [value]', 'configuration profile to be used')
.option('--config [file]', 'configuration file to be used')
.option('-c, --config [file]', 'configuration file to be used')
// mocha options
.option('-c, --colors', 'force enabling of colors')
.option('-C, --no-colors', 'force disabling of colors')
.option('--colors', 'force enabling of colors')
.option('--no-colors', 'force disabling of colors')
.option('-G, --growl', 'enable growl notification support')

@@ -85,5 +85,21 @@ .option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')

.option('--trace', 'trace function calls')
.option('--child <string>', 'option for child processes')
.action(require('../lib/command/run'));
program.command('run-multiple [suites...]')
.description('Executes tests multiple')
.option('-c, --config [file]', 'configuration file to be used')
.option('--all', 'run all suites')
.option('-g, --grep <pattern>', 'only run tests matching <pattern>')
.option('-f, --fgrep <string>', 'only run tests containing <string>')
.option('--steps', 'show step-by-step execution')
.option('--verbose', 'output internal logging information')
.option('-o, --override [value]', 'override current config options')
.option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
.option('-R, --reporter <name>', 'specify the reporter to use')
.option('--recursive', 'include sub directories')
.action(require('../lib/command/run-multiple'));
if (process.argv.length <= 2) {

@@ -90,0 +106,0 @@ console.log('CodeceptJS v' + Codecept.version());

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

## 0.6.0
Major release with extension API and parallel execution.
* **Breaking** Removed path argument from `run`. To specify path other than current directory use `--config` or `-c` option:
Instead of: `codeceptjs run tests` use:
```
# load config and run from tests directory
codeceptjs run -c tests/
# or load codecept.json from tests directory
codeceptjs run -c tests/codecept.json
# run users_test.js inside tests directory
codeceptjs run users_test.js -c tests
```
* **Command `multiple-run` added**, to execute tests in several browsers in parallel by @APshenkin and @davertmik. [See documentation](http://codecept.io/advanced/#multiple-execution).
* **Hooks API added to extend CodeceptJS** with custom listeners and plugins. [See documentation](http://codecept.io/hooks/#hooks_1).
* [Nightmare][WebDriverIO] `within` can work with iframes by @imvetri. [See documentation](http://codecept.io/acceptance/#iframes).
* [WebDriverIO][SeleniumWebdriver][Protractor] Default browser changed to `chrome`
* [Nightmare] Fixed globally locating `nightmare-upload`.
* [WebDriverIO] added `seeNumberOfVisibleElements` method by @elarouche.
* Exit with non-zero code if init throws an error by @rincedd
* New guides published:
* [Installation](http://codecept.io/installation/)
* [Hooks](http://codecept.io/hooks/)
* [Advanced Usage](http://codecept.io/advanced/)
* Meta packages published:
* [codecept-webdriverio](https://www.npmjs.com/package/codecept-webdriverio)
* [codecept-protractor](https://www.npmjs.com/package/codecept-protractor)
* [codecept-nightmare](https://www.npmjs.com/package/codecept-nightmare)
## 0.5.1

@@ -2,0 +38,0 @@

21

lib/codecept.js

@@ -14,2 +14,3 @@ 'use strict';

let runHook = require('./hooks');
const scenarioUi = fsPath.join(__dirname, './interfaces/bdd.js');

@@ -45,7 +46,2 @@

container.create(this.config);
require('./listener/steps');
require('./listener/helpers');
require('./listener/exit');
require('./listener/trace');
this.bootstrap(callback);

@@ -56,3 +52,14 @@ }

bootstrap(done) {
runHook('bootstrap', this.config, done);
// default hooks
runHook(require('./listener/steps'));
runHook(require('./listener/helpers'));
runHook(require('./listener/exit'));
runHook(require('./listener/trace'));
// bootstrap
runHook(this.config.bootstrap, done, 'bootstrap');
// custom hooks
(this.config.hooks || []).forEach((hook) => runHook(hook, done, 'bootstrap'));
}

@@ -62,3 +69,3 @@

teardown(done) {
runHook('teardown', this.config, done);
runHook(this.config.teardown, done, 'teardown');
}

@@ -65,0 +72,0 @@

@@ -8,3 +8,3 @@ 'use strict';

module.exports = function (suite, test, options) {
module.exports = function (test, options) {
// registering options globally to use in config

@@ -15,4 +15,4 @@ process.profile = options.profile;

let testRoot = getTestRoot(suite);
let config = getConfig(testRoot, configFile);
let testRoot = getTestRoot(configFile);
let config = getConfig(configFile);

@@ -35,3 +35,4 @@ // override config with options

output.print(output.colors.grey(err.stack.replace(err.message, '')));
process.exit(1);
}
};

@@ -8,14 +8,6 @@ 'use strict';

module.exports.getTestRoot = function (currentPath) {
let testsPath = path.resolve(currentPath || '.');
return testsPath;
};
module.exports.getConfig = function (configFile) {
module.exports.getConfig = function (testRoot, configFile) {
let testRoot = getTestRoot(configFile);
// using relative config
if (configFile && !path.isAbsolute(configFile)) {
configFile = path.join(testRoot, configFile);
}
let config,

@@ -50,21 +42,19 @@ manualConfigFile = configFile && path.resolve(configFile),

function isObject(item) {
return item && typeof item === 'object' && !Array.isArray(item);
// alias to deep merge
module.exports.deepMerge = require('../utils').deepMerge;
function getTestRoot(currentPath) {
if (!currentPath) currentPath = '.';
if (!path.isAbsolute(currentPath)) currentPath = path.join(process.cwd(), currentPath);
return currentPath = !path.extname(currentPath) ? currentPath : path.dirname(currentPath);
}
module.exports.getTestRoot = getTestRoot;
function deepMerge(target, source) {
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
deepMerge(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return target;
function getTestRoot(currentPath) {
if (!currentPath) currentPath = '.';
if (!path.isAbsolute(currentPath)) currentPath = path.join(process.cwd(), currentPath);
return currentPath = !path.extname(currentPath) ? currentPath : path.dirname(currentPath);
}
module.exports.deepMerge = deepMerge;
module.exports.getTestRoot = getTestRoot;

@@ -71,0 +61,0 @@ function configWithDefaults(config) {

@@ -6,2 +6,46 @@ 'use strict';

let container = {
helpers: {},
support: {},
translation: {}
};
module.exports = {
create: (config) => {
container.helpers = createHelpers(config.helpers || {});
container.translation = loadTranslation(config.translation || null);
container.support = createSupportObjects(config.include || {});
},
support: (name) => {
if (!name) {
return container.support;
}
return container.support[name];
},
helpers: (name) => {
if (!name) {
return container.helpers;
}
return container.helpers[name];
},
translation: () => {
return container.translation;
},
append: (newContainer) => {
const deepMerge = require('./utils').deepMerge;
container = deepMerge(container, newContainer);
},
clear: (newHelpers, newSupport) => {
container.helpers = newHelpers || {};
container.support = newSupport || {};
container.translation = loadTranslation();
}
};
function createHelpers(config) {

@@ -65,4 +109,4 @@ let helpers = {};

if (translation.I != 'I') {
objects[translation.I] = objects.I;
if (container.translation.I != 'I') {
objects[container.translation.I] = objects.I;
}

@@ -96,39 +140,1 @@ }

}
let helpers = {};
let support = {};
let translation = {};
module.exports = {
create: (config) => {
helpers = createHelpers(config.helpers || {});
translation = loadTranslation(config.translation || null);
support = createSupportObjects(config.include || {});
},
support: (name) => {
if (!name) {
return support;
}
return support[name];
},
helpers: (name) => {
if (!name) {
return helpers;
}
return helpers[name];
},
translation: () => {
return translation;
},
clear: (newHelpers, newSupport) => {
helpers = newHelpers || {};
support = newSupport || {};
translation = loadTranslation();
}
};

@@ -73,2 +73,7 @@ if (!window.codeceptjs) {

}
if (by == 'frame') {
if (!Array.isArray(locator)) locator = [locator];
return [locator.reduce((parent, child)=>parent.querySelector(child).contentDocument, window.document).querySelector('body')];
}
return [];

@@ -75,0 +80,0 @@ };

@@ -25,3 +25,4 @@ 'use strict';

* 1. Download [Selenium Server](http://docs.seleniumhq.org/download/)
* 2. Launch the daemon: `java -jar selenium-server-standalone-2.xx.xxx.jar`
* 2. For Chrome browser install [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/getting-started), for Firefox browser install [GeckoDriver](https://github.com/mozilla/geckodriver).
* 3. Launch the daemon: `java -jar selenium-server-standalone-3.xx.xxx.jar`
*

@@ -68,3 +69,3 @@ * #### PhantomJS Installation

this.options = {
browser: 'firefox',
browser: 'chrome',
url: 'http://localhost',

@@ -115,3 +116,3 @@ seleniumAddress: 'http://localhost:4444/wd/hub',

{ name: 'driver', message: "Protractor driver (local, direct, session, hosted, sauce, browserstack)", default: 'hosted' },
{ name: 'browser', message: 'Browser in which testing will be performed', default: 'firefox' },
{ name: 'browser', message: 'Browser in which testing will be performed', default: 'chrome' },
{ name: 'rootElement', message: "Root element of AngularJS application", default: 'body' },

@@ -118,0 +119,0 @@ ];

@@ -26,3 +26,4 @@ 'use strict';

* 1. Download [Selenium Server](http://docs.seleniumhq.org/download/)
* 2. Launch the daemon: `java -jar selenium-server-standalone-2.xx.xxx.jar`
* 2. For Chrome browser install [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/getting-started), for Firefox browser install [GeckoDriver](https://github.com/mozilla/geckodriver).
* 3. Launch the daemon: `java -jar selenium-server-standalone-3.xx.xxx.jar`
*

@@ -114,3 +115,3 @@ *

{ name: 'url', message: "Base url of site to be tested", default: 'http://localhost' },
{ name: 'browser', message: 'Browser in which testing will be performed', default: 'firefox' },
{ name: 'browser', message: 'Browser in which testing will be performed', default: 'chrome' },
];

@@ -117,0 +118,0 @@ }

@@ -25,5 +25,5 @@ 'use strict';

* 1. Download [Selenium Server](http://docs.seleniumhq.org/download/)
* 2. Launch the daemon: `java -jar selenium-server-standalone-2.xx.xxx.jar`
* 2. For Chrome browser install [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/getting-started), for Firefox browser install [GeckoDriver](https://github.com/mozilla/geckodriver).
* 3. Launch the daemon: `java -jar selenium-server-standalone-3.xx.xxx.jar`
*
*
* #### PhantomJS Installation

@@ -46,3 +46,3 @@ *

* * `windowSize`: (optional) default window size. Set to `maximize` or a dimension in the format `640x480`.
* * `waitForTimeout`: (optional) sets default wait time in *ms* for all `wait*` functions. 1000 by default;
* * `waitForTimeout`: (option) sets default wait time in *ms* for all `wait*` functions. 1000 by default;
* * `desiredCapabilities`: Selenium's [desired capabilities](https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities)

@@ -100,3 +100,2 @@ * * `manualStart` (optional, default: false) - do not start browser before a test, start it manually inside a helper with `this.helpers["WebDriverIO"]._startBrowser()`

* ```
*
* For example,

@@ -219,3 +218,3 @@ *

throw new Error(`
WebDriverIO requires at least these parameters
WebDriverIO requires ares.valuet least these parameters
Check your codeceptjs config file to ensure these are set properly

@@ -250,3 +249,3 @@ {

message: 'Browser in which testing will be performed',
default: 'firefox'
default: 'chrome'
}];

@@ -317,2 +316,7 @@ }

_withinBegin(locator) {
let frame = isFrameLocator(locator);
if (frame) {
withinStore.frame = frame;
return this.browser.element(frame).then((res) => this.browser.frame(res.value));
}
withinStore.elFn = this.browser.element;

@@ -332,5 +336,10 @@ withinStore.elsFn = this.browser.elements;

_withinEnd() {
if (withinStore.frame) {
withinStore = {};
return this.browser.frame(null);
}
this.context = 'body';
this.browser.element = withinStore.elFn;
this.browser.elements = withinStore.elsFn;
withinStore = {};
}

@@ -769,2 +778,19 @@

/**
* asserts that an element is visible a given number of times
* Element is located by CSS or XPath.
*
* ```js
* I.seeNumberOfVisibleElements('.buttons', 3);
* ```
*/
seeNumberOfVisibleElements(selector, num) {
return this.browser.isVisible(withStrictLocator(selector))
.then(function (res) {
if(!Array.isArray(res)) res = [res];
res = res.filter((val) => val == true);
return truth(`elements of ${locator}`, 'to be seen').assert.equal(res.length, num);
});
}
/**
* {{> ../webapi/seeInCurrentUrl }}

@@ -1264,2 +1290,9 @@ */

function isFrameLocator(locator) {
if (typeof locator !== 'object') return false;
let key = Object.keys(locator)[0];
if (key !== 'frame') return false;
return locator[key];
}
module.exports = WebDriverIO;

@@ -7,5 +7,6 @@ 'use strict';

module.exports = function (hook, config, done) {
if (typeof config[hook] === 'string' && fileExists(fsPath.join(codecept_dir, config[hook]))) {
var callable = require(fsPath.join(codecept_dir, config[hook]));
module.exports = function (hook, done, stage) {
stage = stage || 'bootstrap';
if (typeof hook === 'string' && fileExists(fsPath.join(codecept_dir, hook))) {
var callable = require(fsPath.join(codecept_dir, hook));
if (typeof callable === 'function') {

@@ -15,8 +16,8 @@ callSync(callable, done);

}
if (typeof callable === 'object' && callable[hook]) {
callSync(callable[hook], done);
if (typeof callable === 'object' && callable[stage]) {
callSync(callable[stage], done);
return;
}
} else if (typeof config[hook] === 'function') {
callSync(config[hook], done);
} else if (typeof hook === 'function') {
callSync(hook, done);
return;

@@ -33,3 +34,3 @@ }

callable();
done();
if (done) done();
}

@@ -36,0 +37,0 @@ }

'use strict';
let event = require('../event');
const event = require('../event');
let failed = false;
module.exports = function () {
let failedTests = [];
let failed = false;
event.dispatcher.on(event.test.failed, function (testOrSuite) {
// NOTE When an error happens in one of the hooks (BeforeAll/BeforeEach...) the event object
// is a suite and not a test
failedTests.push(testOrSuite.fullTitle());
});
let failedTests = [];
// if test was successful after retries
event.dispatcher.on(event.test.passed, function (testOrSuite) {
// NOTE When an error happens in one of the hooks (BeforeAll/BeforeEach...) the event object
// is a suite and not a test
failedTests = failedTests.filter((failed) => testOrSuite.fullTitle() !== failed);
});
event.dispatcher.on(event.test.failed, function (testOrSuite) {
// NOTE When an error happens in one of the hooks (BeforeAll/BeforeEach...) the event object
// is a suite and not a test
failedTests.push(testOrSuite.fullTitle());
});
event.dispatcher.on(event.all.result, function () {
if (failedTests.length) {
process.on('exit', function () {
process.exit(1); // exit with non-zero status if there were failures
});
}
});
// if test was successful after retries
event.dispatcher.on(event.test.passed, function (testOrSuite) {
// NOTE When an error happens in one of the hooks (BeforeAll/BeforeEach...) the event object
// is a suite and not a test
failedTests = failedTests.filter((failed) => testOrSuite.fullTitle() !== failed);
});
event.dispatcher.on(event.all.result, function () {
if (failedTests.length) {
process.exitCode = 1;
}
});
};
'use strict';
let container = require('../container');
let event = require('../event');
let recorder = require('../recorder');
let debug = require('../output').debug;
const event = require('../event');
const container = require('../container');
const recorder = require('../recorder');
const debug = require('../output').debug;
let helpers = container.helpers();
/**
* Enable Helpers to listen to test events
*/
module.exports = function () {
let helpers = container.helpers();
let runHelpersHook = (hook, param) => {
Object.keys(helpers).forEach((key) => {
helpers[key][hook](param);
const runHelpersHook = (hook, param) => {
Object.keys(helpers).forEach((key) => {
helpers[key][hook](param);
});
};
const runAsyncHelpersHook = (hook, param, force) => {
Object.keys(helpers).forEach((key) => {
if (!helpers[key][hook]) return;
recorder.add(`hook ${key}.${hook}()`, () => helpers[key][hook](param), force);
});
};
event.dispatcher.on(event.all.before, function () {
runHelpersHook('_init');
});
};
let runAsyncHelpersHook = (hook, param, force) => {
Object.keys(helpers).forEach((key) => {
if (!helpers[key][hook]) return;
recorder.add(`hook ${key}.${hook}()`, () => helpers[key][hook](param), force);
event.dispatcher.on(event.suite.before, function (suite) {
runAsyncHelpersHook('_beforeSuite', null, true);
});
};
event.dispatcher.on(event.all.before, function () {
runHelpersHook('_init');
});
event.dispatcher.on(event.suite.after, function (suite) {
runAsyncHelpersHook('_afterSuite', null, true);
});
event.dispatcher.on(event.suite.before, function (suite) {
runAsyncHelpersHook('_beforeSuite', null, true);
});
event.dispatcher.on(event.test.started, function (test) {
runHelpersHook('_test', test);
recorder.catch((e) => debug(e));
});
event.dispatcher.on(event.suite.after, function (suite) {
runAsyncHelpersHook('_afterSuite', null, true);
});
event.dispatcher.on(event.test.before, function () {
runAsyncHelpersHook('_before');
});
event.dispatcher.on(event.test.started, function (test) {
runHelpersHook('_test', test);
recorder.catch((e) => debug(e));
});
event.dispatcher.on(event.test.failed, function (test) {
runAsyncHelpersHook('_failed', test, true);
// should not fail test execution, so errors should be catched
recorder.catch((e) => debug(e));
});
event.dispatcher.on(event.test.before, function () {
runAsyncHelpersHook('_before');
});
event.dispatcher.on(event.test.after, function (test) {
runAsyncHelpersHook('_after', {}, true);
});
event.dispatcher.on(event.test.failed, function (test) {
runAsyncHelpersHook('_failed', test, true);
// should not fail test execution, so errors should be catched
recorder.catch((e) => debug(e));
});
event.dispatcher.on(event.step.before, function (step) {
runAsyncHelpersHook('_beforeStep', step);
});
event.dispatcher.on(event.test.after, function (test) {
runAsyncHelpersHook('_after', {}, true);
});
event.dispatcher.on(event.step.before, function (step) {
runAsyncHelpersHook('_beforeStep', step);
});
event.dispatcher.on(event.step.after, function (step) {
runAsyncHelpersHook('_afterStep', step);
});
event.dispatcher.on(event.step.after, function (step) {
runAsyncHelpersHook('_afterStep', step);
});
};
'use strict';
const event = require('../event');
let event = require('../event');
let currentTest;
let steps;
event.dispatcher.on(event.test.started, function (test) {
currentTest = test;
currentTest.steps = [];
});
/**
* Register steps inside tests
*/
module.exports = function () {
event.dispatcher.on(event.test.after, function () {
currentTest = null;
});
event.dispatcher.on(event.test.started, function (test) {
currentTest = test;
currentTest.steps = [];
});
event.dispatcher.on(event.test.failed, function (test) {
if (!currentTest) return;
// last step is failing step
if (!currentTest.steps.length) return;
currentTest.steps.slice(-1)[0].status = 'failed';
});
event.dispatcher.on(event.test.after, function () {
currentTest = null;
});
event.dispatcher.on(event.step.before, function (step) {
if (!currentTest || !currentTest.steps) return;
currentTest.steps.push(step);
});
event.dispatcher.on(event.test.failed, function (test) {
if (!currentTest) return;
// last step is failing step
if (!currentTest.steps.length) return;
currentTest.steps.slice(-1)[0].status = 'failed';
});
event.dispatcher.on(event.step.before, function (step) {
if (!currentTest || !currentTest.steps) return;
currentTest.steps.push(step);
});
};
'use strict';
let event = require('../event');
let AssertionFailedError = require('../assert/error');
let output = require('../output');
let ucfirst = require('../utils').ucfirst;
const output = require('../output');
const event = require('../event');
const AssertionFailedError = require('../assert/error');
const ucfirst = require('../utils').ucfirst;
event.dispatcher.on(event.test.failed, function (test, err) {
let msg = err.message;
if (err instanceof AssertionFailedError) {
msg = err.message = err.inspect();
}
let steps = test.steps;
if (steps && steps.length) {
let scenarioTrace = "";
steps.reverse().forEach((step, i) => {
let line = `- ${step.toCode()} ${step.line()}`;
// if (step.status === 'failed') line = '' + line;
scenarioTrace += "\n" + line;
});
msg += `\n\nScenario Steps:\n${scenarioTrace}\n\n`;
}
/**
* Register stack trace for scenarios
*/
module.exports = function () {
if (output.level() < 3) {
err.stack = ''; // hide internal error stack trace in non-verbose mode
}
event.dispatcher.on(event.test.failed, function (test, err) {
let msg = err.message;
if (err instanceof AssertionFailedError) {
msg = err.message = err.inspect();
}
let steps = test.steps;
if (steps && steps.length) {
let scenarioTrace = "";
steps.reverse().forEach((step, i) => {
let line = `- ${step.toCode()} ${step.line()}`;
// if (step.status === 'failed') line = '' + line;
scenarioTrace += "\n" + line;
});
msg += `\n\nScenario Steps:\n${scenarioTrace}\n\n`;
}
err.stack = msg + err.stack;
test.err = err;
});
if (output.level() < 3) {
err.stack = ''; // hide internal error stack trace in non-verbose mode
}
err.stack = msg + err.stack;
test.err = err;
});
};
'use strict';
let colors = require('chalk');
let print = console.log;
let symbols = require('mocha/lib/reporters/base').symbols;

@@ -17,2 +16,3 @@

let outputLevel = 0;
let outputProcess = '';

@@ -29,2 +29,7 @@ module.exports = {

process: (process) => {
if (process) outputProcess = `[${process}]`;
return outputProcess;
},
debug: (msg) => {

@@ -42,2 +47,3 @@ if (outputLevel >= 2) print(' '.repeat(this.stepShift), styles.debug("> " + msg));

success: (msg) => {

@@ -47,6 +53,7 @@ print(styles.success(msg));

step: function (step) {
step: function (step, suiteDetails) {
if (outputLevel === 0) return;
if (!step) return;
let sym = process.platform === 'win32' ? '*' : '•';
if (suiteDetails) process.stdout.write('[ ' + suiteDetails + ' ] ');
print(' '.repeat(this.stepShift), `${sym} ${step.toString()}`);

@@ -89,8 +96,6 @@ },

}
},
say: (message) => {
print(` ${colors.cyan.bold(message)}`);
if (outputLevel >= 1) print(` ${colors.cyan.bold(message)}`);
},

@@ -118,2 +123,8 @@

function print(...msg) {
if (outputProcess) {
msg.unshift(outputProcess);
}
console.log.apply(this, msg);
}

@@ -120,0 +131,0 @@ function ind() {

@@ -20,4 +20,5 @@ 'use strict';

if (opts.verbose) level = 3;
output.process(opts.child);
output.level(level);
output.print('CodeceptJS v' + require('../codecept').version());

@@ -70,3 +71,3 @@ output.print(`Using test root "${global.codecept_dir}"`);

event.dispatcher.on(event.step.started, function (step) {
output.step(step);
output.step(step, global.suiteDetails);
});

@@ -73,0 +74,0 @@ }

var fs = require('fs');
var path = require('path');
var getParameterNames = require('get-parameter-names');
function isObject(item) {
return item && typeof item === 'object' && !Array.isArray(item);
}
function deepMerge(target, source) {
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
deepMerge(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return target;
}
module.exports.deepMerge = deepMerge;
module.exports.fileExists = function (filePath) {

@@ -26,4 +47,3 @@ try {

if (fn.isSinonProxy) return [];
var funStr = fn.toString();
return funStr.slice(funStr.indexOf('(') + 1, funStr.indexOf(')')).match(/([^\s,]+)/g);
return getParameterNames(fn);
};

@@ -30,0 +50,0 @@

@@ -12,3 +12,3 @@ 'use strict';

let helpers = container.helpers();
let locator = typeof context === 'object' ? JSON.parse(context) : context;
let locator = typeof context === 'object' ? JSON.stringify(context) : context;
let addContextToStep = function (step) {

@@ -15,0 +15,0 @@ step.prefix = `Within ${locator}: `;

{
"name": "codeceptjs",
"version": "0.5.1",
"version": "0.6.0",
"description": "Modern Era Aceptance Testing Framework for NodeJS",

@@ -21,3 +21,3 @@ "homepage": "http://codecept.io",

],
"main": "lib/codecept.js",
"main": "lib/index.js",
"keywords": [

@@ -34,2 +34,3 @@ "tdd",

"escape-string-regexp": "^1.0.3",
"get-parameter-names": "^0.3.0",
"glob": "^6.0.1",

@@ -36,0 +37,0 @@ "inquirer": "^0.11.0",

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

# CodeceptJS [![NPM version][npm-image]][npm-url] [![Build Status](https://travis-ci.org/Codeception/CodeceptJS.svg)](https://travis-ci.org/Codeception/CodeceptJS) [![Join the chat at https://gitter.im/Codeception/CodeceptJS](https://badges.gitter.im/Codeception/CodeceptJS.svg)](https://gitter.im/Codeception/CodeceptJS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
# CodeceptJS [![NPM version][npm-image]][npm-url] [![Build Status](https://travis-ci.org/Codeception/CodeceptJS.svg?branch=master)](https://travis-ci.org/Codeception/CodeceptJS) [![Join the chat at https://gitter.im/Codeception/CodeceptJS](https://badges.gitter.im/Codeception/CodeceptJS.svg)](https://gitter.im/Codeception/CodeceptJS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

@@ -17,3 +17,3 @@ Reference: [Helpers API](https://github.com/Codeception/CodeceptJS/blob/master/docs) | [Demo](https://github.com/Codeception/codeceptjs-demo)

I.see('Welcome');
}
});
```

@@ -20,0 +20,0 @@

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