Added test-id to relationship and checkpoint components and also added editor tests

This commit is contained in:
Ezequiel-Vega 2022-01-25 17:57:29 -03:00
parent ddfd34d6ca
commit 7e5c16e9e1
14 changed files with 339 additions and 93 deletions

View File

@ -0,0 +1,5 @@
{
"name": "Using fixtures to represent data",
"email": "hello@cypress.io",
"body": "Fixtures are a great way to mock data for responses to routes"
}

View File

@ -0,0 +1,16 @@
context('Relationship Topics', () => {
beforeEach(() => {
cy.visit('/editor.html');
cy.reload();
cy.get('[test-id="30-11-relationship"]').click({ force: true });
});
it('Change shape relationship', () => {
cy.get('[test-id="control-56"]').trigger('mousedown', { force: true });
cy.get('body').trigger('mousemove', { clientX: 500, clientY: 200 });
cy.get('body').trigger('mouseup');
cy.matchImageSnapshot('changeShapeRealtionship');
cy.get('[test-id="control-56"]').invoke('attr', 'cy').should('eq', '-131.75');
});
});

View File

@ -0,0 +1,74 @@
context('Edit Topic', () => {
beforeEach(() => {
cy.visit('/editor.html');
cy.reload();
cy.get('[test-id=1]').click();
});
it('Change Main Topic Text', () => {
cy.get('body').type('New Title Main Topic{enter}');
cy.get('[test-id=1] > text > tspan').should('have.text', 'New Title Main Topic');
cy.matchImageSnapshot('changeMainTopicText');
});
it('Change Font Size', () => {
cy.get('#fontSizeTip').click();
cy.get('#small').click();
cy.get('[test-id=1] > text').invoke('attr', 'font-size').should('eq', '8.0625');
cy.matchImageSnapshot('changeFontSizeSmall');
cy.get('#fontSizeTip').click();
// TODO: The parameter {force: true} was placed because it does not detect that the element is visible
cy.get('.popover #normal').click({ force: true });
cy.get('[test-id=1] > text').invoke('attr', 'font-size').should('eq', '10.75');
cy.matchImageSnapshot('changeFontSizeNormal');
cy.get('#fontSizeTip').click();
// TODO: The parameter {force: true} was placed because it does not detect that the element is visible
cy.get('#large').click({ force: true });
cy.get('[test-id=1] > text').invoke('attr', 'font-size').should('eq', '13.4375');
cy.matchImageSnapshot('changeFontSizeNormal');
cy.get('#fontSizeTip').click();
// TODO: The parameter {force: true} was placed because it does not detect that the element is visible
cy.get('#huge').click({ force: true });
cy.get('[test-id=1] > text').invoke('attr', 'font-size').should('eq', '20.15625');
cy.matchImageSnapshot('changeFontSizeHuge');
});
it('Change Font type', () => {
cy.get('#fontFamilyTip').click();
// TODO: The parameter {force: true} was placed because it does not detect that the element is visible
cy.get('[model="Times"]').click({ force: true });
cy.get('[test-id=1] > text').invoke('attr', 'font-family').should('eq', 'Times');
cy.matchImageSnapshot('changeFontType');
});
it('Change Font Italic', () => {
cy.get('#fontItalicTip').click();
cy.get('[test-id=1] > text').invoke('attr', 'font-style').should('eq', 'italic');
cy.matchImageSnapshot('changeFontItalic');
});
it('Change Font color', () => {
cy.get('#fontColorTip').click();
// TODO: The parameter {force: true} was placed because it does not detect that the element is visible
cy.get('[title="RGB (153, 0, 255)"]').click({ force: true });
cy.get('[test-id=1] > text').invoke('attr', 'fill').should('eq', 'rgb(153, 0, 255)');
cy.matchImageSnapshot('changeFontColor');
});
});

View File

@ -0,0 +1,51 @@
context('Node manager', () => {
before(() => {
cy.visit('/editor.html');
});
it('shortcut add sibling node', () => {
// TODO: why is the editor appearing twice in the snapshot?
// cy.matchImageSnapshot('editor');
cy.contains('Mind Mapping').click();
cy.get('body').type('{enter}').type('Mind Mapping rocks!!').type('{enter}');
cy.get('[test-id=36] > text > tspan').should('exist');
cy.matchImageSnapshot('editor-shortcut-edit');
});
it('shortcut add child node', () => {
cy.contains('Mind Mapping rocks!!').click();
cy.get('body').type('{insert}').type('Child 1 mind Mapping rocks!!').type('{enter}');
cy.get('body').type('{enter}').type('Child 2 mind Mapping rocks!!').type('{enter}');
cy.get('[test-id=36] > text > tspan').should('exist');
cy.get('[test-id=37] > text > tspan').should('exist');
cy.matchImageSnapshot('addChildNodeSortcut');
});
it('Delete topic', () => {
cy.get('[test-id=37]').click();
cy.get('body').type('{del}');
cy.get('[test-id=37]').should('not.exist');
cy.matchImageSnapshot('deleteTopicShortcut');
});
it('undo changes', () => {
cy.get('#undoEditionTip').click();
cy.get('[test-id=36] > text > tspan').should('exist');
cy.matchImageSnapshot('undoChange');
});
it('Save changes', () => {
cy.contains('Mind Mapping rocks!!').click();
cy.get('body').type('{ctrl}s');
cy.matchImageSnapshot('saveChagesShortcut');
});
});

