Capturing a text/title on the webpage using Selenium WebDriver - selenium

I am attempting to capture a text (title for different panels on a webpage) and verify the text content. I tried using the xpath to capture the text, but surprisingly on WebDriver, it fails. The same xpath seems to work perfectly fine with the Selenium RC. I wonder why WebDriver does not seem to recognize the xpath while RC does!! The code I have tried is given below:
assertEquals("Identification requests", driver.findElement(By.xpath("//span[8]")).getText());
I also tried the complete xpath:
assertEquals("Identification requests", driver.findElement(By.xpath("html/body/div[2]/div[2]/div/div/div[1]/div/div[2]/div[2]/div/div/kibana-panel/div/div[1]/div[2]/div/span[8]")).getText());
I attempted using the class variable too, but none of these seem to be returning any results. All the attempts fail with an error that the element was not found.
The html code for that portion is as shown below:
<span class="panel-text panel-title ng-binding">Identification requests</span>
The HTML code surrounding the span portion mentioned above is as shown below:
<div class="row-fluid panel-extra">
<div class="panel-extra-container">
<span class="extra row-button" ng-show="panel.editable != false && panel.removable != false">
<span class="extra row-button" ng-hide="panel.draggable == false">
<span class="row-button extra" ng-show="panel.editable != false">
<span class="row-button extra ng-scope" ng-show="task.show" ng-repeat="task in panelMeta.modals">
<span class="row-button extra ng-scope" ng-show="task.show" ng-repeat="task in panelMeta.modals">
<span class="row-button extra ng-scope" ng-show="task.show" ng-repeat="task in panelMeta.modals">
<span class="row-button extra" ng-show="panelMeta.loading == true" style="display: none;">
<span class="panel-text panel-title ng-binding">Identification requests</span>
</div>
</div>
</div>
I have doubts about why the xpath that works for RC wouldn't work for WebDriver. And how I would be able to capture the text?

I would recommend the following (use css selector):
String spanCssSelector ="span.panel-text.panel-title.ng-binding";
WebElement spanItem=driver.findElement(By.cssSelector(spanCssSelector));
String textObtained= spanItem.getText().trim();
assertEquals(textObtained,"Identification requests");
Hope this works for you.

