How to execute random Javascript code on a web page? - java

I'm using htmlunit to test some pages and I'd like to know how can I execute some javascript code in the context of the current page. I'm aware that the docs say I'd better emulate the behavior of a user on a page, but it isn't working this way :( (I have a div which has an onclick property, I call its click method but nothing happens). So I've made some googling and tried:
JavaScriptEngine jse = webClient.getJavaScriptEngine();
jse.execute(page, what here?);
Seems like I have to instantiate the script first, but I've found no info on how to do it (right). Could someone share a code snippet showing how to make webclient instance execute the needed code?

You need to call executeJavaScript() on the page, not on webClient.
Example:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_3);
webClient.setJavaScriptEnabled(true);
HtmlPage page = webClient.getPage("http://www.google.com/ncr");
ScriptResult scriptResult = page.executeJavaScript("document.title");
System.out.println(scriptResult.getJavaScriptResult());
prints "Google". (I'm sure you'll have some more exciting code to put in there.)

I don't know the JavaScriptEngine you're quoting and maybe it's not the answer you want, but this sounds like a perfect case for Selenium IDE.
Selenium IDE is a Firefox add-on that records clicks, typing, and other actions to make a test, which you can play back in the browser.

In TestPlan using the HTMLUnit backend the google example is:
GotoURL http://www.google.com/ncr
set %Title% as evalJavaScript document.title
Notice %Title%

Related

HtmlUnit to take snapshot of Ajax applications

I create a basic GWT (Google Web Toolkit) Ajax application, and now I'm trying to create snapshots to the crawlers read the page.
I create a Servlet to response the crawlers, using HtmlUnit.
My application runs perfectly when I'm on a browser. But when in HtmlUnit, it throws a lot of errors about the special chars I have in the HTML. But these chars are content, and I wouldn't like to replace it with the special codes, once it's currently working, just because of the HtmlUnit. (at least I should check before if I'm using HtmlUnit correctly )
I think HtmlUnit should read the charset information of the page and render it as a browser, once it's the objective of the project I think.
I haven't found good information about this problem. Is this an HtmlUnit limitation? Do I need to change all the content of my website to use this java library to take snapshots?
Here's my code:
if ((queryString != null) && (queryString.contains("_escaped_fragment_"))) {
// ok its the crawler
// rewrite the URL back to the original #! version
// remember to unescape any %XX characters
url = URLDecoder.decode(url, "UTF-8");
String ajaxURL = url.replace("?_escaped_fragment_=", "#!");
final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_24);
HtmlPage page = webClient.getPage(ajaxURL);
// important! Give the headless browser enough time to execute JavaScript
// The exact time to wait may depend on your application.
webClient.waitForBackgroundJavaScript(3000);
// return the snapshot
response.getWriter().write(page.asXml());
The problem was XML confliting with the HTML. #ColinAlworth comments helped me.
I followed Google example, and there was not working.
To it work, you need to remove XML tags and let just the HTML be responded, changing the line:
// return the snapshot
response.getWriter().write(page.asXml());
to
response.getWriter().write(page.asXml().replaceFirst("<\\?.*>",""));
Now it's rendering.
But although it is being rendered, the CSS is ot working, and the DOM is not updated (GWT updates page title when page opens). HTMLUnit throwed a lot of errors about CSS, and I'm using twitter bootstrap without any changes. Apparently, HtmlUnit project have a lot of bugs, good for small tests, but not to parse complex (or even simple) HTMLs.

Java. HtmlUnitDriver. Drop down Window issue

I'm using HtmlUnit in Java to deal with a DropDown Window (Java).
I tried as User skaffman suggests:
WebDriver driver = new HtmlUnitDriver();
driver.get("https://...");
......................
WebClient client = new Webclient();
Page page = client.getPage("https://...");
HtmlSelect select = (HtmlSelect) page.getElementById(mySelectId);
HtmlOption option = select.getOptionByValue(desiredOptionValue);
select.setSelectedAttribute(option, true);
It does not recognize: getElementById. Eclipse recommends to swith to findElement(By.id(" ")) PLEASE HELP
I agree with my college. The above code is correct, make sure you set javascript enabled, otherwise you will have issues with HtmlUnit
driver = new HtmlUnitDriver();
((HtmlUnitDriver) driver).setJavascriptEnabled(true);
In your code, you are declaring the local variable to be of the type Page that will contain the return value from client.getPage("https://...");
Although it's usually good practice to develop toward the generic interface (in this case, Page), the generic interface does not contain the method to getElementById(...).
Try changing your 4th line of code to the following:
HtmlPage page = client.getPage("https://...");
(I am assuming that the conent being returned by client.getPage("https://..."); is of MimeType text/html).
You could also use XmlPage or XhtmlPage, depending on your MimeType.
If it is none of these that you are retrieving via client.getPage("https://...");, then you should not be attempting to call getElementById on a structure that does not have this as part of its API.

Manipulate JavaScript using Java

