Selenium : isDisplayed returns - exception

I'm quite new to Selenium so that question may be silly, but i cannot resolve it...
I'm trying to make a click() with Selenium (in Java, with Eclipse and Firefox and Chrome drivers) on an element that is definitely displayed and visible on the screen, but that returns false when i apply the isDisplayed() method on it. So i get an exception telling me that the element must be visible in order to perform an action on it.
I checked all parents div (i'm not using any iframe in my page), and some of them returns true as other returns false. Here is a small example of code of what i try to do :
<div id=1><div id=2><div id=3><div id=4><img that i want to click on with selenium\></div></div></div></div>
I want to click on the img with selenium, but it sees it as not displayed.
the img is marked as not displayed
the div4 is marked as not displayed
the div3 is marked as displayed by selenium
the div2 is marked as not displayed
the div1 is marked as displayed, as all parents div
But i definitely can see the image and others elements in the same div on my screen.
Any help on that point ?
Thanks !
EDIT : I use JS to modify these properties, particularly div 3, which is not displayed and marked as not displayed at loading, but then after e few action, it became (it is and is marked as) displayed.
Edit 2 : I found out that the styles of the two divs marked as not displayed by selenium have both the style display:block; (seen in the chrome dev tools). Any ideas ?
Edit3 : based on the link given in the comments, i add the computed style of the div :
div4 : it has non zero height and width, display is set on block. It even has a min width and min height.
div3 : it has non zero height and width, display is also set on block
div2 : it has a 0 height a non zero width and a display:block; so it might be the problem.
div1 : it has a 0 height, a non sero width, no display parameters, and hidden overflow-x and y. Thought this one is marked as deisplayed by Selenium...
Any ideas ?

I managed to solve my problem with a simple trick : call the Js function that is supposed to be triggered by the click, using
JavascriptExecutor js;
if (driver instanceof JavascriptExecutor) {
js = (JavascriptExecutor) driver;
} else {
throw new Exception(" Webdriver do not manage JS");
}
js.executeScript("function()");
Another solution that could be suitable is to use a Robot to use the mouse to click on this img, if you have its coordinates of course (or if you can compute it) :
Robot robot = new Robot();
robot.mouseMove(300, 300);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
Though i did not find a solution to the displayed/not displayed problem.
Enjoy :)

Related

Slider - preloader - buttons aren't working after setting style="display: none"

