How to use coerceScriptResult method in Appium Base Driver

Best JavaScript code snippet using appium-base-driver

Run Appium Base Driver automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

execute-child.js

Source: execute-child.js Github

copy
1import _ from 'lodash';
2import B from 'bluebird';
3import vm from 'vm';
4import log from '../logger';
5import { attach } from 'webdriverio';
6
7// duplicate defining these keys here so we don't need to re-load a huge appium
8// dependency tree into memory just to run a wdio script
9const W3C_ELEMENT_KEY = 'element-6066-11e4-a52e-4f735466cecf';
10const MJSONWP_ELEMENT_KEY = 'ELEMENT';
11
12async function runScript (driverOpts, script, timeout) {
13  if (!_.isNumber(timeout)) {
14    throw new Error('Timeout parameter must be a number');
15  }
16
17  // set up fake logger
18  const logLevels = ['error', 'warn', 'log'];
19  const logs = {};
20  const consoleFns = {};
21  for (const level of logLevels) {
22    logs[level] = [];
23    consoleFns[level] = (...logMsgs) => logs[level].push(...logMsgs);
24  }
25
26  const driver = attach(driverOpts);
27
28  const fullScript = buildScript(script);
29  // the timeout here will not matter really, but set it anyway to be on the
30  // safe side
31  const vmCtx = vm.runInNewContext(fullScript, {}, {timeout});
32
33  // run the driver script, giving user access to the driver object, a fake
34  // console logger, and a promise library
35  log.info('Running driver script in Node vm');
36  let result = await vmCtx(driver, consoleFns, B);
37
38  log.info('Ensuring driver script result is appropriate type for return');
39  result = coerceScriptResult(result);
40  return {result, logs};
41}
42
43/**
44 * Embed a user-generated script inside a method which takes only the
45 * predetermined objects we specify
46 *
47 * @param {string} script - the javascript to execute
48 *
49 * @return {string} - the full script to execute
50 */
51function buildScript (script) {
52  return `(async function execute (driver, console, Promise) {
53    ${script}
54  })`;
55}
56
57/**
58 * We can get any manner of crazy thing back from a vm executing untrusted
59 * code. We might also get WebdriverIO objects that aren't suitable for JSON
60 * response. So make sure we convert the things we know about to their
61 * appropriate response format, and squash other weird things.
62 *
63 * @param {Object} obj - object to convert and sanitize
64 *
65 * @return {Object} - safely converted object
66 */
67function coerceScriptResult (obj) {
68  // first ensure obj is of a type that can be JSON encoded safely. This will
69  // get rid of custom objects, functions, etc... and turn them into POJOs
70  try {
71    obj = JSON.parse(JSON.stringify(obj));
72  } catch (e) {
73    log.warn('Could not convert executeDriverScript to safe response!' +
74             `Result was: ${obj}. Will make it null`);
75    return null;
76  }
77
78  let res;
79
80  // now we begin our recursive case options
81  if (_.isPlainObject(obj)) {
82    // if we have an object, it's either an element object or something else
83    // webdriverio has no monadic object types other than element and driver,
84    // and we don't want to allow special casing return of driver
85    res = {};
86
87    if (obj[MJSONWP_ELEMENT_KEY] || obj[W3C_ELEMENT_KEY]) {
88      // if it's an element object, clear out anything that's not the key, and
89      // then return the object
90      if (obj[MJSONWP_ELEMENT_KEY]) {
91        res[MJSONWP_ELEMENT_KEY] = obj[MJSONWP_ELEMENT_KEY];
92      }
93
94      if (obj[W3C_ELEMENT_KEY]) {
95        res[W3C_ELEMENT_KEY] = obj[W3C_ELEMENT_KEY];
96      }
97      return res;
98    }
99
100    // otherwise, recurse into the object
101    for (const key of Object.keys(obj)) {
102      res[key] = coerceScriptResult(obj[key]);
103    }
104    return res;
105  }
106
107  // in the cae of an array, just recurse into the items
108  if (_.isArray(obj)) {
109    return obj.map(coerceScriptResult);
110  }
111
112  // base case, if it's not an object or array, return straightaway
113  return obj;
114}
115
116async function main (driverOpts, script, timeout) {
117  let res;
118  try {
119    res = {success: await runScript(driverOpts, script, timeout)};
120  } catch (error) {
121    res = {error: {message: error.message, stack: error.stack}};
122  }
123  await B.promisify(process.send, {context: process})(res);
124}
125
126if (require.main === module) {
127  log.info('Running driver execution in child process');
128  process.on('message', ({driverOpts, script, timeout}) => {
129    log.info('Parameters received from parent process');
130    main(driverOpts, script, timeout);
131  });
132}
133
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Appium Base Driver on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)