I am currently developing a Keyword driven framework using JavaScript / TestComplete and have an Excel file which contains a step number, Description, Keyword, Locator and Data.
I am currently reading the data from the Excel file (.xlsx) and storing the data (in this case the locator) in a variable..
I am storing the String Browsers.Item(btlExplorer,"",Browsers.pX64 in a variable called locator. When I then attempt this: locator.Run(https://www.google.ie/?gws_rd=ssl#spf=1); I receive this error: JavaScript runtime error. TypeError. getLocator(...).Run is not a function.
This is my getLocator function:
function getLocator(x){
var driver;
var value;
driver = DDT.ExcelDriver("C:\\Users\\Username\\Desktop\\Automation Framework.xlsx", "Sheet1", false);
while (! driver.EOF() && driver.Value(0) != x){
DDT.CurrentDriver.Next();
}
value = driver.Value(3);
Log.Message(value);
DDT.CloseDriver(driver.Name);
return value;
}
And here is the function I am running:
function openGoogle()
{
//Launches the specified browser and opens the specified URL in it.
getLocator(1).Run("https://www.google.ie/?gws_rd=ssl#spf=1");
}
I am new to JavaScript, if you could give me any tips / advice on what is going wrong it would be greatly appreciated.
Since the value returned by the getLocator function is a string, you can work with it as a string and it does not have the Run method.
To get the actual object with the Run method, you need to evaluate the string in this way:
function openGoogle()
{
//Launches the specified browser and opens the specified URL in it.
let brwsr = eval(getLocator(1));
brwsr.Run("https://www.google.ie/?gws_rd=ssl#spf=1");
}
Related
The flowfile uses evaluateJsonPath in order to extract values and setup my Attributes. I need to pass some of the attributes into a JavaScript function which I have in a ExecuteScript processor. The setting is for ECMAScript and the JS code is in the Script Body.
So, as an example if my attributes are A, B, C and my function is foo(arg){}
How do I call the function foo(A)?
I have tried putting at the end of the Script Body, after the declaration of my function foo
foo(A);
foo(${A});
But this keeps failing and I am not able to find any examples on how to pass in the value to the function call. I get either a "A is not defined in " or Expects a , and got a {.
What is the proper way to pass an Attribute to the ExecuteScript processor?
UPDATED: SEE BELOW
So as I'm trying to figure this out here is what I'm dealing with.
Read in a JSON file
Set some attributes with EvaluateJSONPath
HERE I NEED TO merge some attributes and want to use the ExecuteScript to run some JavaScript
JAVASCRIPT
var flowFile = session.get();
if(flowFile){
var argFoo = flowFile.getAttribute("someAttribute");
// Set the value as a new Attribute in the flowFile
session.putAttribute(flowFile, "NewAttribute", argFoo);
}
I've also tried things like
var flowFile = session.get();
if(flowFile){
var argFoo = flowFile.getAttribute("someAttribute");
// Create a new flowFile
var newFlowFile = session.create(flowFile);
// Set the value as a new Attribute in the flowFile
session.putAttribute(newFlowFile, "NewAttribute", argFoo);
}
I'm blindly guessing how to get this to work.
Can someone point me in the right direction here on how to use JavaScript within this ExecuteScript processor?
The latest error is "This FlowFile was not created in this session and was not transferred to any Relationship via ProcessSession.transfer()"
Check these sites:
https://nifi.apache.org/docs/nifi-docs/components/org.apache.nifi/nifi-scripting-nar/1.20.0/org.apache.nifi.processors.script.ExecuteScript/additionalDetails.html
https://community.cloudera.com/t5/Community-Articles/ExecuteScript-Cookbook-part-1/ta-p/248922
https://community.cloudera.com/t5/Community-Articles/ExecuteScript-Cookbook-part-2/ta-p/249018
https://community.cloudera.com/t5/Community-Articles/ExecuteScript-Cookbook-part-3/ta-p/249148
https://github.com/mkalika/nifi-executescript-samples
You don't have to create new a FlowFile, if you want only to add a new attribute.
Example
flowFile = session.get();
if (flowFile != null) {
// Get attributes
var greeting = flowFile.getAttribute("greeting");
var message = greeting + ", Script!";
// Set single attribute
flowFile = session.putAttribute(flowFile, "message", message);
// Set multiple attributes
flowFile = session.putAllAttributes(flowFile, {
"attribute.one": "true",
"attribute.two": "2"
});
session.transfer(flowFile, REL_SUCCESS)
}
I want to get a javascript object from a javascript file, that only constists of this one big object.
For example:
var cars = {
mercedes: {
colour: 'silver',
drivemode: 'alldrive'
},
audi: {
size: '4x2x1,5m'
speed: '220 kmph'
}
};
For the javapart I am using rhino to get that object. For now I have coded:
Context context = context.enter();
context.setOptimizationLevel(9);
context.setLangaugeVersion(170);
context.getWrapFactory().setJavaPrimitiveWrap(false);
Scriptable defaultScope = context.initSafeStandardObjects();
So now i should have the possibility to be able to retrieve the javascript object. But how?
Script function = context.compileString("Any javascriptfunction as String", "javaScriptFile.js", 1, null);
function.exec(context, defaultScope);
But what would that javascript function look like to get that object as JSON (something like cars.stringify() )? And further more is that the right approach in using this function?
And finally how and where to i save the object in a java Object?
i have already checked this post and this post also this post but all dont fit my criteria or are missing out on a code example for clarification
Edit:
I have found another approach in calling/writing a javascript function in java as a string like:
Scriptable scriptObject;
private String functionAsString = "function getAsJson() {var objectString = { colour: \"silver\", drivemode: \"alldrive\" };return JSON.stringify(objectString);}";
Function fct = context.compileFunction(defaultScope, functionAsString, "AnyName", 1, null);
Object result = fct.call(context, defaultScope, scriptObject, null);
The only problem still standing is how do it get "objectString" to contain my cars.js? There somehow has to be a possibility to load that object in this variable
probably something like:
String functionAsString2 = "get cars() {return this.cars;}";
But how/and where do i specify the file in which to use this function?
I have found a way to retrieve the object by using the ScriptEngine from Rhino
private ScriptEngineManager manager = new ScriptEngineManager();
private ScriptEngine engine = manager.getEngineByName("JavaScript");
engine.eval(Files.newBufferReader("PATH TO THE JAVASCRIPT FILE", StandardCharsets.UTF_8));
Object result = engine.get("cars"); //Variable in the javascript File
if(result instanceof Map){
result = (Map<String,Object>) result;
}
so the object is retrieved and can be accessed and casted as a Map> and recursively accesed to in the end having a java Object of the JavaScript Object.
No need to use functions
I have a function in JavaScript
function functioncalled(){
var result = 1;
var activityID = {{ mynames[result][8] }};
console.log(activityID);
}
mynames is a list of lists in Flask template. The above code fails giving me an error - UndefinedError: list object has no element Undefined. But when I access the list element using var activityId = {{mynames[1][8]}} everything works fine. How do I make this work? Is there a workaround? I couldn't find the solution anywhere.
You will not be able to do that, because {{any_flask_variable}}is evaluated on server side and rendered HTML is sent to browser where all javascript runs. At the time of evaluation on the server there is not browser to run javascript code. The best way to resolve this is to assign the list variable to var result.
function functioncalled(){
var result = {{mynames}};
// Here you can access the variable result
console.log(activityID);
}
That off course after assuming that mynames variable can be mapped to js array of arrays.
I'm trying to call a custom JS function stored in OrientDB, from Java, through the OrientDB Java API.
I can use the function inside studio, and it works as expected.
This is the code used to connect to the db and get the function:
OrientGraphFactory factory = new OrientGraphFactory(SERVER_URL, "user", "pass");
OrientGraph txGraph = factory.getTx();
OFunction functionObject = txGraph.getRawGraph().getMetadata()
.getFunctionLibrary().getFunction("functionName");
The problem is that the functionObject returned is null, and inspecting the getFunctionLibrary() result, I can see the list of functions is empty.
Any idea what I'm doing wrong?
Using the official Documentation example, gives the same null result.
LE: For anyone stumbling on this, the full working code is:
OrientGraphFactory factory = new OrientGraphFactory(SERVER_URL, "user", "pass");
OrientGraph txGraph = factory.getTx();
Double response = (Double) txGraph.command(new OCommandFunction("functionName")).execute(functionParameter);
where response is the result the function gives and functionParameteris a parameter I'm passing to the function.
This will work for java functions only (and example in doc is correct because it retrieves java function).
In order to execute js/sql/whatever function use OCommandFunction. Something like this:
txGraph.command(new OCommandFunction("functionName")).execute()
Possibly it could work directly too (if you don't need to convert result to graph objects)
new OCommandFunction("functionName").execute()
But in this case db instance must be attached to thread (db connection object created before function call)
I have a dataconfig.xml file that collects data from an Oracle database. In the Datasource element, I use variables such as ${dataimporter.request.dbname} that return successfully the custom value I passed via the dataimport url.
I am now writing a javascript transformer in this same dataconfig file to add values in a mutivalued field and that includes the database name. Is it possible to refer to the variable ${dataimporter.request.dbname} from within the javascript transformer? If so, what would be the correct syntax?
This is what I have tried, but dbname does not get populated:
function relatedItems(row) {
var relatedItemsArray = new java.util.ArrayList();
var dbname=${dataimporter.request.db_name};
relatedItemsArray.add('type=DOCUMENT;datasource:PB||' + dbname);
row.put('relation', relatedItemsArray);
return row;
}
Any help is greatly appreciated!
Thanks in advance.
I just had that problem myself... The question is old, but just in case, this is how I passed a context variable to a script in the data import handler:
<entity name="fileline" processor="LineEntityProcessor" url="${filelist.fileAbsolutePath}" format="text" transformer="TemplateTransformer,script:relatedItems">
<field column="dbname" template="${dataimporter.request.db_name}"/>
</entity>
the TemplateTransformer will add the parameter in a new field, before passing the augmented row to the script. Then in the script:
function relatedItems(row) {
var dbname= row.get("dbname");
var rawLine = row.get("rawLine");
....
}
you can access your extra variable this way. It seems somewhat convoluted, but that's the best I could find (that works!).
You can access request parameters from the dataimport call from request context which is available to the script the same as 'row' is.
function myScript(row, context) {
var dbName = context.getRequestParameters().get('db_name');
...
}