How to find element by xpath that has same class, name etc - java

There are two buttons with same class, text etc. I have to find and click each.
<a class="jsx-1291462554"><button style="padding: 12px 15px 10px; border-radius: 4px; font: 500 15px / 16px hind; color: white; background-color: rgb(18, 83, 181); justify-content: center; text-align: center; cursor: pointer; text-decoration: none; outline: none; border: none; width: 162px;"><span class="jsx-1291462554 magzter__buttonText">Choose</span></button></a>

//section[contains(#class,'chooseplanTitle')]//button[1]
//section[contains(#class,'chooseplanTitle')]//button[2]

to enable the automatic clicking of a button, we use the XPath function, which is in the class By.
1.Version
driver.FindElement(By.XPath("//button[#class ='CLASS NAME']")).Click();
2.Version
driver.FindElement(By.XPath("//div[normalize-space(.)='NAME']/button")).Click();
To enable an automatic input into the text field we can also use the function CssSelector which is located in the class By.
IWebElement usernameInput = driver.FindElement(By.CssSelector("input[name='username']"));
IWebElement passwordInput = driver.FindElement(By.CssSelector("input[name='password']"));
usernameInput.SendKeys("YourUsername");
passwordInput.SendKeys("YourPassword");

find first and second element that matches the below locator :
(//a[#class="jsx-1291462554"]/button)[1]
(//a[#class="jsx-1291462554"]/button)[2]
find all elements with tag button and is a first child of 'a' with class specified:
//a[#class="jsx-1291462554"]/button[1]
css equalent of first xpath :
a.jsx-1291462554>button:nth-of-type(1)
a.jsx-1291462554>button:nth-of-type(2)
css equalent of second xpath :
a.jsx-1291462554>button:nth-child(1)

Both the elements are a dynamic elements. So to click() on the first Choose you need to induce WebDriverWait for the elementToBeClickable() and you can use either of the following Locator Strategies:
xpath:
WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//p[starts-with(., 'Choose the plan that')]//following::a[1]/button/span[text()='Choose']")));

If is possible, put something to differentiate the buttons's mapping. But if it isn't possible, these mappings will solve
(//section[contains(#class, 'twocol')]/a)[1]
(//section[contains(#class, 'twocol')]/a)[2]

List<WebElement> links = driver.findElements(By.xpath("//a[#class='jsx-1291462554']"));
links.get(0).click();
//Wait here for some action to happen
links.get(1).click();
The xpath varies depending on what you actually want to click, if the button element replace with:
//a[#class='jsx-1291462554']/button
If the button's click action changes the DOM you might encounter a StaleElementReference, in which case you may need to refetch (findElements) again before selecting the 2nd one.

Related

How to fix the ElementNotVisibleException in Edge browser using Selenium?

I am currently testing a GWT web application similar to MS Paint and the problem which I am facing is that my test case passes on the browsers like Chrome, Firefox, and IE but sadly, it fails in the Microsoft Edge browser. I am unable to find out how to fix this issue after searching the whole Internet and trying out many methods which are written on the Stack Overflow and Google Groups, I am feeling extremely hopeless. Meanwhile, here is my code:
public class Insert_Element_in_Edge {
private static WebDriver driver;
#Test
public void main() throws InterruptedException, IOException
{
// TODO Auto-generated method stub
System.setProperty("webdriver.edge.driver", "D:\\SELENIUM\\Drivers\\MicrosoftWebDriver.exe");
driver = new EdgeDriver();
driver.manage().timeouts().implicitlyWait(10,TimeUnit.SECONDS);
driver.manage().window().maximize();
Thread.sleep(3000);
driver.get("xxxx.com");
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.titleContains("xxxx"));
WebElement canvas = driver.findElement(By.id("frontCanvas"));
Thread.sleep(3000);
final String InsertPath="//img[contains(#src,'Insert Element')]";
WebElement Insert = driver.findElement(By.xpath(InsertPath));
Thread.sleep(3000);
Insert.click();
}
}
Here's the error which I am facing:
org.openqa.selenium.ElementNotVisibleException: Element not displayed (WARNING: The server did not provide any stacktrace information)
Given below is the HTML code of the element which I am trying to locate in the Edge browser.
<div id="isc_2Q" eventproxy="isc_XXXIconButton_SClient_1" role="button" aria-label="xxx"
onfocus="isc.EH.handleFocus(isc_XXXIconButton_SClient_1,true);"
onblur="if(window.isc)isc.EH.handleBlur(isc_XXXIconButton_SClient_1,true);"
tabindex="1020" style="position: absolute; left: 0px; top: 54px; width: 40px;
height: 34px; z-index: 201152; padding: 0px; opacity: 1; overflow: visible;
cursor: pointer;" onscroll="return isc_XXXIconButton_SClient_1.$lh()" class="iconHoverZindex">
<div id="isc_2R"
eventproxy="isc_XXXIconButton_SClient_1" style="position: relative;
-webkit-margin-collapse: separate separate; visibility: inherit;
z-index: 201152; padding: 0px; cursor: pointer;">
<table role="presentation" cellspacing="0" cellpadding="0" width="40px" height="34px">
<tbody>
<tr>
<td nowrap="true" class="iconButton" style="background-color:transparent;"
align="center" valign="middle" onfocus="isc_XXXIconButton_SClient_1.$47()">
<img src="Insert Element.png" width="24" height="24" align="TEXTTOPundefined"
class="iconButtonHIcon" eventpart="icon" border="0"
suppress="TRUE" draggable="true"/>
<span style="vertical-align:middle;align-content:center;"></span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
This element is visible in other 3 browsers and is clicked successfully. But I just got stuck in Edge. Also, in Edge, the HTML5 canvas is also not displayed using Selenium. Please help.
You can add wait statement before click on it as given below.
wait.until(ExpectedConditions.ElementIsVisible(By.xpath(InsertPath)));
You have to use element to be clicable as it is a button
WebDriverWait wait = new WebDriverWait (driver, 50);
final String InsertPath="//img[contains(#src,'Insert Element')]";
WebElement Insert= wait.until(ExpectedConditions.elementToBeClickable(By.xpath(InsertPath)));
Insert.click();
In the past I aslo had some trouble location elements with xPath in Edge, GWT and Selenium
Sadly I didnt found a solution but a workaround:
We gave every Element an ID
for example:
panel.getElement().setId("panel-id");
and then used the ID-Locator to find the Element:
findElement(By.id("panel-id"))
I read answers to your question that should solve your problem.
But noone asked you (and you did not provide us, in your question) informations about the version of your MicrosoftWebDriver, Selenium, and Browser that are you using.
From Microsoft WebDriver download, are you using a version that should be supported from your browser?
From EdgeHTML issue tracker, I found only 2 issues (that are fixed) with key element ElementNotVisibleException.
In these cases I usually take a screenshot just before the line where exception occurs and save it somewhere to further investigation. Then I mostly have to add a scrollUp()/scrollToVisible() function before this line to fix the problem.
I would suggest a few tweaks in your code block as follows:
First of all we will try to get rid of all the Thread.sleep(n) calls.
Now, to address the reason for ElementNotVisibleException, we will scroll the element of our interest within the Viewport and then invoke click() method.
Your final code block will may look:
driver = new EdgeDriver();
driver.manage().window().maximize();
driver.get("xxxx.com");
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions.titleContains("xxxx"));
WebElement canvas = driver.findElement(By.id("frontCanvas"));
WebElement Insert = driver.findElement(By.xpath("//div[#id='isc_2R']//td/img[#class='iconButtonHIcon' and contains(#src,'Insert Element.png')]"));
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].scrollIntoView()", Insert);
Insert.click();
Other than above suggestions,
Make sure that "Your Element" that you are looking for is physically visible in your Browser screen. Meaning, if element is not visible , user needs to scroll down in order to see it. Driver behaves similar. In order to prevent "ElementNotVisiable" exception make sure it is also visible on browser page
Try This,
Select elm = new Select(driver.findElement(By.Xpath("Your element's Absolute Xpath")));
//Thread.sleep(100);
elm.selectByValue("Dropdown Value which you want to select");
I've exactly the same problem with GWT. For any reason there's no way to call click directly.
Workaround that worked for me
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].click()", element);

