Problem in HtmlUnit API for Java (Headless Browser)? - java

I am using HtmlUnit headless browser to browse this webpage (you can see the webpage to have a better understanding of the problem).
I have set the select's value to "1"
by the following commands
final WebClient webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER_7);
try {
// Configuring the webClient
webClient.setJavaScriptEnabled(true);
webClient.setThrowExceptionOnScriptError(false);
webClient.setCssEnabled(true);
webClient.setUseInsecureSSL(true);
webClient.setRedirectEnabled(true);
webClient.setActiveXNative(true);
webClient.setAppletEnabled(true);
webClient.setPrintContentOnFailingStatusCode(true);
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
// Adding listeners
webClient.addWebWindowListener(new com.gargoylesoftware.htmlunit.WebWindowListener() {
public void webWindowOpened(WebWindowEvent event) {
numberOfWebWindowOpened++;
System.out.println("Number of opened WebWindow: " + numberOfWebWindowOpened);
}
public void webWindowContentChanged(WebWindowEvent event) {
}
public void webWindowClosed(WebWindowEvent event) {
numberOfWebWindowClosed++;
System.out.println("Number of closed WebWindow: " + numberOfWebWindowClosed);
}
});
webClient.setWebConnection(new HttpWebConnection(webClient) {
public WebResponse getResponse(WebRequestSettings settings) throws IOException {
System.out.println(settings.getUrl());
return super.getResponse(settings);
}
});
CookieManager cm = new CookieManager();
webClient.setCookieManager(cm);
HtmlPage page = webClient.getPage("http://www.ticketmaster.com/event/0B004354D90759FD?artistid=1073053&majorcatid=10002&minorcatid=207");
HtmlSelect select = (HtmlSelect) page.getElementById("quantity_select");
select.setSelectedAttribute("1", true);
and then clicked on the following button
by the following commands
HtmlButtonInput button = (HtmlButtonInput) page.getElementById("find_tickets_button");
HtmlPage captchaPage = button.click();
Thread.sleep(60*1000);
System.out.println("======captcha page=======");
System.out.println(captchaPage.asXml());
but even after clicking on the button and waiting for 60 seconds through the Thread.sleep() method, I am getting the same HtmlPage.
But when I do the same thing through real browser then I get the page that contains CAPTCHA.
I think I am missing something in the htmlunit.
Q1. Why am I not getting the same page (that contains CAPTCHA) through htmlunit's browser?

The web form on that page requires the quantity_select drop-down to be filled in. You're attempting to do that in your code by assuming the drop-down is a select element. However, it's no longer a select element. Try using Firebug to inspect the drop-down and you'll see that JavaScript has replaced the select with a complex set of nested div elements.
If you figure out how to emulate each user click on the divs for that unusual drop-down then you should be able to submit the form.

Related

HtmlUnit wait for redirect

I'm having following scenario I need to implement in HtmlUnit:
-I click button
-Im getting redirected to page www.page.pl/result
-I need to wait few seconds and then I'm getting redirected to www.anotherpage.pl/auth_code=qwe123
The problem is, once I'm getting to /result page, I can't get out of it to next one. There are no manual actions there, I just need to wait until redirect happens
Here is my WebClient
private WebClient initWebClient() {
WebClient webClient = new WebClient();
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setUseInsecureSSL(true);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.getOptions().setRedirectEnabled(true);
return webClient;
}
And how I'm trying to accomplish this, I'v tried several ways, including Thread.sleep() already...
HtmlPage page = webClient.getPage(url);
page.getForms().get(0).getButtonByName("submit").click(); // Redirects me to /result
webClient.waitForBackgroundJavaScript(5000);
webClient.waitForBackgroundJavaScriptStartingBefore(5000);
Thread.sleep(5000);
page.refresh(); //I'm still on /result, while I need to be on completely new page by now
In case anyone else have similar issue, I found solution
webClient.addWebWindowListener(new WebWindowListener() {
#Override
public void webWindowOpened(WebWindowEvent webWindowEvent) {
}
#Override
public void webWindowContentChanged(WebWindowEvent webWindowEvent) {
if (webWindowEvent.getNewPage() != null) {
// do what you need to do with webWindowEvent.getNewPage().getUrl();
}
}
#Override
public void webWindowClosed(WebWindowEvent webWindowEvent) {
}
});

SWT Browser - Google account login

I wanted to add a browser in my java(SWT framework) application.
The browser will show the content of URLs.
I have implemented it using org.eclipse.swt.browser.Browser.
Everything was working fine. But one URL has an option login with google account. When the user
clicked the login with the google account button it's opened a new IE window. After successful login, nothing is happening.
But when I tried the same URL in Chrome/IE/Firefox browser. After successful login, it's redirected to another URL.
Have anyone faced this problem before. How can I get the redirected URL in org.eclipse.swt.browser.Browser after successful login Like Chrome/IE/Firefox?
Code:
Browser browser = new Browser(this, SWT.NONE);
browser.setBounds(x, y, width, height));
browser.setUrl(INITIAL_URL);
browser.addLocationListener(new LocationListener(){
public void changed(LocationEvent e){
System.out.println("URL changed to : " + e.location);
if (e.location.startsWith("https://**************")) {
e.doit = true;
}
if (e.location.contains("*******")) {
browser.setVisible(false);
Application.getDisplay().asyncExec(() -> {
//Get page content and parse it
});
}
}
#Override
public void changing(LocationEvent event) {
// Redirected if needed
}
});
I got a similar question here but it's doesn't help me

