Skip to content

Commit

Permalink
feat(java): ✨ added support to draw diagrams using points (#968)
Browse files Browse the repository at this point in the history
  • Loading branch information
WasiqB authored Jan 11, 2025
1 parent d4cc0f5 commit f119a5e
Show file tree
Hide file tree
Showing 24 changed files with 2,320 additions and 1,428 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@
import java.util.function.Consumer;
import java.util.function.Function;

import io.appium.java_client.AppiumDriver;
import io.github.boykaframework.builders.Locator;
import io.github.boykaframework.exception.FrameworkError;
import org.apache.logging.log4j.Logger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

/**
* Common action methods to perform different actions on devices / browsers and on elements.
Expand Down Expand Up @@ -169,7 +169,7 @@ public static void performElementAction (final Consumer<WebElement> action, fina
public static void performMobileGestures (final Collection<Sequence> sequences) {
LOGGER.traceEntry ();
try {
performDriverAction (driver -> ((AppiumDriver) driver).perform (sequences));
performDriverAction (driver -> ((RemoteWebDriver) driver).perform (sequences));
} catch (final WebDriverException e) {
handleAndThrow (DRIVER_ERROR_OCCURRED, e, e.getMessage ());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@ public void pause (final Duration time) {
LOGGER.traceExit ();
}

@Override
public void pressKeys (final String... keys) {
LOGGER.traceEntry ();
LOGGER.info ("Pressing keys: {}", (Object[]) keys);
ofNullable (this.listener).ifPresent (l -> l.onPressKeys (keys));
performDriverAction (driver -> new Actions (driver).sendKeys (keys)
.perform ());
}

@Override
public void saveLogs () {
LOGGER.traceEntry ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import static java.util.Optional.ofNullable;
import static org.apache.logging.log4j.LogManager.getLogger;

import java.util.List;

import io.github.boykaframework.actions.interfaces.elements.IClickableActions;
import io.github.boykaframework.actions.interfaces.listeners.elements.IClickableActionsListener;
import io.github.boykaframework.builders.Locator;
Expand Down Expand Up @@ -64,7 +66,7 @@ public void click () {
LOGGER.info ("Clicking on element: {}", this.locator.getName ());
ofNullable (this.listener).ifPresent (l -> l.onClick (this.locator));
pause (this.delaySetting.getBeforeClick ());
MouseActionBuilder.builder ()
MouseActionBuilder.buildAction ()
.sourceLocator (this.locator)
.build ()
.click ();
Expand All @@ -76,7 +78,7 @@ public void clickAndHold () {
LOGGER.traceEntry ();
LOGGER.info ("Click and hold on element: {}", this.locator.getName ());
ofNullable (this.listener).ifPresent (l -> l.onClickAndHold (this.locator));
MouseActionBuilder.builder ()
MouseActionBuilder.buildAction ()
.sourceLocator (this.locator)
.build ()
.clickAndHold ();
Expand All @@ -88,7 +90,7 @@ public void doubleClick () {
LOGGER.traceEntry ();
LOGGER.info ("Double Click on element: {}", this.locator.getName ());
ofNullable (this.listener).ifPresent (l -> l.onDoubleClick (this.locator));
MouseActionBuilder.builder ()
MouseActionBuilder.buildAction ()
.sourceLocator (this.locator)
.build ()
.doubleClick ();
Expand All @@ -100,19 +102,32 @@ public void dragTo (final Locator destination) {
LOGGER.traceEntry ();
LOGGER.info ("Drag and Drop on element: {} , {}", this.locator.getName (), destination.getName ());
ofNullable (this.listener).ifPresent (l -> l.onDragTo (this.locator, destination));
MouseActionBuilder.builder ()
MouseActionBuilder.buildAction ()
.sourceLocator (this.locator)
.build ()
.dragAndDrop (destination);
LOGGER.traceExit ();
}

@Override
public void draw (final List<MouseAction> actions) {
LOGGER.traceEntry ();
LOGGER.info ("Drawing on element: {}", this.locator.getName ());
ofNullable (this.listener).ifPresent (l -> l.onDraw (actions));
final var sequence = MouseActionBuilder.buildAction ()
.sourceLocator (this.locator)
.build ()
.composeActions (actions);
performMobileGestures (singletonList (sequence));
LOGGER.traceExit ();
}

@Override
public void hover () {
LOGGER.traceEntry ();
LOGGER.info ("Hover on element: {}", this.locator.getName ());
ofNullable (this.listener).ifPresent (l -> l.onHover (this.locator));
MouseActionBuilder.builder ()
MouseActionBuilder.buildAction ()
.sourceLocator (this.locator)
.build ()
.moveTo ();
Expand All @@ -124,7 +139,7 @@ public void pressBackButton () {
LOGGER.traceEntry ();
LOGGER.info ("Pressing the Mouse Back button...");
ofNullable (this.listener).ifPresent (IClickableActionsListener::onPressBackButton);
final var sequence = MouseActionBuilder.builder ()
final var sequence = MouseActionBuilder.buildAction ()
.build ()
.backButtonClick ();
performMobileGestures (singletonList (sequence));
Expand All @@ -136,7 +151,7 @@ public void pressForwardButton () {
LOGGER.traceEntry ();
LOGGER.info ("Pressing the Mouse Forward button...");
ofNullable (this.listener).ifPresent (IClickableActionsListener::onPressForwardButton);
final var sequence = MouseActionBuilder.builder ()
final var sequence = MouseActionBuilder.buildAction ()
.build ()
.forwardButtonClick ();
performMobileGestures (singletonList (sequence));
Expand All @@ -148,7 +163,7 @@ public void rightClick () {
LOGGER.traceEntry ();
LOGGER.info ("Right Click on element: {}", this.locator.getName ());
ofNullable (this.listener).ifPresent (l -> l.onRightClick (this.locator));
MouseActionBuilder.builder ()
MouseActionBuilder.buildAction ()
.sourceLocator (this.locator)
.build ()
.rightClick ();
Expand All @@ -160,7 +175,7 @@ public void scrollToElement () {
LOGGER.traceEntry ();
LOGGER.info ("Scrolling to element: {}", this.locator.getName ());
ofNullable (this.listener).ifPresent (l -> l.onScrollToElement (this.locator));
MouseActionBuilder.builder ()
MouseActionBuilder.buildAction ()
.sourceLocator (this.locator)
.build ()
.scrollTo ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
import io.github.boykaframework.builders.Locator;
import io.github.boykaframework.config.ui.DelaySetting;
import org.apache.logging.log4j.Logger;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebElement;

/**
Expand Down Expand Up @@ -98,6 +100,22 @@ public String getAttribute (final String attribute) {
return LOGGER.traceExit (getAttributeValue (attribute));
}

@Override
public WebElement getElement () {
LOGGER.traceEntry ();
LOGGER.info ("Getting the WebElement located by: {}", this.locator.getName ());
ofNullable (this.listener).ifPresent (l -> l.onGetElement (this.locator));
return getElementAttribute (e -> e, this.locator, null);
}

@Override
public Point getLocation () {
LOGGER.traceEntry ();
LOGGER.info ("Getting location of element located by: {}", this.locator.getName ());
ofNullable (this.listener).ifPresent (l -> l.onGetLocation (this.locator));
return LOGGER.traceExit (getElementAttribute (WebElement::getLocation, this.locator, new Point (0, 0)));
}

@Override
public String getProperty (final String property) {
LOGGER.traceEntry ();
Expand All @@ -106,6 +124,14 @@ public String getProperty (final String property) {
return LOGGER.traceExit (getPropertyValue (property));
}

@Override
public Dimension getSize () {
LOGGER.traceEntry ();
LOGGER.info ("Getting size of element located by: {}", this.locator.getName ());
ofNullable (this.listener).ifPresent (l -> l.onGetSize (this.locator));
return LOGGER.traceExit (getElementAttribute (WebElement::getSize, this.locator, new Dimension (0, 0)));
}

@Override
public String getStyle (final String styleName) {
LOGGER.traceEntry ();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* MIT License
*
* Copyright (c) 2025, Boyka Framework
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*/

package io.github.boykaframework.actions.elements;

import static org.openqa.selenium.interactions.PointerInput.MouseButton.LEFT;

import java.time.Duration;

import lombok.Builder;
import lombok.Getter;
import org.openqa.selenium.Point;
import org.openqa.selenium.interactions.PointerInput;

/**
* Handles mouse action details.
*
* @author Wasiq Bhamla
* @since 06-Jan-2024
*/
@Getter
@Builder (builderMethodName = "composeAction", buildMethodName = "compose")
public class MouseAction {
/**
* Different Mouse action types.
*/
public enum ActionType {
/**
* Pointer move.
*/
MOVE,
/**
* Pause for the specified duration.
*/
PAUSE,
/**
* Pointer down.
*/
PRESS,
/**
* Pointer up.
*/
RELEASE
}

private ActionType actionType;
@Builder.Default
private PointerInput.MouseButton button = LEFT;
private Duration duration;
private Point location;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
import static io.github.boykaframework.actions.CommonActions.performDriverAction;
import static io.github.boykaframework.actions.CommonActions.performElementAction;
import static io.github.boykaframework.actions.elements.ElementFinder.find;
import static io.github.boykaframework.actions.elements.MouseAction.ActionType.PAUSE;
import static io.github.boykaframework.actions.elements.MouseAction.ActionType.PRESS;
import static io.github.boykaframework.actions.elements.MouseAction.ActionType.RELEASE;
import static io.github.boykaframework.enums.Message.ELEMENT_CANNOT_BE_NULL;
import static io.github.boykaframework.enums.WaitStrategy.CLICKABLE;
import static io.github.boykaframework.manager.ParallelSession.getSession;
Expand All @@ -28,7 +31,9 @@
import static org.openqa.selenium.interactions.PointerInput.Kind.MOUSE;
import static org.openqa.selenium.interactions.PointerInput.MouseButton.BACK;
import static org.openqa.selenium.interactions.PointerInput.MouseButton.FORWARD;
import static org.openqa.selenium.interactions.PointerInput.Origin.viewport;

import java.util.List;
import java.util.function.BiFunction;

import io.github.boykaframework.builders.Locator;
Expand All @@ -44,12 +49,12 @@
* @author Wasiq Bhamla
* @since 27-Dec-2024
*/
@Builder
@Builder (builderMethodName = "buildAction")
public class MouseActionBuilder {
private Locator sourceLocator;

Sequence backButtonClick () {
return mouseAction (BACK);
return mouseButtonAction (BACK);
}

void click () {
Expand All @@ -62,6 +67,23 @@ void clickAndHold () {
.perform (), this.sourceLocator);
}

Sequence composeActions (final List<MouseAction> actions) {
return composeMouseSequence ((mouse, steps) -> {
actions.forEach (action -> {
switch (action.getActionType ()) {
case MOVE -> steps.addAction (
mouse.createPointerMove (action.getDuration (), viewport (), action.getLocation ()));
case PAUSE -> steps.addAction (new Pause (mouse, action.getDuration ()));
case PRESS -> steps.addAction (mouse.createPointerDown (action.getButton ()
.asArg ()));
default -> steps.addAction (mouse.createPointerUp (action.getButton ()
.asArg ()));
}
});
return steps;
});
}

void doubleClick () {
performElementAction ((d, e) -> new Actions (d).doubleClick (e)
.perform (), this.sourceLocator);
Expand All @@ -74,7 +96,7 @@ void dragAndDrop (final Locator targetLocator) {
}

Sequence forwardButtonClick () {
return mouseAction (FORWARD);
return mouseButtonAction (FORWARD);
}

void moveTo () {
Expand All @@ -84,7 +106,7 @@ void moveTo () {

void rightClick () {
if (isNull (this.sourceLocator)) {
performDriverAction ((d) -> new Actions (d).contextClick ()
performDriverAction (d -> new Actions (d).contextClick ()
.perform ());
} else {
performElementAction ((d, e) -> new Actions (d).contextClick (e)
Expand All @@ -103,16 +125,22 @@ private Sequence composeMouseSequence (final BiFunction<PointerInput, Sequence,
return steps.apply (mouse, sequence);
}

private Sequence mouseAction (final PointerInput.MouseButton button) {
private Sequence mouseButtonAction (final PointerInput.MouseButton button) {
final var delaySetting = getSession ().getSetting ()
.getUi ()
.getDelay ();

return composeMouseSequence ((mouse, steps) -> {
steps.addAction (mouse.createPointerDown (button.asArg ()));
steps.addAction (new Pause (mouse, ofMillis (delaySetting.getBeforeSwipe ())));
steps.addAction (mouse.createPointerUp (button.asArg ()));
return steps;
});
final var actions = List.of (MouseAction.composeAction ()
.button (button)
.actionType (PRESS)
.compose (), MouseAction.composeAction ()
.actionType (PAUSE)
.duration (ofMillis (delaySetting.getBeforeSwipe ()))
.compose (), MouseAction.composeAction ()
.actionType (RELEASE)
.button (button)
.compose ());

return composeActions (actions);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ public interface IDriverActions {
*/
void pause (final Duration time);

/**
* Press keys on the window.
*
* @param keys Keys to press.
*/
void pressKeys (final String... keys);

/**
* Save all the available logs to files in `logs` folder.
*/
Expand Down
Loading

0 comments on commit f119a5e

Please sign in to comment.