/* ************************************************************************
qxwebdriver-java
http://github.com/qooxdoo/qxwebdriver-java
Copyright:
2014 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.mobile.core;
import java.util.Iterator;
import java.util.List;
import org.oneandone.qxwebdriver.QxWebDriver;
import org.oneandone.qxwebdriver.ui.Touchable;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.HasInputDevices;
import org.openqa.selenium.interactions.HasTouchScreen;
import org.openqa.selenium.interactions.Mouse;
import org.openqa.selenium.interactions.internal.Coordinates;
import org.openqa.selenium.interactions.touch.TouchActions;
import org.openqa.selenium.internal.Locatable;
public class WidgetImpl extends org.oneandone.qxwebdriver.ui.core.WidgetImpl implements Touchable {
public WidgetImpl(WebElement element, QxWebDriver webDriver) {
super(element, webDriver);
// workaround for https://github.com/selendroid/selendroid/issues/337
contentElement = element;
}
public boolean isDisplayed() {
if (contentElement.isDisplayed()) {
String script = "return arguments[0].offsetWidth > 0 || arguments[0].offsetHeight > 0";
return (Boolean) jsExecutor.executeScript(script, contentElement);
} else {
return false;
}
}
public void tap() {
tap(driver.getWebDriver(), contentElement);
}
public static void tap(WebDriver driver, WebElement element) {
if (driver instanceof HasTouchScreen) {
TouchActions tap = new TouchActions(driver).singleTap(element);
tap.perform();
} else {
element.click();
}
}
public void longtap() {
longtap(driver.getWebDriver(), contentElement);
}
public static void longtap(WebDriver driver, WebElement element) {
if (driver instanceof HasTouchScreen) {
TouchActions longtap = new TouchActions(driver);
Point center = getCenter(element);
longtap.down(center.getX(), center.getY());
longtap.perform();
try {
Thread.sleep(750);
} catch (InterruptedException e) {}
longtap.up(center.getX(), center.getY());
longtap.perform();
} else {
Locatable locatable = (Locatable) element;
Coordinates coords = locatable.getCoordinates();
Mouse mouse = ((HasInputDevices) driver).getMouse();
mouse.mouseDown(coords);
try {
Thread.sleep(750);
} catch (InterruptedException e) {}
mouse.mouseUp(coords);
}
}
protected static Point getCenter(WebElement element) {
Dimension size = element.getSize();
int halfWidth = size.getWidth() / 2;
int halfHeight = size.getHeight() / 2;
Point loc = element.getLocation();
int posX = loc.getX() + halfWidth;
int posY = loc.getY() + halfHeight;
Point point = new Point(posX, posY);
return point;
}
public void track(int x, int y, int step) {
track(driver.getWebDriver(), contentElement, x, y, step);
}
public static void track(WebDriver driver, WebElement element, int x, int y, int step) {
if (driver instanceof HasTouchScreen) {
if (step == 0) {
step = 1;
// TODO: no move if step == 0
}
Point center = getCenter(element);
int posX = center.getX();
int posY = center.getY();
int endX = posX + x;
int endY = posY + y;
TouchActions touchAction = new TouchActions(driver);
touchAction.down(posX, posY);
while ((x < 0 && posX > endX || x > 0 && posX < endX) || (y < 0 && posY> endY || y > 0 && posY < endY)) {
if (x > 0 && posX < endX) {
if (posX + step > endX) {
posX += endX - (posX + step);
} else {
posX += step;
}
}
else if (x < 0 && posX > endX) {
if (posX - step < endX) {
posX -= endX + (posX - step);
} else {
posX -= step;
}
}
if (y > 0 && posY < endY) {
if (posY + step > endY) {
posY += endY - (posY + step);
} else {
posY += step;
}
}
else if (y < 0 && posY > endY) {
if (posY - step < endY) {
posY -= endY + (posY - step);
} else {
posY -= step;
}
}
touchAction.move(posX, posY);
}
touchAction.up(posX, posY)
.perform();
}
else {
Actions mouseAction = new Actions(driver);
mouseAction.dragAndDropBy(element, x, y);
}
}
public void scrollTo(int x, int y) {
String script = "qx.ui.mobile.core.Widget.getWidgetById(arguments[0].id).scrollTo(" + x + ", " + y + ")";
List<WebElement> scrollContainers = driver.findElements(By.cssSelector(".scroll"));
Iterator<WebElement> itr = scrollContainers.iterator();
while (itr.hasNext()) {
WebElement scroller = itr.next();
if (scroller.isDisplayed()) {
driver.executeScript(script, scroller);
}
}
}
}