Skip to content

Commit

Permalink
Feature/provide svg for nodes (#60)
Browse files Browse the repository at this point in the history
* Add svg config to graph node level

* Add Node logic to decide on type of node to render

* Implement svg prop at node level

* Add jest.config.js

* Update unit tests

* Move cypress/common/page-objects into cypress/page-objects

* Add sample.svg

* Add functional tests for svg node prop

* Add unit test for svg at config level

* Update README. Fix sandbox favicon

* Add sample GIF with custom svg feature
  • Loading branch information
danielcaldas authored Apr 1, 2018
1 parent a4ca82e commit 7cb98c7
Show file tree
Hide file tree
Showing 15 changed files with 227 additions and 105 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# react-d3-graph · [![Build Status](https://travis-ci.org/danielcaldas/react-d3-graph.svg?branch=master&style=flat-square)](https://travis-ci.org/danielcaldas/react-d3-graph)

[![npm version](https://img.shields.io/badge/npm-v1.0.1-blue.svg?longCache=true&style=flat-square)](https://www.npmjs.com/package/react-d3-graph) [![npm stats](https://img.shields.io/badge/downloads-2k-brightgreen.svg?longCache=true&style=flat-square)](https://npm-stat.com/charts.html?package=react-d3-graph&from=2017-04-25&to=2018-02-11) [![probot enabled](https://img.shields.io/badge/probot:stale-enabled-yellow.svg?longCache=true&style=flat-square)](https://probot.github.io/) [![trello](https://img.shields.io/badge/trello-board-blue.svg?longCache=true&style=flat-square)](https://trello.com/b/KrnmFXha/react-d3-graph)
[![npm version](https://img.shields.io/badge/npm-v1.0.1-blue.svg?longCache=true&style=flat-square)](https://www.npmjs.com/package/react-d3-graph) [![npm stats](https://img.shields.io/badge/downloads-3k-brightgreen.svg?longCache=true&style=flat-square)](https://npm-stat.com/charts.html?package=react-d3-graph&from=2017-04-25) [![probot enabled](https://img.shields.io/badge/probot:stale-enabled-yellow.svg?longCache=true&style=flat-square)](https://probot.github.io/) [![trello](https://img.shields.io/badge/trello-board-blue.svg?longCache=true&style=flat-square)](https://trello.com/b/KrnmFXha/react-d3-graph)
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)

:book: [1.0.1](https://danielcaldas.github.io/react-d3-graph/docs/index.html) | [1.0.0](https://danielcaldas.github.io/react-d3-graph/docs/1.0.0.html) | [0.4.0](https://danielcaldas.github.io/react-d3-graph/docs/0.4.0.html) | [0.3.0](https://danielcaldas.github.io/react-d3-graph/docs/0.3.0.html)
:book: [1.0.1](https://danielcaldas.github.io/react-d3-graph/docs/index.html)

### _Interactive and configurable graphs with react and d3 effortlessly_

Expand Down
32 changes: 0 additions & 32 deletions cypress/common/page-objects/sandbox.po.js

This file was deleted.

40 changes: 22 additions & 18 deletions cypress/integration/graph.e2e.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*global cy*/
const SANDBOX_URL = Cypress.env('SANDBOX_URL');

const NodePO = require('../common/page-objects/node.po');
const SandboxPO = require('../common/page-objects/sandbox.po');
let nodes = require('./../../sandbox/data').nodes.map(({id}) => id);
const NodePO = require('../page-objects/node.po');
const SandboxPO = require('../page-objects/sandbox.po');
let nodes = require('./../../sandbox/data').nodes.map(({ id }) => id);

describe('[rd3g-graph] graph tests', function () {
before(function () {
describe('[rd3g-graph] graph tests', function() {
before(function() {
this.sandboxPO = new SandboxPO();
// visit sandbox
cy.visit(SANDBOX_URL);
Expand All @@ -16,30 +16,32 @@ describe('[rd3g-graph] graph tests', function () {
this.sandboxPO.pauseGraph();
});

describe('when data is changed', function () {
describe('and we change nodes props', function () {
beforeEach(function () {
describe('when data is changed', function() {
describe('and we change nodes props', function() {
beforeEach(function() {
// expand nodes
this.sandboxPO.clickJsonTreeNodes();
// expand 1st node
this.sandboxPO.clickJsonTreeFirstNode();
});

afterEach(function () {
afterEach(function() {
this.sandboxPO.clickJsonTreeNodes();
});

it('nodes props modifications should be reflected in the graph', function () {
it('nodes props modifications should be reflected in the graph', function() {
// click (+) add prop to 1st node
this.sandboxPO.addJsonTreeFirstNodeProp();

// prop name be color
cy.get('[placeholder="Key"]')
cy
.get('[placeholder="Key"]')
.clear()
.type('color');

// prop value be red and press ENTER
cy.get('[placeholder="Value"]')
cy
.get('[placeholder="Value"]')
.clear()
.type('red{enter}');

Expand All @@ -53,13 +55,13 @@ describe('[rd3g-graph] graph tests', function () {
nodePO.getColor().should('eq', '#d3d3d3');
});

describe('and staticGraph is toggled on', function () {
beforeEach(function () {
describe('and staticGraph is toggled on', function() {
beforeEach(function() {
cy.contains('staticGraph').scrollIntoView();
this.sandboxPO.getFieldInput('staticGraph').click();
});

it('nodes props modifications should be reflected in the graph', function () {
it('nodes props modifications should be reflected in the graph', function() {
cy.get('text').should('have.length', 14);

this.sandboxPO.addNode();
Expand All @@ -72,11 +74,13 @@ describe('[rd3g-graph] graph tests', function () {
// click (+) add prop to 1st node
this.sandboxPO.addJsonTreeFirstNodeProp();
// prop name be color
cy.get('[placeholder="Key"]')
cy
.get('[placeholder="Key"]')
.clear()
.type('color');
// prop value be red and press ENTER
cy.get('[placeholder="Value"]')
cy
.get('[placeholder="Value"]')
.clear()
.type('red{enter}');

Expand All @@ -102,4 +106,4 @@ describe('[rd3g-graph] graph tests', function () {
});
});
});
});
});
78 changes: 59 additions & 19 deletions cypress/integration/node.e2e.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/*global cy*/
const SANDBOX_URL = Cypress.env('SANDBOX_URL');

const NodePO = require('../common/page-objects/node.po');
const SandboxPO = require('../common/page-objects/sandbox.po');
let nodes = require('./../../sandbox/data').nodes.map(({id}) => id);
const NodePO = require('../page-objects/node.po');
const SandboxPO = require('../page-objects/sandbox.po');
let nodes = require('./../../sandbox/data').nodes.map(({ id }) => id);

describe('[rd3g-node] node tests', function () {
before(function () {
describe('[rd3g-node] node tests', function() {
before(function() {
this.sandboxPO = new SandboxPO();
// visit sandbox
cy.visit(SANDBOX_URL);
Expand All @@ -22,18 +22,19 @@ describe('[rd3g-node] node tests', function () {
// });
});

describe('when setting specific node color', function () {
beforeEach(function () {
describe('when setting specific node color', function() {
beforeEach(function() {
// scroll down to node.color config
cy.contains('node.color').scrollIntoView();
// input text 'green'
this.sandboxPO.getFieldInput('node.color')
this.sandboxPO
.getFieldInput('node.color')
.clear()
.type('green');
});

it('all nodes should have the selected color', function () {
nodes.forEach(function (n) {
it('all nodes should have the selected color', function() {
nodes.forEach(function(n) {
const nodePO = new NodePO(n);

// below alternative using async/await
Expand All @@ -43,38 +44,77 @@ describe('[rd3g-node] node tests', function () {
});
});

describe('when setting specific node label fontSize', function () {
beforeEach(function () {
describe('when setting specific node label fontSize', function() {
beforeEach(function() {
// scroll down to node.fontSize config
cy.contains('node.fontSize').scrollIntoView();
// input text '14'
this.sandboxPO.getFieldInput('node.fontSize')
this.sandboxPO
.getFieldInput('node.fontSize')
.clear()
.type('14');
});

it('all nodes labels should have the selected fontSize', function () {
nodes.forEach(function (n) {
it('all nodes labels should have the selected fontSize', function() {
nodes.forEach(function(n) {
const nodePO = new NodePO(n);

nodePO.getFontSize().should('eq', '14');
});
});
});

describe('when toggling off render label', function () {
beforeEach(function () {
describe('when toggling off render label', function() {
beforeEach(function() {
// scroll down to node.renderLabel config & click
cy.contains('node.renderLabel').scrollIntoView();
this.sandboxPO.getFieldInput('node.renderLabel').click();
});

it('all node labels should disappear', function () {
it('all node labels should disappear', function() {
nodes.forEach(n => {
const nodePO = new NodePO(n);

nodePO.getLabel().should('not.be.visible');
});
});
});
});

describe('when rendering custom svg as node', function() {
describe('and svg is provided to specific node at node level', function() {
beforeEach(function() {
// expand nodes
this.sandboxPO.clickJsonTreeNodes();
// expand 1st node
this.sandboxPO.clickJsonTreeFirstNode();
// click (+) add prop to 1st node
this.sandboxPO.addJsonTreeFirstNodeProp();

// prop name be svg
cy
.get('[placeholder="Key"]')
.clear()
.type('svg');

// prop value be './sample.svg' and press ENTER
cy
.get('[placeholder="Value"]')
.clear()
.type('./sample.svg{enter}');
});

afterEach(function() {
this.sandboxPO.deleteJsonTreeFirstNodeProp();
this.sandboxPO.clickJsonTreeNodes();
});

it('target node should be rendered with provided svg', function() {
const nodePO = new NodePO(nodes[0]);

nodePO.getImageHref().should('eq', './sample.svg');
nodePO.getImageWidth().should('eq', '20');
nodePO.getImageHeight().should('eq', '20');
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,20 @@
* @param {string} id the id of the node.
* @returns {undefined}
*/
function NodePO (id) {
function NodePO(id) {
this.id = id;
this.path = `#${this.id} > path`;
this.text = `#${this.id} > text`;
this.image = `#${this.id} > image`;

this.getPath = () => cy.get(this.path);
this.getLabel = () => cy.get(this.text);
this.getColor = () => cy.get(this.path).invoke('attr', 'fill');
this.getFontSize = () => cy.get(this.text).invoke('attr', 'font-size');
this.getImage = () => cy.get(this.image);
this.getImageHref = () => cy.get(this.image).invoke('attr', 'href');
this.getImageWidth = () => cy.get(this.image).invoke('attr', 'width');
this.getImageHeight = () => cy.get(this.image).invoke('attr', 'height');
}

module.exports = NodePO;
module.exports = NodePO;
46 changes: 46 additions & 0 deletions cypress/page-objects/sandbox.po.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*global cy*/

/**
* Page Object for interacting with sandbox interface.
* @returns {undefined}
*/
function SandboxPO() {
// whitelist checkbox inputs
this.checkboxes = ['node.renderLabel', 'staticGraph'];

// actions
this.playGraph = () => cy.get('.container__graph > :nth-child(1) > :nth-child(2)').click();
this.pauseGraph = () => cy.get('.container__graph > :nth-child(1) > :nth-child(3)').click();
this.addNode = () => cy.get('.container__graph > :nth-child(1) > :nth-child(5)').click();
this.removeNode = () => cy.get('.container__graph > :nth-child(1) > :nth-child(6)').click();
this.clickJsonTreeNodes = () => {
cy
.get('.container__graph-data')
.contains('root')
.scrollIntoView();
cy
.get('.container__graph-data')
.contains('nodes')
.click();
};
// must be collapsed
this.clickJsonTreeFirstNode = () =>
cy
.get(
':nth-child(2) > .rejt-not-collapsed > .rejt-not-collapsed-list > :nth-child(1) > .rejt-collapsed > .rejt-collapsed-text'
)
.click();
this.addJsonTreeFirstNodeProp = () =>
cy.get(':nth-child(2) > :nth-child(1) > .rejt-not-collapsed > :nth-child(4) > .rejt-plus-menu').click();
this.deleteJsonTreeFirstNodeProp = () =>
cy.get('.rejt-not-collapsed-list > :nth-child(2) > .rejt-minus-menu').click();

// element getters
this.getFieldInput = field =>
this.checkboxes.includes(field)
? cy.contains(field).children('input')
: cy.contains(field).siblings('.form-control');
this.getGraphNumbers = () => cy.get('.container__graph-info');
}

module.exports = SandboxPO;
Binary file added docs/rd3g-custom-svg.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
verbose: true,
rootDir: 'test'
};
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
"lint": "npm run lint:src && npm run lint:test",
"precommit": "lint-staged",
"start": "http-server ./sandbox/ -p 8888 -c-1",
"test:clean": "jest --no-cache --updateSnapshot --verbose --coverage",
"test:watch": "jest --verbose --coverage --watchAll",
"test": "jest --verbose --coverage"
"test:clean": "jest --no-cache --updateSnapshot --verbose --coverage --config jest.config.js",
"test:watch": "jest --verbose --coverage --watchAll --config jest.config.js",
"test": "jest --verbose --coverage --config jest.config.js"
},
"lint-staged": {
"*.{js,json,css,md}": [
Expand Down
1 change: 1 addition & 0 deletions sandbox/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<meta charset="utf-8">
<title>react-d3-graph</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="shortcut icon" href="https://danielcaldas.github.io/react-d3-graph/sandbox/favicon.ico">
</head>
<body>
<div id="app"></div>
Expand Down
Loading

0 comments on commit 7cb98c7

Please sign in to comment.