diff --git a/docs/helpers/Appium.md b/docs/helpers/Appium.md index ae936c9ae..6b29629c5 100644 --- a/docs/helpers/Appium.md +++ b/docs/helpers/Appium.md @@ -718,6 +718,12 @@ Resumes test execution, so **should be used inside a generator with `yield`** op let pin = yield I.grabTextFrom('#pin'); ``` +## setImmediateValue + +Set immediate value in app. +Appium: support only iOS +TODO: not tested + **Parameters** - `locator` element located by CSS|XPath|strict locator @@ -731,6 +737,13 @@ Resumes test execution, so **should be used inside a generator with `yield`** op let email = yield I.grabValueFrom('input[name=email]'); ``` +- `value` + +## setOrientation + +Set a device orientation. Will fail, if app will not set orientation +Appium: support Android and iOS + **Parameters** - `locator` field located by label|name|CSS|XPath|strict locator diff --git a/docs/helpers/Loki.md b/docs/helpers/Loki.md new file mode 100644 index 000000000..d73f581ae --- /dev/null +++ b/docs/helpers/Loki.md @@ -0,0 +1,110 @@ +# Loki + +Helper with in memory databse for data driven testing and result capturing. + +**Parameters** + +- `config` + +## addCollection + +Will check for an existing collection of the same name and return that, if it already exists. + +**Parameters** + +- `collection` **string** creates a collection with supplied name. + +## clear + +Clears data from a matching collection. + +**Parameters** + +- `collection` **string** name of desired collection. + +## find + +Searches the Users colection for matching values. + +**Parameters** + +- `collection` **string** name of desired collection. +- `query` **Object** used in searching the destination collection for matching values. + +**Examples** + +```javascript +// Searches for a user with an email of "someone@email.com" +I.find("Users",{email: "someone@email.com"}) +``` + +Returns **Array<Object>** Returns an array of objects that match. + +## findAndRemove + +Like `findAndUpdate()` but finds a record in a collection and removes it. + +**Parameters** + +- `collection` **string** name of desired collection. +- `query` **Object** used in searching the destination collection for matching values. + +## findAndUpdate + +Finds a list of values based on the supplied query and runs an update function on each result. + +**Parameters** + +- `collection` **string** name of desired collection. +- `query` **Object** used in searching the destination collection for matching values. +- `updateFunction` **function** executes against each of the results in the result array. + +**Examples** + +```javascript +// Before {email: "someone@email.com", firstname: "Some", surname: "One", address1: "1 Some Place"} +I.findAndUpdate("users",{email: "someone@email.com"},(res)=>{res.number = "01234567890"}) +// Find updated record +I.findOne("Users",{email: "someone@email.com"}) +// After {email: "someone@email.com", firstname: "Some", surname: "One", address1: "1 Some Place", number:01234567890} +``` + +## findCollection + +**Parameters** + +- `collection` **string** name of desired collection. + +## findOne + +Effectively the same as `find()` but returns a single object rather than an array. + +**Parameters** + +- `collection` **string** name of desired collection. +- `query` **Object** used in searching the destination collection for matching values. + +## importData + +Imports data from a directory into a collection. Uses file names to create a collection of the same name and imports the contents of the file as records to the destination. + +**Parameters** + +- `dir` **string** takes a directory as a string. + +## insert + +Inserts records from the supplied data to a matching collection. + +**Parameters** + +- `collection` **string** name of desired collection. +- `data` **Array<Object>** takes an array of objects as records for the destination collection. + +## removeCollection + +Removes a matching collection. + +**Parameters** + +- `collection` **string** finds a collection that matches the supplied name diff --git a/lib/command/init.js b/lib/command/init.js index e0b87c888..982d03365 100644 --- a/lib/command/init.js +++ b/lib/command/init.js @@ -21,7 +21,7 @@ let defaultConfig = { mocha: {} }; -let helpers = ['WebDriverIO', 'Protractor', 'SeleniumWebdriver', 'Nightmare', 'FileSystem', 'REST']; +let helpers = ['WebDriverIO', 'Protractor', 'SeleniumWebdriver', 'Nightmare', 'FileSystem', 'REST', 'Loki']; let translations = Object.keys(require('../../translations')); let noTranslation = 'English (no localization)'; translations.unshift(noTranslation); diff --git a/lib/helper/Loki.js b/lib/helper/Loki.js new file mode 100644 index 000000000..c2b8aff36 --- /dev/null +++ b/lib/helper/Loki.js @@ -0,0 +1,204 @@ +const Helper = require('../helper'); +const fileExists = require('../utils').fileExists; +const fileIncludes = require('../assert/include').fileIncludes; +const fileEquals = require('../assert/equal').fileEquals; + +const requireg = require('requireg'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); +const loki = require('lokijs'); + +/** + * Helper with in memory databse for data driven testing and result capturing. + */ + +class Loki extends Helper { + + constructor(config) { + super(config); + // set defaults + this.options = { + dbName: "db.json", + dbOpts: { + autosave: true, + autosaveInterval: 1000, + }, + dbSeed: true + }; + + // override defaults with config + Object.assign(this.options, config); + } + + static _checkRequirements() { + try { + requireg("lokijs"); + } catch (e) { + return ["lokijs"]; + } + } + + static _config() { + return [{ + name: 'dbName', + message: "What would you like to name the database?", + default: 'db.json' + }, { + name: 'dbSeed', + type: "confirm", + message: 'Would you like to enable databse seeding?', + default: true + }]; + } + + _init() { + //set global directory + this.dir = global.codecept_dir; + this.debugSection('Dir', this.dir); + + //Creates/Initialises the database + this.db = new loki(this.options.dbName, this.options.dbOpts); + //Creates seed data directory if necessary and imports the contents. + this.seedDir = path.join("./seed"); + this.options.dbSeed && mkdirSync(this.seedDir); + this.options.dbSeed && this._loadSeedData(); + } + + _beforeSuite() { + } + + _afterSuite() { + this._stopDb(); + } + + _startDb() { + } + + _stopDb() { + this.db.close(); + } + + _loadSeedData() { + this.importData(this.seedDir); + } + + /** + * + * Will check for an existing collection of the same name and return that, if it already exists. + * @param {string} collection creates a collection with supplied name. + */ + addCollection(collection) { + return !this.findCollection(collection) && this.db.addCollection(collection); + } + /** + * + * @param {string} collection name of desired collection. + */ + findCollection(collection) { + return this.db.getCollection(collection); + } + /** + * + * Removes a matching collection. + * @param {string} collection finds a collection that matches the supplied name + */ + removeCollection(collection) { + return this.db.removeCollection(collection); + } + /** + * + * Inserts records from the supplied data to a matching collection. + * @param {string} collection name of desired collection. + * @param {Object[]} data takes an array of objects as records for the destination collection. + */ + insert(collection, data) { + const c = this.findCollection(collection); + return c.insert(data); + } + /** + * + * Clears data from a matching collection. + * @param {string} collection name of desired collection. + */ + clear(collection) { + const c = this.findCollection(collection); + return c.clear(); + } + /** + * Searches the Users colection for matching values. + * @param {string} collection name of desired collection. + * @param {Object} query used in searching the destination collection for matching values. + * @example + * // Searches for a user with an email of "someone@email.com" + * I.find("Users",{email: "someone@email.com"}) + * @returns {Object[]} Returns an array of objects that match. + */ + find(collection, query) { + const c = this.findCollection(collection); + return c.find(query); + } + /** + * + * Effectively the same as `find()` but returns a single object rather than an array. + * @param {string} collection name of desired collection. + * @param {Object} query used in searching the destination collection for matching values. + */ + findOne(collection, query) { + const c = this.findCollection(collection); + return c.findOne(query); + } + /** + * + * Finds a list of values based on the supplied query and runs an update function on each result. + * @param {string} collection name of desired collection. + * @param {Object} query used in searching the destination collection for matching values. + * @param {function} updateFunction executes against each of the results in the result array. + * @example + * // Before {email: "someone@email.com", firstname: "Some", surname: "One", address1: "1 Some Place"} + * I.findAndUpdate("users",{email: "someone@email.com"},(res)=>{res.number = "01234567890"}) + * // Find updated record + * I.findOne("Users",{email: "someone@email.com"}) + * // After {email: "someone@email.com", firstname: "Some", surname: "One", address1: "1 Some Place", number:01234567890} + */ + findAndUpdate(collection, query, updateFunction) { + const c = this.findCollection(collection); + return c.findAndUpdate(query, updateFunction); + } + /** + * + * Like `findAndUpdate()` but finds a record in a collection and removes it. + * @param {string} collection name of desired collection. + * @param {Object} query used in searching the destination collection for matching values. + */ + findAndRemove(collection, query) { + const c = this.findCollection(collection); + return c.findAndRemove(query); + } + /** + * + * Imports data from a directory into a collection. Uses file names to create a collection of the same name and imports the contents of the file as records to the destination. + * @param {string} dir takes a directory as a string. + */ + importData(dir) { + const files = fs.readdirSync(dir); + files.map(i => { + const fileName = i.substr(0, i.lastIndexOf('.')) || i; + const filePath = path.join(this.dir, dir, i); + const collection = this.db.addCollection(fileName); + return collection.insert(require(filePath)); + }); + } +} + +function mkdirSync(dir) { + try { + fs.mkdirSync(dir); + } catch (e) { + if (e.code !== "EEXIST") { + throw e; + } + } +} + +module.exports = Loki; diff --git a/package.json b/package.json index 81d1f709f..042245735 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "gulp-mustache": "^2.2.0", "gulp-plumber": "^1.0.0", "guppy-pre-commit": "^0.4.0", + "lokijs": "^1.5.0", "nightmare": "^2.5.2", "nightmare-upload": "^0.1.1", "protractor": ">4.0.9 <6.0", @@ -67,7 +68,8 @@ }, "scripts": { "prepublish": "gulp prepublish", - "test": "gulp" + "test": "gulp", + "docs":"gulp docs" }, "license": "MIT" }