Unable to locate an element using and condition in xpath - selenium

When use the condition in Console it says the condition is true but when I run the script, I'm getting the unable to find the element.
Below is the HTML:
<div class="ipc-button__text">Sign In</div>
And the XPath I'm trying to use:
(//div[#class='ipc-button__text']) and (//div[contains(text(),'Sign')])

Try combining the expressions.
//div[#class='ipc-button__text' and contains(text(),'Sign')]
This should fix the issue.
Otherwise each //div expression would be evaluated separately and result in the whole expression being true (because both //div[#class='ipc-button__text'] and //div[contains(text(),'Sign')] are true somewhere in the document), but without a specific div element selected matching both sub-expressions.

Please use following xpath ---- //*[contains(text(),"Sign In")]

There might be the reason that XPath of the element is not loaded when we trying to perform action instead of doing simple use explicit wait condition before performing any action try to use the below approach.
// xpath = //*[contains(text(),"Sign In")]
WebDriverWait wait = new WebDriverWait(driver, timeInSeconds);
WebElement element
= wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(xpath)));
// Perform any action
element.click();

Related

selenium - locate a href link - Unable to find element with link text

I getting below error - if I use linktext() to locate specifications link
Error :
Unable to find element with link text == Specifications
As per the HTML you have shared incase linktext() shows error as:
Error : Unable to find element with link text == Specifications
As an alternative you may need to induce WebDriverWait for the desired element to be clickable and you can use either of the following solutions:
linkText:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.linkText("Specifications"))).click();
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("td.subtabTxtNsel>a.subtabTxtNsel[tag='a']"))).click();
xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//td[#class='subtabTxtNsel']/a[#class='subtabTxtNsel' and contains(.,'Specifications')]"))).click();
The problem is you are using specifications but it is Specifications.
Just with capital S , it should be working fine.
You can use explicit wait, something like :
new WebDriverWait(driver,20).until(ExpectedConditions.elementToBeClickable(By.linkText("Specifications"))).click();
OR with partial link Text :
new WebDriverWait(driver,20).until(ExpectedConditions.elementToBeClickable(By.partialLinkText("Specifications"))).click();
If both of them still are not working, then you can try this xpath :
//td[#class='subtabTxtNsel']/a[text()='Specifications' and #tag='a']
Your binding language is not specified, I have provided answer in JAVA.
UPDATE :
An explicit wait is code you define to wait for a certain condition to occur before proceeding further in the code. The worst case of this is Thread.sleep(), which sets the condition to an exact time period to wait. There are some convenience methods provided that help you write code that will wait only as long as required. WebDriverWait in combination with ExpectedCondition is one way this can be accomplished
Please refer this link for better understanding.

Selenium Webdriver: cssselector

I am trying to do SignIn for this. In it click on 'SignIn' which I have done it successfully. Now when trying to type in Username/Password using Xpath it shows exception which says
Exception in thread "main"
org.openqa.selenium.ElementNotVisibleException: element not visible
code is :-
driver.findElement(By.xpath(".//*[#id='load_form']/fieldset[1]/input")).sendKeys("test123");
driver.findElement(By.xpath(".//*[#id='load_form']/fieldset[2]/input")).sendKeys("test123");
I know this Xpath is same as used in SignUp form, so what are the other ways to locate these two fields? How we can use it by using cssselector?
Thanks for the help in advance.
Go One Level up on finding the relative xpath with
//div[#id='login']/form[#id='load_form']//input[#name='username']
//div[#id='login']/form[#id='load_form']//input[#name='password']
Try this
//For Username
driver.findElement(By.xpath("(//input[#name='username'])[2]")).sendKeys("username test");
//or
driver.findElement(By.cssSelector("#login > #load_form > fieldset > input[name='usernam']")).click();
//For password
driver.findElement(By.xpath("(//input[#name='password'])[2]")).sendKeys("password test");
//or
driver.findElement(By.cssSelector("#login > #load_form > fieldset > input[name='password']")).click();
the above codes are working for me.
There are basically two elements found by provided xpath, and it works with first found element which is invisible as your exception saying, you should try using cssSelector as below :-
driver.findElement(By.cssSelector("div#login input[name = 'username']")).sendKeys("test123");
driver.findElement(By.cssSelector("div#login input[name = 'password']")).sendKeys("test123");
Note:- For learning about cssSelector follow this url and for xPath follow this url
I'm suggesting you before selenium execution with the locator you need to sure that using locator is correct and returns single or multiple element at your browser console by pressing f12. for verify xPath you should use $x("your xpath expression") and for cssSelector you should use document.querySelector("your css selector expression")..
Hope it will help you..:)

