Running multiple instances of selenium webdriver asynchronously (firefox) - javascript

How can I make my webdriver request multiple pages (or open multiple browsers) at the same time, concurrently?
All solutions I found on the internet waits until the previous session has finished loading and only then open a new instance of the browser.
I have tried selenium-webdriver, webdriverjs and wdjs, and none of them seem to be able to do multiple http requests for different pages asynchronously. Even solutions like this https://github.com/OniOni/wd-parallel-async wont work. They all open one at time.
Am I missing something?
PS: I don't want to run multiple browsers concurrently! I want to run multiple instances of the same browser.

Something like:
WebDriver driver1 = new FirefoxDriver();
WebDriver driver2 = new FirefoxDriver();
WebDriver driver3 = new FirefoxDriver();
driver1.get("page1");
driver2.get("page2");
driver3.get("page3");
If you need it truly asynchronous, then you will need to get into Java threading ... which would make this into a longer discussion and off-topic for SO.

Utilize threading. I see you have node.js tagged...I am not as familiar with that, but below is a c# example that works...similar theory should apply.
c#
Parallel.Invoke(
()=> { 1st test execution call },
()=> { 2nd test execution call },
()=> { 3rd test execution call }
);
Although be careful as the webdriver can sometimes get confused and overlap windows. I have found that doing more than 5 at a time on a single machine leads to miscellaneous problems. If you use the Parallel.Invoke in c# you can throttle this to only allow a certain number at a time...although Grid is the best way to do that as you setup your limits in configuration and then it load balances for you.

Related

How to call a function in WebView Javascript from Android Java without delay?

When using this method to call javascript functions there is a few millisecond delay (10ms - 50ms) in callback
webView.evaluateJavascript("javascript: updateARObject()", callback);
How to call a function instantaneously in javascript, all files are in asset folder of Android.
Is it possible with some custom WebView like Xwalkview?
Or socket connection between both?
ARCore is communicating with Three.js in real time, How to achieve that?
The reason the callback is present is because it cannot be done instantaneously from android app.
The main reason for that is that Android uses WebView to run javascript. Modern Android WebView is just an instance of Google Chrome wrapped in android view. As you understand this instance needs to be run on separate process as it does. If one chooses to dig deep he will find out that the communication between android app and WebView is done via AIDL service as all the interprocess communications should be done in android.
Taking into consideration the time needed to write an AIDL call into stack allocate memory and form message(main AIDL method of communication), send it, unwrap in Chrome, parse, execute javascript and do all this operations one more in order to answer - 10ms - 50ms is very low latency.
Maybe ArCore has its own its own js processor to handle js files fast. Or Google Chrome has its own method to communicate with ArCore(or inner instance). I don't know that - but it is Google developed products - I think they know their shortcuts.
Custom WebView may work - the only thing is that basically it will be a new version of browser you will need to support your js for it separately from all the other browsers due to a whole bunch of possible reasons.
Hope it helps you somehow.
From kitkat onwards use evaluateJavascript method instead loadUrl to call the javascript functions like below :
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript("enable();", null);
} else {
webView.loadUrl("javascript:enable();");
}
you can Use function call delay by setting :
window.setTimeout(function () { ... })
But ,It won't necessarily run right away, neither will explicitly setting the delay. If you will use setTimeout, it removes the function from the execution queue and it will only be invoked after JavaScript has finished with the current execution queue.
console.log(1);
setTimeout(function() {console.log(2)});
console.log(3);
console.log(4);
console.log(5);
//console logs 1,3,4,5,2
for more details see http://javascriptweblog.wordpress.com/2010/06/28/understanding-javascript-timers/
Hope, you'll find your answer. Cheers!

run series of test functions to appear as separate tests within browserstack

I have a series of functions like below, that thread through a web application that simulate login, and then runs through many features of the web app. I am using JS, nightwatch.js, and selenium via browserstack.. the problem is, it all reports through browser stack as one large test with this approach; how could I get each function to report within browserstack as separate test?
this.Settings = function(browser) {
browser
.url(Data.urls.settings)
.waitForElementVisible("div.status-editor .box", 1000)
Errors.checkForErrors(browser);
browser.end();
};
this.TeamPanel = function(browser) {
browser
Errors.checkForErrors(browser);
browser.end();
};
It seems you are using the same remote browser instance for all the test functions which therefore are being run as a single test case on BrowserStack. You need to create a new driver instance before every test function. You can either implement that parallelisation logic in your framework or use any sample nightwatch framework like the one here: https://github.com/browserstack/nightwatch-browserstack

Detect resource that hangs while loading with javascript

