diff --git a/app/client/cypress/integration/Smoke_TestSuite/ApiPaneTests/Action_PageOnLoad_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ApiPaneTests/Action_PageOnLoad_spec.js new file mode 100644 index 0000000000..6cec9bc128 --- /dev/null +++ b/app/client/cypress/integration/Smoke_TestSuite/ApiPaneTests/Action_PageOnLoad_spec.js @@ -0,0 +1,49 @@ +const dsl = require("../../../fixtures/tableWidgetDsl.json"); + +describe("API Panel Test Functionality", function() { + before(() => { + cy.addDsl(dsl); + }); + it("Will load an api on load", function() { + cy.NavigateToAPI_Panel(); + cy.CreateAPI("PageLoadApi"); + cy.enterDatasourceAndPath("https://reqres.in/api/", "users"); + cy.WaitAutoSave(); + cy.get("li:contains('Settings')").click({ force: true }); + cy.get("[data-cy=executeOnLoad]") + .find(".bp3-switch") + .click(); + + cy.wait("@setExecuteOnLoad"); + + cy.SearchEntityandOpen("Table1"); + cy.testJsontext("tabledata", "{{PageLoadApi.data.data"); + + cy.wait("@updateLayout"); + + cy.reload(); + cy.wait("@postExecute").should( + "have.nested.property", + "response.body.responseMeta.status", + 200, + ); + }); + + it("Will not crash the app for failure", function() { + cy.SearchEntityandOpen("PageLoadApi"); + cy.get("li:contains('Settings')").click({ force: true }); + cy.get("[data-cy='actionConfiguration.timeoutInMillisecond']") + .find(".bp3-input") + .type("{backspace}{backspace}{backspace}"); + + cy.NavigateToAPI_Panel(); + cy.CreateAPI("NormalApi"); + cy.enterDatasourceAndPath("https://reqres.in/api/", "users"); + cy.WaitAutoSave(); + + cy.reload(); + cy.wait("@postExecute"); + cy.RunAPI(); + cy.ResponseStatusCheck("200 OK"); + }); +}); diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index 4c8162d0ab..74945651a4 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -1668,6 +1668,7 @@ Cypress.Commands.add("startServerAndRoutes", () => { cy.route("POST", "/track/*").as("postTrack"); cy.route("POST", "/api/v1/actions/execute").as("postExecute"); + cy.route("PUT", "/api/v1/actions/executeOnLoad/*").as("setExecuteOnLoad"); cy.route("POST", "/api/v1/actions").as("createNewApi"); cy.route("POST", "/api/v1/import?type=CURL&pageId=*&name=*").as("curlImport"); diff --git a/app/client/src/api/Api.tsx b/app/client/src/api/Api.tsx index 4d23eb78b2..ac312b5e1b 100644 --- a/app/client/src/api/Api.tsx +++ b/app/client/src/api/Api.tsx @@ -117,24 +117,27 @@ class Api { static get( url: string, queryParams?: any, - config?: Partial, + config: Partial = {}, ) { - return axiosInstance.get( - url + convertObjectToQueryParams(queryParams), - _.merge(apiRequestConfig, config), - ); + return axiosInstance.get(url + convertObjectToQueryParams(queryParams), { + ...apiRequestConfig, + ...config, + }); } static post( url: string, body?: any, queryParams?: any, - config?: Partial, + config: Partial = {}, ) { return axiosInstance.post( url + convertObjectToQueryParams(queryParams), body, - _.merge(apiRequestConfig, config), + { + ...apiRequestConfig, + ...config, + }, ); } @@ -142,24 +145,27 @@ class Api { url: string, body?: any, queryParams?: any, - config?: Partial, + config: Partial = {}, ) { return axiosInstance.put( url + convertObjectToQueryParams(queryParams), body, - _.merge(apiRequestConfig, config), + { + ...apiRequestConfig, + ...config, + }, ); } static delete( url: string, queryParams?: any, - config?: Partial, + config: Partial = {}, ) { - return axiosInstance.delete( - url + convertObjectToQueryParams(queryParams), - _.merge(apiRequestConfig, config), - ); + return axiosInstance.delete(url + convertObjectToQueryParams(queryParams), { + ...apiRequestConfig, + ...config, + }); } } diff --git a/app/client/src/components/formControls/InputTextControl.tsx b/app/client/src/components/formControls/InputTextControl.tsx index e9ef0600b6..52a7bcb4a7 100644 --- a/app/client/src/components/formControls/InputTextControl.tsx +++ b/app/client/src/components/formControls/InputTextControl.tsx @@ -18,7 +18,7 @@ export function InputText(props: { const { name, placeholder, dataType, label, isRequired } = props; return ( -
+
{label} {isRequired && "*"} diff --git a/app/client/src/sagas/ActionExecutionSagas.ts b/app/client/src/sagas/ActionExecutionSagas.ts index 86cac74ffd..b5eb22791b 100644 --- a/app/client/src/sagas/ActionExecutionSagas.ts +++ b/app/client/src/sagas/ActionExecutionSagas.ts @@ -671,21 +671,29 @@ function* executePageLoadAction(pageAction: PageAction) { } function* executePageLoadActionsSaga(action: ReduxAction) { - const pageActions = action.payload; - const actionCount = _.flatten(pageActions).length; - PerformanceTracker.startAsyncTracking( - PerformanceTransactionName.EXECUTE_PAGE_LOAD_ACTIONS, - { numActions: actionCount }, - ); - for (const actionSet of pageActions) { - // Load all sets in parallel - yield* yield all( - actionSet.map(apiAction => call(executePageLoadAction, apiAction)), + try { + const pageActions = action.payload; + const actionCount = _.flatten(pageActions).length; + PerformanceTracker.startAsyncTracking( + PerformanceTransactionName.EXECUTE_PAGE_LOAD_ACTIONS, + { numActions: actionCount }, ); + for (const actionSet of pageActions) { + // Load all sets in parallel + yield* yield all( + actionSet.map(apiAction => call(executePageLoadAction, apiAction)), + ); + } + PerformanceTracker.stopAsyncTracking( + PerformanceTransactionName.EXECUTE_PAGE_LOAD_ACTIONS, + ); + } catch (e) { + log.error(e); + AppToaster.show({ + message: "Failed to load onPageLoad actions", + type: ToastType.ERROR, + }); } - PerformanceTracker.stopAsyncTracking( - PerformanceTransactionName.EXECUTE_PAGE_LOAD_ACTIONS, - ); } export function* watchActionExecutionSagas() {