Selenium test (selection of element having no attribute) - html

<! DOCTYPE html>
<html>
<head>Sample</head>
<body>
<div class="panelBody">
<div class=panel-section></div>
<div class=panel-section style="display:block"></div>
</div>
</body>
</html>
In given Snippet there are two elements with same class. I have to select the element which does not having style attribute.If i tried to search with panel-section class its giving ambiguity error.So how to select div element which does not having style attribute.i.e
<div class=panel-section></div>

Try this:
//div[#class='panelBody']/div[not(#style)]
Explanation: First find the div with class panelBody, then find child div elements in the panelBody div which doesn't contain #style attribute.
Use findElements method if there are more than one div element without #style attribute, otherwise findElement() method would suffice.

Since there are more than one elements with same class name, you need to use Selenium's driver.findElements() method. I have tried getting this element, but I wonder if it is clickable. Only element can actually be useful here is text Sample.
Check below code. Let me know if it is similar to what you are looking for.
List<WebElement> linksize=null;
String links[]=null;
linksize = driver.findElements(By.cssSelector("div[class=panel-section]"));
int linksCount = linksize.size();
links= new String[linksCount];
for(int i=0;i<linksCount;i++)
{
links[i] = linksize.get(i).getAttribute("style");
if(links[i].isEmpty())
{
System.out.println("I am div without style");
linksize.get(i).click();
}
}

Related

html div display attribute: handling inline-block and some boolean condition

I have a div tag which contains other elements like form, button etc. div is stretching to entire width of the screen. So I am told that display="inline-block" would fix the issue. But I am also using display attribute to display the div based on some condition
<div display={some condition}...>
So how to handle this situation?
I hope if this helps you
HTML
<div id="selected">
Ahmed
</div>
Javascript
if(your condation){
const div = document.getElementById('selected').style.display ="inline-block"
}else if(your condation){
//code
}
.
.
.
else{
//code
}

Can i use attributes of element to create style rules?

I'm noot good in english, so the title may seem a bit odd.
I want to use css function attr() like this:
I mean i have a container <div> and an inner <div> that i want to have width depending on data-width attribute. For example this would be great, but this doesnt work:
<div class="container">
<div data-width="70%">
</div
</div>
.container {
width: 600px;
height: 200px;
}
.container div {
width: attr(data-width);
height: 100%;
}
Is there any noJS way to use attributes like that?
UPDATE: Guys convinced me that the JS is the only way to do this :)
That's not a big problem (but that's bad. CSS, why youre so illogical? Is the difference between content:attr(data-width) and width: attr(data-width) so big ?).
One of the guys had an idea to go through the all elements with jQuery.
That's ok, but it is very... local? Don't know how to say it in english.
Anyway, i remaked his code a little bit and here it is:
allowed = ['width','color','float'];
$(document).ready(function () {
$('div').each(function (i, el) {
var data = $(el).data(),style = '';
if (!$.isEmptyObject(data)) {
$.each(data, function (attr, value) {
if (allowed.indexOf(attr) != - 1) {
style += attr + ': ' + value + '; ';
}
})
if (style.length != 0) {
$(el).attr('style', style);
}
}
})
})
Idea is simple:
1. We suppose that style we want to add to an element is the only one. I mean there are no scripts that will try to add some other styles,
2. We create an array of allowed attribute names, we need to avoid using wrong names at the style attribute, for example style="answerid: 30671428;",
3. We go through each element, save its data attributes in an object, check if object is empty, and if not - check every attribute if it is allowed, create a string that contains all styles that we need, and - finally - add our style string to the element as the content of style attribute.
That's all, thanks everybody
I would not advise to use CSS alone since it will not allow you to do what you're looking for... instead use a scripting language (in my case jQuery) to accomplish this functionality for you like so: jsFiddle
jQuery
jQuery(document).ready(function(){
var dataElem; // to store each data attribute we come accross
jQuery('div').each(function(){ //loop through each div (can be changed to a class preferably)
dataElem = jQuery(this); //get the current div
if(dataElem.data('width')){ //make sure it exists before anything further
dataElem.width(dataElem.data('width')); //set the element's width to the data attribute's value
dataElem.css("background-color", "yellow");
}
});
});
HTML
<p>The links with a data-width attribute gets a yellow background:</p>
<div>
w3schools.com
</div>
<div class="me" data-width="50"> <!-- change value to see the difference -->
disney.com
</div>
<div>
wikipedia.org
</div>
Notes on the above:
each, data, width.
Instead of doing data-width, use a class attribute. An html tag can have mutliple classes separated by spaces, so if you wanted to be very precise, you could set up as many classes as you need. For instance:
<div class="w70 h100">
</div>
Then in your css:
.w70{
width: 70%;
}
.h100{
height: 100%;
}
And so on.
Is there any noJS way to use attributes like that?
No, you cannot use CSS to set the width of the element to it's data-width attribute. CSS does not allow for this as attr() is only currently available for the CSS content property which is only available on css pseudo elements (::before and ::after).
How can you achieve this with as little javascript as possible?
This is extremely easy to do using the native host provided DOM API.
Select the elements using Document.querySelectorAll().
Iterate the elements and apply the styles using Element.style which can be retrieved from the data-width attribute using Element.dataset
(Demo)
var items = document.querySelectorAll('#container div'), item, i;
for(i = 0; (item = items[i]); i++) item.style.width = item.dataset.width;

