HtmlUnit stops JavaScript execution after a window.open - java

I've recently updated from HTMLUnit 2.4 to 2.5 (we'd go for the latest version but there is a lot of code to refactor due to the deprecated APIs). I'm now having a problem with some JavaScript that opens a window.
The page under test, is a 'Please wait while loading screen' for reports. The page opens a new window then redirects back to page that originally launched the print.
So the JavaScript looks something like:
window.open(url,'report_window');
document.location.href = original_url;
With HtmlUnit 2.4 the script would continue executing and if I grabbed the original Window object it would have performed the redirect. However, after upgrading to HtmlUnit 2.5, the original window is still on the 'Please wait' page - the redirect is never executed. It appears as though the JavaScript stopped executing after the call to window.open.
I have confirmed the page behaves correctly if I test manually. I've also tried different JavaScript after the window.open call to confirm that that particular call is not the issue.
Is anyone aware of an issue like this and any potential workarounds? We have to stay on HtmlUnit 2.5 because of jQuery compatibility.

I was able to fix this issue by removing the CurrentWindowTracker object from the web window listeners on the WebClient object. Unfortunately, this field is completely encapsulated, so I had to retrieve it via reflection.
Field windowListeners = WebClient.class
.getDeclaredField("webWindowListeners_");
windowListeners.setAccessible(true);
Collection webWindowListeners = (Collection) windowListeners
.get(webClient);
webWindowListeners.clear();

Related

HtmlUnit with Knockout JS

