Skip to content

Commit

Permalink
metadata-view: added offline data and tests
Browse files Browse the repository at this point in the history
* Added offline data.
* Added component tests to cover component display.
* Added e2e test to cover opening view, expansion state and data
  provision.
  • Loading branch information
oliver-sanders committed Aug 12, 2024
1 parent 42886c5 commit d6d9e10
Show file tree
Hide file tree
Showing 4 changed files with 351 additions and 1 deletion.
220 changes: 220 additions & 0 deletions cypress/component/info.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
/**
* Copyright (C) NIWA & British Crown (Met Office) & Contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import InfoComponent from '@/components/cylc/Info.vue'
import { Tokens } from '@/utils/uid'

const DESCRIPTION = `Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi.
`
const TOKENS = new Tokens('~user/workflow//1234/foo')
const TASK = {
id: TOKENS.id,
name: TOKENS.task,
tokens: TOKENS,
node: {
state: 'running',
task: {
meta: {
title: 'My Foo',
description: DESCRIPTION,
URL: 'https://cylc.org',
customMeta: {
answer: '42',
question: 'mutually exclusive',
}
}
},
prerequisites: [
{
satisfied: false,
expression: '(c0 & c1) | c2',
conditions: [
{
taskId: 'a',
message: 'succeeded',
reqState: 'succeeded',
exprAlias: 'c0',
satisfied: true,
},
{
taskId: 'b',
message: 'custom message',
reqState: 'custom_output',
exprAlias: 'c1',
satisfied: false,
},
{
taskId: 'a',
message: 'expired',
reqState: 'expired',
exprAlias: 'c2',
satisfied: false,
},
],
},
{
satisfied: true,
expression: 'c0',
conditions: [
{
taskId: 'x',
message: 'succeeded',
reqState: 'succeeded',
exprAlias: 'c0',
satisfied: true,
},
],
},
],
outputs: [
{
label: 'started',
message: 'started',
satisfied: true,
},
{
label: 'succeeded',
message: 'succeeded',
satisfied: false,
},
{
label: 'failed',
message: 'failed',
satisfied: false,
},
]
},
children: [
{
id: TOKENS.clone({ job: '01' }).id,
tokens: TOKENS.clone({ job: '01' }),
name: '01',
node: {
state: 'failed'
}
},
{
id: TOKENS.clone({ job: '02' }).id,
tokens: TOKENS.clone({ job: '02' }),
name: '02',
node: {
state: 'succeeded'
}
},
],
}

describe('Info component', () => {
it('displays task information', () => {
cy.vmount(InfoComponent, {
props: {
task: TASK,
class: 'job_theme--default',
// NOTE: expand all sections by default
panelExpansion: [0, 1, 2],
}
})

// there should be a task icon (running)
cy.get('.c-graph-node .c8-task.running').should('be.visible')

// and two job icons (succeeded & failed)
cy.get('.c-graph-node .c-job').should('have.length', 2)
.get('.c-graph-node .c-job .failed').should('be.visible')
.get('.c-graph-node .c-job .succeeded').should('be.visible')

// the metadata panel
cy.get('.metadata-panel.v-expansion-panel--active').should('be.visible')
.contains('My Foo')
.get('.metadata-panel') // the description should be displayed
.contains(/Lorem ipsum dolor sit amet.*/)
.get('.metadata-panel a:first') // the URL should be an anchor
.should('have.attr', 'href', 'https://cylc.org')
.contains(/^https:\/\/cylc.org$/)

// the prerequisites panel
cy.get('.prerequisites-panel.v-expansion-panel--active').should('be.visible')
.find('.prerequisite-alias.condition')
.should('have.length', 6)
.then((selector) => {
expect(selector[0]).to.contain('(c0 & c1) | c2')
expect(selector[0].classList.toString()).to.equal('prerequisite-alias condition')

expect(selector[0]).to.contain('c0')
expect(selector[1].classList.toString()).to.equal('prerequisite-alias condition satisfied')

expect(selector[0]).to.contain('c1')
expect(selector[2].classList.toString()).to.equal('prerequisite-alias condition')

expect(selector[0]).to.contain('c2')
expect(selector[3].classList.toString()).to.equal('prerequisite-alias condition')

expect(selector[0]).to.contain('c0')
expect(selector[4].classList.toString()).to.equal('prerequisite-alias condition satisfied')

expect(selector[0]).to.contain('c0')
expect(selector[5].classList.toString()).to.equal('prerequisite-alias condition satisfied')
})

