How to test text-overflow element - selenium-webdriver

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)

Related

Go back to parent element - CSS selector in Cypress

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')

Set zIndex programmatically on a Div in AngularJS

I have a number of Div's on a layout, each of them draggable, so there's the possibility of the user dragging them into positions where they will overlap.
I want to set the most recently made visible div to have a z-index value that's +1 from the last, and for this I'm using a $scope.nextIndex variable that's incremented each time one of the div's is made visible.
Each div has its own variable to track its own z-index value: $scope.one_zIndex, $scope.two_zIndex, $scope.three_zIndex, and each correctly gets assigned an incrementally larger value as each div is shown, hidden and shown again.
Each div has its own class: one_z, two_z, three_z
What I can't make work is assigning the variable to the z-index style on the divs themselves via the controller.
var myVar = document.getElementsByClassName("one_z");
If I log this to the console, I get what I expect - an array with one element [0]
[]
0 : div#one_z
length : 1
one_z : div#one_z
__proto__ : HTMLCollection
I would assume that I could set the z-index simply like this:
myVar[0].style.zIndex = $scope.one_zIndex;
However this throws an error:
Uncaught TypeError: Cannot set property 'zIndex' of undefined
What am I missing? Or is there a better way to accomplish this?
Here is a working plunker https://plnkr.co/edit/aaDipIWdqpajghc2F2Da?p=preview
You can set zindex via ng-style:
<div ng-style="{'z-index': $lastIndex;}">...</div>
This example completely useless in your case, but there is an example of ng-style usage. In your case I'd set index as property of you div element data source.
What wound up working was this:
First, I switched to IDs instead of classes, which likely didn't impact the solution but as each div was only ever going to exist once, IDs was the more correct way of identifying them.
Then, in the function that displays the div, I used this:
_.defer(function(){
jQuery('#one_z').css('z-index', $scope.one_zIndex);
});
There appeared to be an issue where I was showing the div and trying to set its z-index before the DOM had updated to include the div, so _.defer (I'm using Underscore.js) prevented the accessing of the z-index until everything had updated once, and it works.
As I mentioned in another comment - using ng-style wasn't working for me, and I had tried the _.defer with that approach as well initially without success.
For the record - I've used jQuery() instead of $() so it's clear in the code that this is a jQuery and not an Angular solution, and while I'd ideally have liked a purely Angular solution to this problem, this is clean enough for me, and doesn't do any DOM manipulation outside of Angular's purview that impacts the rest of the application in any way, it's purely display candy.

ng-html-bind and syntax highlighting

I have an element with ng-html-bind that loads HTML content:
<p ng-bind-html="content.body"></p>
Inside this content I have one or more <code> blocks.
I would like to apply syntax highlighting only to the code tags of the loaded content, for example using angular-highlightjs directive.
Any idea on how to achieve this?
There are many ways to bind html on the page with Angular. One way is with ng-bind-html, but it's not really the best for this use case, since you also need angular-highlightjs directive to compile. You can achieve your goal with $compile like this:
/** Here, you will need to do some transformations to your html string
* 1. Add `hljs` attribute or `class="hljs"` to the `<code>` tag in any `<pre><code>`
* 2. Hopefully you already have your line breaks in place. This will result in
* a single line code block otherwise. See my plunk for how I added '\n'
*/
var myHTML = $scope.content.body;
element.append( $compile( myHTML )($scope) );
See my plunk

How to change valid HTML tags that get rendered in ng-bind-html?

I have a text editor (textAngular) that I've modified to limit the number of valid HTML tags I can generate using that tool. Now, I want to only support a limited number of HTML elements (h3, h4, h5, h6, ol, ul) to produce a news story but I want to disable some of the valid HTML rendered by ng-bind-html. Namely, I want to remove , tags as a valid tags because they could have disastrous results for this user generated content.
Is it possible to remove and tags as something rendered by ng-bind-html?
Unfortunately no, it isn't possible to config the valid HTML tags.
The ng-bind-html use the $sanitize service to strip invalid tags/attributes, and you can see in the source code that all the configurations are private.
// Safe Block Elements - HTML5
var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," +
"aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," +
"h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul"));
// Inline Elements - HTML5
var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," +
"bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," +
"samp,small,span,strike,strong,sub,sup,time,tt,u,var"));
If you really want it, one way you could do is to copy the angular-sanitize.js and modify the valid HTML tags configuration directly.
Please note that if you do it that way, all the ng-bind-html in your entire application will be also affected. If that is undesired, you have to write your own custom directive and inject/use your modified version of $sanitize instead.
If you're into modifying textAngular already, you could modify something around the taCustomRenderers Section of the code and use ta-bind instead of ng-bind-html. They do nearly the same thing except ta-bind runs all the extra renderers.
Custom Renderers Code: textAngularSetup, textAngular - probably in this one you can do your stripping out of unwanted code.

ExtJS: dynamically changing element styles

I'm trying to dynamically assign styles to my elements (in this case, a ExtJS displayfield).
I can't use CSS classes since I don't know what the colors will be until runtime.
I'm trying:
myDisplayField.getEl().applyStyles({ color: '#ff0000' }); //fail
myDisplayField.getEl().setStyle('color', '#ff0000'); //fail
Just to get the mechanism right, but neither seem to work.
It works using Ext.get(<div id>).setStyle(...), but that doesn't seem as clean to me. Is there a reason the former attempts don't work?
What am I missing?
Thanks.
The reason is simple: you're trying to set the styles on a wrong element. Each field, including displayfield, has quite complex table-based DOM structure that encapsulates the field label, the actual input element (or a div for display fields), and the supporting elements. field.getEl() returns the top, or main, element for a component; in this case that's the top <table> tag. What you need is the input element instead.
Now if you take a look at the DOM structure you'll notice that the <div> that you need to set styles on has an id of displayfield-123-inputEl. The -inputEl suffix is there for a reason; in most cases it indicates that the element has a Ext.dom.Element shortcut in its respective Component. For a field, that would be field.inputEl property that is available after the field has been rendered to the DOM. You can use that as well:
myDisplayField.inputEl.setStyle(...)
Or just use the convenience method available for the fields:
myDisplayField.setFieldStyle(...)
I would also suggest not hardcoding the colors but rather use CSS classes instead. In most cases there is a limited choice of colors depending on a condition, like invalid input, etc. Using CSS will require a bit more work upfront but will save you a lot of headache down the road, when someone will come up with a bright idea of changing the shade of red used for the invalid input, or somesuch.

Resources