Skip to content

Commit ac3bf77

Browse files
graph: add offline data and first e2e test
* Add edges into the offline data to allow the graph view to be tested offline. * Add a basic cypress test which checks the layout gets completed and the nodes and edges get rendered.
1 parent ccc69dc commit ac3bf77

File tree

4 files changed

+130
-12
lines changed

4 files changed

+130
-12
lines changed

src/components/cylc/ViewToolbar.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2525
>
2626
<!-- control -->
2727
<div
28-
class="control"
28+
:class="['control', iControl.key]"
2929
v-for="iControl in iGroup.iControls"
3030
:key="iControl.title"
3131
>
3232
<v-tooltip bottom>
3333
<template v-slot:activator="{ on, attrs }">
3434
<v-icon
3535
large
36+
:class="iControl.title"
3637
:disabled="iControl.disabled"
3738
:color="iControl.color"
3839
@click="iControl.callback"

src/services/mock/json/App.json

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,58 @@
407407
"state": "succeeded",
408408
"submitNum": 1
409409
}
410+
],
411+
"edges": [
412+
{
413+
"id": "~user/one//$edge|20000102T0000Z/sleepy|20000102T0000Z/succeeded",
414+
"source": "~user/one//20000102T0000Z/sleepy",
415+
"target": "~user/one//20000102T0000Z/succeeded"
416+
},
417+
{
418+
"id": "~user/one//$edge|20000102T0000Z/waiting|20000102T0000Z/succeeded",
419+
"source": "~user/one//20000102T0000Z/waiting",
420+
"target": "~user/one//20000102T0000Z/succeeded"
421+
},
422+
{
423+
"id": "~user/one//$edge|20000102T0000Z/sleepy|20000102T0000Z/eventually_succeeded",
424+
"source": "~user/one//20000102T0000Z/sleepy",
425+
"target": "~user/one//20000102T0000Z/eventually_succeeded"
426+
},
427+
{
428+
"id": "~user/one//$edge|20000102T0000Z/waiting|20000102T0000Z/eventually_succeeded",
429+
"source": "~user/one//20000102T0000Z/waiting",
430+
"target": "~user/one//20000102T0000Z/eventually_succeeded"
431+
},
432+
{
433+
"id": "~user/one//$edge|20000102T0000Z/sleepy|20000102T0000Z/retrying",
434+
"source": "~user/one//20000102T0000Z/sleepy",
435+
"target": "~user/one//20000102T0000Z/retrying"
436+
},
437+
{
438+
"id": "~user/one//$edge|20000102T0000Z/waiting|20000102T0000Z/retrying",
439+
"source": "~user/one//20000102T0000Z/waiting",
440+
"target": "~user/one//20000102T0000Z/retrying"
441+
},
442+
{
443+
"id": "~user/one//$edge|20000102T0000Z/succeeded|20000102T0000Z/failed",
444+
"source": "~user/one//20000102T0000Z/succeeded",
445+
"target": "~user/one//20000102T0000Z/failed"
446+
},
447+
{
448+
"id": "~user/one//$edge|20000102T0000Z/eventually_succeeded|20000102T0000Z/failed",
449+
"source": "~user/one//20000102T0000Z/eventually_succeeded",
450+
"target": "~user/one//20000102T0000Z/failed"
451+
},
452+
{
453+
"id": "~user/one//$edge|20000102T0000Z/checkpoint|20000102T0000Z/sleepy",
454+
"source": "~user/one//20000102T0000Z/checkpoint",
455+
"target": "~user/one//20000102T0000Z/sleepy"
456+
},
457+
{
458+
"id": "~user/one//$edge|20000102T0000Z/checkpoint|20000102T0000Z/waiting",
459+
"source": "~user/one//20000102T0000Z/checkpoint",
460+
"target": "~user/one//20000102T0000Z/waiting"
461+
}
410462
]
411463
}
412464
}

