HTMLUnit Wait For JS Issue - java

I'm using HTMLUnit in order to put text in a input box and then clicking on a link which is actually a JS call.
The problem comes up when I put text in an input , using inputBox.setValueAttribute("example input"); . In this case , after clicking the button the page does not change at all.
On the other hand , once I delete inputBox.setValueAttribute("example input"); and then click the button, the page content does change and includes an error for empty input.
Below is the code i've used in order to put text in the relevant input and then click the button.
public void addressToBlockPlot(){
WebClient client = new WebClient(BrowserVersion.FIREFOX_24);
client.getOptions().setThrowExceptionOnScriptError(false);
client.getOptions().setThrowExceptionOnScriptError(false);
client.setJavaScriptTimeout(10000);
client.getOptions().setJavaScriptEnabled(true);
client.setAjaxController(new NicelyResynchronizingAjaxController());
client.getOptions().setTimeout(10000);
try {
HtmlPage page = client.getPage("http://mapi.gov.il/Pages/LotAddressLocator.aspx");
HtmlInput inputBox = (HtmlInput)page.getHtmlElementById("AddressInput");
final HtmlAnchor a = (HtmlAnchor) page.getElementById("helkaSubmit");
inputBox.setValueAttribute("example input");
a.click();
client.waitForBackgroundJavaScript(2000);
HtmlPage page2= (HtmlPage) client.getCurrentWindow().getEnclosedPage();
System.out.println(page2.asXml());
} catch (Exception e) {
}
}
Any ideas for solving this issue ?
EDIT:
I've tried using inputBox.setValueAttribute(""); , which resulted in receiving the same error that I got when no input text was set at all.

I have almost similar issue, where JS take some time to load, I have solved this issue by setting wait and retries until page load successfully by adding a condition,
int input_length = page.getByXPath("//input").size();
int tries = 5;
while (tries > 0 && input_length < 12) {
tries--;
synchronized (page) {
page.wait(2000);
}
input_length = page.getByXPath("//input").size();
System.out.println("page loaded successfully");
}
here input_length determines that whether required page is loaded or not. you can use similar condition according to structure of your page.

Related

How to click button and delete input text with Selenium WebDriver

I'm able to navigate this page [here][1] and enter this website [here][2](TOKEN CREATED FOR EACH DEMO FOR THIS LINK)
I'm also able to extract the value from the round count using this xpath here #class,'coefficient'
I can locate the input element on the left hand side but only one text value is deleted. I want to delete all values and enter 50.
It also seems like I can locate the left hand side button because I'm not getting any exceptions or errors but the button is not clickable.
The below two lines:
firstInput.sendKeys(Keys.CONTROL + "a");
firstInput.sendKeys(Keys.DELETE);
is basically to clear the input field, since .clear() is not working as expected in this case, we'd have to do CTRL+a and then delete
A full code will look like this:
driver.manage().window().maximize();
driver.get("https://www.spribe.co/games/aviator");
WebDriverWait wait = new WebDriverWait(driver, 30);
try {
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(),' Got it')]"))).click();
}
catch(Exception e){
e.printStackTrace();
}
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(),'Play Demo ')]"))).click();
String originalWinHandle = driver.getWindowHandle();
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//span[contains(text(),'Yes')]"))).click();
List<String> allHandles = new ArrayList<String>(driver.getWindowHandles());
driver.switchTo().window(allHandles.get(1));
WebElement firstInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//label[text()='BET']/ancestor::div[contains(#class,'feature')]/descendant::input")));
firstInput.sendKeys(Keys.CONTROL + "a");
firstInput.sendKeys(Keys.DELETE);
firstInput.sendKeys("20");
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//label[text()='BET']/.."))).click();

Unable To Click Paypal Button Continue With Selenium

