Click on a button not working - java

I'm using selenium webdriver with java.
I have encountered a situation where i am able to locate & click on a button,but nothing happens after this.
The HTML code for the said button is->
<div id="divAllButtons" class="UCButtonMainCSS" style="display: none;">
<div>
<div id="OtherActionParent" class="mT8">
<div id="btnSave" class="btn fLt mR20">
<span>
<a onclick="Save_onclick()" href="javascript:void(0)">
<span id="Label24">Save</span>
</a>
</span>
</div>
The button when clicked, should redirect to the confirmation page, or show an alert message if mandetory fields are not filled.
I have tried few thing,
1
Button = driver.findElement(By.id("btnSave"));
Button.click();
2
Button = driver.findElement(By.xpath("//div[#id='dataContainer']/div[2]/div/div/div[4]/div/div[1]/div[2]/span/a"));
Button.click();
3
Actions action = new Actions(driver);
WebElement we = driver.findElement(By.xpath("//div[#id='dataContainer']/div[2]/div/div/div[4]/div/div[1]/div[2]/span/a"));
action.moveToElement(we).click().build().perform();
4
Point coordinates = driver.findElement(By.xpath("//div[#id='dataContainer']/div[2]/div/div/div[4]/div/div[1]/div[2]/span/a")).getLocation();
Robot robot = new Robot();
robot.mouseMove(coordinates.getX()+40,coordinates.getY()+30);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
Each of the way appears to work fine to click on the button as message javascript:void(0) is displayed in the bottom corner of the browser.

Try this code to click on the Save button and see if it works:
WebElement Button = driver.findElement(By.xpath("//div[#id='btnSave]//a"));
Button.click();
OR
WebElement Button = driver.findElement(By.xpath("//div[#id='btnSave]//span[.='Save']"));
Button.click();

Try a text based xpath search
text based xpath solved a lot of issues for me. You just need to make sure you have enough wait time before clicking the element
EDIT: try using action
By saveButton = By.xpath("//*[.='Save']");
WebElement element = driver.findElement(saveButton);
Actions action = new Actions(driver);
action.moveToElement(element).build().perform();
driver.findElement(saveButton).click();
Note: untested code written in java

