describe('Basic Flow Rendering', () => { before(() => { cy.visit('/basic'); }); it('renders a flow with three nodes', () => { cy.get('.react-flow__renderer'); cy.get('.react-flow-basic-example'); // check if className prop works cy.get('.react-flow__node').should('have.length', 4); cy.get('.react-flow__edge').should('have.length', 2); cy.get('.react-flow__node').children('.react-flow__handle'); }); it('renders a grid', () => { cy.get('.react-flow__background'); }); it('selects a node by click', () => { cy.get('.react-flow__node:first').click().should('have.class', 'selected'); }); it('deselects node', () => { cy.get('.react-flow__renderer').click('bottomRight'); cy.get('.react-flow__node:first').should('not.have.class', 'selected'); }); it('selects an edge by click', () => { cy.get('.react-flow__edge:first').click({ force: true }).should('have.class', 'selected'); }); it('deselects edge', () => { cy.get('.react-flow__renderer').click('bottomRight'); cy.get('.react-flow__edge:first').should('not.have.class', 'selected'); }); it('selects one node with a selection', () => { cy.get('body') .type('{shift}', { release: false }) .get('.react-flow__selectionpane') .trigger('mousedown', 'topLeft', { which: 1, force: true }) .trigger('mousemove', 800, 75, { which: 1 }) .trigger('mouseup', 'bottomRight', { force: true }) .get('.react-flow__node') .first() .should('have.class', 'selected') .get('.react-flow__node') .last() .should('have.not.class', 'selected') .get('.react-flow__nodesselection-rect'); cy.get('body').type('{shift}', { release: true }); }); it('selects all nodes', () => { cy.get('body') .type('{shift}', { release: false }) .get('.react-flow__selectionpane') .trigger('mousedown', 'topLeft', { which: 1, force: true }) .trigger('mousemove', 'bottomRight', { which: 1 }) .trigger('mouseup', 'bottomRight', { force: true }) .get('.react-flow__node') .should('have.class', 'selected') .get('.react-flow__nodesselection-rect'); cy.get('body').type('{shift}', { release: true }); }); it('removes selection', () => { cy.get('.react-flow__renderer').click('bottomRight'); cy.get('.react-flow__nodesselection-rect').should('not.exist'); }); it('selects an edge', () => { cy.get('.react-flow__edge:first').click({ force: true }).should('have.class', 'selected'); }); it('drags a node', () => { const styleBeforeDrag = Cypress.$('.react-flow__node:first').css('transform'); cy.drag('.react-flow__node:first', { x: 500, y: 25 }).then(($el) => { const styleAfterDrag = $el.css('transform'); expect(styleBeforeDrag).to.not.equal(styleAfterDrag); }); }); it('removes a node', () => { cy.get('.react-flow__node').contains('Node 2').click(); cy.get('body').type('{backspace}'); cy.get('.react-flow__node').should('have.length', 3); cy.get('.react-flow__edge').should('have.length', 1); }); it('connects nodes', () => { cy.get('.react-flow__node') .contains('Node 3') .find('.react-flow__handle.source') .trigger('mousedown', { which: 1 }); cy.get('.react-flow__node') .contains('Node 4') .find('.react-flow__handle.target') .trigger('mousemove') .trigger('mouseup', { force: true }); cy.get('.react-flow__edge').should('have.length', 2); }); it('removes an edge', () => { cy.get('.react-flow__edge:first').click(); cy.get('body').type('{backspace}'); cy.get('.react-flow__edge').should('have.length', 1); }); it('drags the pane', () => { const styleBeforeDrag = Cypress.$('.react-flow__nodes').css('transform'); // for d3 we have to pass the window to the event // https://github.com/cypress-io/cypress/issues/3441 cy.window().then((win) => { cy.get('.react-flow__renderer') .trigger('mousedown', 'topLeft', { which: 1, view: win }) .trigger('mousemove', 'bottomLeft') .trigger('mouseup', { force: true, view: win }) .then(() => { const styleAfterDrag = Cypress.$('.react-flow__nodes').css('transform'); expect(styleBeforeDrag).to.not.equal(styleAfterDrag); }); }); }); it('zooms the pane', () => { const styleBeforeZoom = Cypress.$('.react-flow__nodes').css('transform'); cy.get('.react-flow__renderer') .trigger('wheel', 'topLeft', { deltaY: -200 }) .then(() => { const styleAfterZoom = Cypress.$('.react-flow__nodes').css('transform'); expect(styleBeforeZoom).to.not.equal(styleAfterZoom); }); }); });