My code begins by signing me into PayPal, then signing into eBay and navigating to the pay fees page, then checking out with PayPal. The final "Continue" button I can't click/submit. I've tried by xpath, id and class. I even tried sending TAB 7x until the Continue button and then sending Enter but that didn't work.
I have found this discussion but I'm not sure how to make it work for me.
PayPal Sandbox checkout 'continue button' - Unable to locate element: - C# WebDriver
Here's a screenshot of the PayPal code and page I'm trying to do.
//Chrome WebDriver specific
System.setProperty("webdriver.chrome.driver", "C:\\automation\\drivers\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize(); //maximise webpage
WebDriverWait wait = new WebDriverWait(driver, 20);
//navigate to Paypal
driver.get("https://www.paypal.com/uk/signin");
//wait 2.5s for the page to load
try {
Thread.sleep(2500);
}
catch (Exception e) {
e.printStackTrace();
}
WebElement paypalEmail = driver.findElement(By.id("email"));
paypalEmail.sendKeys("******");
//wait 2.5s for the page to load
try {
Thread.sleep(2500);
}
catch (Exception e) {
e.printStackTrace();
}
WebElement paypalSubmit = driver.findElement(By.id("btnNext"));
paypalSubmit.click();
String URL = ("https://www.paypal.com/uk/signin");
driver.get(URL);
WebElement form2 = driver.findElement(By.cssSelector(".main form"));
WebElement username = form2.findElement(By.id("password"));
username.sendKeys("******");
WebElement paypalSubmit2 = driver.findElement(By.id("btnLogin"));
paypalSubmit2.click();
//navigate to Ebay
driver.get("https://signin.ebay.co.uk/ws/eBayISAPI.dll?SignIn&ru=https%3A%2F%2Fwww.ebay.com%2F");
// Enter user name , password and click on Signin button
WebElement form = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#mainCnt #SignInForm")));
form.findElement(By.cssSelector("input[type=text][placeholder='Email or username']")).sendKeys("******");
form.findElement(By.cssSelector("input[type=password]")).sendKeys("******");
form.findElement(By.id("sgnBt")).click();
driver.get("http://cgi3.ebay.co.uk/ws/eBayISAPI.dll?OneTimePayPalPayment");
//WebElement Pay =
driver.findElement(By.xpath("//input[#value='Pay']")).click();
WebDriverWait wait2 = new WebDriverWait(driver, 15);
wait2.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[#id=\"confirmButtonTop\"]")));
driver.findElement(By.xpath("//*[contains(#id,'confirmButtonTop')]")).click();
}
}
Based on your given screenshot one of following should work to click on continue button :
Method 1 :
WebElement paypalSubmit = driver.findElement(By.xpath("//input[#data-test-id='continueButton']"));
paypalSubmit.click();
Method 2:
By paypalButton=By.xpath("//input[#data-test-id='continueButton']"));
WebElement element=driver.findElement(paypalButton);
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].scrollIntoView(true);",element);
js.executeScript("arguments[0].click();", element);
Try 2nd method if you feel your button require bit scroll to bottom to get clickable.
one more xpaths you can use for button if above don't work :
//input[#value='Continue' and #id='confirmButtonTop']
In my experience, paypal likes to use iFrames. If that's true in your case, that means unless you tell webdriver to switch frame contexts, that paypal form will be unavailable to you regardless of your xpath/css selectors.
You can get a list of all available frames currently loaded with this code:
String[] handles = driver.getWindowHandles()
Your actual page will always be the 0th index in that returned array. If paypal is your only iFrame, then you can target the 1th index. Here's a possible solution to that:
String mainPageHandle = handles[0];
String paypalHandle = handles[1];
driver.switchTo().window(paypalHandle);
// Do paypal interactions
driver.switchTo().window(mainPageHandle);
// Back to the main page
There are definitely more robust ways to handle this, and if your page unfortunately has more than one iFrame, then you may need to do more to verify which handle is which, such as test the presence of an element you know is contained within. In general, the frames will load in the same order every time. As a golden path to this problem, this will get you in and out of that iFrame to perform work.
Sometimes the conventional click() doesn't work. In that case, try using the Javascript Executor Click as below.
Make sure you import this class
org.openqa.selenium.JavascriptExecutor
And use this instead of click();
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", driver.findElement(By.xpath(“//input[#data-test-id='continueButton']”)));
Try this and let me know if this works for you.