src/views/Graph.vue

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
2828
width="100%"
2929
height="100%"
3030
ref="graph"
31+
class="graph"
3132
>
3233
<defs>
3334
<marker
@@ -52,6 +53,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
5253
:id="node.id"
5354
:ref="node.id"
5455
:transform="nodeTransformations[node.id]"
56+
class="graph-node-container"
5557
>
5658
<GraphNode
5759
:task="node"
@@ -64,6 +66,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
6466
GraphNode component layout / dimensions are changed.
6567
-->
6668
<g
69+
class="edges"
6770
:transform="
6871
(transpose) ? 'translate(15, 30)' : 'translate(45, 5)'
6972
"
@@ -90,7 +93,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
9093
<script>
9194
import Vue from 'vue'
9295
import gql from 'graphql-tag'
93-
import { mapState, mapGetters } from 'vuex'
96+
import { mapGetters } from 'vuex'
9497
import pageMixin from '@/mixins/index'
9598
import graphqlMixin from '@/mixins/graphql'
9699
import subscriptionViewMixin from '@/mixins/subscriptionView'
@@ -302,18 +305,13 @@ export default {
302305
clearInterval(this.refreshTimer)
303306
},
304307
computed: {
305-
...mapState('workflows', ['cylcTree']),
306308
...mapGetters('workflows', ['getNodes']),
307309
query () {
308310
return new SubscriptionQuery(
309311
QUERY,
310312
this.variables,
311313
'workflow',
312-
[
313-
// TODO: this callback should be run automatically
314-
// (only one instance for all views)
315-
// new CylcTreeCallback()
316-
]
314+
[]
317315
)
318316
},
319317
workflowIDs () {
@@ -397,8 +395,8 @@ export default {
397395
// list graph nodes from the store (non reactive list)
398396
const ret = []
399397
for (const workflow of this.workflows) {
400-
for (const cycle of workflow.children || []) {
401-
for (const task of cycle.children || []) {
398+
for (const cycle of workflow.children) {
399+
for (const task of cycle.children) {
402400
ret.push(task)
403401
}
404402
}
@@ -631,12 +629,10 @@ export default {
631629
// run the layout algorithm
632630
const jsonString = await graphviz.layout(dotCode, 'json')
633631
const json = JSON.parse(jsonString)
634-
console.log(json)
635632
636633
// update graph node positions
637634
for (const obj of json.objects) {
638635
const [x, y] = obj.pos.split(',')
639-
console.log(obj.name)
640636
const bbox = nodeDimensions[obj.name]
641637
// translations:
642638
// 1. The graphviz node coordinates

tests/e2e/specs/graph.cy.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* Copyright (C) NIWA & British Crown (Met Office) & Contributors.
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation, either version 3 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
18+
function waitForGraphLayout () {
19+
// wait for the initial graph layout to be performed
20+
cy
21+
.get('.c-graph:first')
22+
.then(($el) => { checkGraphLayoutPerformed($el) })
23+
}
24+
25+
function checkGraphLayoutPerformed ($el, depth = 0) {
26+
// Check if the graphID has been set (indicating successful layout) or wait
27+
// one second.
28+
// This is a recursive function which will be called up to 10 times. We can't
29+
// do this in a for loop as otherwise the waits aren't chained correctly.
30+
if (depth > 10) {
31+
expect('graph loaded').to.equal(true)
32+
} else if (typeof $el[0].__vue__.graphID !== 'number') {
33+
cy
34+
.wait(1000)
35+
.then(() => { checkGraphLayoutPerformed($el, depth + 1) })
36+
}
37+
}
38+
39+
describe('Graph View', () => {
40+
it('should load', () => {
41+
cy.visit('/#/graph/one')
42+
waitForGraphLayout()
43+
44+
cy
45+
// there should be 7 graph nodes (all on-screen)
46+
.get('.c-graph:first')
47+
.find('.graph-node-container')
48+
.should('be.visible')
49+
.should('have.length', 7)
50+
51+
// they shouldn't be stacked up in a pile
52+
// (we use SVG transforms to push the nodes around)
53+
.each(($el, index, $list) => {
54+
const el1 = $el[0]
55+
const matrix1 = el1.transform.baseVal[0].matrix
56+
for (const el2 of $list) {
57+
const matrix2 = el2.transform.baseVal[0].matrix
58+
expect(matrix1).to.not.equal(matrix2)
59+
}
60+
})
61+
62+
// there should be 10 graph edges (all on-screen)
63+
.get('.c-graph:first')
64+
.find('.graph:first .edges:first')
65+
.children()
66+
.should('have.length', 10)
67+
.should('be.visible')
68+
})
69+
})

0 commit comments

Comments
 (0)