Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2778] Authorize empty string for direct edit #2781

Merged
merged 2 commits into from
Dec 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const nodeTypeRegistry: NodeTypeRegistry = {

- https://github.com/eclipse-sirius/sirius-web/issues/2812[#2812] [trees] Fix an issue that prevents icon to be displayed in treeNodes.
- https://github.com/eclipse-sirius/sirius-web/issues/2580[#2580] [diagram] Cancel direct edit on 'Esc'.
- https://github.com/eclipse-sirius/sirius-web/issues/2778[#2778] [diagram] Authorize empty string for direct edit.

=== New Features

Expand Down
73 changes: 0 additions & 73 deletions integration-tests/cypress/e2e/project/diagrams/graphical-dnd.cy.js

This file was deleted.

92 changes: 92 additions & 0 deletions integration-tests/cypress/e2e/project/diagrams/graphical-dnd.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*******************************************************************************
* Copyright (c) 2023 Obeo.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.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
*******************************************************************************/
import { Project } from '../../../pages/Project';
import { Studio } from '../../../usecases/Studio';
import { Explorer } from '../../../workbench/Explorer';
import { Details } from '../../../workbench/Details';
import { Diagram } from '../../../workbench/Diagram';

describe('Graphical-dnd', () => {
context('Given a studio template', () => {
let studioProjectId: string = '';
let domainName: string = '';

before(() =>
new Studio().createStudioProject().then((createdProjectData) => {
studioProjectId = createdProjectData.projectId;
new Project().visit(createdProjectData.projectId);
const explorer = new Explorer();
explorer.expand('DomainNewModel');
cy.get('[title="domain::Domain"]').then(($div) => {
domainName = $div.data().testid;
explorer.expand(`${domainName}`);
});
})
);

after(() => cy.deleteProject(studioProjectId));
context('When we create a new instance project', () => {
let instanceProjectId: string = '';

afterEach(() => cy.deleteProject(instanceProjectId));

it('Check graphical Drag and Drop', () => {
const explorer = new Explorer();
explorer.createObject('Entity2', 'Relation');
const details = new Details();
details.getCheckBox('Containment').check();
details.openReferenceWidgetOptions('Target Type');
details.selectReferenceWidgetOption('Entity1');

explorer.expand('ViewNewModel');
explorer.expand('View');
explorer.expand(`${domainName} Diagram Description`);
explorer.expand('Entity2 Node');
details.openReferenceWidgetOptions('Reused Child Node Descriptions');
details.selectReferenceWidgetOption('Entity1 Node');
explorer.createObject('NodePalette', 'Drop Node Tool');
explorer.select('Tool');
details.getTextField('Name').type('{selectAll}Drop Entity1 Tool{Enter}');
details.openReferenceWidgetOptions('Accepted Node Types');
details.selectReferenceWidgetOption('Entity1 Node');
explorer.createObject('Drop Entity1 Tool', 'Change Context');
details.getTextField('Expression').type('{selectAll}aql:targetElement{enter}');
explorer.createObject('aql:targetElement', 'Set Value');
details.getTextField('Feature Name').type('relation{Enter}');
details.getTextField('Value Expression').type('aql:droppedElement{Enter}');

const studio = new Studio();
studio.createProjectFromDomain('Cypress - Studio Instance', domainName, 'Root').then((res) => {
instanceProjectId = res.projectId;
new Explorer().createRepresentation('Root', `${domainName} Diagram Description`, 'diagram');
});

explorer.createObject('Root', 'Entity1s Entity1');
details.getTextField('Name').type('Entity1{Enter}');
explorer.createObject('Root', 'Entity2s Entity2');
details.getTextField('Name').type('Entity2{Enter}');

const diagram = new Diagram();
diagram.dragAndDropNode('Rectangle - Entity1', 'Rectangle - Entity2');
diagram.isNodeInside('Rectangle - Entity1', 'Rectangle - Entity2');

explorer.createObject('Root', 'Entity1s Entity1');
details.getTextField('Name').type('InvalidTarget{Enter}');

diagram.dragAndDropNode('Rectangle - Entity1', 'Rectangle - InvalidTarget');
// The target is invalid, the move is canceled
diagram.isNodeInside('Rectangle - Entity1', 'Rectangle - Entity2');
});
});
});
});
6 changes: 5 additions & 1 deletion integration-tests/cypress/pages/Projects.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*******************************************************************************
* Copyright (c) 2021, 2023 Obeo.
* This program and the accompanying materials
* are made available under the erms of the Eclipse Public License v2.0
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
Expand Down Expand Up @@ -33,4 +33,8 @@ export class Projects {
cy.getByTestId('delete').click();
cy.getByTestId('delete-project').click();
}

public goBackToTheHomepage(): void {
cy.get('[title="Back to the homepage"]').click();
}
}
16 changes: 15 additions & 1 deletion integration-tests/cypress/usecases/Studio.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*******************************************************************************
* Copyright (c) 2023 Obeo.
* This program and the accompanying materials
* are made available under the erms of the Eclipse Public License v2.0
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
Expand All @@ -16,8 +16,22 @@ import { isCreateProjectSuccessPayload } from '../support/server/createProjectCo
import { Explorer } from '../workbench/Explorer';
import { Workbench } from '../workbench/Workbench';
import { CreatedProjectData } from './Studio.types';
import { isCreateProjectFromTemplateSuccessPayload } from '../support/server/createProjectFromTemplateCommand';