View File

@ -0,0 +1,35 @@
context('Change topic position', () => {
beforeEach(() => {
cy.visit('/editor.html');
cy.reload();
});
it('Move up node "Mind Mapping"', () => {
const position = { clientX: 270, clientY: 160 };
cy.contains('Mind Mapping').trigger('mousedown');
cy.get('body').trigger('mousemove', position);
cy.get('body').trigger('mouseup');
cy.matchImageSnapshot('moveupNode');
});
it('Move down node "Mind Mapping"', () => {
cy.contains('Mind Mapping').trigger('mousedown');
cy.get('body').trigger('mousemove', { clientX: 350, clientY: 380 });
cy.get('body').trigger('mouseup');
cy.matchImageSnapshot('movedownNode');
});
it('Move default position node "Mind Mapping"', () => {
cy.contains('Mind Mapping').trigger('mousedown');
cy.get('body').trigger('mousemove', { clientX: 270, clientY: 240 });
cy.get('body').trigger('mouseup');
cy.matchImageSnapshot('moveDefaultPosition');
});
it('Move left node "Mind Mapping"', () => {
cy.contains('Mind Mapping').trigger('mousedown');
cy.get('body').trigger('mousemove', { clientX: 700, clientY: 240 });
cy.get('body').trigger('mouseup');
cy.matchImageSnapshot('moveleftNode');
});
});

View File

@ -0,0 +1,50 @@
context('Change Topic shape', () => {
beforeEach(() => {
cy.visit('/editor.html');
cy.reload();
cy.contains('Try it Now!').click();
});
it('change to square shape', () => {
cy.get('#topicShapeTip').click();
cy.get('#rectagle').click();
cy.get('[test-id=11] > rect').each((element, index, $list) => {
cy.get($list[1]).invoke('attr', 'rx').should('eq', '0');
});
cy.matchImageSnapshot('changeToSquareShape');
});
it('change to rounded rectagle', () => {
cy.get('#topicShapeTip').click();
// TODO: The parameter {force: true} was placed because it does not detect that the element is visible
cy.get('#rounded_rectagle').click({ force: true });
cy.get('[test-id=11] > rect').each((element, index, $list) => {
cy.get($list[1]).invoke('attr', 'rx').should('eq', '4.6499999999999995');
});
cy.matchImageSnapshot('changeToRoundedRectagle');
});
it('change to line', () => {
cy.get('#topicShapeTip').click();
// TODO: The parameter {force: true} was placed because it does not detect that the element is visible
cy.get('#line').click({ force: true });
cy.matchImageSnapshot('changeToLine');
});
it('change to elipse shape', () => {
cy.get('#topicShapeTip').click();
// TODO: The parameter {force: true} was placed because it does not detect that the element is visible
cy.get('#elipse').click({ force: true });
cy.get('[test-id=11] > rect').each((element, index, $list) => {
cy.get($list[1]).invoke('attr', 'rx').should('eq', '13.950000000000001');
});
cy.matchImageSnapshot('changeToElipseShape');
});
});

View File

@ -23,25 +23,25 @@ import ActionDispatcher from './ActionDispatcher';
class ControlPoint { class ControlPoint {
constructor() { constructor() {
const control1 = new Elipse({ this.control1 = new Elipse({
width: 6, width: 6,
height: 6, height: 6,
stroke: '1 solid #6589de', stroke: '1 solid #6589de',
fillColor: 'gray', fillColor: 'gray',
visibility: false, visibility: false,
}); });
control1.setCursor('pointer'); this.control1.setCursor('pointer');
const control2 = new Elipse({ this.control2 = new Elipse({
width: 6, width: 6,
height: 6, height: 6,
stroke: '1 solid #6589de', stroke: '1 solid #6589de',
fillColor: 'gray', fillColor: 'gray',
visibility: false, visibility: false,
}); });
control2.setCursor('pointer'); this.control2.setCursor('pointer');
this._controlPointsController = [control1, control2]; this._controlPointsController = [this.control1, this.control2];
this._controlLines = [ this._controlLines = [
new Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 }), new Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 }),
new Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 }), new Line({ strokeColor: '#6589de', strokeWidth: 1, opacity: 0.3 }),
@ -84,6 +84,11 @@ class ControlPoint {
this._endPoint[1] = { ...this._line.getLine().getTo() }; this._endPoint[1] = { ...this._line.getLine().getTo() };
} }
setControlPointTestId(ctrlPoint1, ctrlPoint2) {
this.control1.setTestId(ctrlPoint1);
this.control2.setTestId(ctrlPoint2);
}
redraw() { redraw() {
if ($defined(this._line)) this._createControlPoint(); if ($defined(this._line)) this._createControlPoint();
} }

