Robot Framework - Execute JavaScript command not working - javascript

I am currently try to run some JavaScript within my robot framework code that creates a new function, and then uses the newly created function to return a value upon calling it. However, when I log the result to the console, I do. It get my desired output. Please help!
The code:
${test}=  Execute Javascript  return function test(){return 1}; test();
Log To Console  ${test}
The console output:
{}

Move the return statement after the function definition, otherwise the return happens before test() is called.
*** Settings ***
Library Selenium2Library
*** Test Cases ***
Example
[Setup] open browser about:blank chrome
[Teardown] close all browsers
${test}= execute javascript function test() {return 1}; return test();
should be equal as strings ${test} 1

Related

How do I change dev tools console scope to be local to a function?

How do I use Chrome dev tools to evaluate code within the local scope of a function? I.e. for the following code
const name1 ="alireza"
function person(){
const name2 ="joe"
}
the result of code manually executed in the console should be
console.log(name2) //"joe"
What you are looking for are breakpoints:
You can dynamically set a breakpoint on a line within the function you want to inspect: devTools will break before the execution of that line and you can evaluate code within the scope of that function in the console.
Alternatively - if you can change the code (which you can also from devTools) - you can put a debugger statement where you want the execution to break.
This is slightly tricky because the statement you want to examine is the only statement in the function.
If you were to add another statement on the following line:
const name1 ="alireza"
function person(){
const name2 ="joe"
const name3 ="bob";
}
Then you could:
Open the Debugger tab
Create a break point on the line after const name2 ="joe"
Open the Console tab
Type person() to run the person function
Wait for the breakpoint to be hit
Return to the Console tab
Type console.log(name2); (or you could just look at the debugging information in the Debugging tab which reports all the in-scope variables).

How to call the function from browser console?

I need to call the function from browser console for testing purpose ?
test is working as expected , but test2 is not working
function test() {
alert(0);
}
(function(e, t) {
var test2 = (function() {
alert(2)
})
})
Calling for browser console
test() // its working
test2() // Uncaught ReferenceError: test2 is not defined
There are two basic problems here:
test2 never exists
test2 is defined inside a function which is never called, so it is never defined.
The code would have to actually call the anonymous function it is inside.
However, assuming that is a side effect of you truncating the code for this question and in your real case that anonymous function does get called:
test2 isn't a global
So in order to access it, you need to be in the right scope.
The only way to do that for the console would be to:
open up the sources tab of the browser's developer tools
add a breakpoint inside the anonymous function
run the code until your reach the breakpoint
then use the console to access test2 which is now in scope.
Note that given the structure of that code you might have to put the breakpoint before test2 has a value assigned to it and then step through the code until after it is defined.
Since your test2 var is a function on it's own, no need to wrap them in ().
Copy/paste this into browser console to check;
var test2 = (function() {
alert(2)
});
test2();
Advanced JavaScript: Why is this function wrapped in parentheses?
Should you really want those parentheses, you can call the existing function like so;
(function(e, t) {
var test2 = (function() {
alert(2)
});
test2(); // <-- Run function
})()
//^^ Extra parentheses to instantly run wrapper function

Chrome (`Version 46.0.2490.80 m`) developer tools and 'undefined'

