I've been testing HtmlUnit with a few sites; in all these sites,they have
elements such as a radio button or checkbox that when you click, then your
profile on that site is updated; you don't need to submit a form or
anything. But when I take the exact same actions with HtmlUnit, my profile
on the server is not really updated. Do I have to do something special
such as synchronizing the local copy of the page that HtmlUnit has with the
server so that the server sees the change? As an example, I have added my
code for switching my resume on a website from private/public and vice
versa. When I visit the page on a browser, all I have to do is click one
of the two radio buttons to make the resume public/private; but when I do
the same on HtmlUnit, and then go and visit the page on a browser to check, I can see that the information on the server hasn't been changed. I've
included my code below. Note that I have another method which logs in to
the site, and I know that I login correctly. Given this is happening
with my sites for me, I thought maybe there is something like synchronizing with the server that I'm not doing.
=====================================
public void update(String urlOfThePage)
{
// First, declare any element name or xapth that you are going to
use. String xpathOfIsPublicRadioButton = "//input[#id='privacy_show']";
String xpathOfIsPrivateRadioButton = "//input[#id='privacy_hide']";
// Get the first page
try
{
final HtmlPage resumePage = (HtmlPage) webclient.getPage(urlOfThePage);
CrawlerUtility.savePage(resumePage, "resumePage");
final HtmlRadioButtonInput makePublicRadioButton =
(HtmlRadioButtonInput)
resumePage.getFirstByXPath(xpathOfIsPublicRadioButton);
final HtmlRadioButtonInput makePrivateRadioButton =
(HtmlRadioButtonInput)
resumePage.getFirstByXPath(xpathOfIsPrivateRadioButton);
Page result = null;
if (isProfilePublic())
{
result = makePrivateRadioButton.click();
System.out.println("The Profile is changed to private
now.");
Thread.sleep(60000);
}
else
{
result = makePublicRadioButton.click();
System.out.println("The Profile is changed to public now.");
Thread.sleep(60000);
}
}
catch (Throwable e)
{
e.printStackTrace();
}//End of try/catch block.
}//End of update().
If you don't submit a form, then you may be using AJAX behind the scenes to send data to the server. HTML unit won't send the same to the server since it will not process the AJAX requests. What you need is something more sophisticated such as Sikuli http://www.sikuli.org which actually clicks on elements on your webpage in the exact same way a user does. You can also try Selenium (http://www.seleniumhq.org/) which is specific to web browsers.
Related
I made a pretty simple selenium test, where I want to open web page, clear field value, start entering text for this field, select first value from the hint drop down.
Web site is aviasales.com (I just found some site with a lot of controls, this is not an advertisement)
I did
DriverFactory.getDriver().findElement(By.id("flights-origin-prepop-whitelabel_en")).clear();
and it was working perfectly, I also checked via console that this is the only one object on a page like:
document.getElementById('flights-origin-prepop-whitelabel_en')
So, in next line I'm sending value:
DriverFactory.getDriver().findElement(By.id("flights-origin-prepop-whitelabel_en")).sendKeys("LAX");
but it send LAX value for both "flights-origin-prepop-whitelabel_en" and "flights-destination-prepop-whitelabel_en" for some reason, then i tried
DriverFactory.getDriver().findElement(By.id("//input[#id='flights-destination-prepop-whitelabel_en'][#placeholder='Destination']")).sendKeys(destinationAirport);
but I got the same result:
What could be a reason and how to fix this?
Thank you!
Yep... there's some weird behavior going on there. The site is copying whatever is entered into the first field into the second for reason I don't understand. I gave up trying to understand it and found a way around it.
Whenever I write code that I know I'm going to reuse, I put them into functions. Here's the script code
driver.navigate().to(url);
setOrigin("LAX");
setDestination("DFW");
...and since you are likely to use these repeatedly, the support functions.
public static void setOrigin(String origin)
{
WebElement e = driver.findElement(By.id("flights-origin-prepop-whitelabel_en"));
e.click();
e.clear();
e.sendKeys(origin);
e.sendKeys(Keys.TAB);
}
public static void setDestination(String dest)
{
WebElement e = driver.findElement(By.id("flights-destination-prepop-whitelabel_en"));
e.click();
e.clear();
e.sendKeys(dest);
e.sendKeys(Keys.TAB);
}
You can see the functions but basically I click in the field, clear the text (because usually there's something already in there), send the text, and then press to move out of the field and choose the default (first choice).
The reason of your issue is the ORIGIN and DESTINATION inputbox binded keyboard event which used to supply an autocomplete list according to your typed characters.
The binded keyborad event breaks the normal sendKeys() functionality. I met similar case in my projects and questions on StackOverFlow.
I tried input 'GSO' into DESTINATION by sendKeys('GSO'), but I get 'GGSSOO' on page after the sendKeys() complete.
To resolve your problem, we can't use sendKeys(), we have to use executeScript() to set the value by javascript in backgroud. But executeScript() won't fire keyborad event so you won't get the autocomplete list. So we need find out a way to fire keyborady event after set value by javascript.
Below code snippet worked on chrome when i tested on aviasales.com:
private void inputAirport(WebElement targetEle, String city) {
String script = "arguments[0].value = arguments[1]";
// set value by javascript in background
((JavascriptExecutor) driver).executeScript(script, targetEle, city + "6");
// wait 1s
Thread.sleep(1000);
// press backspace key to delete the last character to fire keyborad event
targetEle.sendKeys(Keys.BACK_SPACE);
// wait 2s to wait autocomplete list pop-up
Thread.sleep(2000);
// choose the first item of autocomplete list
driver.findElement(By.cssSelector("ul.mewtwo-autocomplete-list > li:nth-child(1)")).click();
}
public void inputOrigin(String city) {
WebElement target = driver.findElement(By.id("flights-origin-prepop-whitelabel_en"));
return inputAirport(target, city);
}
public void inputDestination(String city) {
WebElement target = driver.findElement(By.id("flights-origin-prepopflights-destination-prepop-whitelabel_en"));
return inputAirport(target, city);
}
Goal: alert pop up. whether it's shown or not, I want it to continue. if it shows, have to select the checkbox, and hit continue. if not, ignore.
Blocker: if alert shows, it will handle the action and dialog will be closed. but when it's not, selenium hangs there without handling condition when it's not shown.
background: I use UFT before, maybe my logic could be wrong.
the pop up is application alert(not systems), so assumed "switch to(),accept()/dismiss() won't work. and I will add handle alert right after login and within the login method below.
Selenium framework background. : we use selenium maven framework, serenity BDD. object is set at the beginning of the page. and serenity.properties handle the time out default and so on.
Pop up objects (if it appears):
#FindBy(xpath = "//input[#id='notification-ack']")
private WebElement PcoNoticeChbx; //this is a check box, needs to be checked
#FindBy(xpath = "//button[contains(.,'Continue')]")
private WebElement PcoNoticeContinueBtn;//button to close the alert
*Log in method *
public void loginIntoExtApplication(String baseURL, String loginURL, String uId, String pwd, String extAppEnv)throws Exception {
gotoExtLoginPage(baseURL, loginURL);
enterLoginCredential(uId, pwd);
openAt("https://" + extAppEnv + ".programportaltest.hrsa.gov/sdms-
extranet/index.xhtml");
My Approaches:
//1.
if (PcoNoticeChbx!=null) {
PcoNoticeChbx.click();
PcoNoticeContinueBtn.click();
} else {
System.out.println("Dialog didn't display, no need any action");
}
//2. hanged here after login actions.
if(!getDriver().findElements(By.xpath("//*[#id='submit']")).isEmpty()){
PcoNoticeChbx.click();
PcoNoticeContinueBtn.click();
}
else {
System.out.println("Dialog didn't display, no need any action");
}
//3. added to watch doesn't work, it shows pending, below code failed too. I ran my Maven in Junit in debug mode. it used to work fine. but watch elements always show (pending)..
boolean isPresent = getDriver().findElements(By.id("noticebox")).size() >0
System.out.println("the diaolog exist= " + isPresent);
//4. even tried the try-catch method.
try{
PcoNoticeChbx.click();
PcoNoticeContinueBtn.click();
}catch (Exception e){
// Printing logs for my report
Log.error("Report Category button element is not found.");
// After doing my work, now i want to stop my test case
throw(e);
}
return;
}
//5. tried list webelemets:
List temp = webdriver.findElements(org.openqa.selenium.By.id("noticebox"));
if (temp.Count > 0 && temp[0].Displayed) {
// script to execute if element is found
} else {
// continue the test
}
//6. and below
if (!WebDriver.findElements(By.xpath("//*[#id='submit']")).isEmpty()==true);
{
//handle the dialog
}
else{
//continue
}
// 7.tried with a boolean value, but it also hangs on here first steps
boolean Nbox = PcoNoticeChbx.isDisplayed(); {
if (Nbox==false)
{
System.out.println("Dialog didn't display, no need any action");
}
else if (Nbox==true) {
PcoNoticeChbx.click() ;
PcoNoticeContinueBtn.click();
}
If this is like the popups that I've dealt with they work like this:
Customer comes to site and the site checks for the existence of a cookie. If that cookie exists, the popup is never launched (ideal state). If that cookie does NOT exist (typical state), after a specified period of time a popup appears.
Customer dismisses the popup and a cookie is created with an expiration time
Once that expiration time passes, the cookie expires and the popup will fire again
You need to do some investigation and find the cookie that is created once the popup is dismissed. Clear your cache, browse to the site, and note all the cookies that exist. Wait for the popup and dismiss it. Now find the cookie that was just created and examine it. This is the cookie you need to create. There are a lot of tutorials on creating cookies. It's pretty straightforward.
Once you learn how to create the cookie, you add it to your script as described below:
Navigate to some page on the domain that you know doesn't exist, e.g. www.domain.com/some404page. We do this because it won't trigger the popup countdown and we need to be on the domain to create the cookie.
Create the cookie
Do your normal test
No more popups.
Solution found for my case.
this maybe very easy. but takes some times for me to research. hopefully it will help you.
after use of many methods, for this javascripts confirmation alert. i have used below method. all of help of .CurrentlyVisible() method. because this one, and i guess only this one will give you result even when the element does not exist or null..
if (element(NoticeContinueBtn).**isCurrentlyVisible**()==true) {
PcoNoticeChbx.click();
PcoNoticeContinueBtn.click();
//else just continue
}
Hello I am looking for information on the close tab (not browser) event if there is one in java for a applet. I am wondering if there is an event for that or a way to check a way to check for that. I would like to just capture the event and make a little popup box , stating Your session will expire or something along those lines. Is that possible at all or to a point with java or Javascript?
UPDATE: okay with the information you guys pointed me into i was able to get information on a simple enough javascript. Now it is working fine in IE , Chrome and Firefox but for some reason Safari 5.1.7 isn't liking the code. Not sure why. Here is the code if it helps.
jQuery(function() {
var hiddenBtn = document.getElementById("javaform:browserCloseSubmit");
try{
opera.setOverrideHistoryNavigationMode('compatible');
history.navigationMode = 'compatible';
}catch(e){}
//Sends the information to the javaBean.java file.
function ReturnMessage()
{
return hiddenBtn.click();
}
//UnBind Function
function UnBindWindow()
{
jQuery(window).unbind('beforeunload', ReturnMessage);
}
//Bind Exit Message Dialogue
jQuery(window).bind('beforeunload', ReturnMessage);
});
You have the onBeforeUnload event you can catch in JavaScript. See here.
Use window.onbeforeunload
window.onbeforeunload = function () {
return "Are you sure you want to exit?";
};
Note that it will also end in Are you sure you want to leave this page (or are you sure you want to reload this page if you are reloading)
I want to make a button in NetBeans, that when clicked, will open a webpage, wait until the webpage loads, and logs in to that site. I have some code here, but I am not sure what to do after this:
javascript:(function (){
window.open("http://www.stackoverflow.com");
object.onload="LoginToThisSite"
})();
I also have a bookmarklet that logs you in to the site automatically, I am just not sure how to tie that in to the button.
Here is the code I have in NetBeans for the button:
public void actionPerformed(ActionEvent evt) {
String cmd = evt.getActionCommand();
if (cmd == "POST") {
try {
String url = "http://www.stackoverflow.com";
java.awt.Desktop.getDesktop().browse(java.net.URI.create(url));
}
catch (java.io.IOException e) {
System.out.println("Couldn't open browser...");
}
}
}
I would appreciate all the help I can get, as I am horrible at coding in Java.
Use $(document).ready()
This function would excute after document is loaded
(Jquery)
since you don't have access to the website you are trying to authenticate with the best you can do is to wait an arbitrary length of time (in this case 30000 milliseconds):
<body onload="setTimeout(authenticationAttempt,30000);">
<script>
function authenticationAttempt() {
// add your code to login here
alert('after 30 seconds i assume the page is loaded');
}
</script>
</body>
here is a jsfiddle example which allows 5 seconds for bing.com to load before running additional code.
http://jsfiddle.net/DaveAlger/CFLh2/
if the website you are trying to authenticate with is public you should post a link to it because i still think what you are attempting will not be allowed unless you have access to change the code on the school website.
There is a requirement to fill a webform of some particular site of which HTML source I have available. I want to fill the fields on this form from the database records. I don't want to POST the request to the server as the application user would first verify the filled data and will submit the form manually.
Is there any way in java through which I can achieve this? I have already achieved this in VB .Net but want to include as a part of bigger application which is already developed in java and implements a business logic.
You help would be appreciated.
Thanks,
SRA
Java would be running on the server.
In that case, you just modify the server so that it generates the HTML with the <input> elements prefilled with the values from the database; e.g. using the value attributes. It is a little bit more complicated for selectors, where you have to make sure that one of the choices is preselected.
So, you need to access DB and you also need to fill web form from the client side. If you use Selenium it will be this scenario:
User starts your program. Program opens browser window, logs in and fills form. User checks data and presses "send"-button. Browser window automatically closed by program (potentially possible to keep browser window open, but it's better to clean resources and finish program).
Code sample:
public static void main(String[] args) throws InterruptedException {
webDriver = new FirefoxDriver();
try {
processPage();
} finally {
webDriver.quit();
}
}
private static void processPage() throws InterruptedException {
webDriver.get("http://some_page_url");
// Page element search example
List<WebElement> elements = webDriver.findElements(By.xpath(XPATH_STR));
// Fill page here
}