How to call post method after setting the value of the form for screen scraping using java

Background : I have a webpage (.aspx) which have few dropdown lists.The list value is getting populated using Ajax call based on the selection of previous dropdown. After selecting the value of all drop down lists we can click on download button and the data will be downloaded based on the downloaded data we need to perform some other operations.
what i already did: I am able to set the drop down data via calling the ajax correctly but sending a post request is a problem. Here is the code snippet/pseudo Code.
Feel free to use any tool along with java
public static void main(String[] args) throws FailingHttpStatusCodeException, IOException {
final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_17);
WebRequest request = new WebRequest(new URL(DataDownloader.MY_URL),HttpMethod.POST);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.setJavaScriptTimeout(10000);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
webClient.getOptions().setTimeout(10000);
HtmlPage page = webClient.getPage(request);
HtmlSelect firstDd = (HtmlSelect) page.getElementById("dd1_id");
List<HtmlOption> firstOption = firstDd.getOptions();
firstDd.setSelectedAttribute(firstOption.get(2), true);
webClient.waitForBackgroundJavaScript(3000);
HtmlPage pgAfterFirstDd = (HtmlPage) webClient.getCurrentWindow().getEnclosedPage();
HtmlSelect secondDd = (HtmlSelect) pgAfterFirstDd.getElementById("dd2_id");
List<HtmlOption> secondOption = secondDd.getOptions();
secondDd.setSelectedAttribute(secondOption.get(2), true);
webClient.waitForBackgroundJavaScript(10000);
//set the value for all other dropdowns
HtmlPage finalpage = (HtmlPage) webClient.getCurrentWindow().getEnclosedPage();
HtmlForm form = finalpage.getHtmlElementById("aspnetForm");
webClient.waitForBackgroundJavaScript(10000);
request.setRequestBody("REQUESTBODY");
Page redirectPage = webClient.getPage(request);
// HtmlSubmitInput submitInput=form.getInputByName("btnSubmit");
// submitInput.click();
/*HtmlButton submitButton = (HtmlButton) pageAfterWard.createElement("btnSubmit");
submitButton.setAttribute("type", "submit");
form.appendChild(submitButton);
HtmlPage nextPage = (HtmlPage) submitButton.click();*/
}
Why you hide your error details? Is there any secret? If you like helpful answers you have to provide as many information as possible.
So i do a wild guess...
submitInput.click();
will return a PDF. In this case you have to do something like
Page pdfPage = submitInput.click();
WebResponse resp = pdfPage.getWebResponse();
if("application/pdf".equals(resp.getContentType())) {
.... process the bytes
.... resp.getContentAsStream()
}
HtmlUnit has four kind of pages HtmlPage/XmlPage/TextPage and UnexpectedPage. Binary content like PDF or office documents are handled as UnexpectedPage. Processing this content is up to you.
as you mentioned in the comment under RBRi's Answer that you were getting the typecast error.can you please mention
what the exact error you were getting
what type of file/response you were expecting.
Because the code looks good to me and it should work perfectly..
final WebClient webClient = new WebClient(BrowserVersion.FIREFOX_17);
Looks like you are using an old version, please use the latest one.
WebRequest request = new WebRequest(new URL(DataDownloader.MY_URL),HttpMethod.POST);
With HtmlUnit you usually do not work with requests. The idea is to work more 'browser like'. Use something like getPage(final URL url).
List<HtmlOption> firstOption = firstDd.getOptions();
firstDd.setSelectedAttribute(firstOption.get(2), true);
Do your work more 'browser like'
firstOption.get(2)setSelected(true);
This will do all the background work for you like deselection the other options and event processing for you.
Regarding submitting the form your idea of
HtmlSubmitInput submitInput=form.getInputByName("btnSubmit");
HtmlPage nextPage = submitInput.click();
looks correct. Maybe your have to wait after that also.
If you still have problems you have to provide the URL you are working with to enable us to reproduce/debug your case.

