blob: af5ac049961a48c8d626eba93751046a9ebe8b67 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2020 THALES GLOBAL SERVICES.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.tests.swtbot;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.Collections;
import java.util.ListIterator;
import java.util.Set;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.sirius.diagram.DDiagram;
import org.eclipse.sirius.diagram.ui.business.api.view.SiriusLayoutDataManager;
import org.eclipse.sirius.diagram.ui.edit.api.part.AbstractDiagramContainerEditPart;
import org.eclipse.sirius.diagram.ui.internal.edit.parts.DNodeEditPart;
import org.eclipse.sirius.ext.gmf.runtime.editparts.GraphicalHelper;
import org.eclipse.sirius.tests.support.api.GraphicTestsSupportHelp;
import org.eclipse.sirius.tests.swtbot.support.api.AbstractSiriusSwtBotGefTestCase;
import org.eclipse.sirius.tests.swtbot.support.api.business.UIDiagramRepresentation.ZoomLevel;
import org.eclipse.sirius.tests.swtbot.support.api.business.UILocalSession;
import org.eclipse.sirius.tests.swtbot.support.api.business.UIResource;
import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotSiriusDiagramEditor;
import org.eclipse.sirius.tests.swtbot.support.api.view.DesignerViews;
import org.eclipse.sirius.tests.swtbot.support.utils.SWTBotUtils;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swtbot.eclipse.gef.finder.matchers.IsInstanceOf;
import org.eclipse.swtbot.eclipse.gef.finder.widgets.SWTBotGefEditPart;
/**
* Tests for the popup menu tool that creates element by grouping several elements (grouping two EClass in a new
* EPackage). Validate that the created EPackage is located in the middle of the canvas avoiding overlap.
*
* See VP-1859.
*
* @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a>
*/
public class GroupElementsInOneOtherTests extends AbstractSiriusSwtBotGefTestCase {
private static final String PATH = "data/unit/tools/creation/popupMenu/VP-1859/";
private static final String SEMANTIC_RESOURCE_NAME = "vp-1859.ecore";
private static final String SESSION_RESOURCE_NAME = "vp-1859.aird";
private static final String MODELER_RESOURCE_NAME = "vp-1859.odesign";
private static final String FIRST_REPRESENTATION_NAME = "VP-1859-RealCase";
private static final String FIRST_REPRESENTATION_INSTANCE_NAME = "new " + FIRST_REPRESENTATION_NAME;
private static final String GROUP_TOOL_NAME = "Group in new Package";
private static final String CREATION_TOOL_NAME = "Create 2 packages outside the selected element";
private UIResource sessionAirdResource;
private UILocalSession localSession;
/** Bot of the DiagramEditPart */
protected SWTBotGefEditPart diagramEditPartBot;
private SWTBotGefEditPart class1ChildOfDiagramBot;
private SWTBotGefEditPart class3ChildOfDiagramBot;
private SWTBotGefEditPart class4ChildOfDiagramBot;
@Override
protected void onSetUpBeforeClosingWelcomePage() throws Exception {
copyFileToTestProject(Activator.PLUGIN_ID, PATH, SEMANTIC_RESOURCE_NAME, SESSION_RESOURCE_NAME, MODELER_RESOURCE_NAME);
}
@Override
protected boolean getAutoRefreshMode() {
return true;
}
/**
* Open the diagram and gather the initial bounds of all the bordered nodes.
*/
@Override
protected void onSetUpAfterOpeningDesignerPerspective() throws Exception {
sessionAirdResource = new UIResource(designerProject, "/", SESSION_RESOURCE_NAME);
localSession = designerPerspective.openSessionFromFile(sessionAirdResource);
closeOutline();
editor = (SWTBotSiriusDiagramEditor) openRepresentation(localSession.getOpenedSession(), FIRST_REPRESENTATION_NAME, FIRST_REPRESENTATION_INSTANCE_NAME, DDiagram.class, true, true);
editor.scrollTo(0, 0);
diagramEditPartBot = editor.rootEditPart().children().get(0);
class1ChildOfDiagramBot = diagramEditPartBot.descendants(IsInstanceOf.instanceOf(DNodeEditPart.class)).get(0);
class3ChildOfDiagramBot = diagramEditPartBot.descendants(IsInstanceOf.instanceOf(DNodeEditPart.class)).get(2);
class4ChildOfDiagramBot = diagramEditPartBot.descendants(IsInstanceOf.instanceOf(DNodeEditPart.class)).get(3);
}
/**
* Test that grouping two EClass into a new Package (without scroll), locates this new Package at the center of the
* visible part of the canvas without overlapping.<BR>
* Currently there is no overlapping for the top-left corner. A specific issue VP-2399 must be fix to check that
* there is no overlap of all the figure.
*/
public void testGroupActionInDiagramEditPartWithoutScroll() {
// WARNING : This test need to be ran in a specific resolution (@see
// Xephyr conf)
// Select Class1 & Class3
editor.select(class1ChildOfDiagramBot, class3ChildOfDiagramBot);
// Get the center of the visible part of the editor before the group
// action (in logical coordinates, not in screen coordinates)
Point absoluteEditorCenter = getEditorVisiblePart(class4ChildOfDiagramBot.part()).getCenter();
GraphicalHelper.screen2logical(absoluteEditorCenter, (IGraphicalEditPart) class4ChildOfDiagramBot.part());
// Launch the group action
editor.clickContextMenu(GROUP_TOOL_NAME);
// Check that the top-left corner does not overlap another figure at the
// same level (brother edit parts).
SWTBotGefEditPart package5Bot = editor.getEditPart("Package5", AbstractDiagramContainerEditPart.class);
Point package5AbsoluteLocation = editor.getAbsoluteLocation("Package5", AbstractDiagramContainerEditPart.class);
assertFalse("The location (top-left corner) of the new figure should not overlaped an existing figure",
isThereFigureAtLocation(((GraphicalEditPart) editor.mainEditPart().part()).getContentPane(), package5AbsoluteLocation,
Collections.singleton(((org.eclipse.gef.GraphicalEditPart) package5Bot.part()).getFigure())));
// Assert that the created EPackage is in the center of the screen
// Get the absolute location of p4 package (in logical coordinates, not
// in screen coordinates)
if (GraphicalHelper.getZoom(package5Bot.part()) != ZoomLevel.ZOOM_200.getAmount()) {
GraphicTestsSupportHelp.assertEquals("The newly created Package5 should be at the center of the visible part of the diagram", absoluteEditorCenter, package5AbsoluteLocation, 5, 5);
} else {
// We don't make the same test with zoom at 200% because the middle
// of the visible
// part of the diagram is on another container so the new container
// is shifted.
Point expectedPoint = new Point(300, 125);
if (!package5AbsoluteLocation.equals(expectedPoint)) {
// Check the screen resolution to fail only when it is as expected
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
if (screenSize.width == 1440 || screenSize.height == 900) {
fail("The newly created Package5 should be at the center of the visible part of the diagram. expected:<" + expectedPoint + "> but was:<" + package5AbsoluteLocation + ">");
}
}
}
}
/**
* Test that creating two elements outside the current selection, does not overlapped this new packages
* (VP-2609).<BR>
* Currently there is no overlapping for the top-left corner. A specific issue VP-2399 must be fix to check that
* there is no overlap of all the figure.
*/
public void testMultiCreationOutsideCurrentSelection() {
testMultiCreationOutsideCurrentSelection(false);
}
/**
* Test that creating two elements outside the current selection (with snapToGrid enabled), does not overlapped this
* new packages (VP-2609).<BR>
* Currently there is no overlapping for the top-left corner. A specific issue VP-2399 must be fix to check that
* there is no overlap of all the figure.
*/
public void testMultiCreationOutsideCurrentSelectionWithSnapToGridEnabled() {
testMultiCreationOutsideCurrentSelection(true);
}
/**
* Test that creating two elements outside the current selection (with snapToGrid enabled), does not overlapped this
* new packages (VP-2609).<BR>
* Currently there is no overlapping for the top-left corner. A specific issue VP-2399 must be fix to check that
* there is no overlap of all the figure.
*/
private void testMultiCreationOutsideCurrentSelection(boolean isSnapToGridEnabled) {
if (isSnapToGridEnabled) {
editor.setSnapToGrid(true, 50, 2);
}
try {
// Select Class1 & Class3
editor.select(class1ChildOfDiagramBot, class3ChildOfDiagramBot);
// Launch the action that create 2 packages outside the current
// selected
// element
editor.clickContextMenu(CREATION_TOOL_NAME);
// Check that the two new packages top-left corner does not overlap
// each
// other.
Point package5AbsoluteLocation = editor.getAbsoluteLocation("Package5", AbstractDiagramContainerEditPart.class);
Point package6AbsoluteLocation = editor.getAbsoluteLocation("Package6", AbstractDiagramContainerEditPart.class);
assertFalse("The location (top-left corner) of the first created figure should not overlaped the location (top-left corner) of the second created figure.",
package5AbsoluteLocation.equals(package6AbsoluteLocation));
int padding = SiriusLayoutDataManager.PADDING;
if (isSnapToGridEnabled) {
padding = 50;
}
assertEquals("The x coordinate of Package6 should have a delta of " + padding + " pixels with the x coordinate of the Package5.", package5AbsoluteLocation.x + padding,
package6AbsoluteLocation.x);
assertEquals("The y coordinate of Package6 should have a delta of " + padding + " pixels with the y coordinate of the Package5.", package5AbsoluteLocation.y + padding,
package6AbsoluteLocation.y);
if (isSnapToGridEnabled) {
checkLocationAlignOnGrid(package5AbsoluteLocation, "Package5", padding);
checkLocationAlignOnGrid(package6AbsoluteLocation, "Package6", padding);
}
} finally {
editor.setSnapToGrid(false);
}
}
/**
* Get a rectangle representing the visible part in screen coordinates.
*
* @param part
* a part from the diagram.
* @return A rectangle representing the visible part in screen coordinates.
*/
public static Rectangle getEditorVisiblePart(EditPart part) {
Rectangle result = new Rectangle();
Control control = part.getViewer().getControl();
if (control instanceof FigureCanvas) {
result = ((FigureCanvas) part.getViewer().getControl()).getViewport().getBounds();
}
return result;
}
/**
* Check if there is a figure (children of parent) at the supplied <code>location</code>.
*
* @param parent
* The parent figure
* @param location
* the location being tested.
* @param figuresToIgnore
* {@link IFigure} to ignore
*
* @return true if there is a figure at this location, false otherwise.
*/
protected boolean isThereFigureAtLocation(IFigure parent, Point location, Set<IFigure> figuresToIgnore) {
ListIterator<IFigure> listIterator = parent.getChildren().listIterator();
while (listIterator.hasNext()) {
IFigure child = listIterator.next();
if (!figuresToIgnore.contains(child)) {
Rectangle cBounds = child.getBounds();
if (cBounds.contains(location)) {
return true;
}
}
}
return false;
}
@Override
protected void tearDown() throws Exception {
sessionAirdResource = null;
localSession = null;
editor = null;
diagramEditPartBot = null;
class1ChildOfDiagramBot = null;
class3ChildOfDiagramBot = null;
class4ChildOfDiagramBot = null;
// Reopen outline
new DesignerViews(bot).openOutlineView();
SWTBotUtils.waitAllUiEvents();
super.tearDown();
}
/**
* Check that a diagram element is aligned on the grid.
*
* @param location
* location of the diagram element element to check
* @param elementNameToDisplay
* The name of the element displayed in case of error
* @param gridSpacing
* The current grid spacing
*/
private void checkLocationAlignOnGrid(Point location, String elementNameToDisplay, int gridSpacing) {
boolean locationIsOK = (location.x % gridSpacing) == 0 || (location.y % gridSpacing) == 0;
if (!locationIsOK) {
fail("For " + elementNameToDisplay + ", the x or y coordinate of the top left corner should be on the grid (grid spacing = " + gridSpacing + "), but was: " + location + ".");
}
}
}