I am trying to automate a login page which appears to be using Knockout.js.
HtmlUnit doesnt seem to load the full page, it is missing all the input fields which makes it impossible to actually login.
I have tried ensuring that the JavaScript timeouts are set and have also enabled NicelyResynchronizingAjaxController I am waiting after the page has loaded using:
waitForBackgroundJavaScript,
waitForBackgroundJavaScriptStartingBefore
Thread.sleep (just for
good measure)
I have even checked for additional windows (WebClient.getWebWindows), but there just seems to be the one.
It appears Knockout (assuming it is actually Knockout) is creating the inputs, is this just too much for htmlunit or have I missed something?
This is a know problem (see https://github.com/HtmlUnit/htmlunit/issues/37).
Hopefully i will find some time to figure out what is going wrong here.

Catch JavaScript Errors in Selenium WebDriver – Browser Independent

I am wondering if anyone could expand on any of these attempts or has any other ideas for catching JS errors using WebDriver that will work in Firefox, Chrome, Internet Explorer, and Safari.
Here is what's been tried so far:
Attempt – Problem:
JSErrorCollector.jar - Works fine, but is a Firefox only solution.
Inject JS into page source – I injected window.onerror code into the page’s source code using WebDriver, but any initial errors are missed because the injection is too late.
BrowserMob – I can intercept the HTTP response and planned to inject the window.onerror code into response body, but the author has not implemented the getBody() method yet, so only headers can be modified, that I am aware of. The body is always null for all responses. (I was on a webpage where the author talked about implementing getBody() but it hasn’t happened yet and I cannot find it again)
Fiddler – JS will inject correctly, but Fiddler is Windows only so Safari won’t work.
Parent/Child windows – I use javascript to open and store a reference to the test page’s window. The window.onerror code is contained in the parent window so it will not miss startup errors in the child window. I cannot get this to work in anything but Firefox and Chome somewhat. I already asked a question about it here.
Selenium RC – I haven’t tried it because all my tests use WebDriver, but I know it has some kind of method like captureNetworkTraffic(), but I don’t think it can be used in WebDriver.
IE error popup – I was going to use the parent/child solution for Firefox/Chrome and then look for the IE error popup. This popup displays when the setting is checked to display it. The popup is a native Window window (I think) so I cannot use selenium to access it.
Read browser console – I could not find a way to do this in all browsers. In Chrome I found a way to save the console log to a file and then read the file. That is as far as I got.
I would like a solution similar to BrowserMob since it seems like it would be a cross browser solution. Are there any other proxies that can be put in the test and intercept the response? It would have been excellent if the getBody() method was implemented. I also like the parent/child solution because it also seems like a simple, cross browser solution, but it is not working for IE (parent/child question again).
Thanks for any help.
I don't know of any way to directly catch Javascript code errors by a test framework. If I were to guess, I would use PhantomJS. Or, maybe something like MITM Proxy would work?
As a sidenote, if you run Selenium2 Grid Hub with a separate Node, you can pass a Java option to the JVM of the node like this that will allow a proxy through Fiddler to work. Fiddler listens (by default) on port 8888. With this method you can watch packets.
:: batch script: Set JAVA_OPTS java options to JVM
SET "JAVA_OPTS=-Dwebdriver.chrome.^
driver=%CHROMEDRIVER%"
IF "%PROXY_TO_FIDDLER%"=="true" SET "JAVA_OPTS=%JAVA_OPTS% -DproxySet=true^
-Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=8888"
I created scripts you can use to start your grid and node here. It seems to me that you could use this method to also talk to BrowserMob proxy on port 8080? I have not tried that.

Html Unit not being able to find content created by JS

I am using the JQuery UI datepicker plugin to dynamically change some page content. I get HtmlUnit to click on the text input, which should make the datepicker popup appear. However when I call driver.findElement(By.id("ui-datepicker-month")) I get an exception - it seems anything which is newly added to the DOM by JS does not become visible to HtmlUnit.
I'm not sure if there is any way around this, but it is worth noting when I use Chromedriver I don't have this problem - I am able to find the new elements. Also the getSource() method only ever returns the original source code with HtmlUnit whereas with Chromedriver it returns the updated source.
Is there any way to support the JS using Html Unit?

Kill Java Applet via Javascript

I am working for a developing firm and am doing a major redesign on a Web Application, which reloaded everything after each click, to make extensive use of Javascript, so it actually feels like a real Web application. One of the Features is to use a web-based Painter (think of MSPaint on the Web), which I embed on the Page on Demand. After the image is painted and uploaded, the Web-app then unloads the applet and proceeds to show the directory where the file was uploaded to.
This is where Trouble starts. It all works on IE and Safari, but not on Firefox 3.5 (3.0 works perfectly though). Firebug tells me that the expando property is missing.
The Web-app Tiparlo which I was working on before had a similar Problem (in fact, any manipulation done on an applet via jQuery is faulty) but solved that Problem by wrapping a div around and controlling (hide and show) the div instead of the applet. This, unfortunately isn't applicable on this Web-app, because the Applet has to be destroyed and not just hidden and shown, as it takes up too much resources to be run the entire time where it is not needed.
To make it short: Is it possible to make an Applet destroy itself via Javascript? Alternatively: Is there a workaround on the jQuery/expando/applet problem? I know that applet is deprecated in HTML 4.01 strict but changing it to object is not an option right now.
EDIT: I have added a Picture of Firefox + Firebug to show you the actual Error Message. Posting Code does no god, since it works flawless on every other Browser and is a Firefox 3.5 specific Problem. Here be pictures
Note: You can ignore the JS Bug coming from button.js.
You could always load the applet in a an iframe and just navigate away from the page where the applet is loaded. This will kill it.
Your other option if you want to call the destroy from javascript would be to put something like this in.
<script>
document.MyApplet.killApplet();
</script>
public void killApplet() {
AccessController.doPrivileged(new PrivilegedAction() {
public Void run() {
// kill the JVM System.exit(0); return null;
}
});
}
This is not a nice way to kill an applet but on newer browsers it does not throw a JS error, on older ones like IE6 it will throw a js error.
I would suggest that you create a class that monitors the applet to be killed. run the monitor as some sort of servlet and get javascript to post 'kill applet' commands when it needs to be killed.

How to solve refreshing issues in Facelets and Spring Web Flow?

For my particular project, I'm using Facelets (1.1.14), MyFaces (1.2.3), and Spring Web Flow (2.0.3). My IDE is JDeveloper 10.1.3.3. My browser is IE6 (work requirement).
Okay...ran into a very weird issue today. Normally, when I'm using Facelets, I can make whatever changes I want to my xhtml file, refresh my browser window, and see the changes immediately. I've got Facelets development set to true, and Facelets refresh period set to 1.
Up to this afternoon, I've had no problem with Facelets refreshes on this project. However, just this afternoon, I starting finding that changes to css styles and classes did not appear when I refreshed the page. Then I started seeing similar issues with other page elements. In some cases the changes never appear. At other times, I can refresh the page after a little while has passed and the changes have been reflected.
What happened to my Facelets page refreshes? It's like they've gone all sticky. I'm used to immediate changes on page refresh without complications. Has anyone run into this before? Any solutions or suggestions?
EDIT
The issue has something to do with Spring Web Flow. One of my pages is pure Facelets, and it's reflecting changes on refresh immediately. My other xhtml pages are invoked as view states in my flow definitions, and show the symptoms described above. Still, they were working fine just a day or two ago...
EDIT
Ok, I've been able to isolate the symptom, but I still don't know its cause.
It seems that whenever I have a facelets xhtml file that is rendered as a view-state of a flow and has an h:form element, then I get odd behavior when I make changes to the JSF elements on my page and refresh my browser. This includes not showing changes in their styles or style classes.
Changes to regular HTML elements (like changing the style of an input element) seem to work fine. Changing the h:form to a regular HTML form allow for immediate changes on page refresh, even on JSF elements. When I view the page when I'm not executing a flow (just using Facelets), then I never encounter any problems, even when using an h:form.
Please tell me someone has encountered this before, and has some solution. Anyone?
If you have entry of facelets.REFRESH_PERIOD -1 in your web.xml , this is causing the problem. Just cross check it by removing this entry.
I'm not sure if this applies to Web Flow, but I do know that with Spring MVC, you have an option of having your controller implement the LastModified interface, which allows Spring to send the browser the "Last-Modified" HTTP header.
Servlets typically don't set this HTTP header value, causing browsers to request a new copy of the files each time, however, if the "Last-Modified" header is set, browsers know not to retrieve the contents of a URL if it hasn't been modified since the page was last retrieved.
I suspect your Web Flow "controller" (pardon my abuse of terminology, I'm not familiar with Web Flow) is setting the "Last-Modified" header, while your regular Facelets page is not.
For what it's worth, I think setting Last-Modified is generally a good idea, unless your page is dynamic.

Categories