From 02ee4a384626e518fff809e36583e8d125948a5a Mon Sep 17 00:00:00 2001 From: CarliPinell Date: Tue, 22 Oct 2024 18:33:14 -0400 Subject: [PATCH 01/27] Fixing mustache syntax in Form Collection Record Control --- src/components/renderer/form-collection-record-control.vue | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/renderer/form-collection-record-control.vue b/src/components/renderer/form-collection-record-control.vue index a13b7d4d3..106217843 100644 --- a/src/components/renderer/form-collection-record-control.vue +++ b/src/components/renderer/form-collection-record-control.vue @@ -156,6 +156,7 @@ export default { }, callbackRecord() { this.hasMustache = true; + //console.log("en callbackRecord this.selCollectionId: ", this.selCollectionId); this.loadRecordCollection(this.selCollectionId, 1, this.selDisplayMode); }, errors() { @@ -212,9 +213,9 @@ export default { }, record(record) { this.hasMustache = false; - if (record && !isNaN(record) && record > 0 && this.collection) { + if (record && !isNaN(record) && record > 0 && this.collection.collectionId) { this.selRecordId = record; - this.loadRecordCollection(this.selCollectionId, record, this.collectionmode); + this.loadRecordCollection(this.collection.collectionId, record, this.collectionmode); } else { if (this.isMustache(record)) { this.callbackRecord(); @@ -226,6 +227,7 @@ export default { if(collectionmode) { this.selDisplayMode = collectionmode.modeId; } + //console.log("en collectionmode: ", this.selCollectionId); this.loadRecordCollection(this.selCollectionId, this.selRecordId, this.selDisplayMode); }, }, @@ -235,6 +237,7 @@ export default { }); if (this.collection && this.record) { + //console.log("en mounted this.collection.collectionId: ", this.collection.collectionId); this.loadRecordCollection(this.collection.collectionId, this.record, this.collectionmode.modeId); } }, From 11c48b93c33a57ae8c6d75438b9900864fe440e8 Mon Sep 17 00:00:00 2001 From: CarliPinell Date: Wed, 23 Oct 2024 09:07:09 -0400 Subject: [PATCH 02/27] fixing nustache bug in form collection view --- src/components/renderer/form-collection-view-control.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/renderer/form-collection-view-control.vue b/src/components/renderer/form-collection-view-control.vue index f1f84cfd6..98a3bce9c 100644 --- a/src/components/renderer/form-collection-view-control.vue +++ b/src/components/renderer/form-collection-view-control.vue @@ -206,9 +206,9 @@ export default { }, record(record) { this.hasMustache = false; - if (record && !isNaN(record) && record > 0 && this.collection) { + if (record && !isNaN(record) && record > 0 && this.collection.collectionId) { this.selRecordId = record; - this.loadRecordCollection(this.selCollectionId, record, this.collectionmode); + this.loadRecordCollection(this.collection.collectionId, record, this.collectionmode); } else { if (this.isMustache(record)) { this.callbackRecord(); From a492f4196f3ecf5a540c992a5e06bd3550190a0c Mon Sep 17 00:00:00 2001 From: CarliPinell Date: Wed, 23 Oct 2024 13:50:34 -0400 Subject: [PATCH 03/27] removing consoles --- .../renderer/form-collection-record-control.vue | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/components/renderer/form-collection-record-control.vue b/src/components/renderer/form-collection-record-control.vue index 106217843..765f5bde4 100644 --- a/src/components/renderer/form-collection-record-control.vue +++ b/src/components/renderer/form-collection-record-control.vue @@ -16,7 +16,7 @@ From b7b532c0643385f2087d26b9a33b183b7841ea3b Mon Sep 17 00:00:00 2001 From: Rodrigo Quelca Date: Fri, 25 Oct 2024 14:05:24 -0400 Subject: [PATCH 15/27] FOUR-19784: Clipboard Pasted Successfully message isn't displayed --- src/mixins/Clipboard.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mixins/Clipboard.js b/src/mixins/Clipboard.js index 077729ff2..17b6c01e8 100644 --- a/src/mixins/Clipboard.js +++ b/src/mixins/Clipboard.js @@ -115,6 +115,9 @@ export default { // replace uuids in clipboard content clipboardContent.forEach(this.updateUuids); page.items.splice(index, 1, ...clipboardContent); + if (clipboardContent.length) { + window.ProcessMaker.alert(this.$t("Clipboard Pasted Succesfully"), "success"); + } } if (item.items) { replaceInPage(item); From baddafc60b7ef117beccaaaca933d5f7061f51ed Mon Sep 17 00:00:00 2001 From: CarliPinell Date: Fri, 25 Oct 2024 15:15:21 -0400 Subject: [PATCH 16/27] Fixing Column Field in single field of record on Record List --- src/components/inspector/collection-data-source.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/inspector/collection-data-source.vue b/src/components/inspector/collection-data-source.vue index f71176063..88bf9bd59 100644 --- a/src/components/inspector/collection-data-source.vue +++ b/src/components/inspector/collection-data-source.vue @@ -194,6 +194,9 @@ }, deep: true }, + dataSelectionOptions() { + this.singleField = null; + } }, }; From 7768e0e0f37cb8f8e7cecc99c6d325b5a2242e5e Mon Sep 17 00:00:00 2001 From: CarliPinell Date: Fri, 25 Oct 2024 16:35:44 -0400 Subject: [PATCH 17/27] Fixing collection issue with draft data recovered on task --- src/components/renderer/form-collection-record-control.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/renderer/form-collection-record-control.vue b/src/components/renderer/form-collection-record-control.vue index a13b7d4d3..9de7fb18b 100644 --- a/src/components/renderer/form-collection-record-control.vue +++ b/src/components/renderer/form-collection-record-control.vue @@ -16,6 +16,7 @@ diff --git a/src/components/vue-form-builder.vue b/src/components/vue-form-builder.vue index 02f7cd400..50f51c65c 100644 --- a/src/components/vue-form-builder.vue +++ b/src/components/vue-form-builder.vue @@ -245,7 +245,9 @@ v-model="element.items" :validation-errors="validationErrors" class="card-body" - :class="styleMode === 'Modern' ? elementCssClassModern(element) : elementCssClass(element)" + :class="styleMode === 'Modern' && element.component === 'FormRecordList' + ? elementCssClassModern(element) + : elementCssClass(element)" :selected="selected" :config="element.config" :ai-element="element" @@ -299,7 +301,9 @@ :tabindex="element.config.interactive ? 0 : -1" class="card-body m-0 pb-4 pt-4" :class="[ - styleMode === 'Modern' ? elementCssClassModern(element) : elementCssClass(element), + styleMode === 'Modern' && element.component === 'FormRecordList' + ? elementCssClassModern(element) + : elementCssClass(element), { 'prevent-interaction': !element.config.interactive } ]" @input=" @@ -883,7 +887,7 @@ export default { }, shouldShow(item, accordion) { const sourceOptions = this.inspection.config[item.field]?.sourceOptions; - + //console.log("INICIO this.styleMode: ", this.styleMode); if (sourceOptions === 'Variable') { this.enableOption = true; return true; From 6ad670edd7a6c380de3a67b5b2effb71c38603d6 Mon Sep 17 00:00:00 2001 From: CarliPinell Date: Mon, 28 Oct 2024 12:40:47 -0400 Subject: [PATCH 20/27] removing console log --- src/components/vue-form-builder.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/vue-form-builder.vue b/src/components/vue-form-builder.vue index 2f9ee8f4a..ed348fef5 100644 --- a/src/components/vue-form-builder.vue +++ b/src/components/vue-form-builder.vue @@ -888,7 +888,7 @@ export default { }, shouldShow(item, accordion) { const sourceOptions = this.inspection.config[item.field]?.sourceOptions; - //console.log("INICIO this.styleMode: ", this.styleMode); + if (sourceOptions === 'Variable') { this.enableOption = true; return true; From 4661f6ebccb81b1515bce3f9073e0e216bd2f546 Mon Sep 17 00:00:00 2001 From: Julio Cesar Laura Avendano Date: Mon, 28 Oct 2024 16:43:10 -0400 Subject: [PATCH 21/27] FOUR-19778 Encrypted field does not have read-only mode --- src/components/renderer/form-masked-input.vue | 12 +++--- tests/e2e/specs/EncryptedField.spec.js | 42 ++++++++++++++++++- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/components/renderer/form-masked-input.vue b/src/components/renderer/form-masked-input.vue index 125797398..44c810a59 100644 --- a/src/components/renderer/form-masked-input.vue +++ b/src/components/renderer/form-masked-input.vue @@ -41,7 +41,7 @@ { // After conceal the value should be the same cy.get("[data-cy=preview-content] [name=form_input_1]").should("have.value", secretValue); }); -}); \ No newline at end of file + + it("Encrypted field in preview with 'readonly' property enabled", () => { + visitAndOpenAcordeon(); + dragFormInput(); + // Enable "readonly" mode + cy.get("[data-cy=inspector-readonly]").click(); + cy.get("[data-cy=accordion-Advanced]").click(); + // Enable encrypted + cy.get("[data-cy=inspector-encryptedConfig]") + .children() + .children(".custom-control") + .each((control) => { + // forced click over the control + control.children("input").trigger("click"); + }); + // Display available users/groups + cy.get('[data-cy="inspector-encryptedConfig"] .multiselect').click(); + // Select a group + cy.get('[data-cy="inspector-encryptedConfig"] #option-2-4').click(); + // Go to preview mode + enterPreviewMode(); + // Set initial data + cy.setPreviewDataInput('{"form_input_1":"Other value"}'); + // Click in "Conceal" with data + cy.get('[data-cy=preview-content] [name=form_input_1]').siblings('button').click(); + // After conceal should be keep the "readonly" mode + cy.get("[data-cy=preview-content] [name=form_input_1]").should("have.attr", "readonly"); + // After conceal the value should be different + cy.get("[data-cy=preview-content] [name=form_input_1]").should("have.not.value", secretValue); + // The value in data should be the uuid returned + cy.assertPreviewData({ + form_input_1: uuid, + }); + // Click in "Reveal" + cy.get('[data-cy=preview-content] [name=form_input_1]').siblings('button').click(); + // After conceal should be keep the "readonly" mode + cy.get("[data-cy=preview-content] [name=form_input_1]").should("have.attr", "readonly"); + // After conceal the value should be the same + cy.get("[data-cy=preview-content] [name=form_input_1]").should("have.value", secretValue); + }); +}); From 77e498dd5e845d4e53cb63c8a9065a05ffd4e460 Mon Sep 17 00:00:00 2001 From: Teisha McRae Date: Tue, 29 Oct 2024 11:49:26 -0400 Subject: [PATCH 22/27] Truncate template name; truncate description more --- src/components/ScreenTemplateCard.vue | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/ScreenTemplateCard.vue b/src/components/ScreenTemplateCard.vue index fe7c0df3e..d80b7ae4a 100644 --- a/src/components/ScreenTemplateCard.vue +++ b/src/components/ScreenTemplateCard.vue @@ -24,9 +24,11 @@
- {{ template.name }} + {{ + truncateText(template.name, 45) + }} {{ - truncateText(template.description, 100) + truncateText(template.description, 60) }}
From b15aa6ca1dec337ed8ef8ad111b4078e78d47d47 Mon Sep 17 00:00:00 2001 From: Rodrigo Quelca Date: Fri, 4 Oct 2024 10:49:24 -0400 Subject: [PATCH 23/27] bugfix/FOUR-19011: Case completed message is not displayed add test remove debugger --- src/components/task.vue | 121 ++- src/main.js | 8 + tests/components/TaskWebEntry.vue | 107 +++ tests/e2e/specs/EndEventRedirection.spec.js | 344 ++++++++ tests/e2e/specs/InterstitialRedirect.spec.js | 374 ++++++++ tests/e2e/specs/TaskRedirect.spec.js | 832 ++++++++++++++++++ .../specs/WebEntryEndEventRedirect.spec.js | 56 ++ tests/e2e/support/commands.js | 7 +- 8 files changed, 1810 insertions(+), 39 deletions(-) create mode 100644 tests/components/TaskWebEntry.vue create mode 100644 tests/e2e/specs/EndEventRedirection.spec.js create mode 100644 tests/e2e/specs/InterstitialRedirect.spec.js create mode 100644 tests/e2e/specs/TaskRedirect.spec.js create mode 100644 tests/e2e/specs/WebEntryEndEventRedirect.spec.js diff --git a/src/components/task.vue b/src/components/task.vue index bb7dfbaa8..934fa3069 100644 --- a/src/components/task.vue +++ b/src/components/task.vue @@ -107,6 +107,7 @@ export default { alwaysAllowEditing: { type: Boolean, default: false }, disableInterstitial: { type: Boolean, default: false }, waitLoadingListeners: { type: Boolean, default: false }, + isWebEntry: { type: Boolean, default: false }, }, data() { return { @@ -677,55 +678,97 @@ export default { return null; } }, + /** - * Handles the process completion and redirects the user based on the task assignment. - * @param {object} data - The data object containing endEventDestination. - * @param {string} userId - The ID of the current user. - * @param {string} requestId - The ID of the current request. + * Handles redirection upon process completion, considering destination type and user task validation. + * @async + * @param {Object} data - Contains information about the end event destination. + * @param {number} userId - ID of the current user. + * @param {number} requestId - ID of the request to complete. + * @returns {Promise} */ async processCompletedRedirect(data, userId, requestId) { + // Emit completion event if accessed through web entry. + if (this.isWebEntry) { + this.$emit("completed", requestId); + return; + } + try { - // Verify if is not anotherProcess type - if (data.endEventDestination.type !== "anotherProcess") { - if (data?.endEventDestination.value) { - window.location.href = data?.endEventDestination.value; - } else { - window.location.href = `/requests/${this.requestId}`; - } + const destinationUrl = this.resolveDestinationUrl(data); + if (destinationUrl) { + window.location.href = destinationUrl; return; } - // Parse endEventDestination from the provided data - const endEventDestination = this.parseJsonSafely( - data.endEventDestination.value - ); - // Get the next request using retry logic - const nextRequest = await this.retryApiCall(() => - this.getNextRequest( - endEventDestination.processId, - endEventDestination.startEvent - ) - ); - - const params = { - processRequestId: nextRequest.data.id, - status: "ACTIVE", - page: 1, - perPage: 1 - }; - // Get the tasks for the next request using retry logic - const response = await this.retryApiCall(() => this.getTasks(params)); - // Handle the first task from the response - const firstTask = response.data.data[0]; - if (firstTask && firstTask.user_id === userId) { - this.redirectToTask(firstTask.id); - } else { - this.redirectToRequest(requestId); - } + + // Proceed to handle redirection to the next request if applicable. + await this.handleNextRequestRedirection(data, userId, requestId); } catch (error) { console.error("Error processing completed redirect:", error); this.$emit("completed", requestId); } }, + + /** + * Resolves the URL to redirect to if the end event is not another process. + * @param {Object} data - Contains the end event destination data. + * @returns {string|null} - The URL for redirection, or null if proceeding to another process. + */ + resolveDestinationUrl(data) { + if (data.endEventDestination.type !== "anotherProcess") { + return data.endEventDestination.value || `/requests/${this.requestId}`; + } + return null; + }, + + /** + * Handles redirection logic to the next request's task or fallback to the request itself. + * @async + * @param {Object} data - Contains the end event destination. + * @param {number} userId - ID of the current user. + * @param {number} requestId - ID of the request to complete. + * @returns {Promise} + */ + async handleNextRequestRedirection(data, userId, requestId) { + const nextRequest = await this.fetchNextRequest(data.endEventDestination); + const firstTask = await this.fetchFirstTask(nextRequest); + + if (firstTask?.user_id === userId) { + this.redirectToTask(firstTask.id); + } else { + this.redirectToRequest(requestId); + } + }, + + /** + * Fetch the next request using retry logic. + * @async + * @param {Object} endEventDestination - The parsed end event destination object. + * @returns {Promise} - The next request data. + */ + async fetchNextRequest(endEventDestination) { + const destinationData = this.parseJsonSafely(endEventDestination.value); + return await this.retryApiCall(() => + this.getNextRequest(destinationData.processId, destinationData.startEvent) + ); + }, + + /** + * Fetch the first task from the next request using retry logic. + * @async + * @param {Object} nextRequest - The next request object. + * @returns {Promise} - The first task data, or null if no tasks found. + */ + async fetchFirstTask(nextRequest) { + const params = { + processRequestId: nextRequest.data.id, + status: "ACTIVE", + page: 1, + perPage: 1 + }; + const response = await this.retryApiCall(() => this.getTasks(params)); + return response.data.data[0] || null; + }, getAllowedRequestId() { const permissions = this.task.user_request_permission || []; const permission = permissions.find(item => item.process_request_id === this.parentRequest) @@ -800,6 +843,7 @@ export default { * @param {Object} data - The event data received from the socket listener. */ handleRedirect(data) { + debugger; switch (data.method) { case 'redirectToTask': this.handleRedirectToTask(data); @@ -808,6 +852,7 @@ export default { this.handleProcessUpdated(data); break; case 'processCompletedRedirect': + debugger; this.processCompletedRedirect( data.params[0], this.userId, diff --git a/src/main.js b/src/main.js index 1153cec71..0777ac778 100644 --- a/src/main.js +++ b/src/main.js @@ -325,6 +325,14 @@ window.Echo = { }, 1000); }); }, + + eventMockNext(event, response) { + this.listeners.forEach((listener) => { + setTimeout(() => { + listener.callback(response); + }, 1000); + }); + }, private() { return { notification(callback) { diff --git a/tests/components/TaskWebEntry.vue b/tests/components/TaskWebEntry.vue new file mode 100644 index 000000000..676ed944b --- /dev/null +++ b/tests/components/TaskWebEntry.vue @@ -0,0 +1,107 @@ + + + + + diff --git a/tests/e2e/specs/EndEventRedirection.spec.js b/tests/e2e/specs/EndEventRedirection.spec.js new file mode 100644 index 000000000..bc2d9c114 --- /dev/null +++ b/tests/e2e/specs/EndEventRedirection.spec.js @@ -0,0 +1,344 @@ +import SingleScreen from "../fixtures/single_line_input.json"; + + function initializeTaskAndScreenIntercepts(method, url, response) { + cy.intercept( + method, + url.replace(",screen,", ",").replace(",nested,", ","), + response + ); + cy.intercept( + method, + url.replace(/\?.*$/, "/screen?include=screen,nested"), + response.screen + ); + } + describe("End Event Redirect (Process completed) ", () => { + it("Element destination type is summaryScreen", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: 'taskList', + value: 'http://localhost:5173/tasks', + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + endEventDestination: { + type:"summaryScreen", + value: null + } + }], + method: "processCompletedRedirect" + }); + cy.url().should("eq", "http://localhost:5173/requests/1"); + }); + it("Element destination type is taskList", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: 'taskList', + value: 'http://localhost:5173/tasks', + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + endEventDestination: { + type:"taskList", + value:"http://localhost:5173/tasks" + } + }], + method: "processCompletedRedirect" + }); + cy.url().should("eq", "http://localhost:5173/tasks"); + }); + it("Element destination type is processLaunchpad", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: 'taskList', + value: 'http://localhost:5173/tasks', + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + endEventDestination: { + type:"processLaunchpad", + value: "http://localhost:5173/process-browser/7?categorySelected=-1" + } + }], + method: "processCompletedRedirect" + }); + cy.url().should("eq", "http://localhost:5173/process-browser/7?categorySelected=-1"); + }); + it("Element destination type is homepageDashboard", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: 'homepageDashboard', + value: 'http://localhost:5173/tasks', + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + endEventDestination: { + type: "homepageDashboard", + value: "http://localhost:5173/home/customize-ui/dashboards/eHEXsFrIwmClHoTRnMvOdMKSPbR3HalSFxaIHYxNh67UrtloUiuDBh5N8NrMoQVP" + } + }], + method: "processCompletedRedirect" + }); + cy.url().should("eq", "http://localhost:5173/home/customize-ui/dashboards/eHEXsFrIwmClHoTRnMvOdMKSPbR3HalSFxaIHYxNh67UrtloUiuDBh5N8NrMoQVP"); + }); + it("Element destination type is customDashboard", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: 'homepageDashboard', + value: 'http://localhost:5173/tasks', + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + endEventDestination: { + type: "customDashboard", + value: "http://localhost:5173/home/customize-ui/dashboards/eHEXsFrIwmClHoTRnMvOdMKSPbR3HalSFxaIHYxNh67UrtloUiuDBh5N8NrMoQVP" + } + }], + method: "processCompletedRedirect" + }); + cy.url().should("eq", "http://localhost:5173/home/customize-ui/dashboards/eHEXsFrIwmClHoTRnMvOdMKSPbR3HalSFxaIHYxNh67UrtloUiuDBh5N8NrMoQVP"); + }); + it("Element destination type is externalURL", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: 'homepageDashboard', + value: 'http://localhost:5173/tasks', + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + endEventDestination: { + type: "externalURL", + value: "http://localhost:5173/about" + } + }], + method: "processCompletedRedirect" + }); + cy.url().should("eq", "http://localhost:5173/about"); + }); + it("Element destination type is anotherProcess", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: 'homepageDashboard', + value: 'http://localhost:5173/tasks', + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + cy.intercept( + "POST", + "http://localhost:5173/api/1.0/process_events/4?event=node_1", + {} + ); + cy.intercept( + "GET", + "http://localhost:5173/api/1.1/tasks?user_id=1&process_request_id=undefined&page=1&per_page=1&status=ACTIVE", + { + "data": [ + { + "id": 585, + "uuid": "9ce21eaf-0991-495c-9f11-2e47b409acd5", + "user_id": 1, + "process_id": 7, + "process_request_id": 194, + "subprocess_request_id": null, + "element_id": "node_117", + "element_type": "task", + "element_name": "Form Task 222", + "status": "ACTIVE", + "element_index": 0, + "subprocess_start_event_id": null, + "completed_at": null, + "due_at": "2024-09-01T16:45:13+00:00", + "due_notified": 0, + "initiated_at": null, + "riskchanges_at": "2024-08-31T18:45:13+00:00", + "created_at": "2024-08-29T16:45:13+00:00", + "updated_at": "2024-08-29T16:45:13+00:00", + "version_id": 63, + "version_type": "ProcessMaker\\Models\\ScreenVersion", + "is_self_service": 0, + "self_service_groups": [], + "token_properties": [], + "is_priority": false, + "is_actionbyemail": false, + "user_viewed_at": null, + "advanceStatus": "open", + "draft": null, + "assignable_users": [ + 3 + ], + "can_view_parent_request": false, + } + ] + } + ); + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + endEventDestination: { + type: "anotherProcess", + value: '{"calledElement":"ProcessId-4","processId":4,"startEvent":"node_1","name":"subprocess"}' + } + }], + method: "processCompletedRedirect" + }); + cy.wait(1000); + cy.url().should("eq", "http://localhost:5173/tasks/585/edit"); + }); + }); \ No newline at end of file diff --git a/tests/e2e/specs/InterstitialRedirect.spec.js b/tests/e2e/specs/InterstitialRedirect.spec.js new file mode 100644 index 000000000..9e7c8d658 --- /dev/null +++ b/tests/e2e/specs/InterstitialRedirect.spec.js @@ -0,0 +1,374 @@ +import SingleScreen from "../fixtures/single_line_input.json"; + + function initializeTaskAndScreenIntercepts(method, url, response) { + cy.intercept( + method, + url.replace(",screen,", ",").replace(",nested,", ","), + response + ); + cy.intercept( + method, + url.replace(/\?.*$/, "/screen?include=screen,nested"), + response.screen + ); + } + describe("Interstitial", () => { + it("Load interstitial screen", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + "advanceStatus": "open", + "id": 667, + "element_name": "Form Task 11", + "element_id": "node_92", + "element_type": "task", + "status": "ACTIVE", + "due_at": "2024-09-02T16:12:01.000000Z", + "process_request_id": 219, + "is_self_service": 0, + + "user": { + "id": 1, + "firstname": "Admin", + "lastname": "User", + "email": "admin@processmaker.com", + "username": "admin", + "avatar": "", + "fullname": "Admin User" + }, + "requestor": { + "id": 1, + "uuid": "9cd28c78-f74c-4731-b0e5-aa5e49df3f7e", + "email": "admin@processmaker.com", + "firstname": "Admin", + "lastname": "User", + "username": "admin", + "status": "ACTIVE", + "address": null, + "city": null, + "state": null, + "postal": null, + "country": null, + "phone": null, + "fax": null, + "cell": null, + "title": null, + "birthdate": null, + "timezone": "America\/Los_Angeles", + "datetime_format": "m\/d\/Y H:i", + "language": "en", + "meta": { + }, + "connected_accounts": null, + "is_administrator": true, + "is_system": 0, + "expires_at": null, + "loggedin_at": "2024-08-30T14:01:18+00:00", + "active_at": "2024-08-30T16:12:13+00:00", + "remember_token": null, + "created_at": "2024-08-21T22:58:58+00:00", + "updated_at": "2024-08-23T15:06:58+00:00", + "deleted_at": null, + "delegation_user_id": null, + "manager_id": null, + "schedule": null, + "force_change_password": 0, + "avatar": "", + "password_changed_at": null, + "preferences_2fa": null, + "fullname": "Admin User" + }, + "process_request": { + "id": 219, + "uuid": "9ce415cb-08cd-49c9-aff5-b97fb8362346", + "process_id": 7, + "user_id": 1, + "parent_request_id": null, + "status": "ACTIVE", + "do_not_sanitize": [ + "interstitial_message", + " _user.fullname " + ], + "errors": null, + "completed_at": null, + "initiated_at": "2024-08-30T16:12:01+00:00", + "created_at": "2024-08-30T16:12:01+00:00", + "updated_at": "2024-08-30T16:12:01+00:00", + "case_title": "Case #207", + "case_number": 207, + "callable_id": "ProcessId", + "process_version_id": 143 + }, + "draft": null, + "component": "task-screen", + + "loop_context": "", + "definition": { + "outgoing": {}, + "incoming": {}, + "id": "node_92", + "name": "Form Task 11", + "screenRef": "33", + "allowInterstitial": "true", + "interstitialScreenRef": "22", + "assignment": "requester", + "assignmentLock": "false", + "allowReassignment": "false", + "config": "{\"web_entry\":null}", + "elementDestination": "{\"type\":\"taskSource\",\"value\":null}" + }, + "bpmn_tag_name": "task", + "allow_interstitial": true, + "interstitial_screen": { + "id": 22, + "uuid": "9ca9bc5c-468e-4a11-8bb9-30a29494833d", + "screen_category_id": "1", + "title": "IDA - Dynamic Message - Interstitial Screen 7", + "description": "IDA - Dynamic Message - Interstitial Screen", + "type": "DISPLAY", + "config": [ + { + "name": "Retrieving Invoices - Interstitial Screen", + "items": [ + { + "items": [ + [], + [ + { + "label": "Image", + "config": { + "icon": "fas fa-image", + "name": "Interstitial", + "event": "submit", + "label": "Image", + "value": null, + "width": "297.21", + "height": "220.61", + "variant": "primary", + "renderImage": false, + "customCssSelector": "imgInterstitial" + }, + "component": "FormImage", + "editor-control": "FormImage", + "editor-component": "FormImage" + }, + { + "label": "Rich Text", + "config": { + "icon": "fas fa-pencil-ruler", + "label": null, + "content": "

{{interstitial_title}}<\/h3>", + "interactive": true, + "renderVarHtml": false, + "conditionalHide": null + }, + "component": "FormHtmlViewer", + "editor-control": "FormHtmlEditor", + "editor-component": "FormHtmlEditor" + }, + { + "label": "Rich Text", + "config": { + "icon": "fas fa-pencil-ruler", + "label": null, + "content": "

{{interstitial_message}}<\/h5>", + "interactive": true, + "renderVarHtml": true, + "customCssSelector": null + }, + "component": "FormHtmlViewer", + "editor-control": "FormHtmlEditor", + "editor-component": "FormHtmlEditor" + } + ], + [] + ], + "label": "Multicolumn \/ Table", + "config": { + "icon": "fas fa-table", + "label": null, + "options": [ + { + "value": "1", + "content": "2" + }, + { + "value": "2", + "content": "8" + }, + { + "value": "3", + "content": "2" + } + ], + "customCssSelector": "fullbox" + }, + "component": "FormMultiColumn", + "container": true, + "editor-control": "FormMultiColumn", + "editor-component": "MultiColumn" + } + ], + "order": 1 + } + ], + "computed": [ + { + "id": 5, + "name": "interstitial_title", + "type": "javascript", + "formula": "if(this.interstitial_title == null){\r\n return \"We're getting the next task for you...\";\r\n}", + "property": "interstitial_title" + } + ], + "custom_css": "[selector='imgInterstitial']{\r\n text-align: center;\r\n padding-top: 10px;\r\n padding-bottom: 30px;\r\n}\r\n[selector='fullbox']{\r\n padding: 50px 10px 50px 10px;\r\n}\r\n[selector='text']{\r\n max-width: 430px; \r\n text-align: center;\r\n}", + "created_at": "2024-07-08T15:23:18+00:00", + "updated_at": "2024-08-21T22:59:40+00:00", + "status": "ACTIVE", + "key": null, + "watchers": [], + "translations": null, + "is_template": 0, + "asset_type": null, + "projects": "[]" + }, + "user_request_permission": [ + { + "process_request_id": 219, + "allowed": true + } + ], + "elementDestination": { + "type": "taskSource", + "value": "taskSource" + } + } + ); + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1/screen?include=screen,nested", + { + "id": 63, + "screen_id": 33, + "screen_category_id": 1, + "draft": 0, + "title": "first-form", + "description": "test", + "type": "FORM", + "config": [ + { + "name": "first-form", + "items": [ + { + "label": "Line Input", + "config": { + "icon": "far fa-square", + "name": "form_input_1", + "type": "text", + "label": "New Input", + "helper": null, + "dataFormat": "string", + "validation": null, + "placeholder": null + }, + "component": "FormInput", + "editor-control": "FormInput", + "editor-component": "FormInput" + }, + { + "label": "Submit Button", + "config": { + "icon": "fas fa-share-square", + "name": null, + "event": "submit", + "label": "New Submit", + "loading": false, + "tooltip": [], + "variant": "primary", + "fieldValue": null, + "loadingLabel": "Loading...", + "defaultSubmit": true + }, + "component": "FormButton", + "editor-control": "FormSubmit", + "editor-component": "FormButton" + } + ], + "order": 1 + } + ], + "computed": [], + "custom_css": null, + "created_at": "2024-08-22 15:00:04", + "updated_at": "2024-08-22 15:00:04", + "status": "ACTIVE", + "key": null, + "watchers": [], + "translations": null, + "is_template": 0, + "asset_type": null, + "nested": [] + } + ); + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/2?include=data,user,draft,requestor,processRequest,component,requestData,loopContext,bpmnTagName,interstitial,definition,userRequestPermission,elementDestination", + { + "data": [ + { + "id": 585, + "uuid": "9ce21eaf-0991-495c-9f11-2e47b409acd5", + "user_id": 1, + "process_id": 7, + "process_request_id": 194, + "subprocess_request_id": null, + "element_id": "node_117", + "element_type": "task", + "element_name": "Form Task 222", + "status": "ACTIVE", + "element_index": 0, + "subprocess_start_event_id": null, + "completed_at": null, + "due_at": "2024-09-01T16:45:13+00:00", + "due_notified": 0, + "initiated_at": null, + "riskchanges_at": "2024-08-31T18:45:13+00:00", + "created_at": "2024-08-29T16:45:13+00:00", + "updated_at": "2024-08-29T16:45:13+00:00", + "version_id": 63, + "version_type": "ProcessMaker\\Models\\ScreenVersion", + "is_self_service": 0, + "self_service_groups": [], + "token_properties": [], + "is_priority": false, + "is_actionbyemail": false, + "user_viewed_at": null, + "advanceStatus": "open", + "draft": null, + "assignable_users": [ + 3 + ], + "can_view_parent_request": false, + } + ] + } + ); + + + + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + nodeId: 'node_2', + tokenId: 2, + userId: 1, + }], + method: "redirectToTask" + }); + cy.get("[data-cy=screen-field-Interstitial").should('exist') + }); + }); \ No newline at end of file diff --git a/tests/e2e/specs/TaskRedirect.spec.js b/tests/e2e/specs/TaskRedirect.spec.js new file mode 100644 index 000000000..7821e4329 --- /dev/null +++ b/tests/e2e/specs/TaskRedirect.spec.js @@ -0,0 +1,832 @@ + +import SingleScreen from "../fixtures/single_line_input.json"; + +function initializeTaskAndScreenIntercepts(method, url, response) { + cy.intercept( + method, + url.replace(",screen,", ",").replace(",nested,", ","), + response + ); + cy.intercept( + method, + url.replace(/\?.*$/, "/screen?include=screen,nested"), + response.screen + ); +} +describe("On Task Completed (Submitting Task) ", () => { + it("Element destination type is taskList", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: 'taskList', + value: 'http://localhost:5173/tasks', + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + nodeId: 'node_2', + tokenId: 2, + userId: 1, + }], + method: "redirectToTask" + }); + cy.url().should("eq", "http://localhost:5173/tasks"); + }); + it("Element destination type is processLaunchpad", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: 'processLaunchpad', + value: "http://localhost:5173/process-browser/7?categorySelected=-1", + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + nodeId: 'node_2', + tokenId: 2, + userId: 1, + }], + method: "redirectToTask" + }); + cy.url().should("eq", "http://localhost:5173/process-browser/7?categorySelected=-1"); + }); + it("Element destination type is homepageDashboard", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: 'homepageDashboard', + value: "http://localhost:5173", + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + nodeId: 'node_2', + tokenId: 2, + userId: 1, + }], + method: "redirectToTask" + }); + cy.url().should("eq", "http://localhost:5173/"); + }); + it("Element destination type is customDashboard", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: 'customDashboard', + value: "http://localhost:5173/home/customize-ui/dashboards/eHEXsFrIwmClHoTRnMvOdMKSPbR3HalSFxaIHYxNh67UrtloUiuDBh5N8NrMoQVP", + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + nodeId: 'node_2', + tokenId: 2, + userId: 1, + }], + method: "redirectToTask" + }); + cy.url().should("eq", "http://localhost:5173/home/customize-ui/dashboards/eHEXsFrIwmClHoTRnMvOdMKSPbR3HalSFxaIHYxNh67UrtloUiuDBh5N8NrMoQVP"); + }); + it("Element destination type is externalURL", () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: 'externalURL', + value: "http://localhost:5173/about", + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + + cy.visit("/?scenario=TaskRedirect", {}); + + cy.get(".form-group").find("button").click(); + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + nodeId: 'node_2', + tokenId: 2, + userId: 1, + }], + method: "redirectToTask" + }); + cy.url().should("eq", "http://localhost:5173/about"); + }); + it("Element destination type is taskSource case 1(redirect to task list if the next user is not assigned to the same user)" , () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: "taskSource", + value: "taskSource", + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks?user_id=1&process_request_id=1&page=1&per_page=1&status=ACTIVE", + { + "data": [ + { + "id": 585, + "uuid": "9ce21eaf-0991-495c-9f11-2e47b409acd5", + "user_id": 3, + "process_id": 7, + "process_request_id": 194, + "subprocess_request_id": null, + "element_id": "node_117", + "element_type": "task", + "element_name": "Form Task 222", + "status": "ACTIVE", + "element_index": 0, + "subprocess_start_event_id": null, + "completed_at": null, + "due_at": "2024-09-01T16:45:13+00:00", + "due_notified": 0, + "initiated_at": null, + "riskchanges_at": "2024-08-31T18:45:13+00:00", + "created_at": "2024-08-29T16:45:13+00:00", + "updated_at": "2024-08-29T16:45:13+00:00", + "version_id": 63, + "version_type": "ProcessMaker\\Models\\ScreenVersion", + "is_self_service": 0, + "self_service_groups": [], + "token_properties": [], + "is_priority": false, + "is_actionbyemail": false, + "user_viewed_at": null, + "advanceStatus": "open", + "process_request": { + "id": 194, + "uuid": "9ce21e35-087d-45dd-b1ed-f2874307e293", + "process_id": 7, + "process_collaboration_id": null, + "collaboration_uuid": null, + "user_id": 1, + "parent_request_id": null, + "participant_id": null, + "callable_id": "ProcessId", + "status": "ACTIVE", + "name": "processTL", + "do_not_sanitize": [], + "errors": null, + "completed_at": null, + "initiated_at": "2024-08-29T16:43:53+00:00", + "created_at": "2024-08-29T16:43:53+00:00", + "updated_at": "2024-08-29T16:45:13+00:00", + "process_version_id": 129, + "signal_events": [], + "case_title": "Case #182", + "case_number": 182, + "case_title_formatted": "Case #182<\/b>", + "process": { + "id": 7, + "uuid": "9cdc0e74-0e60-4a33-a6e6-71c96b6b7330", + "process_category_id": "2", + "user_id": 1, + "description": "test", + "name": "processTL", + "cancel_screen_id": null, + "request_detail_screen_id": null, + "status": "ACTIVE", + "is_valid": 1, + "package_key": null, + "pause_timer_start": 0, + "deleted_at": null, + "created_at": "2024-08-26T16:24:52+00:00", + "updated_at": "2024-08-29T16:43:37+00:00", + "updated_by": 1, + "start_events": [ + { + "id": "node_91", + "name": "Start Event", + "config": "{\"web_entry\":null}", + "ownerProcessId": "ProcessId", + "eventDefinitions": [], + "ownerProcessName": "ProcessName", + "allowInterstitial": "false", + "interstitialScreenRef": "1" + } + ], + "self_service_tasks": [], + "signal_events": [], + "conditional_events": [], + "properties": { + "manager_id": "undefined" + }, + "is_template": 0, + "case_title": null, + "launchpad_properties": null, + "asset_type": null, + "alternative": "A", + "has_timer_start_events": false, + "projects": "[]" + } + }, + "process": { + "id": 7, + "uuid": "9cdc0e74-0e60-4a33-a6e6-71c96b6b7330", + "process_category_id": "2", + "user_id": 1, + "description": "test", + "name": "processTL", + "cancel_screen_id": null, + "request_detail_screen_id": null, + "status": "ACTIVE", + "is_valid": 1, + "package_key": null, + "pause_timer_start": 0, + "deleted_at": null, + "created_at": "2024-08-26T16:24:52+00:00", + "updated_at": "2024-08-29T16:43:37+00:00", + "updated_by": 1, + "start_events": [ + { + "id": "node_91", + "name": "Start Event", + "config": "{\"web_entry\":null}", + "ownerProcessId": "ProcessId", + "eventDefinitions": [], + "ownerProcessName": "ProcessName", + "allowInterstitial": "false", + "interstitialScreenRef": "1" + } + ], + "self_service_tasks": [], + "signal_events": [], + "conditional_events": [], + "properties": { + "manager_id": "undefined" + }, + "is_template": 0, + "case_title": null, + "launchpad_properties": null, + "asset_type": null, + "alternative": "A", + "has_timer_start_events": false, + "projects": "[]" + }, + "user": { + "id": 3, + "uuid": "9cdee13e-7aff-4d09-9322-0257e4a4996f", + "email": "homero@simpsom.com", + "firstname": "homero", + "lastname": "simpsom", + "username": "homero", + "status": "ACTIVE", + "address": null, + "city": null, + "state": null, + "postal": null, + "country": null, + "phone": null, + "fax": null, + "cell": null, + "title": "none", + "birthdate": null, + "timezone": "UTC", + "datetime_format": "m\/d\/Y H:i", + "language": "en", + "meta": null, + "connected_accounts": null, + "is_administrator": true, + "is_system": 0, + "expires_at": null, + "loggedin_at": "2024-08-28T02:09:33+00:00", + "active_at": "2024-08-28T02:25:55+00:00", + "remember_token": null, + "created_at": "2024-08-28T02:05:56+00:00", + "updated_at": "2024-08-28T02:06:05+00:00", + "deleted_at": null, + "delegation_user_id": null, + "manager_id": null, + "schedule": null, + "force_change_password": 0, + "avatar": null, + "password_changed_at": "2024-08-28 02:05:56", + "preferences_2fa": null, + "fullname": "homero simpsom" + }, + "draft": null, + "assignable_users": [ + 3 + ], + "can_view_parent_request": false + } + ], + "meta": { + "filter": "", + "sort_by": "due_at", + "sort_order": "asc", + "count": 1, + "total_pages": 1, + "in_overdue": 0, + "current_page": 1, + "from": 1, + "last_page": 1, + "links": [ + { + "url": null, + "label": "« Previous", + "active": false + }, + { + "url": "http:\/\/processmaker.test\/api\/1.0\/tasks?page=1", + "label": "1", + "active": true + }, + { + "url": null, + "label": "Next »", + "active": false + } + ], + "path": "http:\/\/processmaker.test\/api\/1.0\/tasks", + "per_page": 15, + "to": 1, + "total": 1 + } +} + ); + + + cy.visit("/?scenario=TaskRedirect", { + onBeforeLoad: function (window) { + sessionStorage.removeItem('sessionUrlSelfService'); + } + }); + cy.get(".form-group").find("button").click(); + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + nodeId: 'node_2', + tokenId: 2, + userId: 2, + }], + method: "redirectToTask" + }); + cy.url().should("eq", "http://localhost:5173/tasks"); + }); + it("Element destination type is taskSource case 2(redirect to previous page if the next task is not assigned to the same user)" , () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: "taskSource", + value: "taskSource", + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks?user_id=1&process_request_id=1&page=1&per_page=1&status=ACTIVE", + { + "data": [ + { + "id": 585, + "uuid": "9ce21eaf-0991-495c-9f11-2e47b409acd5", + "user_id": 3, + "process_id": 7, + "process_request_id": 194, + "subprocess_request_id": null, + "element_id": "node_117", + "element_type": "task", + "element_name": "Form Task 222", + "status": "ACTIVE", + "element_index": 0, + "subprocess_start_event_id": null, + "completed_at": null, + "due_at": "2024-09-01T16:45:13+00:00", + "due_notified": 0, + "initiated_at": null, + "riskchanges_at": "2024-08-31T18:45:13+00:00", + "created_at": "2024-08-29T16:45:13+00:00", + "updated_at": "2024-08-29T16:45:13+00:00", + "version_id": 63, + "version_type": "ProcessMaker\\Models\\ScreenVersion", + "is_self_service": 0, + "self_service_groups": [], + "token_properties": [], + "is_priority": false, + "is_actionbyemail": false, + "user_viewed_at": null, + "advanceStatus": "open", + "process_request": { + "id": 194, + "uuid": "9ce21e35-087d-45dd-b1ed-f2874307e293", + "process_id": 7, + "process_collaboration_id": null, + "collaboration_uuid": null, + "user_id": 1, + "parent_request_id": null, + "participant_id": null, + "callable_id": "ProcessId", + "status": "ACTIVE", + "name": "processTL", + "do_not_sanitize": [], + "errors": null, + "completed_at": null, + "initiated_at": "2024-08-29T16:43:53+00:00", + "created_at": "2024-08-29T16:43:53+00:00", + "updated_at": "2024-08-29T16:45:13+00:00", + "process_version_id": 129, + "signal_events": [], + "case_title": "Case #182", + "case_number": 182, + "case_title_formatted": "Case #182<\/b>", + "process": { + "id": 7, + "uuid": "9cdc0e74-0e60-4a33-a6e6-71c96b6b7330", + "process_category_id": "2", + "user_id": 1, + "description": "test", + "name": "processTL", + "cancel_screen_id": null, + "request_detail_screen_id": null, + "status": "ACTIVE", + "is_valid": 1, + "package_key": null, + "pause_timer_start": 0, + "deleted_at": null, + "created_at": "2024-08-26T16:24:52+00:00", + "updated_at": "2024-08-29T16:43:37+00:00", + "updated_by": 1, + "start_events": [ + { + "id": "node_91", + "name": "Start Event", + "config": "{\"web_entry\":null}", + "ownerProcessId": "ProcessId", + "eventDefinitions": [], + "ownerProcessName": "ProcessName", + "allowInterstitial": "false", + "interstitialScreenRef": "1" + } + ], + "self_service_tasks": [], + "signal_events": [], + "conditional_events": [], + "properties": { + "manager_id": "undefined" + }, + "is_template": 0, + "case_title": null, + "launchpad_properties": null, + "asset_type": null, + "alternative": "A", + "has_timer_start_events": false, + "projects": "[]" + } + }, + "process": { + "id": 7, + "uuid": "9cdc0e74-0e60-4a33-a6e6-71c96b6b7330", + "process_category_id": "2", + "user_id": 1, + "description": "test", + "name": "processTL", + "cancel_screen_id": null, + "request_detail_screen_id": null, + "status": "ACTIVE", + "is_valid": 1, + "package_key": null, + "pause_timer_start": 0, + "deleted_at": null, + "created_at": "2024-08-26T16:24:52+00:00", + "updated_at": "2024-08-29T16:43:37+00:00", + "updated_by": 1, + "start_events": [ + { + "id": "node_91", + "name": "Start Event", + "config": "{\"web_entry\":null}", + "ownerProcessId": "ProcessId", + "eventDefinitions": [], + "ownerProcessName": "ProcessName", + "allowInterstitial": "false", + "interstitialScreenRef": "1" + } + ], + "self_service_tasks": [], + "signal_events": [], + "conditional_events": [], + "properties": { + "manager_id": "undefined" + }, + "is_template": 0, + "case_title": null, + "launchpad_properties": null, + "asset_type": null, + "alternative": "A", + "has_timer_start_events": false, + "projects": "[]" + }, + "user": { + "id": 3, + "uuid": "9cdee13e-7aff-4d09-9322-0257e4a4996f", + "email": "homero@simpsom.com", + "firstname": "homero", + "lastname": "simpsom", + "username": "homero", + "status": "ACTIVE", + "address": null, + "city": null, + "state": null, + "postal": null, + "country": null, + "phone": null, + "fax": null, + "cell": null, + "title": "none", + "birthdate": null, + "timezone": "UTC", + "datetime_format": "m\/d\/Y H:i", + "language": "en", + "meta": null, + "connected_accounts": null, + "is_administrator": true, + "is_system": 0, + "expires_at": null, + "loggedin_at": "2024-08-28T02:09:33+00:00", + "active_at": "2024-08-28T02:25:55+00:00", + "remember_token": null, + "created_at": "2024-08-28T02:05:56+00:00", + "updated_at": "2024-08-28T02:06:05+00:00", + "deleted_at": null, + "delegation_user_id": null, + "manager_id": null, + "schedule": null, + "force_change_password": 0, + "avatar": null, + "password_changed_at": "2024-08-28 02:05:56", + "preferences_2fa": null, + "fullname": "homero simpsom" + }, + "draft": null, + "assignable_users": [ + 3 + ], + "can_view_parent_request": false + } + ], + "meta": { + "filter": "", + "sort_by": "due_at", + "sort_order": "asc", + "count": 1, + "total_pages": 1, + "in_overdue": 0, + "current_page": 1, + "from": 1, + "last_page": 1, + "links": [ + { + "url": null, + "label": "« Previous", + "active": false + }, + { + "url": "http:\/\/processmaker.test\/api\/1.0\/tasks?page=1", + "label": "1", + "active": true + }, + { + "url": null, + "label": "Next »", + "active": false + } + ], + "path": "http:\/\/processmaker.test\/api\/1.0\/tasks", + "per_page": 15, + "to": 1, + "total": 1 + } + } + ); + + + cy.visit("/?scenario=TaskRedirect", { + onBeforeLoad: function (window) { + sessionStorage.removeItem('sessionUrlSelfService'); + sessionStorage.setItem('sessionUrlSelfService', "http://localhost:5173/about"); + } + }); + cy.get(".form-group").find("button").click(); + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + nodeId: 'node_2', + tokenId: 2, + userId: 2, + }], + method: "redirectToTask" + }); + cy.url().should("eq", "http://localhost:5173/about"); + sessionStorage.removeItem("sessionUrlSelfService"); + }); + it("Element destination type is taskSource case 3(redirect to next task if the next task is assigned to the same user)" , () => { + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination", + { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: "taskSource", + value: "taskSource", + }, + user: { + id: 1 + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE" + } + } + ); + initializeTaskAndScreenIntercepts( + "GET", + "http://localhost:5173/api/1.1/tasks/2?include=data,user,draft,requestor,processRequest,component,requestData,loopContext,bpmnTagName,interstitial,definition,userRequestPermission,elementDestination", + { + "data": [ + { + "id": 585, + "uuid": "9ce21eaf-0991-495c-9f11-2e47b409acd5", + "user_id": 1, + "process_id": 7, + "process_request_id": 194, + "subprocess_request_id": null, + "element_id": "node_117", + "element_type": "task", + "element_name": "Form Task 222", + "status": "ACTIVE", + "element_index": 0, + "subprocess_start_event_id": null, + "completed_at": null, + "due_at": "2024-09-01T16:45:13+00:00", + "due_notified": 0, + "initiated_at": null, + "riskchanges_at": "2024-08-31T18:45:13+00:00", + "created_at": "2024-08-29T16:45:13+00:00", + "updated_at": "2024-08-29T16:45:13+00:00", + "version_id": 63, + "version_type": "ProcessMaker\\Models\\ScreenVersion", + "is_self_service": 0, + "self_service_groups": [], + "token_properties": [], + "is_priority": false, + "is_actionbyemail": false, + "user_viewed_at": null, + "advanceStatus": "open", + "draft": null, + "assignable_users": [ + 3 + ], + "can_view_parent_request": false, + } + ] + } + + ); + + + cy.visit("/?scenario=TaskRedirect", { + onBeforeLoad: function (window) { + sessionStorage.removeItem('sessionUrlSelfService'); + } + }); + cy.get(".form-group").find("button").click(); + + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [{ + nodeId: 'node_2', + tokenId: 2, + userId: 1, + }], + method: "redirectToTask" + }); + cy.url().should("eq", "http://localhost:5173/?scenario=TaskRedirect"); + }); +}); \ No newline at end of file diff --git a/tests/e2e/specs/WebEntryEndEventRedirect.spec.js b/tests/e2e/specs/WebEntryEndEventRedirect.spec.js new file mode 100644 index 000000000..52a6162de --- /dev/null +++ b/tests/e2e/specs/WebEntryEndEventRedirect.spec.js @@ -0,0 +1,56 @@ +import SingleScreen from "../fixtures/single_line_input.json"; + +function initializeTaskAndScreenIntercepts(method, url, response) { + cy.intercept(method, url.replace(",screen,", ",").replace(",nested,", ","), response).as('getTask'); + cy.intercept(method, url.replace(/\?.*$/, "/screen?include=screen,nested"), response.screen).as('getScreen'); +} + +describe("End Event Redirect (Process completed)", () => { + beforeEach(() => { + // Reset the intercepts and the state before each test + cy.visit("/?scenario=TaskWebEntry", {}); + }); + + it("Element destination type is summaryScreen and process was opened from webEntry", () => { + const taskUrl = "http://localhost:5173/api/1.1/tasks/1?include=data,user,draft,requestor,processRequest,component,screen,requestData,loopContext,bpmnTagName,interstitial,definition,nested,userRequestPermission,elementDestination"; + + initializeTaskAndScreenIntercepts("GET", taskUrl, { + id: 1, + advanceStatus: "open", + component: "task-screen", + allow_interstitial: false, + elementDestination: { + type: "taskList", + value: "http://localhost:5173/tasks", + }, + user: { + id: 1, + }, + screen: SingleScreen.screens[0], + process_request: { + id: 1, + status: "ACTIVE", + }, + }); + + // Interact with the UI + cy.get('.form-group > .btn').click(); + + // Emit socket event and verify the URL change + cy.socketEventNext("ProcessMaker\\Events\\RedirectTo", { + params: [ + { + endEventDestination: { + type: "summaryScreen", + value: null, + }, + }, + ], + method: "processCompletedRedirect", + }) + cy.wait(1000); + // This code will execute after the socket event is finished + cy.url().should("eq", "http://localhost:5173/?scenario=TaskWebEntry"); + + }); +}); diff --git a/tests/e2e/support/commands.js b/tests/e2e/support/commands.js index 48e2910cb..4ce0931a8 100644 --- a/tests/e2e/support/commands.js +++ b/tests/e2e/support/commands.js @@ -65,6 +65,11 @@ Cypress.Commands.add("socketEvent", (event, body) => { }); }); +Cypress.Commands.add("socketEventNext", (event, body) => { + cy.window().then((win) => { + win.Echo.eventMockNext(event, body); + }); +}); /** * Converts Cypress fixtures, including JSON, to a Blob. All file types are * converted to base64 then converted to a Blob using Cypress @@ -74,7 +79,7 @@ Cypress.Commands.add("socketEvent", (event, body) => { * @param {String} type - content type of the uploaded file * @return {Promise} Resolves with blob containing fixture contents */ -function getFixtureBlob(fileUrl, type) { +function getFixtureBlob(fileUrl, type, c) { return type === "application/json" ? cy .fixture(fileUrl) From 620b2ad08cd14c6f28acfd427d0278dade5179e8 Mon Sep 17 00:00:00 2001 From: Rodrigo Quelca Date: Tue, 29 Oct 2024 14:57:37 -0400 Subject: [PATCH 24/27] clean code --- src/components/task.vue | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/task.vue b/src/components/task.vue index 934fa3069..7095e06e9 100644 --- a/src/components/task.vue +++ b/src/components/task.vue @@ -843,7 +843,6 @@ export default { * @param {Object} data - The event data received from the socket listener. */ handleRedirect(data) { - debugger; switch (data.method) { case 'redirectToTask': this.handleRedirectToTask(data); @@ -852,7 +851,6 @@ export default { this.handleProcessUpdated(data); break; case 'processCompletedRedirect': - debugger; this.processCompletedRedirect( data.params[0], this.userId, From 584cd743b60b4d50dbb1df7bc3f6b01f287b6fe8 Mon Sep 17 00:00:00 2001 From: Rodrigo Quelca Date: Tue, 29 Oct 2024 16:38:53 -0400 Subject: [PATCH 25/27] restore getFixtureBlob --- tests/e2e/support/commands.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/support/commands.js b/tests/e2e/support/commands.js index 4ce0931a8..6a9da03a5 100644 --- a/tests/e2e/support/commands.js +++ b/tests/e2e/support/commands.js @@ -79,7 +79,7 @@ Cypress.Commands.add("socketEventNext", (event, body) => { * @param {String} type - content type of the uploaded file * @return {Promise} Resolves with blob containing fixture contents */ -function getFixtureBlob(fileUrl, type, c) { +function getFixtureBlob(fileUrl, type) { return type === "application/json" ? cy .fixture(fileUrl) From 7e396e5ba40d91e671df4038a94e8db9905f3271 Mon Sep 17 00:00:00 2001 From: Ryan Cooley Date: Wed, 30 Oct 2024 22:22:26 -0700 Subject: [PATCH 26/27] Update VFE --- package-lock.json | 10 +++++----- package.json | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index c94fa7c25..da0ab20fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "@fortawesome/fontawesome-free": "^5.6.1", "@originjs/vite-plugin-commonjs": "^1.0.3", "@panter/vue-i18next": "^0.15.2", - "@processmaker/vue-form-elements": "0.61.0", + "@processmaker/vue-form-elements": "0.61.1", "@processmaker/vue-multiselect": "2.3.0", "@storybook/addon-essentials": "^7.6.13", "@storybook/addon-interactions": "^7.6.13", @@ -97,7 +97,7 @@ }, "peerDependencies": { "@panter/vue-i18next": "^0.15.0", - "@processmaker/vue-form-elements": "0.61.0", + "@processmaker/vue-form-elements": "0.61.1", "i18next": "^15.0.8", "vue": "^2.6.12", "vuex": "^3.1.1" @@ -4015,9 +4015,9 @@ } }, "node_modules/@processmaker/vue-form-elements": { - "version": "0.61.0", - "resolved": "https://registry.npmjs.org/@processmaker/vue-form-elements/-/vue-form-elements-0.61.0.tgz", - "integrity": "sha512-n42Xtdta08phcLdG4tEXLv3pvkAvkKKhnBXV8y0L9qEc5/3Y76WoqRYqRcesIVJhrVOX3WsY0y8IGgQirGwAFQ==", + "version": "0.61.1", + "resolved": "https://registry.npmjs.org/@processmaker/vue-form-elements/-/vue-form-elements-0.61.1.tgz", + "integrity": "sha512-GnQ77kxhkoE7xjIvikL60dC2ESwYBXkTtr2GOHDnskG2cy1HwWuU/5+SfHY6Op27YVOlvlBMlwh0QCwgPmXKmg==", "dev": true, "dependencies": { "@chantouchsek/validatorjs": "1.2.3", diff --git a/package.json b/package.json index 0518a18cd..33a896d96 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "@fortawesome/fontawesome-free": "^5.6.1", "@originjs/vite-plugin-commonjs": "^1.0.3", "@panter/vue-i18next": "^0.15.2", - "@processmaker/vue-form-elements": "0.61.0", + "@processmaker/vue-form-elements": "0.61.1", "@processmaker/vue-multiselect": "2.3.0", "@storybook/addon-essentials": "^7.6.13", "@storybook/addon-interactions": "^7.6.13", @@ -116,7 +116,7 @@ }, "peerDependencies": { "@panter/vue-i18next": "^0.15.0", - "@processmaker/vue-form-elements": "0.61.0", + "@processmaker/vue-form-elements": "0.61.1", "i18next": "^15.0.8", "vue": "^2.6.12", "vuex": "^3.1.1" From 7b5d5d7d8e069cc702b7053782db216d09390bc8 Mon Sep 17 00:00:00 2001 From: Ryan Cooley Date: Wed, 30 Oct 2024 22:22:36 -0700 Subject: [PATCH 27/27] 3.0.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index da0ab20fe..13c8fbbbe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@processmaker/screen-builder", - "version": "3.0.2", + "version": "3.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@processmaker/screen-builder", - "version": "3.0.2", + "version": "3.0.3", "dependencies": { "@chantouchsek/validatorjs": "1.2.3", "@storybook/addon-docs": "^7.6.13", diff --git a/package.json b/package.json index 33a896d96..e67805b2f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@processmaker/screen-builder", - "version": "3.0.2", + "version": "3.0.3", "scripts": { "dev": "VITE_COVERAGE=true vite", "build": "vite build",