How to click on a link with a span tag inside using selenium java

I am having a problem in clicking the link text given inside a span tag.
html code :
<div id="menu" style="width: 1752px;">
<div class="dd_menu" dd_event_id="dd_event_2">
<a class="dd_menu_menu_entry dd_menu_entry_clickable" href="javascript:void(0);" style="left: 3px; width: 111px;" dd_menu_id="0">
<a class="dd_menu_entry dd_menu_entry_clickable" href="javascript:void(0);" style="left: 114px; width: 131px;" dd_menu_id="1">
<span class="text" style="background-color: rgba(0, 0, 0, 0);">FirstMenu</span>
I need to click on the text 'FirstMenu' .
I have used the xpath : .//*[#id='menu']/div/a[2]/span
It does not seem to work. How do I fix it?
If your requirement is to "click on the link FirstMenu", then you should use that as the locator. No need to mess around with XPath.
driver.findElement(By.partialLinkText("FirstMenu")).click();
The .partialLinkText() locator strategy should account for any extra whitespace padding due to the extra span element.
Your xPath returns span element so you're clicking that span. To make your xpath return a link ament your query to the following:
//*[#id='menu']/div/a[span]
This query returns a "link" that has span element as a child.
Try to use below xpath :-
//span[contains(.,'FirstMenu')]
If it doesn't work then there may be any frame present. You need to switch it on first.
Please let me know if there is more element with name FirstMenu on DOM
Hope it will help you :)
The problem got solved by using the same xpath i specified above with the usual syntax driver.findElement(By.xpath("//*[#id='menu']/div/a[2]/span")).click(); after i gave the order by which testcases have to be executed and using #Test(priority=something) and giving some implicit waits.
Thank you all for the suggestions.
regards,
roma
It is not good to use xpath. If the html of the page is changed your code would stop working. Try with css selector.
This is is simple code and you can modify it for you case:
var collection = driver.getelementsBy(By.cssSelector('div#menu div'))
It should return you collection with elements
And after that you can iterate through collection and find the element you want to click.
Hope the answer helps you.