CSS selector select some part of div class name

Select one part of text in div class:
<div class="enabled_disabled disabled">
<div class="enabled_disabled">
<div class="enabled_disabled">
<div class="enabled_disabled">
<div class="enabled_disabled disabled">
I have those div tags, is there any xpath syntax or fizzler CSS selectors syntax to select just those div tags which have enabled_disabled only (the 3 in the middle)? not those with enabled_disabled disabled
var html = new HtmlDocument();
html.LoadHtml(getitems);
var doc = html.DocumentNode;
var items = (from r in doc.QuerySelectorAll("div.enabled_disabled:not(.disabled)")
let Name = r.InnerHtml//QuerySelector("div.enabled_disabled div.title_bar div.rate_title span.name").InnerText.CleanInnerText()
select new {
CName = Name
}).ToArray();
Fizzler
To select an element with only the class enabled_disabled, you would use:
[class='enabled_disabled']
Using a :not selector is not available in vanilla Fizzler, but can be used if you grab FizzlerEx
XPath
To select an element with only the class enabled_disabled, you would use:
div[#class='enabled_disabled']
In plain old CSS
If the div's assigned classes starts with enabled_disabled:
div[class^=enabled_disabled ]
If the div's assigned classes contains enabled_disabled
div[class*=enabled_disabled ]
If the div only has the class enabled_disabled
div[class=enabled_disabled ]
If the div has the class enabled_disabled and not the class disabled
div.enabled_disabled:not(.disabled)
Given the HTML you list in your question, either of the last two will work for you.
more on attribute selectors from MDN, and, more on :not()
You could use this selector that will match the class and will avoid the other.
$(".enabled_disabled:not('.disabled')");
and you can take out contents out of $()
and it is valid css selector
.enabled_disabled:not(.disabled)
Use not() selector in css.The :not pseudo-class represents an element that is not represented by its argument.
.enabled_disabled:not(.disabled){
}
FIDDLE
More about
SEE THE LINK

Searching in html on the behalf of ID

Is searching possible in html tags on the behalf of ID? for example to find div tag having id="abc".
I can use document.getElementByID("abc"). But i need parent div + its inner HTML in return of searching. i.e if this div has childs
Try this :-
<script >
function showHTML(){
var vinner=document.getElementByID("abc").innerHTML;
var totalinner="<div >"+vinner+"</div>";
alert(totalinner);
}
</script>
HTML part:-
<body onload="showHTML();">
<div id="abc">
Hello inside abc
<div>
Inner div inside abc tag.
</div>
</div>
</body>
Its working fine. You can get Attributes here.
It's hard to understand what you want to achieve:
document.getElementById("abc").parentNode.innerHTML;
//will return <div id="abc"> and other items from parrent
document.getElementById("abc").getAttribute("name");
//will atribute of <div id="abc">
if (document.getElementById("abc").hasChildNodes()) {
// It has at least one
}
Using jQuery is much simplier, you could do that:
$("#abc").attr('id') //retunrs id
$("#abc").attr('class') //returns classes
//or other manipulations
One way to do this is to use outerHTML, which:
gets the serialized HTML fragment describing the element including its descendants.
Given the following HTML:
<div id="abc" data-attr="A custom data-* attribute">Some text in the div.</div>
The following JavaScript will log, in the console, the HTML of the element of id equal to abc:
var htmlString = document.getElementById('abc').outerHTML;
console.log(htmlString);
JS Fiddle demo.
References:
outerHTML.
outerHTML compatibility.

Using XPath to select element with highest z-index

In my Selenium application i try to select an element which has the highest z-index. That value is not defined in the element itself, but on an ancestor node (the nesting level is not known). In addition if an ancestor is not visible by the use of display: none it shouldn't be returned.
Example HTML:
<div class="container" style="z-index: 10">
<div style="display: none">
<!-- this should not be selected because it is invisible (and the z-index is lower than the others) -->
<div myattr="example"></div>
</div>
</div>
<div class="container" style="z-index: 100">
<div>
<!-- this should not be selected because the z-index is lower than the others -->
<div myattr="example"></div>
</div>
</div>
<div class="container" style="z-index: 1000">
<div>
<!-- this should be selected because it is visible and has the highest z-index -->
<div myattr="example"></div>
</div>
</div>
Currently i have a regex that selects all elements with myattr="example" which do not have an ancestor with display: none:
//div[#myattr='example'
and not(ancestor::div[contains(#style,'display:none')])
and not(ancestor::div[contains(#style,'display: none')])]
I need an additional condition to select the element which has the highest z-index, so to speak which is visible on top of others. For each found node it has to be looked at all ancestors until a node with a specific class is found (container in this example). Then return only the element that has highest z-index ancestor.
Is that even possible with XPath?
I tried really hard, but I think you can't achieve this with a single XPath 1.0 expression. You can get close, but not quite there.
You'll need to use some other logic. There's like a thousand different approaches.
For example, get all the container elements, sort them by z-index and test their myattr="example" descendants for visibility:
// Gets all containers - could also be Gets all elements containing z-index
List<WebElement> containers = driver.findElements(By.className("container"));
// Sorts the containers in an descending order by their z-indexes
Collections.sort(containers, Collections.reverseOrder(new Comparator<WebElement>() {
#Override
public int compare(WebElement o1, WebElement o2) {
return getZindex(o1) - getZindex(o2);
}
private int getZindex(WebElement elem) {
String zindex = elem.getAttribute("style").toLowerCase().replace("z-index: ", "");
return Integer.parseInt(zindex);
}
}));
// look for a visible candidate to return as a result
for (WebElement container : containers) {
WebElement result = container.findElement(By.cssSelector("*[myattr='example']"));
if (result.isDisplayed()) {
return result;
}
}
throw new IllegalStateException("No element found.");
EDIT: After you accepted this answer, I returned to the question and came up with an XPath 1.0 solution. It's ugly as hell, will perform poorly and I can't verify its correctness (it works on your example and a few others I tried), so I suggest you to use the WebDriver approach above. Anyway, I'll share it:
Copypastable oneliner:
//div[#myattr='example' and not(ancestor::div[contains(#style,'display: none')])]/ancestor::div[#class='container' and substring-after(#style,'z-index:') > substring-after(../div[not(descendant::div[contains(#style,'display: none')])]/#style,'z-index:')]
Formatted version:
//div
[
#myattr='example'
and not(ancestor::div[contains(#style,'display: none')])
]
/ancestor::div
[
#class='container'
and substring-after(#style,'z-index:')
> substring-after(
../div[not(descendant::div[contains(#style,'display: none')])]/#style,
'z-index:')
]
And a free translation to human language (not a literal one!):
SELECT A VISIBLE <div #myattr='example'> NODE
//div
[
#myattr='example'
and not(ancestor::div[contains(#style,'display: none')])
]
THAT HAS A <div #class='container'> ANCESTOR
/ancestor::div
[
#class='container'
WHOSE z-index IS GREATER THAN z-index...
and substring-after(#style,'z-index:')
> substring-after(
...OF ALL VISIBLE SIBLINGS
../div[not(descendant::div[contains(#style,'display: none')])]/#style,
'z-index:')
]
I assumed you know the highest value of z-index, in that case xpath is
"//div[contains(#style,'1000')]/div[not(contains(#style,'none'))]/div"
Otherwise using below xpath get all style attributes of div
List<WebElement> divTags=driver.findElements(By.xpath("//div[not(contains(#style,'none'))]/parent::div[contains(#style,'z-index')]"))
for(WebElement ele:divTags)
{
ele.getAttribute("style");
}
Store the z-indexes in some variable
Parse stored z-indexes and get the numbers alone
Using some logic find the highest number among those
Doing all the above things have the hold on index of that elements.
After finding highest z-index, get the index of that element
Using that index construct xpath.
I hope above logic will help you to achieve your goal.