autopilot-github

How can we help?

fluent-robot
 

Automation Cloud

Eval.javascript pipe

This pipe executes an arbitrary JavaScript code and returns its results. Depending on its mode, Autopilot exposes different globals for your code.

All modes

Javascript running in any of the available modes has access to ctx, an Object with lots of useful properties, see https://github.com/automationcloud/autopilot/blob/master/packages/engine/src/main/runtime.ts.

The most frequently used properties of ctx are:

  • ctx.script.getGlobal(key:string, optional:boolean=false) / ctx.script.setGlobal(key:string, value:any), used for retrieving and assigning script globals, accessible with the Value.getGlobal pipe and the Global.setGlobal action;
  • ctx.script.requestInput(key:string), an async function which returns an input from API as soon as it’s provided;
  • ctx.fetch, an instance of node-fetch https://github.com/node-fetch/node-fetch;
  • ctx.moment, an instance of MomentJS https://momentjs.com/;
  • other frequently used utilities, e.g. ctx.formatUrl(obj:any), ctx.parseUrl(url:string), ctx.removeDiacritics(string), ctx.levenshtein, ctx.sanitizeHtml.

element mode

Exposes el, an Element instance which is the base entity of all pipes and actions, see https://github.com/automationcloud/autopilot/blob/master/packages/engine/src/main/element.ts.

The most frequently used properties of el are:

  • el.value, the JSON object stored by that instance at that point in time;
  • el.clone(), a function which creates a deep copy of the element, including its value. This is used when returning a new element with a different value, without affecting the previous instance coming through the pipeline;
  • el.evaluateJson(fn:function, arg:any), a function which executes arbitrary Javascript code in the browser’s DOM. This is a very powerful feature and requires responsible usage, since it runs in the browser’s scope. Sample usage:
// dispatches a "click" event on a modified anchor, then returns a localStorage entry
const result = await el.evaluateJson(function(el, value) {
  // this runs inside the browser
  el.setAttribute('target', '_blank');
  
  const ev = new MouseEvent('click');
  el.dispatchEvent(ev);
  
  return window.localStorage.getItem('someLocalStorageKey');
}, el.value);

el.value = result; // this is the contents of 'someLocalStorageKey' in localStorage
return el;
// Creates a visible checkbox to be selectable and clicked, used for hidden elements
await el.remote.evaluate(el => {
  el.style.width = '12px';
  el.style.height = '12px';
  el.style.position = 'static';
  el.style.border = '1px solid red';
  el.style.opacity = 1;
});
return el;
// Makes a floating element (e.g. sidebar) static.
await el.remote.evaluate(el => {
  el.style.position = 'static';
  el.style.top = '0';
});
return el;
// When filtering visible elements does not work as expected because the elements are outside the viewport, use this JS to filter out by coordinates.
el.value = await el.evaluateJson(function(el){
 return el.getBoundingClientRect().x;
});
return el;

In element mode, the pipe must return an Element instance, for example, return el or return el.clone().

value mode

Exposes value, the JSON object stored by the Element instance entering the pipeline under el.value, and exposes el as defined earlier. This is a convenient shortcut for quickly manipulating JSON data, mostly used for mathematics e.g. return value + 1;.
In value mode, the pipe must return a JSON object (serialisable), for example, return {"key": "value"} or return value;.

Frequent examples:

return value.toLowerCase();
return value.length;
return String(value);
return Math.min(...value);
return Math.round(...value);
return value.trim();
return value.length;
// Divide the card number into 4 for different strings.
return value.pan.substring(0,4)
return value.pan.substring(4,8)
return value.pan.substring(8,12)
return value.pan.substring(12,16)

collection mode

Exposes inputSet, an array of all the Element instances that have come through the pipeline. This is frequently used to return a different set of elements, larger or smaller, to the original one.
In collection mode, the pipe must return an iterable object, e.g. return [inputSet[0]] or return inputSet;

2 Likes