codeceptjs
Advanced tools
Comparing version 0.4.13 to 0.4.14
@@ -0,1 +1,48 @@ | ||
## 0.4.14 | ||
* `_beforeStep` and `_afterStep` hooks in helpers are synchronized. Allows to perform additional actions between steps. | ||
Example: fail if JS error occur in custom helper using WebdriverIO: | ||
```js | ||
_before() { | ||
this.err = null; | ||
this.helpers['WebDriverIO'].browser.on('error', (e) => this.err = e); | ||
} | ||
_afterStep() { | ||
if (this.err) throw new Error('Browser JS error '+this.err); | ||
} | ||
``` | ||
Example: fail if JS error occur in custom helper using Nightmare: | ||
```js | ||
_before() { | ||
this.err = null; | ||
this.helpers['Nightmare'].browser.on('page', (type, message, stack) => { | ||
this.err = `${message} ${stack}`; | ||
}); | ||
} | ||
_afterStep() { | ||
if (this.err) throw new Error('Browser JS error '+this.err); | ||
} | ||
``` | ||
* Fixed `codecept list` and `codecept def` commands. | ||
* Added `I.say` method to print arbitrary comments. | ||
```js | ||
I.say('I am going to publish post'); | ||
I.say('I enter title and body'); | ||
I.say('I expect post is visible on site'); | ||
``` | ||
* [Nightmare] `restart` option added. `restart: false` allows to run all tests in a single window, disabled by default. By @nairvijays99 | ||
* [Nightmare] Fixed `resizeWindow` command. | ||
* [Protractor][SeleniumWebdriver] added `windowSize` config option to resize window on start. | ||
* Fixed "Scenario.skip causes 'Cannot read property retries of undefined'" by @MasterOfPoppets | ||
* Fixed providing absolute paths for tests in config by @lennym | ||
## 0.4.13 | ||
@@ -6,3 +53,3 @@ | ||
```js | ||
Feature('Complex JS Stuff', {retries: 3}) | ||
Feature('Complex JS Stuff', {retries: 3}); | ||
@@ -17,5 +64,5 @@ Scenario('Not that complex', {retries: 1}, (I) => { | ||
```js | ||
Feature('Complex JS Stuff', {retries: 3}) | ||
Feature('Complex JS Stuff', {timeout: 5000}); | ||
Scenario('Not that complex', {retries: 1}, (I) => { | ||
Scenario('Not that complex', {timeout: 1000}, (I) => { | ||
// test goes here | ||
@@ -22,0 +69,0 @@ }); |
@@ -6,2 +6,4 @@ 'use strict'; | ||
let recorder = require('./recorder'); | ||
let event = require('./event'); | ||
let output = require('./output'); | ||
@@ -17,8 +19,11 @@ /** | ||
let helpers = container.helpers(); | ||
// add methods from enabled helpers | ||
Object.keys(helpers) | ||
.map(function (key) { return helpers[key];}) | ||
.map((key) => helpers[key]) | ||
.forEach((helper) => { | ||
methodsOfObject(helper, 'Helper') | ||
.filter((method) => { | ||
return method !== 'constructor' && method[0] !== '_';}) | ||
return method !== 'constructor' && method[0] !== '_'; | ||
}) | ||
.forEach((action) => { | ||
@@ -28,3 +33,2 @@ let actionAlias = container.translation().actionAliasFor(action); | ||
obj[action] = obj[actionAlias] = function () { | ||
let args = arguments; | ||
let step = new Step(helper, action); | ||
@@ -35,4 +39,4 @@ if (container.translation().loaded) { | ||
} | ||
recorder.addStep(step, args); | ||
return recorder.promise(); | ||
// add methods to promise chain | ||
return recordStep(step, Array.prototype.slice.call(arguments)); | ||
}; | ||
@@ -42,3 +46,20 @@ }); | ||
// add print comment method | ||
obj.say = (msg) => recorder.add(`say ${msg}`, () => output.say(msg)); | ||
return obj; | ||
}; | ||
function recordStep(step, args) { | ||
step.status = 'queued'; | ||
step.setArguments(args); | ||
event.emit(event.step.before, step); | ||
let task = `${step.name}: ${Object.keys(args).map(key => args[key]).join(', ')}`; | ||
recorder.add(task, () => val = step.run.apply(step, args)); | ||
let val; | ||
event.emit(event.step.after, step); | ||
recorder.add('return step result', () => val); | ||
return recorder.promise(); | ||
} |
@@ -33,3 +33,3 @@ 'use strict'; | ||
} | ||
err.cliMessage = function() { | ||
err.cliMessage = function () { | ||
let msg = this.template | ||
@@ -36,0 +36,0 @@ .replace('{{jar}}', output.colors.bold('{{jar}}')) |
@@ -64,3 +64,3 @@ 'use strict'; | ||
pattern = pattern || this.config.tests; | ||
glob.sync(fsPath.join(codecept_dir, pattern)).forEach((file) => { | ||
glob.sync(fsPath.resolve(codecept_dir, pattern)).forEach((file) => { | ||
this.testFiles.push(fsPath.resolve(file)); | ||
@@ -67,0 +67,0 @@ }); |
@@ -31,55 +31,55 @@ 'use strict'; | ||
} | ||
` | ||
`; | ||
module.exports = function (genPath) { | ||
let testsPath = getTestRoot(genPath); | ||
let config = getConfig(testsPath); | ||
if (!config) return; | ||
let testsPath = getTestRoot(genPath); | ||
let config = getConfig(testsPath); | ||
if (!config) return; | ||
let codecept = new Codecept(config, {}); | ||
codecept.init(testsPath, function(err) { | ||
if (err) { | ||
output.error('Error while running bootstrap file :' + err); | ||
return; | ||
} | ||
let codecept = new Codecept(config, {}); | ||
codecept.init(testsPath, function (err) { | ||
if (err) { | ||
output.error('Error while running bootstrap file :' + err); | ||
return; | ||
} | ||
let helpers = container.helpers(); | ||
let suppportI = container.support('I'); | ||
let translations = container.translation(); | ||
let methods = []; | ||
let actions = []; | ||
for (let name in helpers) { | ||
let helper = helpers[name]; | ||
methodsOfObject(helper).forEach((action) => { | ||
let actionAlias = container.translation() ? container.translation().actionAliasFor(action) : action; | ||
if (!actions[actionAlias]) { | ||
let params = getParamNames(helper[action]); | ||
if (params) params = params.join(', '); | ||
if (!params) params = ''; | ||
methods.push(` ${(actionAlias)}: (${params}) => any; \n`); | ||
actions[actionAlias] = 1 | ||
} | ||
}); | ||
} | ||
for (let name in suppportI) { | ||
if (actions[name]) { | ||
continue | ||
} | ||
let actor = suppportI[name]; | ||
let params = getParamNames(actor); | ||
let helpers = container.helpers(); | ||
let suppportI = container.support('I'); | ||
let translations = container.translation(); | ||
let methods = []; | ||
let actions = []; | ||
for (let name in helpers) { | ||
let helper = helpers[name]; | ||
methodsOfObject(helper).forEach((action) => { | ||
let actionAlias = container.translation() ? container.translation().actionAliasFor(action) : action; | ||
if (!actions[actionAlias]) { | ||
let params = getParamNames(helper[action]); | ||
if (params) params = params.join(', '); | ||
if (!params) params = ''; | ||
methods.push(` ${(name)}: (${params}) => any; \n`); | ||
methods.push(` ${(actionAlias)}: (${params}) => any; \n`); | ||
actions[actionAlias] = 1; | ||
} | ||
}); | ||
} | ||
for (let name in suppportI) { | ||
if (actions[name]) { | ||
continue; | ||
} | ||
let definitionsTemplate = template.replace('{{methods}}', methods.join('')); | ||
definitionsTemplate = definitionsTemplate.replace(/\{\{I\}\}/g, container.translation().I); | ||
let actor = suppportI[name]; | ||
let params = getParamNames(actor); | ||
if (params) params = params.join(', '); | ||
if (!params) params = ''; | ||
methods.push(` ${(name)}: (${params}) => any; \n`); | ||
} | ||
let definitionsTemplate = template.replace('{{methods}}', methods.join('')); | ||
definitionsTemplate = definitionsTemplate.replace(/\{\{I\}\}/g, container.translation().I); | ||
fs.writeFileSync(path.join(testsPath, 'steps.d.ts'), definitionsTemplate); | ||
output.print('TypeScript Definitions provide autocompletion in Visual Studio Code and other IDEs'); | ||
output.print('Definitions were generated in steps.d.ts'); | ||
output.print('Load them by adding at the top of a test file:'); | ||
output.print(output.colors.grey(`\n/// <reference path="./steps.d.ts" />`)); | ||
fs.writeFileSync(path.join(testsPath, 'steps.d.ts'), definitionsTemplate); | ||
output.print('TypeScript Definitions provide autocompletion in Visual Studio Code and other IDEs'); | ||
output.print('Definitions were generated in steps.d.ts'); | ||
output.print('Load them by adding at the top of a test file:'); | ||
output.print(output.colors.grey(`\n/// <reference path="./steps.d.ts" />`)); | ||
codecept.teardown(); | ||
}); | ||
} | ||
codecept.teardown(); | ||
}); | ||
}; |
@@ -53,3 +53,3 @@ 'use strict'; | ||
let defaultExt = config.tests.match((/\*(.*?)$/)[1])[0] || '_test.js'; | ||
let defaultExt = config.tests.match(/\*(.*?)$/[1])[0] || '_test.js'; | ||
@@ -56,0 +56,0 @@ inquirer.prompt([ |
@@ -15,12 +15,12 @@ 'use strict'; | ||
let defaultConfig = { | ||
"tests": "./*_test.js", | ||
"timeout": 10000, | ||
"output": null, | ||
"helpers": {}, | ||
"include": {}, | ||
"bootstrap": false, | ||
"mocha": {} | ||
tests: "./*_test.js", | ||
timeout: 10000, | ||
output: null, | ||
helpers: {}, | ||
include: {}, | ||
bootstrap: false, | ||
mocha: {} | ||
}; | ||
let helpers = ['WebDriverIO', 'Protractor', 'SeleniumWebdriver', 'Nightmare','FileSystem']; | ||
let helpers = ['WebDriverIO', 'Protractor', 'SeleniumWebdriver', 'Nightmare', 'FileSystem']; | ||
let translations = Object.keys(require('../../translations')); | ||
@@ -127,3 +127,3 @@ let noTranslation = 'English (no localization)'; | ||
if (!config.tests.match(/\*(.*?)$/)) { | ||
config.tests = config.tests.replace(/\/+$/,'') + "/*_test.js"; | ||
config.tests = config.tests.replace(/\/+$/, '') + "/*_test.js"; | ||
console.log(`Adding default test mask: ${config.tests}`); | ||
@@ -184,8 +184,8 @@ } | ||
if (isLocal) { | ||
print("Please install dependent packages locally: " + colors.bold('npm install --save-dev '+packages.join(' '))); | ||
print("Please install dependent packages locally: " + colors.bold('npm install --save-dev ' + packages.join(' '))); | ||
} else { | ||
print("Please install dependent packages globally: [sudo] " + colors.bold('npm install -g '+packages.join(' '))); | ||
print("Please install dependent packages globally: [sudo] " + colors.bold('npm install -g ' + packages.join(' '))); | ||
} | ||
} | ||
} | ||
}; | ||
@@ -192,0 +192,0 @@ if (!result.helpers.length) { |
@@ -17,3 +17,3 @@ 'use strict'; | ||
let codecept = new Codecept(config, options); | ||
codecept.init(testsPath, function(err) { | ||
codecept.init(testsPath, function (err) { | ||
if (err) { | ||
@@ -20,0 +20,0 @@ output.error('Error while running bootstrap file :' + err); |
'use strict'; | ||
let urils = require('../utils') | ||
let urils = require('../utils'); | ||
let getConfig = require('./utils').getConfig; | ||
@@ -16,3 +16,3 @@ let getTestRoot = require('./utils').getTestRoot; | ||
let codecept = new Codecept(config, {}); | ||
codecept.init(testsPath, function(err) { | ||
codecept.init(testsPath, function (err) { | ||
if (err) { | ||
@@ -38,3 +38,3 @@ output.error('Error while running bootstrap file :' + err); | ||
if (actions[name]) { | ||
continue | ||
continue; | ||
} | ||
@@ -47,3 +47,3 @@ let actor = suppportI[name]; | ||
} | ||
output.print('PS: Actions are retrieved from enabled helpers. ') | ||
output.print('PS: Actions are retrieved from enabled helpers. '); | ||
output.print('Implement custom actions in your helper classes.'); | ||
@@ -50,0 +50,0 @@ |
@@ -34,2 +34,2 @@ 'use strict'; | ||
} | ||
}; | ||
}; |
@@ -50,3 +50,3 @@ 'use strict'; | ||
function isObject(item) { | ||
return (item && typeof item === 'object' && !Array.isArray(item)); | ||
return item && typeof item === 'object' && !Array.isArray(item); | ||
} | ||
@@ -53,0 +53,0 @@ |
@@ -20,7 +20,7 @@ 'use strict'; | ||
if (require('./utils').installedLocally()) { | ||
install = "npm install --save-dev "+requirements.join(' '); | ||
install = "npm install --save-dev " + requirements.join(' '); | ||
} else { | ||
install = "[sudo] npm install -g "+requirements.join(' '); | ||
install = "[sudo] npm install -g " + requirements.join(' '); | ||
} | ||
throw new Error("Required modules are not installed.\n\nRUN: "+install); | ||
throw new Error("Required modules are not installed.\n\nRUN: " + install); | ||
} | ||
@@ -30,3 +30,3 @@ } | ||
} catch (err) { | ||
throw new Error(`Could not load helper ${helperName} from module '${module}':\n${err.message}`); | ||
throw new Error(`Could not load helper ${helperName} from module '${module}':\n${err.message}\n${JSON.stringify(err)}`); | ||
} | ||
@@ -54,3 +54,3 @@ } | ||
try { | ||
if (typeof(objects[name]) === 'function') { | ||
if (typeof objects[name] === 'function') { | ||
objects[name] = objects[name](); | ||
@@ -90,3 +90,3 @@ } else if (objects[name]._init) { | ||
// get from a provided file instead | ||
vocabulary = require(path.join(global.codecept_dir, translation)); | ||
vocabulary = require(path.join(global.codecept_dir, translation)); | ||
} else { | ||
@@ -93,0 +93,0 @@ throw new Error(`Translation option is set in config, but ${translation} is not a translated locale or filename`); |
@@ -28,4 +28,4 @@ var events = require('events'); | ||
}, | ||
emit: function(event, param) { | ||
var msg = 'Emitted | '+event; | ||
emit: function (event, param) { | ||
var msg = 'Emitted | ' + event; | ||
if (param && param.toString()) { | ||
@@ -32,0 +32,0 @@ msg += ` (${param.toString()})`; |
@@ -21,3 +21,3 @@ 'use strict'; | ||
construtor(config) { | ||
constructor(config) { | ||
this.config = config; | ||
@@ -24,0 +24,0 @@ } |
if (!window.codeceptjs) { | ||
let codeceptjs = {} | ||
let codeceptjs = {}; | ||
@@ -11,28 +11,28 @@ // all found elements are stored here for reuse | ||
// save | ||
let storeElement = function(el) { | ||
let storeElement = function (el) { | ||
if (!el) return; | ||
return codeceptjs.elements.push(el)-1; // return index | ||
} | ||
return codeceptjs.elements.push(el) - 1; // return index | ||
}; | ||
let storeElements = function(els) { | ||
let storeElements = function (els) { | ||
return els.map((el) => storeElement(el)); | ||
} | ||
}; | ||
// finders | ||
codeceptjs.fetchElement = function(id) { | ||
codeceptjs.fetchElement = function (id) { | ||
if (!this.elements[id]) throw new Error(`Element (${id}) is not accessible`); | ||
return this.elements[id]; | ||
} | ||
}; | ||
codeceptjs.findAndStoreElements = function (by, locator, contextEl) { | ||
return storeElements(this.findElements(by, locator, contextEl)); | ||
} | ||
}; | ||
codeceptjs.findAndStoreElement = function (by, locator, contextEl) { | ||
return storeElement(this.findElement(by, locator, contextEl)); | ||
} | ||
}; | ||
codeceptjs.setWithin = function(by, locator) { | ||
codeceptjs.setWithin = function (by, locator) { | ||
this.within = this.findElement(by, locator); | ||
} | ||
}; | ||
@@ -75,10 +75,10 @@ codeceptjs.findElements = function (by, locator, contextEl) { | ||
return []; | ||
} | ||
}; | ||
codeceptjs.findElement = function (by, locator, context) { | ||
return this.findElements(by, locator, context)[0] || null; | ||
} | ||
}; | ||
// actions | ||
codeceptjs.clickEl = function(el) { | ||
codeceptjs.clickEl = function (el) { | ||
document.activeElement.blur(); | ||
@@ -88,5 +88,5 @@ var event = document.createEvent('MouseEvent'); | ||
return this.fetchElement(el).dispatchEvent(event); | ||
} | ||
}; | ||
codeceptjs.doubleClickEl = function(el) { | ||
codeceptjs.doubleClickEl = function (el) { | ||
document.activeElement.blur(); | ||
@@ -96,5 +96,5 @@ var event = document.createEvent('MouseEvent'); | ||
this.fetchElement(el).dispatchEvent(event); | ||
} | ||
}; | ||
codeceptjs.hoverEl = function(el, x, y) { | ||
codeceptjs.hoverEl = function (el, x, y) { | ||
document.activeElement.blur(); | ||
@@ -104,5 +104,5 @@ var event = document.createEvent('MouseEvent'); | ||
this.fetchElement(el).dispatchEvent(event); | ||
} | ||
}; | ||
codeceptjs.checkEl = function(el) { | ||
codeceptjs.checkEl = function (el) { | ||
var element = this.fetchElement(el); | ||
@@ -114,3 +114,3 @@ var event = document.createEvent('HTMLEvents'); | ||
return element.dispatchEvent(event); | ||
} | ||
}; | ||
@@ -117,0 +117,0 @@ window.codeceptjs = codeceptjs; |
'use strict'; | ||
const requireg = require('requireg') | ||
const requireg = require('requireg'); | ||
const Helper = require('../helper'); | ||
@@ -15,6 +15,6 @@ const stringIncludes = require('../assert/include').includes; | ||
let specialKeys = { | ||
'Backspace': '\u0008', | ||
'Enter': '\u000d', | ||
'Delete': '\u007f' | ||
} | ||
Backspace: '\u0008', | ||
Enter: '\u000d', | ||
Delete: '\u007f' | ||
}; | ||
@@ -50,3 +50,5 @@ /** | ||
waitForTimeout: 1000, | ||
rootElement: 'body' | ||
rootElement: 'body', | ||
restart: true, | ||
js_errors: null | ||
}; | ||
@@ -57,3 +59,3 @@ | ||
this.context = this.options.rootElement | ||
this.context = this.options.rootElement; | ||
this.options.waitForTimeout /= 1000; // convert to seconds | ||
@@ -68,7 +70,6 @@ } | ||
static _checkRequirements() | ||
{ | ||
static _checkRequirements() { | ||
try { | ||
requireg("nightmare"); | ||
requireg("nightmare-upload") | ||
requireg("nightmare-upload"); | ||
} catch(e) { | ||
@@ -94,3 +95,3 @@ return ["nightmare", "nightmare-upload"]; | ||
this.evaluate_now(function(by, locator, contextEl) { | ||
this.evaluate_now(function (by, locator, contextEl) { | ||
return window.codeceptjs.findAndStoreElements(by, locator); | ||
@@ -109,3 +110,3 @@ }, done, by, value, contextEl); | ||
this.evaluate_now(function(by, locator, contextEl) { | ||
this.evaluate_now(function (by, locator, contextEl) { | ||
let res = window.codeceptjs.findAndStoreElement(by, locator); | ||
@@ -131,3 +132,3 @@ if (res === null) { | ||
this.evaluate_now(function(el, clean) { | ||
this.evaluate_now(function (el, clean) { | ||
var el = window.codeceptjs.fetchElement(el); | ||
@@ -142,4 +143,4 @@ if (clean) el.value = ''; | ||
this.Nightmare.action('pressKey', function(ns, options, parent, win, renderer, done) { | ||
parent.respondTo('pressKey', function(ch, done) { | ||
this.Nightmare.action('pressKey', function (ns, options, parent, win, renderer, done) { | ||
parent.respondTo('pressKey', function (ch, done) { | ||
win.webContents.sendInputEvent({ | ||
@@ -162,3 +163,3 @@ type: 'keyDown', | ||
done(); | ||
}, function(key, done) { | ||
}, function (key, done) { | ||
this.child.call('pressKey', key, done); | ||
@@ -168,3 +169,30 @@ }); | ||
_beforeSuite() { | ||
if (!this.options.restart) { | ||
return this._startBrowser(); | ||
} | ||
} | ||
_before() { | ||
if (this.options.restart) { | ||
return this._startBrowser(); | ||
} | ||
return this.browser; | ||
} | ||
_after() { | ||
if (this.options.restart) { | ||
return this._stopBrowser(); | ||
} else { | ||
return this.browser.cookies.clearAll(); | ||
} | ||
} | ||
_afterSuite() { | ||
if (!this.options.restart) { | ||
this._stopBrowser(); | ||
} | ||
} | ||
_startBrowser() { | ||
this.browser = this.Nightmare(this.options); | ||
@@ -177,11 +205,8 @@ this.browser.on('dom-ready', () => this._injectClientScripts()); | ||
if (this.options.windowSize) { | ||
if (Array.isArray(this.options.windowSize)) { | ||
let size = this.options.windowSize.split('x'); | ||
this.browser.viewport(size[0], size[1]); | ||
} | ||
let size = this.options.windowSize.split('x'); | ||
return this.browser.viewport(parseInt(size[0]), parseInt(size[1])); | ||
} | ||
return this.browser; | ||
} | ||
_after() { | ||
_stopBrowser() { | ||
return this.browser.end().catch((error) => { | ||
@@ -195,3 +220,3 @@ this.debugSection('Error on End', error); | ||
locator = guessLocator(locator) || {css: locator}; | ||
this.browser.evaluate(function(by, locator) { | ||
this.browser.evaluate(function (by, locator) { | ||
var el = codeceptjs.findElement(by, locator); | ||
@@ -205,3 +230,3 @@ if (!el) throw new Error(`Element by ${by}: ${locator} not found`); | ||
this.context = this.options.rootElement; | ||
return this.browser.evaluate(function() { | ||
return this.browser.evaluate(function () { | ||
codeceptjs.within = null; | ||
@@ -232,4 +257,4 @@ }); | ||
locator = guessLocator(locator) || { css: locator}; | ||
return this.browser.evaluate(function(by, locator) { | ||
return codeceptjs.findElements(by, locator) | ||
return this.browser.evaluate(function (by, locator) { | ||
return codeceptjs.findElements(by, locator); | ||
}, lctype(locator), lcval(locator)); | ||
@@ -347,4 +372,4 @@ } | ||
locator = guessLocator(locator) || { css: locator}; | ||
return this.browser.evaluate(function(by, locator) { | ||
return codeceptjs.findElements(by, locator).filter((e) => e.offsetParent !== null).length | ||
return this.browser.evaluate(function (by, locator) { | ||
return codeceptjs.findElements(by, locator).filter((e) => e.offsetParent !== null).length; | ||
}, lctype(locator), lcval(locator)).then((num) => { | ||
@@ -360,4 +385,4 @@ return equals('number of elements on a page').negate(0, num); | ||
locator = guessLocator(locator) || { css: locator}; | ||
return this.browser.evaluate(function(by, locator) { | ||
return codeceptjs.findElements(by, locator).filter((e) => e.offsetParent !== null).length | ||
return this.browser.evaluate(function (by, locator) { | ||
return codeceptjs.findElements(by, locator).filter((e) => e.offsetParent !== null).length; | ||
}, lctype(locator), lcval(locator)).then((num) => { | ||
@@ -390,3 +415,3 @@ return equals('number of elements on a page').assert(0, num); | ||
seeInSource(text) { | ||
return this.browser.evaluate(function() { | ||
return this.browser.evaluate(function () { | ||
return document.documentElement.outerHTML; | ||
@@ -402,3 +427,3 @@ }).then((source) => { | ||
dontSeeInSource(text) { | ||
return this.browser.evaluate(function() { | ||
return this.browser.evaluate(function () { | ||
return document.documentElement.outerHTML; | ||
@@ -420,3 +445,3 @@ }).then((source) => { | ||
if (el === null) throw new Error(`Clickable element "${locator}" not found by name|text|title|CSS|XPath`); | ||
return this.browser.evaluate(function(el) { | ||
return this.browser.evaluate(function (el) { | ||
return window.codeceptjs.clickEl(el); | ||
@@ -436,3 +461,3 @@ }, el).wait(this.options.waitForAction); // wait for click event to happen | ||
if (el === null) throw new Error(`Clickable element "${locator}" not found by name|text|title|CSS|XPath`); | ||
return this.browser.evaluate(function(el) { | ||
return this.browser.evaluate(function (el) { | ||
return window.codeceptjs.doubleClickEl(el); | ||
@@ -449,3 +474,3 @@ }, el).wait(this.options.waitForAction); // wait for click event to happen | ||
if (el === null) throw new Error(`Element ${locator} not found`); | ||
return this.browser.evaluate(function(el, x, y) { | ||
return this.browser.evaluate(function (el, x, y) { | ||
return window.codeceptjs.hoverEl(el, x, y); | ||
@@ -498,3 +523,3 @@ }, el, offsetX, offsetY).wait(this.options.waitForAction); // wait for hover event to happen | ||
} | ||
return this.browser.evaluate(function(els) { | ||
return this.browser.evaluate(function (els) { | ||
window.codeceptjs.checkEl(els[0]); | ||
@@ -574,4 +599,3 @@ }, els); | ||
*/ | ||
dontSeeCheckboxIsChecked(field) | ||
{ | ||
dontSeeCheckboxIsChecked(field) { | ||
return co.wrap(proceedIsChecked).call(this, 'negate', field); | ||
@@ -583,3 +607,6 @@ } | ||
* | ||
* Due to technical limitation this **works only with CSS selectors** | ||
* ##### Limitations: | ||
* | ||
* * works only with CSS selectors. | ||
* * doesn't work if the Chromium DevTools panel is open (as Chromium allows only one attachment to the debugger at a time. [See more](https://github.com/rosshinkley/nightmare-upload#important-note-about-setting-file-upload-inputs)) | ||
*/ | ||
@@ -604,5 +631,5 @@ attachFile(locator, pathToFile) { | ||
return this.browser.findElement(guessLocator(locator) || { css: locator}).then((el) => { | ||
return this.browser.evaluate(function(el) { | ||
return this.browser.evaluate(function (el) { | ||
return codeceptjs.fetchElement(el).innerText; | ||
}, el) | ||
}, el); | ||
}); | ||
@@ -619,3 +646,3 @@ } | ||
} | ||
return this.browser.evaluate(function(el) { | ||
return this.browser.evaluate(function (el) { | ||
return codeceptjs.fetchElement(el).value; | ||
@@ -631,5 +658,5 @@ }, els[0]); | ||
return this.browser.findElement(guessLocator(locator) || { css: locator}).then((el) => { | ||
return this.browser.evaluate(function(el, attr) { | ||
return this.browser.evaluate(function (el, attr) { | ||
return codeceptjs.fetchElement(el)[attr]; | ||
}, el, attr) | ||
}, el, attr); | ||
}); | ||
@@ -647,14 +674,14 @@ } | ||
selectOption(select, option) { | ||
let fetchAndCheckOption = function(el, locator) { | ||
el = codeceptjs.fetchElement(el); | ||
let found = document.evaluate(locator, el, null, 5); | ||
var current = null; | ||
while (current = found.iterateNext()) { | ||
current.selected = true; | ||
var event = document.createEvent('HTMLEvents'); | ||
if (!el.multiple) el.value = current.value; | ||
event.initEvent('change', true, true); | ||
el.dispatchEvent(event); | ||
} | ||
return !!current; | ||
let fetchAndCheckOption = function (el, locator) { | ||
el = codeceptjs.fetchElement(el); | ||
let found = document.evaluate(locator, el, null, 5); | ||
var current = null; | ||
while (current = found.iterateNext()) { | ||
current.selected = true; | ||
var event = document.createEvent('HTMLEvents'); | ||
if (!el.multiple) el.value = current.value; | ||
event.initEvent('change', true, true); | ||
el.dispatchEvent(event); | ||
} | ||
return !!current; | ||
}; | ||
@@ -676,3 +703,3 @@ let browser = this.browser; | ||
let checked = yield browser.evaluate(fetchAndCheckOption, field, byVisibleText) | ||
let checked = yield browser.evaluate(fetchAndCheckOption, field, byVisibleText); | ||
@@ -682,3 +709,3 @@ if (!checked) { | ||
let byValue = `./option${normalizedValue}|./optgroup/option${normalizedValue}`; | ||
yield browser.evaluate(fetchAndCheckOption, field, byValue) | ||
yield browser.evaluate(fetchAndCheckOption, field, byValue); | ||
} | ||
@@ -739,2 +766,5 @@ } | ||
clearCookie(cookie) { | ||
if (!cookie) { | ||
return this.browser.cookies.clearAll(); | ||
} | ||
return this.browser.cookies.clear(cookie); | ||
@@ -747,3 +777,3 @@ } | ||
wait(sec) { | ||
return new Promise(function(done) { | ||
return new Promise(function (done) { | ||
setTimeout(done, sec * 1000); | ||
@@ -761,5 +791,5 @@ }); | ||
let locator = guessLocator(context) || { css: context}; | ||
this.browser.optionWaitTimeout = sec*1000 || this.options.waitForTimeout; | ||
this.browser.optionWaitTimeout = sec * 1000 || this.options.waitForTimeout; | ||
return this.browser.wait(function(by, locator, text) { | ||
return this.browser.wait(function (by, locator, text) { | ||
return codeceptjs.findElement(by, locator).innerText.indexOf(text) > -1; | ||
@@ -773,6 +803,6 @@ }, lctype(locator), lcval(locator), text); | ||
waitForVisible(locator, sec) { | ||
this.browser.optionWaitTimeout = sec*1000 || this.options.waitForTimeout;; | ||
this.browser.optionWaitTimeout = sec * 1000 || this.options.waitForTimeout; | ||
locator = guessLocator(locator) || { css: locator}; | ||
return this.browser.wait(function(by, locator) { | ||
return this.browser.wait(function (by, locator) { | ||
var el = codeceptjs.findElement(by, locator); | ||
@@ -788,6 +818,6 @@ if (!el) return false; | ||
waitForElement(locator, sec) { | ||
this.browser.optionWaitTimeout = sec*1000 || this.options.waitForTimeout; | ||
this.browser.optionWaitTimeout = sec * 1000 || this.options.waitForTimeout; | ||
locator = guessLocator(locator) || { css: locator}; | ||
return this.browser.wait(function(by, locator) { | ||
return this.browser.wait(function (by, locator) { | ||
return codeceptjs.findElement(by, locator) !== null; | ||
@@ -823,7 +853,7 @@ }, lctype(locator), lcval(locator)); | ||
locator = guessLocator(locator) || {css: locator}; | ||
return this.browser.evaluate(function(by, locator, offsetX, offsetY) { | ||
return this.browser.evaluate(function (by, locator, offsetX, offsetY) { | ||
let el = codeceptjs.findElement(by, locator); | ||
if (!el) throw new Error(`Element not found ${by}: ${locator}`); | ||
let rect = el.getBoundingClientRect(); | ||
window.scrollTo(rect.left+offsetX, rect.top + offsetY); | ||
window.scrollTo(rect.left + offsetX, rect.top + offsetY); | ||
}, lctype(locator), lcval(locator), offsetX, offsetY); | ||
@@ -839,7 +869,7 @@ } | ||
if (!context) { | ||
locator = guessLocator(this.context) || {css: this.context}; | ||
locator = guessLocator(this.context) || {css: this.context}; | ||
if (this.context === this.options.rootElement) { | ||
description = 'web application'; | ||
} else { | ||
description = 'current context ' + this.context;[] | ||
description = 'current context ' + this.context; []; | ||
} | ||
@@ -851,5 +881,5 @@ } else { | ||
return this.browser.evaluate(function(by, locator) { | ||
return this.browser.evaluate(function (by, locator) { | ||
return codeceptjs.findElements(by, locator).map((el) => el.innerText); | ||
}, lctype(locator), lcval(locator)).then(function (texts) { | ||
}, lctype(locator), lcval(locator)).then(function (texts) { | ||
let allText = texts.join(' | '); | ||
@@ -866,12 +896,13 @@ return stringIncludes(description)[assertType](text, allText); | ||
let el = els[0]; | ||
let tag = yield this.browser.evaluate(function(el) { | ||
let tag = yield this.browser.evaluate(function (el) { | ||
return codeceptjs.fetchElement(el).tagName; | ||
}, el); | ||
let fieldVal = yield this.browser.evaluate(function(el) { | ||
return codeceptjs.fetchElement(el).value; } | ||
let fieldVal = yield this.browser.evaluate(function (el) { | ||
return codeceptjs.fetchElement(el).value; | ||
} | ||
, el); | ||
if (tag == 'select') { | ||
// locate option by values and check them | ||
let text = yield this.browser.evaluate(function(el, val) { | ||
return el.querySelector(`option[value="${val}"]`).innerText | ||
let text = yield this.browser.evaluate(function (el, val) { | ||
return el.querySelector(`option[value="${val}"]`).innerText; | ||
}, el, xpathLocator.literal(fieldVal)); | ||
@@ -888,3 +919,3 @@ return equals('select option by ' + field)[assertType](value, text); | ||
} | ||
let selected = yield this.browser.evaluate(function(els) { | ||
let selected = yield this.browser.evaluate(function (els) { | ||
return els.map((el) => codeceptjs.fetchElement(el).checked) | ||
@@ -1004,5 +1035,4 @@ .reduce((prev, cur) => prev || cur); | ||
function guessLocator(locator) { | ||
if (typeof (locator) === 'object') { | ||
if (typeof locator === 'object') { | ||
let key = Object.keys(locator)[0]; | ||
@@ -1026,3 +1056,3 @@ let value = locator[key]; | ||
function isXPath(locator) { | ||
return locator.substr(0, 2) === '//' || locator.substr(0, 3) === './/' | ||
return locator.substr(0, 2) === '//' || locator.substr(0, 3) === './/'; | ||
} | ||
@@ -1035,3 +1065,3 @@ | ||
function lcval(locator) { | ||
return locator[Object.keys(locator)[0]] | ||
return locator[Object.keys(locator)[0]]; | ||
} |
'use strict'; | ||
let protractorWrapper, protractorPlugins, EC; | ||
const requireg = require('requireg') | ||
const requireg = require('requireg'); | ||
const SeleniumWebdriver = require('./SeleniumWebdriver'); | ||
@@ -45,2 +45,3 @@ const stringIncludes = require('../assert/include').includes; | ||
* * `rootElement` - Root element of AngularJS application (default: body) | ||
* * `windowSize`: (optional) default window size. Set to `maximize` or a dimension in the format `640x480`. | ||
* * `manualStart` (optional, default: false) - do not start browser before a test, start it manually inside a helper with `this.helpers["WebDriverIO"]._startBrowser()` | ||
@@ -70,2 +71,3 @@ * * `capabilities`: {} - list of [Desired Capabilities](https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities) | ||
scriptsTimeout: 10000, | ||
windowSize: null, | ||
driver: 'hosted', | ||
@@ -104,3 +106,3 @@ capabilities: {} | ||
let driverProviderModule = requireg('protractor/built/driverProviders/'+this.options.driver); | ||
let driverProviderModule = requireg('protractor/built/driverProviders/' + this.options.driver); | ||
let className = Object.keys(driverProviderModule)[0]; | ||
@@ -111,4 +113,3 @@ this.driverProvider = new driverProviderModule[className](this.options); | ||
static _checkRequirements() | ||
{ | ||
static _checkRequirements() { | ||
try { | ||
@@ -138,2 +139,12 @@ requireg("protractor"); | ||
this.browser.ready = this.browser.manage().timeouts().setScriptTimeout(this.options.scriptsTimeout); | ||
if (this.options.windowSize == 'maximize') { | ||
this.resizeWindow(this.options.windowSize); | ||
} | ||
if (this.options.windowSize) { | ||
var size = this.options.windowSize.split('x'); | ||
this.resizeWindow(parseInt(size[0]), parseInt(size[1])); | ||
} | ||
return this.browser; | ||
@@ -155,7 +166,7 @@ } | ||
if (this.insideAngular) { | ||
let context = this.browser.element(guessLocator(locator) || by.css(locator)); | ||
let context = this.browser.element(guessLocator(locator) || by.css(locator)); | ||
this.browser.findElement = (l) => l ? context.element(l).getWebElement() : context.getWebElement(); | ||
this.browser.findElements = (l) => context.all(l).getWebElements(); | ||
return context; | ||
this.browser.findElement = (l) => l ? context.element(l).getWebElement() : context.getWebElement(); | ||
this.browser.findElements = (l) => context.all(l).getWebElements(); | ||
return context; | ||
} | ||
@@ -211,3 +222,3 @@ return super._withinBegin(locator); | ||
let el = this.browser.element(guessLocator(locator) || by.css(locator)); | ||
return this.browser.wait(EC.presenceOf(el), sec*1000); | ||
return this.browser.wait(EC.presenceOf(el), sec * 1000); | ||
} | ||
@@ -221,3 +232,3 @@ | ||
let el = this.browser.element(guessLocator(locator) || by.css(locator)); | ||
return this.browser.wait(EC.elementToBeClickable(el), sec*1000); | ||
return this.browser.wait(EC.elementToBeClickable(el), sec * 1000); | ||
} | ||
@@ -231,3 +242,3 @@ | ||
let el = this.browser.element(guessLocator(locator) || by.css(locator)); | ||
return this.browser.wait(EC.visibilityOf(el), sec*1000); | ||
return this.browser.wait(EC.visibilityOf(el), sec * 1000); | ||
} | ||
@@ -241,3 +252,3 @@ | ||
let el = this.browser.element(guessLocator(locator) || by.css(locator)); | ||
return this.browser.wait(EC.invisibilityOf(el), sec*1000); | ||
return this.browser.wait(EC.invisibilityOf(el), sec * 1000); | ||
} | ||
@@ -261,3 +272,3 @@ | ||
sec = sec || 1; | ||
return this.browser.wait(EC.textToBePresentInElement(el, text), sec*1000); | ||
return this.browser.wait(EC.textToBePresentInElement(el, text), sec * 1000); | ||
} | ||
@@ -316,3 +327,3 @@ | ||
} | ||
if (typeof (locator) === 'object') { | ||
if (typeof locator === 'object') { | ||
let key = Object.keys(locator)[0]; | ||
@@ -335,3 +346,3 @@ let value = locator[key]; | ||
function isXPath(locator) { | ||
return locator.substr(0, 2) === '//' || locator.substr(0, 3) === './/' | ||
return locator.substr(0, 2) === '//' || locator.substr(0, 3) === './/'; | ||
} | ||
@@ -338,0 +349,0 @@ |
'use strict'; | ||
let until; | ||
const requireg = require('requireg') | ||
const requireg = require('requireg'); | ||
const Helper = require('../helper'); | ||
@@ -48,2 +48,3 @@ const stringIncludes = require('../assert/include').includes; | ||
* * `scriptTimeout`: (optional) sets default timeout for scripts in `executeAsync`. 1000 by default. | ||
* * `windowSize`: (optional) default window size. Set to `maximize` or a dimension in the format `640x480`. | ||
* * `manualStart` (optional, default: false) - do not start browser before a test, start it manually inside a helper with `this.helpers["WebDriverIO"]._startBrowser()` | ||
@@ -71,2 +72,3 @@ * * `capabilities`: {} - list of [Desired Capabilities](https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities) | ||
restart: true, | ||
windowSize: null, | ||
waitforTimeout: 1000, // ms | ||
@@ -85,4 +87,4 @@ scriptTimeout: 1000, // ms | ||
this.context = 'body' | ||
this.options.rootElement = 'body' // protractor compat | ||
this.context = 'body'; | ||
this.options.rootElement = 'body'; // protractor compat | ||
@@ -97,4 +99,3 @@ this.browserBuilder = new this.webdriver.Builder() | ||
static _checkRequirements() | ||
{ | ||
static _checkRequirements() { | ||
try { | ||
@@ -116,2 +117,12 @@ requireg("selenium-webdriver"); | ||
this.browser = this.browserBuilder.build(); | ||
if (this.options.windowSize == 'maximize') { | ||
this.resizeWindow(this.options.windowSize); | ||
} | ||
if (this.options.windowSize) { | ||
var size = this.options.windowSize.split('x'); | ||
this.resizeWindow(parseInt(size[0]), parseInt(size[1])); | ||
} | ||
return this.browser; | ||
@@ -122,3 +133,3 @@ } | ||
if (!this.options.restart && !this.options.manualStart) { | ||
this.debugSection('Session','Starting singleton browser session'); | ||
this.debugSection('Session', 'Starting singleton browser session'); | ||
return this._startBrowser(); | ||
@@ -129,3 +140,5 @@ } | ||
_before() { | ||
if (this.options.restart && !this.options.manualStart) return this._startBrowser(); | ||
if (this.options.restart && !this.options.manualStart) { | ||
return this._startBrowser(); | ||
} | ||
} | ||
@@ -139,3 +152,3 @@ | ||
return this.browser.manage().deleteAllCookies(); | ||
}) | ||
}); | ||
} | ||
@@ -224,3 +237,3 @@ | ||
return this.browser.actions().mouseMove(el, offset).perform(); | ||
}) | ||
}); | ||
} | ||
@@ -289,3 +302,3 @@ | ||
let modifier; | ||
if (Array.isArray(key) && ~['Control','Command','Shift','Alt'].indexOf(key[0])) { | ||
if (Array.isArray(key) && ~['Control', 'Command', 'Shift', 'Alt'].indexOf(key[0])) { | ||
modifier = this.webdriver.Key[key[0].toUpperCase()]; | ||
@@ -301,5 +314,5 @@ key = key[1]; | ||
let action = new this.webdriver.ActionSequence(this.browser); | ||
if (modifier) action.keyDown(modifier) | ||
if (modifier) action.keyDown(modifier); | ||
action.sendKeys(key); | ||
if (modifier) action.keyUp(modifier) | ||
if (modifier) action.keyUp(modifier); | ||
return action.perform(); | ||
@@ -325,3 +338,3 @@ } | ||
return els[0].sendKeys(file); | ||
}); | ||
}); | ||
} | ||
@@ -395,4 +408,3 @@ | ||
*/ | ||
dontSeeCheckboxIsChecked(field) | ||
{ | ||
dontSeeCheckboxIsChecked(field) { | ||
return co.wrap(proceedIsChecked).call(this, 'negate', field); | ||
@@ -412,3 +424,3 @@ } | ||
grabValueFrom(locator) { | ||
return co(findFields(this.browser, locator)).then(function(els) { | ||
return co(findFields(this.browser, locator)).then(function (els) { | ||
if (!els.length) { | ||
@@ -571,3 +583,3 @@ throw new Error(`Field ${locator} was not located by name|label|CSS|XPath`); | ||
this.debug('Screenshot has been saved to ' + outputFile); | ||
return this.browser.takeScreenshot().then(function(png) { | ||
return this.browser.takeScreenshot().then(function (png) { | ||
let fs = require('fs'); | ||
@@ -577,3 +589,3 @@ var stream = fs.createWriteStream(outputFile); | ||
stream.end(); | ||
return new Promise(function(resolve) { | ||
return new Promise(function (resolve) { | ||
return stream.on('finish', resolve); | ||
@@ -661,3 +673,3 @@ }); | ||
sec = sec || this.options.waitforTimeout; | ||
return this.browser.wait(this.webdriver.until.elementsLocated(guessLocator(locator) || by.css(locator)), sec*1000); | ||
return this.browser.wait(this.webdriver.until.elementsLocated(guessLocator(locator) || by.css(locator)), sec * 1000); | ||
} | ||
@@ -671,3 +683,3 @@ | ||
let el = this.browser.findElement(guessLocator(locator) || by.css(locator)); | ||
return this.browser.wait(this.webdriver.until.elementIsVisible(el), sec*1000); | ||
return this.browser.wait(this.webdriver.until.elementIsVisible(el), sec * 1000); | ||
} | ||
@@ -681,3 +693,3 @@ | ||
let el = this.browser.findElement(guessLocator(locator) || by.css(locator)); | ||
return this.browser.wait(this.webdriver.until.elementIsNotVisible(el), sec*1000); | ||
return this.browser.wait(this.webdriver.until.elementIsNotVisible(el), sec * 1000); | ||
} | ||
@@ -691,3 +703,3 @@ | ||
let el = this.browser.findElement(guessLocator(locator) || by.css(locator)); | ||
return this.browser.wait(this.webdriver.until.stalenessOf(el), sec*1000); | ||
return this.browser.wait(this.webdriver.until.stalenessOf(el), sec * 1000); | ||
} | ||
@@ -704,3 +716,3 @@ | ||
sec = sec || this.options.waitforTimeout; | ||
return this.browser.wait(this.webdriver.until.elementTextIs(el, text), sec*1000); | ||
return this.browser.wait(this.webdriver.until.elementTextIs(el, text), sec * 1000); | ||
} | ||
@@ -783,3 +795,3 @@ | ||
let source = ''; | ||
els.forEach(el => promises.push(el.getText().then((elText) => source+= '| ' + elText))); | ||
els.forEach(el => promises.push(el.getText().then((elText) => source += '| ' + elText))); | ||
yield Promise.all(promises); | ||
@@ -815,4 +827,4 @@ return stringIncludes(description)[assertType](text, source); | ||
}); | ||
return Promise.all(elsSelected).then(function(values) { | ||
let selected = values.reduce((prev, cur) => prev || cur) | ||
return Promise.all(elsSelected).then(function (values) { | ||
let selected = values.reduce((prev, cur) => prev || cur); | ||
return truth(`checkable ${option}`, 'to be checked')[assertType](selected); | ||
@@ -866,3 +878,3 @@ }); | ||
} | ||
if (typeof (locator) === 'object') { | ||
if (typeof locator === 'object') { | ||
let key = Object.keys(locator)[0]; | ||
@@ -886,3 +898,3 @@ let value = locator[key]; | ||
function isXPath(locator) { | ||
return locator.substr(0, 2) === '//' || locator.substr(0, 3) === './/' | ||
return locator.substr(0, 2) === '//' || locator.substr(0, 3) === './/'; | ||
} |
@@ -57,3 +57,3 @@ 'use strict'; | ||
* "restart": false, | ||
* "windowSize": "maximize, | ||
* "windowSize": "maximize", | ||
* "timeouts": { | ||
@@ -314,6 +314,6 @@ * "script": 60000, | ||
return this.browser.element(withStrictLocator(locator)).then((res) => { | ||
this.browser.element = function(l) { | ||
this.browser.element = function (l) { | ||
return this.elementIdElement(res.value.ELEMENT, l); | ||
}; | ||
this.browser.elements = function(l) { | ||
this.browser.elements = function (l) { | ||
return this.elementIdElements(res.value.ELEMENT, l); | ||
@@ -350,5 +350,5 @@ }; | ||
_locateCheckable(locator) { | ||
return findCheckable(this.browser, locator).then(function(res) { | ||
return findCheckable(this.browser, locator).then(function (res) { | ||
return res.value; | ||
}) | ||
}); | ||
} | ||
@@ -364,5 +364,5 @@ | ||
_locateClickable(locator) { | ||
return findClickable(this.browser, locator).then(function(res) { | ||
return findClickable(this.browser, locator).then(function (res) { | ||
return res.value; | ||
}) | ||
}); | ||
} | ||
@@ -378,5 +378,5 @@ | ||
_locateFields(locator) { | ||
return findFields(this.browser, locator).then(function(res) { | ||
return findFields(this.browser, locator).then(function (res) { | ||
return res.value; | ||
}) | ||
}); | ||
} | ||
@@ -424,5 +424,5 @@ | ||
} | ||
return findClickable(client, locator).then(function(res) { | ||
return findClickable(client, locator).then(function (res) { | ||
if (!res.value || res.value.length === 0) { | ||
if (typeof(locator) === "object") locator = JSON.stringify(locator); | ||
if (typeof locator === "object") locator = JSON.stringify(locator); | ||
throw new Error(`Clickable element ${locator.toString()} was not found by text|CSS|XPath`); | ||
@@ -443,5 +443,5 @@ } | ||
} | ||
return findClickable(client, locator).then(function(res) { | ||
return findClickable(client, locator).then(function (res) { | ||
if (!res.value || res.value.length === 0) { | ||
if (typeof(locator) === "object") locator = JSON.stringify(locator); | ||
if (typeof locator === "object") locator = JSON.stringify(locator); | ||
throw new Error(`Clickable element ${locator.toString()} was not found by text|CSS|XPath`); | ||
@@ -465,3 +465,3 @@ } | ||
fillField(field, value) { | ||
return findFields(this.browser, field).then(function(res) { | ||
return findFields(this.browser, field).then(function (res) { | ||
if (!res.value || res.value.length === 0) { | ||
@@ -479,3 +479,3 @@ throw new Error(`Field ${field} not found by name|text|CSS|XPath`); | ||
appendField(field, value) { | ||
return findFields(this.browser, field).then(function(res) { | ||
return findFields(this.browser, field).then(function (res) { | ||
if (!res.value || res.value.length === 0) { | ||
@@ -494,3 +494,3 @@ throw new Error(`Field ${field} not found by name|text|CSS|XPath`); | ||
selectOption(select, option) { | ||
return findFields(this.browser, select).then(function(res) { | ||
return findFields(this.browser, select).then(function (res) { | ||
if (!res.value || res.value.length === 0) { | ||
@@ -581,3 +581,3 @@ throw new Error(`Selectable field ${select} not found by name|text|CSS|XPath`); | ||
let elem = res.value[0]; | ||
return client.elementIdSelected(elem.ELEMENT).then(function(isSelected) { | ||
return client.elementIdSelected(elem.ELEMENT).then(function (isSelected) { | ||
if (isSelected.value) return true; | ||
@@ -593,3 +593,3 @@ return this[clickMethod](elem.ELEMENT); | ||
grabTextFrom(locator) { | ||
return this.browser.getText(withStrictLocator(locator)).then(function(text) { | ||
return this.browser.getText(withStrictLocator(locator)).then(function (text) { | ||
return text; | ||
@@ -608,3 +608,3 @@ }); | ||
grabHTMLFrom(locator) { | ||
return this.browser.getHTML(withStrictLocator(locator)).then(function(html) { | ||
return this.browser.getHTML(withStrictLocator(locator)).then(function (html) { | ||
return html; | ||
@@ -618,3 +618,3 @@ }); | ||
grabValueFrom(locator) { | ||
return this.browser.getValue(withStrictLocator(locator)).then(function(text) { | ||
return this.browser.getValue(withStrictLocator(locator)).then(function (text) { | ||
return text; | ||
@@ -628,3 +628,3 @@ }); | ||
grabAttributeFrom(locator, attr) { | ||
return this.browser.getAttribute(withStrictLocator(locator), attr).then(function(text) { | ||
return this.browser.getAttribute(withStrictLocator(locator), attr).then(function (text) { | ||
return text; | ||
@@ -708,3 +708,3 @@ }); | ||
seeElement(locator) { | ||
return this.browser.isVisible(withStrictLocator(locator)).then(function(res) { | ||
return this.browser.isVisible(withStrictLocator(locator)).then(function (res) { | ||
return truth(`elements of ${locator}`, 'to be seen').assert(res); | ||
@@ -718,3 +718,3 @@ }); | ||
dontSeeElement(locator) { | ||
return this.browser.isVisible(withStrictLocator(locator)).then(function(res) { | ||
return this.browser.isVisible(withStrictLocator(locator)).then(function (res) { | ||
return truth(`elements of ${locator}`, 'to be seen').negate(res); | ||
@@ -728,3 +728,3 @@ }); | ||
seeElementInDOM(locator) { | ||
return this.browser.elements(withStrictLocator(locator)).then(function(res) { | ||
return this.browser.elements(withStrictLocator(locator)).then(function (res) { | ||
return empty('elements').negate(res.value); | ||
@@ -738,3 +738,3 @@ }); | ||
dontSeeElementInDOM(locator) { | ||
return this.browser.elements(withStrictLocator(locator)).then(function(res) { | ||
return this.browser.elements(withStrictLocator(locator)).then(function (res) { | ||
return empty('elements').assert(res.value); | ||
@@ -772,3 +772,3 @@ }); | ||
return this.browser.elements(withStrictLocator(selector)) | ||
.then(function(res) { | ||
.then(function (res) { | ||
return assert.equal(res.value.length, num); | ||
@@ -782,3 +782,3 @@ }); | ||
seeInCurrentUrl(url) { | ||
return this.browser.url().then(function(res) { | ||
return this.browser.url().then(function (res) { | ||
return stringIncludes('url').assert(url, res.value); | ||
@@ -792,3 +792,3 @@ }); | ||
dontSeeInCurrentUrl(url) { | ||
return this.browser.url().then(function(res) { | ||
return this.browser.url().then(function (res) { | ||
return stringIncludes('url').negate(url, res.value); | ||
@@ -881,3 +881,3 @@ }); | ||
clearField(field) { | ||
return findFields(this.browser, field).then(function(res) { | ||
return findFields(this.browser, field).then(function (res) { | ||
if (!res.value || res.value.length === 0) { | ||
@@ -896,3 +896,3 @@ throw new Error(`Field ${field} not found by name|text|CSS|XPath`); | ||
seeCookie(name) { | ||
return this.browser.getCookie(name).then(function(res) { | ||
return this.browser.getCookie(name).then(function (res) { | ||
return truth('cookie ' + name, 'to be set').assert(res); | ||
@@ -906,3 +906,3 @@ }); | ||
dontSeeCookie(name) { | ||
return this.browser.getCookie(name).then(function(res) { | ||
return this.browser.getCookie(name).then(function (res) { | ||
return truth('cookie ' + name, 'to be set').negate(res); | ||
@@ -924,3 +924,3 @@ }); | ||
acceptPopup() { | ||
return this.browser.alertText().then(function(res) { | ||
return this.browser.alertText().then(function (res) { | ||
if (res !== null) { | ||
@@ -936,3 +936,3 @@ return this.alertAccept(); | ||
cancelPopup() { | ||
return this.browser.alertText().then(function(res) { | ||
return this.browser.alertText().then(function (res) { | ||
if (res !== null) { | ||
@@ -948,3 +948,3 @@ return this.alertDismiss(); | ||
seeInPopup(text) { | ||
return this.browser.alertText().then(function(res) { | ||
return this.browser.alertText().then(function (res) { | ||
if (res === null) { | ||
@@ -973,3 +973,3 @@ throw new Error('Popup is not opened'); | ||
} | ||
return this.browser.keys(key).then(function() { | ||
return this.browser.keys(key).then(function () { | ||
if (!modifier) return true; | ||
@@ -1036,10 +1036,10 @@ return this.keys(modifier); // release modifeier | ||
context = context || 'body'; | ||
return this.browser.waitUntil(function() { | ||
return this.getText(context).then(function(source) { | ||
if (Array.isArray(source)) { | ||
return source.filter(part => part.indexOf(text) >= 0).length > 0; | ||
} | ||
return source.indexOf(text) >= 0; | ||
}); | ||
}, sec * 1000) | ||
return this.browser.waitUntil(function () { | ||
return this.getText(context).then(function (source) { | ||
if (Array.isArray(source)) { | ||
return source.filter(part => part.indexOf(text) >= 0).length > 0; | ||
} | ||
return source.indexOf(text) >= 0; | ||
}); | ||
}, sec * 1000) | ||
.catch((e) => { | ||
@@ -1115,3 +1115,3 @@ if (e.type === 'WaitUntilTimeoutError') { | ||
} | ||
return this.browser.getText(withStrictLocator(context)).then(function(source) { | ||
return this.browser.getText(withStrictLocator(context)).then(function (source) { | ||
return stringIncludes(description)[assertType](text, source); | ||
@@ -1122,3 +1122,3 @@ }); | ||
function findClickable(client, locator) { | ||
if (typeof(locator) === 'object') return client.elements(withStrictLocator(locator)); | ||
if (typeof locator === 'object') return client.elements(withStrictLocator(locator)); | ||
if (isCSSorXPathLocator(locator)) return client.elements(locator); | ||
@@ -1134,3 +1134,3 @@ | ||
]); | ||
return client.elements(narrowLocator).then(function(els) { | ||
return client.elements(narrowLocator).then(function (els) { | ||
if (els.value.length) { | ||
@@ -1147,3 +1147,3 @@ return els; | ||
]); | ||
return client.elements(wideLocator).then(function(els) { | ||
return client.elements(wideLocator).then(function (els) { | ||
if (els.value.length) { | ||
@@ -1158,3 +1158,3 @@ return els; | ||
function findFields(client, locator) { | ||
if (typeof(locator) === 'object') return client.elements(withStrictLocator(locator)); | ||
if (typeof locator === 'object') return client.elements(withStrictLocator(locator)); | ||
if (isCSSorXPathLocator(locator)) return client.elements(locator); | ||
@@ -1178,3 +1178,3 @@ | ||
function proceedSeeField(assertType, field, value) { | ||
return findFields(this.browser, field).then(function(res) { | ||
return findFields(this.browser, field).then(function (res) { | ||
if (!res.value || res.value.length === 0) { | ||
@@ -1199,3 +1199,3 @@ throw new Error(`Field ${field} not found by name|text|CSS|XPath`); | ||
}); | ||
} | ||
}; | ||
@@ -1206,3 +1206,3 @@ var proceedSingle = (el) => { | ||
}); | ||
} | ||
}; | ||
@@ -1228,3 +1228,3 @@ return this.elementIdName(res.value[0].ELEMENT).then((tag) => { | ||
function proceedSeeCheckbox(assertType, field) { | ||
return findFields(this.browser, field).then(function(res) { | ||
return findFields(this.browser, field).then(function (res) { | ||
if (!res.value || res.value.length === 0) { | ||
@@ -1244,3 +1244,3 @@ throw new Error(`Field ${field} not found by name|text|CSS|XPath`); | ||
function findCheckable(client, locator) { | ||
if (typeof(locator) === 'object') return client.elements(withStrictLocator(locator)); | ||
if (typeof locator === 'object') return client.elements(withStrictLocator(locator)); | ||
if (isCSSorXPathLocator(locator)) return client.elements(locator); | ||
@@ -1253,6 +1253,6 @@ | ||
]); | ||
return client.elements(byText).then(function(els) { | ||
return client.elements(byText).then(function (els) { | ||
if (els.value.length) return els; | ||
let byName = `.//input[@type = 'checkbox' or @type = 'radio'][@name = ${literal}]`; | ||
return client.elements(byName).then(function(els) { | ||
return client.elements(byName).then(function (els) { | ||
if (els.value.length) return els; | ||
@@ -1276,3 +1276,3 @@ return client.elements(locator); // by css or xpath | ||
if (!locator) return null; | ||
if (typeof(locator) !== 'object') return locator; | ||
if (typeof locator !== 'object') return locator; | ||
let key = Object.keys(locator)[0]; | ||
@@ -1284,10 +1284,10 @@ let value = locator[key]; | ||
switch (key) { | ||
case 'by': | ||
case 'xpath': | ||
case 'css': | ||
return value; | ||
case 'id': | ||
return '#' + value; | ||
case 'name': | ||
return `[name="${value}"]`; | ||
case 'by': | ||
case 'xpath': | ||
case 'css': | ||
return value; | ||
case 'id': | ||
return '#' + value; | ||
case 'name': | ||
return `[name="${value}"]`; | ||
} | ||
@@ -1294,0 +1294,0 @@ } |
@@ -7,3 +7,3 @@ 'use strict'; | ||
module.exports = function(hook, config, done) { | ||
module.exports = function (hook, config, done) { | ||
if (typeof config[hook] === 'string' && fileExists(fsPath.join(codecept_dir, config[hook]))) { | ||
@@ -23,4 +23,5 @@ var callable = require(fsPath.join(codecept_dir, config[hook])); | ||
} | ||
done(); | ||
} | ||
// if async - call done | ||
if (done) done(); | ||
}; | ||
@@ -39,2 +40,2 @@ function callSync(callable, done) { | ||
return params && params.length; | ||
} | ||
} |
@@ -87,5 +87,5 @@ /** | ||
context.Scenario = function (title, opts, fn) { | ||
if ((typeof opts == 'function') && !fn) { | ||
if (typeof opts === 'function' && !fn) { | ||
fn = opts; | ||
opts = {} | ||
opts = {}; | ||
} | ||
@@ -123,5 +123,5 @@ | ||
context.xScenario = context.Scenario.skip = function (title) { | ||
context.Scenario(title); | ||
context.Scenario(title, {}); | ||
}; | ||
}); | ||
}; |
@@ -37,2 +37,3 @@ 'use strict'; | ||
runHelpersHook('_test', test); | ||
recorder.catch((e) => debug(e)); | ||
}); | ||
@@ -55,7 +56,7 @@ | ||
event.dispatcher.on(event.step.before, function (step) { | ||
runHelpersHook('_beforeStep', step); | ||
runAsyncHelpersHook('_beforeStep', step); | ||
}); | ||
event.dispatcher.on(event.step.after, function (step) { | ||
runHelpersHook('_afterStep', step); | ||
runAsyncHelpersHook('_afterStep', step); | ||
}); |
@@ -17,3 +17,3 @@ 'use strict'; | ||
module.exports = function () { | ||
recorder.add('Start new session' ,function () { | ||
recorder.add('Start new session', function () { | ||
recorder.session.start('pause'); | ||
@@ -20,0 +20,0 @@ output.print(colors.yellow(" Interative debug session started")); |
'use strict'; | ||
let promise, oldpromise; | ||
let promise, oldPromise; | ||
let running = false; | ||
@@ -14,3 +14,3 @@ let errFn; | ||
/** | ||
* Singlton object to record all test steps as promises and run them in chain. | ||
* Singleton object to record all test steps as promises and run them in chain. | ||
*/ | ||
@@ -35,3 +35,3 @@ module.exports = { | ||
promise = Promise.resolve(); | ||
oldpromise = null; | ||
oldPromise = null; | ||
tasks = []; | ||
@@ -47,3 +47,3 @@ this.session.running = false; | ||
tasks.push('--->'); | ||
oldpromise = promise; | ||
oldPromise = promise; | ||
this.running = true; | ||
@@ -81,8 +81,2 @@ sessionId = name; | ||
addStep(step, args) { | ||
step.status = 'queued'; | ||
let task = `${step.name}: ${Object.keys(args).map(key => args[key]).join(', ')}`; | ||
this.add(task, () => step.run.apply(step, args)); | ||
}, | ||
catch(customErrFn) { | ||
@@ -92,3 +86,3 @@ return promise = promise.catch((err) => { | ||
if (!(err instanceof Error)) { // strange things may happen | ||
err = new Error('[Wrapped Error] '+err.toString()); // we should be prepared for them | ||
err = new Error('[Wrapped Error] ' + JSON.stringify(err)); // we should be prepared for them | ||
} | ||
@@ -105,3 +99,3 @@ if (customErrFn) { | ||
throw(err) { | ||
return this.add('throw error ' + err,function () { | ||
return this.add('throw error ' + err, function () { | ||
throw err; | ||
@@ -108,0 +102,0 @@ }); |
@@ -95,3 +95,3 @@ 'use strict'; | ||
var lines = err.stack.split('\n'); | ||
lines.splice(0,1); | ||
lines.splice(0, 1); | ||
err.stack = lines.join('\n'); | ||
@@ -98,0 +98,0 @@ } |
@@ -19,4 +19,4 @@ 'use strict'; | ||
test.steps = []; | ||
test.fn = function (done) { | ||
recorder.errHandler(function (err) { | ||
@@ -41,3 +41,3 @@ recorder.session.start('teardown'); | ||
let resumeTest = function () { | ||
recorder.add('create new promises queue for generator',function (data) { | ||
recorder.add('create new promises queue for generator', function (data) { | ||
recorder.session.start('generator'); // creating a new promise chain | ||
@@ -77,3 +77,3 @@ try { | ||
module.exports.injected = function (fn) { | ||
return function() { | ||
return function () { | ||
try { | ||
@@ -80,0 +80,0 @@ fn.apply(this, getInjectedArguments(fn)); |
'use strict'; | ||
let event = require('./event'); | ||
/** | ||
@@ -19,7 +17,11 @@ * Each command in test executed through `I.` object is wrapped in Step. | ||
Error.captureStackTrace(this); | ||
this.args = []; | ||
} | ||
setArguments(args) { | ||
this.args = args; | ||
} | ||
run() { | ||
this.args = Array.prototype.slice.call(arguments); | ||
event.emit(event.step.before, this); | ||
let result; | ||
@@ -32,4 +34,2 @@ try { | ||
throw err; | ||
} finally { | ||
event.emit(event.step.after, this); | ||
} | ||
@@ -46,3 +46,5 @@ return result; | ||
// uppercase the first character | ||
.replace(/^(.)|\s(.)/g, function ( $1 ) { return $1.toLowerCase( ); } ); | ||
.replace(/^(.)|\s(.)/g, function ($1) { | ||
return $1.toLowerCase(); | ||
}); | ||
} | ||
@@ -52,9 +54,9 @@ | ||
return this.args.map((arg) => { | ||
if (typeof(arg) === "string" ) { | ||
if (typeof arg === "string") { | ||
return `"${arg}"`; | ||
} else if (Array.isArray(arg)) { | ||
return `[${arg.toString()}]`; | ||
} else if (typeof(arg) === "function" ) { | ||
} else if (typeof arg === "function") { | ||
return "function()"; | ||
} else if (typeof(arg) === "object" ) { | ||
} else if (typeof arg === "object") { | ||
return JSON.stringify(arg); | ||
@@ -61,0 +63,0 @@ } else if (arg.toString) { |
@@ -26,2 +26,2 @@ 'use strict'; | ||
module.exports = Translation; | ||
module.exports = Translation; |
var fs = require('fs'); | ||
var path = require('path'); | ||
module.exports.fileExists = function(filePath) { | ||
module.exports.fileExists = function (filePath) { | ||
try { | ||
@@ -13,3 +13,3 @@ fs.statSync(filePath); | ||
module.exports.isFile = function(filePath) { | ||
module.exports.isFile = function (filePath) { | ||
var filestat; | ||
@@ -25,3 +25,3 @@ try { | ||
module.exports.getParamNames = function(fn) { | ||
module.exports.getParamNames = function (fn) { | ||
if (fn.isSinonProxy) return []; | ||
@@ -32,7 +32,7 @@ var funStr = fn.toString(); | ||
module.exports.installedLocally = function() { | ||
module.exports.installedLocally = function () { | ||
return path.resolve(__dirname + '/../').indexOf(process.cwd()) === 0; | ||
} | ||
}; | ||
module.exports.methodsOfObject = function(obj, className) { | ||
module.exports.methodsOfObject = function (obj, className) { | ||
var methods = []; | ||
@@ -52,3 +52,3 @@ | ||
Object.getOwnPropertyNames(obj).forEach((prop) => { | ||
if (typeof(obj[prop]) !== 'function') return; | ||
if (typeof obj[prop] !== 'function') return; | ||
if (standard.indexOf(prop) >= 0) return; | ||
@@ -65,4 +65,4 @@ if (prop.indexOf('_') === 0) return; | ||
module.exports.template = function(template, data) { | ||
return template.replace(/{{([^{}]*)}}/g, function(a, b) { | ||
module.exports.template = function (template, data) { | ||
return template.replace(/{{([^{}]*)}}/g, function (a, b) { | ||
var r = data[b]; | ||
@@ -74,11 +74,11 @@ if (r === undefined) return ''; | ||
module.exports.ucfirst = function(str) { | ||
module.exports.ucfirst = function (str) { | ||
return str.charAt(0).toUpperCase() + str.substr(1); | ||
}; | ||
module.exports.lcfirst = function(str) { | ||
module.exports.lcfirst = function (str) { | ||
return str.charAt(0).toLowerCase() + str.substr(1); | ||
}; | ||
module.exports.hashCode = function(str) { | ||
module.exports.hashCode = function (str) { | ||
/* Getting 32bit hashCode of string like in Java. | ||
@@ -92,3 +92,3 @@ * Used in Screenshot name to provide short screenshot names | ||
char = str.charCodeAt(i); | ||
hash = ((hash << 5) - hash) + char; | ||
hash = (hash << 5) - hash + char; | ||
hash = hash & hash; // Convert to 32bit integer | ||
@@ -102,3 +102,3 @@ } | ||
if (string.indexOf("'") > -1) { | ||
string = string.split("'", -1).map(function(substr) { | ||
string = string.split("'", -1).map(function (substr) { | ||
return "'" + substr + "'"; | ||
@@ -118,15 +118,15 @@ }).join(',"\'",'); | ||
submittedData: function(dataFile) { | ||
return function(key) { | ||
submittedData: function (dataFile) { | ||
return function (key) { | ||
var data = JSON.parse(fs.readFileSync(dataFile, 'utf8')); | ||
if (key) { | ||
return data['form'][key]; | ||
return data.form[key]; | ||
} | ||
return data; | ||
} | ||
}; | ||
}, | ||
expectError: function() { | ||
expectError: function () { | ||
throw new Error('should not be thrown'); | ||
} | ||
} | ||
}; |
@@ -15,3 +15,3 @@ 'use strict'; | ||
step.prefix = `Within ${locator}: `; | ||
} | ||
}; | ||
@@ -34,3 +34,3 @@ event.dispatcher.on(event.step.after, addContextToStep); | ||
output.stepShift = 1; | ||
event.dispatcher.removeListener(event.step.after, addContextToStep) | ||
event.dispatcher.removeListener(event.step.after, addContextToStep); | ||
}); | ||
@@ -37,0 +37,0 @@ return recorder.promise(); |
{ | ||
"name": "codeceptjs", | ||
"version": "0.4.13", | ||
"version": "0.4.14", | ||
"description": "Modern Era Aceptance Testing Framework for NodeJS", | ||
@@ -48,11 +48,11 @@ "homepage": "http://codecept.io", | ||
"gulp-documentation": "^2.2.0", | ||
"gulp-eslint": "^1.0.0", | ||
"gulp-eslint": "^3.0.0", | ||
"gulp-exclude-gitignore": "^1.0.0", | ||
"gulp-gitmodified": "^1.1.0", | ||
"gulp-if": "^2.0.2", | ||
"gulp-istanbul": "^0.9.0", | ||
"gulp-jscs": "^3.0.2", | ||
"gulp-mocha": "^2.0.0", | ||
"gulp-mustache": "^2.2.0", | ||
"gulp-plumber": "^1.0.0", | ||
"guppy-pre-commit": "^0.3.0", | ||
"guppy-pre-commit": "^0.4.0", | ||
"nightmare": "^2.5.2", | ||
@@ -59,0 +59,0 @@ "nightmare-upload": "^0.1.1", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
220497
6139