Execute an external .js file using selenium webdriver - javascript

How can we execute an external .js file using selenium webdriver file using java selenium. I got some reference "Call external javascript functions from java code", however invoke function is able to accept the function inside that file. I want to just execute the whole file as a whole.

It's as simple as this to run an external JavaScript from your server upon the client:
// Assume Guava, but whatever you use to load files...
String externalJS = Files.toString( new File("external.js"), Charset.forName("utf-8"));
// Execute, assume no arguments, and no value to return
Object ignore = ((JavascriptExecutor) driver).executeScript(externalJS);
The link you provided isn't useful, because it's about executing JavaScript upon the server (within the Java VM) rather than upon the browser/device client.
If rather than executing, you're interested in injecting JavaScript into the page for other scripts etc. to interact with (i.e. rather than a one-off execution), see this question.

Here is the code for nodeJS calling external JS and executing a function within the JS:
var fs = require('fs');
var webdriver = require('selenium-webdriver'),
By = webdriver.By,
until = webdriver.until;
var driver = new webdriver.Builder()
.forBrowser('phantomjs')
.build();
var axeSource = fs.readFileSync('lib/axe.js', 'utf8');
driver
.get('http://www.google.com/ncr')
driver.executeScript(axeSource)
.then(function(){
driver.switchTo().defaultContent();
driver.executeAsyncScript(function() {
var callback = arguments[arguments.length - 1];
window.axe.a11yCheck(document, null, function (results) {
callback(results);
});
}).then(function(str) {
var viola = processResults(str);
console.log(viola);
});
})
driver.quit();

Related

JS Web worker share the same scripts in multiple workers

I have multiple inline workers that I need to run. My problem is that every instance needs to share the same scripts that are imported. But on every instance that I created, it redownloads the scripts.
function workerFn(){
importScripts('https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js');
// Each time this function will do something else
postMessage(_.head([1,2,3]));
}
var code = workerFn.toString();
code = code.substring(code.indexOf("{") + 1, code.lastIndexOf("}"));
var blob = new Blob([code], {type: "application/javascript"});
var worker = new Worker(URL.createObjectURL(blob));
var worker2 = new Worker(URL.createObjectURL(blob));
worker.onmessage = function (m) {};
worker2.onmessage = function (m) {};
So, in the above example, lodash will download twice. How can I prevent this?
Short answer:
Unfortunately, you cannot. It's up to the browser whether it downloads the scripts or not. I assume this does not even happen in every browser.
Another short answer:
The only way to avoid browser re-downloading the script would be to either a) have it compiled in your code (eg. web pack) or b) download it via AJAX, assuming CDN allows requests from other domains.
Neither of these thing is something I would recommend for production code.

How to load external js library in Jmeter?

