下面列出了怎么用org.openqa.selenium.Rectangle的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public Rectangle getRect()
{
Rectangle returnValue = null;
webDriver.getExecutionContext().startStep( createStep( "AT" ), null, null );
try
{
returnValue = baseElement.getRect();
}
catch( Exception e )
{
webDriver.getExecutionContext().completeStep( StepStatus.FAILURE, e, null );
}
webDriver.getExecutionContext().completeStep( StepStatus.SUCCESS, null, null );
return returnValue;
}
@Override
public List<WebElement> findElements( SearchContext context )
{
if ( imageName != null )
{
Rectangle r = webDriver.getCloud().getCloudActionProvider().findImage( webDriver, imageName, propertyMap );
if ( r != null )
{
List<WebElement> elementList = new ArrayList<WebElement>( 1 );
elementList.add( new VisualWebElement( webDriver, r ) );
return elementList;
}
}
return null;
}
@Override
public List<WebElement> findElements( SearchContext context )
{
if ( text != null )
{
Rectangle r = webDriver.getCloud().getCloudActionProvider().findText( webDriver, text, propertyMap );
if ( r != null )
{
List<WebElement> elementList = new ArrayList<WebElement>( 1 );
elementList.add( new VisualWebElement( webDriver, r ) );
return elementList;
}
}
return null;
}
/**
*
* Slides the provided object
*
* @param loc object to slide
* @param xStartMult - x point to start on
* @param xEndMult - y point to end on
* @param yStartMult - y point to start on
* @param yEndMult - y point to end on
*/
public static void slideObject(String loc, float xStartMult, float xEndMult, float yStartMult, float yEndMult) {
// Gets the current scale of the device
int scaleFactor = getScale();
// Gets the rectangle of the object to use the x,y and width, height
Rectangle rect = new QAFExtendedWebElement(loc).getRect();
// Gets point to start y
int startY = Math.round(((rect.getY() + (rect.getHeight() * yStartMult))) * scaleFactor);
// Gets point to stop y
int endY = Math.round((rect.getY() + (rect.getHeight() * yEndMult)) * scaleFactor);
// Gets the point to start x
int startX = Math.round((rect.getX() + (rect.getWidth() * xStartMult)) * scaleFactor);
// gets the point to stop y
int endX = Math.round((rect.getX() + ((rect.getWidth()) * xEndMult)) * scaleFactor);
// swipes using the points provided
swipe(startX + "," + startY, endX + "," + endY);
}
@Test
public void canHandleElementGeRectCommand() throws IOException {
CommandExecutor executor = prepareExecutorMock(
echoCapabilities,
valueResponder(ImmutableMap.of("x", 10, "y", 20, "width", 100, "height", 200)));
RemoteWebDriver driver = new RemoteWebDriver(executor, new ImmutableCapabilities());
RemoteWebElement element = new RemoteWebElement();
element.setParent(driver);
element.setId(UUID.randomUUID().toString());
Rectangle rect = element.getRect();
assertThat(rect).isEqualTo(new Rectangle(new Point(10, 20), new Dimension(100, 200)));
verifyCommands(
executor, driver.getSessionId(),
new CommandPayload(DriverCommand.GET_ELEMENT_RECT, ImmutableMap.of("id", element.getId())));
}
@Override
public ExtendedWebElement getElementsByCoordinates(int x, int y) {
String elementName = String.format("Element founded by x:%d - y:%d", x, y);
WebDriver driver = getDriver();
List<WebElement> elements = getEndLevelElements(driver);
List<WebElement> result = new ArrayList<WebElement>();
Rectangle rect;
for (WebElement webElement : elements) {
try {
rect = getRect(webElement);
} catch (Exception e) {
continue;
}
if (isInside(rect, x, y)) {
result.add(webElement);
}
}
return generateExtenedElement(result, elementName);
}
@Test
void testGetRect()
{
Rectangle rect = Mockito.mock(Rectangle.class);
when(webElement.getRect()).thenReturn(rect);
assertEquals(rect, delegatingWebElement.getRect());
}
public void actualTest(AppiumDriver driver) {
WebDriverWait wait = new WebDriverWait(driver, 10);
try {
// find our reference element
WebElement ref = wait
.until(ExpectedConditions.presenceOfElementLocated(referenceElement));
// get the location and dimensions of the reference element, and find its center point
Rectangle rect = ref.getRect();
int refElMidX = rect.getX() + rect.getWidth() / 2;
int refElMidY = rect.getY() + rect.getHeight() / 2;
// set the center point of our desired element; we know it is one row above the
// reference element so we simply have to subtract the height of the reference element
int desiredElMidX = refElMidX;
int desiredElMidY = refElMidY - rect.getHeight();
// perform the TouchAction that will tap the desired point
TouchAction action = new TouchAction<>(driver);
action.press(PointOption.point(desiredElMidX, desiredElMidY));
action.waitAction(WaitOptions.waitOptions(Duration.ofMillis(500)));
action.release();
action.perform();
// finally, verify we made it to the login screen (which means we did indeed tap on
// the desired element)
wait.until(ExpectedConditions.presenceOfElementLocated(username));
} finally {
driver.quit();
}
}
protected void dragElement(Rectangle elRect, double endXPct, double endYPct, Duration duration) {
Point start = new Point((int)(elRect.x + elRect.width / 2), (int)(elRect.y + elRect.height / 2));
Point end = new Point((int)(size.width * endXPct), (int)(size.height * endYPct));
driver.executeScript("mobile: dragFromToForDuration", ImmutableMap.of(
"fromX", start.x, "fromY", start.y,
"toX", end.x, "toY", end.y,
"duration", duration.toMillis() / 1000.0
));
}
@Test
public void testSplitScreen() throws InterruptedException {
// terminate photos and launch reminders to make sure they're both the most recently-
// launched apps
driver.executeScript("mobile: terminateApp", ImmutableMap.of("bundleId", PHOTOS));
driver.executeScript("mobile: launchApp", ImmutableMap.of("bundleId", REMINDERS));
// go to the home screen so we have access to the dock icons
ImmutableMap<String, String> pressHome = ImmutableMap.of("name", "home");
driver.executeScript("mobile: pressButton", pressHome);
// save the location of the icons in the dock so we know where they are when we need
// to drag them later, but no longer have access to them as elements
Rectangle photosIconRect = getDockIconRect("Photos");
// relaunch reminders
driver.executeScript("mobile: launchApp", ImmutableMap.of("bundleId", REMINDERS));
// pull the dock up so we can see the recent icons, and give it time to settle
showDock();
Thread.sleep(800);
// now we can drag the photos app icon over to the right edge to enter split view
// also give it a bit of time to settle
dragElement(photosIconRect, 1.0, 0.5, Duration.ofMillis(1500));
Thread.sleep(800);
driver.setSetting("defaultActiveApplication", PHOTOS);
wait.until(ExpectedConditions.presenceOfElementLocated(MobileBy.AccessibilityId("All Photos")));
driver.setSetting("defaultActiveApplication", REMINDERS);
wait.until(ExpectedConditions.presenceOfElementLocated(MobileBy.AccessibilityId("New Reminder")));
// clean up by terminating both apps
driver.executeScript("mobile: terminateApp", ImmutableMap.of("bundleId", PHOTOS));
driver.executeScript("mobile: terminateApp", ImmutableMap.of("bundleId", REMINDERS));
}
private void shootBird(AndroidDriver driver, WebElement birdEl, int xOffset, int yOffset) {
Rectangle rect = birdEl.getRect();
Point start = new Point(rect.x + rect.width / 2, rect.y + rect.height / 2);
Point end = start.moveBy(xOffset, yOffset);
Duration dragDuration = Duration.ofMillis(750);
PointerInput finger = new PointerInput(Kind.TOUCH, "finger");
Sequence shoot = new Sequence(finger, 0);
shoot.addAction(finger.createPointerMove(Duration.ofMillis(0), Origin.viewport(), start.x, start.y));
shoot.addAction(finger.createPointerDown(MouseButton.LEFT.asArg()));
shoot.addAction(finger.createPointerMove(dragDuration, Origin.viewport(), end.x, end.y));
shoot.addAction(finger.createPointerUp(MouseButton.LEFT.asArg()));
driver.perform(Arrays.asList(shoot));
}
@Override
public Rectangle findImage( DeviceWebDriver webDriver, String imageName, Map<String, String> propertyMap )
{
ImageExecution imageExec = PerfectoMobile.instance( webDriver.getxFID() ).imaging().imageExists( webDriver.getExecutionId(), webDriver.getDeviceName(), imageName, propertyMap );
if ( imageExec != null && Boolean.parseBoolean( imageExec.getStatus() ) )
return new Rectangle( new Point( Integer.parseInt( imageExec.getLeft() ), Integer.parseInt( imageExec.getTop() ) ), new Dimension( Integer.parseInt( imageExec.getWidth() ), Integer.parseInt( imageExec.getHeight() ) ) );
return null;
}
@Override
public Rectangle findText( DeviceWebDriver webDriver, String text, Map<String, String> propertyMap )
{
ImageExecution imageExec = PerfectoMobile.instance( webDriver.getxFID() ).imaging().textExists( webDriver.getExecutionId(), webDriver.getDeviceName(), text, propertyMap );
if ( imageExec != null && Boolean.parseBoolean( imageExec.getStatus() ) )
return new Rectangle( new Point( Integer.parseInt( imageExec.getLeft() ), Integer.parseInt( imageExec.getTop() ) ), new Dimension( Integer.parseInt( imageExec.getWidth() ), Integer.parseInt( imageExec.getHeight() ) ) );
return null;
}
public VisualWebElement ( DeviceWebDriver webDriver, Rectangle r )
{
this.location = r.getPoint();
this.size = r.getDimension();
this.webDriver = webDriver;
}
/**
* This function will calculate the location of the element on the device and
* manually tap the point location of the middle of the element. This function
* accounts that there may be a header to offset from.
*
* @param loc - locator to find the element to be clicked
* @param addressBar - navigation bar that takes up the top half of the device
* outside of the webview
*/
public static void touchObject(String loc, String addressBar) {
int bannerY = getOffset(addressBar);
int scaleFactor = getScale();
// Gets the rectangle of the element we want to click
Rectangle rect = new QAFExtendedWebElement(loc).getRect();
// calculates the middle x value using the rectangle and multiplying the scale
int x = (rect.getX() + (rect.getWidth() / 2)) * scaleFactor;
// calculates the middle y value using the rectangle, adding the offset
// and multiplying the scale
int y = (rect.getY() + (rect.getHeight() / 2) + bannerY) * scaleFactor;
// Touch the device at the point calculated
touch(x + "," + y);
}
/**
* Gets the offset of the header values to offset y value of the header element
*
* @param addressBar - header element to measure
* @param context - context of the element to use
* @return the y offset of the element
*/
public static int getOffset(String addressBar, String context) {
// Stores the current context so we can switch to it at the end
String curContext = DeviceUtils.getCurrentContext();
// Switch to native context
switchToContext(context);
// Gets the rectangle of the welement to get the x,y and width height
Rectangle view = new QAFExtendedWebElement(addressBar).getRect();
switchToContext(curContext); // Switch back to the original context
// this gets the application size of the area above the viewport
// we will use this to offset the element
return (view.getY() + view.getHeight());
}
@Override
public Rectangle getRect() {
if (rectCache == null) {
rectCache = new ObjectCache<>(super::getRect);
}
return rectCache.getValue();
}
@Test
public void shouldCallGetRectOnUnderlyingWebElement() {
WebDriver.TargetLocator locator = mock(WebDriver.TargetLocator.class);
WebDriverTarget target = mock(WebDriverTarget.class);
TargetedWebElement element = mock(TargetedWebElement.class);
when(element.getRect()).thenReturn(mock(Rectangle.class));
TargetedWebElement targetedWebElement = new TargetedWebElement(locator, target, element);
targetedWebElement.getRect();
verify(element).getRect();
}
/**
* Transforms a map into {@link Rectangle} object.
*
* @param map the source map.
* @return {@link Rectangle} object
*/
public static Rectangle mapToRect(Map<String, Object> map) {
return new Rectangle(toSeleniumCoordinate(map.get("x")),
toSeleniumCoordinate(map.get("y")),
toSeleniumCoordinate(map.get("height")),
toSeleniumCoordinate(map.get("width")));
}
@Override
@SuppressWarnings({"unchecked"})
public Rectangle getRect() {
Response response = execute(DriverCommand.GET_ELEMENT_RECT(id));
Map<String, Object> rawRect = (Map<String, Object>) response.getValue();
int x = ((Number) rawRect.get("x")).intValue();
int y = ((Number) rawRect.get("y")).intValue();
int width = ((Number) rawRect.get("width")).intValue();
int height = ((Number) rawRect.get("height")).intValue();
return new Rectangle(x, y, height, width);
}
@Override
public ICapturable highlight(Rectangle rect) {
try {
Graphics2D g2d = screenshot.createGraphics();
g2d.setColor(Color.red);
g2d.drawRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
} catch (Exception e) {
LOGGER.error("Unable to highligh screenshot: " + e.getMessage());
}
return this;
}
/**
* Method return 1 in case if y is lower than element, -1 if higher, 0 - if
* 'y' within the element's range
*
* @param rect Rectangle
* @param y int
* @return int
*/
public int isLower(Rectangle rect, int y) {
LOGGER.debug(String.format("isLower(): Rectangle: x - %d. y - %d. Width: %d, height: %d", rect.x, rect.y, rect.width, rect.height));
if (y > rect.y + rect.height) {
return 1;
} else if (y < rect.y) {
return -1;
}
return 0;
}
@Override
public ExtendedWebElement getElementsByCoordinates(int x, int y) {
String elementName = String.format("Element founded by x:%d - y:%d", x, y);
WebDriver driver = getDriver();
List<WebElement> elements = getEndLevelElements(driver);
WebElement tempElement;
int index = 0;
int isLower;
Rectangle tempRect;
while (elements.size() != 1) {
index = (int) (Math.round(elements.size() / 2));
tempElement = elements.get(index);
tempRect = getRect(tempElement);
isLower = isLower(tempRect, y);
LOGGER.debug("Is Lower: " + isLower);
if (isInside(tempRect, x, y) || isLower == 0) {
break;
}
if (isLower == 1) {
elements = elements.subList(index, elements.size());
} else {
elements = elements.subList(0, index);
}
}
LOGGER.debug("Index: " + index);
if (elements.size() == 1) {
return generateExtenedElement(elements, elementName);
}
return generateExtenedElement(checkBoundaryElements(elements, x, y, index), elementName);
}
/**
* Method to check boundary elements since there is a chance that there are
* some elements in the same 'y' range
*
* @param elements
* @param x
* @param y
* @param index
* @return
*/
private List<WebElement> checkBoundaryElements(List<WebElement> elements, int x, int y, int index) {
LOGGER.debug(String.format("Index: %d.", index));
List<WebElement> elementsFirstPart = elements.subList(0, index);
List<WebElement> elementsSecondPart = elements.subList(index, elements.size());
List<WebElement> elementsInside = new ArrayList<WebElement>();
WebElement element;
Rectangle tempRect;
for (int i = elementsFirstPart.size() - 1; i >= 0; i--) {
element = elementsFirstPart.get(i);
tempRect = getRect(element);
if (isInside(tempRect, x, y)) {
elementsInside.add(element);
} else if (tempRect.y > y) {
// stop validation as soon as 'y' coordinate will be out of
// element's location
break;
}
}
for (int i = 0; i < elementsSecondPart.size(); i++) {
element = elementsSecondPart.get(i);
tempRect = getRect(element);
if (isInside(tempRect, x, y)) {
elementsInside.add(element);
} else if (tempRect.y + tempRect.height < y) {
// stop validation as soon as 'y' coordinate will be out of
// element's location
break;
}
}
return elementsInside;
}
public Rectangle getRect() {
// TODO Auto-generated method stub
return null;
}
@Override
public Rectangle getRect()
{
return wrappedElement.getRect();
}
private static WebElement mockWebElementWithRect(int x, int y, int height, int width)
{
WebElement element = mock(WebElement.class);
when(element.getRect()).thenReturn(new Rectangle(x, y, height, width));
return element;
}
protected Rectangle getDockIconRect(String appName) {
By iconLocator = By.xpath("//*[@name='Multitasking Dock']//*[@name='" + appName + "']");
WebElement icon = wait.until(
ExpectedConditions.presenceOfElementLocated(iconLocator));
return icon.getRect();
}
@Test
public void ZoomInAndOut() throws InterruptedException {
// tap center to dismiss toolbars
WebElement map = driver.findElementById("com.google.android.apps.maps:id/mainmap_container");
map.click();
Rectangle mapCoordinates = map.getRect();
Point center = getCenter(mapCoordinates);
driver.perform(zoomOut(center, 450));
Thread.sleep(1000);
driver.perform(zoomIn(center, 450));
Thread.sleep(1000);
driver.perform(zoomOut(center.moveBy(0, 250), 300));
Thread.sleep(1000);
driver.perform(zoomIn(center.moveBy(0, -250), 300));
Thread.sleep(3000);
}
private Point getCenter(Rectangle rect) {
return new Point(rect.x + rect.getWidth() / 2, rect.y + rect.getHeight() / 2);
}