I am starting in the world of UI automation with WebDriver and Java. I am getting a problem when I try to select a element of a combo box. This is the code:
WebDriver driver = new FirefoxDriver();
driver.get("http://intersite.com/");
new Select(driver.findElement(By.xpath(".//*[#id='term']"))); //Exception happens in this line org.openqa.selenium.NoSuchElementException: Unable to locate element: {"method":"xpath","selector":".//*[#id='term']"}
And this is the code in the web site (I use Firepath to know the Xpath):
<select name="term" onchange="getTipDoc('');" id="term" class="termination"><option value="">-- Select an Option --</option>
<option value="OPT1">Option 1</option>
<option value="OPT2">Option2</option>
</select>
I see in the tag select, the ID attribute is correct but the exception always happens. I tried with othe method for locate the element like "By.id" but doesn't work too. What can i do?
Regards!
Couple of possible reasons can happen in case like this
Element you are looking for is inside an iframe. Use driver.switchTo().frame(driver.findElement(somethting));
Element look up is faster than the load time. In this case use explicit wait. WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("term"))); See this
There are duplicate Ids. try using select[id='term'][class='termination'] as cssSelector
And, of course use By.id() since the id is available.
you need to wait to get the page load before trying to get its element this code will help you to do that
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(".//*[#id='term']")));
Related
I'm trying to select an element based on its text contents. I am using XPath to achieve this.
I am just puzzled as this should work?
WebElement link = obj.driver.findElement(By.xpath("//div[contains(text(), 'Notifications')]"));
I'll even copy the HTML code:
<div class="linkWrap noCount">Notifications <span class="count _5wk0 hidden_elem uiSideNavCountText">(<span class="countValue fsm">0</span><span class="maxCountIndicator"></span>)</span></div>
The div element has the words "Notifications" inside it. So why doesn't it work.
Go to this page on Facebook: https://www.facebook.com/settings
Use this chrome extension to highlight any area via xPath.
You have a space before the word Notifications:
WebElement link = obj.driver.findElement(By.xpath("//div[contains(text(), 'Notifications')]"));
You should also add a wait for element before trying to find the element:
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[contains(text(), 'Notifications')]"));
WebElement link = obj.driver.findElement(By.xpath("//div[contains(text(), 'Notifications')]"));
I found the issue with the help of some amazing people in this community.
Ok, so my element was in an iFrame.
In order to access the element, I must first access the iFrame
WebElement iframe = obj.driver.findElement(By.xpath("//iframe[#tabindex='-1']"));
obj.driver.switchTo().frame(iframe);
Got below HTMLcode for dropdown:
<select name="PWCMasterPage$PWCWebPartManager$gwpTemplateFr1$TemplateFr1$drpProductType" id="PWCMasterPage_PWCWebPartManager_gwpTemplateFr1_TemplateFr1_drpProductType" tabindex="2" class="PWCDropDownList" profiledatamember="" profileid="TEMPLATE" onblur="this.Holder = GetControlHolder(this);" onchange="this.Holder = GetControlHolder(this);" onfocus="this.Holder = GetControlHolder(this);" data-val-subtype-type="none" controlscollectionname="TemplateFr1_drpProductType" data-configid="TemplateFr1_drpProductType" holdername="TemplateFr1Holder">
<option value=""></option>
<option value="7">Expedited</option>
<option value="8">Premier</option>
<option value="9">Value</option>
</select>
Have been trying to select the dropdown values with:
Select dropDown = new Select(driver.findElement(By.xpath("//*[#id=\"PWCMasterPage_PWCWebPartManager_gwpTemplateFr1_TemplateFr1_drpProductType\"]")));
dropDown.selectByValue("8");
Getting below error:
Exception in thread "main" org.openqa.selenium.NoSuchElementException:
Cannot locate option with value: 8
Select dropDown = new Select(driver.findElement(By.xpath("//*[#id=\"PWCMasterPage_PWCWebPartManager_gwpTemplateFr1_TemplateFr1_drpProductType\"]")));
dropDown.selectByVisibleText("Expedited");
Which resulted in below error:
Exception in thread "main" org.openqa.selenium.NoSuchElementException:
Cannot locate element with text: Expedited
Have tried alternately with selectByVisibleText and selectByIndex as well which resulted in similar errors.
The issue isn't the java code you provided or the HTML source.
I created a simple web page with your html:
<html><body>
<select name="PWCMasterPage$PWCWebPartManager$gwpTemplateFr1$TemplateFr1$drpProductType" id="PWCMasterPage_PWCWebPartManager_gwpTemplateFr1_TemplateFr1_drpProductType" tabindex="2" class="PWCDropDownList" profiledatamember="" profileid="TEMPLATE" onblur="this.Holder = GetControlHolder(this);" onchange="this.Holder = GetControlHolder(this);" onfocus="this.Holder = GetControlHolder(this);" data-val-subtype-type="none" controlscollectionname="TemplateFr1_drpProductType" data-configid="TemplateFr1_drpProductType" holdername="TemplateFr1Holder">
<option value=""></option>
<option value="7">Expedited</option>
<option value="8">Premier</option>
<option value="9">Value</option>
</select>
</body></html>
I created a simple test class - and it works lovely!
Pasting the lot so you can see i do nothing other than open the page, use your code and select the element.
public class StackTest {
private String baseUrl = "C:\\Git\\stackTest.html";
private WebDriver driver;
#Before
public void CreateWebDriver()
{
System.setProperty("webdriver.chrome.driver", "src/test/resources/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get(baseUrl);
}
#After
public void CloseAndQuitWebDriver() {
driver.close();
driver.quit();
}
#Test
public void approach1_ExistingCode()
{
Select dropDown = new Select(driver.findElement(By.xpath("//*[#id=\"PWCMasterPage_PWCWebPartManager_gwpTemplateFr1_TemplateFr1_drpProductType\"]")));
dropDown.selectByValue("8");
}
}
In my opinion, the problem isn't selenium, the problem isn't the xpath, as long as you're doing what #SeleniumUser002 says in his answer then the problem isn't object accessibility.
Have a think about:
What is your site doing that's special?
Is it doing anything script based which creates/populates this drop down at run time?
When you captured the html did you capture it from chrome manually or chromedriver at runtime? (try the latter if you didn't already - Running manually is what a user sees, but chromedriver is what selenium sees. Be careful not to click on anything else other than the object when inspecting so you don't skew the results)
Are you doing any other steps in the script that can influence this dropdown?
First thing i would say to really fixing this issue is to use a breakpoint before your broken line and slowly step though the actions that lead the issue. See if the page is behaving differently at runtime. Walking through slowly also removes synchronisation issues and once the code works once, if it goes back to being flaky you can rule out the code and focus on a better wait strategy.
If that doesn't work and you're STILL seeing all the options present but cannot select, do a dump of what selenium can see:
#Test
public void debug_WhatAreMyOptions()
{
Select dropDown = new Select(driver.findElement(dropdownIdentifier));
System.out.println("dropdown has "+ dropDown.getOptions().size()+" options");
System.out.println("the options are....");
for (var dropdownOptions : dropDown.getOptions()) {
System.out.println(dropdownOptions.getText());
}
}
That might help you actually figure out what's happening to solve the issue.
Without that debugging information no one can tell you what the problem is - but i can suggest work arounds!
Try these...
Set this up:
private By dropdownIdentifier = By.xpath("//*[#id=\"PWCMasterPage_PWCWebPartManager_gwpTemplateFr1_TemplateFr1_drpProductType\"]");
Then try old fashioned clicks without a select object:
public void approach2_Clicks()
{
driver.findElement(dropdownIdentifier ).click(); // to activate
driver.findElement(dropdownIdentifier ).findElement(By.xpath("//*[#value='8']")).click();
}
Or try our old friend javascript:
public void approach3_Javascript()
{
var dropdown = driver.findElement(dropdownIdentifier);
((JavascriptExecutor) driver).executeScript("arguments[0].value='8'", dropdown);
}
However - these work arounds are only possible if the list is populated... My gut tells me that the data isn't there to select at runtime, but as you say it's an internal link so only you can verify that :-)
Give it a go and let us know.
Are you using safari?
If so, there's known issues with webdriver and safari. The long and short of it is to use the driver provided by apple.
This is the selenium issue: https://github.com/SeleniumHQ/selenium/issues/3145
If you look at:
https://webkit.org/blog/6900/webdriver-support-in-safari-10/
They say:
"Safari’s driver is launchable via the /usr/bin/safaridriver
executable, and most client libraries provided by Selenium will
automatically launch the driver this way without further
configuration."
try below solution with WebDriverWait to avoid synchronization issue:
WebDriverWait wait = new WebDriverWait(driver,30);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("PWCDropDownList")));
Select drpCountry = new Select(element);
drpCountry.selectByValue("8");
I want to locate the "item1" div tag in the following DOM. I tried in different ways. But I could not make it happen.
<html></html>
<frameset ... >
<frame>
</frame>
<frame id= "dynamic value" name = "dynamic value">
<html >
<head></head>
<body>
<div name = "item1">
<div name = "item2">
So , I tried the following ways to locate it. But no such element exception was thrown.
driver.getElementsByTagName("frame")[1].getElementsByTagName("div")[0]
driver.swithTo().frame(1);
driver.getElementsByTagName("div")[0]
You should switch to frame before you search for an element.
Try this:
frame = driver.getElementsByTagName("frame")[1]
driver.swithTo().frame(frame);
driver.getElementsByTagName("div")[0]
Note, I am not sure what is getElementsByTagName(), it looks like some sort of custom method for findElement(), so I just copypasted it into my solution from your example.
getElementsByTagName() DOM method in JavaScript
Source
Seems like you are using wrong method to locate an element using tag name.
In Selenium Java, Use below code snippet to switch into frame
driver.swithTo().frame(1); // index = 1 means 2nd frame
driver.findElements(By.tagName("div"))[0]
And with ExplicitWait conditions (to avoid synchronization related issue)
WebDriverWait wait = new WebDriverWait(driver,10);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frameName);
There are a couple of things you need to consider:
Using Selenium while dealing with <iframe> you can safely ignore the <frameset>
It would be difficult to identify the desired <iframe> through their index as it will be inconclusive which <iframe> loads faster.
As the the desired element is within an <iframe> so to locate the element you have to:
Induce WebDriverWait for the desired frameToBeAvailableAndSwitchToIt().
Induce WebDriverWait for the desired visibilityOfElementLocated().
You can use either of the following Locator Strategies:
Using CSS_SELECTOR:
new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.cssSelector("iframe#dynamicValue[name='dynamicValue']")));
WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div[name='item1']")));
Using XPATH:
new WebDriverWait(driver, 20).until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.xpath("//iframe[#id='dynamicValue' and #name='dynamicValue']")));
WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[#name='item1']")));
Reference
You can find a coupple of relevant discussions in:
Is it possible to switch to an element in a frame without using driver.switchTo().frame(“frameName”) in Selenium Webdriver Java?
Ways to deal with #document under iframe
I'm trying to click on an element but I always get the error "cannot locate an element using..".
I've tried it with find by class, by csselector, and by XPath. I also tried the a class first and then the span class element but it's still not working. It's definitely the correct frame, too.
It's really weird because it worked two weeks ago, I didn't change anything in the code and now it's not working. Is it possible that the element is constantly changing? If so, how can I make sure that it still finds the element without adjusting my code every time?
<a class="ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all" href="#" aria-label="Close" role="button">
<span class="ui-icon ui-icon closethick">
::after
</span>
</a>
This is my current code now which still isn't working:
driver.switchTo().defaultContent();
driver.switchTo().frame("frame_vehicleFileTab");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
WebElement closePrint = (new WebDriverWait(driver, 10)).until(
ExpectedConditions.elementToBeClickable(By.xpath("//*[#aria-label='Close']")));
closePrint.click();
After trying DebanjanB's suggestion by searching for the element:
driver.findElement(By.xpath("//a[#class='ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all' and #aria-label='Close']")).click();
I get this error: org.openqa.selenium.ElementNotInteractableException: Element could not be scrolled into view
Update: I fixed it by getting the Selenium IDE extension for Firefox and then choosing the xpath that was generated by the extension together with the javascript executor:
WebElement closePrint = (new WebDriverWait(driver, 10)).until(
ExpectedConditions.presenceOfElementLocated(By.xpath("//div[#id='FileTab:Form:j_id674351400_da78919']/div/a/span")));
JavascriptExecutor js1 = (JavascriptExecutor)driver;
js1.executeScript("arguments[0].click();", closePrint);
I don't know why that xpath works now but I'm glad it does. Thanks everyone for your suggestions!
It will be tough to locate the element through the <span> tag as it is a pseudo element. To locate the element you can use either of the following Locator Strategies:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("a.ui-dialog-titlebar-icon.ui-dialog-titlebar-close.ui-corner-all[aria-label='Close']"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#class='ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all' and #aria-label='Close']"))).click();
As far as I can see in the HTML you have provided:
You can use By.XPATH with this XPATH: "//*[#aria-label='Close']".
Like this:
d.findElement(By.xpath("//*[#aria-label='Close']")).click();
EDIT:
Try using Actions with an Offset this helps if there is an element covering it, this happens with iFrames.
Here is a code snip:
WebElement closePrint = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[#class='ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all' and #aria-label='Close']")));
int width = closePrint.getSize().getWidth();
Actions clicker= new Actions(driver);
act.moveToElement(closePrint).moveByOffset((width/2)-2, 0).click().perform();
Hope this helps you!
In addition to DebanjanB's suggestion, I would also suggest you to use below JavaScript utility to scroll down till the element is visible.
WebElement element = driver.findElement(By.xpath("//a[#class='ui-dialog-titlebar-icon ui-dialog-titlebar-close ui-corner-all' and #aria-label='Close']"));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
I am trying to select a value available in a read only drop down and I have tried so many options but still failing to select the desired option. The drop down has two values available ValueOne and ValueTwo. By default the ValueOne is selected and in my case I need to select ValueTwo. I used firebug to get the below code when I click on the drop down and do Inspect Element with firebug
The Code is :
<td class="rcbInputCell rcbInputCellLeft" style="width:100%;">
<input id="ctl00_ContentPlaceHolder1_RadGrid1_ctl00_ctl02_ctl02_EditFormControl_rcbControllerType1_Input" class="rcbInput radPreventDecorate" type="text" readonly="readonly" value="ValueOne" name="ctl00$ContentPlaceHolder1$RadGrid1$ctl00$ctl02$ctl02$EditFormControl$rcbControllerType1" autocomplete="off">
</td>
So far I have tried
1----------
Select DropDown = new Select(driver.findElement(By.id("ctl00_ContentPlaceHolder1_RadGrid1_ctl00_ctl02_ctl02_EditFormControl_rcbControllerType1_Input")));
DropDown.selectByVisibleText("ValueTwo");
and I get an exception as
:org.openqa.selenium.support.ui.UnexpectedTagNameException: Element should have been "select" but was "input"
2------------
WebElement Dropdown = driver.findElement(By.id("ctl00_ContentPlaceHolder1_RadGrid1_ctl00_ctl02_ctl02_EditFormControl_rcbControllerType1_Input"));
Select clickThis = new Select (Dropdown);
clickThis.selectByVisibleText("ValueTwo");
Get Exception:
org.openqa.selenium.support.ui.UnexpectedTagNameException: Element should have been "select" but was "input"
I also tried selectByIndex but still get the above exception message.
3--------------
driver.findElement(By.id("ctl00_ContentPlaceHolder1_RadGrid1_ctl00_ctl02_ctl02_EditFormControl_rcbControllerType1_Input")).sendKeys("ValueTwo");
Nothing happens and the case is marked as Pass. No error no exception.
Also I am running my webscript on firefox 38.0.5 with selenium 2.46.0 with eclipse TestNG.
I have confirmed the frame is not an iframe.
Please suggest the solution.
The root problem might be, that this is not a standard select box but an javascript based solution. The code above just shows the 'host' html element. I am pretty sure that there will be a) a previous hidden element that becomes visible or b) a newly created element in your DOM that holds the values. You have to find those (dev tools or firebug) to interact with.
Some pseudo code that might appear (just to get a hint):
<ul>
<li id="element1">ValueOne</li>
<li id="element2">ValueTwo</li>
</ul>
And after it appears (wait for in selenium) you just have to click the desired element.
Find your xpath through firepath addon in firefox.
driver.findElement(By.xpath(".//*#id='ctl00_ContentPlaceHolder1_RadGrid1_ctl00_ctl02_ctl02_EditFormControl_rcbControllerType1_Input']")).click();
Select value in dropdown ->goto firpath by right click and copy xpath
driver.findElement(By.xpath(".//*#id='ctl00_ContentPlaceHolder1_RadGrid1_ctl00_ctl02_ctl02_EditFormControl_rcbControllerType1_Input']/span[3]")).click();
hope you will find your solution :-)
You can use this :-
driver.findElement(By.id("ctl00_ContentPlaceHolder1_RadGrid1_ctl00_ctl02_ctl02_EditFormControl_rcbControllerType1_Input")).sendKeys("ValueTwo", Keys.ARROW_DOWN, Keys.ENTER)
you can use the following code. Here what I have done is find the dropdown, click on it and find the option to select and send down key until we see the element to select and after click on it.
public class InputDropdownselect {
#Test
public void login() throws Exception
{
System.setProperty("webdriver.chrome.driver", "G:\\drivers\\chrome\\chromedriver_win32\\chromedriver.exe");
WebDriver driver= new ChromeDriver();
driver.get("https://yourwebsite.com");
driver.manage().window().maximize();
driver.findElement(By.id("txtuser")).sendKeys("123456");
driver.findElement(By.id("txtpassword")).sendKeys("Abc!#1");
driver.findElement(By.id("log-btn")).click();
Thread.sleep(2000);
driver.findElement(By.id("enrollment")).click();
//driver.findElement(By.xpath("//*[#id=\"enrollment\"]")).click();
driver.findElement(By.xpath("//*[#id=\"studentBasicForm\"]/div[2]/div[9]/div/div/input")).click();
Actions action= new Actions(driver);
WebElement joiningYear=driver.findElement(By.xpath("//input[#placeholder=\"Joining Year Group\"]/following::ul[1]/descendant::li/following::span[contains(text(),\"8\")]"));
do {
action.sendKeys(Keys.ARROW_DOWN).perform();
} while (!joiningYear.isDisplayed());
joiningYear.click();
}
}