Not able to extract password field in a modal window using CSS selector - Selenium Java

I am able to click on sign in link in the start page [a link] http://imgur.com , resulting modal window of username and password field. while I was trying to extract password field on the resulted page, found no elements of username and password fields. Even I checked the source code at that instant using driver.getPageSource(); and there is no sign of username or password elements. Following is the code used to extract password field from the specified URL.
pwd = driver.findElement(By.cssSelector("input[type='password']"));
code for clicking the modal window is
driver.findElement(By.partialLinkText("sign in")).click();
Later I found that they are using iframes so I started searching the password fields in each iframe as shown below.
List<WebElement> iFrames = null;
WebElement iFramePwd=null;
iFrames = driver.findElements(By.tagName("iframe"));
if (iFrames.size() > 0) {
for (int l = 0; l < iFrames.size(); l++) {
try{ driver.switchTo().frame(l);
}
catch(NoSuchFrameException ljn){
System.out.println(ljn);
driver.switchTo().defaultContent();
continue;
}
try {
try{
iFramePwd = driver.findElement(By.cssSelector("input[type='password']"));
}
catch(NoSuchElementException lkn){
System.out.println(lkn);
driver.switchTo().defaultContent();
continue;
}
Size of iframes displaying as 5 but when i try to switch to the iFrame iam always getting NoSuchFrameException.
Please visit the specified URL for analyzing the source code. I dont know where i am missing the point. Is there any way to get password field from the modal window. Any help would be greatly appreciated. Thanks in advance
Try this code
WebDriver driver = new FirefoxDriver();
driver.get("http://imgur.com/");
driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.findElement(By.partialLinkText("sign in")).click();
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.className("cboxIframe")));
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("f")));
driver.findElement(By.name("username")).sendKeys("abcd");
driver.findElement(By.xpath(".//*[#id='password']/input")).sendKeys("abcd");
driver.close();
driver.quit();
If we use loop to reach the iframe, there is a problem. You don't know which ifrmae you are in because List of web elements does not grantee the exact sequence of iframe in page. For Example below code is not working and showing error "Element belongs to a different frame than the current one - switch to its containing frame to use it"
List<WebElement> my_iframes = driver.findElements(By.tagName("iframe"));
// moving to inner iframe
if(my_iframes.size() > 0){
for(WebElement my_iframe : my_iframes){
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(my_iframe));
}
}
driver.findElement(By.name("username")).sendKeys("abcd");
driver.findElement(By.xpath(".//*[#id='password']/input")).sendKeys("abcd");

Read alerts in HTML unit

I am working on HTML unit with Java to read HTML pages. I have a scenario where I have to read messages from the popup/ alert window. I have an index page page = form.getInputByName("index").click();
After I click on the index page I get the response page. But before that I get an alert some thing like
I want to read the above message and then proceed with ok.
I tried with alert handlers like `
ConfirmHandler okHandler = new ConfirmHandler(){
#Override
public boolean handleConfirm(Page page, String message) {
System.out.println(">>>>>>>>>>>>>>>>>>> message--"+message);
return true;
}
};
webClient.setConfirmHandler(okHandler);`
But this is not working for me.
You should be using the CollectingAlertHandler instead:
CollectingAlertHandler alertHandler = new CollectingAlertHandler();
webClient.setAlertHandler(alertHandler);
/*Your browsing codes here*/
List<String> alertmsgs = new ArrayList<String>();
alertmsgs = alertHandler.getCollectedAlerts();
Then you can use the message obtained as you want. Reminder: You do not need to click the OK button.

Categories