Unable to use send keys for disabled Element in selenium

The input field for which I am trying to write the code in selenium:
input class="tt-hint" type="text" disabled="" spellcheck="off" autocomplete="off" style="position: absolute; top: 0px; left: 0px; border-color: transparent; box-shadow: none; background: none repeat scroll 0% 0% rgb(255, 255, 255);"
My code is:
WebElementy inp= driver.findElement(By.className("tt-hint"));
inp.sendKeys(new String[] { "mo" });
But the above code does not work. The error I keep getting is:
Exception in thread "main" org.openqa.selenium.InvalidElementStateException: Element is disabled and so may not be used for actions
Any help is appreciated.
I have modified my code to
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].removeAttribute('disabled')",inp);
inp.sendKeys("mo");
I get the output as
The exception says it all. The element is not ready to accept any interaction and DISABLED. JavaScript is only option here. I would remove the disabled attribute and then use sendKeys()
String script = "document.getElementsByClassName('tt-hint')[1].removeAttribute('disabled')";
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript(script);
WebElementy inp= driver.findElement(By.className("tt-hint"));
inp.sendKeys("Whatever");
Javascript is the only option as said by #Saifur.However you do like this also
Either remove the disabled attribute or go with javascript to set the value itself
WebElement inp = driver.findElement(By.className("tt-hint"));
//Option 1 remove the disabled attribute
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].removeAttribute('disabled')",inp);
inp.sendKeys("val");
//Option 2 go for javascript set value
js.executeScript("arguments[0].value=arguments[1]",inp,"val");
The below is the code for Selenium C#, for a hidden Textbox/TextArea
IWebElement element;
IJavaScriptExecutor js = (IJavaScriptExecutor)Driver;
js.ExecuteScript("arguments[0].value=arguments[1]", element, inputValueYouWantToPlace);
Some controls won't recognize the given text and gives error like 'please provide input value'- in this case Enable the element just before sending the value using SendKeys()
`
js.ExecuteScript("arguments[0].removeAttribute('disabled')", input);
js.ExecuteScript("arguments[0].click()", element);
element.SendKeys(inputValueYouWantToPlace);
`

webkit-specific css selector not working

I'm styling my GWT CellTable cells by overriding getCellStyleNames in my column definition. Styles are working, on the most part. I'm trying to color the background of a 4-pixel wide column, with mixed display results depending on the browser engine. I'm expecting the following to work, but it doesn't. I need to set the height for firefox to 0, otherwise the first row appears to have a larger height than the rest of the rows. Any ideas?
.wt-tableRowGreen {
background-color: #8DAF00;
width: 0px;
padding-left: 4px !important;
padding-right: 0px !important;
display: compact;
height: 100%;
}
Setting height to 0 works fine for FF, but breaks the others. Using browser specific selectors isn't working:
-ms-height: 100%;
-webkit-height: 100%;
-moz-height: 0;
If you want to target spesific css for Firefox, this is the solution I use:
#-moz-document url-prefix()
{
/* Css for FF here */
}
Obviously, this is something one should generally avoid, but in some cases it's virtually impossible to get around it.

how to access the styles from CSS

Can we get the value from inside a css definition in the code if CSS resource is used?
e.g.
.iv_menu_thumbnail {
display: block;
width: 24px;
height: 24px;
margin: 3px;
float: left;
cursor: pointer;
}`
Can we know via code the value of width and i want to access from one of my java class?
Thanks in advance
var width = $('.iv_menu_thumbnail').width();
console.log(width);
This will get the width of the element if this is what youre asking for.
As far as I'm concerned you cannot get non numerical values from a css declaration.
But you can set your own values via jQuery using the
.css()
So it would look like this if you want to set a new css value. (or overwrite it)
$(someelement).css('float', 'left');
As far as I know, you can only inspect the computed CSS property on an element where this has been applied. Like:
$(someElementOrId).css('width');
or
$(someElementOrId).width();
Note that the former and the latter differ - the former does not contain the unit of measure, the latter does.
You can have a variables in your Css Resource file and set the width attribute with that variable, and then access the width varialbe from code.
CssResource
Css Resource file
#def small 1px;
#def black #000;
border: small solid black;
Java Code
interface MyResources extends CssResource {
int small();
}

Categories

Resources