I have the following code in a jsr223 sampler:
var key = "key";
var dateStamp = "20160329T134359Z";
var regionName = "us-east-1";
var serviceName = "execute-api";
var kDate= Crypto.HMAC(Crypto.SHA256, dateStamp, "AWS4" + key, { asBytes: true})
var kRegion= Crypto.HMAC(Crypto.SHA256, regionName, kDate, { asBytes: true });
var kService=Crypto.HMAC(Crypto.SHA256, serviceName, kRegion, { asBytes: true });
var kSigning= Crypto.HMAC(Crypto.SHA256, "aws4_request", kService, { asBytes: true });
vars.put("AWSKey", kSigning);
Now when I run it i get this error:
Response code: 500
Response message: javax.script.ScriptException: sun.org.mozilla.javascript.internal.EcmaError: ReferenceError: "Crypto" is not defined. (#6) in at line number 6
Obviously I dont have the crypto libs. However I am at loss on how to load them. I downloaded all the relavant js and put them in the /lib folder and still nothing.
I downloaded this file: https://github.com/Boussetta/CryptoJS-v3.1.2
Which handles the functions in the code above but for the life of me I have not idea how to import it.
TIA
If you want to go for JavaScript - there are 2 options:
Use Rhino load() method like:
load("crypto.js")
Use HmacUtils class from Apache Commons Codec from JavaScript
var rawhmac = org.apache.commons.codec.digest.HmacUtils.hmacSha1(key,data)
var encoded = org.apache.commons.codec.binary.Base64.encodeBase64String(rawhmac)
However I would recommend going for option 3 - switch to "groovy" language instead of JavaScript, that way you will be able to:
Re-use Amazon authentication samples in your test
Get maximum performance and confidence as groovy scripts can be compiled while other languages are interpreted so groovy implementation will take less resources and will work faster. See Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For! article for more details.

How to execute a Javascript function in an HTML page, in a browser, from a Java class on my server?

<script type="text/javascript">
function start() {
window['progress'] = setInterval(function() {
var pbClient = PF('pbClient'),
oldValue = pbClient.getValue(),
newValue = oldValue + 10;
pbClient.setValue(pbClient.getValue() + 10);
if(newValue === 100) {
clearInterval(window['progress']);
}
}, 100);
}
</script>
I want to call this function in my Java class.Actually this problem is the progress bar is in dialog.And I want to go another xhtml page after progress bar
To call an external javascript functions you can use ScriptEngine.eval(java.io.Reader) and here is the documentation
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine Scr_engine = manager.getEngineByName("JavaScript");
// To read script file
engine.eval(Files.newBufferedReader(Paths.get("Full path of you JS file"), StandardCharsets.UTF_8));
Invocable invvoc = (Invocable) Scr_engine;
// To call the JS function from script file
invvoc .invokeFunction("yourFunctionName", "param");
You can't call Javascript functions, which run in the browser, from Java code which runs on your server. You need to send messages over the network for interaction between your server and the client. I would look into Server-Sent Events.
Rhino is what you are looking for.
Rhino is an open-source implementation of JavaScript written entirely in Java. It is typically embedded into Java applications to provide scripting to end users.
Look here : How can I use Javascript in Java?

Call Perl script from Thunderbird Javascript

I wrote a perl script that handles some data automatically. However, I face a problem when I try to call the script from my thunderbird extension that is naturally written in javascript.
var file = Components.classes["#mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath("/usr/bin/perl");
// create an nsIProcess
var process = Components.classes["#mozilla.org/process/util;1"]
.createInstance(Components.interfaces.nsIProcess);
process.init(file);
// Run the process.
// If first param is true, calling thread will be blocked until
// called process terminates.
// Params are used to pass command-line arguments
// to the process
var args = ["package/myperlscript.pl", "some arguments];
process.run(true, args, args.length);
I guess I have the perl script placed at the wrong location. I tried various ones, but I could not get it work. If that is my major mistake, where is the base path that the javascript file expects?

Meteor: wait until file is generated

I do a Meteor.call() synchronously (without callbacks), which downloads from a location and generates a file on the server successfully, and then Meteor.Router.to('/file/generated.just.now');
However, sometimes the file takes a few extra seconds to generate and I redirect to the file before it exists.
I've tried to use Futures and Fibers, but not sure if this can achieve blocking (wait until file is finished written);
if (Meteor.isServer) {
var request = Npm.require('request');
var fs = Npm.require('fs');
var Future = Npm.require('fibers/future'), wait = Future.wait;
Fiber = Npm.require('fibers');
var result = function(){
downloadAndSaveFile(content.pdf, filename).wait();
}.future();
function downloadAndSaveFile(fileUrl, fileName) {
var future = new Future;
request(fileUrl).pipe(fs.createWriteStream(getPath() + fileName)).on('closed', function(){
future.return();
});
return future;
}
}
Meteor's router .to function is client side only, used to invoke the routing callbacks. It doesn't tell the browser to physically redirect, only swap out the DOM to reflect the new page according to what the templates & your routes are.
If you want to redirect you should use
window.location = 'newurl';
Or a link that the user click's created from the .call callback.

Categories