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

appium-uiauto

Package Overview
Dependencies
Maintainers
6
Versions
93
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

appium-uiauto - npm Package Compare versions

Comparing version 1.10.8 to 2.0.0-beta

.jscsrc

152

lib/dynamic-bootstrap.js
// Generate a bootstrap for the UIAuto Instruments script containing
// the environment variables we need.
'use strict';
import path from 'path';
import _ from 'lodash';
import crypto from 'crypto';
import _mkdirp from 'mkdirp';
import { fs } from 'appium-support';
import Promise from 'bluebird';
import buildScript from './build-script';
import log from './logger';
var path = require('path'),
_ = require('underscore'),
crypto = require('crypto'),
Q = require('q'),
mkdirp = Q.denodeify(require('mkdirp')),
fs = require('fs'),
buildCollatedScript = require('./resolve-deps.js'),
logger = require('./logger.js');
let mkdirp = Promise.promisify(_mkdirp);
function getEnv(opts) {
opts = opts || {};
var bootstrapEnv = {
const BOOTSTRAP_JS_PATH = '../../uiauto/bootstrap.js';
const COMMAND_PROXY_CLIENT_PATH = './bin/command-proxy-client.js';
const DEFAULT_INSTRUMENTS_SOCKET = '/tmp/instruments_sock';
function getEnv (opts = {}) {
// build an object with the required properties for bootstrap
return {
nodePath: process.execPath,
commandProxyClientPath: path.resolve(
__dirname, '../bin/command-proxy-client.js'),
instrumentsSock: opts.sock || '/tmp/instruments_sock',
__dirname, COMMAND_PROXY_CLIENT_PATH),
instrumentsSock: opts.sock || DEFAULT_INSTRUMENTS_SOCKET,
interKeyDelay: opts.interKeyDelay || null,

@@ -28,16 +33,19 @@ justLoopInfinitely: opts.justLoopInfinitely,

};
return bootstrapEnv;
}
function buildCode(opts) {
async function buildCode (opts) {
// only build the code if it hasn't been done before
if (opts.code) return opts.code;
var env = getEnv(opts);
logger.debug('Dynamic env: ' + JSON.stringify(env));
var bootstrapJs = path.resolve(__dirname, '../uiauto/bootstrap.js');
var imports = opts.imports || {};
imports = imports.pre || [];
var bootstrapCode = buildCollatedScript(bootstrapJs, imports);
let env = getEnv(opts);
log.debug(`Dynamic env: ${JSON.stringify(env)}`);
var lines = [];
let bootstrapJs = path.resolve(__dirname, BOOTSTRAP_JS_PATH);
// if special imports were sent in, make use of them
let imports = (opts.imports && opts.imports.pre) ? opts.imports.pre : [];
let bootstrapCode = await buildScript(bootstrapJs, imports);
// generate the dynamic part of the bootstrap code
// with the environment set up properly
let lines = [];
lines.push('// This file is automatically generated. Do not manually modify!');

@@ -48,8 +56,10 @@ lines.push('');

lines.push('bootstrap({');
_(env).each(function (value, key) {
// add each defined variable to the environment
for (let [key, value] of _.pairs(env)) {
if (!_.isUndefined(value)) {
var quote = typeof value === 'string' ? '\"' : '';
lines.push(' "' + key + '": ' + quote + value + quote + ',');
let quote = _.isString(value) ? '\"' : '';
lines.push(` "${key}": ${quote}${value}${quote},`);
}
});
}
// get rid of the last comma that was added
lines[lines.length - 1] = lines[lines.length - 1].replace(/,$/, '');

@@ -60,13 +70,13 @@ lines.push('});');

function computeHash(code) {
return crypto.createHash('md5').update(code)
.digest('hex').substring(0, 16);
function computeHash (code) {
return crypto
.createHash('md5')
.update(code)
.digest('hex')
.substring(0, 16);
}
var prepareBootstrap = function (opts) {
logger.debug('Preparing uiauto bootstrap');
opts = opts || {};
function getDynamicBootstrapDir (opts = {}) {
// figuring out where to store dynamic bootstrap
var dynamicBootstrapDir;
let dynamicBootstrapDir;
if (process.env.APPIUM_BOOTSTRAP_DIR) {

@@ -82,34 +92,46 @@ // mainly for test

}
logger.debug('Dynamic bootstrap dir: ' + dynamicBootstrapDir);
return dynamicBootstrapDir;
}
async function writeDynamicBootstrapIfNecessary (dynamicBootstrapDir, dynamicBootstrapPath, code, hash) {
await mkdirp(dynamicBootstrapDir);
// check if there is existing code and it has the same hash
let codeIsGood = true;
try {
let existingCode = await fs.readFile(dynamicBootstrapPath);
codeIsGood = computeHash(existingCode) === hash;
} catch (err) {
codeIsGood = false;
}
// write file if the old code is not the same
if (codeIsGood) {
log.debug(`Reusing dynamic bootstrap: ${dynamicBootstrapPath}`);
} else {
log.debug(`Creating or overwriting dynamic bootstrap: ${dynamicBootstrapPath}`);
await fs.writeFile(dynamicBootstrapPath, code, {flag: 'w+'});
}
}
async function prepareBootstrap (opts = {}) {
log.debug('Preparing bootstrap code');
let dynamicBootstrapDir = getDynamicBootstrapDir(opts);
log.debug(`Dynamic bootstrap dir: ${dynamicBootstrapDir}`);
// building code and hash
var code = buildCode(opts);
var hash = computeHash(code);
var dynamicBootstrapPath = path.resolve(dynamicBootstrapDir,
'bootstrap-' + hash + '.js');
logger.debug('Dynamic bootstrap code: ' + code.split("\n")[0] + '...');
logger.debug('Dynamic bootstrap path: ' + dynamicBootstrapPath);
let code = await buildCode(opts);
let hash = computeHash(code);
let dynamicBootstrapPath = path.resolve(dynamicBootstrapDir,
`bootstrap-${hash}.js`);
log.debug(`Dynamic bootstrap code: ${code.split('\n')[0]}...`);
log.debug(`Dynamic bootstrap path: ${dynamicBootstrapPath}`);
return mkdirp(dynamicBootstrapDir)
.then(function () {
// check existing code
var codeIsGood = true;
try {
var existingCode = fs.readFileSync(dynamicBootstrapPath);
codeIsGood = computeHash(existingCode) === hash;
} catch (err) {
codeIsGood = false;
}
// write file if necessary
if (codeIsGood) {
logger.debug('Reusing dynamic bootstrap: ' + dynamicBootstrapPath);
} else {
logger.debug('Creating or overwritting dynamic bootstrap: ' +
dynamicBootstrapPath);
fs.writeFileSync(dynamicBootstrapPath, code, { flag: 'w+'});
}
return dynamicBootstrapPath;
});
};
exports.prepareBootstrap = prepareBootstrap;
exports.getEnv = getEnv;
await writeDynamicBootstrapIfNecessary(dynamicBootstrapDir,
dynamicBootstrapPath, code, hash);
return dynamicBootstrapPath;
}
export { prepareBootstrap, getEnv };

@@ -1,33 +0,5 @@

'use strict';
import { getLogger } from 'appium-logger';
var winston = require('winston'),
_ = require('underscore');
const log = getLogger('UIAuto');
var logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)({ level : 'info' })
]
});
var loggerWrap = {
init: function (_logger) {
logger = _logger;
},
};
_(['info','debug','warn','error']).each(function (level) {
loggerWrap[level] = function () {
var args = Array.prototype.slice.call(arguments, 0);
logger[level].apply(logger, args);
};
});
loggerWrap.setConsoleLevel = function (level) {
logger.transports.console.level = level;
};
loggerWrap.instance = function () {
return logger;
};
module.exports = loggerWrap;
export default log;
{
"name": "appium-uiauto",
"version": "1.10.8",
"description": "appium uiauto ios driver",
"main": "lib/main.js",
"bin": {},
"scripts": {
"test": "make && make test_uiauto"
},
"repository": {
"type": "git",
"url": "https://github.com/appium/appium-uiauto.git"
},
"author": "",
"description": "Appium iOS UI Automation driver",
"keywords": [
"appium",
"ios"
],
"version": "2.0.0-beta",
"author": "appium",
"licenses": [

@@ -21,25 +16,44 @@ {

],
"repository": {
"type": "git",
"url": "https://github.com/appium/appium-uiauto.git"
},
"bugs": {
"url": "https://github.com/appium/appium-uiauto/issues"
},
"homepage": "https://github.com/appium/appium-uiauto",
"engines": [
"node"
],
"main": "./build/index.js",
"bin": {},
"directories": {
"lib": "lib"
},
"dependencies": {
"argparse": "~0.1.15",
"mkdirp": "~0.5.0",
"q": "~1.1.2",
"winston": "~0.8.3"
"appium-instruments": "^2.0.4",
"appium-logger": "^1.1.7",
"appium-support": "2.0.0-beta13",
"babel-runtime": "=5.5.5",
"bluebird": "^2.9.32",
"lodash": "^3.10.0",
"mkdirp": "^0.5.1",
"source-map-support": "^0.3.1",
"through": "^2.3.8"
},
"scripts": {
"prepublish": "./node_modules/.bin/gulp prepublish",
"test": "./node_modules/.bin/gulp once",
"watch": "./node_modules/.bin/gulp"
},
"devDependencies": {
"appium-instruments": "1.5.3",
"underscore": "~1.7.0",
"chai": "~1.10.0",
"sinon-chai": "~2.6.0",
"chai-as-promised": "~4.1.1",
"jscs": "~1.8.1",
"jshint": "~2.5.1",
"mocha": "~2.1.0",
"rimraf": "~2.2.8",
"sinon": "~1.12.2",
"through": "~2.3.4"
"appium-gulp-plugins": "^1.2.12",
"appium-xcode": "^2.0.5",
"chai": "^3.0.0",
"chai-as-promised": "^5.1.0",
"gulp": "^3.8.11",
"mochawait": "^2.0.0",
"q": "^1.4.1",
"sinon": "^1.15.4",
"sinon-chai": "^2.8.0"
}
}

@@ -1,14 +0,40 @@

appium-uiauto
=============
# Appium-UIAuto rewrite
ui-auto driver use by Appium for Ios.
`uiauto` portion will remain as is, since it is run on the device, not in our ES6+ environment. What remains consists of three major parts:
## Publishing
1. Command Proxy:
- acts as the bridge between `Appium` and the iOS UI Automation framework
- will require significant async rewriting
- two ends of the equation
- `lib/uiauto-client.js` - should export `UIAutoClient`
- `uiauto/lib/commands.js` - server. should be named more appropriately
```
npm version [patch|minor|major]
# make sure everything is commited
git push origin master
git push --tags
npm publish
```
2. Dynamic Bootstrap:
- creates the bootstrap environment to be pushed onto the device
- currently synchronous, but uses synchronized fs functions, and returns a Promise, so modify to async so we handle things in the same way
3. Dependency Resolver:
- collates a dependency tree for the bootstrap app
- needs to be renamed according to its functionality - `createScript` or somesuch
- currently synchronous, but uses synchronized fs functions, so rewrite to async
- the logic can remain the same since the code parsed is old-style
And, of course... tests.
This rewrite will pull in most of the iOS behavioural tests from Appium. This seems a good time to revisit our tests both in terms of organization and coverage.
Dependencies for moving tests out of Appium:
1. Requires a way to start/stop simulator and load app (appium-ios-simulator?).
2. Requires a way to start instruments with the bootstrap code (appium-instruments?).
3. Rethink our test organization
- move from app-based organization to functionality-based. Find, action, etc. While it seems unlikely that we will have a new test app to test against by the time this happens, idealy at some point everything would be tested against a single app, and some of the initial complexity (e.g., having one test run against one app, and another test run against another) would go away.
- This would be a good time to keep track of the desiderata for a new test app. What tests do we have that have no assertions because there is nothing appropriate to check for? What tests require going through a long setup to get to the place where the feature can be tested? Where is there unnecessary complexity that makes false negatives likely?
- We currently have some cases where we test the same feature multiple times, and other features not at all. Reorganizing will allow us to merge tests, and make the holes more obvious.

@@ -0,8 +1,10 @@

// transpile:mocha
/* globals $, rootPage, alerts */
'use strict';
var base = require('./base');
import { instrumentsInstanceInit, globalInit, killAll } from './base';
describe('alarm', function () {
var imports = { post: [
instrumentsInstanceInit;
describe('alarm', async function () {
let imports = { post: [
'uiauto/lib/alerts.js',

@@ -17,11 +19,12 @@ 'uiauto/lib/status.js',

]};
base.globalInit(this, { imports: imports, bootstrap: 'basic'});
before(async () => {
await globalInit(this, { imports: imports, bootstrap: 'basic'});
});
describe("textfields", function () {
var ctx;
base.instrumentsInstanceInit()
.then(function (_ctx) { ctx = _ctx; }).done();
describe('textfields', async function () {
let ctx;
before(function () {
return ctx.execFunc(
before(async () => {
ctx = await instrumentsInstanceInit();
await ctx.execFunc(
function () {

@@ -33,4 +36,4 @@ alerts.configure();

afterEach(function () {
return ctx.execFunc(
afterEach(async () => {
await ctx.execFunc(
function () {

@@ -41,6 +44,7 @@ $('#UICatalog').first().tap();

);
await killAll(ctx);
});
it('should retrieve alert text and then accept alert', function () {
return ctx.execFunc(
it('should retrieve alert text and then accept alert', async () => {
let res = await ctx.execFunc(
function () {

@@ -55,8 +59,6 @@ rootPage.clickMenuItem('Alert Views');

}
).then(function (res) {
console.warn('res -->', res);
res.should.include('A Short Title Is Best');
});
);
res.should.include('A Short Title Is Best');
});
});
});

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

'use strict';
// 'use strict';
var chai = require('chai'),
chaiAsPromised = require("chai-as-promised"),
Q = require('q'),
CommandProxy = require('../../lib/command-proxy'),
instrumentsUtils = require('appium-instruments').utils,
getEnv = require('../../lib/dynamic-bootstrap').getEnv,
_ = require('underscore'),
path = require('path'),
fs = require('fs'),
logger = require('../../lib/logger');
import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import Promise from 'bluebird';
import { UIAutoClient, prepareBootstrap } from '../..';
import Instruments from 'appium-instruments';
import { getEnv } from '../../lib/dynamic-bootstrap';
import _ from 'lodash';
import path from 'path';
import { fs } from 'appium-support';
import logger from '../../lib/logger';

@@ -18,2 +18,3 @@ chai.use(chaiAsPromised);

process.env.APPIUM_BOOTSTRAP_DIR = '/tmp/appium-uiauto/test/functional/bootstrap';

@@ -23,17 +24,17 @@

var prepareBootstrap = function (opts) {
async function localPrepareBootstrap (opts) {
opts = opts || {};
var rootDir = path.resolve(__dirname, '../..');
let rootDir = path.resolve(__dirname, '../../..');
if (opts.bootstrap === 'basic') {
var env = getEnv();
var postImports = [];
let env = getEnv();
let postImports = [];
if (opts.imports && opts.imports.post) {
postImports = opts.imports.post;
}
postImports = _(postImports).map(function (item) {
return '#import "' + path.resolve( rootDir , item) + '"';
postImports = postImports.map(function (item) {
return '#import "' + path.resolve(rootDir , item) + '"';
});
var code = fs.readFileSync(path.resolve(
__dirname, '../../test/assets/base-bootstrap.js'), 'utf8');
_({
let code = await fs.readFile(path.resolve(
__dirname, '../../../test/assets/base-bootstrap.js'), 'utf8');
let vars = {
'<ROOT_DIR>': rootDir,

@@ -44,6 +45,7 @@ '"<POST_IMPORTS>"': postImports.join('\n'),

'<instrumentsSock>': env.instrumentsSock
}).each(function (value, key) {
};
for (let [key, value] of _.pairs(vars)) {
code = code.replace(new RegExp(key, 'g'), value);
});
return require('../../lib/dynamic-bootstrap').prepareBootstrap({
}
return prepareBootstrap({
code: code,

@@ -60,141 +62,101 @@ isVerbose: true

delete opts.chai;
return require('../../lib/dynamic-bootstrap')
.prepareBootstrap(opts);
return prepareBootstrap(opts);
}
};
}
var newInstruments = function (bootstrapFile) {
return instrumentsUtils.quickInstrument({
app: path.resolve(__dirname, '../assets/UICatalog.app'),
async function newInstruments (bootstrapFile) {
return Instruments.utils.quickInstrument({
app: path.resolve(__dirname, '../../../test/assets/UICatalog.app'),
bootstrap: bootstrapFile,
logger: logger.instance(),
simulatorSdkAndDevice: 'iPhone 6 (8.1 Simulator)',
launchTries: 2
});
};
}
var init = function (bootstrapFile, opts) {
var deferred = Q.defer();
var proxy = new CommandProxy(opts);
var instruments;
proxy.start(
// first connection
function (err) {
instruments.launchHandler(err);
if (err) return deferred.reject(err);
deferred.resolve({proxy: proxy, instruments: instruments});
},
// regular cb
function (err) {
if (err) return deferred.reject(err);
newInstruments(bootstrapFile).then(function (_instruments) {
instruments = _instruments;
instruments.start(null, function () {
proxy.safeShutdown(function () {});
});
})
.catch(function (err) { deferred.reject(err); })
.done();
}
);
return deferred.promise;
};
async function init (bootstrapFile, sock) {
let proxy = new UIAutoClient(sock);
let instruments = await newInstruments(bootstrapFile);
instruments.start(null, async () => {
await proxy.safeShutdown();
throw new Error('Unexpected shutdown of instruments');
});
var killAll = function (ctx) {
return Q.nfcall(ctx.instruments.shutdown.bind(ctx.instruments))
.then(function () {
return instrumentsUtils.killAllInstruments();
}).catch(function () {})
.then(function () {
return ctx.proxy.safeShutdown(function () {});
});
};
try {
await proxy.start();
instruments.launchHandler();
} catch (err) {
// need to make sure instruments handles business
instruments.launchHandler(err);
throw err;
}
return {proxy, instruments};
}
async function killAll (ctx) {
let asyncShutdown = Promise.promisify(ctx.instruments.shutdown, ctx.instruments);
try {
await asyncShutdown();
} catch (e) {
// pass
console.log(e);
}
await Instruments.utils.killAllInstruments();
await ctx.proxy.safeShutdown();
}
var bootstrapFile;
exports.globalInit = function (ctx, opts) {
ctx.timeout(180000);
async function globalInit (ctx, opts) {
ctx.timeout(20000);
before(function () {
return prepareBootstrap(opts).then(function (_bootstrapFile) {
bootstrapFile = _bootstrapFile;
});
});
};
bootstrapFile = await localPrepareBootstrap(opts);
}
exports.instrumentsInstanceInit = function (opts) {
var deferred = Q.defer();
async function instrumentsInstanceInit (opts = {}) {
let ctx = await init(bootstrapFile, opts.sock);
ctx.sendCommand = async (cmd) => {
return ctx.proxy.sendCommand(cmd);
};
ctx.exec = ctx.sendCommand;
var ctx;
before(function () {
return init(bootstrapFile, opts)
.then(function (_ctx) {
ctx = _ctx;
ctx.sendCommand = function (cmd) {
var deferred = Q.defer();
ctx.proxy.sendCommand(cmd, function (result) {
if (result.status === 0) {
deferred.resolve(result.value);
} else {
deferred.reject(JSON.stringify(result));
}
});
return deferred.promise;
};
ctx.execFunc = async (func, params) => {
params = params || [];
let script =
'(function (){' +
' var params = JSON.parse(\'' + JSON.stringify(params) + '\');\n' +
' return (' + func.toString() + ').apply(null, params);' +
'})();';
return ctx.exec(script);
};
ctx.exec = ctx.sendCommand;
let cmd = '$.isVerbose = ' + (process.env.VERBOSE ? true : false) + ';\n';
await ctx.exec(cmd);
ctx.execFunc = function (func, params) {
params = params || [];
var script =
'(function (){' +
' var params = JSON.parse(\'' + JSON.stringify(params) + '\');\n' +
' return (' + func.toString() + ').apply(null, params);' +
'})();';
return ctx.exec(script);
};
}).then(function () {
var cmd = '';
cmd += '$.isVerbose = ' + (process.env.VERBOSE ? true : false) + ';\n';
return ctx.exec(cmd);
})
.then(function () {
// some uiauto helpers
return ctx.execFunc(function () {
/* global rootPage:true */
rootPage = {};
// click item in root page menu
rootPage.clickMenuItem = function (partialText) {
$.each($('tableview').children(), function (idx, child) {
if (child.name().indexOf(partialText) >= 0 ){
$(child).tap();
return false;
}
});
};
});
}).then(function () {
return ctx.execFunc(function () {
/* global $ */
$.delay(500);
while (!$('tableview').isVisible()) {
$.warn('waiting for page to load');
$.delay(500);
}
}).then(
function () {
deferred.resolve(ctx);
},
function (err) {
deferred.reject(err);
}
);
// some uiauto helpers
await ctx.execFunc(function () {
/* global rootPage:true */
rootPage = {};
// click item in root page menu
rootPage.clickMenuItem = function (partialText) {
$.each($('tableview').children(), function (idx, child) {
if (child.name().indexOf(partialText) >= 0 ){
$(child).tap();
return false;
}
});
};
});
after(function () {
return killAll(ctx);
await ctx.execFunc(function () {
/* global $ */
$.delay(500);
while (!$('tableview').isVisible()) {
$.warn('waiting for page to load');
$.delay(500);
}
});
return deferred.promise;
};
return ctx;
}
export { instrumentsInstanceInit, globalInit, killAll };

@@ -1,32 +0,39 @@

'use strict';
// transpile:mocha
var base = require('./base');
import { instrumentsInstanceInit, globalInit, killAll } from './base';
describe('bootstrap', function () {
describe('basic test bootstrap', function () {
let ctx;
before(async function () {
await globalInit(this, {bootstrap: 'basic'});
ctx = await instrumentsInstanceInit();
});
after(async () => {
await killAll(ctx);
});
describe("basic test bootstrap", function () {
base.globalInit(this, {bootstrap: 'basic'});
var ctx;
base.instrumentsInstanceInit().then(function (_ctx) { ctx = _ctx; });
it('should start and execute one command', function () {
return ctx.sendCommand("'123'")
.should.become('123')
.then(function () { return ctx.sendCommand("typeof $.lookup"); })
.should.become('undefined')
.then(function () { return ctx.sendCommand("typeof chai"); })
.should.become('object');
it('should start and execute one command', async () => {
(await ctx.sendCommand("'123'")).should.equal('123');
(await ctx.sendCommand('typeof $.lookup')).should.equal('undefined');
(await ctx.sendCommand('typeof chai')).should.equal('object');
});
});
describe("regular bootstrap without chai", function () {
base.globalInit(this);
var ctx;
base.instrumentsInstanceInit().then(function (_ctx) { ctx = _ctx; });
describe('regular bootstrap without chai', function () {
let ctx;
before(async function () {
await globalInit(this);
ctx = await instrumentsInstanceInit();
});
after(async () => {
if (ctx) {
await killAll(ctx);
}
});
it('should start and execute one command', function () {
return ctx.sendCommand("'123'")
.should.become('123')
.then(function () { return ctx.sendCommand("typeof chai"); })
.should.become('undefined');
it('should start and execute one command', async () => {
(await ctx.sendCommand("'123'")).should.equal('123');
(await ctx.sendCommand('typeof chai')).should.equal('undefined');
});

@@ -36,11 +43,15 @@ });

describe("regular bootstrap with chai", function () {
base.globalInit(this, {chai: true});
var ctx;
base.instrumentsInstanceInit().then(function (_ctx) { ctx = _ctx; });
let ctx;
before(async function () {
await globalInit(this, {bootstrap: 'basic'});
ctx = await instrumentsInstanceInit();
});
after(async () => {
await killAll(ctx
);
});
it('should start and execute one command', function () {
return ctx.sendCommand("'123'")
.should.become('123')
.then(function () { return ctx.sendCommand("typeof chai"); })
.should.become('object');
it('should start and execute one command', async () => {
(await ctx.sendCommand("'123'")).should.equal('123');
(await ctx.sendCommand('typeof chai')).should.equal('object');
});

@@ -47,0 +58,0 @@ });

@@ -0,42 +1,55 @@

// transpile:mocha
/* globals $ */
'use strict';
var base = require('./base'),
_ = require('underscore'),
Q = require('q');
import { instrumentsInstanceInit, globalInit, killAll } from './base';
import { getVersion } from 'appium-xcode';
import _ from 'lodash';
import Promise from 'bluebird';
describe('commands', function () {
base.globalInit(this, {bootstrap: 'basic'});
let numCommands = 100;
before(async () => {
await globalInit(this, {bootstrap: 'basic'});
describe("simple sequences", function () {
var ctx;
base.instrumentsInstanceInit().then(function (_ctx) { ctx = _ctx; });
// xcode 7 is a bit slow.
let xcodeVersion = await getVersion();
if (xcodeVersion[0] >= 7) {
numCommands = 50;
}
});
it('should send one valid command returning a value', function () {
return ctx.sendCommand("'123'")
.should.become('123');
describe('simple sequences', function () {
let ctx;
before(async () => {
ctx = await instrumentsInstanceInit();
});
after(async () => {
await killAll(ctx);
});
it('should send one valid command returning empty value', function () {
return ctx.sendCommand("$.warn('starting')")
.should.become('');
it('should send one valid command returning a value', async () => {
(await ctx.sendCommand("'123'")).should.equal('123');
});
it('should respond to invalid command and not die', function () {
return ctx.sendCommand("i_am_invalid()")
.should.be.rejectedWith(/"status":17/)
.then(function () {
return ctx.sendCommand("$.warn('still alive')");
});
it('should send one valid command returning empty value', async () => {
(await ctx.sendCommand("$.warn('starting')")).should.equal('');
});
it('should repond to 10 commands in a row', function () {
var seq = [];
_(10).times(function (i) {
seq.push(function () {
return ctx.sendCommand('(function () { return ' + i + '})()')
.should.become(i);
it('should respond to invalid command and not die', async () => {
await ctx.sendCommand('i_am_invalid()').should.be.rejectedWith(/Can't find variable: i_am_invalid/);
await ctx.sendCommand("$.warn('still alive')");
});
it('should repond to 10 commands in a row', async () => {
let seq = [];
_.times(10, function (i) {
seq.push(async () => {
(await ctx.sendCommand(`(function () { return ${i}})()`)).should.equal(i);
});
});
return seq.reduce(Q.when, new Q());
await Promise.reduce(seq, async (res, task) => {
await res;
return task();
}, null);
});

@@ -46,47 +59,54 @@

describe("sending 100 valid commands", function () {
var ctx;
base.instrumentsInstanceInit().then(function (_ctx) { ctx = _ctx; });
describe(`sending ${numCommands} valid commands`, () => {
let ctx;
before(async () => {
ctx = await instrumentsInstanceInit();
});
after(async () => {
await killAll(ctx);
});
it('should work', function () {
var seq = [];
_(100).times(function (i) {
seq.push(function () {
return ctx.sendCommand('(function () { return "' + i + '"})()')
.should.become("" + i)
.then(function () {
if ((i+1)%10 === 0) console.log('sent:', (i+1));
});
it('should work', async () => {
let seq = [];
_.times(numCommands, (i) => {
seq.push(async () => {
(await ctx.sendCommand(`(function () { return "${i}"})()`)).should.equal(i.toString());
// if ((i+1)%10 === 0) console.log('sent:', (i+1));
});
});
return seq.reduce(Q.when, new Q());
await Promise.reduce(seq, async (res, task) => {
await res;
return task();
}, null);
});
});
describe("sending 100 alternating valid and invalid", function () {
var ctx;
base.instrumentsInstanceInit().then(function (_ctx) { ctx = _ctx; });
describe(`sending ${numCommands} alternating valid and invalid`, () => {
let ctx;
before(async () => {
ctx = await instrumentsInstanceInit();
});
after(async () => {
await killAll(ctx);
});
it('should work', function () {
var seq = [];
_(100).times(function (i) {
it('should work', async () => {
let seq = [];
_.times(numCommands, (i) => {
if (i%2 === 0)
seq.push(function () {
return ctx.sendCommand('(function () { return "' + i + '"})()')
.should.become("" + i)
.then(function () {
if ((i+1)%10 === 0) console.log('sent:', (i+1));
});
seq.push(async () => {
(await ctx.sendCommand(`(function () { return "${i}"})()`)).should.equal(i.toString());
// if ((i+1)%10 === 0) console.log('sent:', (i+1));
});
else
seq.push(function () {
return ctx.sendCommand('(ffffunction () { return "' + i + '"})()')
.should.be.rejectedWith(/"status":17/)
.then(function () {
if ((i+1)%10 === 0) console.log('sent:', (i+1));
});
seq.push(async () => {
await ctx.sendCommand('(ffffunction () { return "' + i + '"})()')
.should.be.rejectedWith(/Unexpected token/);
// if ((i+1)%10 === 0) console.log('sent:', (i+1));
});
});
return seq.reduce(Q.when, new Q());
await Promise.reduce(seq, async (res, task) => {
await res;
return task();
}, null);
});

@@ -96,8 +116,13 @@

describe("command with big result", function () {
var ctx;
base.instrumentsInstanceInit().then(function (_ctx) { ctx = _ctx; });
describe('command with big result', () => {
let ctx;
before(async () => {
ctx = await instrumentsInstanceInit();
});
after(async () => {
await killAll(ctx);
});
// UIAuto code
var configureUIAuto = function () {
let configureUIAuto = () => {
$.extend($, {

@@ -120,3 +145,2 @@ oneMamaLongString: function (n, mapping) {

oneMamaHugeTree: function (n, d) {
//var root = {name: 'root'};
function addChildren(root, depth) {

@@ -139,17 +163,15 @@ if (depth === d) return;

before(function () {
return ctx.execFunc(configureUIAuto);
before(async () => {
await ctx.execFunc(configureUIAuto);
});
var testN = function (n) {
return ctx.sendCommand('$.oneMamaLongString(' + n + ')')
.then(function (s) {
s.should.have.length(n);
_(n).times(function (i) {
parseInt(s[i] , 10).should.equal(i%10);
});
});
let testN = async (n) => {
let s = await ctx.sendCommand(`$.oneMamaLongString(${n})`);
s.should.have.length(n);
_.times(n, function (i) {
parseInt(s[i] , 10).should.equal(i%10);
});
};
it('should work a small string', function () {
it('should work a small string', () => {
return testN(1000);

@@ -166,14 +188,12 @@ });

var testNWithSpaces = function (n) {
return ctx.sendCommand("$.oneMamaLongString(" + n + ",[0,1,2,3,4,' ',6,7,8,9])")
.then(function (s) {
s.should.have.length(n);
_(n).times(function (i) {
if (i%10 === 5){
s[i].should.equal(' ');
} else {
parseInt(s[i] , 10).should.equal(i%10);
}
});
});
let testNWithSpaces = async (n) => {
let s = await ctx.sendCommand(`$.oneMamaLongString(${n}, [0,1,2,3,4,' ',6,7,8,9])`);
s.should.have.length(n);
_.times(n, function (i) {
if (i%10 === 5){
s[i].should.equal(' ');
} else {
parseInt(s[i] , 10).should.equal(i%10);
}
});
};

@@ -185,17 +205,20 @@

var getHugeTree = function (n,d) {
return ctx.sendCommand('$.oneMamaHugeTree(' + n + ', ' + d + ')');
let getHugeTree = async (n, d) => {
return ctx.sendCommand(`$.oneMamaHugeTree(${n}, ${d})`);
};
it('should work with a medium tree', function () {
return getHugeTree(5,3);
it('should work with a medium tree', async () => {
let res = await getHugeTree(5, 3);
res.name.should.equal('root');
res.children.c1.children.c2.children
.c3.name.should.equal('child 3');
JSON.stringify(res).length.should.be.above(4000);
});
it('should work with a huge tree', function () {
return getHugeTree(5,7).then(function (res) {
res.name.should.equal('root');
res.children.c1.children.c2.children
.c3.children.c2.name.should.equal('child 2');
JSON.stringify(res).length.should.be.above(2000000);
});
it('should work with a huge tree', async () => {
let res = await getHugeTree(5, 7);
res.name.should.equal('root');
res.children.c1.children.c2.children
.c3.children.c2.name.should.equal('child 2');
JSON.stringify(res).length.should.be.above(2000000);
});

@@ -202,0 +225,0 @@ });

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

'use strict';
// transpile:mocha
var base = require('./base'),
path = require('path'),
rimraf = require('rimraf');
import { instrumentsInstanceInit, globalInit, killAll } from './base';
import path from'path';
import { rimraf } from 'appium-support';
describe('config', function () {
describe("custom sock", function () {
var altSockDir = '/tmp/abcd';
var altSock = path.resolve(altSockDir, 'sock');
describe('custom socket', () => {
let altSockDir = '/tmp/abcd';
let altSock = path.resolve(altSockDir, 'sock');
before(function () {
rimraf.sync('/tmp/abcd');
let ctx;
before(async function () {
await rimraf(altSockDir);
await globalInit(this, { chai: true, sock: altSock });
ctx = await instrumentsInstanceInit({ sock: altSock });
});
after(async () => {
await killAll(ctx);
});
base.globalInit(this, { chai: true, sock: altSock });
var ctx;
base.instrumentsInstanceInit({ sock: altSock })
.then(function (_ctx) { ctx = _ctx; }).done();
it('should use the alternate sock', function () {
ctx.proxy.should.exist;
ctx.proxy.getSock().should.equal(altSock);
ctx.proxy.sock.should.equal(altSock);
});
it('should work', function () {
return ctx.execFunc(
it('should work', async () => {
let res = await ctx.execFunc(
function () {
return "OK Boss";
return 'OK Boss';
}
).then(function (res) {
res.should.equal("OK Boss");
});
);
res.should.equal('OK Boss');
});

@@ -36,0 +36,0 @@

@@ -0,16 +1,22 @@

// transpile:mocha
/* globals $, rootPage */
'use strict';
var base = require('./base');
import { instrumentsInstanceInit, globalInit, killAll } from './base';
describe('find', function () {
base.globalInit(this, { chai: true });
describe('find', async () => {
before(async function () {
await globalInit(this, { chai: true });
});
describe("textfields", function () {
var ctx;
base.instrumentsInstanceInit()
.then(function (_ctx) { ctx = _ctx; }).done();
describe("textfields", async function () {
let ctx;
before(async () => {
ctx = await instrumentsInstanceInit();
});
after(async () => {
await killAll(ctx);
});
afterEach(function () {
return ctx.execFunc(
afterEach(async () => {
await ctx.execFunc(
function () {

@@ -23,4 +29,4 @@ $('#UICatalog').first().tap();

it('should not return duplicate UIATextField', function () {
return ctx.execFunc(
it('should not return duplicate UIATextField', async () => {
let res = await ctx.execFunc(
function () {

@@ -34,10 +40,8 @@ rootPage.clickMenuItem('Text Fields');

}
).then(function (res) {
console.warn('res -->', res);
res.should.have.length(1);
});
);
res.should.have.length(1);
});
it('should not return duplicate UIASecureTextField', function () {
return ctx.execFunc(
it('should not return duplicate UIASecureTextField', async () => {
let res = await ctx.execFunc(
function () {

@@ -51,5 +55,4 @@ rootPage.clickMenuItem('Text Fields');

}
).then(function (res) {
res.should.have.length(1);
});
);
res.should.have.length(1);
});

@@ -59,9 +62,13 @@

describe("byUIAutomation", function () {
var ctx;
base.instrumentsInstanceInit()
.then(function (_ctx) { ctx = _ctx; }).done();
describe('byUIAutomation', () => {
let ctx;
before(async () => {
ctx = await instrumentsInstanceInit();
});
after(async () => {
await killAll(ctx);
});
afterEach(function () {
return ctx.execFunc(
afterEach(async () => {
await ctx.execFunc(
function () {

@@ -74,4 +81,4 @@ $('#UICatalog').first().tap();

it('should use global context by default', function () {
return ctx.execFunc(
it('should use global context by default', async () => {
let res = await ctx.execFunc(
function () {

@@ -83,10 +90,9 @@ rootPage.clickMenuItem('Text Fields');

}
).then(function (res) {
res.should.have.length(5);
res[0].ELEMENT.should.exist;
});
);
res.should.have.length(5);
res[0].ELEMENT.should.exist;
});
it('should eval the raw code if it doesn\'t start with a dot', function () {
return ctx.execFunc(
it('should eval the raw code if it does not start with a dot', async () => {
let res = await ctx.execFunc(
function () {

@@ -98,10 +104,9 @@ rootPage.clickMenuItem('Text Fields');

}
).then(function (res) {
res.should.have.length(1);
res[0].ELEMENT.should.exist;
});
);
res.should.have.length(1);
res[0].ELEMENT.should.exist;
});
it('should retrieve context from cache when ctx param is a string', function () {
return ctx.execFunc(
it('should retrieve context from cache when ctx param is a string', async () => {
let res = await ctx.execFunc(
function () {

@@ -118,10 +123,9 @@ rootPage.clickMenuItem('Text Fields');

}
).then(function (res) {
res.should.have.length(1);
res[0].ELEMENT.should.exist;
});
);
res.should.have.length(1);
res[0].ELEMENT.should.exist;
});
it('should use context when ctx param is an object', function () {
return ctx.execFunc(
it('should use context when ctx param is an object', async () => {
let res = await ctx.execFunc(
function () {

@@ -137,10 +141,9 @@ rootPage.clickMenuItem('Text Fields');

}
).then(function (res) {
res.should.have.length(1);
res[0].ELEMENT.should.exist;
});
);
res.should.have.length(1);
res[0].ELEMENT.should.exist;
});
it('should work when retrieving only one element', function () {
return ctx.execFunc(
it('should work when retrieving only one element', async () => {
let res = await ctx.execFunc(
function () {

@@ -175,6 +178,5 @@ rootPage.clickMenuItem('Text Fields');

}
).then(function (res) {
res.should.have.length(4);
res[0].ELEMENT.should.exist;
});
);
res.should.have.length(4);
res[0].ELEMENT.should.exist;
});

@@ -181,0 +183,0 @@

@@ -0,30 +1,47 @@

// transpile:mocha
/* globals $ */
'use strict';
var base = require('./base');
describe('grace period', function () {
var imports = { post: [
import { instrumentsInstanceInit, globalInit, killAll } from './base';
import { getVersion } from 'appium-xcode';
describe('grace period', async () => {
let imports = { post: [
'uiauto/lib/mechanic-ext/gesture-ext.js',
'uiauto/lib/mechanic-ext/keyboard-ext.js',
]};
base.globalInit(this, { imports: imports, bootstrap: 'basic'});
before(async function () {
await globalInit(this, { imports: imports, bootstrap: 'basic'});
});
describe("looking for unexistant object", function () {
var ctx;
base.instrumentsInstanceInit()
.then(function (_ctx) { ctx = _ctx; }).done();
describe('looking for non-existant object', async function () {
let expectedTime = 2000;
let ctx;
before(async () => {
ctx = await instrumentsInstanceInit();
it('should be quick when grace period is not set', function () {
var refMs = Date.now();
return ctx.execFunc(
// xcode 7 is a bit slow.
let xcodeVersion = await getVersion();
if (xcodeVersion[0] >= 7) {
expectedTime = 4000;
}
});
after(async () => {
await killAll(ctx);
});
it('should be quick when grace period is not set', async () => {
let refMs = Date.now();
let res = await ctx.execFunc(
function () {
return $('#not exist');
}
).should.eventually.have.length(0)
.then(function () { (Date.now() - refMs).should.be.below(1000); });
);
(Date.now() - refMs).should.be.below(expectedTime);
res.should.have.length(0);
});
it('should be quick when pushing and poping 0 timeout', function () {
var refMs = Date.now();
return ctx.execFunc(
it('should be quick when pushing and popping 0 timeout', async () => {
let refMs = Date.now();
let res = await ctx.execFunc(
function () {

@@ -36,10 +53,11 @@ $.target().pushTimeout(0);

}
).should.eventually.have.length(0)
.then(function () { (Date.now() - refMs).should.be.below(1000); });
);
res.should.have.length(0);
(Date.now() - refMs).should.be.below(expectedTime);
});
// Skipping because of bug, it takes more than 25 second!
it.skip('should be quick when grace period is set to 1', function () {
var refMs = Date.now();
return ctx.execFunc(
it.skip('should be quick when grace period is set to 1', async () => {
let refMs = Date.now();
let res = await ctx.execFunc(
function () {

@@ -52,10 +70,7 @@ $.target().setTimeout(1);

}
).should.eventually.have.length(0)
.then(function () {
(Date.now() - refMs).should.be.below(5000);
});
);
res.should.have.length(0)
(Date.now() - refMs).should.be.below(5000);
});
});
});

@@ -0,9 +1,10 @@

// transpile:mocha
/* globals $ */
'use strict';
var base = require('./base'),
_ = require('underscore');
import { instrumentsInstanceInit, globalInit, killAll } from './base';
import _ from 'lodash';
describe('keyboard', function () {
var imports = { post: [
describe('keyboard', async () => {
let imports = { post: [
'uiauto/lib/mechanic-ext/gesture-ext.js',

@@ -13,12 +14,18 @@ 'uiauto/lib/mechanic-ext/keyboard-ext.js',

]};
base.globalInit(this, { imports: imports, bootstrap: 'basic'});
before(async function () {
await globalInit(this, { imports: imports, bootstrap: 'basic'});
});
describe("hide keyboard", function () {
describe('hide keyboard', async function () {
/* globals rootPage: true */
var ctx;
base.instrumentsInstanceInit()
.then(function (_ctx) { ctx = _ctx; }).done();
let ctx;
before(async () => {
ctx = await instrumentsInstanceInit();
});
after(async () => {
await killAll(ctx);
});
afterEach(function () {
return ctx.execFunc(
afterEach(async () => {
await ctx.execFunc(
function () {

@@ -31,6 +38,5 @@ $('#UICatalog').first().tap();

_(['pressKey', 'press']).each(function (strategy) {
it('should hide the keyboard by pressing the done key (' +
strategy + ')', function () {
return ctx.execFunc(
_.each(['pressKey', 'press'], function (strategy) {
it(`should hide the keyboard by pressing the done key (${strategy})`, async () => {
await ctx.execFunc(
function (strategy) {

@@ -47,6 +53,5 @@ rootPage.clickMenuItem('Text Fields');

_(['tapOutside', 'tapOut']).each(function (strategy) {
it('should hide the keyboard by tapping outside(' +
strategy + ')', function () {
return ctx.execFunc(
_.each(['tapOutside', 'tapOut'], function (strategy) {
it(`should hide the keyboard by tapping outside (${strategy})`, async () => {
await ctx.execFunc(
function (strategy) {

@@ -63,4 +68,4 @@ rootPage.clickMenuItem('Web View');

it('should hide the keyboard with the default strategy', function () {
return ctx.execFunc(
it('should hide the keyboard with the default strategy', async () => {
await ctx.execFunc(
function () {

@@ -75,5 +80,3 @@ rootPage.clickMenuItem('Web View');

});
});
});

@@ -0,19 +1,23 @@

// transpile:mocha
/* globals $ */
'use strict';
var base = require('./base');
import { instrumentsInstanceInit, globalInit, killAll } from './base';
describe('nil', function () {
var imports = { post: [
describe('nil', async function () {
let imports = { post: [
'uiauto/lib/element-patch/nil-patch.js',
'uiauto/lib/mechanic-ext/basics-ext.js'
]};
base.globalInit(this, { imports: imports, bootstrap: 'basic'});
let ctx;
before(async function () {
await globalInit(this, { imports: imports, bootstrap: 'basic'});
ctx = await instrumentsInstanceInit();
});
after(async () => {
await killAll(ctx);
});
var ctx;
base.instrumentsInstanceInit()
.then(function (_ctx) { ctx = _ctx; }).done();
afterEach(function () {
return ctx.execFunc(
afterEach(async () => {
await ctx.execFunc(
function () {

@@ -26,36 +30,28 @@ $('#UICatalog').first().tap();

it('isNil should return true for not nil elements', function () {
return ctx.execFunc(
it('isNil should return true for not nil elements', async () => {
let res = await ctx.execFunc(
function () {
return $('cell')[0].isNil();
}
).then(function (res) {
console.warn('res -->', res);
res.should.not.be.ok;
});
);
res.should.be.false;
});
it('isNil should return true for nil elements', function () {
return ctx.execFunc(
it('isNil should return true for nil elements', async () => {
let res = await ctx.execFunc(
function () {
return $('cell')[0].images().isNil();
}
).then(function (res) {
console.warn('res -->', res);
res.should.be.ok;
});
);
res.should.be.true;
});
it('isNil should return true for manually created UIAElementNil', function () {
return ctx.execFunc(
it('isNil should return true for manually created UIAElementNil', async () => {
let res = await ctx.execFunc(
function () {
return $.nil.isNil();
}
).then(function (res) {
console.warn('res -->', res);
res.should.be.ok;
});
);
res.should.be.true;
});
});

@@ -0,21 +1,25 @@

// transpile:mocha
/* globals $, env */
'use strict';
var base = require('./base'),
_ = require('underscore');
import { instrumentsInstanceInit, globalInit, killAll } from './base';
import _ from 'lodash';
describe('sendKey', function () {
var imports = { post: [
describe('sendKey', async function () {
let imports = { post: [
'uiauto/lib/mechanic-ext/keyboard-ext.js',
'uiauto/lib/element-patch/helper-patch.js'
]};
base.globalInit(this, { imports: imports, bootstrap: 'basic'});
/* globals rootPage: true */
var ctx;
base.instrumentsInstanceInit()
.then(function (_ctx) { ctx = _ctx; }).done();
let ctx;
before(async function () {
await globalInit(this, { imports: imports, bootstrap: 'basic'});
ctx = await instrumentsInstanceInit();
});
after(async () => {
await killAll(ctx);
});
afterEach(function () {
return ctx.execFunc(
afterEach(async () => {
await ctx.execFunc(
function () {

@@ -28,5 +32,6 @@ $('#UICatalog').first().tap();

_([undefined,'oneByOne', 'grouped', 'setValue']).each(function (sendKeyStrategy) {
it('should work with strategy: ' + sendKeyStrategy, function () {
return ctx.execFunc(
let keyStrategies = [undefined, 'oneByOne', 'grouped', 'setValue'];
_.each(keyStrategies, function (sendKeyStrategy) {
it(`should work with strategy: ${sendKeyStrategy}`, async () => {
await ctx.execFunc(
function (sendKeyStrategy) {

@@ -46,3 +51,2 @@ env.sendKeyStrategy = sendKeyStrategy;

});
});

@@ -1,11 +0,9 @@

'use strict';
// transpile:mocha
var chai = require('chai'),
fs = require('fs'),
prepareBootstrap = require('../../lib/dynamic-bootstrap').prepareBootstrap,
logger = require('../../lib/logger'),
Q = require('q'),
rimraf = Q.denodeify(require('rimraf')),
sinon = require('sinon'),
sinonChai = require("sinon-chai");
import { prepareBootstrap } from '../..';
import log from '../../lib/logger';
import chai from 'chai';
import { fs, rimraf } from 'appium-support';
import sinon from 'sinon';
import sinonChai from 'sinon-chai';

@@ -17,3 +15,3 @@ chai.should();

function envFromCode(code) {
// let's pick out the dynamic env from the new bootrap file with this
// let's pick out the dynamic env from the new bootsrap file with this
// regex so we can be sure it matches what we expect

@@ -26,3 +24,3 @@ var envRe = /^bootstrap\((\{[^]+})\);$/m;

function checkCode(code) {
async function checkCode (code) {
var env = envFromCode(code);

@@ -32,3 +30,3 @@ env.nodePath.should.equal(process.execPath);

env.instrumentsSock.should.exist;
fs.existsSync(env.commandProxyClientPath).should.be.ok;
(await fs.exists(env.commandProxyClientPath)).should.be.true;
return env;

@@ -38,53 +36,38 @@ }

before(function () {
sinon.spy(logger, "debug");
sinon.spy(log, 'debug');
});
after(function () {
logger.debug.restore();
log.debug.restore();
});
it('should generate dynamic bootstrap', function (done) {
it('should generate dynamic bootstrap', async () => {
process.env.APPIUM_BOOTSTRAP_DIR = '/tmp/appium-uiauto/test/unit/bootstrap';
rimraf(process.env.APPIUM_BOOTSTRAP_DIR)
await rimraf(process.env.APPIUM_BOOTSTRAP_DIR);
// first call: should create new bootstrap file
.then(function () { return prepareBootstrap(); })
.then(function (bootstrapFile) {
bootstrapFile.should.match(/\/tmp\/appium-uiauto\/test\/unit\/bootstrap\/bootstrap\-.*\.js/);
var code = fs.readFileSync(bootstrapFile, 'utf8');
checkCode(code);
})
.then(function () {
logger.debug.calledWithMatch(/Creating or overwritting dynamic bootstrap/).should.be.ok;
logger.debug.reset();
})
let bootstrapFile = await prepareBootstrap();
bootstrapFile.should.match(/\/tmp\/appium-uiauto\/test\/unit\/bootstrap\/bootstrap\-.*\.js/);
let code = await fs.readFile(bootstrapFile, 'utf8');
await checkCode(code);
log.debug.calledWithMatch(/Creating or overwriting dynamic bootstrap/).should.be.true;
log.debug.reset();
// second call: should reuse bootstrap file
.then(function () { return prepareBootstrap(); })
.then(function (bootstrapFile) {
bootstrapFile.should.match(/\/tmp\/appium-uiauto\/test\/unit\/bootstrap\/bootstrap\-.*\.js/);
var code = fs.readFileSync(bootstrapFile, 'utf8');
checkCode(code);
}).then(function () {
logger.debug.calledWithMatch(/Reusing dynamic bootstrap/).should.be.ok;
logger.debug.reset();
})
// second call: should reuse bootstrap file
bootstrapFile = await prepareBootstrap();
bootstrapFile.should.match(/\/tmp\/appium-uiauto\/test\/unit\/bootstrap\/bootstrap\-.*\.js/);
code = await fs.readFile(bootstrapFile, 'utf8');
await checkCode(code);
log.debug.calledWithMatch(/Reusing dynamic bootstrap/).should.be.true;
log.debug.reset();
// fourth call using custom socket path: should create different bootstrap file
.then(function () {
return prepareBootstrap({sock: '/tmp/abcd/sock'});
}).then(function (bootstrapFile) {
bootstrapFile.should.match(/\/tmp\/appium-uiauto\/test\/unit\/bootstrap\/bootstrap\-.*\.js/);
var code = fs.readFileSync(bootstrapFile, 'utf8');
var env = checkCode(code, {isVerbose: true, gracePeriod: 5});
env.instrumentsSock.should.equal('/tmp/abcd/sock');
})
.then(function () {
logger.debug.calledWithMatch(/Creating or overwritting dynamic bootstrap/).should.be.ok;
logger.debug.reset();
})
.nodeify(done);
// third call using custom socket path: should create different bootstrap file
bootstrapFile = await prepareBootstrap({sock: '/tmp/abcd/sock'});
bootstrapFile.should.match(/\/tmp\/appium-uiauto\/test\/unit\/bootstrap\/bootstrap\-.*\.js/);
code = await fs.readFile(bootstrapFile, 'utf8');
let env = await checkCode(code, {isVerbose: true, gracePeriod: 5});
env.instrumentsSock.should.equal('/tmp/abcd/sock');
log.debug.calledWithMatch(/Creating or overwriting dynamic bootstrap/).should.be.ok;
log.debug.reset();
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc