Xpath/ search input node by text - xpath

I have a search box (<input> element), and I try to get the element by the text that written into it.
I try to do the next:
// input [#value= "my text"]
but it doesn't work (just to be clear - the value is not attribute of the input element. accully, when I do inspect element, I don't see the text that written in this text box).
<div class="EwdOOOOO">
<div class="GOOOEOOO">Hello </div>
<input type="text" class="GOBLEOOO">
</div>
and the seatch box I put:
"How are you?"
You can see that "How are you?" isn't found in the DOM.
Thanks.

Are you sure to get your input and populate it ?
like :
WebElement input = driver.findElement(By.xpath("//input[#class='GOBLEOOO']"));
input.sendKeys("How are you?");
So you can get your element like that :
WebElement inputByValue = driver.findElement(By.xpath("//input[#value='my text']"));
or you have another way to do that
WebElement inputByValue= driver.findElement(By.xpath("//input[contains(#value,'my text')]"));
contains() return true if the value of your attribute #value contains the next parameter (string)
Because there is always a value attribute in an input since you type values in.
Here for more Input specs.
If you want to found an element with the value you typed in the input field you can use this xpath.
// you get the value you typed in the input
String myValue = driver.findElement(By.xpath("//input[#class='GOBLEOOO']")).getAttribute("value");
//you get a element that contains myValue into his attributes
WebElement element = driver.findElement(By.xpath("//*[contains(#id ,myValue) or contains(#value, myValue) or contains(#name, myValue)]"));

See my answer here. Sometimes the text value that you are setting is assigned as a "value" attribute of text box and not as "text"
WebElement input = driver.findElement(By.cssSelector("input[type='text']"));
input.sendKeys(enteredValue)
String retrievedText = input.getAttribute("value");
if(retrievedText.equals(enteredValue)){
//do stuff
}

Related

I need to click this input only if it has "aria-checked ="true"

I need to click this input only if it has "aria-checked ="true"
<input class="mat-checkbox-input cdk-visually-hidden" type="checkbox" id="mat-checkbox-131-input" tabindex="0" aria-checked="true" style="" xpath="1">
Ruby:
aria_checked = true
if aria_checked = true
impressora_etiqueta = "//mat-checkbox[#id='mat-checkbox-23']/label/div"
page.find(:xpath, impressora_etiqueta).click
end
There are many ways to do what you want - simplest is probably
page.first('#mat-checkbox-23[aria-checked="true"]', minimum: 0)&.click
which will look for the first element with the given id and aria-checked = "true" and click it if one exists.
Note: the id in your test and sample HTML didn't match so I went the id from your test, adjust as needed. Also you have a class of cdk-visually-hidden shown -- If that's actually making the element not visible on the page, then this won't work and you'll need to add more surrounding HTML to your question with a better description of exactly what you're trying to do (you can't click on non-visible elements)

css/xpath selector to exclude the child node in the element when using selenium webdriver (java)

CSS/xpath selector to get the link text excluding the text in .muted.
I have html like this:
<a href="link">
Text
<span class="muted"> –text</span>
</a>
When I do getText(), I get the complete text like, Text-text. Is it possible to exclude the muted subclass text ?
Tried cssSelector = "a:not([span='muted'])" doesn't work.
xpath = "//a/node()[not(name()='span')][1]"
ERROR: The result of the xpath expression "//a/node()[not(name()='span')][1]" is: [objectText]. It should be an element.
AFAIK this cannot be done with CSS selector only. You can try to use JavaScriptExecutor to get required text.
As you didn't mention programming language you use I show you example on Python:
link = driver.find_element_by_css_selector('a[href="link"]')
driver.execute_script('return arguments[0].childNodes[0].nodeValue', link)
This will return just "Text" without " -text"
You cannot do this using Selenium WebDriver's API. You have to handle it in your code as follows:
// Get the entire link text
String linkText = driver.findElement(By.xpath("//a[#href='link']")).getText();
// Get the span text only
String spanText = driver.findElement(By.xpath("//a[#href='link']/span[#class='muted']")).getText();
// Replace the span text from link text and trim any whitespace
linkText.replace(spanText, "").trim();

Can nightwatchjs perform an assertion based on a reference with accuracy?