How take XPATH inside a iframe?

Im trying to get the XPATH inside a iframe called "gadget_6"
i need the xpath of select div. Using selenium i do:
self.change_frame('__gadget_6') #Change to the correct iframe
after that, i try to do:
self.selec_orgvdc = self.driver.find_element(By.XPATH,'/html/body/div[5]/div/div/div/table/tbody/tr/td/div')
for posteriorly do:
self.selec_orgvdc.click
but i obtain the error:
InvalidSelectorException: Message: invalid selector: Unable to locate an element with the xpath expression /html/body/div[5]/div/div/div/table/tbody/tr/td/div because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '/html/body/div[5]/div/div/div/table/tbody/tr/td/div' is not a valid XPath expression.
Someone can help me?
New modification:
self.change_frame('__gadget_6')
time.sleep(4)
self.logger.info("Buscando orgvdc")
#self.selec_orgvdc = self.driver.find_element(By.CSS_SELECTOR,'div.GN4Y2ATIMD table div.gwt-Label')
self.selec_orgvdc = self.driver.find_element(By.XPATH,'//div[5]/div/div/div/table/tbody/tr/td/div')
self.logger.info("Encontrado!")
Hi to work with xpath inside iframe first you have to sitch your driver instance ti that iframe then only you can perform any action
1.To switch to an iframe plz do it like : driver.switchTo().frame("selfservice");
Also looking at your source code i can clearly see there is 2 (two) i frames
1.iframe id = __gadget_6
2.iframe id = selfservice
hence i can guess why its not working in your case cause you are switching to a wrong i frame
now try this xpath //*[#class='GN4Y2ATIMD']/div/div/div/table/tbody/tr/td/div to perform click this will surely work.
XPath shouldn't include the /html/body. try this:
self.selec_orgvdc = self.driver.find_element(By.XPATH,'//div[5]/div/div/div/table/tbody/tr/td/div')
Note that this will be quite brittle. Even better would be to do something like this CSS:
self.selec_orgvdc = self.driver.find_element(By.CSS,'div.GN4Y2ATIMD table div.gwt-Label')

Need help regarding Run Keyword if xpath matches and then click element

I am trying to validate xpath expression and if it is true click element .Following is the code that I am trying to do .
Xpath_combined variable returns Boolean : true . Please help me in correcting the syntax or valid expression
Variable
${xpath_combined} //div[text()='00:04:56:AC:41:F6'] AND //div[contains(text(),'Device-77')]
Keyword
Run keyword if ${xpath_combined} == "true" Click Element //i[#class='fa fa-lg fa-file-text-o grow']
Error from console output
Evaluating expression '//div\[text()='00:04:56:AC:41:F6'\] AND //div\[contains(text(),'Gambit-77')\] == "true"' failed: SyntaxError: invalid syntax (<string>, line 1)]
You can create different scenarios how to solve this question. But, you can try this solution:
Xpath = With xpath, find the the parent element which contains both elements. But this depends on your code structure f.e. Try to find body element, with two child elements containing specific text conditions:
xpath=//body[//div[text()='00:04:56:AC:41:F6'] AND //div[contains(text(),'Device-77')]]
Set variable the right way or use scalar. Note: we will use Get Matching Xpath Keyword, so we don't need to use 'xpath=' prefix
${xpath_combined}= Set Variable //body[//div[text()='00:04:56:AC:41:F6'] AND //div[contains(text(),'Device-77')]]
Get Matching Xpath Count It will return 1 occurence of xpath. There is only one body element which passes the xpath expression
${count}= Get Matching Xpath Count ${xpath_combined}
Run Keyword If If the xpath count is exactly 1 time, the elements are present on the page and you are allowed to click on icon. Note: don't forget to add xpath= prefix to Click Element locator
Run keyword if ${count} == 1 Click Element xpath=//i[#class='fa fa-lg fa-file-text-o grow']
Though the other solution is fully viable one, here's an alternative which is an it more universal.
It combines two keywords - Get Webelement which returns a selenium object if it exists, and Run Keyword And Return Status - which returns True if a keyword succeeds, False otherwise:
${locator}= Set Variable //body[//div[text()='00:04:56:AC:41:F6'] AND //div[contains(text(),'Device-77')]]
${target}= Set Variable //i[#class='fa fa-lg fa-file-text-o grow']
${the element is present}= Run Keyword And Return Status Get Webelement ${locator}
Run Keyword If ${the element is present} Click Element ${target}
Another benefit is that you are not constrained by an xpath locator - it'll work with css, id or whatever other strategy.
Alternatively, one could use Element Should Be Visible instead of Get Webelement, but that works only for elements actuaĺly visible, not just present in the DOM.