// the outputs panel
cy.get('.outputs-panel.v-expansion-panel--active').should('be.visible')
.find('.condition')
.should('have.length', 3)
.then((selector) => {
expect(selector[0]).to.contain('started')
expect(selector[0].classList.toString()).to.equal('condition satisfied')

expect(selector[1]).to.contain('succeeded')
expect(selector[1].classList.toString()).to.equal('condition')

expect(selector[2]).to.contain('failed')
expect(selector[2].classList.toString()).to.equal('condition')
})
})

it('should expand sections as intended', () => {
const spy = cy.spy()
cy.vmount(InfoComponent, {
props: {
task: TASK,
class: 'job_theme--default'
},
listeners: {
'update:panelExpansion': spy,
}
}).as('wrapper')

// ONLY the metadata panel should be expanded by default
cy.get('.v-expansion-panel--active')
.should('have.length', 1)
.should('have.class', 'metadata-panel')

// the update:panelExpansion event should be emitted when a panel is
// expanded/collapsed
cy.get('.prerequisites-panel')
.find('button')
.should('be.visible')
.click({ force: true })
.get('@wrapper').then(({ wrapper }) => {
expect(
wrapper.emitted('update:panelExpansion')[0][0]
).to.deep.equal([0, 1])
})
})
})
4 changes: 3 additions & 1 deletion src/services/mock/json/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const { LogData } = require('./logData.cjs')
const { LogFiles } = require('./logFiles.cjs')
const analysisQuery = require('./analysisQuery.json')
const ganttQuery = require('./ganttQuery.json')
const InfoViewSubscription = require('./infoView.json')

const workflows = [workflowOne, ...workflowsMulti]
const analysisTaskQuery = analysisQuery.taskQuery
Expand All @@ -43,5 +44,6 @@ module.exports = {
analysisTaskQuery,
analysisJobQuery,
analysisQuery,
ganttQuery
ganttQuery,
InfoViewSubscription
}
81 changes: 81 additions & 0 deletions src/services/mock/json/infoView.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"deltas": {
"id": "~user/one",
"added": {
"taskProxies": [
{
"id": "~user/one//20000102T0000Z/failed",
"state": "failed",
"isHeld": false,
"isQueued": false,
"isRunahead": false,

"task": {
"meanElapsedTime": "10",
"meta": {
"title": "Failed Task",
"description": "A task that always fails!",
"URL": "https://cylc.org",
"userDefined": {
"my custom field": "My custom value!"
}
}
},

"jobs": [
{
"id": "~user/one//20000102T0000Z/failed/01",
"jobId": "1234",
"startedTime": 0,
"state": "failed"
}
],

"prerequisites": [
{
"satisfied": true,
"expression": "c0 & c1",
"conditions": [
{
"taskId": "20000102T0000Z/succeeded",
"reqState": "succeeded",
"expreAlias": "c0",
"satisfied": true
},
{
"taskId": "20000102T0000Z/eventually_succeeded",
"reqState": "succeeded",
"expreAlias": "c1",
"satisfied": true
}
]
}
],

"outputs": [
{
"label": "submitted",
"satisfied": true
},
{
"label": "started",
"satisfied": true
},
{
"label": "succeeded",
"satisfied": false
},
{
"label": "failed",
"satisfied": true
},
{
"label": "expired",
"satisfied": false
}
]
}
]
}
}
}
47 changes: 47 additions & 0 deletions tests/e2e/specs/info.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright (C) NIWA & British Crown (Met Office) & Contributors.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

describe('Info View', () => {
it('works', () => {
// test opening the "Info View" from a task in the "Tree View"
cy.visit('/#/workspace/one')
// click on task 20000102T0000Z/failed
.get('.c-treeitem .c-treeitem .c-treeitem:first')
.find('.c-task')
.click({ force: true })

// from the menu select the "Info" psudo-mutation
.get('.v-list > :nth-child(6)')
.contains('Info')
.click({ force: true })

// the info view should open
.get('.c-info').should('be.visible')

// the metadata panel should be expanded by default
.find('.v-expansion-panel--active')
.should('have.length', 1)
.should('have.class', 'metadata-panel')

// other panels should expand when clicked
.get('.c-info .v-expansion-panel:nth-child(2)')
.find('button')
.click({ force: true })
.get('.v-expansion-panel--active')
.should('have.length', 2)
})
})

0 comments on commit d6d9e10

Please sign in to comment.