How to execute a Javascript function in python with selenium - javascript

I have a function called 'checkdata(code)' in javascript, which, as you can see, takes an argument called 'code' to run and returns a 15-char string.
So, I found out (and tested) how to call no-argument functions in javascript, but my problem is that when I call checkdata(code), I always get a 'none' return value.
This is what I'm doing so far:
wd = webdriver.Firefox()
wd.get('My Webpage')
a = wd.execute_script("return checkdata()", code) //Code is a local variable
//from my python script
print a
I'm making this, since I read it on an unofficial selenium documentation and here: link
But, as I said before, I just keep getting none printed.
How can I call my function passing that parameter?

Build the string
a = wd.execute_script("return checkdata('" + code + "');")

Rather than building a string (which means you'd have to escape your quotes properly), try this:
a = wd.execute_script("return checkdata(arguments[0])", code)

Related

Replace Unicode from each output of NodeJS - Code optimization

I am reading data from a serial port and with test case capturing the required output, then this output is sent to html
now while reading from serial port, there are few unicode charachters in the output.
I can remove them by using
.replace(/[^\x0000-\xFFFF]/g, "").trim();
there are approx 50 places where I need to use this replace and trim method, so I am trying to define a function, where I can pass the output to the function and it will give me clean output.
So I do not have to write .replace and .trim to every output.
here is what I tried till now.
This is the function I define to do the replace and trim.
function cleanoutput () {
var output = output.replace(/[^\x0000-\xFFFF]/g, "").trim();
}
This is the function calling to the output
display.adults = cleanoutput (adults.slice(28, 31));
By doing this I am getting error in function cleanoutput
error - "Cannot read property 'replace' of undefined"
I am just learning nodejs, need help on making this work.
There are two problems with your function: first, you are using replace on a variable that probably is not defined yet but is probably intended to work on a parameter, that is not defined either.
The second problem is that your function is not returning anything, so it is implicitly returning undefined.
display.adults will be undefined after the execution of the cleanoutput function.
You can fix those problems with something like this:
function cleanoutput (output) {
return output.replace(/[^\x0000-\xFFFF]/g, "").trim();
}
My suggestion is to dive a little bit deeper into javascript functions.
There are plenty of articles, blog posts, and youtube videos on the topic and I'm sure you will find a good one.

JXA and .length

I am trying to turn an old javascript program of mine into a service on a mac using automator. When I use my Code, it doesn't work. I have checked what I can, and I have found that the most basic issue I encounter is that the .length property from javascript does not work. This simple program doesn't return what it should. It returns nothing:
function run(input) {
var ina = 'hello';
var newn = ina.length;
return newn;
}
Your code returns 5.
input is an array of 0 elements. Not of much use in script editor. When run from a command line it is the parameters.
As a side note run is the run handler for all AppleScript (including JXA), so you would not call function run. It is called for you.
UPDATE:
In automator, The result (5) is sent to the next automator task. You can do a "Set Value of Variable" right after you do "Run JavaScript" with your script to capture the 5.

Replicating/overriding javascript's console.log function

OK, so here's what I'm trying to do:
I'm building a Javascript->Cocoa/Objective-C bridge (a tiny test actually), which means that I'm able to call an Objective-C function from my JavaScript code.
One of the issues faced is that messages/errors/logs/etc from console.log are not visible, so they are to be forwarded to the corresponding Cocoa function (i created one like - (void)log:(NSString*)msg which simply takes a parameter as string and prints it out in the Xcode's console window.
Now, the thing is how do I replicate 100% what console.log does + forward the message to my own log function?
This is what I've done so far:
Javascript
console.log = function(text) {
API.log_(text);
}
Objective-C
- (void)log:(NSString*)msg
{
NSLog(#"Logging from JS : %#", msg);
}
If "text" is a simple text string when calling console.log("something"), then it works fine. If I pass the console.log function an object, then it's not working as expected (e.g. in Chrome's Javascript console window).
How would you go about it?
Is it possible to get the string output of what console.log would normally print out?
P.S. I tried playing with JSON.stringify(obj, null, 4) a bit, but it still doesn't seem right. Any ideas?
It sounds like you want the original functionality to persist whilst also capturing the input and passing it to your API. That could be achieved by something like (JSFiddle):
var original = console.log,
API = {
log_: function() {
// Your API functionality
}
};
console.log = function() {
original.apply(console, arguments);
API.log_(arguments);
};
A couple of things to point out. Firstly, the native console.log can receive any number of parameters, so we use arguments to handle this. We have to use .apply() to call the original method in the context of console and it also allows us to pass the arguments exactly as they were on the original call.

Javascript error halts $document.ready()

I'm updating an existing website running on Expression Engine. So far, I've stayed away from any code I didn't write or couldn't understand. I recently must have altered some bit of code someplace (helpful, I know) and now a block of JS I didn't write is causing an error that seems to bypass the document.ready() event. The window.load() event however is still taking place.
In the Chrome DevTools Console, the error "Uncought TypeError: Cannot call method 'replace' of UNDEFINED" points to the definition of a function "fixedEncodeURIComponent" pasted below.
$("#MessageContainer.Counted").counter({
type: 'char',
goal: 250,
count: 'down'
}).change(function(){
var TEMP = fixedEncodeURIComponent($(this).val());
$("#Message").val(TEMP);
});
var TEMP = fixedEncodeURIComponent($("#MessageContainer.Test").val());
$("#Message").val(TEMP);
function fixedEncodeURIComponent (str) {
str=str.replace(/"/g, '');
return encodeURIComponent(str).replace(/[!'()*]/g, escape);
}
As I interpret the error, this function is being passed a variable that is not a string. I added an alert(str) to the function definition and the result was UNDEFINED as I expected. The first of several unknowns for me is which call to the function 'fixedEncodeURIComponent' is being passed a bad variable. I assume that it's the first call, but that's just a guess. It so happens that this first call contains a syntax I have never encountered before. I don't know how to interpret what happens when $(this) is passed as a function argument.
Any insights would be greatly appreciated. Also, if there's more information you need please let me know. The client's site is password protected but I can include any code you request.
Thank you.
I'm taking a guess that the }); on line 3 is exiting a document.ready context. If that's the case then your second call to fixedEncodeURIComponent may be getting called before the DOM is even loaded.
Start by wrapping
var TEMP = fixedEncodeURIComponent($("#MessageContainer.Test").val());
$("#Message").val(TEMP);
in a
$(function() {
// code
});
block. If that doesn't work, check that #MessageContainer.Test actually matches an element. Since this is code you inherited, the class name "Test" clues me in that the block in question might be a remnant of someone trying to debug an issue and maybe it should have been removed.
I suspect $("#MessageContainer.Test") since it looks like its supposed to be an ID selector instead of what it actually is when jQUery parses it(which is an ID selector combined with a class selector). $("MessageContainer\\.Test") allows you to select an element with ID MessageContainer.Test

How do I convert a string into an executable line of code in Javascript?

I have the following bit of code
console.log("I am");
var x = "console.log('Alive!')";
Now I only want to use x to execute the code-string that is assigned to it - I may not even know the value of x for example but simply want to execute it whatever it maybe - is this possible?
eval() This will convert string to javascript code.
eval("console.log('Alive! Woo!')");
eval and new Function let you parse and execute JavaScript code from strings.
In general, avoid executing code from strings. And never execute code from strings where the strings are untrusted input (for instance, if you take input from user A, never use these to evaluate it in a session with user B).
I see answers here pointing you at eval. eval grants access to your local variables and such to the code, making it really powerful and really dangerous if you use it with untrusted input.
Where possible, avoid eval. You can easily avoid it in your case:
For instance:
console.log("I am");
var x = "console.log('Alive!')";
new Function(x)();
That code creates a function whose body is the text from x, then immediately executes the function.
What you are looking for is eval(). By passing a string to this function you will evaluate the string as JavaScript code and it will return whatever return-value the code in the string returns.
Be aware when using this function though. You do not want to evaluate any code you do not know is safe to execute. For example, running user-generated code could mess up whatever you are making. While using this in JavaScript on a website this will probably only cause issues on the client-side and hence probably won't be much of a security threat, you would want to be VERY careful when evaluating code on for example a server side.
As have been hinted to in other posts here you probably want to make a function instead of an evaluated string if you are in control of the source code that is to be run.
What you are looking for is called a function:
function x() {
console.log('Alive!');
}
If x is already a string containing the code you could use eval(x) to execute it. eval is evil though.
var x = "console.log('Alive!')";
eval(x)

Categories