Could anyone have a look at this snippet of code?
I recreated another loader and included the last amount possible of code I could to show you the problem.
Basically I have a div container, which is "all-page-container" which has an inline style="display: none" which makes it non visible until the loader is done (but also it makes it wait at least 2 seconds to show the actual page content).
But this also makes the js part of the code as
var s = $('.slider'),
sWrapper = s.find('.slider-wrapper'),
sItem = s.find('.slide'),
btn = s.find('.slider-link'),
sWidth = sItem.width(),
sCount = sItem.length,
slide_date = s.find('.slide-date'),
slide_title = s.find('.slide-title'),
slide_text = s.find('.slide-text'),
slide_more = s.find('.slide-more'),
slide_image = s.find('.slide-image img'),
sTotalWidth = sCount * sWidth;
Not find the actual classes, because of the display:none, does anyone know how could I overcome this issue?
I fixed it with a while loop which checks until a property is set to 0 to load the script, but obviously this isn't going to fix the major problem.
https://jsfiddle.net/boxxo/95ocxrb2/59/
if you remove the inline style="display:none", obviously the buttons are going to work ask expected and also the slider is going to work properly.
(The buttons are actually running, I added logs into the conditions and the "next" and "previous" are definitely executing correctly).
If anyone could help I would be grateful.
Thanks everyone.
(I also checked other questions on the site, but couldn't find the solution to my issue, and also other guys are using display: none to hide the page content until the preloader is done loading).
The problem is that width of the element that is not visible (display: none) is 0 same as height. If initially, the page is not visible (width display: none) your animation will not work.
Just add console.log({sWidth}); to see for yourself.
To solve the issue you can show the div before you start your code. Or use different CSS properties:
visibility: hidden;
visibility: visible;
This property works similarly to display: none but the width and height is not 0, the element still occupies the same space but it's not visible.

Autosized textarea clipping issue with IE

I'm trying to implement a simple auto sized textarea component with VueJS but I'm facing an issue with IE.
On this browser only, we can feel the height calculation. The size of the textarea changes twice and we can easily see the following content moving.
Here's how I'm doing it :
Each time the value changes, I'm calling the following resizeTextarea method :
resizeTextarea: function() {
// Set the height to auto to have a correct scrollHeight
this.textareaStyle.height = 'auto';
// Wait for the next tick to be sure that the heigh is set to 'auto'
this.$nextTick(this.setHeight);
},
With the referenced setHeight method :
setHeight: function() {
//IE COMPATIBILITY this.textareaStyle.height = `${this.$refs.input.scrollHeight}px`;
this.textareaStyle.height = ''.concat(this.$refs.input.scrollHeight, 'px');
},
As you can see, the process is quite simple :
Setting the textarea's height to auto;
After the value is updated, setting the height to the component's scrollHeight.
However, I have to wait the next tick to set the height and I'm guessing that this causes the clip with IE.
In my HTML template, I'm binding the textareaStyle data to the textarea component and I'm referencing it via a ref :
<textarea
v-model="message"
ref="input"
:style="textareaStyle"
></textarea>
You can found a working example here, please run it on IE and another browser to see the difference.
Notes :
I'm not using ES' syntax to ensure IE compatibility;
I've already tried to use the autosize package but the results are the same.
This issue may be due (and most certainly is) to my implementation of the auto sized textarea, so I'll consider this issue closed if the current system get fixed or if another solution (working in every modern browsers + IE 11) is found.

Inconsistent click handling when using :active pseudo class

Can anyone explain why the click handler is not invoked consistently in this example?
http://jsfiddle.net/4QBnf/
For instance, if you click in the upper left half of the div, it does not reliably increment the counter.
If I remove the padding-top from this block it works just fine:
.click-check:active {
background-color:blue;
padding-top: 25px;
}
I have tested this in a number of different browsers and it behaves the same way.
I found two possible issues with your code. You can view the fixes here:
http://jsfiddle.net/4QBnf/6/
CSS Box Model vs jQuery Box Model
Whenever you click on the top half of your box, you aren't technically clicking on .click-check, you are actually clicking on .count. This image shows the location of .count relative to .click-check:
jQuery counts this as a click on .click-check, but CSS doesn't. The number increments, but the CSS "active" effect isn't applied.
You can resolve this by removing the .count div and placing everything inside of .click-check.
jQuery Counter
The second issue is with your jQuery code. The code currrently reads:
$('.click-check').click(function() { $('.count').html(count++); });
count isn't increased until after this line is done. This means that the first click appears to have no effect.
This line will increment count, then display it to the user:
$('.click-check').click(function() { $('.click-check').html(++count); });
I've applied both updates to your example here:
http://jsfiddle.net/4QBnf/6/
Update
An alternate way to resolve the issue is to do everything through jQuery. This synchronizes all of the appearance and logic into a single box-model interpretation.
var count=0;
$('.click-check').mousedown(function() {
$('.click-check').addClass("active");
$('.click-check').html(++count);
setTimeout(function(){
$('.click-check').removeClass("active");
}, 50);
});
http://jsfiddle.net/4QBnf/15/

Flex 4 <s:Scroller> Recalculate Range?

I am building a Flex 4 application which uses a <s:Scroller> component to vertically scroll overflown content. Let me explain what happens before I ask my question:
The body of the page is loaded from a database
Once the information has loaded, the "body" of the application (in this case the list of items you see below) is constructed
Once the list is constructed, the entire encapsulating component is transitioned into view using TweenMax, like so:
myComponent.visible = true;
TweenMax.to(myComponent, 1, {
alpha : 1,
y -= 20 //Slides the component up 20px from its original location
});
Below is the result. Notice how the scrollbar is scrolled the whole way down, but you can see the tips of a few white letters that were cut off at the very bottom.
Using my custom menu, I can navigate away from the page, and come back to it, and Flex will correctly recalculate the range of the scroller so I can scroll down and see all of the desired content. This issue only happens if the initial URL that the user enters is a longer page like this one.
Any ideas on how I can force Flex to recalculate the range of the scroller?
Thank you for your time.
Ok, after many hours of researching, piecing together, and trial and error here is what I came up with.
What I was doing wrong:
When I first posted this question, the "component" that I had mentioned was already added as a child element of the <s:Scroller>, but collapsed and hidden away, like this:
<comp:MyComp alpha="0" height="0" visible="false"/>
When the data would be loaded and the component's visual appearance would be restored and transitioned into place, like this:
myComp.visible = true;
myComp.height = NaN;
myComp.invalidateSize();
myComp.height = myComp.measuredHeight;
TweenMax.to(myComp, 1, {
alpha : 1,
y -= 20 //Slides the component up 20px from its original location
});
This method of approach didn't force the <s:Scroller> to recalculate its proper size until later, sometimes not until myComp was transitioned away and another component was transitioned into place using the same method. Even then, the size of the scroller would fit the size of the previous component, not the one that is currently displaying.
Now, what I am doing correctly:
My research showed me that anytime the addElement() method is called, either directly within the <s:Scroller> itself or by any of its children, the scroller's measure() method is called, and properly re-sizes the scroller.
Instead of placing the components inside of the scroller and simply hiding them until I need them, I dynamically created them in ActionScript, set their properties, and added and removed them as needed using the addElement() and removeElement() methods respectively. Now, as old elements are transitioned away and new ones take their place, the scroller re-sizes itself correctly.
There was one final problem that I was faced with. If the very first page the user was viewing (i.e. there was no previous component that was transitioned away and destroyed) required a scroller, it wouldn't show up.
I corrected this final issue by adding an event listener that listened for when the new component had finished transitioning into place. Inside of the event handler, I explicitly set the height of the component using this code:
newComp.height = NaN;
newComp.invalidateSize();
newComp.height = newComp.measuredHeight;
Now that the component has an explicit height, the scroller now appears, even if it is the first page.
The scroller now works as expected in all cases, and does not cut off any content or disappear when it shouldn't.
I hope that it is helpful to someone.

Why is there this extra space that is not inspect-able on chrome?

My page didn't require a horizontal scroll bar initially, but now one appears mysteriously that is beyond any of the elements that are covered on inspect on Chrome and firebug. No elements pass that blue line so I'm not sure how to fix this.
I know I can hide the scrollbar with overflow-y:hidden, but that's not the point. It shouldn't be there at all.
EDIT Here's the jsfiddle: http://jsfiddle.net/S8RUp/
A bit messy, but I think it gets the point across.
The jsFiddle link has too many overflowing contents to be useful. What you can do to ease debugging is to use a bit of code like this to show you only elements that are over a threshold width:
// using jQuery - you can use other library or include it temporarily for debugging purposes
$('*').each(function() {
var w = parseInt($(this).width(), 10);
// you can put something larger than 700, depending on your situation
if (w > 700) {
console.log(w, this);
}
});
It will have a few false positives (the html node for example), but you'll probably find the culprit easily enough.