Get a css property with selenium webdriver by selectors - selenium

I am doing a exercise with client java to use cssSelector method to retrieve some objects having a particular web element's CSS property.
The statement
driver.findElements(By.cssSelector(".item-result .content-main .block-opening"))
returns all elements from page using the class ".item-result .content-main .block-opening" (refer to my blocks below) and all is fine up to there!
Nevertheless, I only want those which have a property text-indent whose value is -999em. To perform it, I first use
driver.findElements(By.cssSelector(".item-result .content-main .block-opening[text-indent]"))
to retrieve all elements having a text-indent css property but I realize that no element is matching while I have text-indent property inside my css block.
HTML block
<html id="ng-app" data-ng-app="rwd" data-ng-controller="AppCtrl" lang="fr" class="ng-
scope">
<head>...</head>
<body>
...
<span class="block-opening icon-time-filled ng-scope" data-ng-if="bloc.openClosed ==
'O'">Ouvert</span>
...
</body>
</html>
CSS block
.item-result .content-main .block-opening {
width: 25px;
color: #a1a1a1;
text-indent: -999em;
}
I was hoping to find exactly what i want to by the use of
driver.findElements(By.cssSelector(".item-result .content-main .block-opening[text-indent='-999em']"))
Since elements related to text-indent are not found, I am blocked to find those having text-indent to -999em.
Please any help would be appreciated!

Perhaps a little bit of a longer route but you could try getting a list of all the elements and checking the css-properties, with the appropriate method.
List<Webelement> elements = driver.findElements(By.cssSelector(".item-result .content-main .block-opening"));
for (Webelement element : elements) {
if (element.getCssValue("text-indent").equals("-999em")) {
return element;
}
}
Caveat, I've never tried to get the text-indent value, as such I can't guarantee that the above will work.
http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/WebElement.html#getCssValue(java.lang.String)

You can locate that element using xpath using inner text value
By.xpath("//span[text()='Ouvert']")

Related

Protractor Automation: Selection of element