I'm connecting to a webserver with a specific JavaScript. (Using HttpURLConnection atm)
What i need is a connection that makes it possible to manipulate a JavaScript function.
Afterwards i want to run the whole JavaScript again.
I want the following function always to return "new FlashSocketBackend()"
function createBackend() {
if (flashSocketsWork) {
return new FlashSocketBackend()
} else {
return new COMETBackend()
}
}
Do i have to use HtmlUnit for this?
Whats the easiest way to connect, manipulate and re-run the script?
Thanks.
With HtmlUnit you indeed can do it.
Even though you can not manipulate an existing JS function, you can however execute what JavaScript code you wish on an existing page.
Example:
WebClient htmlunit = new WebClient();
HtmlPage page = htmlunit.getPage("http://www.google.com");
page = page.executeJavaScript("<JS code here>").getNewPage();
//manipulate the JS code and re-excute
page = page.executeJavaScript("<manipulated JS code here>").getNewPage();
//manipulate the JS code and re-excute
page = page.executeJavaScript("<manipulated JS code here>").getNewPage();
more:
http://www.aviyehuda.com/2011/05/htmlunit-a-quick-introduction/
Your best shot is probably to use Rhino — an open-source implementation of JavaScript written entirely in Java. Loading your page with a window.location and hopefully running your JavaScript function. I read sometime before Bringing the Browser to the Server and seemed possible.

:first / :first-child doesn't seem to work with Selenium 2

While migrating from Selenium 1 to Selenium 2 I am running into a problem.
I have the structural equivalent of the following:
<ul id="documentType">
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
Previously I would in Selenium 1 use the following css selector to find the first anchor link:
#documentType li:first-child a
This would work great, however, when I switch to selenium 2 and try and use the equivalent I get element not found. The following does work but is less precise then I would like.
#documentType li a
I have tried but could not get to work the following:
#documentType li:first a
For greater detail I'm using HtmlUnitDriver with the following code:
driver.findElementByCssSelector("#documentType li a");
Any help on getting the equivalent of the original selector working I would greatly appreciate it!
I be confused :)
EDIT: Phill Sacre brought up a good point on the fact I'm directly using HtmlUnitDriver which could be the source of the problem since it's a pure java implementation. I do this specifically for the ability to deal with a nasty Ajax problem of how to know when Ajax is done running. You can do this with the following code:
protected void waitForAjaxToComplete() {
long result = jQueryActive();
while (result != 0) {
result = (Long) driver.executeScript("return jQuery.active;");
}
}
This is obviously advantageous over using the technique of waiting for an element to appear which can be very inaccurate. I wish WebDriver would expose the executeScript method which would resolve this problem.
Further I noted that by default HtmlUnitDriver does use a java based implementation to parse the css selector supplied and I'm guessing this is the source of the problem. The parser is com.steadystate.css.parser.SACParserCSS21.SACParserCSS21 which may not properly take into account the :first and :first-child qualifiers.
What seems to make this ok is that the behavior of HtmlUnitDriver seems to return the first element by default. It's sister method findElementsByCssSelector seems to return an ordered list.
As a result while this appears to be a bug I may have answered my own question by learning how HtmlUnitDriver operates.
Which browser were you doing your Selenium 1 testing on? Looking in the Selenium documentation, the HtmlUnit driver is a pure-Java solution (i.e. it doesn't run in a browser, obviously).
Now I think there are some differences in selectors between browsers, so if you were using the Firefox browser before it may be worth using the FirefoxDriver to run your Selenium 2 tests?
Similar to Phill's answer- HtmlUnit parser the page differently than FF. I would start the debugging process by running the same test using the FF driver and see if it passes there. If it does pass, then the next step I would do is get the HTML from the HtmlUnit driver (I guess the command would be driver.getPageHtml() or something similar). I would compare that html with the html you get when you look at the html through a real browser (FF, chrome,..). Sometimes you see that tags have been put in by the real browser (i.e., by its parser) or by the HtmlUnit browser. You can either correct your selector or use a different driver (or go tell the developers to fix their html because that what usually causes these problems :-)
I had the same problem with this selector (using Spock/Geb). This has been resolved in the new version of Geb which is 0.9.2 (which has the changes to the HTML unit driver too). Now $('tr:first-child a') works fine with HTMLUnitDriver
I can provide the following CSS Selectors
1. css=#documentType > li > a -- First Link
2. css=#documentType > li+li > a -- Second Link
3. css=#documentType > li+li+li > a -- Third Link
else, you can try
1.css=#documentType > li:nth-child(2) > a -- Second Link
2.css=#documentType > li:nth-child(3) > a -- Third Link

How do I overwrite the URL in an IE address bar using RFT?

I need to execute the following steps:
1. Start an IE browser window and open a URL (Done using StartBrowser(final string URL)
2. Start a session (done by logging in)
3. Now, I want to enter a different URL in the same browser window which has the same session.
My question is related to Step 3. How can I overwrite the URL in the existing IE window.
Note: I am using a keyword driven framework written in java.
From the IBM RFT online help: You can use the loadURL() method of the browser object.
If you do not have the browser object already 'learned' into your object map, just record a click on the browser toolbar. Then you can modify that line to be Browser_htmlBrowser().loadURL("http://stackoverflow.com");
Thanks Tom. I agree that loadURL has the implementation to do what I need.
There is one more aspect that may interest others looking at this question, i.e. the way the appropriate browser object is captured. Obviously the easist way is to use the RFT record and click way, and use the appropriate recognition properties or the other way is to implement it is find the existing browseron the fly when the method is called irrespective of recognistion properties etc which may be more useful for some scenarios or frameworks, like it is done below.
RootTestObject root = getRootTestObject();
TestObject[] testobj = root.find(atDescendant(".class", "Html.HtmlBrowser"));
BrowserTestObject bto;
bto = new BrowserTestObject(testobj[0]);
bto.loadUrl(curParamOne);

Categories

Resources