From 81487c184d610def07fec4a8919f9be8f133c730 Mon Sep 17 00:00:00 2001 From: Jakob Vogelsang Date: Sat, 15 Oct 2022 22:20:29 +0200 Subject: [PATCH] feat(editors/communication): add GSE and SMV editor type elements (#1021) --- src/editors/communication/gse-editor.ts | 37 + src/editors/communication/smv-editor.ts | 37 + .../communication/subnetwork-editor.ts | 70 +- src/icons/icons.ts | 9 + ...work-editor-wizarding-editing.test.snap.js | 373 ---------- .../subnetwork-editor-wizarding.test.snap.js | 61 -- ...ubnetwork-editor-wizarding-editing.test.ts | 10 - .../subnetwork-editor-wizarding.test.ts | 13 +- .../testfiles/communication/communication.scd | 672 ++++++++++++++++++ .../conductingap-editor.test.snap.js | 2 +- .../__snapshots__/gse-editor.test.snap.js | 14 + .../__snapshots__/smv-editor.test.snap.js | 14 + .../subnetwork-editor.test.snap.js | 68 +- .../communication/conductingap-editor.test.ts | 8 +- .../editors/communication/gse-editor.test.ts | 23 + .../editors/communication/smv-editor.test.ts | 23 + .../communication/subnetwork-editor.test.ts | 108 +-- 17 files changed, 1031 insertions(+), 511 deletions(-) create mode 100644 src/editors/communication/gse-editor.ts create mode 100644 src/editors/communication/smv-editor.ts delete mode 100644 test/integration/editors/communication/__snapshots__/subnetwork-editor-wizarding-editing.test.snap.js delete mode 100644 test/integration/editors/communication/__snapshots__/subnetwork-editor-wizarding.test.snap.js create mode 100644 test/testfiles/communication/communication.scd create mode 100644 test/unit/editors/communication/__snapshots__/gse-editor.test.snap.js create mode 100644 test/unit/editors/communication/__snapshots__/smv-editor.test.snap.js create mode 100644 test/unit/editors/communication/gse-editor.test.ts create mode 100644 test/unit/editors/communication/smv-editor.test.ts diff --git a/src/editors/communication/gse-editor.ts b/src/editors/communication/gse-editor.ts new file mode 100644 index 0000000000..c40193dcf3 --- /dev/null +++ b/src/editors/communication/gse-editor.ts @@ -0,0 +1,37 @@ +import { + LitElement, + TemplateResult, + html, + customElement, + property, + state, +} from 'lit-element'; + +import '@material/mwc-icon'; + +import '../../action-icon.js'; +import { sizableGooseIcon } from '../../icons/icons.js'; + +@customElement('gse-editor') +export class GseEditor extends LitElement { + @property({ attribute: false }) + doc!: XMLDocument; + + @property({ attribute: false }) + element!: Element; + + @state() + get label(): string { + return ( + this.element.getAttribute('ldInst') + + '/' + + this.element.getAttribute('cbName') + ); + } + + render(): TemplateResult { + return html`${sizableGooseIcon}`; + } +} diff --git a/src/editors/communication/smv-editor.ts b/src/editors/communication/smv-editor.ts new file mode 100644 index 0000000000..90b7431633 --- /dev/null +++ b/src/editors/communication/smv-editor.ts @@ -0,0 +1,37 @@ +import { + LitElement, + TemplateResult, + html, + customElement, + property, + state, +} from 'lit-element'; + +import '@material/mwc-icon'; + +import '../../action-icon.js'; +import { sizableSmvIcon } from '../../icons/icons.js'; + +@customElement('smv-editor') +export class SmvEditor extends LitElement { + @property({ attribute: false }) + doc!: XMLDocument; + + @property({ attribute: false }) + element!: Element; + + @state() + get label(): string { + return ( + this.element.getAttribute('ldInst') + + '/' + + this.element.getAttribute('cbName') + ); + } + + render(): TemplateResult { + return html`${sizableSmvIcon} + `; + } +} diff --git a/src/editors/communication/subnetwork-editor.ts b/src/editors/communication/subnetwork-editor.ts index 176ffd8381..8ba1a00765 100644 --- a/src/editors/communication/subnetwork-editor.ts +++ b/src/editors/communication/subnetwork-editor.ts @@ -11,6 +11,8 @@ import { translate } from 'lit-translate'; import '@material/mwc-icon-button'; import './connectedap-editor.js'; +import './gse-editor.js'; +import './smv-editor.js'; import { newWizardEvent, newActionEvent, @@ -75,6 +77,50 @@ export class SubNetworkEditor extends LitElement { ); } + private renderSmvEditors(iedName: string): TemplateResult[] { + return Array.from( + this.element + .closest('Communication') + ?.querySelectorAll(`ConnectedAP[iedName="${iedName}"] > SMV`) ?? [] + ).map( + smv => html`` + ); + } + + private renderGseEditors(iedName: string): TemplateResult[] { + return Array.from( + this.element + .closest('Communication') + ?.querySelectorAll(`ConnectedAP[iedName="${iedName}"] > GSE`) ?? [] + ).map( + gse => html`` + ); + } + + private renderConnectedApEditors(iedName: string): TemplateResult[] { + return Array.from( + this.element.parentElement?.querySelectorAll( + `:scope > SubNetwork > ConnectedAP[iedName="${iedName}"]` + ) ?? [] + ).map( + connectedAP => + html`` + ); + } + private renderIEDs(): TemplateResult[] { return Array.from(this.element.querySelectorAll(':scope > ConnectedAP')) .map(connAP => connAP.getAttribute('iedName')!) @@ -82,19 +128,9 @@ export class SubNetworkEditor extends LitElement { .sort(compareNames) .map( iedName => html` - ${Array.from( - this.element.parentElement?.querySelectorAll( - `:scope > SubNetwork > ConnectedAP[iedName="${iedName}"]` - ) ?? [] - ).map( - connectedAP => - html`` - )} + ${this.renderConnectedApEditors(iedName)}${this.renderGseEditors( + iedName + )}${this.renderSmvEditors(iedName)} ` ); } @@ -149,6 +185,14 @@ export class SubNetworkEditor extends LitElement { display: none; } + #iedSection:not(:focus):not(:focus-within) gse-editor { + display: none; + } + + #iedSection:not(:focus):not(:focus-within) smv-editor { + display: none; + } + #iedSection .disabled { pointer-events: none; opacity: 0.5; diff --git a/src/icons/icons.ts b/src/icons/icons.ts index 38f8a7080d..7d600bd545 100644 --- a/src/icons/icons.ts +++ b/src/icons/icons.ts @@ -676,3 +676,12 @@ export const openSCDIcon = html` `; + +export const sizableSmvIcon = svg` + + + `; + +export const sizableGooseIcon = svg` + +`; diff --git a/test/integration/editors/communication/__snapshots__/subnetwork-editor-wizarding-editing.test.snap.js b/test/integration/editors/communication/__snapshots__/subnetwork-editor-wizarding-editing.test.snap.js deleted file mode 100644 index 46a28a2e1e..0000000000 --- a/test/integration/editors/communication/__snapshots__/subnetwork-editor-wizarding-editing.test.snap.js +++ /dev/null @@ -1,373 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["subnetwork-editor wizarding editing integration edit wizard changes name attribute on primary action"] = -` - - - - - - - - - - - - -
- - - - -
-
-`; -/* end snapshot subnetwork-editor wizarding editing integration edit wizard changes name attribute on primary action */ - -snapshots["subnetwork-editor wizarding editing integration edit wizard changes desc attribute on primary action"] = -` - - - - - - - - - - - - -
- - - - -
-
-`; -/* end snapshot subnetwork-editor wizarding editing integration edit wizard changes desc attribute on primary action */ - -snapshots["subnetwork-editor wizarding editing integration edit wizard deletes desc attribute if wizard-textfield is deactivated"] = -` - - - - - - - - - - - - -
- - - - -
-
-`; -/* end snapshot subnetwork-editor wizarding editing integration edit wizard deletes desc attribute if wizard-textfield is deactivated */ - -snapshots["subnetwork-editor wizarding editing integration edit wizard changes type attribute on primary action"] = -` - - - - - - - - - - - - -
- - - - -
-
-`; -/* end snapshot subnetwork-editor wizarding editing integration edit wizard changes type attribute on primary action */ - -snapshots["subnetwork-editor wizarding editing integration edit wizard deletes type attribute if wizard-textfield is deactivated"] = -` - - - - - - - - - - - - -
- - - - -
-
-`; -/* end snapshot subnetwork-editor wizarding editing integration edit wizard deletes type attribute if wizard-textfield is deactivated */ - -snapshots["subnetwork-editor wizarding editing integration edit wizard changes BitRate value on primary action"] = -` - - - - - - - - - - - - -
- - - - -
-
-`; -/* end snapshot subnetwork-editor wizarding editing integration edit wizard changes BitRate value on primary action */ - -snapshots["subnetwork-editor wizarding editing integration edit wizard changes BitRate multiplier on primary action"] = -` - - - - - - - - - - - - -
- - - - -
-
-`; -/* end snapshot subnetwork-editor wizarding editing integration edit wizard changes BitRate multiplier on primary action */ - -snapshots["subnetwork-editor wizarding editing integration edit wizard deletes BitRate element if voltage wizard-textfield is deactivated"] = -` - - - - - - - - - - - - -
- - - - -
-
-`; -/* end snapshot subnetwork-editor wizarding editing integration edit wizard deletes BitRate element if voltage wizard-textfield is deactivated */ - -snapshots["subnetwork-editor wizarding editing integration remove action removes SubNetwork on clicking delete button"] = -` - - - - - - - - - - - - -
- - - - -
-
-`; -/* end snapshot subnetwork-editor wizarding editing integration remove action removes SubNetwork on clicking delete button */ - -snapshots["subnetwork-editor wizarding editing integration add ConnectedAP action add ConnectedAP on primary action"] = -` - - - - - - - - - - - - -
- - - - -
-
-`; -/* end snapshot subnetwork-editor wizarding editing integration add ConnectedAP action add ConnectedAP on primary action */ - diff --git a/test/integration/editors/communication/__snapshots__/subnetwork-editor-wizarding.test.snap.js b/test/integration/editors/communication/__snapshots__/subnetwork-editor-wizarding.test.snap.js deleted file mode 100644 index e18e5824fa..0000000000 --- a/test/integration/editors/communication/__snapshots__/subnetwork-editor-wizarding.test.snap.js +++ /dev/null @@ -1,61 +0,0 @@ -/* @web/test-runner snapshot v1 */ -export const snapshots = {}; - -snapshots["subnetwork-editor wizarding integration edit/add Subnetwork wizard looks like the latest snapshot"] = -` -
- - - - - - - - -
- - - - -
-`; -/* end snapshot subnetwork-editor wizarding integration edit/add Subnetwork wizard looks like the latest snapshot */ - diff --git a/test/integration/editors/communication/subnetwork-editor-wizarding-editing.test.ts b/test/integration/editors/communication/subnetwork-editor-wizarding-editing.test.ts index 402455457f..afcdc8a1e1 100644 --- a/test/integration/editors/communication/subnetwork-editor-wizarding-editing.test.ts +++ b/test/integration/editors/communication/subnetwork-editor-wizarding-editing.test.ts @@ -86,7 +86,6 @@ describe('subnetwork-editor wizarding editing integration', () => { expect(doc.querySelector('SubNetwork')?.getAttribute('name')).to.equal( 'newSubNetwork' ); - await expect(element).shadowDom.to.equalSnapshot(); }); it('changes desc attribute on primary action', async () => { @@ -96,7 +95,6 @@ describe('subnetwork-editor wizarding editing integration', () => { expect(doc.querySelector('SubNetwork')?.getAttribute('desc')).to.equal( 'newDesc' ); - await expect(element).shadowDom.to.equalSnapshot(); }); it('deletes desc attribute if wizard-textfield is deactivated', async () => { @@ -106,7 +104,6 @@ describe('subnetwork-editor wizarding editing integration', () => { primaryAction.click(); await parent.updateComplete; expect(doc.querySelector('SubNetwork')?.getAttribute('desc')).to.be.null; - await expect(element).shadowDom.to.equalSnapshot(); }); it('changes type attribute on primary action', async () => { @@ -116,7 +113,6 @@ describe('subnetwork-editor wizarding editing integration', () => { expect(doc.querySelector('SubNetwork')?.getAttribute('type')).to.equal( 'newType' ); - await expect(element).shadowDom.to.equalSnapshot(); }); it('deletes type attribute if wizard-textfield is deactivated', async () => { @@ -126,7 +122,6 @@ describe('subnetwork-editor wizarding editing integration', () => { primaryAction.click(); await parent.updateComplete; expect(doc.querySelector('SubNetwork')?.getAttribute('type')).to.be.null; - await expect(element).shadowDom.to.equalSnapshot(); }); it('changes BitRate value on primary action', async () => { @@ -134,7 +129,6 @@ describe('subnetwork-editor wizarding editing integration', () => { primaryAction.click(); await parent.updateComplete; expect(doc.querySelector('BitRate')?.innerHTML).to.equal('20.0'); - await expect(element).shadowDom.to.equalSnapshot(); }); it('changes BitRate multiplier on primary action', async () => { @@ -147,7 +141,6 @@ describe('subnetwork-editor wizarding editing integration', () => { expect(doc.querySelector('BitRate')?.getAttribute('unit')).to.equal( 'b/s' ); - await expect(element).shadowDom.to.equalSnapshot(); }); it('deletes BitRate element if voltage wizard-textfield is deactivated', async () => { @@ -158,7 +151,6 @@ describe('subnetwork-editor wizarding editing integration', () => { await parent.updateComplete; expect(doc.querySelector('SubNetwork')?.querySelector('BitRate')).to.be .null; - await expect(element).shadowDom.to.equalSnapshot(); }); }); describe('remove action', () => { @@ -194,7 +186,6 @@ describe('subnetwork-editor wizarding editing integration', () => { deleteButton.click(); await parent.updateComplete; expect(doc.querySelector('SubNetwork[name="StationBus"]')).to.not.exist; - await expect(element).shadowDom.to.equalSnapshot(); }); }); @@ -256,7 +247,6 @@ describe('subnetwork-editor wizarding editing integration', () => { ':root > Communication > SubNetwork[name="StationBus"] > ConnectedAP[iedName="IED3"][apName="P2"]' ) ).to.exist; - await expect(element).shadowDom.to.equalSnapshot(); }); }); }); diff --git a/test/integration/editors/communication/subnetwork-editor-wizarding.test.ts b/test/integration/editors/communication/subnetwork-editor-wizarding.test.ts index cdad21dd49..ce29be94fe 100644 --- a/test/integration/editors/communication/subnetwork-editor-wizarding.test.ts +++ b/test/integration/editors/communication/subnetwork-editor-wizarding.test.ts @@ -16,6 +16,7 @@ describe('subnetwork-editor wizarding integration', () => { doc = await fetch('/test/testfiles/valid2007B4.scd') .then(response => response.text()) .then(str => new DOMParser().parseFromString(str, 'application/xml')); + parent = ( await fixture( html` { )).click(); await parent.updateComplete; }); - it('looks like the latest snapshot', async () => { - await expect(parent.wizardUI.dialog).to.equalSnapshot(); - }); + describe('the first input element', () => { it('edits the attribute name', async () => { expect(parent.wizardUI.inputs[0].label).to.equal('name'); }); + it('edits only for valid inputs', async () => { await fc.assert( fc.asyncProperty(regexString(regExp.tName, 1), async name => { @@ -51,10 +51,12 @@ describe('subnetwork-editor wizarding integration', () => { ); }); }); + describe('the second input element', () => { it('edits the attribute desc', async () => { expect(parent.wizardUI.inputs[1].label).to.equal('desc'); }); + it('edits only for valid inputs', async () => { await fc.assert( fc.asyncProperty(regexString(regExp.desc), async desc => { @@ -65,10 +67,12 @@ describe('subnetwork-editor wizarding integration', () => { ); }); }); + describe('the third input element', () => { it('edits the attribute type', async () => { expect(parent.wizardUI.inputs[2].label).to.equal('type'); }); + it('edits only for valid inputs', async () => { await fc.assert( fc.asyncProperty(regexString(regExp.desc, 1), async type => { @@ -79,10 +83,12 @@ describe('subnetwork-editor wizarding integration', () => { ); }); }); + describe('the fourth input element', () => { it('edits the attribute ', async () => { expect(parent.wizardUI.inputs[3].label).to.equal('BitRate'); }); + it('edits only for valid inputs', async () => { await fc.assert( fc.asyncProperty(regexString(regExp.decimal), async BitRate => { @@ -92,6 +98,7 @@ describe('subnetwork-editor wizarding integration', () => { }) ); }); + it('rejects edition for invalid inputs', async () => { await fc.assert( fc.asyncProperty( diff --git a/test/testfiles/communication/communication.scd b/test/testfiles/communication/communication.scd new file mode 100644 index 0000000000..a10970eb83 --- /dev/null +++ b/test/testfiles/communication/communication.scd @@ -0,0 +1,672 @@ + + +
+ + + 110 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100.0 + +
+

192.168.210.111

+
+ +
+

01-0C-CD-01-00-00

+

0000

+
+
+
+
+ + 100 + +
+

192.168.210.113

+
+ +
+

01-0C-CD-04-00-01

+

4002

+
+
+
+ +
+

192.168.210.115

+
+ +
+

01-0C-CD-01-00-01

+

0001

+
+
+
+
+ + 100 + +
+

192.168.210.117

+
+ +
+

01-0C-CD-04-00-00

+

4000

+
+
+ +
+

01-0C-CD-04-00-02

+

4001

+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + status-only + + + + + + + + status-only + + + + + + + + + + + + + + + sbo-with-enhanced-security + + + 30000 + + + 600 + + + + + + + + + + + + + + + + + + + + + + + + + IEC 61850-7-4:2007B4 + + + + + + + + + + + + + + + + + + + sbo-with-enhanced-security + + + 30000 + + + 600 + + + + + + + + + + + + IEC 61850-8-1:2003 + + + + + + + A + + + + + 0.01 + + + 0 + + + + + Hz + + + + + + + + + A + + + + + 0.001 + + + 0 + + + + + + + + + + + + + + + + + IEC 61850-8-1:2003 + + + + + + + + + + + + + + IEC 61850-8-1:2003 + + + + + + + + + IEC 61850-8-1:2003 + + + + + + + y + z + a + f + p + n + µ + m + c + d + + da + h + k + M + G + T + P + E + Z + Y + + + + m + kg + s + A + K + mol + cd + deg + rad + sr + Gy + Bq + °C + Sv + F + C + S + H + V + ohm + J + N + Hz + lx + Lm + Wb + T + W + Pa + + + m/s + m/s² + m³/s + m/m³ + M + kg/m³ + m²/s + W/m K + J/K + ppm + 1/s + rad/s + W/m² + J/m² + S/m + K/s + Pa/s + J/kg K + VA + Watts + VAr + phi + cos(phi) + Vs + + As + + A²t + VAh + Wh + VArh + V/Hz + Hz/s + char + char/s + kgm² + dB + J/Wh + W/s + l/s + dBm + h + min + Ohm/m + percent/s + + + Load Break + Disconnector + Earthing Switch + High Speed Earthing Switch + + + status-only + + + pulse + persistent + persistent-feedback + + + Ok + Warning + Alarm + + + status-only + direct-with-normal-security + sbo-with-normal-security + direct-with-enhanced-security + sbo-with-enhanced-security + + + on + blocked + test + test/blocked + off + + + not-supported + bay-control + station-control + remote-control + automatic-bay + automatic-station + automatic-remote + maintenance + process + + + diff --git a/test/unit/editors/communication/__snapshots__/conductingap-editor.test.snap.js b/test/unit/editors/communication/__snapshots__/conductingap-editor.test.snap.js index 532ea49c4c..729f529150 100644 --- a/test/unit/editors/communication/__snapshots__/conductingap-editor.test.snap.js +++ b/test/unit/editors/communication/__snapshots__/conductingap-editor.test.snap.js @@ -4,7 +4,7 @@ export const snapshots = {}; snapshots["A component to visualize SCL element ConnectedAP looks like the latest snapshot"] = ` + + + +`; +/* end snapshot Editor web component for GSE element looks like its latest snapshot */ + diff --git a/test/unit/editors/communication/__snapshots__/smv-editor.test.snap.js b/test/unit/editors/communication/__snapshots__/smv-editor.test.snap.js new file mode 100644 index 0000000000..0a6d050e00 --- /dev/null +++ b/test/unit/editors/communication/__snapshots__/smv-editor.test.snap.js @@ -0,0 +1,14 @@ +/* @web/test-runner snapshot v1 */ +export const snapshots = {}; + +snapshots["Editor web component for SMV element looks like its latest snapshot"] = +` + + + +`; +/* end snapshot Editor web component for SMV element looks like its latest snapshot */ + diff --git a/test/unit/editors/communication/__snapshots__/subnetwork-editor.test.snap.js b/test/unit/editors/communication/__snapshots__/subnetwork-editor.test.snap.js index 0d24a34c4e..032cd7faa1 100644 --- a/test/unit/editors/communication/__snapshots__/subnetwork-editor.test.snap.js +++ b/test/unit/editors/communication/__snapshots__/subnetwork-editor.test.snap.js @@ -1,7 +1,7 @@ /* @web/test-runner snapshot v1 */ export const snapshots = {}; -snapshots["subnetwork-editor looks like the latest snapshot"] = +snapshots["subnetwork-editor with child GSE elements looks like the latest snapshot"] = ` + + + + `; -/* end snapshot subnetwork-editor looks like the latest snapshot */ +/* end snapshot subnetwork-editor with child GSE elements looks like the latest snapshot */ + +snapshots["subnetwork-editor with child SMV elements looks like the latest snapshot"] = +` + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
+
+`; +/* end snapshot subnetwork-editor with child SMV elements looks like the latest snapshot */ diff --git a/test/unit/editors/communication/conductingap-editor.test.ts b/test/unit/editors/communication/conductingap-editor.test.ts index 50963e44d7..42e14753b5 100644 --- a/test/unit/editors/communication/conductingap-editor.test.ts +++ b/test/unit/editors/communication/conductingap-editor.test.ts @@ -13,9 +13,10 @@ describe('A component to visualize SCL element ConnectedAP', () => { let actionEvent: SinonSpy; beforeEach(async () => { - validSCL = await fetch('/test/testfiles/valid2007B4.scd') + validSCL = await fetch('/test/testfiles/communication/communication.scd') .then(response => response.text()) .then(str => new DOMParser().parseFromString(str, 'application/xml')); + element = ( await fixture( html` { window.addEventListener('editor-action', actionEvent); }); - it('looks like the latest snapshot', async () => { - await expect(element).shadowDom.to.equalSnapshot(); - }); + it('looks like the latest snapshot', async () => + await expect(element).shadowDom.to.equalSnapshot()); it('renders label UNDEFINED in case ConnectedAP apName attribute is missing', async () => { const connAp = validSCL.querySelector('ConnectedAP'); diff --git a/test/unit/editors/communication/gse-editor.test.ts b/test/unit/editors/communication/gse-editor.test.ts new file mode 100644 index 0000000000..a15ebb31ad --- /dev/null +++ b/test/unit/editors/communication/gse-editor.test.ts @@ -0,0 +1,23 @@ +import { expect, fixture, html } from '@open-wc/testing'; + +import '../../../../src/editors/communication/gse-editor.js'; +import { GseEditor } from '../../../../src/editors/communication/gse-editor.js'; + +describe('Editor web component for GSE element', () => { + let element: GseEditor; + + beforeEach(async () => { + const doc = await fetch('/test/testfiles/communication/communication.scd') + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')); + + const gse = doc.querySelector('GSE')!; + + element = await fixture( + html`` + ); + }); + + it('looks like its latest snapshot', async () => + await expect(element).shadowDom.to.equalSnapshot()); +}); diff --git a/test/unit/editors/communication/smv-editor.test.ts b/test/unit/editors/communication/smv-editor.test.ts new file mode 100644 index 0000000000..ff97f3f025 --- /dev/null +++ b/test/unit/editors/communication/smv-editor.test.ts @@ -0,0 +1,23 @@ +import { expect, fixture, html } from '@open-wc/testing'; + +import '../../../../src/editors/communication/smv-editor.js'; +import { SmvEditor } from '../../../../src/editors/communication/smv-editor.js'; + +describe('Editor web component for SMV element', () => { + let element: SmvEditor; + + beforeEach(async () => { + const doc = await fetch('/test/testfiles/communication/communication.scd') + .then(response => response.text()) + .then(str => new DOMParser().parseFromString(str, 'application/xml')); + + const smv = doc.querySelector('SMV')!; + + element = await fixture( + html`` + ); + }); + + it('looks like its latest snapshot', async () => + await expect(element).shadowDom.to.equalSnapshot()); +}); diff --git a/test/unit/editors/communication/subnetwork-editor.test.ts b/test/unit/editors/communication/subnetwork-editor.test.ts index 3d265b8ba5..197ad8ebb4 100644 --- a/test/unit/editors/communication/subnetwork-editor.test.ts +++ b/test/unit/editors/communication/subnetwork-editor.test.ts @@ -4,68 +4,90 @@ import '../../../../src/editors/communication/subnetwork-editor.js'; import { SubNetworkEditor } from '../../../../src/editors/communication/subnetwork-editor.js'; describe('subnetwork-editor', () => { + let doc: XMLDocument; let element: SubNetworkEditor; let subNetwork: Element; beforeEach(async () => { - const validSCL = await fetch('/test/testfiles/communication.scd') + doc = await fetch('/test/testfiles/communication/communication.scd') .then(response => response.text()) .then(str => new DOMParser().parseFromString(str, 'application/xml')); - - subNetwork = validSCL.querySelector('SubNetwork')!; - element = ( - await fixture( - html`` - ) - ); }); - it('has a name property', () => - expect(element).to.have.property('name', 'StationBus')); + describe('with child GSE elements', () => { + beforeEach(async () => { + subNetwork = doc.querySelector('SubNetwork[name="StationBus"]')!; + element = ( + await fixture( + html`` + ) + ); + }); - it('indicates missing required name as UNDEFINED', async () => { - subNetwork.removeAttribute('name'); - await element.requestUpdate(); + it('looks like the latest snapshot', async () => + await expect(element).shadowDom.to.equalSnapshot()); - expect(element).to.have.property('name', 'UNDEFINED'); - }); + it('has a name property', () => + expect(element).to.have.property('name', 'StationBus')); - it('has a desc property', () => - expect(element).to.have.property('desc', 'desc')); + it('indicates missing required name as UNDEFINED', async () => { + subNetwork.removeAttribute('name'); + await element.requestUpdate(); - it('has a type property', () => - expect(element).to.have.property('type', '8-MMS')); + expect(element).to.have.property('name', 'UNDEFINED'); + }); - it('return null with missing type attribute', async () => { - subNetwork.removeAttribute('type'); - await element.requestUpdate(); + it('has a desc property', () => + expect(element).to.have.property('desc', 'desc')); - expect(element).to.have.property('type', null); - }); + it('has a type property', () => + expect(element).to.have.property('type', '8-MMS')); - it('has a BitRate property', () => - expect(element).to.have.property('bitrate', '100.0 b/s')); + it('return null with missing type attribute', async () => { + subNetwork.removeAttribute('type'); + await element.requestUpdate(); - it('includes multiplier to bitrate property', async () => { - const bitrate = subNetwork.querySelector('BitRate'); - bitrate?.setAttribute('multiplier', 'M'); - await element.requestUpdate(); + expect(element).to.have.property('type', null); + }); - expect(element).to.have.property('bitrate', '100.0 Mb/s'); - }); + it('has a BitRate property', () => + expect(element).to.have.property('bitrate', '100.0 b/s')); - it('returns null with missing BitRate content event though BitRate exist as element', async () => { - const bitrate = subNetwork.querySelector('BitRate'); - bitrate!.textContent = null; - bitrate?.setAttribute('multiplier', 'M'); - await element.requestUpdate(); + it('includes multiplier to bitrate property', async () => { + const bitrate = subNetwork.querySelector('BitRate'); + bitrate?.setAttribute('multiplier', 'M'); + await element.requestUpdate(); - expect(element).to.have.property('bitrate', null); + expect(element).to.have.property('bitrate', '100.0 Mb/s'); + }); + + it('returns null with missing BitRate content event though BitRate exist as element', async () => { + const bitrate = subNetwork.querySelector('BitRate'); + bitrate!.textContent = null; + bitrate?.setAttribute('multiplier', 'M'); + await element.requestUpdate(); + + expect(element).to.have.property('bitrate', null); + }); }); - it('looks like the latest snapshot', async () => - await expect(element).shadowDom.to.equalSnapshot()); + describe('with child SMV elements', () => { + beforeEach(async () => { + subNetwork = doc.querySelector('SubNetwork[name="ProcessBus1"]')!; + element = ( + await fixture( + html`` + ) + ); + }); + + it('looks like the latest snapshot', async () => + await expect(element).shadowDom.to.equalSnapshot()); + }); });