Sorry for the really bad 'title'...
I have a simple script running in Chrome (Version 46.0.2490.80 m) developer tools. Where is this undefined coming from?
This same script when run 'normally' works as expected:
It is because the developer tools parses the string you provide into the console and execute it as a function and return/print the return value whatever the statement you had put is returning.
Execute the below code, there is no return statement, hence it will print undefined.
(function(){
[1,2,3].forEach(function(val) {
console.log(val);
});
//no return statement //Hence undefined
})();
But look at the below case, the function is returning some value.
(function(){
[1,2,3].forEach(function(val) {
console.log(val);
});
return "YOU DONT SEE UNDEFINED NOW"; //prints the string
})();
whereas if it is executed by the browser script, the developer-tools prints whatever the function prints and the function returns value to its caller. (Here, developer-tools need not to print all the function return values run by browser script, then your logs becomes messed up. You will see random return values returned by each and every function.

How can I override/extend ReferenceError in Chrome's JavaScript?

To make debugging easier, I'm capturing all of the console logs in Chrome so that users who submit a feedback entry will also submit all of the logs to our server. When someone encounters a problem in production, I can first and foremost get them back to work so that I can then sit down and more thoroughly go through all of the logs to determine the root cause of whatever issue the user encountered in production.
The technique I use to capture the logs involves overriding console.log so that all text entered in the first argument gets stored in an array while simultaneously invoking the legacy function so that I can still see the logs in the console too.
The problem is when there's the occasional uncaught exception. These aren't included in the uploaded logs, so it's not always clear what caused the problem. So I tried overriding ReferenceError by writing a JavaScript function that takes a function as an argument, then returns a new function that does stuff with it, like storing data in a variable, and then invoking the legacy function as the last step:
function overrideException(legacyFn) {
/** arguments for original fn **/
return function() {
var args = [];
args[0] = arguments[0];
// pass in as arguments to original function and store result to
// prove we overrode the ReferenceError
output = ">> " + legacyFn.apply(this, args).stack;
return legacyFn.apply(this, arguments);
}
}
To test the overrideException function, I ran the following code on the console:
ReferenceError = overrideException(ReferenceError);
Afterwards, I tested the returned function, the new ReferenceError, by manually throwing a ReferenceError:
throw new ReferenceError("YES!! IT WORKS! HAHAHA!");
The resulting output on the console is:
ReferenceError: YES!! IT WORKS! HAHAHA!
And checking the global variable output from the overrideException function shows that it did indeed run:
output
">> ReferenceError: YES!! IT WORKS! HAHAHA!
at ReferenceError (<anonymous>)
at new <anonymous> (<anonymous>:18:35)
at <anonymous>:2:7
at Object.InjectedScript._evaluateOn (<anonymous>:562:39)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:521:52)
at Object.InjectedScript.evaluate (<anonymous>:440:21)"
Now, here's where things start to fall apart. In our code, we're not going to know when an uncaught exception occurs, so I tested it by attempting to run a function that doesn't exist:
ttt();
Which results in:
ReferenceError: ttt is not defined
However, unlike the case where we explicitly throw an error, in this case, the function doesn't fire, and we're left with only the legacy functionality. The contents of the variable output is the same as in the first test.
So the question seems to be this: How do we override the ReferenceError functionality that the JavaScript engine uses to throw errors so that it's the same one we use when we throw a ReferenceError?
Keep in mind that my problem is limited only to Chrome at this time; I'm building a Chrome Packaged app.
I have done quite a bit of research for the same reason: I wanted to log errors and report them.
"Overriding" a native type (whether ReferenceError, String, or Array) is not possible.
Chrome binds these before any Javascript is run, so redefining window.ReferenceError has no effect.
You can extend ReferenceError with something like ReferenceError.prototype.extension = function() { return 0; }, or even override toString (for consistency, try it on the page, not the Dev Tools).
That doesn't help you much.
But not to worry....
(1) Use window.onerror to get file name, 1-indexed line number, and 0-indexed position of uncaught errors, as well as the error itself.
var errorData = [];
onerror = function(message, file, line, position, error) {
errorData.push({message:message, file:file, line:line, position:position, error:error});
};
See the fiddle for an example. Since the OP was Chrome-specific, this has only been tested to work in Chrome.
(2) Because of improvements to (1), this is no longer necessary, but I leave this second technique here for completeness, and since onerror is not guaranteed to work for all errors on all browsers. You will also sometimes see the following:
var errors = [];
function protectedFunction(f) {
return function() {
try {
f.apply(this, arguments);
} catch(e) {
errors.push(e);
throw e;
}
};
}
setTimeout = protectedFunction(setTimeout);
setInterval = protectedFunction(setInterval);
etc...
FYI, all this is very similar to what has been done in the Google Closure Compiler library, in goog.debug, created during Gmail development with the intent of doing exactly this. Of particular interest is goog.debug.ErrorHandler and goog.debug.ErrorReporter.

Node.js vs Javascript Closure

I'm working my way through the Eloquent JavaScript Book and in it there is the following code:
function createFunction(){
var local = 100;
return function(){return local;};
}
When I run this via the node console (run node from command prompt) by calling createFunction(), I get [Function] as a returned value. However, according to the book I should get 100.
So my two questions: Why is this? and Second, is running these little examples in the node console a bad idea for testing JS code?
You need to call the response of createFunction().
createFunction()();
The first invocation (()) calls createFunction() and returns the inner function, which the second invocation executes and returns the local variable which was closed over.
Running small examples in a node console (or any other) is fine, so long as you know the environment, e.g. a browser's console is generally eval()'d, which can create side effects, such as how delete can apparently delete variables, not just object properties.
You get 100 by invoking the return value of createFunction, which is itself a function.
createFunction()();
...or perhaps more clearly...
var new_func = createFunction();
new_func();
function createFunction(){
var local = 100;
// v---v-----------------------v return a function from createFunction
return function(){return local;};
}
// v------- the returned function is assigned to the new_func variable
var new_func = createFunction();
// v------- the returned function is invoked
new_func();
For those that have a similar problem, I completely missed the double () so the call looks like createFunction()().

Categories