export class Studio {
public createStudioProject(): Cypress.Chainable<CreatedProjectData> {
return cy.createProjectFromTemplate('studio-template').then((res) => {
const payload = res.body.data.createProjectFromTemplate;
if (isCreateProjectFromTemplateSuccessPayload(payload)) {
const projectId = payload.project.id;
const data: CreatedProjectData = { projectId };
return cy.wrap(data);
} else {
throw new Error(`The project studio has not been created`);
}
});
}

public createProjectFromDomain(name: string, domain: string, entity: string): Cypress.Chainable<CreatedProjectData> {
return cy.createProject(name).then((res) => {
const payload = res.body.data.createProject;
Expand Down
14 changes: 13 additions & 1 deletion integration-tests/cypress/workbench/Details.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*******************************************************************************
* Copyright (c) 2023 Obeo.
* This program and the accompanying materials
* are made available under the erms of the Eclipse Public License v2.0
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
Expand All @@ -19,4 +19,16 @@ export class Details {
public getTextField(label: string): Cypress.Chainable<JQuery<HTMLInputElement | HTMLTextAreaElement>> {
return this.getDetailsView().find(`[data-testid="input-${label}"]`);
}

public getCheckBox(label: string): Cypress.Chainable<JQuery<HTMLInputElement>> {
return this.getDetailsView().findByTestId(label).find('input');
}

public openReferenceWidgetOptions(label: string): void {
this.getDetailsView().findByTestId(label).find('button[title="Open"]').click();
}

public selectReferenceWidgetOption(option: string): void {
cy.getByTestId(`option-${option}`).should('exist').click();
}
}
50 changes: 49 additions & 1 deletion integration-tests/cypress/workbench/Diagram.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*******************************************************************************
* Copyright (c) 2023 Obeo.
* This program and the accompanying materials
* are made available under the erms of the Eclipse Public License v2.0
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
Expand All @@ -27,4 +27,52 @@ export class Diagram {
public getPalette(): Cypress.Chainable<JQuery<HTMLElement>> {
return cy.getByTestId('Palette');
}

public dragAndDropNode(sourceNodeTestId: string, targetNodeTestId: string): void {
cy.window().then((win) => {
cy.getByTestId('rf__wrapper')
.findByTestId(targetNodeTestId)
.then((node) => {
const target = node[0];
if (target) {
const { x, y } = target.getBoundingClientRect();
cy.getByTestId('rf__wrapper').findByTestId(sourceNodeTestId).trigger('mousedown', {
button: 0,
force: true,
view: win,
});
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(400); // the time needed to calculate compatible nodes
cy.getByTestId('rf__wrapper').findByTestId(sourceNodeTestId).trigger('mousemove', {
clientX: x,
clientY: y,
force: true,
view: win,
});
cy.getByTestId('rf__wrapper').findByTestId(sourceNodeTestId).trigger('mouseup', { view: win });
// eslint-disable-next-line cypress/no-unnecessary-waiting
cy.wait(500); // the time needed to process the drop action
}
});
});
}

public isNodeInside(childNodeTestId: string, parentNodeTestId: string): void {
cy.window().then(() => {
cy.getByTestId(parentNodeTestId).then(($parentNode) => {
cy.getByTestId(childNodeTestId).then(($childNode) => {
const parentPosition = $parentNode[0]?.getBoundingClientRect();
const childPosition = $childNode[0]?.getBoundingClientRect();
if (parentPosition && childPosition) {
expect(childPosition.top >= parentPosition.top).to.be.true;
expect(childPosition.bottom <= parentPosition.bottom).to.be.true;
expect(childPosition.left >= parentPosition.left).to.be.true;
expect(childPosition.right <= parentPosition.right).to.be.true;
} else {
expect(false, 'Nodes to be tested do not exist');
}
});
});
});
}
}
5 changes: 5 additions & 0 deletions integration-tests/cypress/workbench/Explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ export class Explorer {
cy.getByTestId('create-object').click();
}

public select(treeItemLabel: string): void {
this.getTreeItemByLabel(treeItemLabel).should('exist');
this.getTreeItemByLabel(treeItemLabel).click();
}

public createRepresentation(
treeItemLabel: string,
representationDescriptionName: string,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,20 +141,17 @@ export const DiagramDirectEditInput = ({ labelId, editingKey, onClose, transform
}, [initialLabelItemError, initialLabelItemData]);

const doRename = () => {
const isNameValid = state.newLabel.length >= 1;
if (isNameValid) {
renameElement({
variables: {
input: {
id: crypto.randomUUID(),
editingContextId: editingContextId,
representationId: diagramId,
labelId: labelId,
newText: state.newLabel,
},
renameElement({
variables: {
input: {
id: crypto.randomUUID(),
editingContextId: editingContextId,
representationId: diagramId,
labelId: labelId,
newText: state.newLabel,
},
});
}
},
});
};

const handleChange = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,22 +123,17 @@ export const TreeItemDirectEditInput = ({
}, [renameTreeItemData, renameTreeItemError]);

const doRename = () => {
const isNameValid = state.newLabel.length >= 1;
if (isNameValid) {
renameTreeItem({
variables: {
input: {
id: crypto.randomUUID(),
editingContextId: editingContextId,
representationId: treeId,
treeItemId: treeItemId,
newLabel: state.newLabel,
},
renameTreeItem({
variables: {
input: {
id: crypto.randomUUID(),
editingContextId: editingContextId,
representationId: treeId,
treeItemId: treeItemId,
newLabel: state.newLabel,
},
});
} else {
onClose();
}
},
});
};

const handleChange = (event) => {
Expand Down