1
+ import { barChartCypherQuery } from '../fixtures/cypher_queries' ;
2
+
3
+ const WAITING_TIME = 20000 ;
4
+ // Ignore warnings that may appear when using the Cypress dev server
5
+ Cypress . on ( 'uncaught:exception' , ( err , runnable ) => {
6
+ console . log ( err , runnable ) ;
7
+ return false ;
8
+ } ) ;
9
+
10
+ describe ( 'Testing bar chart' , ( ) => {
11
+ beforeEach ( 'open neodash' , ( ) => {
12
+ cy . viewport ( 1920 , 1080 ) ;
13
+ cy . visit ( '/' , {
14
+ onBeforeLoad ( win ) {
15
+ win . localStorage . clear ( ) ;
16
+ } ,
17
+ } ) ;
18
+
19
+ cy . get ( '#form-dialog-title' , { timeout : 20000 } ) . should ( 'contain' , 'NeoDash - Neo4j Dashboard Builder' ) . click ( ) ;
20
+
21
+ cy . get ( '#form-dialog-title' ) . then ( ( $div ) => {
22
+ const text = $div . text ( ) ;
23
+ if ( text == 'NeoDash - Neo4j Dashboard Builder' ) {
24
+ cy . wait ( 500 ) ;
25
+ // Create new dashboard
26
+ cy . contains ( 'New Dashboard' ) . click ( ) ;
27
+ }
28
+ } ) ;
29
+
30
+ cy . get ( '#form-dialog-title' , { timeout : 20000 } ) . should ( 'contain' , 'Connect to Neo4j' ) ;
31
+
32
+ cy . get ( '#url' ) . clear ( ) . type ( 'localhost' ) ;
33
+ cy . get ( '#dbusername' ) . clear ( ) . type ( 'neo4j' ) ;
34
+ cy . get ( '#dbpassword' ) . type ( 'test1234' ) ;
35
+ cy . get ( 'button' ) . contains ( 'Connect' ) . click ( ) ;
36
+ cy . wait ( 100 ) ;
37
+
38
+ //Opens the div containing all report cards
39
+ cy . get ( '.react-grid-layout:eq(0)' ) . within ( ( ) => {
40
+ //Finds the 2nd card
41
+ cy . get ( '.MuiGrid-root' )
42
+ . eq ( 1 )
43
+ . within ( ( ) => {
44
+ //Clicks the 2nd button (opens settings)
45
+ cy . get ( 'button' ) . eq ( 1 ) . click ( ) ;
46
+ } ) ;
47
+ } ) ;
48
+ cy . get ( '.react-grid-layout:eq(0)' ) . within ( ( ) => {
49
+ //Finds the 2nd card
50
+ cy . get ( '.MuiGrid-root' )
51
+ . eq ( 1 )
52
+ . within ( ( ) => {
53
+ //Opens the drop down
54
+ cy . getDataTest ( 'type-dropdown' ) . click ( ) ;
55
+ } ) ;
56
+ } ) ;
57
+ // Selects the Bar option
58
+ cy . get ( '[id^="react-select-5-option"]' )
59
+ . contains ( / B a r C h a r t / i)
60
+ . should ( 'be.visible' )
61
+ . click ( { force : true } ) ;
62
+ cy . get ( '.react-grid-layout .MuiGrid-root:eq(1) #type input[name="Type"]' ) . should ( 'have.value' , 'Bar Chart' ) ;
63
+
64
+ // Creates basic bar chart
65
+ cy . get ( '.react-grid-layout' )
66
+ . first ( )
67
+ . within ( ( ) => {
68
+ //Finds the 2nd card
69
+ cy . get ( '.MuiGrid-root' )
70
+ . eq ( 1 )
71
+ . within ( ( ) => {
72
+ //Removes text in cypher editor and types new query
73
+ cy . get ( '.ndl-cypher-editor div[role="textbox"]' )
74
+ . should ( 'be.visible' )
75
+ . click ( )
76
+ . clear ( )
77
+ . type ( barChartCypherQuery ) ;
78
+
79
+ cy . wait ( 400 ) ;
80
+ cy . get ( 'button[aria-label="run"]' ) . click ( ) ;
81
+ } ) ;
82
+ } ) ;
83
+
84
+ cy . wait ( 500 ) ;
85
+ } ) ;
86
+
87
+ it ( 'Checking Colour Picker settings' , ( ) => {
88
+ //Opens advanced settings
89
+ cy . get ( '.react-grid-layout' )
90
+ . first ( )
91
+ . within ( ( ) => {
92
+ //Finds the 2nd card
93
+ cy . get ( '.MuiGrid-root' )
94
+ . eq ( 1 )
95
+ . within ( ( ) => {
96
+ // Access advanced settings
97
+ cy . get ( 'button' ) . eq ( 1 ) . click ( ) ;
98
+ cy . get ( '[role="switch"]' ) . click ( ) ;
99
+ cy . wait ( 200 ) ;
100
+ // Changing setting for colour picker
101
+ cy . get ( '[data-testid="colorpicker-input"]' ) . find ( 'input' ) . click ( ) . type ( '{selectall}' ) . type ( 'red' ) ;
102
+ cy . get ( 'button[aria-label="run"]' ) . click ( ) ;
103
+ // Checking that colour picker was applied correctly
104
+ cy . get ( '.card-view' ) . should ( 'have.css' , 'background-color' , 'rgb(255, 0, 0)' ) ;
105
+ cy . wait ( 200 ) ;
106
+ // Changing colour back to white
107
+ cy . get ( 'button' ) . eq ( 1 ) . click ( ) ;
108
+ cy . get ( '[data-testid="colorpicker-input"]' ) . find ( 'input' ) . click ( ) . type ( '{selectall}' ) . type ( 'white' ) ;
109
+ cy . get ( 'button[aria-label="run"]' ) . click ( ) ;
110
+ // Checking colour has been set back to white
111
+ cy . wait ( 200 ) ;
112
+ cy . get ( '.card-view' ) . should ( 'have.css' , 'background-color' , 'rgb(255, 255, 255)' ) ;
113
+ } ) ;
114
+ } ) ;
115
+ } ) ;
116
+
117
+ it ( 'Checking Selector Description' , ( ) => {
118
+ //Opens first 2nd card
119
+ cy . get ( '.react-grid-layout:eq(0) .MuiGrid-root:eq(1)' ) . within ( ( ) => {
120
+ // Access advanced settings
121
+ cy . get ( 'button' ) . eq ( 1 ) . click ( ) ;
122
+ cy . get ( '[role="switch"]' ) . click ( ) ;
123
+ cy . wait ( 200 ) ;
124
+ // Changing Selector Description to 'Test'
125
+ cy . get ( '.ndl-textarea' ) . contains ( 'span' , 'Selector Description' ) . click ( ) . type ( 'Test' ) ;
126
+ cy . get ( 'button[aria-label="run"]' ) . click ( ) ;
127
+ // Pressing Selector Description button
128
+ cy . get ( 'button[aria-label="details"]' ) . click ( ) ;
129
+ } ) ;
130
+ // Checking that Selector Description is behaving as expected
131
+ cy . get ( '.MuiDialog-paper' ) . should ( 'be.visible' ) . and ( 'contain.text' , 'Test' ) ;
132
+ cy . wait ( 1000 ) ;
133
+
134
+ // Click elsewhere on the page to close dialog box
135
+ cy . get ( 'div[role="dialog"]' ) . parent ( ) . click ( - 100 , - 100 , { force : true } ) ;
136
+ } ) ;
137
+
138
+ it ( 'Checking full screen bar chart setting' , ( ) => {
139
+ //Opens first 2nd card
140
+ cy . get ( '.react-grid-layout:eq(0) .MuiGrid-root:eq(1)' ) . within ( ( ) => {
141
+ // Opening settings
142
+ cy . get ( 'button' ) . eq ( 1 ) . click ( ) ;
143
+ // Activating advanced settings
144
+ cy . get ( '[role="switch"]' ) . click ( ) ;
145
+ cy . wait ( 200 ) ;
146
+ // Finding fullscreen setting and changing it to 'on'
147
+ cy . get ( '.ndl-dropdown' )
148
+ . contains ( 'label' , 'Fullscreen enabled' )
149
+ . scrollIntoView ( )
150
+ . should ( 'be.visible' )
151
+ . click ( )
152
+ . type ( 'on{enter}' ) ;
153
+ // Pressing run to return to card view
154
+ cy . get ( 'button[aria-label="run"]' ) . click ( ) ;
155
+ cy . get ( 'button[aria-label="maximize"]' ) . click ( ) ;
156
+ } ) ;
157
+ // Modal outside of scope of card
158
+ // Checking existence of full-screen modal
159
+ cy . get ( '.dialog-xxl' ) . should ( 'be.visible' ) ;
160
+ // Action to close full-screen modal
161
+ cy . get ( 'button[aria-label="un-maximize"]' ) . click ( ) ;
162
+ // Checking that fullscreen has un-maximized
163
+ // Check that the div is no longer in the DOM
164
+ cy . get ( 'div[data-focus-lock-disabled="false"]' ) . should ( 'not.exist' ) ;
165
+ } ) ;
166
+
167
+ it ( 'Checking "Autorun Query" works as intended' , ( ) => {
168
+ // Custom command to open advanced settings
169
+ cy . advancedSettings ( ( ) => {
170
+ // Finding 'Auto-run query setting and changing it to 'off'
171
+ cy . get ( '.ndl-dropdown' )
172
+ . contains ( 'label' , 'Auto-run query' )
173
+ . scrollIntoView ( )
174
+ . should ( 'be.visible' )
175
+ . click ( )
176
+ . type ( 'off{enter}' ) ;
177
+ cy . wait ( 200 ) ;
178
+ cy . get ( 'button[aria-label="run"]' ) . click ( ) ;
179
+ cy . get ( '.ndl-cypher-editor' ) . should ( 'be.visible' ) ;
180
+ cy . get ( 'g' ) . should ( 'not.exist' ) ;
181
+ cy . wait ( 100 ) ;
182
+ cy . get ( '.MuiCardContent-root' ) . find ( 'button[aria-label="run"]' ) . filter ( ':visible' ) . click ( ) ;
183
+ cy . get ( 'g' ) . should ( 'exist' ) ;
184
+ } ) ;
185
+ } ) ;
186
+
187
+ it ( 'Checking Legend integration works as intended' , ( ) => {
188
+ cy . advancedSettings ( ( ) => {
189
+ // Checking that legend appears
190
+ cy . setDropdownValue ( 'Show Legend' , 'on' ) ;
191
+ cy . wait ( 100 ) ;
192
+ cy . get ( 'button[aria-label="run"]' ) . click ( ) ;
193
+ cy . wait ( 100 ) ;
194
+ //Checking that legend matches value specified: in the case - 'count'
195
+ cy . get ( 'svg g g text' ) . last ( ) . contains ( / c o u n t / i) ;
196
+ } ) ;
197
+ cy . advancedSettings ( ( ) => {
198
+ // Activating advanced settings
199
+ cy . get ( '[role="switch"]' ) . click ( ) ;
200
+ // Checking that legend disappears
201
+ cy . setDropdownValue ( 'Show Legend' , 'off' ) ;
202
+ cy . wait ( 100 ) ;
203
+ cy . get ( 'button[aria-label="run"]' ) . click ( ) ;
204
+ cy . wait ( 100 ) ;
205
+ cy . get ( 'svg g g text' ) . last ( ) . contains ( / c o u n t / i) . should ( 'not.exist' ) ;
206
+ } ) ;
207
+ } ) ;
208
+
209
+ it ( 'Checking the stacked grouping function works as intended' , ( ) => {
210
+ cy . advancedSettings ( ( ) => {
211
+ cy . get ( '.ndl-cypher-editor div[role="textbox"]' )
212
+ . should ( 'be.visible' )
213
+ . click ( )
214
+ . clear ( )
215
+ . type (
216
+ 'MATCH (p:Person)-[:DIRECTED]->(n:Movie) RETURN n.released AS released, p.name AS Director, count(n.title) AS count LIMIT 5'
217
+ ) ;
218
+ cy . setDropdownValue ( 'Grouping' , 'on' ) ;
219
+ cy . wait ( 100 ) ;
220
+ cy . get ( 'button[aria-label="run"]' ) . click ( ) ;
221
+ cy . get ( '.ndl-dropdown:contains("Group")' ) . find ( 'svg' ) . parent ( ) . click ( ) . type ( 'Director{enter}' ) ;
222
+ // Checking that the groups are stacked
223
+ cy . get ( '.MuiCardContent-root' )
224
+ . find ( 'g' )
225
+ . children ( 'g' )
226
+ . eq ( 3 ) // Get the fourth g element (index starts from 0)
227
+ . invoke ( 'attr' , 'transform' )
228
+ . then ( ( transformValue ) => {
229
+ // Captures the first number in the tranlsate attribute using the parenthisis to capture the first digit and put it in the second value of the resulting array
230
+ // if transformValue is translate(100,200), then transformValue.match(/translate\((\d+),\d+\)/) will produce an array like ["translate(100,200)", "100"],
231
+ const match = transformValue . match ( / t r a n s l a t e \( ( \d + ) , \d + \) / ) ;
232
+ if ( match ?. [ 1 ] ) {
233
+ const xValue = match [ 1 ] ;
234
+ console . log ( 'xValue: ' , xValue ) ;
235
+
236
+ // Now find sibling g elements with the same x transform value
237
+ cy . get ( '.MuiCardContent-root' )
238
+ . find ( 'g' )
239
+ . children ( 'g' )
240
+ . filter ( ( index , element ) => {
241
+ const siblingTransform = Cypress . $ ( element ) . attr ( 'transform' ) ;
242
+ return siblingTransform ?. includes ( `translate(${ xValue } ,` ) ;
243
+ } )
244
+ . should ( 'have.length' , 3 ) ; // Check that there's at least one element
245
+ } else {
246
+ throw new Error ( 'Transform attribute not found or invalid format' ) ;
247
+ }
248
+ } ) ;
249
+ } ) ;
250
+ cy . get ( '.ndl-dropdown:contains("Group")' ) . find ( 'svg' ) . parent ( ) . click ( ) . type ( '(none){enter}' ) ;
251
+ // Checking that the stacked grouped elements do not exist
252
+ cy . get ( '.MuiCardContent-root' )
253
+ . find ( 'g' )
254
+ . children ( 'g' )
255
+ . eq ( 3 ) // Get the fourth g element (index starts from 0)
256
+ . invoke ( 'attr' , 'transform' )
257
+ . then ( ( transformValue ) => {
258
+ // Captures the first number in the tranlsate attribute using the parenthisis to capture the first digit and put it in the second value of the resulting array
259
+ // if transformValue is translate(100,200), then transformValue.match(/translate\((\d+),\d+\)/) will produce an array like ["translate(100,200)", "100"],
260
+ const match = transformValue . match ( / t r a n s l a t e \( ( \d + ) , \d + \) / ) ;
261
+ if ( match ?. [ 1 ] ) {
262
+ const xValue = match [ 1 ] ;
263
+ console . log ( 'xValue: ' , xValue ) ;
264
+
265
+ // Now find sibling g elements with the same x transform value
266
+ cy . get ( '.MuiCardContent-root' )
267
+ . find ( 'g' )
268
+ . children ( 'g' )
269
+ . filter ( ( index , element ) => {
270
+ const siblingTransform = Cypress . $ ( element ) . attr ( 'transform' ) ;
271
+ return siblingTransform ?. includes ( `translate(${ xValue } ,` ) ;
272
+ } )
273
+ . should ( 'have.length' , 1 ) ; // Check that there are no matching elements
274
+ } else {
275
+ throw new Error ( 'Transform attribute not found or invalid format' ) ;
276
+ }
277
+ } ) ;
278
+ } ) ;
279
+
280
+ // How to properly test this?
281
+ it ( 'Testing grouped grouping mode' , ( ) => {
282
+ cy . advancedSettings ( ( ) => {
283
+ cy . get ( '.ndl-cypher-editor div[role="textbox"]' )
284
+ . should ( 'be.visible' )
285
+ . click ( )
286
+ . clear ( )
287
+ . type (
288
+ 'MATCH (p:Person)-[:DIRECTED]->(n:Movie) RETURN n.released AS released, p.name AS Director, count(n.title) AS count LIMIT 5'
289
+ ) ;
290
+ cy . setDropdownValue ( 'Grouping' , 'on' ) ;
291
+ cy . setDropdownValue ( 'Group Mode' , 'grouped' ) ;
292
+ cy . wait ( 400 ) ;
293
+ cy . get ( 'button[aria-label="run"]' ) . click ( ) ;
294
+ cy . get ( '.ndl-dropdown:contains("Group")' ) . find ( 'svg' ) . parent ( ) . click ( ) . type ( 'Director{enter}' ) ;
295
+ } ) ;
296
+ } ) ;
297
+
298
+ it ( 'Testing "Show Value on Bars"' , ( ) => {
299
+ cy . advancedSettings ( ( ) => {
300
+ cy . setDropdownValue ( 'Show Values On Bars' , 'on' ) ;
301
+ cy . get ( 'button[aria-label="run"]' ) . click ( ) ;
302
+ cy . get ( '.MuiCardContent-root' )
303
+ . find ( 'div svg > g > g > text' )
304
+ . should ( 'have.length' , 5 )
305
+ . then ( ( textElements ) => {
306
+ cy . log ( 'Number of text elements:' , textElements . length ) ;
307
+ } ) ;
308
+ } ) ;
309
+ cy . wait ( 100 )
310
+ cy . openSettings ( ( ) => {
311
+ cy . setDropdownValue ( 'Show Values On Bars' , 'off' )
312
+ cy . get ( 'button[aria-label="run"]' ) . click ( ) ;
313
+ cy . get ( '.MuiCardContent-root' )
314
+ . find ( 'div svg > g > g > text' )
315
+ . should ( 'not.exist' )
316
+ } )
317
+ } ) ;
318
+ } ) ;
0 commit comments