feat(#3298): add cypress e2e tests for compact adapter feature (#3308)

* feat(#3298): Add test to validate code editor for compact adapters in UI (#3299)

* feat(#3298): Add test to validate code editor for compact adapters in UI

* feat(#3298): Add test to validate success path of add compact adapters (#3301)

* feat(#3298): Add test to validate success path of add compact adapters

* feat(#3298): Add header to yml file

* feat(#3298): Return Conflict Status Code for Duplicate Adapter ID (#3302)

* feat(#3298): Return status code conflict when adapter id is already taken

* feat(#3298): Fix checkstyle

* feat(#3298): Add test to check rename rule for compact adapters

* feat(#3298): Add test to check rename unit transformation rule for compact adapters

* feat(#3298): Fix e2e tests and improve error message in ui
diff --git a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java
index 62c514b..5c42478 100644
--- a/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java
+++ b/streampipes-connect-management/src/main/java/org/apache/streampipes/connect/management/management/AdapterMasterManagement.java
@@ -53,10 +53,11 @@
 
   private final DataStreamResourceManager dataStreamResourceManager;
 
-  public AdapterMasterManagement(IAdapterStorage adapterInstanceStorage,
-                                 AdapterResourceManager adapterResourceManager,
-                                 DataStreamResourceManager dataStreamResourceManager,
-                                 AdapterMetrics adapterMetrics
+  public AdapterMasterManagement(
+      IAdapterStorage adapterInstanceStorage,
+      AdapterResourceManager adapterResourceManager,
+      DataStreamResourceManager dataStreamResourceManager,
+      AdapterMetrics adapterMetrics
   ) {
     this.adapterInstanceStorage = adapterInstanceStorage;
     this.adapterMetrics = adapterMetrics;
@@ -64,28 +65,40 @@
     this.dataStreamResourceManager = dataStreamResourceManager;
   }
 
-  public void addAdapter(AdapterDescription ad,
-                           String adapterElementId,
-                           String principalSid)
+  public void addAdapter(
+      AdapterDescription adapterDescription,
+      String adapterId,
+      String principalSid
+  )
       throws AdapterException {
 
-    // Create elementId for adapter
+    // Create elementId for datastream
     var dataStreamElementId = ElementIdGenerator.makeElementId(SpDataStream.class);
-    ad.setElementId(adapterElementId);
-    ad.setCreatedAt(System.currentTimeMillis());
-    ad.setCorrespondingDataStreamElementId(dataStreamElementId);
+    adapterDescription.setElementId(adapterId);
+    adapterDescription.setCreatedAt(System.currentTimeMillis());
+    adapterDescription.setCorrespondingDataStreamElementId(dataStreamElementId);
 
     // Add EventGrounding to AdapterDescription
     var eventGrounding = GroundingUtils.createEventGrounding();
-    ad.setEventGrounding(eventGrounding);
+    adapterDescription.setEventGrounding(eventGrounding);
 
-    this.adapterResourceManager.encryptAndCreate(ad);
+    this.adapterResourceManager.encryptAndCreate(adapterDescription);
 
-    // Create stream
-    var storedDescription = new SourcesManagement().createAdapterDataStream(ad, dataStreamElementId);
-    storedDescription.setCorrespondingAdapterId(adapterElementId);
+    // Stream is only created if the adpater is successfully stored
+    createDataStreamForAdapter(adapterDescription, adapterId, dataStreamElementId, principalSid);
+  }
+
+  private void createDataStreamForAdapter(
+      AdapterDescription adapterDescription,
+      String adapterId,
+      String streamId,
+      String principalSid
+  ) throws AdapterException {
+    var storedDescription = new SourcesManagement()
+        .createAdapterDataStream(adapterDescription, streamId);
+    storedDescription.setCorrespondingAdapterId(adapterId);
     installDataSource(storedDescription, principalSid, true);
-    LOG.info("Install source (source URL: {} in backend", ad.getElementId());
+    LOG.info("Install source (source URL: {} in backend", adapterDescription.getElementId());
   }
 
   public AdapterDescription getAdapter(String elementId) throws AdapterException {
@@ -163,7 +176,8 @@
       var baseUrl = new ExtensionsServiceEndpointGenerator().getEndpointBaseUrl(
           ad.getAppId(),
           SpServiceUrlProvider.ADAPTER,
-          ad.getDeploymentConfiguration().getDesiredServiceTags()
+          ad.getDeploymentConfiguration()
+            .getDesiredServiceTags()
       );
 
       // Update selected endpoint URL of adapter
@@ -182,9 +196,11 @@
     }
   }
 
-  private void installDataSource(SpDataStream stream,
-                                 String principalSid,
-                                 boolean publicElement) throws AdapterException {
+  private void installDataSource(
+      SpDataStream stream,
+      String principalSid,
+      boolean publicElement
+  ) throws AdapterException {
     try {
       new DataStreamVerifier(stream).verifyAndAdd(principalSid, publicElement);
     } catch (SepaParseException e) {
diff --git a/streampipes-connect-management/src/test/java/org/apache/streampipes/connect/management/management/AdapterMasterManagementTest.java b/streampipes-connect-management/src/test/java/org/apache/streampipes/connect/management/management/AdapterMasterManagementTest.java
index 6d920fb..e1e1832 100644
--- a/streampipes-connect-management/src/test/java/org/apache/streampipes/connect/management/management/AdapterMasterManagementTest.java
+++ b/streampipes-connect-management/src/test/java/org/apache/streampipes/connect/management/management/AdapterMasterManagementTest.java
@@ -36,12 +36,12 @@
 public class AdapterMasterManagementTest {
 
   @Test
-  public void getAdapterFailNull() {
-    AdapterInstanceStorageImpl adapterStorage = mock(AdapterInstanceStorageImpl.class);
-    AdapterResourceManager resourceManager = mock(AdapterResourceManager.class);
+  public void getAdapter_FailNull() {
+    var adapterStorage = mock(AdapterInstanceStorageImpl.class);
+    var resourceManager = mock(AdapterResourceManager.class);
     when(adapterStorage.findAll()).thenReturn(null);
 
-    AdapterMasterManagement adapterMasterManagement =
+    var adapterMasterManagement =
         new AdapterMasterManagement(
             adapterStorage,
             resourceManager,
@@ -53,13 +53,13 @@
   }
 
   @Test
-  public void getAdapterFail() {
-    List<AdapterDescription> adapterDescriptions = List.of(new AdapterDescription());
-    AdapterInstanceStorageImpl adapterStorage = mock(AdapterInstanceStorageImpl.class);
-    AdapterResourceManager resourceManager = mock(AdapterResourceManager.class);
+  public void getAdapter_Fail() {
+    var adapterDescriptions = List.of(new AdapterDescription());
+    var adapterStorage = mock(AdapterInstanceStorageImpl.class);
+    var resourceManager = mock(AdapterResourceManager.class);
     when(adapterStorage.findAll()).thenReturn(adapterDescriptions);
 
-    AdapterMasterManagement adapterMasterManagement =
+    var adapterMasterManagement =
         new AdapterMasterManagement(
             adapterStorage,
             resourceManager,
@@ -71,10 +71,10 @@
   }
 
   @Test
-  public void getAllAdaptersSuccess() throws AdapterException {
-    List<AdapterDescription> adapterDescriptions = List.of(new AdapterDescription());
-    AdapterInstanceStorageImpl adapterStorage = mock(AdapterInstanceStorageImpl.class);
-    AdapterResourceManager resourceManager = mock(AdapterResourceManager.class);
+  public void getAllAdapters_Success() throws AdapterException {
+    var adapterDescriptions = List.of(new AdapterDescription());
+    var adapterStorage = mock(AdapterInstanceStorageImpl.class);
+    var resourceManager = mock(AdapterResourceManager.class);
     when(adapterStorage.findAll()).thenReturn(adapterDescriptions);
 
     AdapterMasterManagement adapterMasterManagement =
@@ -91,12 +91,12 @@
   }
 
   @Test
-  public void getAllAdaptersFail() {
-    AdapterInstanceStorageImpl adapterStorage = mock(AdapterInstanceStorageImpl.class);
-    AdapterResourceManager resourceManager = mock(AdapterResourceManager.class);
+  public void getAllAdapters_Fail() {
+    var adapterStorage = mock(AdapterInstanceStorageImpl.class);
+    var resourceManager = mock(AdapterResourceManager.class);
     when(adapterStorage.findAll()).thenReturn(null);
 
-    AdapterMasterManagement adapterMasterManagement =
+    var adapterMasterManagement =
         new AdapterMasterManagement(
             adapterStorage,
             resourceManager,
diff --git a/streampipes-model/src/main/java/org/apache/streampipes/model/message/Notifications.java b/streampipes-model/src/main/java/org/apache/streampipes/model/message/Notifications.java
index 4e14af9..965a842 100644
--- a/streampipes-model/src/main/java/org/apache/streampipes/model/message/Notifications.java
+++ b/streampipes-model/src/main/java/org/apache/streampipes/model/message/Notifications.java
@@ -44,8 +44,12 @@
     return new ErrorMessage(new Notification(type.name(), type.description()));
   }
 
+  public static ErrorMessage error(String message, String description) {
+    return new ErrorMessage(new Notification(message, description));
+  }
+
   public static ErrorMessage error(String message) {
-    return new ErrorMessage(new Notification(message, ""));
+    return error(message, "");
   }
 
   public static ErrorMessage error(NotificationType type, String info) {
diff --git a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AdapterResourceManager.java b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AdapterResourceManager.java
index 72c7712..8e3d4d4 100644
--- a/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AdapterResourceManager.java
+++ b/streampipes-resource-management/src/main/java/org/apache/streampipes/resource/management/AdapterResourceManager.java
@@ -17,6 +17,7 @@
  */
 package org.apache.streampipes.resource.management;
 
+import org.apache.streampipes.commons.exceptions.connect.AdapterException;
 import org.apache.streampipes.model.connect.adapter.AdapterDescription;
 import org.apache.streampipes.model.util.Cloner;
 import org.apache.streampipes.resource.management.secret.SecretProvider;
@@ -30,7 +31,8 @@
   }
 
   public AdapterResourceManager() {
-    super(StorageDispatcher.INSTANCE.getNoSqlStore().getAdapterInstanceStorage());
+    super(StorageDispatcher.INSTANCE.getNoSqlStore()
+                                    .getAdapterInstanceStorage());
   }
 
   /**
@@ -39,10 +41,15 @@
    * @param adapterDescription input adapter description
    * @return the id of the created adapter
    */
-  public String encryptAndCreate(AdapterDescription adapterDescription) {
-    AdapterDescription encryptedAdapterDescription = cloneAndEncrypt(adapterDescription);
+  public String encryptAndCreate(AdapterDescription adapterDescription) throws AdapterException {
+    var encryptedAdapterDescription = cloneAndEncrypt(adapterDescription);
     encryptedAdapterDescription.setRev(null);
-    return db.persist(encryptedAdapterDescription).v;
+
+    try {
+      return db.persist(encryptedAdapterDescription).v;
+    } catch (org.lightcouch.DocumentConflictException e) {
+      throw new AdapterException("Conflict occurred while creating the adapter", e);
+    }
   }
 
   /**
@@ -50,8 +57,15 @@
    *
    * @param adapterDescription input adapter description
    */
-  public void encryptAndUpdate(AdapterDescription adapterDescription) {
-    db.updateElement(cloneAndEncrypt(adapterDescription));
+  public void encryptAndUpdate(AdapterDescription adapterDescription) throws AdapterException {
+    try {
+      db.updateElement(cloneAndEncrypt(adapterDescription));
+    } catch (org.lightcouch.DocumentConflictException e) {
+      throw new AdapterException(
+          "Conflict occurred while editing the adapter with id: %s".formatted(adapterDescription.getElementId()),
+          e
+      );
+    }
   }
 
   public void delete(String elementId) {
@@ -63,7 +77,8 @@
    */
   private AdapterDescription cloneAndEncrypt(AdapterDescription adapterDescription) {
     AdapterDescription encryptedAdapterDescription = new Cloner().adapterDescription(adapterDescription);
-    SecretProvider.getEncryptionService().apply(encryptedAdapterDescription);
+    SecretProvider.getEncryptionService()
+                  .apply(encryptedAdapterDescription);
     return encryptedAdapterDescription;
   }
 
diff --git a/streampipes-resource-management/src/test/java/org/apache/streampipes/resource/management/AdapterResourceManagerTest.java b/streampipes-resource-management/src/test/java/org/apache/streampipes/resource/management/AdapterResourceManagerTest.java
index d815855..d461671 100644
--- a/streampipes-resource-management/src/test/java/org/apache/streampipes/resource/management/AdapterResourceManagerTest.java
+++ b/streampipes-resource-management/src/test/java/org/apache/streampipes/resource/management/AdapterResourceManagerTest.java
@@ -18,25 +18,59 @@
 
 package org.apache.streampipes.resource.management;
 
+import org.apache.streampipes.commons.exceptions.connect.AdapterException;
+import org.apache.streampipes.model.Tuple2;
 import org.apache.streampipes.model.connect.adapter.AdapterDescription;
 import org.apache.streampipes.storage.api.IAdapterStorage;
 
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 public class AdapterResourceManagerTest {
 
-  @Test
-  public void encryptAndUpdateValidateDescriptionStored() {
+  private IAdapterStorage storage;
+  private AdapterResourceManager adapterResourceManager;
 
-    IAdapterStorage storage = mock(IAdapterStorage.class);
-    AdapterResourceManager adapterResourceManager = new AdapterResourceManager(storage);
+  @BeforeEach
+  void setUp() {
+    storage = mock(IAdapterStorage.class);
+    adapterResourceManager = new AdapterResourceManager(storage);
+  }
+
+  @Test
+  public void encryptAndUpdate_ValidateDescriptionStored() throws AdapterException {
+
     adapterResourceManager.encryptAndUpdate(new AdapterDescription());
 
     verify(storage, times(1)).updateElement(any());
   }
+
+  @Test
+  void encryptAndCreate_ReturnsIdOnSuccess() throws AdapterException {
+    var id = "adapterId";
+
+    when(storage.persist(any())).thenReturn(new Tuple2<>(true, id));
+    var result = adapterResourceManager.encryptAndCreate(new AdapterDescription());
+
+    verify(storage, times(1)).persist(any());
+    assertEquals(id, result);
+  }
+
+  @Test
+  void encryptAndCreate_ThrowsAdapterExceptionOnConflict() {
+
+    doThrow(new org.lightcouch.DocumentConflictException("Conflict")).when(storage).persist(any());
+
+    assertThrows(AdapterException.class, () -> adapterResourceManager.encryptAndCreate(new AdapterDescription()));
+  }
+
 }
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java
index b972aaa..372769a 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/AdapterResource.java
@@ -40,6 +40,7 @@
 import org.apache.streampipes.storage.api.IPipelineStorage;
 import org.apache.streampipes.storage.management.StorageDispatcher;
 
+import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.apache.http.HttpStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -115,7 +116,7 @@
       updateManager.updateAdapter(adapterDescription);
     } catch (AdapterException e) {
       LOG.error("Error while updating adapter with id {}", adapterDescription.getElementId(), e);
-      return ok(Notifications.error(e.getMessage()));
+      return ok(Notifications.error(e.getMessage(), ExceptionUtils.getStackTrace(e)));
     }
 
     return ok(Notifications.success(adapterDescription.getElementId()));
diff --git a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/CompactAdapterResource.java b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/CompactAdapterResource.java
index 88424c2..0e51f00 100644
--- a/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/CompactAdapterResource.java
+++ b/streampipes-rest/src/main/java/org/apache/streampipes/rest/impl/connect/CompactAdapterResource.java
@@ -37,6 +37,7 @@
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -58,7 +59,7 @@
   public CompactAdapterResource() {
     super(() -> new AdapterMasterManagement(
         StorageDispatcher.INSTANCE.getNoSqlStore()
-            .getAdapterInstanceStorage(),
+                                  .getAdapterInstanceStorage(),
         new SpResourceManager().manageAdapters(),
         new SpResourceManager().manageDataStreams(),
         AdapterMetricsManager.INSTANCE.getAdapterMetrics()
@@ -82,11 +83,23 @@
     var adapterDescription = getGeneratedAdapterDescription(compactAdapter);
     var principalSid = getAuthenticatedUserSid();
 
+    var adapterId = adapterDescription.getElementId();
+
     try {
-      var adapterId = adapterDescription.getElementId();
       managementService.addAdapter(adapterDescription, adapterId, principalSid);
+    } catch (AdapterException e) {
+      LOG.error(
+          "Error while storing the adapterDescription with appId {}. An adapter with the given id already exists.",
+          adapterDescription.getAppId(), e
+      );
+      return ResponseEntity.status(HttpStatus.CONFLICT)
+                           .body(Notifications.error(e.getMessage()));
+    }
+
+    try {
       if (compactAdapter.createOptions() != null) {
-        if (compactAdapter.createOptions().persist()) {
+        if (compactAdapter.createOptions()
+                          .persist()) {
           var storedAdapter = managementService.getAdapter(adapterId);
           var status = new PersistPipelineHandler(
               getNoSqlStorage().getPipelineTemplateStorage(),
@@ -96,7 +109,8 @@
               getAuthenticatedUserSid()
           ).createAndStartPersistPipeline(storedAdapter);
         }
-        if (compactAdapter.createOptions().start()) {
+        if (compactAdapter.createOptions()
+                          .start()) {
           managementService.startStreamAdapter(adapterId);
         }
       }
@@ -143,8 +157,10 @@
     return new CompactAdapterManagement(generators).convertToAdapterDescription(compactAdapter);
   }
 
-  private AdapterDescription getGeneratedAdapterDescription(CompactAdapter compactAdapter,
-                                                            AdapterDescription existingAdapter) throws Exception {
+  private AdapterDescription getGeneratedAdapterDescription(
+      CompactAdapter compactAdapter,
+      AdapterDescription existingAdapter
+  ) throws Exception {
     var generators = adapterGenerationSteps.getGenerators();
     return new CompactAdapterManagement(generators).convertToAdapterDescription(compactAdapter, existingAdapter);
   }
diff --git a/ui/cypress/fixtures/connect/compact/machineDataSimulator.yml b/ui/cypress/fixtures/connect/compact/machineDataSimulator.yml
new file mode 100644
index 0000000..128b249
--- /dev/null
+++ b/ui/cypress/fixtures/connect/compact/machineDataSimulator.yml
@@ -0,0 +1,24 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+id: sp:adapterdescription:4pxl2w
+name: Test
+appId: org.apache.streampipes.connect.iiot.adapters.simulator.machine
+configuration:
+    - wait-time-ms: '1000'
+    - selected-simulator-option: flowrate
+createOptions:
+    persist: false
+    start: false
diff --git a/ui/cypress/support/builder/CompactAdapterBuilder.ts b/ui/cypress/support/builder/CompactAdapterBuilder.ts
new file mode 100644
index 0000000..2325985
--- /dev/null
+++ b/ui/cypress/support/builder/CompactAdapterBuilder.ts
@@ -0,0 +1,93 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+import { CompactAdapter } from '../../../projects/streampipes/platform-services/src/lib/model/gen/streampipes-model';
+
+export class CompactAdapterBuilder {
+    private compactAdapter: CompactAdapter;
+
+    constructor() {
+        this.compactAdapter = new CompactAdapter();
+        this.compactAdapter.configuration = [];
+        this.compactAdapter.createOptions = {
+            persist: false,
+            start: false,
+        };
+        this.compactAdapter.transform = {
+            rename: {},
+            measurementUnit: {},
+        };
+    }
+
+    public static create(appId: string) {
+        const builder = new CompactAdapterBuilder();
+        builder.compactAdapter.appId = appId;
+        return builder;
+    }
+
+    // Optional parameter, when not set a random id will be generated
+    public setId(id: string) {
+        this.compactAdapter.id = id;
+        return this;
+    }
+
+    public setName(name: string) {
+        this.compactAdapter.name = name;
+        return this;
+    }
+
+    public setDescription(description: string) {
+        this.compactAdapter.description = description;
+        return this;
+    }
+
+    public withRename(from: string, to: string) {
+        this.compactAdapter.transform.rename[from] = to;
+        return this;
+    }
+
+    public withMeasurementUnit(property: string, unit: string) {
+        this.compactAdapter.transform.measurementUnit[property] = unit;
+        return this;
+    }
+
+    public addConfiguration(key: string, value: string) {
+        const configuration = { [key]: value };
+        this.compactAdapter.configuration.push(configuration);
+        return this;
+    }
+
+    public setPersist() {
+        this.compactAdapter.createOptions.persist = true;
+        return this;
+    }
+
+    public setStart() {
+        this.compactAdapter.createOptions.start = true;
+        return this;
+    }
+
+    public build() {
+        if (!this.compactAdapter.id) {
+            this.compactAdapter.id =
+                'sp:adapterdescription:' +
+                Math.random().toString(36).substring(7);
+        }
+        return this.compactAdapter;
+    }
+}
diff --git a/ui/cypress/support/utils/CompactUtils.ts b/ui/cypress/support/utils/CompactUtils.ts
new file mode 100644
index 0000000..38df176
--- /dev/null
+++ b/ui/cypress/support/utils/CompactUtils.ts
@@ -0,0 +1,27 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+export class CompactUtils {
+    public static ymlConfiguration() {
+        return cy.dataCy('yaml-configuration', { timeout: 5000 });
+    }
+
+    public static jsonConfiguration() {
+        return cy.dataCy('json-configuration', { timeout: 5000 });
+    }
+}
diff --git a/ui/cypress/support/utils/GeneralUtils.ts b/ui/cypress/support/utils/GeneralUtils.ts
new file mode 100644
index 0000000..8db505e
--- /dev/null
+++ b/ui/cypress/support/utils/GeneralUtils.ts
@@ -0,0 +1,23 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+export class GeneralUtils {
+    public static tab(identifier: string) {
+        return cy.dataCy(`tab-${identifier}`).click();
+    }
+}
diff --git a/ui/cypress/support/utils/ProcessingElementTestUtils.ts b/ui/cypress/support/utils/ProcessingElementTestUtils.ts
index f2607a1..6340635 100644
--- a/ui/cypress/support/utils/ProcessingElementTestUtils.ts
+++ b/ui/cypress/support/utils/ProcessingElementTestUtils.ts
@@ -18,7 +18,7 @@
 
 import { FileManagementUtils } from './FileManagementUtils';
 import { ConnectUtils } from './connect/ConnectUtils';
-import { PipelineUtils } from './PipelineUtils';
+import { PipelineUtils } from './pipeline/PipelineUtils';
 import { DataLakeUtils } from './datalake/DataLakeUtils';
 import { PipelineBuilder } from '../builder/PipelineBuilder';
 import { PipelineElementBuilder } from '../builder/PipelineElementBuilder';
diff --git a/ui/cypress/support/utils/ThirdPartyIntegrationUtils.ts b/ui/cypress/support/utils/ThirdPartyIntegrationUtils.ts
index a9229a9..09a871c 100644
--- a/ui/cypress/support/utils/ThirdPartyIntegrationUtils.ts
+++ b/ui/cypress/support/utils/ThirdPartyIntegrationUtils.ts
@@ -18,7 +18,7 @@
 
 import { ConnectUtils } from './connect/ConnectUtils';
 import { PipelineBuilder } from '../builder/PipelineBuilder';
-import { PipelineUtils } from './PipelineUtils';
+import { PipelineUtils } from './pipeline/PipelineUtils';
 import { PipelineElementInput } from '../model/PipelineElementInput';
 import { AdapterInput } from '../model/AdapterInput';
 import { AdapterBuilder } from '../builder/AdapterBuilder';
diff --git a/ui/cypress/support/utils/connect/CompactAdapterUtils.ts b/ui/cypress/support/utils/connect/CompactAdapterUtils.ts
new file mode 100644
index 0000000..43757f5
--- /dev/null
+++ b/ui/cypress/support/utils/connect/CompactAdapterUtils.ts
@@ -0,0 +1,81 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+import { CompactAdapter } from '../../../../projects/streampipes/platform-services/src/lib/model/gen/streampipes-model';
+import { CompactAdapterBuilder } from '../../builder/CompactAdapterBuilder';
+
+export class CompactAdapterUtils {
+    /**
+     * Stores a compact adapter by sending a POST request to the backend.
+     *
+     * @param {CompactAdapter} compactAdapter - The compact adapter to be stored.
+     * @param {boolean} [failOnStatusCode=true] - Whether to fail the request on a non-2xx status code.
+     * @returns {Cypress.Chainable} - The Cypress chainable object representing the request.
+     */
+    public static storeCompactAdapter(
+        compactAdapter: CompactAdapter,
+        failOnStatusCode: boolean = true,
+    ): Cypress.Chainable {
+        return this.postCompactAdapterRequest(
+            'application/json',
+            compactAdapter,
+            failOnStatusCode,
+        );
+    }
+
+    /**
+     * Stores a compact YAML adapter by sending a POST request to the backend.
+     *
+     * @param {string} body - The YAML string representing the compact adapter.
+     * @returns {Cypress.Chainable} - The Cypress chainable object representing the request.
+     */
+    public static storeCompactYmlAdapter(body: string) {
+        return this.postCompactAdapterRequest('application/yml', body);
+    }
+
+    private static postCompactAdapterRequest(
+        contentType: string,
+        body: any,
+        failOnStatusCode = true,
+    ) {
+        const token = window.localStorage.getItem('auth-token');
+        return cy.request({
+            method: 'POST',
+            url: '/streampipes-backend/api/v2/connect/compact-adapters',
+            body: body,
+            failOnStatusCode: failOnStatusCode,
+            headers: {
+                'Accept': contentType,
+                'Content-Type': contentType,
+                'Authorization': `Bearer ${token}`,
+            },
+        });
+    }
+
+    /**
+     * Creates a CompactAdapterBuilder instance configured for a machine data simulator.
+     */
+    public static getMachineDataSimulator(): CompactAdapterBuilder {
+        return CompactAdapterBuilder.create(
+            'org.apache.streampipes.connect.iiot.adapters.simulator.machine',
+        )
+            .setName('Test')
+            .addConfiguration('wait-time-ms', '1000')
+            .addConfiguration('selected-simulator-option', 'flowrate');
+    }
+}
diff --git a/ui/cypress/support/utils/connect/ConnectBtns.ts b/ui/cypress/support/utils/connect/ConnectBtns.ts
index 20bfd69..ea8b2d8 100644
--- a/ui/cypress/support/utils/connect/ConnectBtns.ts
+++ b/ui/cypress/support/utils/connect/ConnectBtns.ts
@@ -17,7 +17,11 @@
  */
 export class ConnectBtns {
     public static detailsAdapter() {
-        return cy.dataCy('details-adapter');
+        return cy.dataCy('details-adapter', { timeout: 10000 });
+    }
+
+    public static deleteAdapter() {
+        return cy.dataCy('delete-adapter', { timeout: 10000 });
     }
 
     public static editAdapter() {
@@ -69,6 +73,10 @@
         return cy.dataCy('stop-all-adapters-btn');
     }
 
+    public static showCodeCheckbox() {
+        return cy.dataCy('show-code-checkbox');
+    }
+
     // ========================================================================
 
     // =====================  Event Schema buttons  ==========================
diff --git a/ui/cypress/support/utils/connect/ConnectUtils.ts b/ui/cypress/support/utils/connect/ConnectUtils.ts
index aaeccff..0a0eae2 100644
--- a/ui/cypress/support/utils/connect/ConnectUtils.ts
+++ b/ui/cypress/support/utils/connect/ConnectUtils.ts
@@ -23,7 +23,7 @@
 import { ConnectBtns } from './ConnectBtns';
 import { AdapterBuilder } from '../../builder/AdapterBuilder';
 import { UserUtils } from '../UserUtils';
-import { PipelineUtils } from '../PipelineUtils';
+import { PipelineUtils } from '../pipeline/PipelineUtils';
 
 export class ConnectUtils {
     public static testAdapter(
@@ -76,9 +76,11 @@
             );
         }
 
-        ConnectEventSchemaUtils.markPropertyAsTimestamp(
-            adapterConfiguration.timestampProperty,
-        );
+        if (adapterConfiguration.timestampProperty) {
+            ConnectEventSchemaUtils.markPropertyAsTimestamp(
+                adapterConfiguration.timestampProperty,
+            );
+        }
 
         ConnectEventSchemaUtils.finishEventSchemaConfiguration();
     }
@@ -356,6 +358,12 @@
         ConnectUtils.validateEventsInPreview(amountOfProperties);
     }
 
+    public static getLivePreviewValue(runtimeName: string) {
+        return cy.dataCy(`live-preview-value-${runtimeName}`, {
+            timeout: 10000,
+        });
+    }
+
     public static validateEventsInPreview(amountOfProperties: number) {
         // View data
         ConnectBtns.detailsAdapter().click();
@@ -370,11 +378,25 @@
             amountOfProperties,
         );
 
-        cy.wait(1000);
+        cy.dataCy('live-preview-table-no-data', { timout: 1000 }).should(
+            'not.exist',
+        );
+    }
 
-        cy.dataCy('live-preview-table-value')
-            .invoke('text')
-            .then(text => expect(text).not.to.include('no data'));
+    /**
+     * Validates the event schema for an adapter by checking the amount of properties
+     * and the runtime names of the event properties
+     * @param runtimeNames runtime names of the event properties
+     */
+    public static validateEventSchema(runtimeNames: string[]) {
+        ConnectUtils.goToConnect();
+        ConnectBtns.detailsAdapter().click();
+
+        cy.get('tr.mat-mdc-row').should('have.length', runtimeNames.length);
+
+        runtimeNames.forEach(name => {
+            cy.get('td.mat-column-runtimeName').contains(name).should('exist');
+        });
     }
 
     public static tearDownPreprocessingRuleTest(
@@ -403,4 +425,21 @@
         // Close dialog
         cy.get('button').contains('Close').parent().click();
     }
+
+    public static validateAdapterIsRunning() {
+        ConnectUtils.goToConnect();
+        ConnectBtns.startAdapter().should('have.length', 0);
+        ConnectBtns.stopAdapter().should('have.length', 1);
+    }
+
+    public static validateAdapterIsStopped() {
+        ConnectUtils.goToConnect();
+        ConnectBtns.startAdapter().should('have.length', 1);
+        ConnectBtns.stopAdapter().should('have.length', 0);
+    }
+
+    public static checkAmountOfAdapters(amount: number) {
+        ConnectUtils.goToConnect();
+        ConnectBtns.deleteAdapter().should('have.length', amount);
+    }
 }
diff --git a/ui/cypress/support/utils/pipeline/PipelineBtns.ts b/ui/cypress/support/utils/pipeline/PipelineBtns.ts
new file mode 100644
index 0000000..6ace822
--- /dev/null
+++ b/ui/cypress/support/utils/pipeline/PipelineBtns.ts
@@ -0,0 +1,23 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+export class PipelineBtns {
+    public static deletePipeline() {
+        return cy.dataCy('delete-pipeline', { timeout: 10000 });
+    }
+}
diff --git a/ui/cypress/support/utils/PipelineUtils.ts b/ui/cypress/support/utils/pipeline/PipelineUtils.ts
similarity index 72%
rename from ui/cypress/support/utils/PipelineUtils.ts
rename to ui/cypress/support/utils/pipeline/PipelineUtils.ts
index b901e22..0fa9ce4 100644
--- a/ui/cypress/support/utils/PipelineUtils.ts
+++ b/ui/cypress/support/utils/pipeline/PipelineUtils.ts
@@ -1,25 +1,26 @@
 /*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
  *
- *    http://www.apache.org/licenses/LICENSE-2.0
+ *     http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
  *
  */
 
-import { PipelineInput } from '../model/PipelineInput';
-import { StaticPropertyUtils } from './userInput/StaticPropertyUtils';
-import { OutputStrategyUtils } from './OutputStrategyUtils';
-import { PipelineElementInput } from '../model/PipelineElementInput';
+import { PipelineInput } from '../../model/PipelineInput';
+import { StaticPropertyUtils } from '../userInput/StaticPropertyUtils';
+import { OutputStrategyUtils } from '../OutputStrategyUtils';
+import { PipelineElementInput } from '../../model/PipelineElementInput';
+import { PipelineBtns } from './PipelineBtns';
 
 export class PipelineUtils {
     public static addPipeline(pipelineInput: PipelineInput) {
@@ -131,21 +132,18 @@
     }
 
     public static checkAmountOfPipelinesPipeline(amount: number) {
-        cy.visit('#/pipelines');
-        cy.dataCy('delete-pipeline').should('have.length', amount);
+        PipelineUtils.goToPipelines();
+        PipelineBtns.deletePipeline().should('have.length', amount);
     }
 
     public static deletePipeline() {
         // Delete pipeline
-        cy.visit('#/pipelines');
-        cy.dataCy('delete-pipeline').should('have.length', 1);
-        cy.dataCy('delete-pipeline').click({ force: true });
+        PipelineUtils.goToPipelines();
+        PipelineBtns.deletePipeline().should('have.length', 1);
+        PipelineBtns.deletePipeline().click({ force: true });
 
         cy.dataCy('sp-pipeline-stop-and-delete').click();
 
-        cy.dataCy('delete-pipeline', { timeout: 10000 }).should(
-            'have.length',
-            0,
-        );
+        PipelineBtns.deletePipeline().should('have.length', 0);
     }
 }
diff --git a/ui/cypress/tests/connect/compact/addCompactAdapter.spec.ts b/ui/cypress/tests/connect/compact/addCompactAdapter.spec.ts
new file mode 100644
index 0000000..c19e345
--- /dev/null
+++ b/ui/cypress/tests/connect/compact/addCompactAdapter.spec.ts
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { ConnectUtils } from '../../../support/utils/connect/ConnectUtils';
+import { CompactAdapterUtils } from '../../../support/utils/connect/CompactAdapterUtils';
+import { PipelineUtils } from '../../../support/utils/pipeline/PipelineUtils';
+
+describe('Add Compact Adapters', () => {
+    beforeEach('Setup Test', () => {
+        cy.initStreamPipesTest();
+    });
+
+    it('Add an adapter via the compact API. Do not start', () => {
+        const compactAdapter =
+            CompactAdapterUtils.getMachineDataSimulator().build();
+
+        CompactAdapterUtils.storeCompactAdapter(compactAdapter).then(() => {
+            ConnectUtils.validateAdapterIsStopped();
+
+            PipelineUtils.checkAmountOfPipelinesPipeline(0);
+        });
+    });
+
+    it('Add an adapter via the compact API. Start Adapter', () => {
+        const compactAdapter = CompactAdapterUtils.getMachineDataSimulator()
+            .setStart()
+            .build();
+
+        CompactAdapterUtils.storeCompactAdapter(compactAdapter).then(() => {
+            ConnectUtils.validateAdapterIsRunning();
+
+            PipelineUtils.checkAmountOfPipelinesPipeline(0);
+        });
+    });
+
+    it('Add an adapter via the compact API. Start Adapter and start persist pipeline', () => {
+        const compactAdapter = CompactAdapterUtils.getMachineDataSimulator()
+            .setStart()
+            .setPersist()
+            .build();
+
+        CompactAdapterUtils.storeCompactAdapter(compactAdapter).then(() => {
+            ConnectUtils.validateAdapterIsRunning();
+
+            PipelineUtils.checkAmountOfPipelinesPipeline(1);
+        });
+    });
+
+    it('Add an adapter via the compact API via yml API.', () => {
+        cy.readFile(
+            'cypress/fixtures/connect/compact/machineDataSimulator.yml',
+        ).then(ymlDescription => {
+            CompactAdapterUtils.storeCompactYmlAdapter(ymlDescription).then(
+                () => {
+                    ConnectUtils.validateAdapterIsStopped();
+                },
+            );
+        });
+    });
+
+    it('Ensure correct error code when adapter with the same id already exists', () => {
+        const compactAdapter = CompactAdapterUtils.getMachineDataSimulator()
+            .setStart()
+            .setPersist()
+            .build();
+
+        CompactAdapterUtils.storeCompactAdapter(compactAdapter).then(
+            response => {
+                expect(response.status).to.equal(200);
+                ConnectUtils.checkAmountOfAdapters(1);
+
+                // Store the same adapter a second time and validate that resource returns status of conflict
+                CompactAdapterUtils.storeCompactAdapter(
+                    compactAdapter,
+                    false,
+                ).then(response => {
+                    expect(response.status).to.equal(409);
+
+                    ConnectUtils.checkAmountOfAdapters(1);
+                });
+            },
+        );
+    });
+});
diff --git a/ui/cypress/tests/connect/compact/compactAdapterWithTransformation.spec.ts b/ui/cypress/tests/connect/compact/compactAdapterWithTransformation.spec.ts
new file mode 100644
index 0000000..4af2f35
--- /dev/null
+++ b/ui/cypress/tests/connect/compact/compactAdapterWithTransformation.spec.ts
@@ -0,0 +1,73 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+import { ConnectUtils } from '../../../support/utils/connect/ConnectUtils';
+import { CompactAdapterUtils } from '../../../support/utils/connect/CompactAdapterUtils';
+import { ConnectBtns } from '../../../support/utils/connect/ConnectBtns';
+
+describe('Add Compact Adapters', () => {
+    beforeEach('Setup Test', () => {
+        cy.initStreamPipesTest();
+    });
+
+    it('Add an adapter and rename a property', () => {
+        const newPropertyName = 'temperature_renamed';
+        const compactAdapter = CompactAdapterUtils.getMachineDataSimulator()
+            .withRename('temperature', newPropertyName)
+            .setStart()
+            .build();
+
+        CompactAdapterUtils.storeCompactAdapter(compactAdapter).then(() => {
+            const runtimeNames = [
+                'density',
+                'mass_flow',
+                'sensor_fault_flags',
+                'sensorId',
+                newPropertyName,
+                'timestamp',
+                'volume_flow',
+            ];
+
+            ConnectUtils.validateEventSchema(runtimeNames);
+        });
+    });
+
+    it('Add an adapter and change measurement unit', () => {
+        const compactAdapter = CompactAdapterUtils.getMachineDataSimulator()
+            .withMeasurementUnit(
+                'temperature',
+                'http://qudt.org/vocab/unit#DegreeFahrenheit',
+            )
+            .setStart()
+            .build();
+
+        CompactAdapterUtils.storeCompactAdapter(compactAdapter).then(() => {
+            ConnectUtils.goToConnect();
+            ConnectBtns.detailsAdapter().click();
+
+            // This assertion works because the original value is below 100
+            // with the transformation the value is above 100
+            ConnectUtils.getLivePreviewValue('temperature')
+                .invoke('text')
+                .then(text => {
+                    const value = parseFloat(text.trim());
+                    expect(value).to.be.greaterThan(100);
+                });
+        });
+    });
+});
diff --git a/ui/cypress/tests/connect/compact/uiConfiguration.spec.ts b/ui/cypress/tests/connect/compact/uiConfiguration.spec.ts
new file mode 100644
index 0000000..798d8a8
--- /dev/null
+++ b/ui/cypress/tests/connect/compact/uiConfiguration.spec.ts
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { ConnectUtils } from '../../../support/utils/connect/ConnectUtils';
+import { AdapterBuilder } from '../../../support/builder/AdapterBuilder';
+import { ConnectBtns } from '../../../support/utils/connect/ConnectBtns';
+import { GeneralUtils } from '../../../support/utils/GeneralUtils';
+import { CompactUtils } from '../../../support/utils/CompactUtils';
+
+describe('Test Compact Adapters', () => {
+    beforeEach('Setup Test', () => {
+        cy.initStreamPipesTest();
+    });
+
+    it('Validate that code for existing adapter is displayed correctly', () => {
+        const adapterInput = AdapterBuilder.create('Machine_Data_Simulator')
+            .setName('Machine Data Simulator Test')
+            .addInput('input', 'wait-time-ms', '1000')
+            .build();
+
+        ConnectUtils.addAdapter(adapterInput);
+
+        // Validate code editor in start dialog
+        ConnectBtns.showCodeCheckbox().parent().click();
+        validateCodeEditor();
+
+        ConnectUtils.startAdapter(adapterInput);
+
+        // Validate code editor in adapter details
+        ConnectBtns.detailsAdapter().click();
+        GeneralUtils.tab('Code');
+        validateCodeEditor();
+    });
+
+    const validateCodeEditor = () => {
+        CompactUtils.ymlConfiguration().should('be.visible');
+        cy.contains('span', 'JSON').click();
+        CompactUtils.jsonConfiguration().should('be.visible');
+    };
+});
diff --git a/ui/cypress/tests/connect/deleteAdapterWithMultipleUsers.smoke.spec.ts b/ui/cypress/tests/connect/deleteAdapterWithMultipleUsers.smoke.spec.ts
index 29c854c..a11332a 100644
--- a/ui/cypress/tests/connect/deleteAdapterWithMultipleUsers.smoke.spec.ts
+++ b/ui/cypress/tests/connect/deleteAdapterWithMultipleUsers.smoke.spec.ts
@@ -20,7 +20,7 @@
 import { PipelineBuilder } from '../../support/builder/PipelineBuilder';
 import { PipelineElementBuilder } from '../../support/builder/PipelineElementBuilder';
 import { UserUtils } from '../../support/utils/UserUtils';
-import { PipelineUtils } from '../../support/utils/PipelineUtils';
+import { PipelineUtils } from '../../support/utils/pipeline/PipelineUtils';
 
 const adapterName = 'simulator';
 
diff --git a/ui/cypress/tests/connect/editAdapter.smoke.spec.ts b/ui/cypress/tests/connect/editAdapter.smoke.spec.ts
index 214e843..a1d2013 100644
--- a/ui/cypress/tests/connect/editAdapter.smoke.spec.ts
+++ b/ui/cypress/tests/connect/editAdapter.smoke.spec.ts
@@ -57,6 +57,8 @@
 
         cy.dataCy('sp-adapter-name').clear().type(newAdapterName);
 
+        // This wait is required to ensure that there is no couch db update conflict
+        cy.wait(1000);
         ConnectBtns.storeEditAdapter().click();
 
         cy.dataCy('sp-connect-adapter-success-added', {
diff --git a/ui/cypress/tests/connect/editAdapterSettingsAndPipeline.spec.ts b/ui/cypress/tests/connect/editAdapterSettingsAndPipeline.spec.ts
index c30f355..c3f14b7 100644
--- a/ui/cypress/tests/connect/editAdapterSettingsAndPipeline.spec.ts
+++ b/ui/cypress/tests/connect/editAdapterSettingsAndPipeline.spec.ts
@@ -18,7 +18,7 @@
 
 import { ConnectUtils } from '../../support/utils/connect/ConnectUtils';
 import { ConnectBtns } from '../../support/utils/connect/ConnectBtns';
-import { PipelineUtils } from '../../support/utils/PipelineUtils';
+import { PipelineUtils } from '../../support/utils/pipeline/PipelineUtils';
 import { PipelineElementBuilder } from '../../support/builder/PipelineElementBuilder';
 import { PipelineBuilder } from '../../support/builder/PipelineBuilder';
 import { AdapterBuilder } from '../../support/builder/AdapterBuilder';
diff --git a/ui/cypress/tests/connect/persistInDataLake.smoke.spec.ts b/ui/cypress/tests/connect/persistInDataLake.smoke.spec.ts
index 39c672b..939bf44 100644
--- a/ui/cypress/tests/connect/persistInDataLake.smoke.spec.ts
+++ b/ui/cypress/tests/connect/persistInDataLake.smoke.spec.ts
@@ -17,7 +17,7 @@
  */
 
 import { ConnectUtils } from '../../support/utils/connect/ConnectUtils';
-import { PipelineUtils } from '../../support/utils/PipelineUtils';
+import { PipelineUtils } from '../../support/utils/pipeline/PipelineUtils';
 import { FileManagementUtils } from '../../support/utils/FileManagementUtils';
 import { AdapterBuilder } from '../../support/builder/AdapterBuilder';
 import { ConnectBtns } from '../../support/utils/connect/ConnectBtns';
diff --git a/ui/cypress/tests/datalake/configuration.smoke.spec.ts b/ui/cypress/tests/datalake/configuration.smoke.spec.ts
index 3b5532e..1b095ab 100644
--- a/ui/cypress/tests/datalake/configuration.smoke.spec.ts
+++ b/ui/cypress/tests/datalake/configuration.smoke.spec.ts
@@ -16,7 +16,7 @@
  *
  */
 
-import { PipelineUtils } from '../../support/utils/PipelineUtils';
+import { PipelineUtils } from '../../support/utils/pipeline/PipelineUtils';
 import { DataLakeUtils } from '../../support/utils/datalake/DataLakeUtils';
 
 describe('Test Truncate data in datalake', () => {
diff --git a/ui/cypress/tests/experimental/restartStreamPipes/restartStreamPipes1.ts b/ui/cypress/tests/experimental/restartStreamPipes/restartStreamPipes1.ts
index 3f098de..d8eafe8 100644
--- a/ui/cypress/tests/experimental/restartStreamPipes/restartStreamPipes1.ts
+++ b/ui/cypress/tests/experimental/restartStreamPipes/restartStreamPipes1.ts
@@ -17,7 +17,7 @@
  */
 
 import { ConnectUtils } from '../../../support/utils/connect/ConnectUtils';
-import { PipelineUtils } from '../../../support/utils/PipelineUtils';
+import { PipelineUtils } from '../../../support/utils/pipeline/PipelineUtils';
 import { PipelineElementBuilder } from '../../../support/builder/PipelineElementBuilder';
 import { PipelineBuilder } from '../../../support/builder/PipelineBuilder';
 import { DashboardUtils } from '../../../support/utils/DashboardUtils';
diff --git a/ui/cypress/tests/experimental/testJvmArchetype/testJvmArchetype.ts b/ui/cypress/tests/experimental/testJvmArchetype/testJvmArchetype.ts
index 2a41d84..c15490d 100644
--- a/ui/cypress/tests/experimental/testJvmArchetype/testJvmArchetype.ts
+++ b/ui/cypress/tests/experimental/testJvmArchetype/testJvmArchetype.ts
@@ -17,7 +17,7 @@
  */
 
 import { ConnectUtils } from '../../../support/utils/connect/ConnectUtils';
-import { PipelineUtils } from '../../../support/utils/PipelineUtils';
+import { PipelineUtils } from '../../../support/utils/pipeline/PipelineUtils';
 import { PipelineElementBuilder } from '../../../support/builder/PipelineElementBuilder';
 import { PipelineBuilder } from '../../../support/builder/PipelineBuilder';
 import { DashboardUtils } from '../../../support/utils/DashboardUtils';
diff --git a/ui/cypress/tests/pipeline/pipelineTest.smoke.spec.ts b/ui/cypress/tests/pipeline/pipelineTest.smoke.spec.ts
index 1de708d..010f769 100644
--- a/ui/cypress/tests/pipeline/pipelineTest.smoke.spec.ts
+++ b/ui/cypress/tests/pipeline/pipelineTest.smoke.spec.ts
@@ -17,7 +17,7 @@
  */
 
 import { ConnectUtils } from '../../support/utils/connect/ConnectUtils';
-import { PipelineUtils } from '../../support/utils/PipelineUtils';
+import { PipelineUtils } from '../../support/utils/pipeline/PipelineUtils';
 import { PipelineElementBuilder } from '../../support/builder/PipelineElementBuilder';
 import { PipelineBuilder } from '../../support/builder/PipelineBuilder';
 
diff --git a/ui/cypress/tests/pipeline/updatePipelineTest.smoke.spec.ts b/ui/cypress/tests/pipeline/updatePipelineTest.smoke.spec.ts
index b2e69bd..5de2359 100644
--- a/ui/cypress/tests/pipeline/updatePipelineTest.smoke.spec.ts
+++ b/ui/cypress/tests/pipeline/updatePipelineTest.smoke.spec.ts
@@ -17,7 +17,7 @@
  */
 
 import { ConnectUtils } from '../../support/utils/connect/ConnectUtils';
-import { PipelineUtils } from '../../support/utils/PipelineUtils';
+import { PipelineUtils } from '../../support/utils/pipeline/PipelineUtils';
 import { PipelineElementBuilder } from '../../support/builder/PipelineElementBuilder';
 import { PipelineBuilder } from '../../support/builder/PipelineBuilder';
 
diff --git a/ui/cypress/tests/pipelineElement/PipelineElementDocumentation.spec.ts b/ui/cypress/tests/pipelineElement/PipelineElementDocumentation.spec.ts
index 726ed1c..4387a2e 100644
--- a/ui/cypress/tests/pipelineElement/PipelineElementDocumentation.spec.ts
+++ b/ui/cypress/tests/pipelineElement/PipelineElementDocumentation.spec.ts
@@ -16,7 +16,7 @@
  *
  */
 
-import { PipelineUtils } from '../../support/utils/PipelineUtils';
+import { PipelineUtils } from '../../support/utils/pipeline/PipelineUtils';
 
 describe('Validate that the markdown documentation for pipeline elements works', () => {
     beforeEach('Setup Test', () => {
diff --git a/ui/cypress/tests/pipelineElementConfigurationTemplate/pipelineElementConfigurationTemplate.ts b/ui/cypress/tests/pipelineElementConfigurationTemplate/pipelineElementConfigurationTemplate.ts
index 2b9fff9..16ea5c3 100644
--- a/ui/cypress/tests/pipelineElementConfigurationTemplate/pipelineElementConfigurationTemplate.ts
+++ b/ui/cypress/tests/pipelineElementConfigurationTemplate/pipelineElementConfigurationTemplate.ts
@@ -16,7 +16,7 @@
  *
  */
 
-import { PipelineUtils } from '../../support/utils/PipelineUtils';
+import { PipelineUtils } from '../../support/utils/pipeline/PipelineUtils';
 import { PipelineBuilder } from '../../support/builder/PipelineBuilder';
 import { PipelineElementBuilder } from '../../support/builder/PipelineElementBuilder';
 import { ConnectUtils } from '../../support/utils/connect/ConnectUtils';
diff --git a/ui/cypress/tests/userManagement/testGroupManagement.spec.ts b/ui/cypress/tests/userManagement/testGroupManagement.spec.ts
index 2f4de9e..03d7159 100644
--- a/ui/cypress/tests/userManagement/testGroupManagement.spec.ts
+++ b/ui/cypress/tests/userManagement/testGroupManagement.spec.ts
@@ -20,7 +20,7 @@
 import { UserRole } from '../../../src/app/_enums/user-role.enum';
 import { UserUtils } from '../../support/utils/UserUtils';
 import { ConnectUtils } from '../../support/utils/connect/ConnectUtils';
-import { PipelineUtils } from '../../support/utils/PipelineUtils';
+import { PipelineUtils } from '../../support/utils/pipeline/PipelineUtils';
 import { PipelineElementBuilder } from '../../support/builder/PipelineElementBuilder';
 import { PipelineBuilder } from '../../support/builder/PipelineBuilder';
 
diff --git a/ui/cypress/tests/userManagement/testUserRolePipeline.spec.ts b/ui/cypress/tests/userManagement/testUserRolePipeline.spec.ts
index a992334..94d8341 100644
--- a/ui/cypress/tests/userManagement/testUserRolePipeline.spec.ts
+++ b/ui/cypress/tests/userManagement/testUserRolePipeline.spec.ts
@@ -20,7 +20,7 @@
 import { UserRole } from '../../../src/app/_enums/user-role.enum';
 import { UserUtils } from '../../support/utils/UserUtils';
 import { ConnectUtils } from '../../support/utils/connect/ConnectUtils';
-import { PipelineUtils } from '../../support/utils/PipelineUtils';
+import { PipelineUtils } from '../../support/utils/pipeline/PipelineUtils';
 import { PipelineElementBuilder } from '../../support/builder/PipelineElementBuilder';
 import { PipelineBuilder } from '../../support/builder/PipelineBuilder';
 
diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.html b/ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.html
index 68f9377..c613d3c 100644
--- a/ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.html
+++ b/ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.html
@@ -42,6 +42,7 @@
                     *ngFor="let item of spNavigationItems"
                     (click)="navigateTo(item)"
                     [active]="activeLink === item.itemId"
+                    [attr.data-cy]="'tab-' + item.itemTitle"
                 >
                     <span>{{ item.itemTitle }}</span>
                 </a>
diff --git a/ui/src/app/connect/components/adapter-configuration/start-adapter-configuration/start-adapter-configuration.component.html b/ui/src/app/connect/components/adapter-configuration/start-adapter-configuration/start-adapter-configuration.component.html
index f7ff5b8..d4eecdd 100644
--- a/ui/src/app/connect/components/adapter-configuration/start-adapter-configuration/start-adapter-configuration.component.html
+++ b/ui/src/app/connect/components/adapter-configuration/start-adapter-configuration/start-adapter-configuration.component.html
@@ -150,6 +150,7 @@
             optionTitle="Show code"
             optionDescription="Show code to programmatically deploy this adapter over the API"
             optionIcon="code"
+            dataCy="show-code-checkbox"
             (optionSelectedEmitter)="showCode = $event"
         >
             @if (showCode) {
diff --git a/ui/src/app/connect/dialog/adapter-started/adapter-started-dialog.component.ts b/ui/src/app/connect/dialog/adapter-started/adapter-started-dialog.component.ts
index 598dae3..459327f 100644
--- a/ui/src/app/connect/dialog/adapter-started/adapter-started-dialog.component.ts
+++ b/ui/src/app/connect/dialog/adapter-started/adapter-started-dialog.component.ts
@@ -24,6 +24,7 @@
     CompactPipeline,
     CompactPipelineElement,
     ErrorMessage,
+    Message,
     PipelineOperationStatus,
     PipelineTemplateService,
     PipelineUpdateInfo,
@@ -112,16 +113,22 @@
     updateAdapter(): void {
         this.loadingText = `Updating adapter ${this.adapter.name}`;
         this.loading = true;
-        this.adapterService.updateAdapter(this.adapter).subscribe(
-            res => {
-                this.onAdapterReady(
-                    `Adapter ${this.adapter.name} was successfully updated and is available in the pipeline editor.`,
-                );
+        this.adapterService.updateAdapter(this.adapter).subscribe({
+            next: status => {
+                if (status.success) {
+                    this.onAdapterReady(
+                        `Adapter ${this.adapter.name} was successfully updated and is available in the pipeline editor.`,
+                    );
+                } else {
+                    const errorLogMessage = this.getErrorLogMessage(status);
+
+                    this.onAdapterFailure(errorLogMessage);
+                }
             },
-            error => {
+            error: error => {
                 this.onAdapterFailure(error.error);
             },
-        );
+        });
     }
 
     addAdapter() {
@@ -137,16 +144,8 @@
                         this.startAdapter(adapterElementId, true);
                     }
                 } else {
-                    const errorMsg: SpLogMessage = {
-                        cause:
-                            status.notifications.length > 0
-                                ? status.notifications[0].title
-                                : 'Unknown Error',
-                        detail: '',
-                        fullStackTrace: '',
-                        level: 'ERROR',
-                        title: 'Unknown Error',
-                    };
+                    const errorMsg: SpLogMessage =
+                        this.getErrorLogMessage(status);
 
                     this.onAdapterFailure(errorMsg);
                 }
@@ -157,6 +156,20 @@
         );
     }
 
+    private getErrorLogMessage(status: Message): SpLogMessage {
+        const notification = status.notifications[0] || {
+            title: 'Unknown Error',
+            description: '',
+        };
+        return {
+            cause: notification.title,
+            detail: '',
+            fullStackTrace: notification.description,
+            level: 'ERROR',
+            title: 'Unknown Error',
+        };
+    }
+
     startAdapter(adapterElementId: string, showPreview = false) {
         const successMessage =
             'Your new data stream is now available in the pipeline editor.';
diff --git a/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.html b/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.html
index 083d929..a6590ce 100644
--- a/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.html
+++ b/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.html
@@ -22,6 +22,7 @@
             [innerHTML]="configuration | yamlpretty"
             class="preview-text"
             [ngStyle]="{ maxHeight: maxHeight }"
+            data-cy="yaml-configuration"
         ></pre>
     </mat-tab>
     <mat-tab label="JSON">
@@ -29,6 +30,7 @@
             [innerHTML]="configuration | jsonpretty"
             class="preview-text"
             [ngStyle]="{ maxHeight: maxHeight }"
+            data-cy="json-configuration"
         ></pre>
     </mat-tab>
 </mat-tab-group>
diff --git a/ui/src/app/core-ui/pipeline-element-runtime-info/live-preview-table/live-preview-table.component.html b/ui/src/app/core-ui/pipeline-element-runtime-info/live-preview-table/live-preview-table.component.html
index ffaf3bd..ceb6851 100644
--- a/ui/src/app/core-ui/pipeline-element-runtime-info/live-preview-table/live-preview-table.component.html
+++ b/ui/src/app/core-ui/pipeline-element-runtime-info/live-preview-table/live-preview-table.component.html
@@ -57,7 +57,12 @@
             <th mat-header-cell *matHeaderCellDef><strong>Value</strong></th>
             <td mat-cell *matCellDef="let element" style="width: 200px">
                 @if (element.value === undefined) {
-                    <div class="value no-data">no data</div>
+                    <div
+                        data-cy="live-preview-table-no-data"
+                        class="value no-data"
+                    >
+                        no data
+                    </div>
                 } @else {
                     <ng-container *ngIf="element.isImage">
                         <img
@@ -75,7 +80,9 @@
                     </ng-container>
                     <ng-container *ngIf="element.hasNoDomainProperty">
                         <div
-                            data-cy="live-preview-table-value"
+                            [attr.data-cy]="
+                                'live-preview-value-' + element.runtimeName
+                            "
                             class="value"
                             [class.value-changed]="element.valueChanged"
                         >