diff --git a/package-lock.json b/package-lock.json index f465fa8..122a0b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65,6 +65,7 @@ "karma-webpack": "^5.0.1", "mocha": "^10.8.2", "mocha-test-container-support": "^0.2.0", + "modeler-moddle": "^0.2.0", "npm-run-all2": "^7.0.0", "puppeteer": "^23.7.0", "raw-loader": "^4.0.2", @@ -7376,7 +7377,8 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/modeler-moddle/-/modeler-moddle-0.2.0.tgz", "integrity": "sha512-l8OUpvX94m3spe+RBwWFQ0bGvPBZ3FBCiSY3yNtDk52j0YRj+cnVOxTMQvVM+i6k1T326IfqYM3F9HJfPZtXRw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/mri": { "version": "1.2.0", diff --git a/package.json b/package.json index ccd72ad..bf5abce 100644 --- a/package.json +++ b/package.json @@ -116,6 +116,7 @@ "karma-webpack": "^5.0.1", "mocha": "^10.8.2", "mocha-test-container-support": "^0.2.0", + "modeler-moddle": "^0.2.0", "npm-run-all2": "^7.0.0", "puppeteer": "^23.7.0", "raw-loader": "^4.0.2", diff --git a/test/spec/Example.spec.js b/test/spec/Example.spec.js index 736c788..93aec03 100644 --- a/test/spec/Example.spec.js +++ b/test/spec/Example.spec.js @@ -38,7 +38,7 @@ import CamundaBehaviorsModule from 'camunda-bpmn-js-behaviors/lib/camunda-platfo import ZeebeBehaviorsModule from 'camunda-bpmn-js-behaviors/lib/camunda-cloud'; import CamundaModdle from 'camunda-bpmn-moddle/resources/camunda'; - +import ModelerModdle from 'modeler-moddle/resources/modeler'; import ZeebeModdle from 'zeebe-bpmn-moddle/resources/zeebe'; import CloudElementTemplatesPropertiesProviderModule from 'src/cloud-element-templates'; @@ -50,7 +50,8 @@ const singleStart = window.__env__ && window.__env__.SINGLE_START; insertCoreStyles(); insertBpmnStyles(); -insertCSS('bottom-panel.css', ` + +insertCSS('example.css', ` .test-container { display: flex; flex-direction: column; @@ -75,22 +76,30 @@ insertCSS('bottom-panel.css', ` display: flex; flex-direction: column; background-color: #f7f7f8; - padding: 5px; box-sizing: border-box; border-top: solid 1px #ccc; font-family: sans-serif; } - .panel .errors { + .panel .errorContainer { resize: none; flex-grow: 1; background-color: #f7f7f8; border: none; - margin-bottom: 5px; + padding: 5px; font-family: sans-serif; line-height: 1.5; outline: none; - overflow-y: scroll; + overflow: auto; + } + + .panel .errorItem { + cursor: pointer; + } + + .panel .footerContainer { + border-top: solid 1px #ccc; + padding: 5px; } .panel button, @@ -100,6 +109,34 @@ insertCSS('bottom-panel.css', ` `); +const ChangeEnginesModule = { + + __init__: [ function(bpmnjs, eventBus, elementTemplates) { + + eventBus.on([ + 'import.done', + 'elements.changed' + ], function() { + const executionPlatformVersion = bpmnjs.getDefinitions().get('executionPlatformVersion'); + + elementTemplates.setEngines({ + camunda: executionPlatformVersion + }); + }); + } ] +}; + +const LogTemplateErrorsModule = { + + __init__: [ function(eventBus) { + + eventBus.on('elementTemplates.errors', function({ errors }) { + console.error('element template parse errors', errors); + }); + } ] +}; + + describe('', function() { let modelerContainer; @@ -133,7 +170,8 @@ describe('', function() { LintingModule ], moddleExtensions = { - zeebe: ZeebeModdle + zeebe: ZeebeModdle, + modeler: ModelerModdle }, propertiesPanel = {}, description = {}, @@ -197,10 +235,13 @@ describe('', function() { ElementTemplatesIconsRenderer, CreateAppendAnythingModule, CreateAppendElementTemplatesModule, + ChangeEnginesModule, + LogTemplateErrorsModule, LintingModule ], moddleExtensions: { - zeebe: ZeebeModdle + zeebe: ZeebeModdle, + modeler: ModelerModdle }, propertiesPanel: { parent: null @@ -212,71 +253,11 @@ describe('', function() { } ); - const modeler = result.modeler; - - const linter = new Linter({ - plugins: [ - ElementTemplateLinterPlugin(elementTemplates) - ] - - }); - - const linting = modeler.get('linting'); - const bpmnjs = modeler.get('bpmnjs'); - const eventBus = modeler.get('eventBus'); - - const lint = () => { - const definitions = bpmnjs.getDefinitions(); - - linter.lint(definitions).then(reports => { - linting.setErrors(reports); - - const errorContainer = panel.querySelector('.errors'); - errorContainer.innerHTML = ''; - - reports.forEach((report) => { - let { id, message, node, data } = report; - node = node || (data && data.node); - const name = node && node.name; - - const errorMessage = `${ name || id }: ${ message }`; - const item = domify(`
${escapeHtml(errorMessage)}
`); - item.addEventListener('click', () => { - linting.showError(report); - }); - - errorContainer.appendChild(item); - }); - }); - }; - - lint(); - - eventBus.on('elements.changed', lint); - linting.activate(); - - const propertiesPanelParent = domify('
'); - - bpmnjs._container.appendChild(propertiesPanelParent); - - modeler.get('propertiesPanel').attachTo(propertiesPanelParent); - - const panel = domify(` -
-
-
- - - -
-
- `); - - bpmnjs._container.appendChild(panel); - - // then expect(result.error).not.to.exist; + + // and + createTestUI(result.modeler); }); @@ -301,28 +282,117 @@ describe('', function() { ElementTemplatesPropertiesProviderModule ], moddleExtensions: { - camunda: CamundaModdle + camunda: CamundaModdle, + modeler: ModelerModdle }, elementTemplates } ); - const modeler = result.modeler; - const bpmnjs = modeler.get('bpmnjs'); - const propertiesPanelParent = domify('
'); - - bpmnjs._container.appendChild(propertiesPanelParent); - - modeler.get('propertiesPanel').attachTo(propertiesPanelParent); - - // then expect(result.error).not.to.exist; + + // and then + createTestUI(result.modeler); }); }); -const escapeHtml = (unsafe) => { +function escapeHTML(unsafe) { return unsafe.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"').replaceAll("'", '''); -}; +} + +function createTestUI(modeler) { + + const linting = modeler.get('linting', false); + const elementTemplates = modeler.get('elementTemplates', false); + const propertiesPanel = modeler.get('propertiesPanel', false); + + const canvas = modeler.get('canvas'); + const modeling = modeler.get('modeling'); + const bpmnjs = modeler.get('bpmnjs'); + const eventBus = modeler.get('eventBus'); + + const container = bpmnjs._container; + + if (propertiesPanel) { + + const propertiesPanelParent = domify('
'); + + container.appendChild(propertiesPanelParent); + + propertiesPanel.attachTo(propertiesPanelParent); + } + + if (linting && elementTemplates) { + const linter = new Linter({ + plugins: [ + ElementTemplateLinterPlugin(elementTemplates.getAll()) + ] + }); + + const linterPanel = domify(` +
+
+
+ + +
+
+ `); + + container.appendChild(linterPanel); + + linterPanel.querySelector('input').value = bpmnjs.getDefinitions().get('executionPlatformVersion'); + + linterPanel.querySelector('input').addEventListener('input', ({ target }) => { + modeling.updateModdleProperties( + canvas.getRootElement(), + bpmnjs.getDefinitions(), + { executionPlatformVersion: target.value } + ); + }); + + const lint = () => { + const definitions = bpmnjs.getDefinitions(); + + linter.lint(definitions).then(reports => { + linting.setErrors(reports); + + const errorContainer = linterPanel.querySelector('.errorContainer'); + errorContainer.innerHTML = ''; + + reports.map((report) => { + const { id, message, category, rule, documentation } = report; + + if (category === 'rule-error') { + return domify(`
${ category } Rule <${ escapeHTML(rule) }> errored with the following message: ${ escapeHTML(message) }
`); + } + + const element = domify(`
${ category } ${ id }: ${escapeHTML(message) }
`); + + if (documentation.url) { + const documentationLink = domify(`ref`); + + documentationLink.addEventListener('click', e => e.stopPropagation()); + + element.appendChild(documentationLink); + } + + element.addEventListener('click', () => { + linting.showError(report); + }); + + return element; + }).forEach(item => errorContainer.appendChild(item)); + }); + }; + + linting.activate(); + + lint(); + + eventBus.on('elements.changed', lint); + } +} \ No newline at end of file diff --git a/test/spec/cloud-element-templates/fixtures/engines.json b/test/spec/cloud-element-templates/fixtures/engines.json new file mode 100644 index 0000000..edc5e7a --- /dev/null +++ b/test/spec/cloud-element-templates/fixtures/engines.json @@ -0,0 +1,88 @@ +[ + { + "$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", + "id": "example.engines.test.multiple", + "name": " Test - Multiple", + "description": "does not match , if explicit =1> is provided", + "version": 2, + "engines": { + "camunda": "^8.6", + "webModeler": "^4.1", + "desktopModeler": "^0" + }, + "appliesTo": [ + "bpmn:Task" + ], + "properties": [] + }, + { + "$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", + "id": "example.engines.test.multiple", + "name": " Test - Multiple", + "description": "matches when compatible and/or run-time is indicated, or properties are not provided", + "version": 1, + "engines": { + "camunda": "^8.6", + "webModeler": "^4.1" + }, + "appliesTo": [ + "bpmn:Task" + ], + "properties": [] + }, + + { + "$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", + "id": "example.engines.test.basic", + "name": " Test - Basic", + "description": "matches when compatible run-time is indicated, or property is not provided", + "version": 3, + "engines": { + "camunda": "^8.6" + }, + "appliesTo": [ + "bpmn:Task" + ], + "properties": [] + }, + { + "$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", + "id": "example.engines.test.basic", + "name": " Test - Basic", + "description": "matches when compatible run-time is indicated, or property is not provided", + "version": 2, + "engines": { + "camunda": "^8.5" + }, + "appliesTo": [ + "bpmn:Task" + ], + "properties": [] + }, + { + "$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", + "id": "example.engines.test.basic", + "name": " Test - Basic", + "description": "always matches", + "version": 1, + "appliesTo": [ + "bpmn:Task" + ], + "properties": [] + }, + + { + "$schema": "https://unpkg.com/@camunda/zeebe-element-templates-json-schema/resources/schema.json", + "id": "example.engines.test.broken", + "name": " Test - broken Semver range", + "description": "specifies broken semver range", + "version": 1, + "engines": { + "camunda": "-foobar" + }, + "appliesTo": [ + "bpmn:Task" + ], + "properties": [] + } +] \ No newline at end of file