View File

@ -56,6 +56,7 @@ class Relationship extends ConnectionLine {
this._line2d.setCursor('pointer'); this._line2d.setCursor('pointer');
this._line2d.setStroke(1, 'solid', strokeColor); this._line2d.setStroke(1, 'solid', strokeColor);
this._line2d.setDashed(4, 2); this._line2d.setDashed(4, 2);
this._line2d.setTestId(`${model.getFromNode()}-${model.getToNode()}-relationship`);
this._focusShape = this._createLine(this.getLineType(), ConnectionLine.SIMPLE_CURVED); this._focusShape = this._createLine(this.getLineType(), ConnectionLine.SIMPLE_CURVED);
this._focusShape.setStroke(2, 'solid', '#3f96ff'); this._focusShape.setStroke(2, 'solid', '#3f96ff');
@ -83,6 +84,12 @@ class Relationship extends ConnectionLine {
if ($defined(model.getSrcCtrlPoint())) { if ($defined(model.getSrcCtrlPoint())) {
const srcPoint = { ...model.getSrcCtrlPoint() }; const srcPoint = { ...model.getSrcCtrlPoint() };
this.setSrcControlPoint(srcPoint); this.setSrcControlPoint(srcPoint);
// Set test id in control point
this._controlPointsController.setControlPointTestId(
`control-${Math.abs(srcPoint.x)}`,
`control-${Math.abs(srcPoint.y)}`,
);
} }
if ($defined(model.getDestCtrlPoint())) { if ($defined(model.getDestCtrlPoint())) {
const destPoint = { ...model.getDestCtrlPoint() }; const destPoint = { ...model.getDestCtrlPoint() };

View File

@ -103,9 +103,9 @@ class RelationshipPivot {
const model = this._designer.getModel(); const model = this._designer.getModel();
const topics = model.getTopics(); const topics = model.getTopics();
topics.forEach(((topic) => { topics.forEach((topic) => {
topic.removeEvent('ontfocus', this._onTopicClick); topic.removeEvent('ontfocus', this._onTopicClick);
})); });
workspace.removeChild(this._pivot); workspace.removeChild(this._pivot);
workspace.removeChild(this._startArrow); workspace.removeChild(this._startArrow);
@ -166,9 +166,7 @@ class RelationshipPivot {
// Avoid circular connections ... // Avoid circular connections ...
if (targetTopic.getId() !== sourceTopic.getId()) { if (targetTopic.getId() !== sourceTopic.getId()) {
const relModel = mindmap.createRelationship(targetTopic.getId(), sourceTopic.getId()); const relModel = mindmap.createRelationship(targetTopic.getId(), sourceTopic.getId());
this._designer this._designer.getActionDispatcher().addRelationship(relModel);
.getActionDispatcher()
.addRelationship(relModel);
} }
this.dispose(); this.dispose();
} }

View File

@ -16,16 +16,9 @@
* limitations under the License. * limitations under the License.
*/ */
import $ from 'jquery'; import $ from 'jquery';
import { $assert, $defined } from '@wisemapping/core-js';
import { import {
$assert, Rect, Image, Line, Text, Group,
$defined,
} from '@wisemapping/core-js';
import {
Rect,
Image,
Line,
Text,
Group,
} from '@wisemapping/web2d'; } from '@wisemapping/web2d';
import NodeGraph from './NodeGraph'; import NodeGraph from './NodeGraph';
@ -41,12 +34,8 @@ import NoteEditor from './widget/NoteEditor';
import ActionDispatcher from './ActionDispatcher'; import ActionDispatcher from './ActionDispatcher';
import LinkEditor from './widget/LinkEditor'; import LinkEditor from './widget/LinkEditor';
import TopicEventDispatcher, { import TopicEventDispatcher, { TopicEvent } from './TopicEventDispatcher';
TopicEvent, import { TopicShape } from './model/INodeModel';
} from './TopicEventDispatcher';
import {
TopicShape,
} from './model/INodeModel';
const ICON_SCALING_FACTOR = 1.3; const ICON_SCALING_FACTOR = 1.3;
@ -648,6 +637,9 @@ class Topic extends NodeGraph {
// Register listeners ... // Register listeners ...
this._registerDefaultListenersToElement(group, this); this._registerDefaultListenersToElement(group, this);
// Set test id
group.setTestId(model.getId());
} }
_registerDefaultListenersToElement(elem, topic) { _registerDefaultListenersToElement(elem, topic) {
@ -890,8 +882,9 @@ class Topic extends NodeGraph {
getIncomingLines() { getIncomingLines() {
const children = this.getChildren(); const children = this.getChildren();
return children.filter((node) => $defined(node.getOutgoingLine())) return children
.map(((node) => node.getOutgoingLine())); .filter((node) => $defined(node.getOutgoingLine()))
.map((node) => node.getOutgoingLine());
} }
/** */ /** */
@ -1055,8 +1048,7 @@ class Topic extends NodeGraph {
}; };
const oldSize = this.getSize(); const oldSize = this.getSize();
const hasSizeChanged = oldSize.width !== roundedSize.width const hasSizeChanged = oldSize.width !== roundedSize.width || oldSize.height !== roundedSize.height;
|| oldSize.height !== roundedSize.height;
if (hasSizeChanged || force) { if (hasSizeChanged || force) {
NodeGraph.prototype.setSize.call(this, roundedSize); NodeGraph.prototype.setSize.call(this, roundedSize);

View File

@ -83,7 +83,9 @@ class XMLSerializerPela implements XMLMindmapSerializer {
parentTopic.setAttribute('position', `${pos.x},${pos.y}`); parentTopic.setAttribute('position', `${pos.x},${pos.y}`);
const order = topic.getOrder(); const order = topic.getOrder();
if (typeof order === 'number' && Number.isFinite(order)) { parentTopic.setAttribute('order', order.toString()); } if (typeof order === 'number' && Number.isFinite(order)) {
parentTopic.setAttribute('order', order.toString());
}
} }
const text = topic.getText(); const text = topic.getText();
@ -99,8 +101,7 @@ class XMLSerializerPela implements XMLMindmapSerializer {
const size = topic.getImageSize(); const size = topic.getImageSize();
parentTopic.setAttribute( parentTopic.setAttribute(
'image', 'image',
`${size.width},${size.height `${size.width},${size.height}:${topic.getImageUrl()}`,
}:${topic.getImageUrl()}`,
); );
} }
} }
@ -253,7 +254,9 @@ class XMLSerializerPela implements XMLMindmapSerializer {
// Add all the topics nodes ... // Add all the topics nodes ...
const childNodes = Array.from(rootElem.childNodes); const childNodes = Array.from(rootElem.childNodes);
const topicsNodes = childNodes const topicsNodes = childNodes
.filter((child: ChildNode) => (child.nodeType === 1 && (child as Element).tagName === 'topic')) .filter(
(child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'topic',
)
.map((c) => c as Element); .map((c) => c as Element);
topicsNodes.forEach((child) => { topicsNodes.forEach((child) => {
const topic = this._deserializeNode(child, mindmap); const topic = this._deserializeNode(child, mindmap);
@ -262,7 +265,9 @@ class XMLSerializerPela implements XMLMindmapSerializer {
// Then all relationshops, they are connected to topics ... // Then all relationshops, they are connected to topics ...
const relationshipsNodes = childNodes const relationshipsNodes = childNodes
.filter((child: ChildNode) => (child.nodeType === 1 && (child as Element).tagName === 'relationship')) .filter(
(child: ChildNode) => child.nodeType === 1 && (child as Element).tagName === 'relationship',
)
.map((c) => c as Element); .map((c) => c as Element);
relationshipsNodes.forEach((child) => { relationshipsNodes.forEach((child) => {
try { try {
@ -280,9 +285,7 @@ class XMLSerializerPela implements XMLMindmapSerializer {
} }
_deserializeNode(domElem: Element, mindmap: Mindmap) { _deserializeNode(domElem: Element, mindmap: Mindmap) {
const type = domElem.getAttribute('central') != null const type = domElem.getAttribute('central') != null ? 'CentralTopic' : 'MainTopic';
? 'CentralTopic'
: 'MainTopic';
// Load attributes... // Load attributes...
let id: number | null = null; let id: number | null = null;

View File

@ -288,6 +288,10 @@ class ElementClass {
getParent() { getParent() {
return this.peer.getParent(); return this.peer.getParent();
} }
setTestId(testId) {
this.peer._native.setAttribute('test-id', testId);
}
} }
Element._SIGNATURE_MULTIPLE_ARGUMENTS = -1; Element._SIGNATURE_MULTIPLE_ARGUMENTS = -1;

View File

@ -144,6 +144,12 @@ class Group extends ElementClass {
setOpacity(value) { setOpacity(value) {
this.peer.setOpacity(value); this.peer.setOpacity(value);
} }
/*
setTestId(testId) {
this.peer._native.setAttribute('test-id', testId);
}
*/
} }
export default Group; export default Group;