package org.catrobat.catroid3d.test.cucumber.util; import org.catrobat.catroid3d.ProjectManager; import org.catrobat.catroid3d.WorldListener; import org.catrobat.catroid3d.io.GestureHandler; import org.catrobat.catroid3d.physics.CollisionDetector; import org.catrobat.catroid3d.physics.Entity; import org.catrobat.catroid3d.ui.ObjectHandler; import org.catrobat.catroid3d.ui.element.ObjectDialogBox; import org.catrobat.catroid3d.ui.element.ToggleOnOffButton; import org.catrobat.catroid3d.ui.screen.BaseScreen; import org.catrobat.catroid3d.ui.screen.MainMenuScreen; import org.catrobat.catroid3d.ui.screen.ProjectBuildScreen; import android.app.Activity; import android.app.Instrumentation; import android.graphics.PointF; import android.util.Log; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.graphics.PerspectiveCamera; import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.math.Vector3; import com.badlogic.gdx.scenes.scene2d.Actor; import com.badlogic.gdx.scenes.scene2d.ui.Button; import com.badlogic.gdx.scenes.scene2d.ui.SplitPane; import com.robotium.solo.Solo; import cucumber.api.android.CucumberInstrumentation; public class SoloLibgdxWrapper extends Solo { private WorldListener worldListener; public SoloLibgdxWrapper(Instrumentation instrumentation, Activity activity) { super(instrumentation, activity); worldListener = ProjectManager.getInstance().getWorldActivity().getWorldListener(); } public void clickOnButton(String buttonId) { try { Button buttonToClick = getActiveScreen().getButton(buttonId); if(buttonToClick == null) { Log.e(CucumberInstrumentation.TAG, "Button (" + buttonId + ") was not found in current screen!"); return; } Vector2 stageCoordinates = libgdxLocalCoordinatesToSoloCoordinates(buttonToClick); this.clickOnScreen(stageCoordinates.x, stageCoordinates.y); } catch(Exception e) { Log.e(CucumberInstrumentation.TAG, e.toString()); } } public boolean isEntityAtPosition(String entityName, Matrix4 position) { Vector3 entityPosition = getEntityPosition(entityName); Vector3 positionToCheck = new Vector3(); position.getTranslation(positionToCheck); if(entityPosition.epsilonEquals(positionToCheck, 5.0f)) { return true; } return false; } public boolean isEntityVisible(String entityName) { Entity entity = worldListener.getWorld().getEntity(entityName); if(entity == null) { return false; } return true; } public Vector3 getEntityPosition(String entityName) { Entity entity = worldListener.getWorld().getEntity(entityName); Vector3 entityPosition = new Vector3(); entity.modelInstance.transform.getTranslation(entityPosition); return entityPosition; } public boolean isEntityFallingDown(String entityName) { Entity entity = worldListener.getWorld().getEntity(entityName); Vector3 velocity = entity.body.getLinearVelocity(); if(velocity.y < 0) { return true; } return false; } public boolean isToggleOnOffButtonChecked(String buttonId) { try { Button buttonToClick = getActiveScreen().getButton(buttonId); if(buttonToClick instanceof ToggleOnOffButton) { return buttonToClick.isChecked(); } } catch(Exception e) { Log.e(CucumberInstrumentation.TAG, e.toString()); } return false; } public boolean isButtonVisible(String buttonId) { try { Button buttonToClick = getActiveScreen().getButton(buttonId); return buttonToClick.isVisible(); } catch(Exception e) { Log.e(CucumberInstrumentation.TAG, e.toString()); } return false; } public boolean isChooseObjectSplitPaneVisible() { try { BaseScreen screen = getActiveScreen(); if(screen instanceof ProjectBuildScreen) { ObjectHandler objectHandler = UtilTest.getFieldFromObject((ProjectBuildScreen)screen, "objectHandler", ObjectHandler.class); SplitPane chooseObjectSplitPane = UtilTest.getFieldFromObject(objectHandler, "chooseObjectSplitPane", SplitPane.class); return chooseObjectSplitPane.isVisible(); } } catch(Exception e) { Log.e(CucumberInstrumentation.TAG, e.toString()); } return false; } public boolean isObjectDialogBoxVisible() { try { BaseScreen screen = getActiveScreen(); if(screen instanceof ProjectBuildScreen) { ObjectHandler objectHandler = UtilTest.getFieldFromObject((ProjectBuildScreen)screen, "objectHandler", ObjectHandler.class); ObjectDialogBox objectDialogBox = UtilTest.getFieldFromObject(objectHandler, "objectDialogBox", ObjectDialogBox.class); return objectDialogBox.isVisible(); } } catch(Exception e) { Log.e(CucumberInstrumentation.TAG, e.toString()); } return false; } public void clickLongOnEntity(String entityName) { clickLongOnEntityPostion(getEntityPosition(entityName)); } public void clickLongOnEntityPostion(Vector3 entityPosition) { Vector2 screenCoords = entityWorldCoordsToScreenCoords(entityPosition); this.clickLongOnScreen(screenCoords.x, screenCoords.y); } public void dragEntityToPosition(String entityName, Vector3 newPosition) { dragEntityToPosition(getEntityPosition(entityName), newPosition); } public void dragEntityToPosition(Vector3 entityPosition, Vector3 newPosition) { Vector2 screenCoords = entityWorldCoordsToScreenCoords(entityPosition); Vector2 newPositionScreenCoords = entityWorldCoordsToScreenCoords(newPosition); this.drag(screenCoords.x, newPositionScreenCoords.x, screenCoords.y, newPositionScreenCoords.y, 20); } public void pinchToZoomIn() { int width = Gdx.graphics.getWidth(); int height = Gdx.graphics.getHeight(); this.pinchToZoom(new PointF(width*2/6, height/2), new PointF(width*4/6, height/2), new PointF(width/6, height/2), new PointF(width*5/6, height/2)); } public void pinchToZoomOut() { int width = Gdx.graphics.getWidth(); int height = Gdx.graphics.getHeight(); this.pinchToZoom(new PointF(width/6, height/2), new PointF(width*5/6, height/2), new PointF(width*2/6, height/2), new PointF(width*4/6, height/2)); } public BaseScreen getActiveScreen() throws IllegalArgumentException, NoSuchFieldException, IllegalAccessException { boolean showMainMenu = UtilTest.getFieldFromObject(worldListener, "showMainMenu", Boolean.class); boolean loading = UtilTest.getFieldFromObject(worldListener, "loading", Boolean.class); if(showMainMenu || loading) { return UtilTest.getFieldFromObject(worldListener, "mainMenuScreen", MainMenuScreen.class); } else { return UtilTest.getFieldFromObject(worldListener, "projectBuildScreen", ProjectBuildScreen.class); } } public PerspectiveCamera getCamera() { return worldListener.movingCamera; } public void swipeLeftForRotation(int degrees) { int height = Gdx.graphics.getHeight(); int width = Gdx.graphics.getWidth(); float lengthToSwipe = degrees/360f * width; float startPointX = width/2 + lengthToSwipe/2; float endPointX = width/2 - lengthToSwipe/2; drag(startPointX, endPointX, height/2f, height/2f, 20); } public void swipeRightForRotation(int degrees) { int height = Gdx.graphics.getHeight(); int width = Gdx.graphics.getWidth(); float lengthToSwipe = degrees/360f * width; float startPointX = width/2 - lengthToSwipe/2; float endPointX = width/2 + lengthToSwipe/2; drag(startPointX, endPointX, height/2f, height/2f, 20); } public void swipeDownwardsForRotation(int degrees) { int height = Gdx.graphics.getHeight(); int width = Gdx.graphics.getHeight(); float lengthToSwipe = degrees/360f * height; float startPointY = height/2 - lengthToSwipe/2; float endPointY = height/2 + lengthToSwipe/2; drag(width/2f, width/2f, startPointY, endPointY, 20); } public void swipeUpwardsForRotation(int degrees) { int height = Gdx.graphics.getHeight(); int width = Gdx.graphics.getHeight(); float lengthToSwipe = degrees/360f * height; float startPointY = height/2 + lengthToSwipe/2; float endPointY = height/2 - lengthToSwipe/2; drag(width/2f, width/2f, startPointY, endPointY, 20); } public void swipeLeft(int stepCount) { int width = Gdx.graphics.getWidth(); int height = Gdx.graphics.getHeight(); float startPointX = width*3/4f; float endPointX = width/4f; drag(startPointX,endPointX, height/2f, height/2f, stepCount); } public void swipeRight(int stepCount) { int width = Gdx.graphics.getWidth(); int height = Gdx.graphics.getHeight(); float startPointX = width/4f; float endPointX = width*3/4f; drag(startPointX,endPointX, height/2f, height/2f, stepCount); } public void swipeUp(int stepCount) { int width = Gdx.graphics.getWidth(); int height = Gdx.graphics.getHeight(); float startPointY = height*3/4f; float endPointY = height/4f; drag(width/2f, width/2f, startPointY, endPointY, stepCount); } public void swipeDown(int stepCount) { int width = Gdx.graphics.getWidth(); int height = Gdx.graphics.getHeight(); float startPointY = height/4f; float endPointY = height*3/4f; drag(width/2f, width/2f, startPointY, endPointY, stepCount); } private Vector2 entityWorldCoordsToScreenCoords(Vector3 entityWorldCoords) { try { BaseScreen screen = getActiveScreen(); if(screen instanceof ProjectBuildScreen) { GestureHandler gestureHandler = UtilTest.getFieldFromObject(screen, "gestureHandler", GestureHandler.class); CollisionDetector collisionDetector = UtilTest.getFieldFromObject(gestureHandler, "collisionDetector", CollisionDetector.class); Vector2 entityScreenCoords = new Vector2(collisionDetector.worldGroundCoordsToScreenCoords(entityWorldCoords)); entityScreenCoords.y = Gdx.graphics.getHeight() - entityScreenCoords.y; return entityScreenCoords; } } catch(Exception e) { Log.e(CucumberInstrumentation.TAG, e.toString()); } return null; } private Vector2 libgdxLocalCoordinatesToSoloCoordinates(Actor actor) { Vector2 coordinates = new Vector2(0, 0); actor.localToStageCoordinates(coordinates); actor.getStage().stageToScreenCoordinates(coordinates); coordinates.x += actor.getWidth()/2.0f; coordinates.y -= actor.getHeight()/2.0f; return coordinates; } }