The webpage in question is an SPA, I could describe it as a single large div with several div "boards" inside it, which we scroll into view by applying a webkit transform on the parent div.
Unfortunately, once scrolled too far, the elements returned by WebDriver are "disabled" - the WebElement property "Displayed" is false, the Text property is blank, and I can't execute any clicks/actions on the element. It is however visible on the page at the time and perfectly functional.
While investigating the problem, I created a small test webpage to see under what conditions this occurs.
Link to JSFiddle sample page to show functionality
NB Note that we are not using IFrames in this website, JSFiddle is just to demonstrate functionality.
<html><head>
<script type="text/javascript" src="jquery-1.8.3.js"></script>
<style type="text/css">
.board-nav {
font-size: 12px;
color: #1b1a1a;
margin-right: 10px;
vertical-align: middle;
}
.scroller{
-webkit-transition: -webkit-transform 0ms; transition: -webkit-transform 0ms;
-webkit-transform-origin: 0px 0px;
-webkit-transform: translate(0px, 0px) scale(1) translateZ(0px);
transition-property: transform;
transform-origin: 0px 0px 0px;
transform: translate(0px, 0px) scale(1) translateZ(0px);
height: 4000px;
}
</style>
<script type="text/javascript">
var boardPositions = [0, -878, -1748, -2598, -3468];
var $scroller = null;
function changeBoard(event) {
var newValue = 'translate(0px, ' + boardPositions[event.target.id] + 'px) scale(1) translateZ(0px)';
$('.scroller').css('-webkit-transform',newValue);
$('.scroller').css('transform', newValue);
}
$(document).ready( function(){
var $boards = $('.board-nav');
$boards.on('click', changeBoard);
});
</script>
</head><body>
<div>
<div class="board-nav" id="0">Info</div>
<div class="board-nav" id="1">Board1</div>
<div class="board-nav" id="2">Board2</div>
<div class="board-nav" id="3">Board3</div>
<div class="board-nav" id="4">Board4</div>
</div>
<div id="content" style="width:1612px; height:864px; position:absolute; left:58px; overflow:hidden">
<div class="scroller">
<ul class="vertical">
<li class="v" id="li0">
<div class="target"><span>Info</span></div>
</li>
<li class="v" id="li1">
<div class="target"><span>Board1</span></div>
</li>
<li class="v" id="li2">
<div class="target"><span>Board2</span></div>
</li>
<li class="v" id="li3">
<div class="target"><span>Board3</span></div>
</li>
<li class="v" id="li4">
<div class="target"><span>Board4</span></div>
</li>
</ul>
</div>
</div>
</body></html>
It seems that as soon as the parent div Y location becomes less than around -2000, all child elements become "disabled" in this manner. Prior to this (around -1900 for example), the elements are returned with all information valid. I can switch from Board 3, back to Board 2, and then all elements are returned correctly again. Back to Board 3 - all boards "disabled". So this seems to be a browser WebDriver limitation.
WebDriver C# test code :
var driver = new FirefoxDriver();
driver.Manage().Window.Maximize();
driver.Navigate().GoToUrl("testpage.html");
var elements = driver.FindElements(By.ClassName("v"));
return elements[3].FindElement(By.TagName("span")).Text;
Firefox handles this the best - it at least shows Info/Board1/Board2 before giving up. Chrome doesn't handle any of the Boards, returning the same Displayed = false, blank Text for all boards.
So my question is - is there any way to get around this? I can test the text on the other boards are correct, while Board1/Info is showing, but won't be able to interact with the last 2 Boards.
ANSWER:
Just resolved my problem by adding a height attribute to the parent div "scroller" element - my guess is WebDriver couldn't determine the height of the parent div and so assumed beyond a certain location it was no longer visible.
I've updated the code above and JSFiddle with the solution