I'm trying to automate selection of some products...Here's a screenshot
The user clicks on the top row of 'base' colours and then selects the desired colour from the resulting pallet beneath.
I am able to select a base colour without issue.
element(by.xpath('html/body/main-app/kf-sidebar-app/div[1]/app-container/div/dashboard/div/div/visualise/open-interface/div/div/div[2]/div[2]/digitalbridge-category-list/div/digitalbridge-category-view[2]/div/div[1]/div/div[2]')).click();
...selecting the desired colour is altogether much more maddening!!! The closest I've got has resulted in a "Element not visible" message....tried adding in 'waits' but no difference.
This code..
var EC = protractor.ExpectedConditions;
var paintSelected = element(by.xpath('.//div[#id="2386"]'));
browser.wait(EC.visibilityOf(paintSelected), 7000);
paintSelected.click();
..produces line-after-line of..
[11:27:22] W/element - more than one element found for locator By(xpath, .//div[#id="2386"]) - the first result will be used
This keeps running until the 7000ms timeout is reached. I've tried using 'first' but it's not 'recognised'....also tried [0] but again, not recognised.
Here's the line from Console...
<div _ngcontent-c63="" class="item circle" id="2386" style="background-image: url("https://shortbite.s3-eu-west-1.amazonaws.com:443/category/raw/941027c0-f6e6-434c-9ab9-66f9918c33e6.png?Signature=Zbffcvf73Nv9g2v9G3SmcYn6h24%3D&Expires=1510141234&AWSAccessKeyId=AKIAIUUATNKB37DELIXQ");"> </div>
Please try and save my sanity! Thanks
David
Try putting your selector into the console i.e $x(".//div[#id='2386']").
Just to see if you really have two elements with the same Id
Also do a find elements and debug the collection of elements.
One thing I have done with my extended framework is implemented a highlight element functionality.
IJavaScriptExecutor js = Driver as IJavaScriptExecutor;
js.ExecuteScript("arguments[0].setAttribute(arguments[1], arguments[2])", ReferenceElement, "style",
"border: 2px solid red; border-style: dashed;");
if you have id you can check all elements available with that id in chrome or firefox console like that:
$$('#2386')
$$ will return all, one $ will return the first one.
because if you have more than 1 element with the same locator, protractor will get the first one.
If there is no way to give you elements different locators you can get it by index.
for example in you code first loacte all elements and assign it to varible:
var allColors = $$('#2386'); // same as element.all(by.id('2386'))
or get them by index
var firstColor = $$('#2386').get(0); // or $$('#2386').first();
var secondColor = $$('#2386').get(1); // or $$('#2386').first();
Use firepath and find out the absolute xpath .
Then add some wait and try to click on the element using absolute xpath

Locating Element with same class in Selenium using c#

I am trying to access ABC. I know that simple By.ClassName("bb") will not work here. How else can I access this content.
<body>
<div id="Frame">
<div class="bb"></div>
<div class="bb">ABC</div>
</div>
</body>
You can use the below css selector to get the value of "ABC".
.bb:nth-child(2)
You can use "XPath" Expression to find or locating your element.
Example : element = findElement(By.xpath("Your xpath expression");
For your XML use following line.
element = findElement(By.xpath("/body/div/div[#class='bb'][node()]");
There is a way to do this in the search using XPath but I am not an XPath expert. I can give you a solution using CSS Selectors. Basically you grab all the DIVs with class bb and then search their text to find the desired text.
String searchText = "ABC";
IReadOnlyCollection<IWebElement> divs = driver.FindElements(By.CssSelector("div.bb"));
foreach (IWebElement div in divs)
{
if (div.Text == searchText)
{
break; // exit the for and use the variable 'div' which contains the desired DIV
}
}

Using Selenium to select text

Want to select the text "This is for testing selector" from below HTML code.
<div class="breadcrumb">
<a title=" Home" href="http://www.google.com/"> Home</a>
<span class="arrow">»</span>
<a title="abc" href="http://www.google.com/">test1</a>
<span class="arrow">»</span><a title="xyz" href="http://www.google.com/">test2</a>
<span class="arrow">»</span>
This is for testing selector
</div>
I'm not sure if there an easy way out for this or not. It turned out to be more difficult than I thought. Below mentioned code is tested locally and giving correct output for me ;)
String MyString= driver.findElement(By.xpath("//div[#class='breadcrumb']")).getText();
//get all child nodes of div parent class
List<WebElement> ele= driver.findElements(By.xpath("//div[#class='breadcrumb']/child::*"));
for(WebElement i:ele) {
//substracing a text of child node from parent node text
MyString= MyString.substring(i.getText().length(), MyString.length());
//removing white spaces
MyString=MyString.trim();
}
System.out.println(MyString);
Let me know if it works for you or not!
Try with this example :
driver.get("http://www.google.com/");
WebElement text =
findElement(By.className("breadcrumb")).find("span").get(1);
Actions select = new Actions(driver);
select.doubleClick(text).build().perform();
I suggest also that you copy the xpath for the text you need and put it here to have the exact xpath
You cannot select text inside an element using xpath.
Xpath can only help you select XML elements, or in this case, HTML elements.
Typically, text should be encased in a span tag, however, in your case, it isn't.
What you could do, however, is select the div element encasing the text. Try this xpath :
(//div[#class='breadcrumb']/span)[3]/following-sibling::text()
You could try Abhijeet's Answer if you just want to get the text inside. As an added check, check if the string obtained from using getText() on root element contains the string obtained from using getText() on the child elements.

How to locate any element based on css style class property value in selenium

I need to locate an element based on the background-image, see screenshot for reference.
<em unselectable="on" class="x-btn-split">
...
</em>
Style:
em.x-btn-split
{
background-image: url("/EXT/theme/sfdc/images/button/split_mutton_arrow.png");
}
I need to locate the element that have background-image url as "/EXT/theme/sfdc/images/button/split_mutton_arrow.png"
From what is given, it looks like you can simply check the class here:
driver.find_element_by_css_selector("em.x-btn-split")
If you insist on checking the background-image, you'll have to find all the em tags and filter them out checking the background-image CSS property in the loop:
value_to_find = "/EXT/theme/sfdc/images/button/split_mutton_arrow.png"
try:
em = next(em for em in driver.find_elements_by_css_selector("em.x-btn-split")
if em.value_of_css_property("background-image") == value_to_find)
print("Found!")
print(em)
except StopIteration:
print("Not Found!")
(Examples in Python)

safari - contenteditable, after making it empty, creates an element with text-align:center

In safari,
i had a simple edtable div with a input button, on deletion of the element (backspace or delete), caret moves to center of edtiable div with some inline styled p tag with text-align:center and inline style "color"
<div class="editable" contenteditable="true">
<input type="button" value="inputBtn" />
</div>
http://jsfiddle.net/VqCvt/
its a strange behavior observed only in safari.
Over a year after this post, this issue is still a problem. This issue is directly tied to the input tag. Once an input tag has been in a contenteditable element, Safari will attempt to make the style of the text similar to the input (I confirmed this by observing that the resulting style was different for type="text" vs type="button"). It's a very strange bug. I have found a workaround that works, but it's pretty absurd. My fix is basically to test when my main input no longer has content, and then removing the element, and re-adding it
<div id="content-wrapper">
<div contenteditable="true" id="content" role="textbox"></div>
</div>
and in my "keyup" listener, I put the following code
// Grab main editable content div
var element = document.getElementById("content");
// Check empty state conditions. These work for me, but you may have your own conditions.
if (element.getElementsByTagName("input").length == 0 &&
element.innerText.trim().length == 0) {
// Grab parent container
var elementContainer = document.getElementById("content-wrapper");
// Add a copy of your element to the same specifications. If you have custom style attributes that you set through javascript, don't forget to copy them over
elementContainer.innerHTML = '<div contenteditable="true" id="content" role="textbox"></div>';
// Re-focus the element so the user doesn't have to click again to keep typing
element = document.getElementById("content");
element.focus();
}
What this code does works for my case because input is the only elements which are allowed in my code other than text nodes and <br>, so I first check to make sure there are no input elements, and then make sure the innerText is empty (this indicates no content in my case, you may have to customize your conditions for the "empty" state). Once the empty state is confirmed, I replace the old div with a new one to the same specification, and the user never notices. A very strange issue with a hacky workaround, but I think contenteditables.
You could probably also strip out the HTML that Safari is generating, but for my case this solution is much simpler. I hope this helps someone in the future.