How to locate an element using selenium webdriver which doesn't have unique identifier like Name, Id, title etc?

I am new to Selenium. Not sure how to handle this scenario. I am working on a website which has several buttons with following code,
<a class="Some big class name" datacommunication="SelectItem" token="some token number" model-id="Id1" element="button">
<i class="classname">Book Ticket</i>
</a>
<a class="Some big class name" datacommunication="SelectItem" token="some token number" model-id="Id2" element="button">
<i class="classname">Book Ticket</i>
</a>
I tried to click on it using following commands,
ele = driver.FindElement(By.ClassName("Some big class name")); but it fails with following message, Compound class names are not supported. Consider searching for one class name and filtering the results.
ele = driver.FindElement(By.CssSelector("a[model-id='Id1']")); fails with 'Test method TestBot.HomeTest.bookTicket threw exception:
OpenQA.Selenium.WebDriverTimeoutException: Timed out after 10 seconds'
Tried using XPATH,
ele = driver.FindElement(By.XPath("\\\a[#model-id='Id1']")); doesn't work either.
I have no control on html. Can't change it.
Please let me know how to identify elements in such scenarios.
You can't have spaces in class names. Those are actually multiple classes separated by a space. You can find the above elements using a css selector
var ele = driver.FindElements(By.CssSelector(".Some.big.class.name"))
Of course, this will find both elements. To find just the first, you could use
var ele = driver.FindElement(By.CssSelector("a[model-id='Id1']"))
You can find help on css selectors here: http://www.w3schools.com/cssref/css_selectors.asp
Update:
I just noticed your XPath appears to have the slashes the wrong way around. If you wish to use XPath, try
//a[#model-id='Id1']
Note, however, that css selectors perform better than XPath.
There are multiple number of ways to locate your WebElement in Selenium WebDriver.
But always remember all are based on you attribute or combination of HTML tags so case could be any of them
1- First way is using id
2- 2nd one is Name
3- Class Name
4- Some time you can used Tagname
5- Some time linkText
6- Some time partial link text
7- Using xpath
8- Using css selector
So in you case we need to take help of Xpath and Css Selector
So xpath of you elements
Syntax : //[#attribute ='value of selected tag']
Example
id1: //a[#model-id='Id1']
id2: //a[#model-id='Id2']
For both element following are the css Selector
Syntax [attribute ='value']
id1:
a[model-id='Id1']
id2:
a[model-id='Id2']
http://www.slideshare.net/weekendtesting/css-selector-29312437
http://www.slideshare.net/weekendtesting/locators-in-selenium-bnt-09
Thanks a lot for help. I have used following code to overcome above mentioned issue,
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector("a[data-model-id='c5']"))).Click();
With above code, I am able to click on the button.
Thanks again for your help and knowledge sharing.
Amit
You can locate by using xpath.
WebElement ele = driver.findElement(By.xpath("//*[#class='Some big class name']"));
there is difference between findElements and findElement.
FindElement: findElement returns a single element.
FindElements : returns a list of same element.As in this example there are multiple classes with same class name , so use driver.findElements method .
driver.findElements will return a list of all elements with that class name .
Now , you have list of all elements but you want only one of the element.
So iterate over list to get a single element out of a list.
List<WebElement> elementList= driver.FindElement(By.ClassName("Some.big.class.name"));
Iterator itr = elementList.iterator();
while(itr.hasNext())
{
WebElement element = itr.next();
if(element.getAttribute("model-id").equals("Id1")){
element.click();
break;
}//if block ends here
}//while loop ends here
You can also use XPATH , if nothing works
To identify the elements in selenium there are multiple ways.
To see the details please refer BY Class.
Try to find the way which can identify the element uniquely. Start with id if available and if nothing works go for XPATH. XPATH is slower than id and CSS selector.