I have a bunch of functions that need to be called on $(window).on('load' ...). Occasionally, the site hangs indefinitely while loading. There are a bunch of embeds and other pieces of media being pulled in from various APIs.
Is it possible to detect what is still pending without attaching an event listener to every resource?
Edit for clarification:
#PamBlam's comment below was more tuned in to the problem -- I want to be able to do this with javascript, so it could happen client side while my users are browsing.
Specifically, I'd like to be able to identify pending requests and get any relevant details, and send a note to an error logger (such as sentry) to see what specific resources are problems for users on the live site. Perhaps the only solution would be to create a new loadResource function (as suggested in some answers) that compiles these details and, after a long timeout, sends a note to the logger if it still hasn't finished. But, this seems like overkill. Also some of these resources are <iframe>s that are included in the HTML, so more work to add that in.
What I was hoping for - and I'm guessing that this doesn't exist, as I assume javascript doesn't have permission to see what's happening on the browser level - was something that could, after a long time out, essentially look at the Network tab of dev tools and send a report of what is still pending.
One of the best ways to debug JavaScript is Chrome DevTools(while I am a big advocate of Firefox, in this case Chrome is just mind blowing). Use debug breakpoints and network to the best of your capabilities.
Appending the link for referral
https://developers.google.com/web/tools/chrome-devtools/
Count how many resources are loading, and decrement the count when each is finished. When the count is zero all resources are done.
var resourcesPending = 0;
// Load some resources
resourcesPending++;
loadAResource(function(){
resourcesPending--;
if(!resourcesPending) allResourcesLoaded();
});
resourcesPending++;
loadAResource(function(){
resourcesPending--;
if(!resourcesPending) allResourcesLoaded();
});
// etc..

Firefox ChromeWorker not loading script

I have a requirement where I need to communicate with native code to perform some operations. I have been successful by using JS-Ctypes and things are panning out as expected. Since the communication from my web application with the native code takes some time, thus blocking the main JS thread consequently freezing the UI.
Thus I need to create a separate thread to be delegated with the communication with the native code and post back results to the main thread which will give the appropriate feedback to the user. Firefox ChromeWorker are exactly what I need to use, since they are independent threads with access to JS-Ctypes.
My problem is that for the life of me, I can't seem to load a script using that approach. This is what I currently have:
main.js
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
Components.utils.import("resource://gre/modules/Services.jsm");
var worker = new ChromeWorker("js/fpman/myworker.js");
worker.onmessage = function(e){
console.log(e.data);
};
worker.postMessage('start');
myworker.js
self.onmessage = function(e){
var sum = 1 + 1;
postMessage("Sum is " + sum);
};
When that code runs in the main JS, I get this error on firebug console
Failed to load script: http://localhost:8080/myapp/js/fpman/myworker.js (nsresult = 0x805303f4)
Point to note, when I use a normal worker thread i.e
var worker = new Worker("js/fpman/myworker.js");
the js file (myworker.js) is loaded fine and I get the expected result, but of course that doesn't suffice my needs since a normal worker doesn't have access to JS-Ctypes. So it seems the problem is how am creating the ChromeWorker. Could someone please enlighten me on how to appropriately instantiate and use the ChromeWorker Object from an application. I have seen a lot of reference of usage of ChromeWorker in extensions, but that is not what I want, I want to use the ChromeWorker in my web application.
Thanks.
That particular error is NS_ERROR_DOM_BAD_URI
I don't believe what you are doing will work, and I know it won't work very soon in Firefox because enablePrivilege is going away completely.

Silverlight 4 MVVM: Call Javascript function from viewmodel

we have developed an Intranet Management Application with Silverlight 4. We have been asked to add the functionality to call a remote desktop tool which is installed on clients using the Intranet SL App. In an earlier version of the tool written in ASP.NET we just added a Javascript function to the aspx page like this:
function RunShellCommand()
{
var launcher = new ActiveXObject("WScript.Shell");
launcher.Run("mstsc.exe");
}
and called it from ASP.NET.
Now it's clear that SL4 is running in a sandbox and that I cant use the AutomationFactory to create a WScript.Shell object (out of browser mode is not an option).
I thought I could circle around the problem by, again, adding the RunShellCommand javascript method in the aspx page where the SL4 control is hosted and call it via
HtmlPage.RegisterScriptableObject("Page", this);
HtmlPage.Window.Invoke("RunShellCommand", "dummydata");
from my ViewModel. When I run the Application the debugger just skips the RegisterScriptableObject method and quits. Nothing happens.
My question is if am doing something wrong or if this just wont work this way.
Is it possible that I cant do a RegisterScriptableObject from a viewmodel?
EDIT: When I explicitly put a try, catch block around the two methods I get an ArgumentException from the first method stating that the current instance has no scriptable members. When I delete the first method and only run the Invoke, I get a browser error stating that the automation server cant create the object. So is there really no way (except OOB mode) to do this?
Yes, the explanation is correct: you should add at least one method with the ScriptableMember attribute in order that you can use the RegisterScriptableObjectmethod. But it is used only for calling C#-methods from JavaScript.
As far as I see, you want to do the opposite: to call JavaScript code from the Silverlight application. Then you need only one line:
HtmlPage.Window.Invoke("RunShellCommand");
The error automation server cant create the object has nothing to do with Silverlight. I'm sure that if you call the JS function directly - the error will remain.
According to the internet, the reason might be not installed Microsoft Windows Script. Or it is because of security restrictions of the browser.

Categories