JAVA - Selenium WebDriver - Assertions and Waits

I am having a problem with my Assertion, or rather with the "time" the assertion is being executed. So, the assertion is working as it should, however, it is going too fast, as it is executing without waiting for the page it should be targeting to load. Which means that the assertion is failing the test.
Having this in mind, I tried searching around how to add a "wait" to the assert to make it wait for the page to load before running, but with no success.
So, would anyone, please be able to help with this, as in how would I code so, that the assert "waits" for the page to load and then executes?
I've tried adding the wait to the header method, i tried adding the wait to the test script, but no success.
public class test1 extends DriverSetup{
//Here we are setting the method to use the homePage
private HomePage homePage = new HomePage(getDriver());
//Here we are setting the method logInPage
private AuthenticationPage authenticationPage = new AuthenticationPage(getDriver());
//Here are setting the method CreateAccountPage
private CreateAccountPage createAccountPage = new CreateAccountPage(getDriver());
//Here we are setting the method to access the Website HomePage with the driver
private void accessWebsiteHomePage (){
getDriver().get("http://automationpractice.com/index.php");
}
#Test
public void CreateAccount() {
accessWebsiteHomePage();
//Log in
homePage.logInBut();
//Authentication page "Create a new account" box
authenticationPage.setCreateAccountEmailAddress(emailGenerator.Email());
authenticationPage.CreateAccountButtonClick();
Assert.assertEquals("CREATE AN ACCOUNT", createAccountPage.HeaderCheckRightPage());
The assert should be targeting the "CREATE AN ACCOUNT" page, but it is targeting the "AUTHENTICATION" page, which comes before it, hence the test fails as the "actual" value being printed is the "AUTHENTICATION" page, not the "CREATE AN ACCOUNT" page.
You need to use an explicit wait. Here is one that will wait for the title to be equal to something:
private ExpectedCondition<Boolean> titleIsEqualTo(final String searchString) {
return driver -> driver.getTitle().equals(searchString);
}
You can make it more reliable by forcing the case of what you want to match like this:
private ExpectedCondition<Boolean> titleIsEqualTo(final String searchString) {
return driver -> driver.getTitle().toLowerCase().equals(searchString.toLowerCase());
}
You would then need to put the following in before your assertion:
WebDriverWait wait = new WebDriverWait(driver, 10, 100);
wait.until(titleIsEqualTo("CREATE AN ACCOUNT"));
I'm making the assumption that by header you mean the page title since you haven't shown the code that collects the header.
*Edit*
A non-lambda version of the above ExpectedCondition is:
private ExpectedCondition<Boolean> titleIsEqualTo(final String searchString) {
return new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver driver) {
return driver.getTitle().toLowerCase().equals(searchString.toLowerCase());
}
};
}

Receiving error when Uploading File using HtmlUnit