Just try with javascript executor. it may work....
WebElement save = driver.findElement(By.id("btnSave"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", save);

The problem is solved. The issue was not to locate the element but the onClick() event was not firing. Then i found out that something else was there which stopped from the event to fire. I had used java script to enable the date picker box & did this,
((JavascriptExecutor)driver).executeScript ("document.getElementById('txtOriginDate').removeAttribute('readonly',0);");
WebElement originDateBox= driver.findElement(By.xpath(prop.getProperty("originDateBox")));
originDateBox.clear();
originDateBox.sendKeys("9-Dec-2014"); //Enter date
Developer designed this in such a way that if you don't use date picker to select date, a specific variable was not set. Which eventually made the onclick event not to fire.
The date picker code was something like this,
var jsoncustdate = "";
var jsonorigindate = "";
function onSelectCalender( StrDt, obj )
{
if ( !varReadonly )
{
if ( $( "#txtCustDescisionDate" ).attr( "IsDisable" ) == "FALSE" )
{
if ( obj.id == "txtCustDescisionDate" )
{
custobjDt = new Date( obj.selectedYear, obj.selectedMonth,obj.selectedDay, 0, 0, 0, 0 );
jsoncustdate = custobjDt.getTime();
jsoncustdate = "\/Date(" + jsoncustdate + ")\/";
DisabledBtnStage();
// $("#txtFromDate").datepicker("option", "maxDate", objDt);
}
if ( obj.id == "txtOriginDate" )
{
var objDt = new Date( obj.selectedYear, obj.selectedMonth,obj.selectedDay,0, 0,0,0 );
jsonorigindate = objDt.getTime();
jsonorigindate = "\/Date(" + jsonorigindate + ")\/";
DisabledBtnStage();
// $("#txtToDate").datepicker("option", "minDate", objDt);
}
}
elogCommon.CheckMandatory();
}
}
I finally used date picker in normal way & the event fired smoothly.
Thank you guys for help . .cheers !!!

Related

React.js How to define a custom id, rather than showing react-select-1--value in html

How do I change the React.js application to stop randomly allocating inputIds, so that Selenium will work consistently?
I'm working with Selenium and a React.js application. The application is constantly under development. I have a Selenium method working to randomly select the react dropdowns using a single, reusable method, but the ids of the react dropdowns keep changing for some reason, perhaps each time the application is built, so this creates rework for the Selenium testing.
Selenium Method: (in JAVA)
Other than those react-select inputIds changing, this method works to randomly select options in the react dropdowns, but it needs to be cleaned up. It will select an option whether or not there is already an option selected by navigating away, then back to the dropdown.
public String RandomSelect(WebDriver mydriver, String myid)
{
try{
Actions actions = new Actions(mydriver);
actions.pause(300);
WebElement dropdown = mydriver.findElement(By.id(myid));
String scrollElementIntoMiddle = "var viewPortHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);" +"var elementTop = arguments[0].getBoundingClientRect().top;"+"window.scrollBy(0, elementTop-(viewPortHeight/2));";
((JavascriptExecutor) mydriver).executeScript(scrollElementIntoMiddle, dropdown);
//((JavascriptExecutor) mydriver).executeScript(
// "arguments[0].scrollIntoView();", dropdown);
actions.moveToElement(dropdown).click().build().perform();
actions.pause(1000);
actions.sendKeys(Keys.DELETE).build().perform();
actions.pause(1000);
actions.sendKeys(Keys.TAB).build().perform();
actions.pause(1000);
actions.moveToElement(dropdown).click().build().perform();
actions.pause(1000);
// actions.pause(3000);
//actions.sendKeys(Keys.DELETE);
WebDriverWait wait = new WebDriverWait(mydriver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.className("Select-option")));
List<WebElement> options = mydriver.findElements(By.className("Select-option"));
List<String> stroptions = new ArrayList<>();
System.out.println(options.size());
for (WebElement option: options) {
stroptions.add(option.getText());
System.out.println(option.getText());
}
Random rand = new Random();
int randomNum = rand.nextInt((options.size()));
String randomoption = stroptions.get(randomNum).toString();
actions.sendKeys(randomoption+Keys.RETURN).click().build().perform();
System.out.println("Random Option Is: "+ randomoption);
// mydriver.findElement(By.className("main-container"));
options.clear();
return randomoption;
}
catch (Exception ex)
{
System.out.println("React Select Error: " + ex.toString());
return null;
}
}
Using the Selenium Method:
Doing something like this 100's of times is easier than typing all the Selenium methods 100's of times.
WebDriver driver;
driver = new EdgeDriver();
ReactDropdown mydropdown = new ReactDropdown();
mydropdown.RandomSelect(driver, "react-select-1--value");
How can I remove the dynamically assigned "react-select-1--value" and define the id as something more intuitive like "mydropdown--value", so that each time the application builds the id is maintained?
This is an example of the rendered html:
React.js html output
<div class="prop-row">
<div class="dropdown field mydropdown ">
<div class="field-label">
<label for="mydropdown">mydropdownlabel</label>
</div>
<div class="Select mydropdown undefined is-searchable Select--single">
<div class="Select-control">
<span class="Select-multi-value-wrapper" id="react-select-1--value">
<div class="Select-placeholder">Select...</div>
Getting rid of that ugly:
id="react-select-1--value"
and changing it to
id="mydropdown--value"
so that it is the same, detailed, and predictable every time would be ideal for testing. There's more than 15 dropdowns on one page and without an intuitive id, I need to either change my Selenium method, or the developers need to add better ids to the application. We want our Selenium tests to run in a pipeline using TestNG, and that will never work until this is resolved. Going with changing the react inputId's seems more Configuration Management(CM) friendly anyway to me. All those inputs should be managed through CM.
I just started with react, and it's not the most intuitive to me, yet...
You can use xpath as -
//span[#class='Select-multi-value-wrapper' and #id[starts-with(#id,'react-select')
I found a solution on my own, inputId is the key to make a unique id and to remove that react-select ugly. Here is an example....
import React from 'react';
import Select from 'react-select';
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' }
];
export class Counter extends React.Component {
state = {
selectedOption: null,
}
handleChange = (selectedOption) => {
this.setState({ selectedOption });
console.log(`Option selected:`, selectedOption);
}
render() {
const { selectedOption } = this.state;
return (
<Select
value={selectedOption}
inputId="mydropdown"
onChange={this.handleChange}
options={options}
/>
);
}
}
After an inputId is statically defined, my Selenium method seems to work better.

