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.
Related
I am trying to automate testing with Selenium Webdriver without the need of xpath. I'm facing problem when the site is modified then xpath is being changed. For elements(like buttons, drop downs etc) which needs some action to be performed any how it needs xpath or someother things to identify that element. If I want to fetch data(table contents) from site to validate its excecution,then here I will need lots of xpaths to do so.
Is there a better way to avoid some xpaths?
Instead of using xpath, you can map the elements by css selectors, like this:
driver.findElement(By.cssSelector("css selector"), OR
by ID, like this:
driver.findElement(By.id("coolestWidgetEvah")).
There are much more than these 2. See Selenium docomentation
Steven, you basically have 2 choices the way I see it. One is to inject your own attributes (i.e qa attrib for instance) into your web elements which will never change. Please see this post, on how you can achieve this:
Selenium: Can I set any of the attribute value of a WebElement in Selenium?
Alternatively you can still use 'naked' xpath in order to locate your elements.
By 'naked' i mean generic, so not so specific.
Consider this element sitting below this:
div id="username"
input class="usernameField"
button type='submit
So, instead of locating it like this (which is specific/aggresive):
//div[#id='username']//input[#class='usernameField']//button[#type='submit']
you can use a more mild approach, omitting the specific values, like so:
//div[#id]//input[#class]//button[#type]
Which is less likely to break upon change. However, beware you need to be 100% sure that with the 2nd approach you are locating a unique element. In other, words if there are more than 1 buttons you might select the wrong one or cause a Selenium exception.
I would recommend this Xpath helper add-on for Chrome which highlights on the screen when your xpath is correct and also shows you how many elements match you Xpath (i.e. unique or not?)
xpath Helper
Hope the above, makes sense, don't hesitate to ask if it does not!
Best of luck!
Ofcoarse there are certain other ways without using id/xpath/CSS and even "sendKeys". The solution is to do that via Sikuli.
Things to do:
You have to download the Sikuli exe jar (sikulixsetup-1.1.0). (from https://launchpad.net/sikuli/+download)
Install the Sikuli exe jar which extracts the "sikulixapi" and adds to the PATH variable.
Add the External jar "sikulixapi" at project level through Eclipse.
Now take images of the elements where you want to pass some text or click.
Use the reference of the images in Selenium Java code to write text & perform clicks.
Here is a simple code to browse to "https://www.google.co.in/" move on to Login page & enter Emailid & Password without any xpath or sendkeys.
package SikuliDemo;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.sikuli.script.Pattern;
import org.sikuli.script.Screen;
public class SikuliDemoScript {
public static void main(String[] args) throws Exception
{
Screen screen = new Screen();
Pattern image1 = new Pattern("C:\\Utility\\OP_Resources\\Sikuli_op_images\\gmailLogo.png");
Pattern image2 = new Pattern("C:\\Utility\\OP_Resources\\Sikuli_op_images\\gmailSignIn.png");
Pattern image3 = new Pattern("C:\\Utility\\OP_Resources\\Sikuli_op_images\\Email.png");
Pattern image4 = new Pattern("C:\\Utility\\OP_Resources\\Sikuli_op_images\\EmailNext.png");
Pattern image5 = new Pattern("C:\\Utility\\OP_Resources\\Sikuli_op_images\\Password.png");
Pattern image6 = new Pattern("C:\\Utility\\OP_Resources\\Sikuli_op_images\\SignIn.png");
System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://www.google.co.in/");
screen.wait(image1, 10);
screen.click(image1);
screen.wait(image2, 10);
screen.click(image2);
screen.type(image3, "selenium");
screen.click(image4);
screen.wait(image5, 10);
screen.type(image5, "admin123");
screen.click(image6);
driver.quit();
}
}
Let me know if this answers your question.
I am performing some test on a website, which is referring to a javascript array _gaq and it is not defined anywhere in the page. I can see the similar exception in Browser but there it is ignoring it. I set the method setThrowExceptionOnScriptError(false) but still it is throwing
com.gargoylesoftware.htmlunit.ScriptException: ReferenceError: "_gaq" is not defined.
Below is my code
WebClient wb = new WebClient(BrowserVersion.CHROME);
wb.getOptions().setThrowExceptionOnScriptError(false);
page = wb.getPage("http://www.axisbank.com/");
HtmlElement el = ((HtmlElement)(page.getByXPath("//*[#id=\"form1\"]/div[5]/div[2]/div[3]/div/div[5]/img").get(0)));
page = el.click();
el = ((HtmlElement)(page.getByXPath("//*[#id=\"ContentPlaceHolder1_btnLogin\"]").get(0)));
System.out.println(el.asText());
page = el.click();
Any suggestion how to solve this problem. I tried adding page.executeScript("var _gaq = []"), but still failing
Don't use HtmlUnit for pages with serious JavaScript. Its JavaScript engine simply not good enough.
Use Selenium instead.
I am automating UI flow using Webdriver and Java. Need help in the following:
Clicking a link, verifying the title, clicking browser back button - these steps are repeated for number of links in the content. I am using page object design and all the objects are in different class. My code is:
objectBase.clickLink1();
titleVeri(pageTitle1);
driver.navigate().back();
objectBase.clickLink2();
titleVeri(pageTitle2);
driver.navigate().back();
objectBase is the name of the object where I kept all my page objects. clickLink1 and clickLink2 are methods on page objects class which does clicking on links. titleVeri is utility method for verifying the title.
What I need is construct this inside loop as I have more this.
you could use a map for this, make a method clickLink(key) in objectBase
then do something like
Map<String,String> myMap = new TreeMap();
myMap.put("1",pageTitle1);
myMap.put("2",pageTitle2);
for(Map.Entry<String,String> entry : myMap.entrySet()){
objectBase.clickLink(entry.getKey());
titleVeri(entry.getValue());
driver.navigate().back();
}
What you are describing is not strictly possible. The reason is that you cannot have a pointer to a function.
However, you said that you are using the Page objects pattern. Rather than using the clickLink1() function, do you have a function that returns link1()? That way you could use a Map (like BevynQ said).
Map<WebElement, String> linksAndTitles = new HashMap();
linksAndTitles.put(page.getHomePageLink(), "Home");
linksAndTitles.put(page.getUserPageLink(), "Contact Details");
...and so on for each of the different links...
for (WebElement link: linksAndTitles.keySet()){
link.click();
titleVeri(linksAndTitles.get(link));
driver.navigate().back();
}
As a side note...if one of those links is the Logout link...that has to be tested seperatly.
Furthermore...I really don't recommend this test...it's likely just a waste of time. On each of your pages, in your isLoaded() function, you should test the title. That way, whenever you call page.get(), the title will be automatically tested, and it isn't part of your test.
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.
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%