I am currently attempting to automate the upload of a file to a specific site. I am able to successfully login to the site and navigate to the import page; however, when I attempt to import the file, I receive an error. My guess is that it is because I am simply a user and am not granted permissions to write to the server. However, if I perform the import manually, then it is successful. Normally there would be four stages to the import. However, after the first step you can see that an error occurred. My code is listed below along with the error I am receiving:
public static void main(String args[]) throws Exception {
login();
}
#SuppressWarnings("resource")
public static void login() throws Exception {
// Open the webclient using Internet Explorer (Chrome does not work).
final WebClient webClient = new WebClient(BrowserVersion.INTERNET_EXPLORER);
// Get the first page
final HtmlPage page = webClient.getPage("http://telephone.qqest.com/phone/Login/Login.asp");
// Get the form that we are dealing with.
final HtmlForm loginForm = page.getFormByName("frmLogin");
final HtmlTextInput userName = loginForm.getInputByName("Login");
final com.gargoylesoftware.htmlunit.html.HtmlPasswordInput passWord = (com.gargoylesoftware.htmlunit.html.HtmlPasswordInput)
loginForm.getInputByName("Password");
final HtmlTextInput companyID = loginForm.getInputByName("Ident");
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setRedirectEnabled(true);
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
webClient.getCookieManager().setCookiesEnabled(true);
//final HtmlInput login = loginForm.getInputByName("Login");
// Change the values of the text fields.
userName.setValueAttribute("xxxx");
passWord.setValueAttribute("xxxxx");
companyID.setValueAttribute("xxxxx");
//create a submit button - it doesn't work with 'input'
DomElement loginBtn = page.createElement("button");
loginBtn.setAttribute("type", "submit");
// append the button to the form
loginForm.appendChild(loginBtn);
// submit the form
loginBtn.click();
//navigate to page for import.
HtmlPage page3 = webClient.getPage("http://telephone.qqest.com/phone/Imports/Employee/Module.asp");
//populate the textfield with the specified file.
final HtmlForm importForm = page3.getFormByName("ImportForm");
final HtmlFileInput inputFile = importForm.getInputByName("UploadFile");
inputFile.setValueAttribute("C:\\Users\\thisFile.xls");
inputFile.click();
final HtmlSubmitInput importBtn = (HtmlSubmitInput)importForm.getInputByValue("Import");
try {
importBtn.fireEvent(Event.TYPE_INPUT);
}
catch (NullPointerException ex) {
System.err.println(ex);
}
HtmlPage page4 = webClient.getPage("http://telephone.qqest.com/phone/Imports/Employee/ImportFile.asp?FileType=application/vnd.ms-excel&FilePath=c%3A%5Cinetpub%5Cwwwroot%5Cphone%5CDownloads%5CImports%5C&FileName=thisFile.xls.asp");
System.out.println("Import Page: " + page4.asText());
}
The error I am receiving:
Stage 1 of 4: Upload File - Completed
Microsoft JET Database Engine error '80004005'
Cannot update. Database or object is read-only.
/phone/Imports/Employee/ImportFile.asp, line 155
I have figured out a solution and wanted to post it for those who might find it useful in the future. The problem was that I was simply trying to redirect to the import page by using the URL. Prior I had tried to submit the forms with an importBtn.click() statement; however, I needed to declare this statement as its own HtmlPage variable.
final HtmlSubmitInput importBtn = (HtmlSubmitInput)importForm.getInputByValue("Import");
HtmlPage page4 = importBtn.click();
// loops until the page changes.
while(page4 == page3) {
// The page hasn't changed.
Thread.sleep(500);
}
System.out.println("Import Page: " + page4.asText());

How to change between pages with Selenium

I am trying to create a Test Case with Selenium, where I will create an application in one Page named "Policy". In this Application I want to create some Members. To go from Policy page to Members Page you have to press the button "Members" after you've successfully created the Policy Application. After creating all the members you need you have to navigate back to Policy page to continue.
(Main Menu Page -> Policy Page -> Members Page -> Policy Page)
I am using Page Object Pattern. I successfully log in the App, navigate to Policy Page, create the Application, but cannot go to Members Page in order to continue my Test. And of course, get back to Policy page. How can I do that? My test fails after message "Policy Created succesfully" is shown in Eclipse Console.
My code is:
#Test
public void TEST1_NavigateToPolicy() throws Exception {
MenuPage.policySelection();
}
#Test
public void TEST2_PolicyCreation() throws Exception {
PolicyPage.handleMultipleWindows("Policy");
PolicyPage.createPolicy( some requirements here);
PolicyPage.checkMessageByIdContains("Operation Apply executed Successfully", MESSAGE);
System.out.println("Policy Created succesfully");
}
#Test
public void TEST3_MemberCreation() {
//Navigate to Member Page and Create Member
PolicyPage.clickButton(MEMBERS_BUTTON);
}
Unless I'm testing the actual navigation via the UI I like to do as much navigating as possible by browsing directly to the page I need. It gives the test fewer opportunities to fail, and is often quicker as it can save extra steps.
So, I'd browse directly to the page simply using:
driver.get("yourURL");
Navigation between Policy and Members page can be done by:
#Test
public void TEST3_MemberCreation() {
// Create a policy
TEST2_PolicyCreation();
// Store the current window handle
String policyPageWindow = _webDriver.getWindowHandle();
// Clicking the "Members" button on Policy page
WebElement clickMemBerPageButton = _webDriver.findElement(By.name("MEMBERS_BUTTON"));
clickMemBerPageButton.click();
// switch focus of WebDriver to the next found window handle (that's your newly opened "Members" window)
for (String winHandle : _webDriver.getWindowHandles()) {
_webDriver.switchTo().window(winHandle);
}
//code to do something on new window (Members page)
// Switch back to policy page
_webDriver.switchTo().window(policyPageWindow);
}
Then this will be my sample code for you.
#Test
public void TEST3_MemberCreation() {
homePage = login(admin);
PolicyPage policyPage = homePage.NavigateToPolicyPage();
policyPage.handleMultipleWindows("Policy");
policyPage.createPolicy( some requirements here);
policyPage.checkMessageByIdContains("Operation Apply executed Successfully", MESSAGE);
System.out.println("Policy Created succesfully");
}
MembersPage membersPage = policyPage.clickMembersButton;(You have to handle the page navigation code inside this method and return MembersPage object)
membersPage.createMember(Data);
}
MembersPage clickMembersButton(){
element.click();
switchTo.window(newWindowHandle);
return new MembersPage();
}

Categories

Resources