Selenium - Select Item From List By The ul li Value Text

I've got the following HTML
<div id="colLeft_OrderGroups" class="GroupList GroupList_Left">
<div class="SelectList" style="height:516px;">
<div class="DialogSubtitle">Available groups</div>
<ul class="ui-selectable" id="grdAvailableGroups" style="width:100%; margin-right:2px">
<li value="10929">AppraisersGroupTest</li>
</ul>
</div>
</div>
How do I select the option based off the "AppraisersGroupTest" text?
There will be multiple values in the list soon, so I need to be able to specify the text.
I have tried the answer in this post, but I'm getting syntax errors I cannot resolve.
Looking at your HTML, I'm going to assume that the value of the desired LI is going to always be "10929" for your desired "AppraisersGroupTest." With that info, you can use the code below.
String value = "10929";
WebElement dropdown = driver.findElement(By.id("grdAvailableGroups"));
dropdown.click(); // assuming you have to click the "dropdown" to open it
dropdown.findElement(By.cssSelector("li[value=" + value + "]")).click();
If it turns out that is not a good assumption, you can use the code below to search for the desired text and click the element.
String searchText = "AppraisersGroupTest";
WebElement dropdown = driver.findElement(By.id("grdAvailableGroups"));
dropdown.click(); // assuming you have to click the "dropdown" to open it
List<WebElement> options = dropdown.findElements(By.tagName("li"));
for (WebElement option : options)
{
if (option.getText().equals(searchText))
{
option.click(); // click the desired option
break;
}
}
You can achieve this using one liner xPath as below :-
String text = "AppraisersGroupTest";
WebElement el = driver.findElement(By.xpath("//div[#id = 'colLeft_OrderGroups']/descendant::li[text() = '" + text + "']"));
el.click();
Hope it will help you...:)
'For anyone who may need it
Sub Memlogin()
'Login Members Profile
Dim IE As New selenium.WebDriver
Set IE = New ChromeDriver
With IE
.Get "Your URL"
.FindElementByName("Uni_user_id").SendKeys ("Your User ID")
.FindElementByName("password").SendKeys ("Your Password")
.FindElementById("Uni_login_button").Click
'Select Profile Section
.Get "Secondary URL if Needed"
.Wait Now + TimeValue("00:00:10")
End With
'Select Desired Tab
Dim MTab, Tabs, User As selenium.WebElement
Set MTab = IE.FindElementByTag("ul")
Set Tabs = IE.FindElementByClass("li class-name ")
Set User = IE.FindElementByXPath("//a[text()=""li innerText""]")
IE.Actions.MoveToElement(User).Click(User).Perform
IE.Wait Now + TimeValue("00:00:20")
End Sub
List item

Tooltip text using Selenium 2 + Java when tootip is a parameter in onmouseover method

How can I get a tooltip for a link Footnote using Selenium 2 + Java? I am expecting "Tooltip for footnote" as the text.
html is as:
<a onmouseout="rdm.js.util.RDMUtils.hideTooltip(event);return true"
onmouseover="rdm.js.util.RDMUtils.showTooltipEncoded(event,
"<p>;</p>; Tooltip for footnote <br />");return true"
href="#">Footnote</a>
this is a code that work form me
WebElement element = findElement(driver, cssSelector, 1);
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.perform();
element.getText();

Javascript on a icon that expands and collapse a table not working with the enter button

