/* ************************************************************************ qxwebdriver-java http://github.com/qooxdoo/qxwebdriver-java Copyright: 2012-2013 1&1 Internet AG, Germany, http://www.1und1.de License: LGPL: http://www.gnu.org/licenses/lgpl.html EPL: http://www.eclipse.org/org/documents/epl-v10.php See the license.txt file in the project's top-level directory for details. Authors: * Daniel Wagner (danielwagner) ************************************************************************ */ package org.oneandone.qxwebdriver.ui.core.scroll; import java.util.concurrent.TimeUnit; import org.oneandone.qxwebdriver.QxWebDriver; import org.oneandone.qxwebdriver.ui.Scrollable; import org.oneandone.qxwebdriver.ui.Widget; import org.openqa.selenium.Dimension; import org.openqa.selenium.NoSuchElementException; import org.openqa.selenium.Point; import org.openqa.selenium.TimeoutException; import org.openqa.selenium.WebElement; /** * Represents a <a href="http://demo.qooxdoo.org/current/apiviewer/#qx.ui.core.scroll.AbstractScrollArea">ScrollArea</a> * widget */ public class AbstractScrollArea extends org.oneandone.qxwebdriver.ui.core.WidgetImpl implements Scrollable { public AbstractScrollArea(WebElement element, QxWebDriver webDriver) { super(element, webDriver); } protected Widget getScrollbar(String direction) { String childControlId = "scrollbar-" + direction; try { org.oneandone.qxwebdriver.ui.Widget scrollBar = waitForChildControl(childControlId, 2); return scrollBar; } catch(TimeoutException e) { return null; } } public void scrollTo(String direction, Integer position) { Widget scrollBar = getScrollbar(direction); if (scrollBar == null) { return; } jsRunner.runScript("scrollTo", scrollBar.getContentElement(), position); } public Long getScrollPosition(String direction) { Widget scrollBar = getScrollbar(direction); if (scrollBar == null) { return new Long(0); } return getScrollPosition(scrollBar); } protected Long getScrollPosition(Widget scrollBar) { try { String result = scrollBar.getPropertyValueAsJson("position"); return Long.parseLong(result); } catch(com.opera.core.systems.scope.exceptions.ScopeException e) { return null; } } protected Long getScrollStep(Widget scrollBar) { String result = scrollBar.getPropertyValueAsJson("singleStep"); return Long.parseLong(result); } public Long getScrollStep(String direction) { Widget scrollBar = getScrollbar(direction); if (scrollBar == null) { return new Long(0); } return getScrollStep(scrollBar); } public Long getMaximum(String direction) { Widget scrollBar = getScrollbar(direction); if (scrollBar == null) { return new Long(0); } return getMaximum(scrollBar); } protected Long getMaximum(Widget scrollBar) { String result = scrollBar.getPropertyValueAsJson("maximum"); return Long.parseLong(result); } public Widget scrollToChild(String direction, org.openqa.selenium.By locator) { driver.manage().timeouts().implicitlyWait(100, TimeUnit.MILLISECONDS); WebElement target = null; try { target = contentElement.findElement(locator); } catch (NoSuchElementException e) {} if (target != null && isChildInView(target)) { return driver.getWidgetForElement(target); } Long singleStep = getScrollStep(direction); Long maximum = getMaximum(direction); Long scrollPosition = getScrollPosition(direction); while (scrollPosition < maximum) { // Virtual list items are created on demand, so query the DOM again try { target = contentElement.findElement(locator); } catch (NoSuchElementException e) {} if (target != null && isChildInView(target)) { // Scroll one more stop after the target item is visible. // Without this, clicking the target in IE9 and Firefox doesn't // work sometimes. int to = (int) (scrollPosition + singleStep); scrollTo(direction, to); driver.manage().timeouts().implicitlyWait(4, TimeUnit.SECONDS); return driver.getWidgetForElement(target); } int to = (int) (scrollPosition + singleStep); scrollTo(direction, to); scrollPosition = getScrollPosition(direction); } //TODO: Find out the original timeout and re-apply it driver.manage().timeouts().implicitlyWait(4, TimeUnit.SECONDS); return null; } public Boolean isChildInView(WebElement child) { Point paneLocation = contentElement.getLocation(); int paneTop = paneLocation.getY(); int paneLeft = paneLocation.getX(); Dimension paneSize = contentElement.getSize(); int paneHeight = paneSize.height; int paneBottom = paneTop + paneHeight; int paneWidth = paneSize.width; int paneRight = paneLeft + paneWidth; Point childLocation = child.getLocation(); int childTop = childLocation.getY(); int childLeft = childLocation.getX(); if (childTop >= paneTop && childTop < paneBottom && childLeft >= paneLeft && childLeft < paneRight) { return true; } return false; } }