orgchart 3.1.4 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/gulpfile.js CHANGED
@@ -9,7 +9,7 @@ var merge = require('merge-stream');
9
9
  var csslint = require('gulp-csslint');
10
10
  var cleanCSS = require('gulp-clean-css');
11
11
  var sourcemaps = require('gulp-sourcemaps');
12
- var testcafe = require('gulp-testcafe');
12
+ var cypress = require('cypress');
13
13
  var jest = require('gulp-jest').default;
14
14
  var paths = {
15
15
  src: 'src',
@@ -65,8 +65,9 @@ gulp.task('visual-regression', function () {
65
65
  });
66
66
 
67
67
  gulp.task('e2e-tests', gulp.series('addAssets', function () {
68
- return gulp.src('test/e2e/**/test.js')
69
- .pipe(testcafe({ browsers: ['chrome:headless', 'firefox:headless'] }));
68
+ return cypress.run({
69
+ spec: 'test/cypress/e2e/**/*.cy.js',
70
+ });
70
71
  }));
71
72
 
72
73
  gulp.task('test', gulp.series('e2e-tests', 'visual-regression'));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orgchart",
3
- "version": "3.1.4",
3
+ "version": "3.4.0",
4
4
  "description": "Simple and direct organization chart(tree-like hierarchy) plugin based on pure DOM and jQuery.",
5
5
  "main": "./dist/js/jquery.orgchart.min.js",
6
6
  "style": [
@@ -10,7 +10,8 @@
10
10
  "test": "gulp test",
11
11
  "unit-tests": "gulp unit-tests",
12
12
  "build": "gulp build",
13
- "start": "gulp serve"
13
+ "start": "gulp serve",
14
+ "cypress:open": "cypress open"
14
15
  },
15
16
  "jest": {
16
17
  "preset": "jest-puppeteer"
@@ -39,11 +40,13 @@
39
40
  "html2canvas": "^1.4.1",
40
41
  "jquery": "^3.6.2",
41
42
  "jquery-mockjax": "^2.6.0",
43
+ "json-digger": "^1.3.0",
42
44
  "jspdf": "^2.5.1"
43
45
  },
44
46
  "devDependencies": {
45
47
  "browser-sync": "^2.26.7",
46
48
  "chai": "^4.2.0",
49
+ "cypress": "^12.3.0",
47
50
  "del": "^3.0.0",
48
51
  "gulp": "^4.0.2",
49
52
  "gulp-clean-css": "^3.10.0",
@@ -51,22 +54,20 @@
51
54
  "gulp-eslint": "^4.0.2",
52
55
  "gulp-inject": "^4.3.2",
53
56
  "gulp-jest": "^4.0.3",
54
- "gulp-mocha": "^6.0.0",
57
+ "gulp-mocha": "^8.0.0",
55
58
  "gulp-rename": "^1.4.0",
56
59
  "gulp-sourcemaps": "^2.6.5",
57
- "gulp-testcafe": "^0.9.2",
58
60
  "gulp-uglify": "^3.0.2",
59
61
  "jest": "^29.3.1",
60
62
  "jest-cli": "^29.3.1",
61
- "jest-image-snapshot": "^2.11.0",
63
+ "jest-image-snapshot": "^6.1.0",
62
64
  "jest-puppeteer": "^4.3.0",
63
65
  "jsdom": "^16.5.0",
64
66
  "jsdom-global": "^3.0.2",
65
67
  "merge-stream": "^1.0.1",
66
- "mocha": "^6.2.0",
68
+ "mocha": "^10.2.0",
67
69
  "puppeteer": "^1.20.0",
68
70
  "sinon": "^4.5.0",
69
- "sinon-chai": "^2.14.0",
70
- "testcafe": "^1.5.0"
71
+ "sinon-chai": "^2.14.0"
71
72
  }
72
73
  }
@@ -402,6 +402,8 @@
402
402
  position: absolute;
403
403
  left: 5px;
404
404
  bottom: -2px;
405
+ width: 1rem;
406
+ height: 1rem;
405
407
  }
406
408
 