I have on this page a clickable +/- icon that will expand and collapse a table of information when the user clicks on it in the jsp page, but the issue is that if the user tabs to this icon and try to expand/collapse it by pressing the enter button, the javascript won't run; it only works with mouse click for some reason. Here's what I have on the jsp page:
<td>
<a onclick="hideShowTable(${count}, this.id)" style="cursor:hand"
title="Expand/Collapse Table" tabindex="40"
id="eCTable${count}"
>+
</a>
</td>
That executes this function in the js file:
function hideShowTable(tableCounter, id)
{
//Loop through all rows of the month
for(i=1; i<=12; i++)
{
var tableElm = document.getElementById("tableMonth"+ i +"_"+tableCounter);
//Hide or show the div tag
if (tableElm .style.display == "block"){
tableElm .style.display = "none";
document.getElementById(id).innerText="+";
}
else{
tableElm .style.display = "block";
document.getElementById(id).innerText="-";
}
}
}
The description says:
The onclick event occurs when the pointing device button is clicked over an element. This attribute may be used with most elements.
I think you can try using form's onsubmit() rather than onclick() . Give a try..

webdriver target="_blank"

Page has image with hyperlink and that hyperlink has target="_blank" and every time i press that image loads new firefox and that hyperlink is redirected to that new firefox web
and i lose all control of that webpage.
Is possilble to remove or change that target="_blank" on hyperlink, bcause i want to load webpage in same webdriver
WebDriver driver = new FirefoxDriver();
driver.get("http://www.page.eu/");
WebElement submit;
submit = driver.findElement(By.xpath("//img[#alt='page']"));
submit.click();
that hyperlink have target="_blank"
i need to change that target somehow by using webdriver + javascript maybe or what?
is it possible?
edited
thanks for suggestions, but still is this problem
i tried to make like Grooveek said but no changes
WebElement labels2 = driver.findElement(By.xpath("//a[#href='http://tahtpage.net']"));
WebElement aa = (WebElement) ((JavascriptExecutor) driver).executeScript("labels2.setAttribute('target','_self')",labels2 );
aa.click();
i have an error
org.openqa.selenium.WebDriverException: null (WARNING: The server did not provide any stacktrace information)
i'm not good at javascrit so i think is problem in that executor
Instead of clicking on the image, you could just directly go to the URL in the link:
WebElement link = (driver.findElement(By.xpath("//img[#alt='page']/parent::*"));
String href = link.getAttribute("href");
driver.get(href);
Try the following:
WebElement labels2 = driver.findElement(By.xpath("//a[#href='http://tahtpage.net']"));
WebElement aa = (WebElement) ((JavascriptExecutor) driver).executeScript("arguments[0].setAttribute('target','_self')",labels2 );
aa.click();
You are getting a null exception because you are using labels2 in your javascript, which doesn't exist in that context. By changing it to arguments[0] Selenium will take the labels2 parameter and reference it in javascript appropriately.
Evaluating javascript in the window will help you to suppress target=blank links
Here's the example from the Webdriver docs
List<WebElement> labels = driver.findElements(By.tagName("label"));
List<WebElement> inputs = (List<WebElement>) ((JavascriptExecutor)driver).executeScript(
"var labels = arguments[0], inputs = []; for (var i=0; i < labels.length; i++){" +
"inputs.push(document.getElementById(labels[i].getAttribute('for'))); } return inputs;", labels);
Adapt it to modify the DOM to throw target="_blank links"
Why don't you wanna use SwitchTo().Window?
I think you should use the SwitchTo().Window as suggested by simeon sinichkin. however, i didn't like his example.Here is simple example.
driver.Navigate().GoToUrl(baseURL);
//Get the Main Window Handle
var baseWindow = driver.CurrentWindowHandle;
// navigate to another window (_blank)
driver.FindElement(By.Id("btn_help")).Click();
Thread.Sleep(2000);
//switch back to Main Window
driver.SwitchTo().Window(baseWindow);
hope that helps
Why don't you use:
target="_self"

Categories