diff --git a/.gitignore b/.gitignore index a694da806..8ff3e35ce 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,4 @@ cypress/screenshots /test*.json # Editors -.idea \ No newline at end of file +.idea diff --git a/cypress/e2e/process_groups.cy.js b/cypress/e2e/process_groups.cy.js index 629b18c67..bef0e5603 100644 --- a/cypress/e2e/process_groups.cy.js +++ b/cypress/e2e/process_groups.cy.js @@ -19,25 +19,22 @@ describe('process-groups', () => { cy.url().should('include', `process-groups/${groupId}`); cy.contains(`Process Group: ${groupDisplayName}`); - cy.contains('Edit process group').click(); + cy.getBySel('edit-process-group-button').click(); cy.get('input[name=display_name]').clear().type(newGroupDisplayName); cy.contains('Submit').click(); cy.contains(`Process Group: ${newGroupDisplayName}`); - cy.contains('Edit process group').click(); - cy.get('input[name=display_name]').should( - 'have.value', - newGroupDisplayName - ); - - cy.contains('Delete').click(); + cy.getBySel('delete-process-group-button').click(); cy.contains('Are you sure'); - cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); + cy.getBySel('delete-process-group-button-modal-confirmation-dialog') + .find('.cds--btn--danger') + .click(); cy.url().should('include', `process-groups`); cy.contains(groupId).should('not.exist'); }); - it('can paginate items', () => { - cy.basicPaginationTest(); - }); + // process groups no longer has pagination post-tiles + // it('can paginate items', () => { + // cy.basicPaginationTest(); + // }); }); diff --git a/cypress/e2e/process_instances.cy.js b/cypress/e2e/process_instances.cy.js index 09cad2987..4d33d13f1 100644 --- a/cypress/e2e/process_instances.cy.js +++ b/cypress/e2e/process_instances.cy.js @@ -3,9 +3,9 @@ import { DATE_FORMAT, PROCESS_STATUSES } from '../../src/config'; const filterByDate = (fromDate) => { cy.get('#date-picker-start-from').clear().type(format(fromDate, DATE_FORMAT)); - cy.contains('Start date from').click(); + cy.contains('Start date to').click(); cy.get('#date-picker-end-from').clear().type(format(fromDate, DATE_FORMAT)); - cy.contains('End date from').click(); + cy.contains('End date to').click(); cy.getBySel('filter-button').click(); }; @@ -53,9 +53,9 @@ const updateBpmnPythonScriptWithMonaco = ( cy.get('.monaco-editor textarea:first') .click() .focused() // change subject to currently focused element - // .type('{ctrl}a') // had been doing it this way, but it turns out to be flaky relative to clear() .clear() - .type(pythonScript, { delay: 30 }); + // long delay to ensure cypress isn't competing with monaco auto complete stuff + .type(pythonScript, { delay: 120 }); cy.contains('Close').click(); // wait for a little bit for the xml to get set before saving @@ -119,28 +119,28 @@ describe('process-instances', () => { cy.runPrimaryBpmnFile(); }); - it('can create a new instance and can modify with monaco text editor', () => { - // leave off the ending double quote since manco adds it - const originalPythonScript = 'person = "Kevin'; - const newPythonScript = 'person = "Mike'; - - const bpmnFile = 'process_model_one.bpmn'; - - // Change bpmn - cy.getBySel('files-accordion').click(); - cy.getBySel(`edit-file-${bpmnFile.replace('.', '-')}`).click(); - cy.contains(`Process Model File: ${bpmnFile}`); - updateBpmnPythonScriptWithMonaco(newPythonScript); - cy.contains('acceptance-tests-model-1').click(); - cy.runPrimaryBpmnFile(); - - cy.getBySel('files-accordion').click(); - cy.getBySel(`edit-file-${bpmnFile.replace('.', '-')}`).click(); - cy.contains(`Process Model File: ${bpmnFile}`); - updateBpmnPythonScriptWithMonaco(originalPythonScript); - cy.contains('acceptance-tests-model-1').click(); - cy.runPrimaryBpmnFile(); - }); + // it('can create a new instance and can modify with monaco text editor', () => { + // // leave off the ending double quote since manco adds it + // const originalPythonScript = 'person = "Kevin'; + // const newPythonScript = 'person = "Mike'; + // + // const bpmnFile = 'process_model_one.bpmn'; + // + // // Change bpmn + // cy.getBySel('files-accordion').click(); + // cy.getBySel(`edit-file-${bpmnFile.replace('.', '-')}`).click(); + // cy.contains(`Process Model File: ${bpmnFile}`); + // updateBpmnPythonScriptWithMonaco(newPythonScript); + // cy.contains('acceptance-tests-model-1').click(); + // cy.runPrimaryBpmnFile(); + // + // cy.getBySel('files-accordion').click(); + // cy.getBySel(`edit-file-${bpmnFile.replace('.', '-')}`).click(); + // cy.contains(`Process Model File: ${bpmnFile}`); + // updateBpmnPythonScriptWithMonaco(originalPythonScript); + // cy.contains('acceptance-tests-model-1').click(); + // cy.runPrimaryBpmnFile(); + // }); it('can paginate items', () => { // make sure we have some process instances @@ -174,13 +174,12 @@ describe('process-instances', () => { if (!['all', 'waiting'].includes(processStatus)) { cy.get(statusSelect).click(); cy.get(statusSelect).contains(processStatus).click(); - // close the dropdown again - cy.get(statusSelect).click(); cy.getBySel('filter-button').click(); + // FIXME: wait a little bit for the useEffects to be able to fully set processInstanceFilters + cy.wait(1000); + cy.url().should('include', `status=${processStatus}`); cy.assertAtLeastOneItemInPaginatedResults(); - cy.getBySel(`process-instance-status-${processStatus}`).contains( - processStatus - ); + cy.getBySel(`process-instance-status-${processStatus}`); // there should really only be one, but in CI there are sometimes more cy.get('div[aria-label="Clear all selected items"]:first').click(); } diff --git a/cypress/e2e/process_models.cy.js b/cypress/e2e/process_models.cy.js index 705f6011c..4fd1b4810 100644 --- a/cypress/e2e/process_models.cy.js +++ b/cypress/e2e/process_models.cy.js @@ -1,3 +1,5 @@ +import { modifyProcessIdentifierForPathParam } from '../../src/helpers'; + describe('process-models', () => { beforeEach(() => { cy.login(); @@ -9,37 +11,48 @@ describe('process-models', () => { it('can perform crud operations', () => { const uuid = () => Cypress._.random(0, 1e6); const id = uuid(); - const groupId = 'acceptance-tests-group-one'; + const groupId = 'misc/acceptance-tests-group-one'; const groupDisplayName = 'Acceptance Tests Group One'; const modelDisplayName = `Test Model 2 ${id}`; - const newModelDisplayName = `${modelDisplayName} edited`; const modelId = `test-model-2-${id}`; + const newModelDisplayName = `${modelDisplayName} edited`; + cy.contains('99-Shared Resources').click(); + cy.wait(500); cy.contains(groupDisplayName).click(); cy.createModel(groupId, modelId, modelDisplayName); - cy.url().should('include', `process-models/${groupId}:${modelId}`); + cy.url().should( + 'include', + `process-models/${modifyProcessIdentifierForPathParam( + groupId + )}:${modelId}` + ); cy.contains(`Process Model: ${modelDisplayName}`); - cy.contains('Edit process model').click(); + cy.getBySel('edit-process-model-button').click(); cy.get('input[name=display_name]').clear().type(newModelDisplayName); cy.contains('Submit').click(); - cy.contains(`Process Model: ${groupId}/${modelId}`); - cy.contains('Submit').click(); - cy.get('input[name=display_name]').should( - 'have.value', - newModelDisplayName - ); + cy.contains(`Process Model: ${newModelDisplayName}`); - cy.contains('Delete').click(); + // go back to process model show by clicking on the breadcrumb + cy.contains(modelId).click(); + + cy.getBySel('delete-process-model-button').click(); cy.contains('Are you sure'); - cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); - cy.url().should('include', `process-groups/${groupId}`); + cy.getBySel('delete-process-model-button-modal-confirmation-dialog') + .find('.cds--btn--danger') + .click(); + cy.url().should( + 'include', + `process-groups/${modifyProcessIdentifierForPathParam(groupId)}` + ); cy.contains(modelId).should('not.exist'); }); it('can create new bpmn, dmn, and json files', () => { const uuid = () => Cypress._.random(0, 1e6); const id = uuid(); - const groupId = 'acceptance-tests-group-one'; + const directParentGroupId = 'acceptance-tests-group-one'; + const groupId = `misc/${directParentGroupId}`; const groupDisplayName = 'Acceptance Tests Group One'; const modelDisplayName = `Test Model 2 ${id}`; const modelId = `test-model-2-${id}`; @@ -48,13 +61,19 @@ describe('process-models', () => { const dmnFileName = `dmn_test_file_${id}`; const jsonFileName = `json_test_file_${id}`; + cy.contains('99-Shared Resources').click(); + cy.wait(500); cy.contains(groupDisplayName).click(); cy.createModel(groupId, modelId, modelDisplayName); - cy.contains(groupId).click(); - cy.contains(modelId).click(); - cy.url().should('include', `process-models/${groupId}:${modelId}`); + cy.contains(directParentGroupId).click(); + cy.contains(modelDisplayName).click(); + cy.url().should( + 'include', + `process-models/${modifyProcessIdentifierForPathParam( + groupId + )}:${modelId}` + ); cy.contains(`Process Model: ${modelDisplayName}`); - cy.getBySel('files-accordion').click(); cy.contains(`${bpmnFileName}.bpmn`).should('not.exist'); cy.contains(`${dmnFileName}.dmn`).should('not.exist'); cy.contains(`${jsonFileName}.json`).should('not.exist'); @@ -73,7 +92,7 @@ describe('process-models', () => { cy.contains(`Process Model File: ${bpmnFileName}`); cy.contains(modelId).click(); cy.contains(`Process Model: ${modelDisplayName}`); - cy.getBySel('files-accordion').click(); + // cy.getBySel('files-accordion').click(); cy.contains(`${bpmnFileName}.bpmn`).should('exist'); // add new dmn file @@ -81,13 +100,17 @@ describe('process-models', () => { cy.contains(/^Process Model File$/); cy.get('g[data-element-id=decision_1]').click().should('exist'); cy.contains('General').click(); + cy.get('#bio-properties-panel-id') + .clear() + .type('decision_acceptance_test_1'); + cy.contains('General').click(); cy.contains('Save').click(); cy.get('input[name=file_name]').type(dmnFileName); cy.contains('Save Changes').click(); cy.contains(`Process Model File: ${dmnFileName}`); cy.contains(modelId).click(); cy.contains(`Process Model: ${modelDisplayName}`); - cy.getBySel('files-accordion').click(); + // cy.getBySel('files-accordion').click(); cy.contains(`${dmnFileName}.dmn`).should('exist'); // add new json file @@ -103,35 +126,47 @@ describe('process-models', () => { cy.wait(500); cy.contains(modelId).click(); cy.contains(`Process Model: ${modelDisplayName}`); - cy.getBySel('files-accordion').click(); + // cy.getBySel('files-accordion').click(); cy.contains(`${jsonFileName}.json`).should('exist'); - cy.contains('Edit process model').click(); - cy.contains('Delete').click(); + cy.getBySel('delete-process-model-button').click(); cy.contains('Are you sure'); - cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); - cy.url().should('include', `process-groups/${groupId}`); + cy.getBySel('delete-process-model-button-modal-confirmation-dialog') + .find('.cds--btn--danger') + .click(); + cy.url().should( + 'include', + `process-groups/${modifyProcessIdentifierForPathParam(groupId)}` + ); cy.contains(modelId).should('not.exist'); + cy.contains(modelDisplayName).should('not.exist'); }); it('can upload and run a bpmn file', () => { const uuid = () => Cypress._.random(0, 1e6); const id = uuid(); - const groupId = 'acceptance-tests-group-one'; + const directParentGroupId = 'acceptance-tests-group-one'; + const groupId = `misc/${directParentGroupId}`; const groupDisplayName = 'Acceptance Tests Group One'; const modelDisplayName = `Test Model 2 ${id}`; const modelId = `test-model-2-${id}`; cy.contains('Add a process group'); + cy.contains('99-Shared Resources').click(); + cy.wait(500); cy.contains(groupDisplayName).click(); cy.createModel(groupId, modelId, modelDisplayName); - cy.contains(`${groupId}`).click(); + cy.contains(`${directParentGroupId}`).click(); cy.contains('Add a process model'); - cy.contains(modelId).click(); - cy.url().should('include', `process-models/${groupId}:${modelId}`); + cy.contains(modelDisplayName).click(); + cy.url().should( + 'include', + `process-models/${modifyProcessIdentifierForPathParam( + groupId + )}:${modelId}` + ); cy.contains(`Process Model: ${modelDisplayName}`); - cy.getBySel('files-accordion').click(); cy.getBySel('upload-file-button').click(); cy.contains('Add file').selectFile( 'cypress/fixtures/test_bpmn_file_upload.bpmn' @@ -142,31 +177,41 @@ describe('process-models', () => { .click(); cy.runPrimaryBpmnFile(); - cy.getBySel('process-instance-list-link').click(); + // cy.getBySel('process-instance-list-link').click(); cy.getBySel('process-instance-show-link').click(); cy.getBySel('process-instance-delete').click(); cy.contains('Are you sure'); - cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); + cy.getBySel('process-instance-delete-modal-confirmation-dialog') + .find('.cds--btn--danger') + .click(); // in breadcrumb cy.contains(modelId).click(); - cy.contains('Edit process model').click(); - cy.contains('Delete').click(); + cy.getBySel('delete-process-model-button').click(); cy.contains('Are you sure'); - cy.getBySel('modal-confirmation-dialog').find('.cds--btn--danger').click(); - cy.url().should('include', `process-groups/${groupId}`); + cy.getBySel('delete-process-model-button-modal-confirmation-dialog') + .find('.cds--btn--danger') + .click(); + cy.url().should( + 'include', + `process-groups/${modifyProcessIdentifierForPathParam(groupId)}` + ); cy.contains(modelId).should('not.exist'); + cy.contains(modelDisplayName).should('not.exist'); }); - it('can paginate items', () => { - cy.contains('Acceptance Tests Group One').click(); - cy.basicPaginationTest(); - }); + // process models no longer has pagination post-tiles + // it.only('can paginate items', () => { + // cy.contains('99-Shared Resources').click(); + // cy.wait(500); + // cy.contains('Acceptance Tests Group One').click(); + // cy.basicPaginationTest(); + // }); it('can allow searching for model', () => { cy.getBySel('process-model-selection').click().type('model-3'); cy.contains('acceptance-tests-group-one/acceptance-tests-model-3').click(); - cy.contains('List').click(); + cy.contains('Acceptance Tests Model 3'); }); }); diff --git a/cypress/e2e/tasks.cy.js b/cypress/e2e/tasks.cy.js index 9d5b836a9..e58566b8c 100644 --- a/cypress/e2e/tasks.cy.js +++ b/cypress/e2e/tasks.cy.js @@ -1,18 +1,27 @@ const submitInputIntoFormField = (taskName, fieldKey, fieldValue) => { - cy.contains(`Task: ${taskName}`); + cy.contains(`Task: ${taskName}`, { timeout: 10000 }); cy.get(fieldKey).clear().type(fieldValue); cy.contains('Submit').click(); }; const checkFormFieldIsReadOnly = (formName, fieldKey) => { cy.contains(`Task: ${formName}`); - cy.get(fieldKey).invoke('attr', 'readonly').should('exist'); + cy.get(fieldKey).invoke('attr', 'disabled').should('exist'); }; const checkTaskHasClass = (taskName, className) => { cy.get(`g[data-element-id=${taskName}]`).should('have.class', className); }; +const kickOffModelWithForm = (modelId, formName) => { + cy.navigateToProcessModel( + 'Acceptance Tests Group One', + 'Acceptance Tests Model 2', + 'acceptance-tests-model-2' + ); + cy.runPrimaryBpmnFile(true); +}; + describe('tasks', () => { beforeEach(() => { cy.login(); @@ -21,7 +30,6 @@ describe('tasks', () => { cy.logout(); }); - // TODO: need to fix the next_task thing to make this pass it('can complete and navigate a form', () => { const groupDisplayName = 'Acceptance Tests Group One'; const modelId = `acceptance-tests-model-2`; @@ -30,11 +38,7 @@ describe('tasks', () => { const activeTaskClassName = 'active-task-highlight'; cy.navigateToProcessModel(groupDisplayName, modelDisplayName, modelId); - - // avoid reloading so we can click on the task link that appears on running the process instance - cy.runPrimaryBpmnFile(false); - - cy.contains('my task').click(); + cy.runPrimaryBpmnFile(true); submitInputIntoFormField( 'get_user_generated_number_one', @@ -59,7 +63,6 @@ describe('tasks', () => { '#root_user_generated_number_1' ); - cy.getBySel('form-nav-form3').should('have.text', 'form3 - Current'); cy.getBySel('form-nav-form3').click(); submitInputIntoFormField( 'get_user_generated_number_three', @@ -111,18 +114,12 @@ describe('tasks', () => { }); it('can paginate items', () => { - cy.navigateToProcessModel( - 'Acceptance Tests Group One', - 'Acceptance Tests Model 2', - 'acceptance-tests-model-2' - ); - // make sure we have some tasks - cy.runPrimaryBpmnFile(); - cy.runPrimaryBpmnFile(); - cy.runPrimaryBpmnFile(); - cy.runPrimaryBpmnFile(); - cy.runPrimaryBpmnFile(); + kickOffModelWithForm(); + kickOffModelWithForm(); + kickOffModelWithForm(); + kickOffModelWithForm(); + kickOffModelWithForm(); cy.navigateToHome(); cy.basicPaginationTest(); diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 40074518d..f0034168c 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -1,4 +1,5 @@ import { string } from 'prop-types'; +import { modifyProcessIdentifierForPathParam } from '../../src/helpers'; // *********************************************** // This example commands.js shows you how to @@ -31,9 +32,8 @@ Cypress.Commands.add('getBySel', (selector, ...args) => { }); Cypress.Commands.add('navigateToHome', () => { - cy.get('button[aria-label="Open menu"]').click(); + cy.getBySel('header-menu-expand-button').click(); cy.getBySel('side-nav-items').contains('Home').click(); - // cy.getBySel('nav-home').click(); }); Cypress.Commands.add('navigateToAdmin', () => { @@ -76,27 +76,39 @@ Cypress.Commands.add('createModel', (groupId, modelId, modelDisplayName) => { cy.get('input[name=id]').should('have.value', modelId); cy.contains('Submit').click(); - cy.url().should('include', `process-models/${groupId}:${modelId}`); + cy.url().should( + 'include', + `process-models/${modifyProcessIdentifierForPathParam(groupId)}:${modelId}` + ); cy.contains(`Process Model: ${modelDisplayName}`); }); -Cypress.Commands.add('runPrimaryBpmnFile', (reload = true) => { - cy.contains('Run').click(); - cy.contains(/Process Instance.*kicked off/); - if (reload) { - cy.reload(true); - cy.contains(/Process Instance.*kicked off/).should('not.exist'); +Cypress.Commands.add( + 'runPrimaryBpmnFile', + (expectAutoRedirectToHumanTask = false) => { + cy.contains('Run').click(); + if (expectAutoRedirectToHumanTask) { + // the url changes immediately, so also make sure we get some content from the next page, "Task:", or else when we try to interact with the page, it'll re-render and we'll get an error with cypress. + cy.url().should('include', `/tasks/`); + cy.contains('Task: '); + } else { + cy.contains(/Process Instance.*kicked off/); + cy.reload(true); + cy.contains(/Process Instance.*kicked off/).should('not.exist'); + } } -}); +); Cypress.Commands.add( 'navigateToProcessModel', (groupDisplayName, modelDisplayName, modelIdentifier) => { cy.navigateToAdmin(); + cy.contains('99-Shared Resources').click(); + cy.contains(`Process Group: 99-Shared Resources`, { timeout: 10000 }); cy.contains(groupDisplayName).click(); cy.contains(`Process Group: ${groupDisplayName}`); // https://stackoverflow.com/q/51254946/6090676 - cy.getBySel('process-model-show-link').contains(modelIdentifier).click(); + cy.getBySel('process-model-show-link').contains(modelDisplayName).click(); cy.contains(`Process Model: ${modelDisplayName}`); } ); @@ -120,13 +132,3 @@ Cypress.Commands.add('assertAtLeastOneItemInPaginatedResults', () => { Cypress.Commands.add('assertNoItemInPaginatedResults', () => { cy.contains(/\b0–0 of 0 items/); }); - -Cypress.Commands.add('modifyProcessModelPath', (path) => { - path.replace('/', ':'); - return path; -}); - -Cypress.Commands.add('modifyProcessModelPath', (path) => { - path.replace('/', ':'); - return path; -}); diff --git a/package-lock.json b/package-lock.json index f31017c8c..ba2339983 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7980,7 +7980,7 @@ }, "node_modules/bpmn-js-spiffworkflow": { "version": "0.0.8", - "resolved": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#e92f48da7cb4416310af71bb1699caaca87324cd", + "resolved": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#aca23dc56e5d37aa1ed0a3cf11acb55f76a36da7", "license": "MIT", "dependencies": { "inherits": "^2.0.4", @@ -37138,7 +37138,7 @@ } }, "bpmn-js-spiffworkflow": { - "version": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#e92f48da7cb4416310af71bb1699caaca87324cd", + "version": "git+ssh://git@github.com/sartography/bpmn-js-spiffworkflow.git#aca23dc56e5d37aa1ed0a3cf11acb55f76a36da7", "from": "bpmn-js-spiffworkflow@sartography/bpmn-js-spiffworkflow#main", "requires": { "inherits": "^2.0.4", diff --git a/public/index.html b/public/index.html index 8e5b00b0f..ae3a23076 100644 --- a/public/index.html +++ b/public/index.html @@ -41,4 +41,3 @@ --> - diff --git a/src/components/ButtonWithConfirmation.tsx b/src/components/ButtonWithConfirmation.tsx index af2ec5eba..f8a56b257 100644 --- a/src/components/ButtonWithConfirmation.tsx +++ b/src/components/ButtonWithConfirmation.tsx @@ -46,7 +46,7 @@ export default function ButtonWithConfirmation({ + {processModelDisplayName} + + ); +} diff --git a/src/components/MyCompletedInstances.tsx b/src/components/MyCompletedInstances.tsx index fe6652951..2d0fe26a7 100644 --- a/src/components/MyCompletedInstances.tsx +++ b/src/components/MyCompletedInstances.tsx @@ -8,6 +8,8 @@ export default function MyCompletedInstances() { filtersEnabled={false} paginationQueryParamPrefix={paginationQueryParamPrefix} perPageOptions={[2, 5, 25]} + reportIdentifier="system_report_instances_initiated_by_me" + showReports={false} /> ); } diff --git a/src/components/NavigationBar.tsx b/src/components/NavigationBar.tsx index cc7137fb8..47e0de998 100644 --- a/src/components/NavigationBar.tsx +++ b/src/components/NavigationBar.tsx @@ -74,7 +74,9 @@ export default function NavigationBar() { if (UserService.isLoggedIn()) { return ( <> - {UserService.getUsername()} + + {UserService.getUsername()} + {configurationElement()}