Repository: GoogleCloudDataproc/dataproc-jupyter-plugin (language: python)

Issue:
Sprint8 review comments



Discussion / hints:

Fix patch:
diff --git a/dataproc_plugin/handlers.py b/dataproc_plugin/handlers.py
index 210bcf23..858dc1d8 100644
--- a/dataproc_plugin/handlers.py
+++ b/dataproc_plugin/handlers.py
@@ -78,7 +78,7 @@ def get_cached_credentials():
                         'access_token': '',
                         'config_error': 0,
                         'login_error': 1
-                            }
+                        }
             else:
                 credentials = {
                 'project_id': '',
@@ -135,15 +135,16 @@ def get(self):
         cmd = "gcloud auth login"
         process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
         output, _ = process.communicate()
-         # Check if the authentication was successful
+        # Check if the authentication was successful
         if process.returncode == 0:
-            self.finish({'login':'SUCCEEDED'})
+            self.finish({'login' : 'SUCCEEDED'})
         else:
-            self.finish({'login':'FAILED'})
+            self.finish({'login' : 'FAILED'})
 
 class ConfigHandler(APIHandler):
     @tornado.web.authenticated
     def post(self):
+        ERROR_MESSAGE = "Project and region update "
         global credentials_cache
         input_data = self.get_json_body()
         project_id = input_data["projectId"]
@@ -157,20 +158,17 @@ def post(self):
             output, _ = region_set.communicate()
             if region_set.returncode == 0:
                 credentials_cache = None
-                self.finish({'config':'Project and Region Updated Successfully'})
+                self.finish({'config' : ERROR_MESSAGE + 'successful'})
             else:
-                self.finish({'config':'Project and Region Updation Failed'})
+                self.finish({'config' : ERROR_MESSAGE + 'failed'})
         else:
-            self.finish({'config':'Project and Region Updation Failed'})
+            self.finish({'config' : ERROR_MESSAGE + 'failed'})
 
 
 def setup_handlers(web_app):
     host_pattern = ".*$"
 
     base_url = web_app.settings["base_url"]
-    route_pattern = url_path_join(base_url, "dataproc-plugin", "get-example")
-    handlers = [(route_pattern, RouteHandler)]
-    web_app.add_handlers(host_pattern, handlers)
 
     # Prepend the base_url so that it works in a JupyterHub setting
     route_pattern = url_path_join(base_url, "dataproc-plugin", "credentials")
@@ -184,7 +182,3 @@ def setup_handlers(web_app):
     route_pattern = url_path_join(base_url, "dataproc-plugin", "configuration")
     handlers = [(route_pattern, ConfigHandler)]
     web_app.add_handlers(host_pattern, handlers)
-
-    route_pattern = url_path_join(base_url, "dataproc-plugin", "get-example")
-    handlers = [(route_pattern, TestHandler)]
-    web_app.add_handlers(host_pattern, handlers)
diff --git a/package.json b/package.json
index fc04b529..dffadfa2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "dataproc_plugin",
-  "version": "1.0.4",
+  "version": "1.0.5",
   "description": "It is a plugin to work with dataproc services in Jupyterlab",
   "keywords": [
     "jupyter",
diff --git a/pyproject.toml b/pyproject.toml
index be488a36..e5113254 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -22,7 +22,10 @@ classifiers = [
     "Programming Language :: Python :: 3.11",
 ]
 dependencies = [
-    "jupyter_server>=2.0.1,<3"
+    "jupyter_server>=2.0.1,<3",
+    "cachetools>=5.0.0",
+    "google-cloud==0.34.0",
+    "kernels_mixer @ git+https://github.com/GoogleCloudPlatform/jupyter-extensions.git@master#subdirectory=kernels_mixer"
 ]
 dynamic = ["version", "description", "authors", "urls", "keywords"]
 
@@ -41,6 +44,9 @@ source = "nodejs"
 [tool.hatch.metadata.hooks.nodejs]
 fields = ["description", "authors", "urls"]
 
+[tool.hatch.metadata]
+allow-direct-references = true
+
 [tool.hatch.build.targets.sdist]
 artifacts = ["dataproc_plugin/labextension"]
 exclude = [".github", "binder"]
diff --git a/src/batches/batchDetails.tsx b/src/batches/batchDetails.tsx
index 29602dc5..85f37984 100644
--- a/src/batches/batchDetails.tsx
+++ b/src/batches/batchDetails.tsx
@@ -29,6 +29,7 @@ import {
   BASE_URL,
   NETWORK_KEY,
   NETWORK_LABEL,
+  POLLING_TIME_LIMIT,
   SERVICE_ACCOUNT_KEY,
   SERVICE_ACCOUNT_LABEL,
   SUBNETWORK_KEY,
@@ -119,14 +120,32 @@ function BatchDetails({
   const [isLoading, setIsLoading] = useState(true);
   const [deletePopupOpen, setDeletePopupOpen] = useState(false);
   const [selectedBatch, setSelectedBatch] = useState('');
+  const [timer, setTimer] = useState<NodeJS.Timer | undefined>(undefined);
+  const pollingBatchDetails = async (
+    pollingFunction: () => void,
+    pollingDisable: boolean
+  ) => {
+    if (pollingDisable) {
+      clearInterval(timer);
+    } else {
+      setTimer(setInterval(pollingFunction, POLLING_TIME_LIMIT));
+    }
+  };
 
   const handleDetailedBatchView = () => {
+    pollingBatchDetails(getBatchDetails, true);
     setDetailedBatchView(false);
   };
 
   useEffect(() => {
     getBatchDetails();
+    pollingBatchDetails(getBatchDetails, false);
+
+    return () => {
+      pollingBatchDetails(getBatchDetails, true);
+    };
   }, []);
+
   const getBatchDetails = async () => {
     const credentials = await authApi();
     if (credentials) {
@@ -162,31 +181,37 @@ function BatchDetails({
         .catch((err: Error) => {
           setIsLoading(false);
           console.error('Error in getting Batch details', err);
-          toast.error('Failed to fetch Batch details');
+          toast.error(`Failed to fetch batch details ${batchSelected}`);
         });
     }
   };
 
-  const statusMsg = statusMessageBatch(batchInfoResponse);
+const statusMsg = statusMessageBatch(batchInfoResponse);
   const startTime = jobTimeFormat(batchInfoResponse.createTime);
-  const startTimeElapsed = new Date(batchInfoResponse.createTime);
-  const endTime = batchInfoResponse.stateTime;
-  let jobStartTime;
-  let runTimeString = '';
-  if (batchInfoResponse.stateHistory) {
-    jobStartTime = new Date(
-      batchInfoResponse.stateHistory[
-        batchInfoResponse.stateHistory.length - 1
-      ].stateStartTime
-    );
-    runTimeString = elapsedTime(endTime, jobStartTime);
-  }
-  const batch = BatchTypeValue(batchInfoResponse);
+const startTimeElapsed = new Date(batchInfoResponse.createTime);
+
+const endTime = new Date(batchInfoResponse.stateTime);
+
+let jobStartTime: Date;
+let runTimeString = '';
+
+if (batchInfoResponse.stateHistory) {
+  const lastStateHistory = batchInfoResponse.stateHistory[
+    batchInfoResponse.stateHistory.length - 1
+  ];
+  jobStartTime = new Date(lastStateHistory.stateStartTime);
+  runTimeString = elapsedTime(endTime, jobStartTime);
+}
+
+const batch = BatchTypeValue(batchInfoResponse);
+
+const elapsedTimeString = elapsedTime(
+  new Date(batchInfoResponse.stateTime),
+  startTimeElapsed
+);
+
+
 
-  const elapsedTimeString = elapsedTime(
-    batchInfoResponse.stateTime,
-    startTimeElapsed
-  );
 
   const handleDeleteBatch = (batchSelected: string) => {
     setSelectedBatch(batchSelected);
@@ -235,6 +260,7 @@ function BatchDetails({
         <div className="scroll-comp">
           <div className="cluster-details-header">
             <div
+              role="button"
               className="back-arrow-icon"
               onClick={() => handleDetailedBatchView()}
             >
@@ -249,6 +275,7 @@ function BatchDetails({
             </div>
 
             <div
+              role="button"
               className="action-cluster-section"
               onClick={() => handleDeleteBatch(batchSelected)}
             >
@@ -355,7 +382,7 @@ function BatchDetails({
             {batch === 'Spark' && batchInfoResponse.sparkBatch.mainClass && (
               <>
                 <div className="row-details">
-                  <div className="details-label">Main Class</div>
+                  <div className="details-label">Main class</div>
                   <div className="details-value">
                     {batchInfoResponse.sparkBatch.mainClass}
                   </div>
diff --git a/src/batches/batches.tsx b/src/batches/batches.tsx
index 4e29b7a8..b168a883 100644
--- a/src/batches/batches.tsx
+++ b/src/batches/batches.tsx
@@ -47,7 +47,7 @@ const iconDelete = new LabIcon({
   svgstr: deleteIcon
 });
 
-const ServerlessComponent = (): React.JSX.Element => {
+const BatchesComponent = (): React.JSX.Element => {
   const [batchesList, setBatchesList] = useState([]);
   const [selectedMode, setSelectedMode] = useState('Batches');
   const [isLoading, setIsLoading] = useState(true);
@@ -103,31 +103,37 @@ const ServerlessComponent = (): React.JSX.Element => {
             .json()
             .then((responseResult: any) => {
               let transformBatchListData = [];
-              transformBatchListData = responseResult.batches.map(
-                (data: any) => {
-                  const startTimeDisplay = jobTimeFormat(data.createTime);
-                  const startTime = new Date(data.createTime);
-                  const elapsedTimeString = elapsedTime(
-                    data.stateTime,
-                    startTime
-                  );
-                  const batchType = Object.keys(data).filter(key =>
-                    key.endsWith('Batch')
-                  );
-                  const batchTypeDisplay = jobTypeDisplay(
-                    batchType[0].split('Batch')[0]
-                  );
-                  return {
-                    batchID: data.name.split('/')[5],
-                    status: data.state,
-                    location: data.name.split('/')[3],
-                    creationTime: startTimeDisplay,
-                    type: batchTypeDisplay,
-                    elapsedTime: elapsedTimeString,
-                    actions: renderActions(data)
-                  };
-                }
-              );
+              if (responseResult && responseResult.batches) {
+                transformBatchListData = responseResult.batches.map(
+                  (data: any) => {
+                    const startTimeDisplay = jobTimeFormat(data.createTime);
+                    const startTime = new Date(data.createTime);
+                    const elapsedTimeString = elapsedTime(
+                      data.stateTime,
+                      startTime
+                    );
+                    const batchType = Object.keys(data).filter(key =>
+                      key.endsWith('Batch')
+                    );
+                    /*
+                     Extracting batchID, location from batchInfo.name
+                      Example: "projects/{project}/locations/{location}/batches/{batchID}"
+                    */
+                    const batchTypeDisplay = jobTypeDisplay(
+                      batchType[0].split('Batch')[0]
+                    );
+                    return {
+                      batchID: data.name.split('/')[5],
+                      status: data.state,
+                      location: data.name.split('/')[3],
+                      creationTime: startTimeDisplay,
+                      type: batchTypeDisplay,
+                      elapsedTime: elapsedTimeString,
+                      actions: renderActions(data)
+                    };
+                  }
+                );
+              }
 
               const existingBatchData = previousBatchesList ?? [];
               //setStateAction never type issue
@@ -152,7 +158,7 @@ const ServerlessComponent = (): React.JSX.Element => {
         .catch((err: Error) => {
           setIsLoading(false);
           console.error('Error listing batches', err);
-          toast.error('Failed to fetch Batches');
+          toast.error('Failed to fetch batches');
         });
     }
   };
@@ -177,7 +183,7 @@ const ServerlessComponent = (): React.JSX.Element => {
     setDeletePopupOpen(false);
   };
 
-  function renderActions(data: { name: string }) {
+  const renderActions = (data: { name: string }) => {
     return (
       <div className="actions-icon" role="button" aria-label="Delete Job">
         <div
@@ -189,7 +195,7 @@ const ServerlessComponent = (): React.JSX.Element => {
         </div>
       </div>
     );
-  }
+  };
 
   const toggleStyleSelection = (toggleItem: string) => {
     if (selectedMode === toggleItem) {
@@ -248,16 +254,18 @@ const ServerlessComponent = (): React.JSX.Element => {
               setDetailedBatchView={setDetailedBatchView}
             />
           ) : (
-            <div className="clusters-list-component">
+            <div className="clusters-list-component" role="tablist">
               {
                 <div className="clusters-list-overlay" role="tab">
                   <div
+                    role="tabpanel"
                     className={toggleStyleSelection('Batches')}
                     onClick={() => selectedModeChange('Batches')}
                   >
                     Batches
                   </div>
                   <div
+                    role="tabpanel"
                     className={toggleStyleSelection('Sessions')}
                     onClick={() => selectedModeChange('Sessions')}
                   >
@@ -284,11 +292,13 @@ const ServerlessComponent = (): React.JSX.Element => {
         </>
       ) : (
         loginError && (
-          <div className="login-error">Please login to continue</div>
+          <div role="alert" className="login-error">
+            Please login to continue
+          </div>
         )
       )}
       {configError && (
-        <div className="login-error">
+        <div role="alert" className="login-error">
           Please Configure Gcloud with Account, Project ID and Region
         </div>
       )}
@@ -296,13 +306,12 @@ const ServerlessComponent = (): React.JSX.Element => {
   );
 };
 
-export class Serverless extends ReactWidget {
+export class Batches extends ReactWidget {
   constructor() {
     super();
-    this.addClass('jp-ReactWidget');
   }
 
   render(): React.JSX.Element {
-    return <ServerlessComponent />;
+    return <BatchesComponent />;
   }
 }
diff --git a/src/batches/listBatches.tsx b/src/batches/listBatches.tsx
index d3a6cfda..df729d05 100644
--- a/src/batches/listBatches.tsx
+++ b/src/batches/listBatches.tsx
@@ -127,26 +127,17 @@ function ListBatches({
     rows,
     prepareRow,
     state,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     preGlobalFilteredRows,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     setGlobalFilter,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     page,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     canPreviousPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     canNextPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     nextPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     previousPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     setPageSize,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     state: { pageIndex, pageSize }
   } = useTable(
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
+    //@ts-ignore react-table 'columns' which is declared here on type 'TableOptions<ICluster>'
     { columns, data, autoResetPage: false, initialState: { pageSize: 50 } },
     useGlobalFilter,
     usePagination
@@ -165,6 +156,7 @@ function ListBatches({
     if (cell.column.Header === 'Batch ID') {
       return (
         <td
+          role="button"
           {...cell.getCellProps()}
           className="cluster-name"
           onClick={() => handleBatchDetails(cell.value)}
@@ -233,10 +225,8 @@ function ListBatches({
             <div className="filter-cluster-section">
               <GlobalFilter
                 preGlobalFilteredRows={preGlobalFilteredRows}
-                //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
                 globalFilter={state.globalFilter}
                 setGlobalFilter={setGlobalFilter}
-                listBatchAPI={listBatchAPI}
                 setPollingDisable={setPollingDisable}
               />
             </div>
diff --git a/src/cluster/cluster.tsx b/src/cluster/cluster.tsx
index 494551f0..3db14ccc 100644
--- a/src/cluster/cluster.tsx
+++ b/src/cluster/cluster.tsx
@@ -31,8 +31,6 @@ import {
   API_HEADER_CONTENT_TYPE,
   BASE_URL,
   POLLING_TIME_LIMIT,
-  // STATUS_RUNNING,
-  // STATUS_STOPPED,
   API_HEADER_BEARER,
   LOGIN_STATE,
   ClusterStatus
@@ -130,33 +128,39 @@ const ClusterComponent = (): React.JSX.Element => {
             .json()
             .then((responseResult: any) => {
               let transformClusterListData = [];
-              setClusterResponse(responseResult);
+              if (responseResult && responseResult.clusters) {
+                setClusterResponse(responseResult);
+                transformClusterListData = responseResult.clusters.map(
+                  (data: any) => {
+                    const statusVal = statusValue(data);
+                    /*
+                     Extracting zone from zoneUri
+                      Example: "projects/{project}/zones/{zone}"
+                  */
+                    const zoneUri =
+                      data.config.gceClusterConfig.zoneUri.split('/');
 
-              transformClusterListData = responseResult.clusters.map(
-                (data: any) => {
-                  const statusVal = statusValue(data);
-                  return {
-                    clusterUuid: data.clusterUuid,
-                    status: statusVal,
-                    clusterName: data.clusterName,
-                    clusterImage: data.config.softwareConfig.imageVersion,
-                    region: data.labels['goog-dataproc-location'],
-                    zone: data.config.gceClusterConfig.zoneUri.split('/')[
-                      data.config.gceClusterConfig.zoneUri.split('/').length - 1
-                    ],
-                    totalWorkersNode: data.config.workerConfig
-                      ? data.config.workerConfig.numInstances
-                      : 0,
-                    schedulesDeletion: data.config.lifecycleConfig
-                      ? 'On'
-                      : 'Off',
-                    actions: renderActions(data)
-                  };
-                }
-              );
+                    return {
+                      clusterUuid: data.clusterUuid,
+                      status: statusVal,
+                      clusterName: data.clusterName,
+                      clusterImage: data.config.softwareConfig.imageVersion,
+                      region: data.labels['goog-dataproc-location'],
+                      zone: zoneUri[zoneUri.length - 1],
+                      totalWorkersNode: data.config.workerConfig
+                        ? data.config.workerConfig.numInstances
+                        : 0,
+                      schedulesDeletion: data.config.lifecycleConfig
+                        ? 'On'
+                        : 'Off',
+                      actions: renderActions(data)
+                    };
+                  }
+                );
+              }
               const existingClusterData = previousClustersList ?? [];
               //setStateAction never type issue
-              let allClustersData: any = [
+              const allClustersData: any = [
                 ...(existingClusterData as []),
                 ...transformClusterListData
               ];
@@ -177,7 +181,7 @@ const ClusterComponent = (): React.JSX.Element => {
         .catch((err: Error) => {
           setIsLoading(false);
           console.error('Error listing clusters', err);
-          toast.error('Failed to fetch Clusters ');
+          toast.error('Failed to fetch clusters');
         });
     }
   };
@@ -220,7 +224,7 @@ const ClusterComponent = (): React.JSX.Element => {
         })
         .catch((err: Error) => {
           console.error('Error fetching status', err);
-          toast.error('Failed to Fetch the Status');
+          toast.error(`Failed to fetch the status ${selectedcluster}`);
         });
 
       listClustersAPI();
@@ -257,7 +261,7 @@ const ClusterComponent = (): React.JSX.Element => {
         })
         .catch((err: Error) => {
           console.error('Error restarting cluster', err);
-          toast.error('Failed to Restart the Cluster');
+          toast.error(`Failed to restart the cluster ${selectedcluster}`);
         });
 
       listClustersAPI();
@@ -265,12 +269,17 @@ const ClusterComponent = (): React.JSX.Element => {
     }
   };
 
-  function startButton(data: {
+  const startButton = (data: {
     status: { state: ClusterStatus };
     clusterName: string;
-  }) {
+  }) => {
     return (
       <div
+        role="button"
+        aria-disabled={
+          data.status.state !== ClusterStatus.STATUS_STOPPED &&
+          restartEnabled !== true
+        }
         className={
           data.status.state === ClusterStatus.STATUS_STOPPED &&
           restartEnabled !== true
@@ -291,14 +300,16 @@ const ClusterComponent = (): React.JSX.Element => {
         )}
       </div>
     );
-  }
+  };
 
-  function stopButton(data: {
+  const stopButton = (data: {
     status: { state: ClusterStatus };
     clusterName: string;
-  }) {
+  }) => {
     return (
       <div
+        role="button"
+        aria-disabled={data.status.state !== ClusterStatus.STATUS_RUNNING}
         className={
           data.status.state === ClusterStatus.STATUS_RUNNING
             ? 'icon-buttons-style'
@@ -318,14 +329,16 @@ const ClusterComponent = (): React.JSX.Element => {
         )}
       </div>
     );
-  }
+  };
 
-  function restartButton(data: {
+  const restartButton = (data: {
     status: { state: ClusterStatus };
     clusterName: string;
-  }) {
+  }) => {
     return (
       <div
+        role="button"
+        aria-disabled={data.status.state !== ClusterStatus.STATUS_RUNNING}
         className={
           data.status.state === ClusterStatus.STATUS_RUNNING
             ? 'icon-buttons-style'
@@ -345,11 +358,11 @@ const ClusterComponent = (): React.JSX.Element => {
         )}
       </div>
     );
-  }
-  function renderActions(data: {
+  };
+  const renderActions = (data: {
     status: { state: ClusterStatus };
     clusterName: string;
-  }) {
+  }) => {
     return (
       <div className="actions-icon">
         {startButton(data)}
@@ -357,7 +370,7 @@ const ClusterComponent = (): React.JSX.Element => {
         {restartButton(data)}
       </div>
     );
-  }
+  };
 
   const toggleStyleSelection = (toggleItem: string) => {
     if (selectedMode === toggleItem) {
@@ -414,16 +427,18 @@ const ClusterComponent = (): React.JSX.Element => {
             />
           )}
           {!detailedView && (
-            <div className="clusters-list-component">
+            <div className="clusters-list-component" role="tablist">
               {!detailedJobView && !submitJobView && (
-                <div className="clusters-list-overlay">
+                <div className="clusters-list-overlay" role="tab">
                   <div
+                    role="tabpanel"
                     className={toggleStyleSelection('Clusters')}
                     onClick={() => selectedModeChange('Clusters')}
                   >
                     Clusters
                   </div>
                   <div
+                    role="tabpanel"
                     className={toggleStyleSelection('Jobs')}
                     onClick={() => selectedModeChange('Jobs')}
                   >
@@ -476,7 +491,6 @@ const ClusterComponent = (): React.JSX.Element => {
 export class Cluster extends ReactWidget {
   constructor() {
     super();
-    this.addClass('jp-ReactWidget');
   }
 
   render(): React.JSX.Element {
diff --git a/src/cluster/clusterDetails.tsx b/src/cluster/clusterDetails.tsx
index 1bacceee..54fb4c4d 100644
--- a/src/cluster/clusterDetails.tsx
+++ b/src/cluster/clusterDetails.tsx
@@ -195,7 +195,7 @@ function ClusterDetails({
         .catch((err: Error) => {
           setIsLoading(false);
           console.error('Error listing clusters Details', err);
-          toast.error('Failed to fetch Cluster Details');
+          toast.error(`Failed to fetch cluster details ${clusterSelected}`);
         });
     }
   };
@@ -204,6 +204,8 @@ function ClusterDetails({
     return (
       <div className="cluster-details-action-parent">
         <div
+          role="button"
+          aria-disabled={clusterInfo.status.state !== STATUS_STOPPED}
           className={
             clusterInfo.status.state === STATUS_STOPPED
               ? 'action-cluster-section'
@@ -214,7 +216,11 @@ function ClusterDetails({
             startClusterApi(clusterInfo.clusterName)
           }
         >
-          <div className="action-cluster-icon">
+          <div
+            className="action-cluster-icon"
+            role="button"
+            aria-disabled={clusterInfo.status.state !== STATUS_STOPPED}
+          >
             {clusterInfo.status.state === STATUS_STOPPED ? (
               <iconStartCluster.react tag="div" />
             ) : (
@@ -224,6 +230,8 @@ function ClusterDetails({
           <div className="action-cluster-text">START</div>
         </div>
         <div
+          role="button"
+          aria-disabled={clusterInfo.status.state !== STATUS_RUNNING}
           className={
             clusterInfo.status.state === STATUS_RUNNING
               ? 'action-cluster-section'
@@ -244,6 +252,7 @@ function ClusterDetails({
           <div className="action-cluster-text">STOP</div>
         </div>
         <div
+          role="button"
           className="action-cluster-section"
           onClick={() => handleDeleteCluster(clusterInfo.clusterName)}
         >
@@ -269,12 +278,17 @@ function ClusterDetails({
     <div>
       {errorView && (
         <div className="error-view-parent">
-          <div className="back-arrow-icon" onClick={() => handleDetailedView()}>
+          <div
+            role="button"
+            aria-label="back-arrow-icon"
+            className="back-arrow-icon"
+            onClick={() => handleDetailedView()}
+          >
             <iconLeftArrow.react tag="div" />
           </div>
           <div className="error-view-message-parent">
             <iconError.react tag="div" />
-            <div className="error-view-message">
+            <div role="alert" className="error-view-message">
               Unable to find the resource you requested
             </div>
           </div>
@@ -297,115 +311,121 @@ function ClusterDetails({
           }
         />
       )}
-      {!submitJobView &&
-      <div className="scroll-comp">
-        <ToastContainer />
-        {!errorView && clusterInfo.clusterName !== '' ? (
-          <div>
-            {!detailedJobView && (
-              <div>
-                <div className="cluster-details-header">
-                  <div
-                    className="back-arrow-icon"
-                    onClick={() => handleDetailedView()}
-                  >
-                    <iconLeftArrow.react tag="div" />
-                  </div>
-                  <div className="cluster-details-title">Cluster details</div>
-                  {clusterDetailsAction()}
-                  <ViewLogs
-                    clusterInfo={clusterInfo}
-                    projectName={projectName}
-                  />
-                </div>
-                <div className="cluster-details-container">
-                  <div className="row-details"></div>
-                  <div className="row-details">
-                    <div className="cluster-details-label">Name</div>
-                    <div className="cluster-details-value">
-                      {clusterInfo.clusterName}
+      {!submitJobView && (
+        <div className="scroll-comp">
+          <ToastContainer />
+          {!errorView && clusterInfo.clusterName !== '' ? (
+            <div>
+              {!detailedJobView && (
+                <div>
+                  <div className="cluster-details-header">
+                    <div
+                      role="button"
+                      aria-label="back-arrow-icon"
+                      className="back-arrow-icon"
+                      onClick={() => handleDetailedView()}
+                    >
+                      <iconLeftArrow.react tag="div" />
                     </div>
+                    <div className="cluster-details-title">Cluster details</div>
+                    {clusterDetailsAction()}
+                    <ViewLogs
+                      clusterInfo={clusterInfo}
+                      projectName={projectName}
+                    />
                   </div>
-                  <div className="row-details">
-                    <div className="cluster-details-label">Cluster UUID</div>
-                    <div className="cluster-details-value">
-                      {clusterInfo.clusterUuid}
+                  <div className="cluster-details-container">
+                    <div className="row-details"></div>
+                    <div className="row-details">
+                      <div className="cluster-details-label">Name</div>
+                      <div className="cluster-details-value">
+                        {clusterInfo.clusterName}
+                      </div>
                     </div>
-                  </div>
-                  <div className="row-details">
-                    <div className="cluster-details-label">Type</div>
-                    <div className="cluster-details-value">
-                      Dataproc Cluster
+                    <div className="row-details">
+                      <div className="cluster-details-label">Cluster UUID</div>
+                      <div className="cluster-details-value">
+                        {clusterInfo.clusterUuid}
+                      </div>
                     </div>
-                  </div>
-                  <div className="row-details">
-                    <div className="cluster-details-label">Status</div>
-                    <div className="cluster-detail-status-parent">
-                      {clusterInfo.status.state === STATUS_RUNNING && (
-                        <iconClusterRunning.react tag="div" />
-                      )}
-                      {clusterInfo.status.state === STATUS_STOPPED && (
-                        <iconStop.react tag="div" />
-                      )}
-                      {clusterInfo.status.state === STATUS_ERROR && (
-                        <iconClusterError.react tag="div" />
-                      )}
-                      {(clusterInfo.status.state === STATUS_PROVISIONING ||
-                        clusterInfo.status.state === STATUS_CREATING ||
-                        clusterInfo.status.state === STATUS_STARTING ||
-                        clusterInfo.status.state === STATUS_STOPPING ||
-                        clusterInfo.status.state === STATUS_DELETING) && (
-                        <div>
-                          <ClipLoader
-                            color="#8A8A8A"
-                            loading={true}
-                            size={15}
-                            aria-label="Loading Spinner"
-                            data-testid="loader"
-                          />
+                    <div className="row-details">
+                      <div className="cluster-details-label">Type</div>
+                      <div className="cluster-details-value">
+                        Dataproc Cluster
+                      </div>
+                    </div>
+                    <div className="row-details">
+                      <div className="cluster-details-label">Status</div>
+                      <div
+                        className="cluster-detail-status-parent"
+                        aria-status={clusterInfo.status.state}
+                        aria-label={clusterInfo.status.state}
+                      >
+                        {clusterInfo.status.state === STATUS_RUNNING && (
+                          <iconClusterRunning.react tag="div" />
+                        )}
+                        {clusterInfo.status.state === STATUS_STOPPED && (
+                          <iconStop.react tag="div" />
+                        )}
+                        {clusterInfo.status.state === STATUS_ERROR && (
+                          <iconClusterError.react tag="div" />
+                        )}
+                        {(clusterInfo.status.state === STATUS_PROVISIONING ||
+                          clusterInfo.status.state === STATUS_CREATING ||
+                          clusterInfo.status.state === STATUS_STARTING ||
+                          clusterInfo.status.state === STATUS_STOPPING ||
+                          clusterInfo.status.state === STATUS_DELETING) && (
+                          <div>
+                            <ClipLoader
+                              color="#8A8A8A"
+                              loading={true}
+                              size={15}
+                              aria-label="Loading Spinner"
+                              data-testid="loader"
+                            />
+                          </div>
+                        )}
+                        <div className="cluster-status">
+                          {clusterInfo.status.state === STATUS_CREATING
+                            ? STATUS_PROVISIONING
+                            : clusterInfo.status.state.toLowerCase()}
                         </div>
-                      )}
-                      <div className="cluster-status">
-                        {clusterInfo.status.state === STATUS_CREATING
-                          ? STATUS_PROVISIONING
-                          : clusterInfo.status.state.toLowerCase()}
                       </div>
                     </div>
                   </div>
+                  <div className="cluster-details-header">
+                    <div className="cluster-details-title">Jobs</div>
+                  </div>
                 </div>
-                <div className="cluster-details-header">
-                  <div className="cluster-details-title">Jobs</div>
+              )}
+              <JobComponent
+                clusterSelected={clusterSelected}
+                setDetailedView={setDetailedView}
+                detailedJobView={detailedJobView}
+                setDetailedJobView={setDetailedJobView}
+                setSubmitJobView={setSubmitJobView}
+                setSelectedJobClone={setSelectedJobClone}
+                clusterResponse={clusterResponse}
+              />
+            </div>
+          ) : (
+            <div className="loader-full-style">
+              {isLoading && (
+                <div>
+                  <ClipLoader
+                    color="#8A8A8A"
+                    loading={true}
+                    size={20}
+                    aria-label="Loading Spinner"
+                    data-testid="loader"
+                  />
+                  Loading Cluster Details
                 </div>
-              </div>
-            )}
-            <JobComponent
-              clusterSelected={clusterSelected}
-              setDetailedView={setDetailedView}
-              detailedJobView={detailedJobView}
-              setDetailedJobView={setDetailedJobView}
-              setSubmitJobView={setSubmitJobView}
-              setSelectedJobClone={setSelectedJobClone}
-              clusterResponse={clusterResponse}
-            />
-          </div>
-        ) : (
-          <div className="loader-full-style">
-            {isLoading && (
-              <div>
-                <ClipLoader
-                  color="#8A8A8A"
-                  loading={true}
-                  size={20}
-                  aria-label="Loading Spinner"
-                  data-testid="loader"
-                />
-                Loading Cluster Details
-              </div>
-            )}
-          </div>
-        )}
-      </div>
-      }
+              )}
+            </div>
+          )}
+        </div>
+      )}
     </div>
   );
 }
diff --git a/src/cluster/listCluster.tsx b/src/cluster/listCluster.tsx
index 3eaa6ff2..d0eb2dd3 100644
--- a/src/cluster/listCluster.tsx
+++ b/src/cluster/listCluster.tsx
@@ -146,6 +146,7 @@ function ListCluster({
       return (
         <td
           {...cell.getCellProps()}
+          role="button"
           className="cluster-name"
           onClick={() =>
             cell.row.original.status !== STATUS_DELETING &&
@@ -158,7 +159,12 @@ function ListCluster({
     } else if (cell.column.Header === 'Status') {
       return (
         <td {...cell.getCellProps()} className="clusters-table-data">
-          <div key="Status" className="cluster-status-parent">
+          <div
+            key="Status"
+            className="cluster-status-parent"
+            role="status"
+            aria-labels="cell.value"
+          >
             {cell.value === STATUS_RUNNING && (
               <iconClusterRunning.react tag="div" />
             )}
@@ -201,26 +207,17 @@ function ListCluster({
     rows,
     prepareRow,
     state,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     preGlobalFilteredRows,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     setGlobalFilter,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     page,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     canPreviousPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     canNextPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     nextPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     previousPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     setPageSize,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     state: { pageIndex, pageSize }
   } = useTable(
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
+    //@ts-ignore react-table 'columns' which is declared here on type 'TableOptions<ICluster>'
     { columns, data, autoResetPage: false, initialState: { pageSize: 50 } },
     useGlobalFilter,
     usePagination
@@ -230,6 +227,7 @@ function ListCluster({
     <div>
       <div className="create-cluster-overlay">
         <div
+          role="button"
           className="create-cluster-sub-overlay"
           onClick={() => {
             window.open(
@@ -255,10 +253,8 @@ function ListCluster({
             <div className="filter-cluster-section">
               <GlobalFilter
                 preGlobalFilteredRows={preGlobalFilteredRows}
-                //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
                 globalFilter={state.globalFilter}
                 setGlobalFilter={setGlobalFilter}
-                listClustersAPI={listClustersAPI}
                 setPollingDisable={setPollingDisable}
               />
             </div>
diff --git a/src/index.ts b/src/index.ts
index 577b7c78..fd3502c1 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -24,7 +24,7 @@ import { ILauncher } from '@jupyterlab/launcher';
 import { LabIcon } from '@jupyterlab/ui-components';
 import { IMainMenu } from '@jupyterlab/mainmenu';
 import { Cluster } from './cluster/cluster';
-import { Serverless } from './batches/batches';
+import { Batches } from './batches/batches';
 import clusterIcon from '../style/icons/cluster_icon.svg';
 import serverlessIcon from '../style/icons/serverless_icon.svg';
 import { Menu } from '@lumino/widgets';
@@ -59,7 +59,7 @@ const extension: JupyterFrontEndPlugin<void> = {
     commands.addCommand(createClusterComponentCommand, {
       caption: 'Create a new Cluster Component',
       label: 'Clusters',
-      // @ts-ignore
+      // @ts-ignore jupyter lab icon command issue
       icon: args => (args['isPalette'] ? null : iconCluster),
       execute: () => {
         const content = new Cluster();
@@ -70,15 +70,15 @@ const extension: JupyterFrontEndPlugin<void> = {
       }
     });
 
-    const createServerlessComponentCommand = 'create-serverless-component';
-    commands.addCommand(createServerlessComponentCommand, {
+    const createBatchesComponentCommand = 'create-batches-component';
+    commands.addCommand(createBatchesComponentCommand, {
       caption: 'Create a new Serverless Component',
       label: 'Serverless',
-      // @ts-ignore
+      // @ts-ignore jupyter lab icon command issue
       icon: args => (args['isPalette'] ? null : iconServerless),
       execute: () => {
-        const content = new Serverless();
-        const widget = new MainAreaWidget<Serverless>({ content });
+        const content = new Batches();
+        const widget = new MainAreaWidget<Batches>({ content });
         widget.title.label = 'Serverless';
         widget.title.icon = iconServerless;
         app.shell.add(widget, 'main');
@@ -134,10 +134,10 @@ const extension: JupyterFrontEndPlugin<void> = {
           launcher.add({
             command: commandNotebook,
             category: 'Dataproc Serverless Notebooks',
-            //@ts-ignore
+            //@ts-ignore jupyter lab Launcher type issue
             metadata: kernelsData?.metadata,
             rank: index + 1,
-            //@ts-ignore
+            //@ts-ignore jupyter lab Launcher type issue
             args: kernelsData?.argv
           });
         }
@@ -172,51 +172,22 @@ const extension: JupyterFrontEndPlugin<void> = {
           launcher.add({
             command: commandNotebook,
             category: 'Dataproc Cluster Notebooks',
-            //@ts-ignore
+            //@ts-ignore jupyter lab Launcher type issue
             metadata: kernelsData?.metadata,
             rank: index + 1,
-            //@ts-ignore
+            //@ts-ignore jupyter lab Launcher type issue
             args: kernelsData?.argv
           });
         }
       });
 
-      // Object.values(kernels).forEach(kernelsData => {
-      //   if (kernelsData?.resources.endpointParentResource) {
-      //     const commandConsole = `console:create-${kernelsData?.display_name}`;
-      //     commands.addCommand(commandConsole, {
-      //       caption: kernelsData?.display_name,
-      //       label: kernelsData?.display_name,
-      //       icon: iconDisplay(kernelsData),
-      //       execute: async () => {
-      //         await app.commands.execute('console:create', {
-      //           activate: true,
-      //           kernel: { name: kernelsData?.name }
-      //         });
-
-      //         await app.commands.execute('console:open', {
-      //           activate: true,
-      //           kernel: { name: kernelsData?.name }
-      //         });
-      //       }
-      //     });
-
-      //     launcher.add({
-      //       command: commandConsole,
-      //       category: 'Dataproc Console',
-      //       metadata: kernelsData?.metadata,
-      //       args: kernelsData?.argv
-      //     });
-      //   }
-      // });
-
       launcher.add({
         command: createClusterComponentCommand,
         category: TITLE_LAUNCHER_CATEGORY,
         rank: 1
       });
       launcher.add({
-        command: createServerlessComponentCommand,
+        command: createBatchesComponentCommand,
         category: TITLE_LAUNCHER_CATEGORY,
         rank: 2
       });
diff --git a/src/jobs/jobDetails.tsx b/src/jobs/jobDetails.tsx
index 90026cd9..ea4aa94f 100644
--- a/src/jobs/jobDetails.tsx
+++ b/src/jobs/jobDetails.tsx
@@ -18,7 +18,6 @@
 import React, { useEffect, useState } from 'react';
 import { LabIcon } from '@jupyterlab/ui-components';
 import LeftArrowIcon from '../../style/icons/left_arrow_icon.svg';
-// import { Icon } from 'semantic-ui-react';
 import 'semantic-ui-css/semantic.min.css';
 import CloneJobIcon from '../../style/icons/clone_job_icon.svg';
 import StopClusterIcon from '../../style/icons/stop_cluster_icon.svg';
@@ -141,7 +140,7 @@ function JobDetails({
   const [selectedJobClone, setSelectedJobClone] = useState({});
   const [submitJobView, setSubmitJobView] = useState(false);
   const [keyValidation, setKeyValidation] = useState(-1);
-  const [valueValidation, setvalueValidation] = useState(-1);
+  const [valueValidation, setValueValidation] = useState(-1);
   const [duplicateKeyError, setDuplicateKeyError] = useState(-1);
 
   const [deletePopupOpen, setDeletePopupOpen] = useState(false);
@@ -226,14 +225,14 @@ function JobDetails({
           response
             .json()
             .then((responseResultJob: Response) => {
-              // TODO: Handle Toast here
+              toast.success(`Request to update job ${jobSelected} submitted`);
               console.log(responseResultJob);
             })
             .catch((e: Error) => console.error(e));
         })
         .catch((err: Error) => {
           console.error('Error in updating job', err);
-          toast.error('Failed to Update the job ');
+          toast.error(`Failed to update the job ${jobSelected}`);
         });
     }
   };
@@ -242,8 +241,14 @@ function JobDetails({
     const payload = jobInfoResponse;
     const labelObject: { [key: string]: string } = {};
     labelDetailUpdated.forEach((label: string) => {
-      const key = label.split(':')[0];
-      const value = label.split(':')[1];
+      /*
+         Extracting key, value from label
+         Example: "{client:dataproc_plugin}"
+      */
+      const labelParts = label.split(':');
+
+      const key = labelParts[0];
+      const value = labelParts[1];
       labelObject[key] = value;
     });
     payload.labels = labelObject;
@@ -295,7 +300,7 @@ function JobDetails({
         .catch((err: Error) => {
           setIsLoading(false);
           console.error('Error in getting job details', err);
-          toast.error('Failed to fetch Job details ');
+          toast.error(`Failed to fetch job details ${jobSelected}`);
         });
     }
   };
@@ -305,17 +310,16 @@ function JobDetails({
   const jobType = jobTypeDisplay(job);
   const jobArgument = jobTypeValueArguments(jobInfo);
   const jobTypeConcat = jobArgument + 'Job';
-  //@ts-ignore
+  //@ts-ignore string used as index
   const argumentsList = jobInfo[jobTypeConcat].args;
   const statusMsg = statusMessage(jobInfo);
-
-  const endTime = jobInfo.status.stateStartTime;
+  const endTime = new Date(jobInfo.status.stateStartTime);
   const jobStartTime = new Date(
     jobInfo.statusHistory[jobInfo.statusHistory.length - 1].stateStartTime
   );
-
   const elapsedTimeString = elapsedTime(endTime, jobStartTime);
 
+
   const statusStyleSelection = (jobInfo: any) => {
     if (jobInfo.status.state === STATUS_RUNNING) {
       return 'action-cluster-section'; //CSS class
@@ -348,7 +352,11 @@ function JobDetails({
     <div>
       {errorView && (
         <div className="error-view-parent">
-          <div className="back-arrow-icon" onClick={() => setErrorView(false)}>
+          <div
+            role="button"
+            className="back-arrow-icon"
+            onClick={() => setErrorView(false)}
+          >
             <iconLeftArrow.react tag="div" />
           </div>
           <div className="error-view-message-parent">
@@ -404,6 +412,7 @@ function JobDetails({
                 </div>
                 <div className="cluster-details-title">Job details</div>
                 <div
+                  role="button"
                   className="action-cluster-section"
                   onClick={() => handleCloneJob()}
                 >
@@ -414,6 +423,7 @@ function JobDetails({
                 </div>
 
                 <div
+                  role="button"
                   className={statusStyleSelection(jobInfo)}
                   onClick={() =>
                     jobInfo.status.state === STATUS_RUNNING &&
@@ -430,6 +440,7 @@ function JobDetails({
                   <div className="action-cluster-text">STOP</div>
                 </div>
                 <div
+                  role="button"
                   className="action-cluster-section"
                   onClick={() => handleDeleteJob(jobInfo.reference.jobId)}
                 >
@@ -471,6 +482,7 @@ function JobDetails({
               </div>
               <div className="job-edit-header">
                 <div
+                  role="button"
                   className={styleJobEdit(labelEditMode)}
                   onClick={() => (labelEditMode ? '' : handleJobLabelEdit())}
                 >
@@ -517,6 +529,7 @@ function JobDetails({
                   <div className="cluster-details-label">Cluster</div>
 
                   <div
+                    role="button"
                     className="cluster-details-value-job"
                     onClick={() => handleDetailedClusterView()}
                   >
@@ -621,9 +634,15 @@ function JobDetails({
                     <div className="job-label-style-parent">
                       {labelDetail.length > 0
                         ? labelDetail.map(label => {
+                            /*
+                            Extracting key, value from label
+                               Example: "{client:dataproc_plugin}"
+                         */
+                            const labelParts = label.split(':');
+
                             return (
                               <div key={label} className="job-label-style">
-                                {label.split(':')[0]} : {label.split(':')[1]}
+                                {labelParts[0]} : {labelParts[1]}
                               </div>
                             );
                           })
@@ -635,12 +654,12 @@ function JobDetails({
                       setLabelDetail={setLabelDetail}
                       labelDetailUpdated={labelDetailUpdated}
                       setLabelDetailUpdated={setLabelDetailUpdated}
-                      selectedJobClone={selectedJobClone ? true : false}
+                      selectedJobClone={!!selectedJobClone}
                       buttonText="ADD LABEL"
                       keyValidation={keyValidation}
                       setKeyValidation={setKeyValidation}
                       valueValidation={valueValidation}
-                      setvalueValidation={setvalueValidation}
+                      setValueValidation={setValueValidation}
                       labelEditMode={labelEditMode}
                       duplicateKeyError={duplicateKeyError}
                       setDuplicateKeyError={setDuplicateKeyError}
@@ -651,6 +670,7 @@ function JobDetails({
                   <div className="job-button-style-parent">
                     <div className="job-save-button-style">
                       <div
+                        role="button"
                         onClick={() => {
                           handleSaveEdit();
                         }}
@@ -660,6 +680,7 @@ function JobDetails({
                     </div>
                     <div className="job-cancel-button-style">
                       <div
+                        role="button"
                         onClick={() => {
                           handleCancelEdit();
                         }}
diff --git a/src/jobs/jobs.tsx b/src/jobs/jobs.tsx
index d21821ff..d20bf1d1 100644
--- a/src/jobs/jobs.tsx
+++ b/src/jobs/jobs.tsx
@@ -225,40 +225,42 @@ function JobComponent({
             .json()
             .then((responseResult: any) => {
               let transformJobListData = [];
-              transformJobListData = responseResult.jobs.map((data: any) => {
-                const startTime = jobTimeFormat(
-                  data.statusHistory[0].stateStartTime
-                );
-                const job = jobTypeValue(data);
-                const jobType = jobTypeDisplay(job);
-                const endTime = data.status.stateStartTime;
-                const jobStartTime = new Date(
-                  data.statusHistory[0].stateStartTime
-                );
+              if (responseResult && responseResult.jobs) {
+                transformJobListData = responseResult.jobs.map((data: any) => {
+                  const startTime = jobTimeFormat(
+                    data.statusHistory[0].stateStartTime
+                  );
+                  const job = jobTypeValue(data);
+                  const jobType = jobTypeDisplay(job);
+                  const endTime = data.status.stateStartTime;
+                  const jobStartTime = new Date(
+                    data.statusHistory[0].stateStartTime
+                  );
 
-                const elapsedTimeString = elapsedTime(endTime, jobStartTime);
+                  const elapsedTimeString = elapsedTime(endTime, jobStartTime);
 
-                const statusMsg = statusMessage(data);
+                  const statusMsg = statusMessage(data);
 
-                const labelvalue = [];
-                if (data.labels) {
-                  for (const [key, value] of Object.entries(data.labels)) {
-                    labelvalue.push(`${key} : ${value}`);
+                  const labelvalue = [];
+                  if (data.labels) {
+                    for (const [key, value] of Object.entries(data.labels)) {
+                      labelvalue.push(`${key} : ${value}`);
+                    }
+                  } else {
+                    labelvalue.push('None');
                   }
-                } else {
-                  labelvalue.push('None');
-                }
-                return {
-                  jobid: data.reference.jobId,
-                  status: statusMsg,
-                  region: credentials.region_id,
-                  type: jobType,
-                  starttime: startTime,
-                  elapsedtime: elapsedTimeString,
-                  labels: labelvalue,
-                  actions: renderActions(data)
-                };
-              });
+                  return {
+                    jobid: data.reference.jobId,
+                    status: statusMsg,
+                    region: credentials.region_id,
+                    type: jobType,
+                    starttime: startTime,
+                    elapsedtime: elapsedTimeString,
+                    labels: labelvalue,
+                    actions: renderActions(data)
+                  };
+                });
+              }
               const existingJobsData = previousJobsList ?? [];
               //setStateAction never type issue
               let allJobsData: any = [
@@ -281,24 +283,25 @@ function JobComponent({
         .catch((err: Error) => {
           setIsLoading(false);
           console.error('Error listing jobs', err);
-          toast.error('Failed to fetch Jobs');
+          toast.error('Failed to fetch jobs');
         });
     }
   };
 
-  function handleCloneJob(data: object) {
+  const handleCloneJob = (data: object) => {
     setSubmitJobView(true);
     setSelectedJobClone(data);
-  }
-  function renderActions(data: {
+  };
+  const renderActions = (data: {
     reference: { jobId: string };
     status: { state: ClusterStatus };
     clusterName: string;
-  }) {
+  }) => {
     const jobId = data.reference.jobId;
     return (
       <div className="actions-icon">
         <div
+          role="button"
           className="icon-buttons-style"
           title="Clone Job"
           onClick={() => handleCloneJob(data)}
@@ -306,6 +309,8 @@ function JobComponent({
           <iconClone.react tag="div" />
         </div>
         <div
+          role="button"
+          aria-disabled={data.status.state !== ClusterStatus.STATUS_RUNNING}
           className={
             data.status.state === ClusterStatus.STATUS_RUNNING
               ? 'icon-buttons-style'
@@ -325,6 +330,8 @@ function JobComponent({
           )}
         </div>
         <div
+          role="button"
+          aria-disabled={data.status.state !== ClusterStatus.STATUS_RUNNING}
           className={
             data.status.state === ClusterStatus.STATUS_RUNNING
               ? 'icon-buttons-style-disable'
@@ -345,7 +352,7 @@ function JobComponent({
         </div>
       </div>
     );
-  }
+  };
 
   useEffect(() => {
     listJobsAPI();
@@ -374,6 +381,7 @@ function JobComponent({
     if (cell.column.Header === 'Job ID') {
       return (
         <td
+          role="button"
           {...cell.getCellProps()}
           className="cluster-name"
           onClick={() => jobDetails(cell.value)}
@@ -441,26 +449,16 @@ function JobComponent({
     rows,
     prepareRow,
     state,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     preGlobalFilteredRows,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     setGlobalFilter,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     page,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     canPreviousPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     canNextPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     nextPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     previousPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     setPageSize,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     state: { pageIndex, pageSize }
   } = useTable(
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     { columns, data, autoResetPage: false, initialState: { pageSize: 50 } },
     useGlobalFilter,
     usePagination
@@ -505,6 +503,7 @@ function JobComponent({
             clusterResponse.clusters.length > 0 && (
               <div className="create-cluster-overlay">
                 <div
+                  role="button"
                   className="create-cluster-sub-overlay"
                   onClick={() => {
                     handleSubmitJobOpen();
@@ -526,8 +525,7 @@ function JobComponent({
                 <div className="filter-cluster-text"></div>
                 <div className="filter-cluster-section">
                   <GlobalFilter
-                    preGlobalFilteredRows={preGlobalFilteredRows}
-                    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
+                    preGlobalFilteredRows={preGlobalFilteredRows}                 
                     globalFilter={state.globalFilter}
                     setGlobalFilter={setGlobalFilter}
                     setPollingDisable={setPollingDisable}
diff --git a/src/jobs/labelProperties.tsx b/src/jobs/labelProperties.tsx
index e49eb7e4..6626085a 100644
--- a/src/jobs/labelProperties.tsx
+++ b/src/jobs/labelProperties.tsx
@@ -22,6 +22,7 @@ import plusIconDisable from '../../style/icons/plus_icon_disable.svg';
 import deleteIcon from '../../style/icons/delete_icon.svg';
 import errorIcon from '../../style/icons/error_icon.svg';
 import { Input } from 'semantic-ui-react';
+import { DEFAULT_LABEL_DETAIL } from '../utils/const';
 
 const iconPlus = new LabIcon({
   name: 'launcher:plus-icon',
@@ -50,19 +51,23 @@ function LabelProperties({
   keyValidation,
   setKeyValidation,
   valueValidation,
-  setvalueValidation,
+  setValueValidation,
   duplicateKeyError,
   setDuplicateKeyError,
   labelEditMode
 }: any) {
+  /* 
+  labelDetail used to store the permanent label details when onblur 
+  labelDetailUpdated used to store the temporay label details when onchange 
+  */
   useEffect(() => {
     if (!labelEditMode) {
-      buttonText === 'ADD LABEL' && !selectedJobClone
-        ? setLabelDetail(['client:dataproc-jupyter-plugin'])
-        : setLabelDetail([]);
-      buttonText === 'ADD LABEL' && !selectedJobClone
-        ? setLabelDetailUpdated(['client:dataproc-jupyter-plugin'])
-        : setLabelDetail([]);
+      if (buttonText === 'ADD LABEL' && !selectedJobClone) {
+        setLabelDetail([DEFAULT_LABEL_DETAIL]);
+        setLabelDetailUpdated([DEFAULT_LABEL_DETAIL]);
+      } else {
+        setLabelDetail([]);
+      }
     }
   }, []);
 
@@ -73,17 +78,17 @@ function LabelProperties({
     setLabelDetail(labelAdd);
   };
 
-  const handleDeleteLabel = (index: any, value: string) => {
+  const handleDeleteLabel = (index: number, value: string) => {
     const labelDelete = [...labelDetail];
     labelDelete.splice(index, 1);
     setLabelDetailUpdated(labelDelete);
     setLabelDetail(labelDelete);
     setDuplicateKeyError(-1);
     setKeyValidation(-1);
-    setvalueValidation(-1);
+    setValueValidation(-1);
   };
 
-  const handleEditLabelSwitch = (index: any) => {
+  const handleEditLabelSwitch = () => {
     if (duplicateKeyError === -1) {
       setLabelDetail(labelDetailUpdated);
     }
@@ -91,17 +96,19 @@ function LabelProperties({
   const handleEditLabel = (
     value: string,
     index: number,
-    keyValue: string,
-    keyValueData: string
+    keyValue: string
   ) => {
     const labelEdit = [...labelDetail];
+
     labelEdit.forEach((data, dataNumber: any) => {
       if (index === dataNumber) {
+        /*
+          allowed aplhanumeric and spaces and underscores
+        */
+        const regexp = /^[a-z0-9-_]+$/;
         if (keyValue === 'key') {
-          const regexp = /^[a-z0-9-_]+$/;
-          const check = value;
           if (
-            check.search(regexp) === -1 ||
+            value.search(regexp) === -1 ||
             value.charAt(0) !== value.charAt(0).toLowerCase()
           ) {
             setKeyValidation(index);
@@ -116,20 +123,21 @@ function LabelProperties({
           );
           if (duplicateIndex !== -1) {
             setDuplicateKeyError(index);
-            // Show error message or take necessary action
           } else {
             setDuplicateKeyError(-1);
           }
 
           data = data.replace(data.split(':')[0], value);
         } else {
-          const regexp = /^[a-z0-9-_]+$/;
-          const check = value;
-          if (check.search(regexp) === -1) {
-            setvalueValidation(index);
+          if (value.search(regexp) === -1) {
+            setValueValidation(index);
           } else {
-            setvalueValidation(-1);
+            setValueValidation(-1);
           }
+          /*
+          value is split from labels 
+          Example:"client:dataproc_plugin"
+          */
           if (data.split(':')[1] === '') {
             data = data + value;
           } else {
@@ -143,7 +151,7 @@ function LabelProperties({
     setLabelDetailUpdated(labelEdit);
   };
 
-  const styleAddLabelButton = (buttonText: any, labelDetail: any) => {
+  const styleAddLabelButton = (buttonText: string, labelDetail: any) => {
     if (
       buttonText === 'ADD LABEL' &&
       (labelDetail.length === 0 ||
@@ -173,7 +181,13 @@ function LabelProperties({
     <div>
       <div className="job-label-edit-parent">
         {labelDetail.length > 0 &&
-          labelDetail.map((label: any, index: any) => {
+          labelDetail.map((label: any, index: number) => {
+            /*
+                     Extracting key, value from label
+                      Example: "{client:dataProc_plugin}"
+                  */
+            const labelSplit = label.split(':');
+
             return (
               <div key={label}>
                 <div className="job-label-edit-row">
@@ -182,26 +196,25 @@ function LabelProperties({
                       placeholder={`Key ${index + 1}*`}
                       className="edit-input-style"
                       disabled={
-                        label.split(':')[0] === '' ||
+                        labelSplit[0] === '' ||
                         buttonText !== 'ADD LABEL' ||
                         duplicateKeyError !== -1
                           ? false
                           : true
                       }
-                      onBlur={() => handleEditLabelSwitch(index)}
+                      onBlur={() => handleEditLabelSwitch()}
                       onChange={e =>
                         handleEditLabel(
                           e.target.value,
                           index,
-                          'key',
-                          label.split(':')[0]
+                          'key'
                         )
                       }
-                      defaultValue={label.split(':')[0]}
+                      defaultValue={labelSplit[0]}
                     />
 
                     {labelDetailUpdated[index].split(':')[0] === '' ? (
-                      <div className="error-key-parent">
+                      <div role="alert" className="error-key-parent">
                         <iconError.react tag="div" />
                         <div className="error-key-missing">key is required</div>
                       </div>
@@ -233,16 +246,15 @@ function LabelProperties({
                     <Input
                       placeholder={`Value ${index + 1}`}
                       className="edit-input-style"
-                      onBlur={() => handleEditLabelSwitch(index)}
+                      onBlur={() => handleEditLabelSwitch()}
                       onChange={e =>
                         handleEditLabel(
                           e.target.value,
                           index,
-                          'value',
-                          label.split(':')[1]
+                          'value'
                         )
                       }
-                      defaultValue={label.split(':')[1]}
+                      defaultValue={labelSplit[1]}
                     />
                     {valueValidation === index &&
                       buttonText === 'ADD LABEL' && (
@@ -257,10 +269,9 @@ function LabelProperties({
                       )}
                   </div>
                   <div
-                    className='labels-delete-icon'
-                    onClick={() =>
-                      handleDeleteLabel(index, label.split(':')[0])
-                    }
+                    role="button"
+                    className="labels-delete-icon"
+                    onClick={() => handleDeleteLabel(index, labelSplit[0])}
                   >
                     <iconDelete.react tag="div" />
                   </div>
@@ -270,6 +281,7 @@ function LabelProperties({
             );
           })}
         <div
+          role="button"
           className={styleAddLabelButton(buttonText, labelDetail)}
           onClick={() => {
             (labelDetail.length === 0 ||
diff --git a/src/jobs/submitJob.tsx b/src/jobs/submitJob.tsx
index dacd4aaf..7fd8337f 100644
--- a/src/jobs/submitJob.tsx
+++ b/src/jobs/submitJob.tsx
@@ -27,14 +27,14 @@ import 'react-tagsinput/react-tagsinput.css';
 import {
   API_HEADER_BEARER,
   API_HEADER_CONTENT_TYPE,
-  ARCHIVEFILESMESSAGE,
-  ARGUMENTSMESSAGE,
+  ARCHIVE_FILES_MESSAGE,
+  ARGUMENTS_MESSAGE,
   BASE_URL,
-  FILESMESSAGE,
-  JARFILEMESSAGE,
-  MAINCLASSMESSAGE,
-  MAXRESTARTMESSAGE,
-  QUERYFILEMESSAGE,
+  FILES_MESSAGE,
+  JAR_FILE_MESSAGE,
+  MAIN_CLASS_MESSAGE,
+  MAX_RESTART_MESSAGE,
+  QUERY_FILE_MESSAGE,
   RESTART_JOB_URL,
   STATUS_RUNNING
 } from '../utils/const';
@@ -77,7 +77,7 @@ function jobTypeFunction(jobKey: string) {
       return jobType;
   }
 }
-function handleOptionalFields(selectedJobClone: any, jobTypeKey: any) {
+const handleOptionalFields = (selectedJobClone: any, jobTypeKey: any) => {
   let args: string[] = [];
   let jarFileUris: string[] = [];
   let archiveUris: string[] = [];
@@ -115,7 +115,7 @@ function handleOptionalFields(selectedJobClone: any, jobTypeKey: any) {
     pythonFileUris,
     maxFailuresPerHour
   };
-}
+};
 function SubmitJob(
   this: any,
   { setSubmitJobView, selectedJobClone, clusterResponse }: any
@@ -210,7 +210,7 @@ function SubmitJob(
   const [mainClassValidation, setMainClassValidation] = useState(true);
   const [generationCompleted, setGenerationCompleted] = useState(false);
   const [keyValidation, setKeyValidation] = useState(-1);
-  const [valueValidation, setvalueValidation] = useState(-1);
+  const [valueValidation, setValueValidation] = useState(-1);
   const [jobIdValidation, setjobIdValidation] = useState(true);
   const [duplicateKeyError, setDuplicateKeyError] = useState(-1);
   const [mainClassActive, setMainClassActive] = useState(false);
@@ -281,7 +281,7 @@ function SubmitJob(
     setQuerySourceTypeList(querySourceData);
   }, []);
   useEffect(() => {
-    submitButtonDisable();
+    disableSubmitButtonIfInvalid();
     generateRandomHex();
   }, [
     clusterSelected,
@@ -303,7 +303,7 @@ function SubmitJob(
     jobIdValidation,
     duplicateKeyError
   ]);
-  const submitButtonDisable = () => {
+  const disableSubmitButtonIfInvalid  = () => {
     const isSparkJob = jobTypeSelected === 'spark';
     const isSparkRJob = jobTypeSelected === 'sparkR';
     const isPySparkJob = jobTypeSelected === 'pySpark';
@@ -613,6 +613,7 @@ function SubmitJob(
               .json()
               .then((responseResult: any) => {
                 console.log(responseResult);
+                toast.success(`Job ${jobIdSelected} successfully submitted`);
               })
               .catch((e: any) => {
                 console.log(e);
@@ -677,6 +678,7 @@ function SubmitJob(
       <div className="scroll-comp">
         <div className="cluster-details-header">
           <div
+            role="button"
             className="back-arrow-icon"
             onClick={() => handleSubmitJobBackView()}
           >
@@ -691,7 +693,7 @@ function SubmitJob(
           </div>
           {clusterList.length === 0 ? (
             <Input
-              className="select-job-style"
+              className="input-style"
               value="No clusters running"
               readOnly
             />
@@ -707,7 +709,7 @@ function SubmitJob(
           <div className="submit-job-label-header">Job</div>
           <div className="submit-job-cluster-message">Job ID*</div>
           <Input
-            className="select-job-style"
+            className="input-style"
             onChange={e => handleInputChange(e)}
             type="text"
             value={hexNumber}
@@ -745,7 +747,7 @@ function SubmitJob(
               <>
                 <div className="submit-job-cluster-message">Query file*</div>
                 <Input
-                  className="select-job-style"
+                  className="input-style"
                   onChange={e =>
                     handleValidationFiles(
                       e.target.value,
@@ -766,7 +768,7 @@ function SubmitJob(
                   </div>
                 )}
                 {queryFileValidation && (
-                  <div className="submit-job-message">{QUERYFILEMESSAGE}</div>
+                  <div className="submit-job-message">{QUERY_FILE_MESSAGE}</div>
                 )}
               </>
             )}
@@ -775,7 +777,7 @@ function SubmitJob(
               <>
                 <div className="submit-job-cluster-message">Query text*</div>
                 <Input
-                  className="select-job-style"
+                  className="input-style"
                   onChange={e => setQueryTextSelected(e.target.value)}
                   value={queryTextSelected}
                 />
@@ -788,7 +790,7 @@ function SubmitJob(
                 Main class or jar*
               </div>
               <Input
-                className="select-job-style"
+                className="input-style"
                 onChange={e =>
                   handleValidationFiles(
                     e.target.value,
@@ -796,7 +798,7 @@ function SubmitJob(
                     setMainClassValidation
                   )
                 }
-                onBlur={()=>setMainClassActive(true)}
+                onBlur={() => setMainClassActive(true)}
                 addOnBlur={true}
                 value={mainClassSelected}
               />
@@ -809,7 +811,7 @@ function SubmitJob(
                 </div>
               )}
               {(mainClassSelected !== '' || !mainClassActive) && (
-                <div className="submit-job-message">{MAINCLASSMESSAGE}</div>
+                <div className="submit-job-message">{MAIN_CLASS_MESSAGE}</div>
               )}
             </>
           )}
@@ -817,7 +819,7 @@ function SubmitJob(
             <>
               <div className="submit-job-cluster-message">Main R file*</div>
               <Input
-                className="select-job-style"
+                className="input-style"
                 onChange={e =>
                   handleValidationFiles(
                     e.target.value,
@@ -838,7 +840,7 @@ function SubmitJob(
                 </div>
               )}
               {mainRValidation && (
-                <div className="submit-job-message">{QUERYFILEMESSAGE}</div>
+                <div className="submit-job-message">{QUERY_FILE_MESSAGE}</div>
               )}
             </>
           )}
@@ -848,7 +850,7 @@ function SubmitJob(
                 Main Python file*
               </div>
               <Input
-                className="select-job-style"
+                className="input-style"
                 onChange={e =>
                   handleValidationFiles(
                     e.target.value,
@@ -869,7 +871,7 @@ function SubmitJob(
                 </div>
               )}
               {mainPythonValidation && (
-                <div className="submit-job-message">{QUERYFILEMESSAGE}</div>
+                <div className="submit-job-message">{QUERY_FILE_MESSAGE}</div>
               )}
             </>
           )}
@@ -879,7 +881,7 @@ function SubmitJob(
                 Additional python files
               </div>
               <TagsInput
-                className="select-job-style"
+                className="input-style"
                 onChange={e =>
                   handleValidationFiles(
                     e,
@@ -928,7 +930,7 @@ function SubmitJob(
                 </div>
               )}
               {jarFileValidation && (
-                <div className="submit-job-message">{JARFILEMESSAGE}</div>
+                <div className="submit-job-message">{JAR_FILE_MESSAGE}</div>
               )}
             </>
           )}
@@ -954,7 +956,7 @@ function SubmitJob(
                 </div>
               )}
               {fileValidation && (
-                <div className="submit-job-message">{FILESMESSAGE}</div>
+                <div className="submit-job-message">{FILES_MESSAGE}</div>
               )}
             </>
           )}
@@ -984,7 +986,7 @@ function SubmitJob(
                 </div>
               )}
               {archieveFileValidation && (
-                <div className="submit-job-message">{ARCHIVEFILESMESSAGE}</div>
+                <div className="submit-job-message">{ARCHIVE_FILES_MESSAGE}</div>
               )}
             </>
           )}
@@ -997,7 +999,7 @@ function SubmitJob(
                 value={argumentSelected}
                 inputProps={{ placeholder: '' }}
               />
-              <div className="submit-job-message">{ARGUMENTSMESSAGE}</div>
+              <div className="submit-job-message">{ARGUMENTS_MESSAGE}</div>
             </>
           )}
           {querySourceSelected === 'queryFile' &&
@@ -1014,7 +1016,7 @@ function SubmitJob(
                   keyValidation={keyValidation}
                   setKeyValidation={setKeyValidation}
                   valueValidation={valueValidation}
-                  setvalueValidation={setvalueValidation}
+                  setValueValidation={setValueValidation}
                   duplicateKeyError={duplicateKeyError}
                   setDuplicateKeyError={setDuplicateKeyError}
                 />
@@ -1024,12 +1026,12 @@ function SubmitJob(
             Max restarts per hour
           </div>
           <Input
-            className="select-job-style"
+            className="input-style"
             onChange={e => setMaxRestartSelected(e.target.value)}
             value={maxRestartSelected}
           />
           <div className="submit-job-message-with-link">
-            {MAXRESTARTMESSAGE}
+            {MAX_RESTART_MESSAGE}
             <div
               className="submit-job-learn-more"
               onClick={() => {
@@ -1051,7 +1053,7 @@ function SubmitJob(
             keyValidation={keyValidation}
             setKeyValidation={setKeyValidation}
             valueValidation={valueValidation}
-            setvalueValidation={setvalueValidation}
+            setValueValidation={setValueValidation}
             duplicateKeyError={duplicateKeyError}
             setDuplicateKeyError={setDuplicateKeyError}
           />
@@ -1066,7 +1068,7 @@ function SubmitJob(
             keyValidation={keyValidation}
             setKeyValidation={setKeyValidation}
             valueValidation={valueValidation}
-            setvalueValidation={setvalueValidation}
+            setValueValidation={setValueValidation}
             duplicateKeyError={duplicateKeyError}
             setDuplicateKeyError={setDuplicateKeyError}
           />
@@ -1079,6 +1081,7 @@ function SubmitJob(
               }
             >
               <div
+                role="button"
                 onClick={() => {
                   handleSubmitJobView();
                 }}
@@ -1088,6 +1091,7 @@ function SubmitJob(
             </div>
             <div className="job-cancel-button-style">
               <div
+                role="button"
                 onClick={() => {
                   handleCancelJobButton();
                 }}
diff --git a/src/login/authLogin.tsx b/src/login/authLogin.tsx
index 845f5bed..2e63eb46 100644
--- a/src/login/authLogin.tsx
+++ b/src/login/authLogin.tsx
@@ -89,6 +89,7 @@ const AuthLoginComponent = (): React.JSX.Element => {
           <div className="login-error">Please login to continue</div>
           <div style={{ alignItems: 'center' }}>
             <div
+              role="button"
               className={
                 isloginDisabled
                   ? 'signin-google-icon disabled'
@@ -113,7 +114,6 @@ const AuthLoginComponent = (): React.JSX.Element => {
 export class AuthLogin extends ReactWidget {
   constructor() {
     super();
-    this.addClass('jp-ReactWidget');
   }
 
   render(): React.JSX.Element {
diff --git a/src/login/configSelection.tsx b/src/login/configSelection.tsx
index c871ad88..d49037d9 100644
--- a/src/login/configSelection.tsx
+++ b/src/login/configSelection.tsx
@@ -30,7 +30,7 @@ import { Select } from 'semantic-ui-react';
 import 'semantic-ui-css/semantic.min.css';
 import { requestAPI } from '../handler/handler';
 import ClipLoader from 'react-spinners/ClipLoader';
-import { ToastContainer, toast } from 'react-toastify';
+import { ToastContainer, ToastOptions, toast } from 'react-toastify';
 import 'react-toastify/dist/ReactToastify.css';
 
 function ConfigSelection({ loginState, configError, setConfigError }: any) {
@@ -90,22 +90,17 @@ function ConfigSelection({ loginState, configError, setConfigError }: any) {
         const configStatus = (data as { config: string }).config;
         setIsLoading(false);
         if (configStatus && !toast.isActive('custom-toast')) {
+          const toastifyCustomStyle: ToastOptions<{}> = {
+            hideProgressBar: true,
+            autoClose: false,
+            theme: "dark",
+            position: toast.POSITION.BOTTOM_CENTER,
+            toastId: 'custom-toast'
+          }
           if(configStatus.includes('Failed')) {
-            toast.error(configStatus, {
-              hideProgressBar: true,
-              autoClose: false,
-              theme: "dark",
-              position: toast.POSITION.BOTTOM_CENTER,
-              toastId: 'custom-toast'
-            });
+            toast.error(configStatus, toastifyCustomStyle);
           } else {
-            toast.success(configStatus, {
-              hideProgressBar: true,
-              autoClose: false,
-              theme: "dark",
-              position: toast.POSITION.BOTTOM_CENTER,
-              toastId: 'custom-toast'
-            });
+            toast.success(configStatus, toastifyCustomStyle);
           }
         }
       }
@@ -136,7 +131,7 @@ function ConfigSelection({ loginState, configError, setConfigError }: any) {
         .catch((err: any) => {
           setIsLoadingUser(false);
           console.error('Error displaying user info', err);
-          toast.error('Failed to fetch User Information ');
+          toast.error('Failed to fetch user information');
         });
     }
   };
@@ -173,7 +168,7 @@ function ConfigSelection({ loginState, configError, setConfigError }: any) {
         .catch((err: any) => {
           setIsLoadingProject(false);
           console.error('Error fetching project list', err);
-          toast.error('Failed to fetch the project list ');
+          toast.error('Failed to fetch the projects');
         });
     }
   };
@@ -222,14 +217,12 @@ function ConfigSelection({ loginState, configError, setConfigError }: any) {
           .catch((error: any) => {
             setIsLoadingRegion(false);
             console.error('Error fetching region list:', error.message);
-            // Handle the error here (e.g., show an error message to the user)
           });
       }
     } catch (error) {
       setIsLoadingRegion(false);
       console.error('Error fetching region list:');
-      toast.error('Failed to fetch the region list ');
-      // Handle the error here (e.g., show an error message to the user)
+      toast.error('Failed to fetch the regions');
     }
   };
   const handleDropdownOpen = () => {
@@ -353,7 +346,7 @@ function ConfigSelection({ loginState, configError, setConfigError }: any) {
                 <div className="user-overlay">
                   <div className="user-image-overlay">
                     <img
-                      src={userInfo.picture} // Path to your placeholder image
+                      src={userInfo.picture}
                       alt="User Image"
                       className="user-image"
                     />
diff --git a/src/react-table-config.d.ts b/src/react-table-config.d.ts
new file mode 100644
index 00000000..744d6578
--- /dev/null
+++ b/src/react-table-config.d.ts
@@ -0,0 +1,120 @@
+import {
+    UseColumnOrderInstanceProps,
+    UseColumnOrderState,
+    UseExpandedHooks,
+    UseExpandedInstanceProps,
+    UseExpandedOptions,
+    UseExpandedRowProps,
+    UseExpandedState,
+    UseFiltersColumnOptions,
+    UseFiltersColumnProps,
+    UseFiltersInstanceProps,
+    UseFiltersOptions,
+    UseFiltersState,
+    UseGlobalFiltersColumnOptions,
+    UseGlobalFiltersInstanceProps,
+    UseGlobalFiltersOptions,
+    UseGlobalFiltersState,
+    UseGroupByCellProps,
+    UseGroupByColumnOptions,
+    UseGroupByColumnProps,
+    UseGroupByHooks,
+    UseGroupByInstanceProps,
+    UseGroupByOptions,
+    UseGroupByRowProps,
+    UseGroupByState,
+    UsePaginationInstanceProps,
+    UsePaginationOptions,
+    UsePaginationState,
+    UseResizeColumnsColumnOptions,
+    UseResizeColumnsColumnProps,
+    UseResizeColumnsOptions,
+    UseResizeColumnsState,
+    UseRowSelectHooks,
+    UseRowSelectInstanceProps,
+    UseRowSelectOptions,
+    UseRowSelectRowProps,
+    UseRowSelectState,
+    UseRowStateCellProps,
+    UseRowStateInstanceProps,
+    UseRowStateOptions,
+    UseRowStateRowProps,
+    UseRowStateState,
+    UseSortByColumnOptions,
+    UseSortByColumnProps,
+    UseSortByHooks,
+    UseSortByInstanceProps,
+    UseSortByOptions,
+    UseSortByState
+  } from 'react-table'
+  
+  declare module 'react-table' {
+    // take this file as-is, or comment out the sections that don't apply to your plugin configuration
+  
+    export interface TableOptions<D extends Record<string, unknown>>
+      extends UseExpandedOptions<D>,
+        UseFiltersOptions<D>,
+        UseGlobalFiltersOptions<D>,
+        UseGroupByOptions<D>,
+        UsePaginationOptions<D>,
+        UseResizeColumnsOptions<D>,
+        UseRowSelectOptions<D>,
+        UseRowStateOptions<D>,
+        UseSortByOptions<D>,
+        // note that having Record here allows you to add anything to the options, this matches the spirit of the
+        // underlying js library, but might be cleaner if it's replaced by a more specific type that matches your
+        // feature set, this is a safe default.
+        Record<string, any> {}
+  
+    export interface Hooks<D extends Record<string, unknown> = Record<string, unknown>>
+      extends UseExpandedHooks<D>,
+        UseGroupByHooks<D>,
+        UseRowSelectHooks<D>,
+        UseSortByHooks<D> {}
+  
+    export interface TableInstance<D extends Record<string, unknown> = Record<string, unknown>>
+      extends UseColumnOrderInstanceProps<D>,
+        UseExpandedInstanceProps<D>,
+        UseFiltersInstanceProps<D>,
+        UseGlobalFiltersInstanceProps<D>,
+        UseGroupByInstanceProps<D>,
+        UsePaginationInstanceProps<D>,
+        UseRowSelectInstanceProps<D>,
+        UseRowStateInstanceProps<D>,
+        UseSortByInstanceProps<D> {}
+  
+    export interface TableState<D extends Record<string, unknown> = Record<string, unknown>>
+      extends UseColumnOrderState<D>,
+        UseExpandedState<D>,
+        UseFiltersState<D>,
+        UseGlobalFiltersState<D>,
+        UseGroupByState<D>,
+        UsePaginationState<D>,
+        UseResizeColumnsState<D>,
+        UseRowSelectState<D>,
+        UseRowStateState<D>,
+        UseSortByState<D> {}
+  
+    export interface ColumnInterface<D extends Record<string, unknown> = Record<string, unknown>>
+      extends UseFiltersColumnOptions<D>,
+        UseGlobalFiltersColumnOptions<D>,
+        UseGroupByColumnOptions<D>,
+        UseResizeColumnsColumnOptions<D>,
+        UseSortByColumnOptions<D> {}
+  
+    export interface ColumnInstance<D extends Record<string, unknown> = Record<string, unknown>>
+      extends UseFiltersColumnProps<D>,
+        UseGroupByColumnProps<D>,
+        UseResizeColumnsColumnProps<D>,
+        UseSortByColumnProps<D> {}
+  
+    export interface Cell<D extends Record<string, unknown> = Record<string, unknown>, V = any>
+      extends UseGroupByCellProps<D>,
+        UseRowStateCellProps<D> {}
+  
+    export interface Row<D extends Record<string, unknown> = Record<string, unknown>>
+      extends UseExpandedRowProps<D>,
+        UseGroupByRowProps<D>,
+        UseRowSelectRowProps<D>,
+        UseRowStateRowProps<D> {}
+  }
\ No newline at end of file
diff --git a/src/sessions/listSessions.tsx b/src/sessions/listSessions.tsx
index a60516bc..dc81e146 100644
--- a/src/sessions/listSessions.tsx
+++ b/src/sessions/listSessions.tsx
@@ -77,7 +77,6 @@ const iconDelete = new LabIcon({
 });
 
 function ListSessions() {
-  //   handleBatchDetails
   const [sessionsList, setSessionsList] = useState([]);
   const [isLoading, setIsLoading] = useState(true);
   const [pollingDisable, setPollingDisable] = useState(false);
@@ -151,34 +150,36 @@ function ListSessions() {
             .json()
             .then((responseResult: any) => {
               let transformSessionListData = [];
-              let sessionsListNew = responseResult.sessions;
-              sessionsListNew.sort(
-                (a: { createTime: string }, b: { createTime: string }) => {
-                  const dateA = new Date(a.createTime);
-                  const dateB = new Date(b.createTime);
-                  return Number(dateB) - Number(dateA);
-                }
-              );
-              transformSessionListData = sessionsListNew.map((data: any) => {
-                const startTimeDisplay = jobTimeFormat(data.createTime);
-                const startTime = new Date(data.createTime);
-                let elapsedTimeString = '';
-                if (
-                  data.state === STATUS_TERMINATED ||
-                  data.state === STATUS_FAIL
-                ) {
-                  elapsedTimeString = elapsedTime(data.stateTime, startTime);
-                }
+              if (responseResult && responseResult.sessions) {
+                let sessionsListNew = responseResult.sessions;
+                sessionsListNew.sort(
+                  (a: { createTime: string }, b: { createTime: string }) => {
+                    const dateA = new Date(a.createTime);
+                    const dateB = new Date(b.createTime);
+                    return Number(dateB) - Number(dateA);
+                  }
+                );
+                transformSessionListData = sessionsListNew.map((data: any) => {
+                  const startTimeDisplay = jobTimeFormat(data.createTime);
+                  const startTime = new Date(data.createTime);
+                  let elapsedTimeString = '';
+                  if (
+                    data.state === STATUS_TERMINATED ||
+                    data.state === STATUS_FAIL
+                  ) {
+                    elapsedTimeString = elapsedTime(data.stateTime, startTime);
+                  }
 
-                return {
-                  sessionID: data.name.split('/')[5],
-                  status: data.state,
-                  location: data.name.split('/')[3],
-                  creationTime: startTimeDisplay,
-                  elapsedTime: elapsedTimeString,
-                  actions: renderActions(data)
-                };
-              });
+                  return {
+                    sessionID: data.name.split('/')[5],
+                    status: data.state,
+                    location: data.name.split('/')[3],
+                    creationTime: startTimeDisplay,
+                    elapsedTime: elapsedTimeString,
+                    actions: renderActions(data)
+                  };
+                });
+              }
 
               const existingSessionsData = previousSessionsList ?? [];
               //setStateAction never type issue
@@ -202,7 +203,7 @@ function ListSessions() {
         .catch((err: Error) => {
           setIsLoading(false);
           console.error('Error listing Sessions', err);
-          toast.error('Failed to fetch Sessions');
+          toast.error('Failed to fetch sessions');
         });
     }
   };
@@ -226,26 +227,16 @@ function ListSessions() {
     rows,
     prepareRow,
     state,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     preGlobalFilteredRows,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     setGlobalFilter,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     page,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     canPreviousPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     canNextPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     nextPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     previousPage,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     setPageSize,
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     state: { pageIndex, pageSize }
   } = useTable(
-    //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
     { columns, data, autoResetPage: false, initialState: { pageSize: 50 } },
     useGlobalFilter,
     usePagination
@@ -260,10 +251,18 @@ function ListSessions() {
     };
   }, [pollingDisable]);
 
-  function renderActions(data: { state: ClusterStatus; name: string }) {
+  const renderActions = (data: { state: ClusterStatus; name: string }) => {
+    /*
+      Extracting sessionId from sessionInfo
+      Example: "projects/{project}/locations/{location}/sessions/{name}"
+    */
+    let sessionValue = data.name.split('/')[5];
+
     return (
       <div className="actions-icon">
         <div
+          role="button"
+          aria-disabled={data.state !== ClusterStatus.STATUS_ACTIVE}
           className={
             data.state === ClusterStatus.STATUS_ACTIVE
               ? 'icon-buttons-style'
@@ -272,7 +271,7 @@ function ListSessions() {
           title="Terminate Session"
           onClick={
             data.state === ClusterStatus.STATUS_ACTIVE
-              ? () => terminateSessionAPI(data.name.split('/')[5])
+              ? () => terminateSessionAPI(sessionValue)
               : undefined
           }
         >
@@ -283,15 +282,16 @@ function ListSessions() {
           )}
         </div>
         <div
+          role="button"
           className="icon-buttons-style"
           title="Delete Session"
-          onClick={() => handleDeleteSession(data.name.split('/')[5])}
+          onClick={() => handleDeleteSession(sessionValue)}
         >
           <iconDelete.react tag="div" />
         </div>
       </div>
     );
-  }
+  };
   const handleSessionDetails = (selectedName: string) => {
     pollingSessions(listSessionsAPI, true);
     setSessionSelected(selectedName);
@@ -309,6 +309,7 @@ function ListSessions() {
     if (cell.column.Header === 'Session ID') {
       return (
         <td
+          role="button"
           {...cell.getCellProps()}
           className="cluster-name"
           onClick={() => handleSessionDetails(cell.value)}
@@ -386,7 +387,6 @@ function ListSessions() {
             <div className="filter-cluster-section">
               <GlobalFilter
                 preGlobalFilteredRows={preGlobalFilteredRows}
-                //@ts-ignore react-table Property does not exist on type 'TableInstance<object>'
                 globalFilter={state.globalFilter}
                 setGlobalFilter={setGlobalFilter}
                 setPollingDisable={setPollingDisable}
diff --git a/src/sessions/sessionDetails.tsx b/src/sessions/sessionDetails.tsx
index 58ce929c..22c73d92 100644
--- a/src/sessions/sessionDetails.tsx
+++ b/src/sessions/sessionDetails.tsx
@@ -151,7 +151,7 @@ function SessionDetails({
         .catch((err: Error) => {
           setIsLoading(false);
           console.error('Error loading session details', err);
-          toast.error('Failed to fetch Session details');
+          toast.error(`Failed to fetch session details ${sessionSelected}`);
         });
     }
   };
@@ -164,6 +164,7 @@ function SessionDetails({
       pollingSessionDetails(getSessionDetails, true);
     };
   }, []);
+  
   const createTimeDisplay = jobTimeFormat(sessionInfo.createTime);
   const parts = createTimeDisplay.split(',');
   const createTimeString = parts.slice(0, 2).join(',');
@@ -173,7 +174,8 @@ function SessionDetails({
     sessionInfo.state === STATUS_TERMINATED ||
     sessionInfo.state === STATUS_FAIL
   ) {
-    elapsedTimeString = elapsedTime(sessionInfo.stateTime, sessionStartTime);
+    const sessionStateTime = new Date(sessionInfo.stateTime); // Convert string to Date
+    elapsedTimeString = elapsedTime(sessionStateTime, sessionStartTime);
   }
   const sessionActiveTime =
     sessionInfo.stateHistory &&
@@ -183,7 +185,8 @@ function SessionDetails({
       : '';
   let runTimeString = '';
   if (sessionActiveTime !== '') {
-    runTimeString = elapsedTime(sessionInfo.stateTime, sessionActiveTime);
+    const sessionInfoStateTime = new Date(sessionInfo.stateTime);
+    runTimeString = elapsedTime(sessionInfoStateTime, sessionActiveTime);
   }
 
   return (
@@ -195,6 +198,7 @@ function SessionDetails({
             <div>
               <div className="cluster-details-header">
                 <div
+                  role="button"
                   className="back-arrow-icon"
                   onClick={() => handleDetailedView()}
                 >
@@ -202,6 +206,7 @@ function SessionDetails({
                 </div>
                 <div className="cluster-details-title">Session details</div>
                 <div
+                  role="button"
                   className={
                     sessionInfo.state === STATUS_ACTIVE
                       ? 'action-cluster-section'
@@ -353,9 +358,15 @@ function SessionDetails({
                   <div className="session-label-style-parent">
                     {labelDetail.length > 0
                       ? labelDetail.map(label => {
+                         /*
+                            Extracting key, value from label
+                               Example: "{client:dataproc_plugin}"
+                         */
+                          const labelParts = label.split(':');
+                         
                           return (
                             <div key={label} className="job-label-style">
-                              {label.split(':')[0]} : {label.split(':')[1]}
+                              {labelParts[0]} : {labelParts[1]}
                             </div>
                           );
                         })
diff --git a/src/utils/batchService.tsx b/src/utils/batchService.tsx
index 48e783d5..dcd93a91 100644
--- a/src/utils/batchService.tsx
+++ b/src/utils/batchService.tsx
@@ -47,7 +47,7 @@ export const deleteBatchAPI = async (selectedBatch: string) => {
       })
       .catch((err: Error) => {
         console.error('Error deleting batches', err);
-        toast.error('Failed to Delete the Batch ');
+        toast.error(`Failed to delete the batch ${selectedBatch}`);
       });
   }
 };
diff --git a/src/utils/clusterServices.tsx b/src/utils/clusterServices.tsx
index acf2dce7..ee0c0735 100644
--- a/src/utils/clusterServices.tsx
+++ b/src/utils/clusterServices.tsx
@@ -41,7 +41,6 @@ export const deleteClusterApi = async (selectedcluster: string) => {
           .json()
           .then((responseResult: Response) => {
             console.log(responseResult);
-            // listClustersAPI();
           })
           .catch((e: Error) => console.log(e));
       })
@@ -76,11 +75,9 @@ export const startStopAPI = async (
           .catch((e: Error) => console.log(e));
       })
       .catch((err: Error) => {
-        console.error('Error starting/stopping cluster', err);
-        toast.error('Failed to Start/Stop the Cluster');
+        console.error(`Error ${operation} cluster`, err);
+        toast.error(`Failed to ${operation} the cluster ${selectedcluster}`);
       });
-
-    // listClustersAPI();
   }
 };
 
diff --git a/src/utils/const.ts b/src/utils/const.ts
index 7c15c175..0d089d79 100644
--- a/src/utils/const.ts
+++ b/src/utils/const.ts
@@ -72,19 +72,19 @@ export const MONTH_NAMES = [
   'Nov',
   'Dec'
 ];
-export const QUERYFILEMESSAGE =
+export const QUERY_FILE_MESSAGE =
   'Can be a GCS file with the gs:// prefix, an HDFS file on the cluster with the hdfs:// prefix, or a local file on the cluster with the file:// prefix';
-export const MAINCLASSMESSAGE =
+export const MAIN_CLASS_MESSAGE =
   'The fully qualified name of a class in a provided or standard jar file, for example, com.example.wordcount, or a provided jar file to use the main class of that jar file';
-export const JARFILEMESSAGE =
+export const JAR_FILE_MESSAGE =
   'Jar files are included in the CLASSPATH. Can be a GCS file with the gs:// prefix, an HDFS file on the cluster with the hdfs:// prefix, or a local file on the cluster with the file:// prefix.';
-export const FILESMESSAGE =
+export const FILES_MESSAGE =
   'Files are included in the working directory of each executor. Can be a GCS file with the gs:// prefix, an HDFS file on the cluster with the hdfs:// prefix, or a local file on the cluster with the file:// prefix.';
-export const ARCHIVEFILESMESSAGE =
+export const ARCHIVE_FILES_MESSAGE =
   'Archive files are extracted in the Spark working directory. Can be a GCS file with the gs:// prefix, an HDFS file on the cluster with the hdfs:// prefix, or a local file on the cluster with the file:// prefix. Supported file types: .jar, .tar, .tar.gz, .tgz, .zip';
-export const ARGUMENTSMESSAGE =
+export const ARGUMENTS_MESSAGE =
   'Additional arguments to pass to the main class. Press Return after each argument.';
-export const MAXRESTARTMESSAGE =
+export const MAX_RESTART_MESSAGE =
   'Leave blank if you do not want to allow automatic restarts on job failure. ';
 export const VIEW_LOGS_CLUSTER_URL =
   'https://console.cloud.google.com/logs/query;query=resource.type="cloud_dataproc_cluster" resource.labels.cluster_name=';
@@ -102,3 +102,4 @@ export const DCU_HOURS = 3600000;
 export const GB_MONTHS = 2592000;
 export const TITLE_LAUNCHER_CATEGORY = 'Dataproc Jobs and Sessions';
 export const SPARK_HISTORY_SERVER = 'Spark History Server';
+export const DEFAULT_LABEL_DETAIL = 'client:dataproc-jupyter-plugin';
diff --git a/src/utils/deletePopup.tsx b/src/utils/deletePopup.tsx
index a0e02fa2..a54f8351 100644
--- a/src/utils/deletePopup.tsx
+++ b/src/utils/deletePopup.tsx
@@ -31,10 +31,10 @@ function DeletePopup({ onCancel, onDelete, deletePopupOpen, DeleteMsg }: any) {
         <div className="popup-text">{DeleteMsg}</div>
 
         <div className="popup-buttons">
-          <div className="popup-button-style" onClick={onCancel}>
+          <div role="button" className="popup-button-style" onClick={onCancel}>
             CANCEL
           </div>
-          <div className="popup-button-style" onClick={onDelete}>
+          <div role="button" className="popup-button-style" onClick={onDelete}>
             DELETE
           </div>
         </div>
diff --git a/src/utils/globalFilter.tsx b/src/utils/globalFilter.tsx
index 28ccf0e0..6bade3b7 100644
--- a/src/utils/globalFilter.tsx
+++ b/src/utils/globalFilter.tsx
@@ -43,6 +43,7 @@ function GlobalFilter({
           onChange(e.target.value);
         }}
         placeholder={'Filter Table'}
+        aria-label="filterd value"
         className="filter-section-part"
       />
     </span>
diff --git a/src/utils/jobServices.tsx b/src/utils/jobServices.tsx
index a8fb2428..70d9270e 100644
--- a/src/utils/jobServices.tsx
+++ b/src/utils/jobServices.tsx
@@ -41,8 +41,8 @@ export const stopJobApi = async (jobId: string) => {
           .catch((e: Error) => console.log(e));
       })
       .catch((err: Error) => {
-        console.error('Error Stoping jobs', err);
-        toast.error('Failed to Stop job');
+        console.error('Error to  stop job', err);
+        toast.error(`Failed to stop job ${jobId}`);
       });
   }
 };
@@ -64,13 +64,12 @@ export const deleteJobApi = async (jobId: string) => {
           .json()
           .then((responseResult: Response) => {
             console.log(responseResult);
-            // listJobsAPI();
           })
           .catch((e: Error) => console.log(e));
       })
       .catch((err: Error) => {
         console.error('Error Deleting Job', err);
-        toast.error('Failed to Delete the job');
+        toast.error(`Failed to delete the job ${jobId}`);
       });
   }
 };
diff --git a/src/utils/paginationView.tsx b/src/utils/paginationView.tsx
index 640ca100..bcd664c9 100644
--- a/src/utils/paginationView.tsx
+++ b/src/utils/paginationView.tsx
@@ -59,7 +59,7 @@ export const PaginationView = ({
 }: IPaginationViewProps) => {
   return (
     <div className="pagination-parent-view">
-      <div>Rows per page:</div>
+      <div>Rows per page: </div>
       <select
         className="page-size-selection"
         value={pageSize}
@@ -75,15 +75,15 @@ export const PaginationView = ({
       </select>
       {(pageIndex + 1) * pageSize > allData.length ? (
         <div className="page-display-part">
-          {pageIndex * pageSize + 1} - {allData.length} of {allData.length}
+          {pageIndex * pageSize + 1} -{' '} {allData.length} of {allData.length}
         </div>
       ) : (
         <div className="page-display-part">
-          {pageIndex * pageSize + 1} -{(pageIndex + 1) * pageSize} of{' '}
+          {pageIndex * pageSize + 1} -{' '} {(pageIndex + 1) * pageSize} of{' '}
           {allData.length}
         </div>
       )}
-      <div
+      <div role="button"
         className={
           !canPreviousPage ? 'page-move-button disabled' : 'page-move-button'
         }
@@ -91,7 +91,7 @@ export const PaginationView = ({
       >
         {'<'}
       </div>
-      <div
+      <div role="button"
         onClick={() => nextPage()}
         className={
           !canNextPage ? 'page-move-button disabled' : 'page-move-button'
diff --git a/src/utils/sessionService.tsx b/src/utils/sessionService.tsx
index 9e23492f..75a15893 100644
--- a/src/utils/sessionService.tsx
+++ b/src/utils/sessionService.tsx
@@ -38,19 +38,11 @@ export const deleteSessionAPI = async (selectedSession: string) => {
       }
     )
       .then((response: Response) => {
-        response
-          .json()
-          .then((responseResult: Response) => {
-            console.log(responseResult);
-          })
-          .catch((e: Error) => console.log(e));
+        console.log(response);
       })
       .catch((err: Error) => {
         console.error('Error deleting session', err);
-
-        toast.error('Failed to delete the session');
-
-
+        toast.error(`Failed to delete the session ${selectedSession}`);
       });
   }
 };
@@ -77,7 +69,7 @@ export const terminateSessionAPI = async (selectedSession: string) => {
       })
       .catch((err: Error) => {
         console.error('Error terminating session', err);
-        toast.error('Failed to terminate session');
+        toast.error(`Failed to terminate session ${selectedSession}`);
       });
   }
 };
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index c5683980..1017e9fc 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -96,6 +96,8 @@ export const jobTypeValue = (data: IJobData): string | undefined => {
       return SPARKSQL;
     case 'pyspark':
       return PYSPARK;
+    default:
+      return jobTypeName;
   }
 };
 export const jobTypeValueArguments = (data: IJobData): string => {
@@ -115,6 +117,8 @@ export const BatchTypeValue = (data: IJobData): string | undefined => {
       return SPARKSQL;
     case 'pyspark':
       return PYSPARK;
+    default:
+      return batchTypeName;
   }
 };
 
@@ -135,7 +139,7 @@ export const jobTypeDisplay = (data: string | undefined) => {
   }
 };
 
-export const elapsedTime = (endTime: string, jobStartTime: Date): string => {
+export const elapsedTime = (endTime: Date, jobStartTime: Date): string => {
   const jobEndTime = new Date(endTime);
   const elapsedMilliseconds = jobEndTime.getTime() - jobStartTime.getTime();
   const elapsedSeconds = Math.round(elapsedMilliseconds / 1000) % 60;
diff --git a/src/utils/viewLogs.tsx b/src/utils/viewLogs.tsx
index c5a16fa5..cb3072d8 100644
--- a/src/utils/viewLogs.tsx
+++ b/src/utils/viewLogs.tsx
@@ -81,7 +81,7 @@ function ViewLogs({
 
   return (
     <>
-      <div
+      <div role="button"
         className={
           (batchInfoResponse?.runtimeInfo?.endpoints &&
             batchInfoResponse?.runtimeInfo?.endpoints[SPARK_HISTORY_SERVER]) ||
@@ -130,39 +130,45 @@ function ViewLogs({
         )}
       </div>
       <div
+        role="button"
         className="action-cluster-section"
         onClick={() => {
-          if (sessionInfo) {
-            /*
+          /*
             Extracting project, location, session_id from sessionInfo.name
             Example: "projects/{project}/locations/{location}/sessionTemplates/{session_id}"
             */
+          const sessionValueUri=sessionInfo.name.split('/')
+           
+          if (sessionInfo) {
+           
             window.open(
               `${VIEW_LOGS_SESSION_URL} resource.labels.project_id="${
-                sessionInfo.name.split('/')[1]
+                sessionValueUri[1]
               }" resource.labels.location="${
-                sessionInfo.name.split('/')[3]
+                sessionValueUri[3]
               }" resource.labels.session_id="${
-                sessionInfo.name.split('/')[5]
+                sessionValueUri[5]
               }";cursorTimestamp=${sessionInfo.createTime};?project=${
-                sessionInfo.name.split('/')[1]
+                sessionValueUri[1]
               }`,
               '_blank'
             );
           } else {
-            /*
+             /*
             Extracting project, location, batch_id from batchInfoResponse.name 
             Example: "projects/{project}/locations/{location}/batches/{batch_id}"
             */
+            const batchValueUri=batchInfoResponse.name.split('/')
+           
             window.open(
               `${VIEW_LOGS_BATCH_URL} resource.labels.project_id="${
-                batchInfoResponse.name.split('/')[1]
+                batchValueUri[1]
               }" resource.labels.location="${
-                batchInfoResponse.name.split('/')[3]
+                batchValueUri[3]
               }" resource.labels.batch_id="${
-                batchInfoResponse.name.split('/')[5]
+                batchValueUri[5]
               }";cursorTimestamp=${batchInfoResponse.createTime};?project=${
-                batchInfoResponse.name.split('/')[1]
+                batchValueUri[1]
               }`,
               '_blank'
             );
diff --git a/style/submitJob.css b/style/submitJob.css
index 4c635aa8..be684425 100644
--- a/style/submitJob.css
+++ b/style/submitJob.css
@@ -58,6 +58,14 @@
   width: 50%;
   margin-top: 10px;
   min-height: 40px;
+  outline: none;
+}
+.input-style{
+    background: #ffffff;
+    width: 50%;
+    margin-top: 10px;
+    min-height: 40px;
+    outline: none;
 }
 .react-tagsinput-input {
   font-family: 'Roboto' !important;
@@ -96,7 +104,6 @@
   background-color: grey !important;
   padding-right: 6px !important;
 }
-
 a {
   color: black !important;
 }
@@ -203,8 +210,16 @@ a:hover {
 }
 
 /* Highlight input field when focus */
-.ui.input>input:focus {
+.ui.input>input {
+  outline: none;
+  border-radius: 4px;
+  border: 1px solid black !important;
+}
+.ui.input>input:focus{
   border: 3px solid #3367D6 !important;
+  
+  border-radius: 4px;
+  outline: none;
 }
 
 /* Highlight tags input field when focus */
diff --git a/tsconfig.json b/tsconfig.json
index 8906c2ce..b45c2152 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -18,7 +18,8 @@
     "strict": true,
     "strictNullChecks": true,
     "target": "ES2018",
-    "types": ["jest"]
+    "types": ["jest"],
+    "skipLibCheck": true
   },
   "include": ["src/*", "src/**/*"]
 }


Test patch:
diff --git a/dataproc_plugin/tests/test_handlers.py b/dataproc_plugin/tests/test_handlers.py
index da92e477..a64912cd 100644
--- a/dataproc_plugin/tests/test_handlers.py
+++ b/dataproc_plugin/tests/test_handlers.py
@@ -24,4 +24,4 @@ async def test_get_example(jp_fetch):
     payload = json.loads(response.body)
     assert payload == {
         "data": "This is /dataproc-plugin/get-example endpoint!"
-    }
\ No newline at end of file
+    }