I have an element with the following styles
<ul class="textboxlist-bits" style="background-color: transparent;">
Now I want to select the element based on the style attribute.
The css selector ul [style="background-color: transparent;"] does not work there.
Kindly suggest an appropriate selector to identify such element.
I think you only have to remove the first space:
ul[style="background-color: transparent;"]
Now it is searching all ul-tags which have this style; with the space between it tries to select all dom elements in(!) a ul-tag which have this sytle.
Here an example with the querySelector for javascript, it should work with selenium too.
A possible solution is to select all elements with matching class name, then the first of those with the correct style attribute. You haven't said which language the test is written in, but an example in C# would be:
IWebElement element = driver.FindElements(By.CssSelector("ul.textboxlist-bits")).First(e => e.GetAttribute("style").Contains("background-color: transparent;"));
Maybe this http://reference.sitepoint.com/css/elementtypeselector
not sure if you mean something like an if statement in c?
[ { attribute | attribute { = | |= | ~= } attribute value } ] {
declare stuff here..
}
or
this matches any type input that matches 'submit'
input[type="submit"] {
declarations
}
Related
Can someone please assist in following case:
I have to check in if statement does element exist. Since there is no possibility to use Xpath in find command (Throws Syntax error when run it with Xpath).
My code looks:
cy.xpath(list)
.eq(index)
.then(($el1) => {
cy.get('body').then((body) => {
if (
body.find(
currentBase +
currentTitle[index] +
currentExtension
).length > 0
) {
...
Where currentBase is Xpath before text, currentText - element with text and currentExtension is concatentation to get element below that text element.
I do not want to use those classes since they are dynamic ones (also, can not be changed with some unique attribute in near future)
And DOM looks:
Namely, easily is found marked img element, but with following CSS, it does not work
#structures img[src*="/static/media/image"].$('..').$('..').$('..') div:nth-child(2)
What I want is, to find div below element with text Element One
What I am doing wrong?
Or is there any other way in Cypress to use together if statement and to pass that step if element is not found?
Thank you in advance
You can do something like this. This will get you the div element just below Element One and which is also the parent element for the img
cy.get('img[src*="/static/media/image"]').parent('div')
I have a simple ng-class that switches two classes based on the condition. When the class is switched, the order of the classes is messed up not sure why. Has anyone a solution for this?
<div class="ui" ng-class="{'two column grid' : submitNow, 'one column grid' : defaultState}"></div>
Rendered HTML when submitNow is true. This works as expected
<!-- submitNow is true -->
<div class="ui ng-scope two column grid"></div>
Rendered HTML when defaultState is true. This messes up the order of classes added by ng-class
<!-- defaultState is true -->
<div class="ui ng-scope column grid one"></div>
*** Edit ****
Quite strange because it works on jsfiddle. But here's the screenshot of my rendered html code
Here is a demo
https://codepen.io/vibwaj/pen/KKPBdNp
OK...looking at the style rules in elements inspector, semantic ui uses selectors like .ui[class*="two column"].grid > .row > .column
Not sure why they do it that way which is unusual and does make the order important.
Also not sure if it is angular or the browser that sorts the order of those classes. I suspect it is the browser, but that is a guess.
Rather than try to figure out what causes the sort you can add the following rule to fix layout for non specific class order.
.ui.two.column.grid > .row > .column,
.ui.two.column.grid > .column:not(.row){
width:50%!important;
}
Working codepen
Update:
I didn't notice the semantic UI framework that is using this approach.
If you still need the same approach, you can check the forked Codepen which I created a custom directive to be alternative than the original NgClass directive.
app.directive("myNgClass", function() {
return {
link: function(scope, element, attrs) {
scope.$watch(
function() {
return attrs.isExpand;
},
function(isExpand) {
element.removeAttr("class");
if (JSON.parse(isExpand)) {
element.addClass("two column grid");
} else {
element.addClass("one column grid");
}
}
);
}
};
});
Original Answer
So diving deep into the NgClass directive implementation in Angularjs source code and checking how they update the classes, there is a function called updateClasses.
In this function, it finds which classes should be removed and added.
Instead of replacing all the classes when the Boolean flag gets inverted, NgClass keeps the overlapping classes and checks which classes should be added / removed.
So in your case,one column grid (the default case) and two column grid have the column grid classes in common, so it will keep them, but remove the one from the start and add two at the end. So the result will be column grid one.
I really don't suggest to use the order of the classes as CSS selectors. This will make it more harder to select elements and make things more complex.
I also have a comment regarding the CSS selectors that you are using. I really suggest you to read Keep your CSS selectors short article so you can have a better practice of using shorter selector and why keeping the CSS selectors short can help with many things.
For example, If you don't need the one, column and grid classes seprately, you can just use .one-column-grid as a class name / CSS Selector instead of .one.column.grid.
when the text attribute is set to
text-overflow: ellipsis;
the overflowed text will be displayed as "XX..." (see screenshot for more )
how can I find the overflowed text/element in webdriver?
thanks in advance
Screenshot of Overflowed text
Probably the easiest/best way to do this is to use the JS innerText property, e.g.
driver.findElement(lcoator).getAttribute("innerText");
If I remember correctly, some browsers use textContent instead.
driver.findElement(lcoator).getAttribute("textContent");
This should get you the full text inside that element.
You could also pull innerHTML and parse it (if needed) or remove the text-overflow style from the element but these are harder/more complicated.
In case you have jQuery available in your project, you can write your own selector:
$.expr[':'].truncated = function (e) {
// you *might* want to check if css property "text-overflow"
// is set to "ellipsis" as well, to filter other truncations:
return e.offsetWidth < e.scrollWidth;
};
and go from there:
items = $('.your-selector:truncated');
(heavily based on the answers here)
I have multiple divs with the same class name. I was able to retrieve all the divs through the findelements code. But I have a select element within one of the div. I am trying to retrieve the select element within the div.
The HTML code is as below.
Selenium code I tried.
IList <IWebElement> elements = driver.FindElements(By.XPath("//div[#class='className']"));
foreach (IWebElement widget in elements)
if(widget.FindElement(By.TagName("select").Enabled)
----- Perform sone operations-----
The above code is not working. Can anyone suggest solution to identify the select element.
Doing
IWebElement element = driver.FindElement(By.XPath("//div[#class='className']//select"));
will directly get you to the select tag you want to interact with.
If it so happens that this returns more than 1 element, you can further narrow down your search by providing a class or any other attribute to the select tag on your xpath, like so:
IWebElement element = driver.FindElement(By.XPath("//div[#class='className']//select[contains(#X,'Y')]"));
Where:
X - can be any attribute of that element (id, name, class...)
Y - a substring value of X attribute
Take for example:
This page:
"//div//ul/li/a" will give you 57 matches;
"//div//ul[contains(#class,'sf-menu')]/li/a" will give you 3 matches;
"//div//ul[contains(#class,'sf-menu')]/li/a[contains(#title,'Dress')]" will give you 1 match;
Good luck!
I am writing an automation test script using Robot Framework & Selenium2Library for testing our web application( in .txt format) . One of my test cases involves to check the CSS style attribute of an HTML tag.
Is there any specific keyword in Robot Framework to obtain the CSS style attribute of an html element?
Here is my testing scenario:
<div id="check_style" style="width:20px;height:20px;background-color:#ffcc00;"></div>
Now, I have to store the background color of this particular html tag into a variable ${bg_color}. Is there any specific keyword in Robot Framework to do this process?
Can you please suggest an effective way to handle this situation?
I think we can make use of this javascript function for the above mentioned purpose :
document.getElementById("check_style").style["background-color"]
But how to make use of this particular function to store the value of background-color inot a variable ${bg_color} ?
( I have tried to execute ${bg_color} = Execute Javascript document.getElementById("check_style").style["background-color"],
but didn't work ! )
You can use the Selenium2Library Get Element Attribute keyword to get the style attribute:
| | ${style}= | Get element attribute | id=check_style#style
You can then either use a regular expression to find the background color attribute or do some additional parsing. The latter would be easier to do in python than with robot keywords.
For example, if you understand regular expressions, something like the following might work. Of course, you'll probably want to add some bullet-proofing.
| | ${style}= | get element attribute | id=check_style#style
| | ${color}= | evaluate | re.search("background-color: *(.*?);", '''${style}''').group(1) | re
Note: you might not get the same literal value as is in the raw HTML. For example, on my machine ${color} comes back as rgb(255, 204, 0) even though the color in the HTML is #ffcc00.
For whatever reason I had a bunch of trouble getting this to work. I think it's because my CSS was defined in an external file (therefore pulling the style attribute came up empty).
Also note that RF now has changed the definition of Get Element Attribute to take two parameters, not one.
I'd like to pass along a great solution I found after a bunch of searching -- I found this amazing keyword here How to get the css style of text-overflow in robot framework
*** Keywords ***
Get CSS Property Value
[Documentation]
... Get the CSS property value of an Element.
...
... This keyword retrieves the CSS property value of an element. The element
... is retrieved using the locator.
...
... Arguments:
... - locator (string) any Selenium Library supported locator xpath/css/id etc.
... - property_name (string) the name of the css property for which the value is returned.
...
... Returns (string) returns the string value of the given css attribute or fails.
...
[Arguments] ${locator} ${attribute name}
${css}= Get WebElement ${locator}
${prop_val}= Call Method ${css} value_of_css_property ${attribute name}
[Return] ${prop_val}
after which I could simply run
${style}= Get CSS Property Value class:logo background-image
and do a plain text comparison. Sub in any CSS value for background-image and have fun with this!
Get css value using javascript in robot framework. link here
# Get element using Xpath in JavaScript.
${element}= Set Variable document.evaluate("${xpath_locator}", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue
# Get css attribute value using getComputedStyle()
${attribute_value}= Execute Javascript return window.getComputedStyle(${element},null).getPropertyValue('${css_attribute}');
Log ${attribute_value}