407
409
  .orgchart .node .toggleBtn::before {
@@ -958,7 +958,7 @@
958
958
  $children.addClass('sliding').removeClass('slide-up').eq(0).one('transitionend', { 'vNodes': $children }, this.expandVNodesEnd);
959
959
  } else {
960
960
  $descendants.addClass('sliding slide-up').eq(0).one('transitionend', { 'vNodes': $descendants }, this.collapseVNodesEnd);
961
- $descendants.find('.toggleBtn').removeClass('oci-minus-square').addClass('oci-plus-square');
961
+ $descendants.find('.toggleBtn').removeClass('oci-minus-square oci-plus-square');
962
962
  }
963
963
  },
964
964
  //
@@ -1094,6 +1094,7 @@
1094
1094
  },
1095
1095
  // when user drops the node, it will be removed from original parent node and be added to new parent node
1096
1096
  dropHandler: function (event) {
1097
+ var that = this;
1097
1098
  var $dropZone = $(event.delegateTarget);
1098
1099
  var $dragged = this.$chart.data('dragged');
1099
1100
 
@@ -1115,6 +1116,25 @@
1115
1116
  if (dropEvent.isDefaultPrevented()) {
1116
1117
  return;
1117
1118
  }
1119
+ // special process for hybrid chart
1120
+ if (this.$chart.data('options').verticalLevel > 1) {
1121
+ var datasource = this.$chart.data('options').data;
1122
+ var digger = new JSONDigger(datasource, this.$chart.data('options').nodeId, 'children');
1123
+ digger.findNodeById($dragged.data('nodeData').id).then(function(draggedNode) {
1124
+ var copy = Object.assign({}, draggedNode)
1125
+ digger.removeNode(draggedNode.id).then(function() {
1126
+ digger.findNodeById($dropZone.data('nodeData').id).then(function(dropNode) {
1127
+ if (dropNode.children) {
1128
+ dropNode.children.push(copy);
1129
+ } else {
1130
+ dropNode.children = [copy];
1131
+ }
1132
+ that.init({ 'data': datasource });
1133
+ });
1134
+ });
1135
+ });
1136
+ } else {
1137
+ // The folowing code snippets are used to process horizontal chart
1118
1138
  // firstly, deal with the hierarchy of drop zone
1119
1139
  if (!$dropZone.siblings('.nodes').length) { // if the drop zone is a leaf node
1120
1140
  $dropZone.append('<i class="edge verticalEdge bottomEdge oci"></i>')
@@ -1142,6 +1162,7 @@
1142
1162
  $dragZone.find('.bottomEdge, .symbol').remove()
1143
1163
  .end().siblings('.nodes').remove();
1144
1164
  }
1165
+ }
1145
1166
  },
1146
1167
  //