In a case where a same element could change for a different id or name depending on many factors, I would be able to do an assertion on this element with accuracy.
Doest nighwatchjs permit to do an assertion based on a relative position like can do SAHI ? (Left of this element ..., Under a div, etc.)
I want to avoid Xpath solutions, it's based on the element type (div, id, name, etc.) and if I set it to all types:
//*[contains(text(),'hello world')]
I will get many occurrences and couldn't be able to know which one I'm trying to assert.
e.g : Running the same test on the same page, I would be able to find this "hello world" even if the div id changes or another element.
<div id="homebutton">
<p>
<a href=#>
<span name="hm">Home</span>
<a>
</p>
</div>
<div id=[0-9]>
<p>
<a href=#>
<span name="hw">hello world</span>
<a>
</p>
</div>
[...]
<div id=[0-9]>
<p>
<a href=#>
<span name="hw">hello world</span>
<a>
</p>
</div>
<div id="logoutbutton">
<p>
<a href=#>
<span name="lo">Logout</span>
<a>
</p>
</div>
Test example : Assert element containing string "hello world", not the one which is near the logout button but the one which is near the home button.
Expanding on my previous answer, you have two options, if the Hello World you want is *always the 2nd to last, appearing just before the Logout button then you want the 2nd to last of a type, you could use an xPath selector like this:
"//*[.='hello world'][last()-1]"
That's right in the Rosetta doc I shared with you, so you should know that by now
Another option is to get a collection of all matches. For that, I'd write a helper function like so:
module.exports = {
getCountOfElementsUseXpath : function (client, selector, value) {
// set an empty variable to store the count of elements
var elementCount;
// get a collection of all elements that match the passed selector
client.getEls(selector, function(collection) {
// set the variable to be that collection's length
elementCount = collection.length;
// log the count of elements to the terminal
console.log("There were " + elementCount + " question types")
return elementCount;
});
},
};
Then you can use that with some formula for how far your selector is from the last element.
The xpath selector "//div[contains(text(), 'hello world')]"
would match on both of the elements you've shown. If the element itself can change, you would use a wildcard: "//*[contains(text(), 'hello world')]"
For a match, on any element with that exact text:
"//*[.='hello world']"
A great source, a "Rosetta stone", for selector construction
To use an xpath selector with nightwatch:
"some test": function(client){
client
.useXpath().waitForElementPresent("//div[contains(text(), 'hello world')]", this.timeout)
}
The Xpath solution is okay but here is the solution I needed, more generic and giving many more options :
Using elements and manage to return an array of childrend elements
I choosed to return an array of objects with data matching my needs :
[{ id: webElementId, size: {width: 18, height: 35}, ...}, {id: webElementId, ...}, etc.]
With those informations, I can do many things:
Find an element with a specific text, attribute or cssproperty and
perform any action on it, like assertions or click on the right of it through a calculation of his size.
Mouse hover each elements matched (if you want to browse tabs with
submenus ul li / ol li)
More data is filled, more you can perform assertions.

XPath - Nested path scraping

I'm trying to perform html scrapping of a webpage. I like to fetch the three alternate text (alt - highlighted) from the three "img" elements.
I'm using the following code extract the whole "img" element of slide-1.
from lxml import html
import requests
page = requests.get('sample.html')
tree = html.fromstring(page.content)
text_val = tree.xpath('//a[class="cover-wrapper"][id = "slide-1"]/text()')
print text_val
I'm not getting the alternate text values displayed. But it is an empty list.
HTML Script used:
This is one possible XPath :
//div[#id='slide-1']/a[#class='cover-wrapper']/img/#alt
Explanation :
//div[#id='slide-1'] : This part find the target <div> element by comparing the id attribute value. Notice the use #attribute_name syntax to reference attribute in XPath. Missing the # symbol would change the XPath selector meaning to be referencing a -child- element with the same name, instead of an attribute.
/a[#class='cover-wrapper'] : from each <div> element found by the previous bit of the XPath, find child element <a> that has class attribute value equals 'cover-wrapper'
/img/#alt : then from each of such <a> elements, find child element <img> and return its alt attribute
You might want to change the id filter to be starts-with(#id,'slide-') if you meant to return the all 3 alt attributes in the screenshot.
Try this:
//a[#class="cover-wrapper"]/img/#alt
So, I am first selecting the node having a tag and class as cover-wrapper and then I select the node img and then the attribute alt of img.
To find the whole image element :
//a[#class="cover-wrapper"]
I think you want:
//div[#class="showcase-wrapper"][#id="slide-1"]/a/img/#alt

Validating input type number in html5

I want to restrict entry of input onto a field of type number such that input cannot be outside range of min-max specified in the html.
input type = "number" min = "1" max = "5"
Is there a way of outputting the number field without the text box and i would rather not use
"input type = range"
as slider does not show value currently selected
Please help.
Thanks.
Based on what you said, I suggest using a simple input text field and check it's value validity on submission via JavaScript (as #Kush mentions above). You could also check it as the user types, or moves focus away from that field.
<form>
Only 1 to 100 <input type="text" name="number" pattern="\d{1,2}(?!\d)|100" title="one to hundreed only">
<input type="submit">
</form>

Resources