You can use assert
assertEquals("Identification requests", driver.findElement(By.xpath("//span[starts-with(#class, 'panel-text')]")).getText());
Or
assertEquals("Identification requests", driver.findElement(By.xpath("//span[#class='panel-text panel-title ng-binding']")).getText());
Or just findElement via text() function of Xpath:
driver.findElement(By.xpath("//span[starts-with(#class, 'panel-text')][text()='Identification requests']));
Or via full class attribute value:
driver.findElement(By.xpath("//span[#class='panel-text panel-title ng-binding'][text()='Identification requests']));

Related

InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified error clicking on div ng-click element with Selenium

I am trying to select
<div ng-click="select('expert')" class="select-exp__item select-exp__item_active" ng-class="{'select-exp__item_active': 'expert'===selected}" style="">
I have tried a few things
driver.find_element_by_css_selector("div[ng-click='select('expert')']").click()
driver.find_element_by_class_name('select-exp__item-title').click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable(By.XPATH("//div[#class='select-exp__item select-exp__item_active']").click()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable(By.XPATH("//div[#class='select-exp__item select-exp__item_active' and contains(#ng-click, 'select('expert')')]").click()
...but I get the same error each time:
InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified
Grateful for any guidance, have googled "selenium ng-click" extensively without much luck and still learning Selenium, thank you.
Here's the full HTML:
<div class="agmodal__wrapper agmodal onboarding-wrapper ng-scope agmodal__wrapper--visible" ng-controller="OnboardingController as ctrl" ng-class="{'agmodal__wrapper--visible': ctrl.shown}" tabindex="-1" style="">
<div class="onboarding">
<div class="onboarding__body">
<!-- ngIf: ctrl.onboardingService.step === 1 --><section class="select-exp step ng-scope" ng-if="ctrl.onboardingService.step === 1" style="">
<div class="select-exp__header step__header">
<div class="select-exp__title step__title">Welcome to AMZScout PRO Extension</div>
<div class="select-exp__desc step__desc">
PRO Extension helps you find the perfect product to sell on Amazon
</div>
</div>
<div class="select-exp__body">
<div class="select-exp__body-title">
Select your experience level with Amazon</div>
<div class="select-exp__body-desc">
We will adjust the amount of pop up tips and certain parameters based on your experience. You will be able
to
change this choice later in the Settings.</div>
<div class="select-exp__items">
<div ng-click="select('beginner')" class="select-exp__item" ng-class="{'select-exp__item_active': 'beginner'===selected}">
<div class="select-exp__item-title">Beginner</div>
<div class="select-exp__item-desc">If you are new to Amazon research, you’ll see vital parameters that
will help you choose a great
product quickly. Great for learning.</div>
</div>
<div ng-click="select('expert')" class="select-exp__item select-exp__item_active" ng-class="{'select-exp__item_active': 'expert'===selected}" style="">
<div class="select-exp__item-title">Expert</div>
<div class="select-exp__item-desc">As an expert, you’ll see the full data and be able to fine-tune your
research.</div>
</div>
</div>
</div>
This error message...
InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified
...implies that the selector which you have used isn't a valid selector expression.
Analysis
As per your first code trial:
driver.find_element_by_css_selector("div[ng-click='select('expert')']").click()
( and ) have a special effect when used within a css-selectors. So the expression stands invalid. You need to escape the characters.
Solution
As the desired element is an Angular element you need to use WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.select-exp__item.select-exp__item_active[ng-click=\"select('expert')\"]"))).click()
XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='select-exp__item select-exp__item_active' and #ng-click=\"select('expert')\"]"))).click()
Try located the element with css selector like this:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, 'div.select-exp__item.select-exp__item_active'))).click()
You are wrong in using WebdriverWait, your code:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable(By("value").click()
It's should like this pattern:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By, 'value'))).click()
Explicit Waits

How do i fetch the text from div tag and print in one line

//div[#id='Container']/div/div[2] -This line gives me the following code:
<div style="margin-left: auto;margin-right: auto;width: 25%;" xpath="1">
<span class="dxeBase_Office2010Silver field-fnt" id="Version" style="color:#000000 !important;">
Version
</span>
9.1.2.170
</div>
How do i print "Version is 9.1.2.170" in one line.
Any help will be appreciated.
To print the text Version is 9.1.2.170 you can use:
Using Java and xpath:
System.out.println(driver.findElement(By.xpath("//div/span[#class='dxeBase_Office2010Silver field-fnt' and #id='Version']/..")).getText());
Using Python and xpath:
print(driver.find_element_by_xpath("//div/span[#class='dxeBase_Office2010Silver field-fnt' and #id='Version']/..").text)

trouble making in xpath for "ul" html code in selenium webdriver

HTML code:
<div id="routingPanel" class="">
<div id="routingPanelRight">
<ul id="routingList" class="ui-sortable">
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="srl" data-id="15">
<a class="ui-corner-all" tabindex="-1">AS-HTTS-US-LAN-SW</a>
<span class="fa fa-trash"/>
<span class="type">[srl]</span>
</li>
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="queue" data-id="119">
<a class="ui-corner-all" tabindex="-1">AS-EMEA-NORTH</a>
<span class="fa fa-trash"/>
<span class="type">[queue]</span>
</li></ul></div></div>
I need to click on a button which is having the span class"fa fa-trash" but it is inside li class. And i have list on buttons on the page with li class changing.
I am giving testdata from excel file so i can't use the direct value.
i tried to use this xpath
.//*[#id='routingList']/li[5]/span[1] //testdata1
.//*[#id='routingList']/li[2]/span[1] //testdata2
where li value changes everytime from excel file.
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated((By.xpath("//ul[#id='routingList']/li/span[1]")))).click();
List<WebElement> options = driver.findElements(By.xpath("//ul[#id='routingList']/li/span[1]"));
for (WebElement option : options) {
if(testData.equals(option.getText()))
option.click();
Tried above code but it is deleting only one from the list ,where i have passed two more testdata that needs to be deleted.
Need suggestions Please
According to the information you gave me in comments, I think the problem is that you are trying to get a text from an element that doesn't contain text.
Let's say your testData is AS-HTTS-US-LAN-SW. In the HTML you provided and the xpath you mentioned, you are selecting an autoclosing tag <span class="fa fa-trash"/>. Once this tag is selected, you are trying to get the text inside of it, and there is none.
<ul id="routingList" class="ui-sortable">
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="srl" data-id="15">
===========================
<a class="ui-corner-all" tabindex="-1">AS-HTTS-US-LAN-SW</a> ----> The text is contained here
<span class="fa fa-trash"/> ---> No text in that tag
===========================
<span class="type">[srl]</span>
</li>
</ul>
So, basically, you have to modify a little bit your xpath from : //ul[#id='routingList']/li/span[1] to : //ul[#id='routingList']/li/a to get the text, and then go back to the parent node to find your button with : ../span[contains(#class, 'fa fa-trash')]
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated((By.xpath("//ul[#id='routingList']/li/span[1]")))) // removed the click here because you were clicking on the first element of the list
List<WebElement> options = driver.findElements(By.xpath("//ul[#id='routingList']/li/a"));
for (WebElement option : options) {
if(testData.equals(option.getText()))
option.findElement(By.xpath("../span[contains(#class, 'fa fa-trash')]")).click();
Tell me if it helped
I know you already accepted an answer but there's a more efficient way to do this. You can specify the text you are looking for as part of the XPath. So, you do a single search instead of looping through all the options which can be a performance hit if there are many options. Also, with something like this you are likely to use it more than once so put it in a function.
In this case, the function would take in the string you are looking for and then click the appropriate element.
public void selectRegion(String regionName)
{
driver.findElement(By.xpath("//a[.='" + regionName + "']/following-sibling::span[#class='fa fa-trash']")).click();
}
and you would call it like
selectRegion(testData);
The function looks for an A tag that contains the desired text and then clicks the sibling SPAN with class fa fa-trash.

No such element Exception. class name with double__

I am trying to get the text under the tag. That is Arduus, Gstaad, Switzerland. I tried with the classname and also with xpath.
driver.findElement(By.className("chalet-details__title"));
String chaletTitle = driver.findElement(By.xpath("//div/h1[#class='chalet-details_title']")).getText();
But its giving NoSuchElementException. The classname has double underscore(__) .Is it because of that not working? Can anyone help me with this?
<div class="col-md-12 col-sm-12 col-xs-12">
<h1 class="chalet-details__title">
<span class="chalet-details__title-property">Arduus</span>,
<a class="chalet-details__title-resort" href="/ski- resorts/switzerland/gstaad">Gstaad</a>,
<a class="chalet-details__title-country" href="/ski- resorts/switzerland">Switzerland</a>
</h1>
<div class="chalet-details__rating">
<div class="chalet-details__wrapper">
<span class="chalet-details__star" style="width: 108px;"></span>
<span class="chalet-details__mask"></span>
</div>
</div>
</div>
You can try something like:
driver.findElement(by.cssSelector("h1.chalet-details__title"))
I just tried this and it worked fine with the provided html, if this still fails for you, can you verify that there aren't any iframes on the page.
Both your locators are OK, but you might need to wait for your element to be present in DOM:
WebDriverWait wait= new WebDriverWait(driver,20 );
String chaletTitle = wait.until(ExpectedConditions.presenceOfElementLocated(By.className("chalet-details__title"))).getText();
Another reason for NoSuchElementException: your element could be located inside an iframe, so you need to switch to that frame before handling target element:
driver.switchTo().frame("iframeNameOrId");
If it has no attributes as id or name:
WebElement someFrame = driver.findElement(By.xpath("//iframe[#someAttr='someValue']"));
driver.switchTo().frame(someFrame);
To get all the text under h1 tag find all elements using locator as follows:
List<WebElement> items = driver.findElements(By.cssSelector("h1.chalet-details__title > *")); //it will find all elements immediately under the h1 tag
Now, iterate over the elements.
Complete code:
List<WebElement> items = driver.findElements(By.cssSelector("h1.chalet-details__title > *"));
for(WebElement item : items){
System.out.println(item.getText());
}

want to gettext from span

I want to get text "Entered code is already exists" using selenium webdriver , I tried using id="code_error" but no use
HTML code is as follows :
<div class="leftsection">
<div class="form-element">
<fieldset>
<label><span class="required">*</span>Code:</label>
<input type="text" maxlength="6" value="" id="code" name="code" style="border: 1px solid rgb(178, 178, 178);">
</fieldset>
<span role="alert" class="errormsg" id="code_error">Entered Code already exists</span>
</div>
i used xpath , id, cssselecor but it returns NULL.
Have a look at the below code..works perfectly
options=driver.find_elements_by_class_name("errormsg")
for i in options:
print i.text
when selenium can parse JavaScript, you can use this:
var text = document.getElementById('sbucode_error').innerHTML;
Please use Selenium Ide to check whether id=code_error selector pointing to your element then use the below mentioned code to get text from that.
driver.findElement(By.id("code_error")).getText();
String text = driver.findElementById("code_error").getText(); should do the trick for you :)