1147
1168
  touchstartHandler: function (event) {
@@ -0,0 +1,115 @@
1
+ describe('Hybrid(horizontal + vertical) Chart', () => {
2
+
3
+ const laolao = '.node:contains("Lao Lao")';
4
+ const bomiao = '.node:contains("Bo Miao")';
5
+ const sumiao = '.node:contains("Su Miao")';
6
+ const hongmiao = '.node:contains("Hong Miao")';
7
+ const lixin = '.node:contains("Li Xin")';
8
+ const tiehua = '.node:contains("Tie Hua")';
9
+ const heihei = '.node:contains("Hei Hei")';
10
+ const pangpang = '.node:contains("Pang Pang")';
11
+ const dandan = '.node:contains("Dan Dan")';
12
+
13
+ beforeEach(() => {
14
+ cy.visit('demo/drag-drop.html');
15
+ });
16
+
17
+ function dropNodeToAnother (sourceNode, targetNode) {
18
+ const dataTransfer = new DataTransfer();
19
+ cy.get(sourceNode).trigger('dragstart', { dataTransfer, force: true });
20
+ cy.get(targetNode).trigger('drop', { dataTransfer, force: true });
21
+ }
22
+
23
+ it('drag lixin onto hongmiao', () => {
24
+ dropNodeToAnother(lixin, hongmiao);
25
+ cy.get(hongmiao).should(($node) => {
26
+ expect($node.siblings('.nodes')).to.exist;
27
+ expect($node.siblings('.nodes').find('.node:contains("Li Xin")')).to.exist;
28
+ });
29
+ cy.get(bomiao).should(($node) => {
30
+ expect($node.siblings('.nodes')).not.to.exist;
31
+ });
32
+ });
33
+
34
+ it('drag lixin onto heihei', () => {
35
+ dropNodeToAnother(lixin, heihei);
36
+ cy.get(heihei).should(($node) => {
37
+ expect($node.siblings('.nodes').find('.node').length).to.equal(3);
38
+ expect($node.siblings('.nodes').find('.node:contains("Li Xin")')).to.exist;
39
+ });
40
+ cy.get(bomiao).should(($node) => {
41
+ expect($node.siblings('.nodes')).not.to.exist;
42
+ });
43
+ });
44
+
45
+ it('heihei onto hongmiao', () => {
46
+ dropNodeToAnother(heihei, hongmiao);
47
+ cy.get(hongmiao).should(($node) => {
48
+ expect($node.siblings('.nodes')).to.exist;
49
+ expect($node.siblings('.nodes').find('.node').length).to.equal(3);
50
+ expect($node.siblings('.nodes').find('.node:contains("Hei Hei")')).to.exist;
51
+ });
52
+ cy.get(sumiao).should(($node) => {
53
+ expect($node.siblings('.nodes').find('.node:contains("Tie Hua")')).to.exist;
54
+ });
55
+ });
56
+
57
+ it('heihei onto bomiao', () => {
58
+ dropNodeToAnother(heihei, bomiao);
59
+ cy.get(bomiao).should(($node) => {
60
+ expect($node.siblings('.nodes').find('.node').length).to.equal(4);
61
+ expect($node.siblings('.nodes').find('.node:contains("Hei Hei")')).to.exist;
62
+ });
63
+ cy.get(sumiao).should(($node) => {
64
+ expect($node.siblings('.nodes').find('.node:contains("Tie Hua")')).to.exist;
65
+ });
66
+ });
67
+
68
+ it('pangpang onto heihei', () => {
69
+ dropNodeToAnother(pangpang, heihei);
70
+ cy.get(heihei).should(($node) => {
71
+ expect($node.siblings('.nodes').find('.node').length).to.equal(2);
72
+ expect($node.siblings('.nodes').find('.node:contains("Pang Pang")')).to.exist;
73
+ });
74
+ });
75
+
76
+ it('dandan onto heihei', () => {
77
+ dropNodeToAnother(dandan, heihei);
78
+ cy.get(heihei).should(($node) => {
79
+ expect($node.siblings('.nodes').find('.node').length).to.equal(2);
80
+ expect($node.siblings('.nodes').find('.node:contains("Dan Dan")')).to.exist;
81
+ });
82
+ });
83
+
84
+ it('pangpang onto dandan', () => {
85
+ dropNodeToAnother(pangpang, dandan);
86
+ cy.get(heihei).should(($node) => {
87
+ expect($node.siblings('.nodes').find('.node')).to.exist;
88
+ expect($node.siblings('.nodes').find('.node:contains("Dan Dan")')).to.exist;
89
+ });
90
+ cy.get(dandan).should(($node) => {
91
+ expect($node.siblings('.nodes').find('.node')).to.exist;
92
+ expect($node.siblings('.nodes').find('.node:contains("Pang Pang")')).to.exist;
93
+ });
94
+ });
95
+
96
+ it('heihei onto pangpang', () => {
97
+ dropNodeToAnother(heihei, pangpang);
98
+ cy.get(heihei).should(($node) => {
99
+ expect($node.siblings('.nodes').find('.node').length).to.equal(2);
100
+ expect($node.siblings('.nodes').find('.node:contains("Pang Pang")')).to.exist;
101
+ expect($node.siblings('.nodes').find('.node:contains("Dan Dan")')).to.exist;
102
+ });
103
+ });
104
+
105
+ it('hongmiao onto lixin', () => {
106
+ dropNodeToAnother(hongmiao, lixin);
107
+ cy.get(laolao).should(($node) => {
108
+ expect($node.siblings('.nodes').children('.hierarchy:contains("Hong Miao")')).to.exist;
109
+ });
110
+ cy.get(lixin).should(($node) => {
111
+ expect($node.siblings('.nodes').find('.node:contains("Hong Miao")')).not.to.exist;
112
+ });
113
+ });
114
+
115
+ });
@@ -0,0 +1,80 @@
1
+ describe('Edit Chart', () => {
2
+
3
+ const editPanel = '#edit-panel';
4
+ const ballgame = '.node:contains("Ball game")';
5
+ const football = '.node:contains("Football")';
6
+ const viewState = '#rd-view';
7
+ const editState = '#rd-edit';
8
+ const selectedNode = '#selected-node';
9
+ const newNodes = '#new-nodelist .new-node';
10
+ const addInput = '#btn-add-input';
11
+ const removeInput = '#btn-remove-input';
12
+ const parentRel = '#rd-parent';
13
+ const childRel = '#rd-child';
14
+ const siblingRel = '#rd-sibling';
15
+ const addBtn = '#btn-add-nodes';
16
+ const deleteBtn = '#btn-delete-nodes';
17
+ const resetBtn = '#btn-reset';
18
+
19
+ beforeEach(() => {
20
+ cy.visit('demo/edit-chart.html');
21
+ });
22
+
23
+ it('add parent(root) node -- sports', () => {
24
+ cy.get(ballgame).click();
25
+ cy.get(newNodes).eq(0).type('Sports');
26
+ cy.get(parentRel).click();
27
+ cy.get(addBtn).click();
28
+ cy.get(selectedNode).should('have.value', 'Ball game');
29
+ cy.get(ballgame).should(($node) => {
30
+ expect($node.closest('.nodes').siblings('.node')).to.have.text('Sports');
31
+ });
32
+ });
33
+
34
+ it('add child nodes -- Futsal and Beach football', () => {
35
+ cy.get(football).click();
36
+ cy.get(newNodes).eq(0).type('Futsal');
37
+ cy.get(addInput).click();
38
+ cy.get(newNodes).eq(1).type('Beach football');
39
+ cy.get(addInput).click();
40
+ cy.get(newNodes).eq(2).type('Robot football');
41
+ cy.get(removeInput).click();
42
+ cy.get(childRel).click();
43
+ cy.get(addBtn).click();
44
+ cy.get(selectedNode).should('have.value', 'Football');
45
+ cy.get(football).should(($node) => {
46
+ expect($node.siblings('.nodes').children('.hierarchy').length).to.equal(2);
47
+ });
48
+ cy.get(football).should(($node) => {
49
+ expect($node.siblings('.nodes').find('.node:contains("Futsal")')).to.exist;
50
+ expect($node.siblings('.nodes').find('.node:contains("Beach football")')).to.exist;
51
+ });
52
+
53
+ cy.get(resetBtn).click();
54
+ cy.get(football).should('not.have.class', 'focused');
55
+ cy.get(selectedNode).should('have.value', '');
56
+ cy.get(newNodes).should('have.length', 1);
57
+ cy.get(childRel).should('not.be.checked');
58
+ });
59
+
60
+ it('add sibling node -- Baseball', () => {
61
+ cy.get(football).click();
62
+ cy.get(newNodes).eq(0).type('Baseball');
63
+ cy.get(siblingRel).click();
64
+ cy.get(addBtn).click();
65
+ cy.get(selectedNode).should('have.value', 'Football');
66
+ cy.get(ballgame).should(($node) => {
67
+ expect($node.siblings('.nodes').children('.hierarchy').length).to.equal(4);
68
+ expect($node.siblings('.nodes').find('.node:contains("Baseball")')).to.exist;
69
+ });
70
+ });
71
+
72
+ it('delete the football node', () => {
73
+ cy.get(football).click();
74
+ cy.get(selectedNode).should('have.value', 'Football');
75
+ cy.get(deleteBtn).click();
76
+ cy.get(selectedNode).should('have.value', '');
77
+ cy.get(football).should('not.exist');
78
+ });
79
+
80
+ });
@@ -0,0 +1,82 @@
1
+ describe('Local Datasource', () => {
2
+
3
+ const laolao = '.node:contains("Lao Lao")';
4
+ const bomiao = '.node:contains("Bo Miao")';
5
+ const sumiao = '.node:contains("Su Miao")';
6
+ const hongmiao = '.node:contains("Hong Miao")';
7
+ const tiehua = '.node:contains("Tie Hua")';
8
+ const heihei = '.node:contains("Hei Hei")';
9
+ const pangpang = '.node:contains("Pang Pang")';
10
+ const dandan = '.node:contains("Dan Dan")';
11
+
12
+ beforeEach(() => {
13
+ cy.visit('demo/local-datasource.html');
14
+ });
15
+
16
+ it('bottomEdge of root node works well', () => {
17
+ cy.get(laolao).find('.bottomEdge').click();
18
+ cy.get(bomiao).get(sumiao).get(hongmiao).should('not.be.visible');
19
+
20
+ cy.get(laolao).find('.bottomEdge').click();
21
+ cy.get(bomiao).get(sumiao).get(hongmiao).should('be.visible');
22
+ });
23
+
24
+ it('topEdge of sumiao node works well', () => {
25
+ cy.get(sumiao).find('.topEdge').click();
26
+ cy.get(laolao).get(bomiao).get(hongmiao).should('not.be.visible');
27
+
28
+ cy.get(sumiao).find('.topEdge').click();
29
+ cy.get(laolao).should('be.visible');
30
+ cy.get(bomiao).get(hongmiao).should('not.be.visible');
31
+ });
32
+
33
+ it('leftEdge of sumiao node works well', () => {
34
+ cy.get(sumiao).find('.leftEdge').click();
35
+ cy.get(bomiao).get(hongmiao).should('not.be.visible');
36
+
37
+ cy.get(sumiao).find('.leftEdge').click();
38
+ cy.get(bomiao).get(hongmiao).should('be.visible');
39
+ });
40
+
41
+ it('rightEdge of sumiao node works well', () => {
42
+ cy.get(sumiao).find('.rightEdge').click();
43
+ cy.get(bomiao).get(hongmiao).should('not.be.visible');
44
+
45
+ cy.get(sumiao).find('.rightEdge').click();
46
+ cy.get(bomiao).get(hongmiao).should('be.visible');
47
+ });
48
+
49
+ it('bottomEdge of sumiao node works well', () => {
50
+ cy.get(sumiao).find('.bottomEdge').click();
51
+ cy.get(tiehua).get(heihei).get(pangpang).get(dandan).should('not.be.visible');
52
+
53
+ cy.get(sumiao).find('.bottomEdge').click();
54
+ cy.get(tiehua).get(heihei).get(pangpang).should('be.visible');
55
+ });
56
+
57
+ it('topEdge of heihei node works well', () => {
58
+ cy.get(heihei).find('.topEdge').click();
59
+ cy.get(laolao).get(bomiao).get(sumiao).get(hongmiao).get(tiehua).get(pangpang).should('not.be.visible');
60
+
61
+ cy.get(heihei).find('.topEdge').click();
62
+ cy.get(sumiao).should('be.visible');
63
+ cy.get(laolao).should('not.be.visible');
64
+ });
65
+
66
+ it('horizontalEdge of heihei node works well', () => {
67
+ cy.get(heihei).find('.topEdge').click();
68
+ cy.get(heihei).find('.leftEdge').click();
69
+ cy.get(sumiao).get(tiehua).get(pangpang).should('be.visible');
70
+ cy.get(laolao).should('not.be.visible');
71
+ });
72
+
73
+ it('horizontalEdge of pangpang node works well', () => {
74
+ cy.get(pangpang).find('.leftEdge').click();
75
+ cy.get(tiehua).get(heihei).get(dandan).should('not.be.visible');
76
+
77
+ cy.get(pangpang).find('.leftEdge').click();
78
+ cy.get(tiehua).get(heihei).should('be.visible');
79
+ });
80
+
81
+ });
82
+
@@ -0,0 +1,33 @@
1
+ describe('Load data on-demand', () => {
2
+
3
+ const sumiao = '.node:contains("Su Miao")';
4
+ const heihei = '.node:contains("Hei Hei")';
5
+
6
+ beforeEach(() => {
7
+ cy.visit('demo/ondemand-loading-data.html');
8
+ });
9
+
10
+ it('load child nodes of hehei', () => {
11
+ cy.get(heihei).find('.bottomEdge').click();
12
+ cy.get(heihei).should(($node) => {
13
+ expect($node.siblings('.nodes').children('.hierarchy').length).to.equal(2);
14
+ });
15
+ });
16
+
17
+ it('load parent node of sumiao', () => {
18
+ cy.get(sumiao).find('.topEdge').click();
19
+ cy.get(sumiao).should(($node) => {
20
+ expect($node.closest('.nodes').siblings('.node:contains("Lao Lao")')).to.exist;
21
+ });
22
+ });
23
+
24
+ it('load parent and sibling nodes of sumiao', () => {
25
+ cy.get(sumiao).find('.leftEdge').click();
26
+ cy.get(sumiao).should(($node) => {
27
+ expect($node.closest('.nodes').siblings('.node:contains("Lao Lao")')).to.exist;
28
+ expect($node.closest('.hierarchy').siblings().length).to.equal(7);
29
+ });
30
+
31
+ });
32
+
33
+ });
@@ -0,0 +1,41 @@
1
+ describe('Pan & Zoom', () => {
2
+
3
+ beforeEach(() => {
4
+ cy.visit('demo/pan-zoom.html');
5
+ });
6
+
7
+ const chart = '.orgchart';
8
+
9
+ it('drag the chart to the top', () => {
10
+ cy.get(chart)
11
+ .trigger('mousedown', { which: 1, pageX: 10, pageY: 200 })
12
+ .trigger('mousemove', { which: 1, pageX: 10, pageY: 100 })
13
+ .trigger('mouseup')
14
+ .should('have.css', 'transform', 'matrix(1, 0, 0, 1, 0, -100)');
15
+ });
16
+
17
+ it('drag the chart to the bottom', () => {
18
+ cy.get(chart)
19
+ .trigger('mousedown', { which: 1, pageX: 10, pageY: 100 })
20
+ .trigger('mousemove', { which: 1, pageX: 10, pageY: 200 })
21
+ .trigger('mouseup')
22
+ .should('have.css', 'transform', 'matrix(1, 0, 0, 1, 0, 100)');
23
+ });
24
+
25
+ it('drag the chart to the left', () => {
26
+ cy.get(chart)
27
+ .trigger('mousedown', { which: 1, pageX: 200, pageY: 10 })
28
+ .trigger('mousemove', { which: 1, pageX: 100, pageY: 10 })
29
+ .trigger('mouseup')
30
+ .should('have.css', 'transform', 'matrix(1, 0, 0, 1, -100, 0)');
31
+ });
32
+
33
+ it('drag the chart to the right', () => {
34
+ cy.get(chart)
35
+ .trigger('mousedown', { which: 1, pageX: 100, pageY: 10 })
36
+ .trigger('mousemove', { which: 1, pageX: 200, pageY: 10 })
37
+ .trigger('mouseup')
38
+ .should('have.css', 'transform', 'matrix(1, 0, 0, 1, 100, 0)');
39
+ });
40
+
41
+ });
@@ -0,0 +1,26 @@
1
+ describe('Refresh orgchart with new options', () => {
2
+
3
+ beforeEach(() => {
4
+ cy.visit('demo/reload-data.html');
5
+ });
6
+
7
+ const loadChart1 = '#btn-chart1';
8
+ const loadChart2 = '#btn-chart2';
9
+ const loadChart3 = '#btn-chart3';
10
+
11
+ it('load chart2', () => {
12
+ cy.get(loadChart2).click();
13
+ cy.get('.node').should('have.length', 3);
14
+ });
15
+
16
+ it('load chart3', () => {
17
+ cy.get(loadChart3).click();
18
+ cy.get('.node').should('have.length', 4);
19
+ });
20
+
21
+ it('load chart1', () => {
22
+ cy.get(loadChart1).click();
23
+ cy.get('.node').should('have.length', 9);
24
+ });
25
+
26
+ });
@@ -0,0 +1,33 @@
1
+ describe('Toggle sibling nodes respectively', () => {
2
+
3
+ const bomiao = '.node:contains("Bo Miao")';
4
+ const sumiao = '.node:contains("Su Miao")';
5
+ const hongmiao = '.node:contains("Hong Miao")';
6
+ const renwu = '.node:contains("Ren Wu")';
7
+ const lixin = '.node:contains("Li Xin")';
8
+ const xingan = '.node:contains("Xing An")';
9
+ const yidian = '.node:contains("Yi Dian")';
10
+
11
+ beforeEach(() => {
12
+ cy.visit('demo/toggle-sibs-resp.html');
13
+ });
14
+
15
+ it('toggle the left side sibling nodes of sumiao', () => {
16
+ cy.get(sumiao).find('.leftEdge').click();
17
+ cy.get(bomiao).get(renwu).get(lixin).should('not.be.visible');
18
+
19
+ cy.get(sumiao).find('.leftEdge').click();
20
+ cy.get(bomiao).should('be.visible');
21
+ cy.get(renwu).get(lixin).should('not.be.visible');
22
+ });
23
+
24
+ it('toggle the right side sibling nodes of sumiao', () => {
25
+ cy.get(sumiao).find('.rightEdge').click();
26
+ cy.get(hongmiao).get(xingan).get(yidian).should('not.be.visible');
27
+
28
+ cy.get(sumiao).find('.rightEdge').click();
29
+ cy.get(hongmiao).should('be.visible');
30
+ cy.get(xingan).get(yidian).should('not.be.visible');
31
+ });
32
+
33
+ });
@@ -0,0 +1,38 @@
1
+ describe('Hybrid(horizontal + vertical) Chart', () => {
2
+
3
+ beforeEach(() => {
4
+ cy.visit('demo/vertical-level.html');
5
+ });
6
+
7
+ const sumiao = '.node:contains("Su Miao")';
8
+ const tiehua = '.node:contains("Tie Hua")';
9
+ const heihei = '.node:contains("Hei Hei")';
10
+ const pangpang = '.node:contains("Pang Pang")';
11
+ const dandan = '.node:contains("Dan Dan")';
12
+ const erdan = '.node:contains("Er Dan")';
13
+ const sandan = '.node:contains("San Dan")';
14
+ const sidan = '.node:contains("Si Dan")';
15
+ const wudan = '.node:contains("Wu Dan")';
16
+
17
+ it('toggle the vertical nodes', () => {
18
+ cy.get(dandan).find('.toggleBtn').click();
19
+ cy.get(erdan).get(sandan).should('be.visible');
20
+ cy.get(sidan).get(wudan).should('not.be.visible');
21
+
22
+ cy.get(heihei).find('.toggleBtn').click();
23
+ cy.get(pangpang).get(dandan).get(erdan).get(sandan).should('not.be.visible');
24
+
25
+ cy.get(heihei).find('.toggleBtn').click();
26
+ cy.get(pangpang).get(dandan).should('be.visible');
27
+ });
28
+
29
+ it('toggle the vertical nodes by cicking horizontal nodes', () => {
30
+ cy.get(sumiao).find('.bottomEdge').click();
31
+ cy.get(tiehua).get(heihei).get(pangpang).get(dandan).should('be.visible');
32
+
33
+ cy.get(sumiao).find('.bottomEdge').click();
34
+ cy.get(tiehua).get(heihei).should('be.visible');
35
+ cy.get(pangpang).get(dandan).should('not.be.visible');
36
+ });
37
+
38
+ });
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "Using fixtures to represent data",
3
+ "email": "hello@cypress.io",
4
+ "body": "Fixtures are a great way to mock data for responses to routes"
5
+ }
@@ -0,0 +1,25 @@
1
+ // ***********************************************
2
+ // This example commands.js shows you how to
3
+ // create various custom commands and overwrite
4
+ // existing commands.
5
+ //
6
+ // For more comprehensive examples of custom
7
+ // commands please read more here:
8
+ // https://on.cypress.io/custom-commands
9
+ // ***********************************************
10
+ //
11
+ //
12
+ // -- This is a parent command --
13
+ // Cypress.Commands.add('login', (email, password) => { ... })
14
+ //
15
+ //
16
+ // -- This is a child command --
17
+ // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
18
+ //
19
+ //
20
+ // -- This is a dual command --
21
+ // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
22
+ //
23
+ //
24
+ // -- This will overwrite an existing command --
25
+ // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
@@ -0,0 +1,20 @@
1
+ // ***********************************************************
2
+ // This example support/e2e.js is processed and
3
+ // loaded automatically before your test files.
4
+ //
5
+ // This is a great place to put global configuration and
6
+ // behavior that modifies Cypress.
7
+ //
8
+ // You can change the location of this file or turn off
9
+ // automatically serving support files with the
10
+ // 'supportFile' configuration option.
11
+ //
12
+ // You can read more here:
13
+ // https://on.cypress.io/configuration
14
+ // ***********************************************************
15
+
16
+ // Import commands.js using ES2015 syntax:
17
+ import './commands'
18
+
19
+ // Alternatively you can use CommonJS syntax:
20
+ // require('./commands')