You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2023/02/27 17:30:05 UTC

[camel-k] 01/19: chore: test rearrange

This is an automated email from the ASF dual-hosted git repository.

pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 54a7378eab23e69224774c09c56ac8b5bf45e0d7
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Feb 21 15:31:27 2023 +0100

    chore: test rearrange
    
    Common workflow
---
 .github/actions/e2e-common/exec-tests.sh           |   4 +-
 e2e/{global => }/builder/build_test.go             |   0
 e2e/{global => }/builder/files/groovy.groovy       |   0
 e2e/{global => }/builder/registry_test.go          |   0
 e2e/common/cli/bind_test.go                        |  64 ++++
 .../cli/config_test.go}                            |  49 +--
 e2e/common/cli/debug_test.go                       | 110 ++++++
 .../knative/doc.go => common/cli/default.go}       |   8 +-
 e2e/common/cli/delete_test.go                      |  87 +++++
 e2e/common/cli/describe_test.go                    |  84 +++++
 e2e/common/cli/dev_mode_test.go                    | 221 ++++++++++++
 .../cli/dump_test.go}                              |  45 ++-
 .../cli/duplicate_parameters_test.go               |   2 +-
 .../common/build => common/cli}/files/Java.java    |   0
 .../cli/files/JavaDuplicateParams.java             |   0
 .../cli/files/TimerCustomKameletIntegration.java   |   0
 .../cli/files/promote-route-edited.groovy          |   0
 .../cli/files/promote-route.groovy                 |   0
 .../cli}/files/resource-file-location-route.groovy |   0
 .../install => common}/cli/files/run.yaml          |   0
 .../cli/files/timer-kamelet-usage.groovy           |   0
 e2e/{global/common => common/cli}/files/yaml.yaml  |   0
 e2e/common/cli/get_test.go                         |  72 ++++
 e2e/common/cli/help_test.go                        |  57 ++++
 e2e/common/cli/kamel-config.yaml                   |   3 +
 .../install => common}/cli/kamelet_test.go         |  57 ++--
 e2e/{namespace/install => common}/cli/log_test.go  |  43 ++-
 .../cli/offline_commands_test.go                   |  11 +-
 e2e/common/cli/run_test.go                         | 181 ++++++++++
 .../install => common}/cli/version_test.go         |  12 +-
 e2e/common/config/config_test.go                   | 350 +++++++++++++++++++
 .../builder/doc.go => common/config/default.go}    |   8 +-
 .../config/files/build-property-file-route.groovy  |   0
 .../config/files/build-property-route.groovy       |   0
 .../files/config-configmap-properties-route.groovy |   0
 .../config/files/config-configmap-route.groovy     |   0
 .../common/config/files/config-file-route.groovy   |   0
 .../config/files/config-secret-key-route.groovy    |   0
 .../common/config/files/config-secret-route.groovy |   0
 e2e/{global => }/common/config/files/my.properties |   0
 .../common/config/files/property-file-route.groovy |   0
 .../common/config/files/property-route.groovy      |   0
 .../common/config/files/quarkus.properties         |   0
 .../resource-configmap-key-location-route.groovy   |   0
 .../files/resource-configmap-location-route.groovy |   0
 .../config/files/resource-configmap-route.groovy   |   0
 .../resource-file-base64-encoded-route.groovy      |   0
 .../config/files/resource-file-binary-route.groovy |   0
 .../files/resource-file-location-route.groovy      |   0
 .../common/config/files/resource-file-route.groovy |   0
 .../config/files/resource-secret-route.groovy      |   0
 .../common/config/files/resources-data-same.txt    |   0
 .../common/config/files/resources-data.txt         |   0
 .../common/config/files/resources-data.zip         | Bin
 .../knative/doc.go => common/languages/default.go} |   8 +-
 e2e/{global => }/common/languages/files/Java.java  |   0
 e2e/{global => }/common/languages/files/Prop.java  |   0
 .../common/languages/files/groovy.groovy           |   0
 .../common/languages/files/js-polyglot.js          |   0
 e2e/{global => }/common/languages/files/js.js      |   0
 e2e/{global => }/common/languages/files/kotlin.kts |   0
 .../common/languages/files/prop.properties         |   0
 e2e/{global => }/common/languages/files/xml.xml    |   0
 .../common/languages/files/yaml-polyglot.yaml      |   0
 e2e/{global => }/common/languages/files/yaml.yaml  |   0
 e2e/{global => }/common/languages/groovy_test.go   |  28 +-
 .../common/languages/init_test_support.go          |   4 +-
 .../xml_test.go => common/languages/java_test.go}  |  37 +-
 .../yaml_test.go => common/languages/js_test.go}   |  30 +-
 e2e/{global => }/common/languages/kotlin_test.go   |  28 +-
 e2e/{global => }/common/languages/polyglot_test.go |  22 +-
 .../js_test.go => common/languages/xml_test.go}    |  30 +-
 .../xml_test.go => common/languages/yaml_test.go}  |  30 +-
 e2e/{global/common => common/misc}/client_test.go  |  55 +--
 e2e/common/misc/cron_test.go                       |  75 +++++
 .../knative/doc.go => common/misc/default.go}      |   8 +-
 .../common => common/misc}/files/BadRoute.java     |   0
 e2e/{global/common => common/misc}/files/Java.java |   0
 .../misc}/files/TimerCustomKameletIntegration.java |   0
 .../misc}/files/TimerKameletIntegration.java       |   2 +-
 .../common => common/misc}/files/Unresolvable.java |   0
 .../misc}/files/cron-fallback.yaml                 |   0
 .../common => common/misc}/files/cron-quartz.yaml  |   0
 .../common => common/misc}/files/cron-timer.yaml   |   0
 .../common => common/misc}/files/cron-yaml.yaml    |   0
 e2e/{global/common => common/misc}/files/cron.yaml |   0
 .../kamelets/timer-custom-source.kamelet.yaml      |   0
 .../misc/files/my-timer-source.kamelet.yaml}       |   2 +-
 .../misc/files/registry}/FoobarDecryption.java     |   0
 .../misc/files/registry}/LaughingRoute.java        |   0
 .../misc/files/registry}/classpath/Xslt.java       |   0
 .../misc/files/registry}/classpath/cheese.xsl      |   0
 .../files => common/misc/files/registry}/laugh.txt |   0
 .../misc/files/registry}/laughs/haha.txt           |   0
 .../misc/files/registry}/laughs/hehe.txt           |   0
 .../misc/files/registry}/sample-decryption-1.0.jar | Bin
 .../misc/files/registry}/sample-decryption-1.0.pom |   0
 .../main/java/camelk/DeterministicDecryption.java  |   0
 .../misc}/files/rest-consumer.yaml                 |   0
 .../misc}/files/rest-producer.yaml                 |   0
 .../knative => common/misc}/files/yaml.yaml        |   0
 e2e/common/misc/integration_fail_test.go           | 120 +++++++
 e2e/common/misc/kamelet_binding_test.go            | 170 ++++++++++
 e2e/common/misc/kamelet_binding_with_image_test.go | 109 ++++++
 .../install/cli => common/misc}/kamelet_test.go    |  49 ++-
 .../common => common/misc}/kamelet_update_test.go  |  22 +-
 .../build => common/misc}/maven_repository_test.go |  31 +-
 .../misc}/platformless_run_test.go                 |  28 +-
 e2e/common/misc/registry_maven_wagon_test.go       | 141 ++++++++
 e2e/common/misc/rest_test.go                       |  91 +++++
 e2e/common/misc/scale_binding_test.go              | 133 ++++++++
 e2e/common/misc/scale_integration_test.go          | 131 ++++++++
 .../misc/structured_logs_test.go}                  |  47 ++-
 e2e/{global/common => common/misc}/tekton_test.go  |  35 +-
 .../startup_test.go}                               |  29 +-
 .../common/doc.go => common/teardown_test.go}      |  17 +-
 e2e/common/traits/affinity_test.go                 | 152 +++++++++
 e2e/common/traits/container_test.go                | 100 ++++++
 .../knative/doc.go => common/traits/default.go}    |   8 +-
 e2e/common/traits/deployment_test.go               |  93 +++++
 .../traits/error_handler_test.go}                  |  24 +-
 e2e/common/traits/errored_trait_test.go            |  79 +++++
 .../common/traits/files/ErroredRoute.java          |   0
 e2e/{global => }/common/traits/files/Java.java     |   0
 e2e/{global => }/common/traits/files/Master.java   |   0
 .../common/traits/files/NeverReady.java            |   0
 .../common/traits/files/PlatformHttpServer.java    |   0
 .../common/traits/files/PodTest.groovy             |   0
 .../traits}/files/ServiceBinding.java              |   0
 .../common/traits/files/jvm/Classpath.java         |   0
 .../common/traits/files/jvm/sample-1.0.jar         | Bin
 .../common/traits/files/openapi/petstore-api.yaml  |   0
 .../common/traits/files/openapi/petstore.groovy    |   0
 .../files/template-with-supplemental-groups.yaml   |   0
 e2e/{global => }/common/traits/files/template.yaml |   0
 e2e/common/traits/health_test.go                   | 328 ++++++++++++++++++
 e2e/{global => }/common/traits/istio_test.go       |  36 +-
 .../traits/jolokia_test.go}                        |  47 ++-
 e2e/{global => }/common/traits/jvm_test.go         |  43 ++-
 e2e/common/traits/master_test.go                   |  69 ++++
 e2e/common/traits/openapi_test.go                  |  89 +++++
 e2e/common/traits/pdb_test.go                      | 162 +++++++++
 e2e/{global => }/common/traits/pod_test.go         |  38 +--
 e2e/{global => }/common/traits/prometheus_test.go  |  63 ++--
 e2e/common/traits/pull_secret_test.go              |  90 +++++
 e2e/common/traits/route_test.go                    | 329 ++++++++++++++++++
 .../traits}/service_binding_test.go                |  43 ++-
 e2e/common/traits/service_test.go                  | 111 ++++++
 e2e/common/traits/toleration_test.go               | 129 +++++++
 e2e/global/common/config/config_test.go            | 373 ---------------------
 e2e/global/common/cron_test.go                     |  93 -----
 e2e/global/common/integration_fail_test.go         | 137 --------
 e2e/global/common/kamelet_binding_test.go          | 181 ----------
 .../common/kamelet_binding_with_image_test.go      | 118 -------
 e2e/global/common/kamelet_test.go                  |  82 -----
 e2e/global/common/languages/java_test.go           |  61 ----
 e2e/global/common/rest_test.go                     | 100 ------
 e2e/global/common/scale_binding_test.go            | 140 --------
 e2e/global/common/scale_integration_test.go        | 139 --------
 e2e/global/common/traits/affinity_test.go          | 155 ---------
 e2e/global/common/traits/container_test.go         | 104 ------
 e2e/global/common/traits/deployment_test.go        |  98 ------
 e2e/global/common/traits/error_handler_test.go     |  59 ----
 e2e/global/common/traits/errored_trait_test.go     |  82 -----
 e2e/global/common/traits/health_test.go            | 345 -------------------
 e2e/global/common/traits/jolokia_test.go           |  61 ----
 e2e/global/common/traits/master_test.go            |  84 -----
 e2e/global/common/traits/openapi_test.go           | 118 -------
 e2e/global/common/traits/pdb_test.go               | 175 ----------
 e2e/global/common/traits/pull_secret_test.go       |  93 -----
 e2e/global/common/traits/route_test.go             | 341 -------------------
 e2e/global/common/traits/service_test.go           | 114 -------
 e2e/global/common/traits/toleration_test.go        | 144 --------
 e2e/global/registry/registry_maven_wagon_test.go   | 144 --------
 .../service_binding_kamelet_test.go                |  74 ----
 e2e/{global => }/knative/files/display.groovy      |   0
 e2e/{global => }/knative/files/flow.yaml           |   0
 e2e/{global => }/knative/files/http_out.groovy     |   0
 e2e/{global => }/knative/files/knative1.groovy     |   0
 e2e/{global => }/knative/files/knative2.groovy     |   0
 e2e/{global => }/knative/files/knative3.groovy     |   0
 .../knative/files/knative_broker_receiver.groovy   |   0
 .../knative/files/knative_broker_sender.groovy     |   0
 e2e/{global => }/knative/files/knativech1.groovy   |   0
 e2e/{global => }/knative/files/knativech2.groovy   |   0
 e2e/{global => }/knative/files/knativeevt1.groovy  |   0
 e2e/{global => }/knative/files/knativeevt2.groovy  |   0
 .../knative/files/knativegetpost1.groovy           |   0
 .../knative/files/knativegetpost2.groovy           |   0
 .../knative/files/knativemultihop1.groovy          |   0
 .../knative/files/knativemultihop2.groovy          |   0
 .../knative/files/knativemultihop3.groovy          |   0
 e2e/{global => }/knative/files/petstore-api.yaml   |   0
 e2e/{global => }/knative/files/petstore.groovy     |   0
 .../knative/files/podtest-knative1.groovy          |   0
 .../knative/files/podtest-knative2.groovy          |   0
 .../knative/files/template-knative.yaml            |   0
 e2e/{local => knative}/files/yaml.yaml             |   0
 e2e/{global => }/knative/kamelet_test.go           |   0
 e2e/{global => }/knative/knative_platform_test.go  |   0
 e2e/{global => }/knative/knative_test.go           |   0
 e2e/{global => }/knative/openapi_test.go           |   0
 e2e/{global => }/knative/pod_test.go               |   0
 e2e/local/files/dependency.groovy                  |  25 --
 e2e/local/files/trait.groovy                       |  25 --
 e2e/local/local_build_test.go                      | 252 --------------
 e2e/local/local_inspect_test.go                    |  98 ------
 e2e/local/local_run_test.go                        | 221 ------------
 e2e/local/util.go                                  |  66 ----
 e2e/namespace/install/cli/bind_test.go             |  71 ----
 e2e/namespace/install/cli/config_test.go           |  71 ----
 e2e/namespace/install/cli/debug_test.go            | 117 -------
 e2e/namespace/install/cli/delete_test.go           |  88 -----
 e2e/namespace/install/cli/describe_test.go         |  84 -----
 e2e/namespace/install/cli/dev_mode_test.go         | 223 ------------
 e2e/namespace/install/cli/dump_test.go             |  61 ----
 e2e/namespace/install/cli/get_test.go              |  73 ----
 e2e/namespace/install/cli/help_test.go             |  57 ----
 e2e/namespace/install/cli/run_test.go              | 183 ----------
 e2e/namespace/install/files/Java.java              |  28 --
 e2e/namespace/upgrade/files/yaml.yaml              |  28 --
 e2e/{namespace => }/native/files/Groovy.groovy     |   0
 e2e/{namespace => }/native/files/Java.java         |   0
 e2e/{namespace => }/native/files/JavaScript.js     |   0
 e2e/{namespace => }/native/files/Kotlin.kts        |   0
 e2e/{namespace => }/native/files/Xml.xml           |   0
 .../install/cli => native}/files/yaml.yaml         |   0
 e2e/{namespace => }/native/native_binding_test.go  |   0
 e2e/{namespace => }/native/native_test.go          |   0
 e2e/{namespace => }/native/native_test_support.go  |   0
 .../native/native_with_sources_test.go             |   0
 e2e/support/test_support.go                        |  16 +-
 .../telemetry/files/rest-consumer.yaml             |   0
 .../telemetry/files/rest-producer.yaml             |   0
 e2e/{global => }/telemetry/telemetry_test.go       |   0
 e2e/{namespace => }/upgrade/cli_upgrade_test.go    |   2 +-
 e2e/{namespace/install => upgrade}/files/yaml.yaml |   0
 e2e/{namespace => }/upgrade/olm_install_test.go    |   2 +-
 e2e/{namespace => }/upgrade/olm_upgrade_test.go    |   2 +-
 e2e/{namespace => }/upgrade/util.go                |   2 +-
 .../install/cli}/files/Java.java                   |   0
 .../install/cli/files/timer-kamelet-usage.groovy   |   0
 .../install/cli/global_kamelet_test.go             |   2 +-
 .../install/cli/global_test.go                     |   2 +-
 .../install/cli/install_test.go                    |   2 +-
 .../install/cli}/maven_ca_secret_test.go           |   2 +-
 .../install/cli/uninstall_test.go                  |   2 +-
 .../install/kustomize/common.go                    |   0
 .../install/kustomize/operator_test.go             |   0
 .../install/kustomize/setup_test.go                |   0
 .../install/kustomize/uninstall_test.go            |   0
 .../misc}/environment_test.go                      |   2 +-
 .../cli => withnewnamespace/misc}/files/Java.java  |   0
 .../misc}/files/yaml.yaml                          |   0
 .../misc}/incremental_build_test.go                |   2 +-
 .../misc}/maven_http_proxy_test.go                 |   2 +-
 .../misc}/operator_id_filtering_test.go            |   2 +-
 .../misc}/operator_metrics_test.go                 |   2 +-
 .../cli => withnewnamespace/misc}/promote_test.go  |   2 +-
 .../common => withnewnamespace/misc}/reset_test.go |   2 +-
 .../misc}/secondary_platform_test.go               |   2 +-
 script/Makefile                                    |  86 ++---
 262 files changed, 4527 insertions(+), 6008 deletions(-)

diff --git a/.github/actions/e2e-common/exec-tests.sh b/.github/actions/e2e-common/exec-tests.sh
index 0373a9971..0d2d75c6a 100755
--- a/.github/actions/e2e-common/exec-tests.sh
+++ b/.github/actions/e2e-common/exec-tests.sh
@@ -134,9 +134,7 @@ fi
 # Then run all integration tests rather than ending on first failure
 set -e
 exit_code=0
-DO_TEST_PREBUILD=false make test-integration || exit_code=1
-DO_TEST_PREBUILD=false make test-registry-maven-wagon || exit_code=1
-DO_TEST_PREBUILD=false make test-service-binding || exit_code=1
+DO_TEST_PREBUILD=false GOTESTFMT="-json 2>&1 | gotestfmt" make test-common || exit_code=1
 set +e
 
 echo "Tests completed with exit code: ${exit_code}"
diff --git a/e2e/global/builder/build_test.go b/e2e/builder/build_test.go
similarity index 100%
rename from e2e/global/builder/build_test.go
rename to e2e/builder/build_test.go
diff --git a/e2e/global/builder/files/groovy.groovy b/e2e/builder/files/groovy.groovy
similarity index 100%
rename from e2e/global/builder/files/groovy.groovy
rename to e2e/builder/files/groovy.groovy
diff --git a/e2e/global/builder/registry_test.go b/e2e/builder/registry_test.go
similarity index 100%
rename from e2e/global/builder/registry_test.go
rename to e2e/builder/registry_test.go
diff --git a/e2e/common/cli/bind_test.go b/e2e/common/cli/bind_test.go
new file mode 100644
index 000000000..cc2341c15
--- /dev/null
+++ b/e2e/common/cli/bind_test.go
@@ -0,0 +1,64 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package cli
+
+import (
+	"testing"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/onsi/gomega"
+
+	. "github.com/apache/camel-k/e2e/support"
+)
+
+func TestKamelCLIBind(t *testing.T) {
+	RegisterTestingT(t)
+
+	Expect(CreateTimerKamelet(ns, "test-timer-source")()).To(Succeed())
+
+	t.Run("bind timer to log", func(t *testing.T) {
+		Expect(KamelBindWithID(operatorID, ns, "test-timer-source", "log:info", "-p", "source.message=helloTest").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "test-timer-source-to-log"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationLogs(ns, "test-timer-source-to-log")).Should(ContainSubstring("Body: helloTest"))
+		Expect(KamelBindWithID(operatorID, ns, "test-timer-source", "log:info", "-p", "source.message=newText").Execute()).To(Succeed())
+		Eventually(IntegrationLogs(ns, "test-timer-source-to-log")).Should(ContainSubstring("Body: newText"))
+	})
+
+	t.Run("unsuccessful binding, no property", func(t *testing.T) {
+		Expect(KamelBindWithID(operatorID, ns, "timer-source", "log:info").Execute()).NotTo(Succeed())
+	})
+
+	t.Run("bind uris", func(t *testing.T) {
+		Expect(KamelBindWithID(operatorID, ns, "timer:foo", "log:bar").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "timer-to-log"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationLogs(ns, "timer-to-log")).Should(ContainSubstring("Body is null"))
+	})
+
+	t.Run("bind with custom SA", func(t *testing.T) {
+		Expect(KamelBindWithID(operatorID, ns, "timer:foo", "log:bar", "--service-account", "my-service-account").Execute()).To(Succeed())
+		Eventually(IntegrationSpecSA(ns, "timer-to-log")).Should(Equal("my-service-account"))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/global/common/platformless_run_test.go b/e2e/common/cli/config_test.go
similarity index 53%
copy from e2e/global/common/platformless_run_test.go
copy to e2e/common/cli/config_test.go
index cd9694c44..046acf759 100644
--- a/e2e/global/common/platformless_run_test.go
+++ b/e2e/common/cli/config_test.go
@@ -20,45 +20,48 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package cli
 
 import (
 	"os"
+	"strings"
 	"testing"
 
+	corev1 "k8s.io/api/core/v1"
+
 	. "github.com/onsi/gomega"
 	"github.com/stretchr/testify/assert"
 
-	corev1 "k8s.io/api/core/v1"
-
 	. "github.com/apache/camel-k/e2e/support"
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/util/openshift"
+	"github.com/apache/camel-k/pkg/cmd"
 )
 
-func TestPlatformlessRun(t *testing.T) {
-	needsExternalRepo := os.Getenv("STAGING_RUNTIME_REPO") != "" || os.Getenv("KAMEL_INSTALL_MAVEN_REPOSITORIES") != ""
-	ocp, err := openshift.IsOpenShift(TestClient())
-	assert.Nil(t, err)
-	if needsExternalRepo || !ocp {
-		t.Skip("This test is for OpenShift only and cannot work when a custom platform configuration is needed")
-		return
-	}
+func TestKamelCLIConfig(t *testing.T) {
+	RegisterTestingT(t)
 
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-platform-missing"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
+	t.Run("check default namespace", func(t *testing.T) {
+		_, err := os.Stat(cmd.DefaultConfigLocation)
+		assert.True(t, os.IsNotExist(err), "No file at "+cmd.DefaultConfigLocation+" was expected")
+		t.Cleanup(func() { os.Remove(cmd.DefaultConfigLocation) })
+		Expect(Kamel("config", "--default-namespace", ns).Execute()).To(Succeed())
+		_, err = os.Stat(cmd.DefaultConfigLocation)
+		assert.Nil(t, err, "A file at "+cmd.DefaultConfigLocation+" was expected")
+		Expect(Kamel("run", "--operator-id", operatorID, "files/yaml.yaml").Execute()).To(Succeed())
 
-		// Delete the platform from the namespace before running the integration
-		Eventually(DeletePlatform(ns)).Should(BeTrue())
-
-		Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed())
 		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "yaml", v1.IntegrationConditionReady), TestTimeoutShort).
+			Should(Equal(corev1.ConditionTrue))
 		Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
 
-		// Platform should be recreated
-		Eventually(Platform(ns)).ShouldNot(BeNil())
-		Eventually(PlatformProfile(ns)).Should(Equal(v1.TraitProfile("")))
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		// first line of the integration logs
+		logs := strings.Split(IntegrationLogs(ns, "yaml")(), "\n")[0]
+		podName := IntegrationPod(ns, "yaml")().Name
+
+		logsCLI := GetOutputStringAsync(Kamel("log", "yaml"))
+		Eventually(logsCLI).Should(ContainSubstring("Monitoring pod " + podName))
+		Eventually(logsCLI).Should(ContainSubstring(logs))
 	})
+
+	Expect(Kamel("delete", "--all").Execute()).To(Succeed())
 }
diff --git a/e2e/common/cli/debug_test.go b/e2e/common/cli/debug_test.go
new file mode 100644
index 000000000..2b3d75b2e
--- /dev/null
+++ b/e2e/common/cli/debug_test.go
@@ -0,0 +1,110 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package cli
+
+import (
+	"context"
+	. "github.com/apache/camel-k/e2e/support"
+	. "github.com/onsi/gomega"
+	v1 "k8s.io/api/core/v1"
+	"net"
+	"testing"
+	"time"
+)
+
+func TestKamelCLIDebug(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("debug local default port check", func(t *testing.T) {
+		Expect(Kamel("run", "-n", ns, "files/yaml.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutMedium).Should(Equal(v1.PodRunning))
+		Expect(portIsInUse("127.0.0.1", "5005")()).To(BeFalse())
+
+		debugTestContext, cancel := context.WithCancel(TestContext)
+		defer cancelAndWait(cancel)
+		go KamelWithContext(debugTestContext, "debug", "yaml", "-n", ns).ExecuteContext(debugTestContext)
+
+		Eventually(portIsInUse("127.0.0.1", "5005"), TestTimeoutMedium, 5*time.Second).Should(BeTrue())
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("debug local port check", func(t *testing.T) {
+		Expect(Kamel("run", "-n", ns, "files/yaml.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutMedium).Should(Equal(v1.PodRunning))
+		Expect(portIsInUse("127.0.0.1", "5006")()).To(BeFalse())
+
+		debugTestContext, cancel := context.WithCancel(TestContext)
+		defer cancelAndWait(cancel)
+		go KamelWithContext(debugTestContext, "debug", "yaml", "--port", "5006", "-n", ns).ExecuteContext(debugTestContext)
+
+		Eventually(portIsInUse("127.0.0.1", "5006"), TestTimeoutMedium, 5*time.Second).Should(BeTrue())
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("debug logs check", func(t *testing.T) {
+		Expect(Kamel("run", "-n", ns, "files/yaml.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutMedium).Should(Equal(v1.PodRunning))
+
+		debugTestContext, cancel := context.WithCancel(TestContext)
+		defer cancelAndWait(cancel)
+		go KamelWithContext(debugTestContext, "debug", "yaml", "-n", ns).ExecuteContext(debugTestContext)
+
+		Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutMedium).Should(ContainSubstring("Listening for transport dt_socket at address: 5005"))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("Pod config test", func(t *testing.T) {
+		Expect(Kamel("run", "-n", ns, "files/yaml.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutMedium).Should(Equal(v1.PodRunning))
+
+		debugTestContext, cancel := context.WithCancel(TestContext)
+		defer cancelAndWait(cancel)
+		go KamelWithContext(debugTestContext, "debug", "yaml", "-n", ns).ExecuteContext(debugTestContext)
+
+		Eventually(func() string {
+			return IntegrationPod(ns, "yaml")().Spec.Containers[0].Args[0]
+		}).Should(ContainSubstring("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005"))
+		Expect(IntegrationPod(ns, "yaml")().GetLabels()["camel.apache.org/debug"]).To(Not(BeNil()))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
+
+func portIsInUse(host string, port string) func() bool {
+	return func() bool {
+
+		conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), time.Second*5)
+
+		if conn != nil {
+			defer conn.Close()
+		}
+
+		return conn != nil && err == nil
+	}
+}
+
+func cancelAndWait(cancel context.CancelFunc) {
+	cancel()
+	time.Sleep(TestTimeoutShort)
+}
diff --git a/e2e/global/knative/doc.go b/e2e/common/cli/default.go
similarity index 79%
copy from e2e/global/knative/doc.go
copy to e2e/common/cli/default.go
index 6fe4069e4..1f7169227 100644
--- a/e2e/global/knative/doc.go
+++ b/e2e/common/cli/default.go
@@ -1,8 +1,6 @@
 //go:build integration
 // +build integration
 
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
 /*
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
@@ -20,5 +18,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-// Package knative contains Knative related e2e tests
-package knative
+package cli
+
+const ns = "camel-k-test-integration"
+const operatorID = "camel-k-test-integration"
diff --git a/e2e/common/cli/delete_test.go b/e2e/common/cli/delete_test.go
new file mode 100644
index 000000000..3b25ba949
--- /dev/null
+++ b/e2e/common/cli/delete_test.go
@@ -0,0 +1,87 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package cli
+
+import (
+	"testing"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/onsi/gomega"
+
+	. "github.com/apache/camel-k/e2e/support"
+)
+
+func TestKamelCLIDelete(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("delete running integration", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "../files/yaml.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Expect(Kamel("delete", "yaml", "-n", ns).Execute()).To(Succeed())
+		Eventually(Integration(ns, "yaml")).Should(BeNil())
+		Eventually(IntegrationPod(ns, "yaml"), TestTimeoutLong).Should(BeNil())
+	})
+
+	t.Run("delete building integration", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "../files/yaml.yaml").Execute()).To(Succeed())
+		Expect(Kamel("delete", "yaml", "-n", ns).Execute()).To(Succeed())
+		Eventually(Integration(ns, "yaml")).Should(BeNil())
+		Eventually(IntegrationPod(ns, "yaml"), TestTimeoutLong).Should(BeNil())
+	})
+
+	t.Run("delete integration from csv", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "github:apache/camel-k/e2e/namespace/install/cli/files/yaml.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Expect(Kamel("delete", "yaml", "-n", ns).Execute()).To(Succeed())
+		Eventually(Integration(ns, "yaml")).Should(BeNil())
+		Eventually(IntegrationPod(ns, "yaml"), TestTimeoutLong).Should(BeNil())
+	})
+
+	t.Run("delete several integrations", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "../files/yaml.yaml").Execute()).To(Succeed())
+		Expect(KamelRunWithID(operatorID, ns, "../files/Java.java").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Expect(Kamel("delete", "yaml", "-n", ns).Execute()).To(Succeed())
+		Eventually(Integration(ns, "yaml")).Should(BeNil())
+		Eventually(IntegrationPod(ns, "yaml"), TestTimeoutLong).Should(BeNil())
+		Expect(Kamel("delete", "java", "-n", ns).Execute()).To(Succeed())
+		Eventually(Integration(ns, "java")).Should(BeNil())
+		Eventually(IntegrationPod(ns, "java"), TestTimeoutLong).Should(BeNil())
+	})
+
+	t.Run("delete all integrations", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "../files/yaml.yaml").Execute()).To(Succeed())
+		Expect(KamelRunWithID(operatorID, ns, "../files/Java.java").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		Eventually(Integration(ns, "yaml")).Should(BeNil())
+		Eventually(IntegrationPod(ns, "yaml"), TestTimeoutLong).Should(BeNil())
+		Eventually(Integration(ns, "java")).Should(BeNil())
+		Eventually(IntegrationPod(ns, "java"), TestTimeoutLong).Should(BeNil())
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/common/cli/describe_test.go b/e2e/common/cli/describe_test.go
new file mode 100644
index 000000000..7fd3eb417
--- /dev/null
+++ b/e2e/common/cli/describe_test.go
@@ -0,0 +1,84 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package cli
+
+import (
+	"regexp"
+	"testing"
+
+	. "github.com/onsi/gomega"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	"github.com/apache/camel-k/pkg/util/defaults"
+)
+
+func TestKamelCliDescribe(t *testing.T) {
+	RegisterTestingT(t)
+
+	Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed())
+	Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+
+	t.Run("Test kamel describe integration", func(t *testing.T) {
+		integration := GetOutputString(Kamel("describe", "integration", "yaml", "-n", ns))
+		r, _ := regexp.Compile("(?sm).*Name:\\s+yaml.*")
+		Expect(integration).To(MatchRegexp(r.String()))
+
+		r, _ = regexp.Compile("(?sm).*Phase:\\s+Running.*")
+		Expect(integration).To(MatchRegexp(r.String()))
+
+		Expect(integration).To(ContainSubstring("Dependencies:"))
+		Expect(integration).To(ContainSubstring("Conditions:"))
+	})
+
+	t.Run("Test kamel describe integration kit", func(t *testing.T) {
+		kitName := Integration(ns, "yaml")().Status.IntegrationKit.Name
+		kit := GetOutputString(Kamel("describe", "kit", kitName, "-n", ns))
+
+		r, _ := regexp.Compile("(?sm).*Namespace:\\s+" + ns + ".*")
+		Expect(kit).To(MatchRegexp(r.String()))
+
+		r, _ = regexp.Compile("(?sm).*Runtime Version:\\s+" + defaults.DefaultRuntimeVersion + ".*")
+		Expect(kit).To(MatchRegexp(r.String()))
+
+		Expect(kit).To(ContainSubstring("camel-quarkus-core"))
+
+		Expect(kit).To(ContainSubstring("Artifacts:"))
+		Expect(kit).To(ContainSubstring("Dependencies:"))
+	})
+
+	t.Run("Test kamel describe integration platform", func(t *testing.T) {
+		platform := GetOutputString(Kamel("describe", "platform", operatorID, "-n", ns))
+		r, _ := regexp.Compile("(?sm).*Name:\\s+camel-k.*")
+		Expect(platform).To(MatchRegexp(r.String()))
+
+		r, _ = regexp.Compile("(?sm).*Namespace:\\s+" + ns + ".*")
+		Expect(platform).To(MatchRegexp(r.String()))
+
+		r, _ = regexp.Compile("(?sm).*Runtime Version:\\s+" + defaults.DefaultRuntimeVersion + ".*")
+		Expect(platform).To(MatchRegexp(r.String()))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/common/cli/dev_mode_test.go b/e2e/common/cli/dev_mode_test.go
new file mode 100644
index 000000000..8967185e5
--- /dev/null
+++ b/e2e/common/cli/dev_mode_test.go
@@ -0,0 +1,221 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package cli
+
+import (
+	"context"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"testing"
+	"time"
+
+	. "github.com/onsi/gomega"
+	"github.com/stretchr/testify/assert"
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	"github.com/apache/camel-k/e2e/support/util"
+)
+
+func TestRunDevMode(t *testing.T) {
+	RegisterTestingT(t)
+
+	/*
+	 * TODO
+	 * The changing of the yaml file constant from "string" to "magic" is not being
+	 * picked up when deploying on OCP4 and so the test is failing.
+	 *
+	 * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment.
+	 */
+	if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" {
+		t.Skip("WARNING: Test marked as problematic ... skipping")
+	}
+
+	t.Run("run yaml dev mode", func(t *testing.T) {
+		RegisterTestingT(t)
+		ctx, cancel := context.WithCancel(TestContext)
+		defer cancel()
+		piper, pipew := io.Pipe()
+		defer pipew.Close()
+		defer piper.Close()
+
+		file := util.MakeTempCopy(t, "files/yaml.yaml")
+
+		kamelRun := KamelRunWithContext(ctx, operatorID, ns, file, "--dev")
+		kamelRun.SetOut(pipew)
+
+		logScanner := util.NewLogScanner(ctx, piper, `integration "yaml" in phase Running`, "Magicstring!", "Magicjordan!")
+
+		args := os.Args
+		defer func() { os.Args = args }()
+
+		globalTest := os.Getenv("CAMEL_K_FORCE_GLOBAL_TEST") == "true"
+		if globalTest {
+			os.Args = []string{"kamel", "run", "-n", ns, file, "--dev"}
+		} else {
+			os.Args = []string{"kamel", "run", "-n", ns, "--operator-id", operatorID, file, "--dev"}
+		}
+		go kamelRun.Execute()
+
+		Eventually(logScanner.IsFound(`integration "yaml" in phase Running`), TestTimeoutMedium).Should(BeTrue())
+		Eventually(logScanner.IsFound("Magicstring!"), TestTimeoutMedium).Should(BeTrue())
+		Expect(logScanner.IsFound("Magicjordan!")()).To(BeFalse())
+
+		util.ReplaceInFile(t, file, "string!", "jordan!")
+		Eventually(logScanner.IsFound("Magicjordan!"), TestTimeoutMedium).Should(BeTrue())
+	})
+
+	t.Run("run yaml remote dev mode", func(t *testing.T) {
+		RegisterTestingT(t)
+		ctx, cancel := context.WithCancel(TestContext)
+		defer cancel()
+		piper, pipew := io.Pipe()
+		defer pipew.Close()
+		defer piper.Close()
+
+		remoteFile := "https://raw.githubusercontent.com/apache/camel-k/b29333f0a878d5d09fb3965be8fe586d77dd95d0/e2e/common/files/yaml.yaml"
+		kamelRun := KamelRunWithContext(ctx, operatorID, ns, remoteFile, "--dev")
+		kamelRun.SetOut(pipew)
+
+		logScanner := util.NewLogScanner(ctx, piper, "Magicstring!")
+
+		args := os.Args
+		defer func() { os.Args = args }()
+
+		globalTest := os.Getenv("CAMEL_K_FORCE_GLOBAL_TEST") == "true"
+		if globalTest {
+			os.Args = []string{"kamel", "run", "-n", ns, remoteFile, "--dev"}
+		} else {
+			os.Args = []string{"kamel", "run", "-n", ns, "--operator-id", operatorID, remoteFile, "--dev"}
+		}
+
+		go kamelRun.Execute()
+
+		Eventually(logScanner.IsFound("Magicstring!"), TestTimeoutMedium).Should(BeTrue())
+	})
+
+	t.Run("Dev mode resource file generated configmap", func(t *testing.T) {
+		var tmpFile *os.File
+		var err error
+		if tmpFile, err = ioutil.TempFile("", "camel-k-"); err != nil {
+			t.Error(err)
+		}
+		assert.Nil(t, tmpFile.Close())
+		assert.Nil(t, ioutil.WriteFile(tmpFile.Name(), []byte("Hello from test!"), 0o644))
+
+		RegisterTestingT(t)
+		ctx, cancel := context.WithCancel(TestContext)
+		defer cancel()
+		piper, pipew := io.Pipe()
+		defer pipew.Close()
+		defer piper.Close()
+
+		file := util.MakeTempCopy(t, "files/resource-file-location-route.groovy")
+
+		kamelRun := KamelRunWithContext(ctx, operatorID, ns, file, "--dev", "--resource", fmt.Sprintf("file:%s@/tmp/file.txt", filepath.ToSlash(tmpFile.Name())))
+		kamelRun.SetOut(pipew)
+
+		logScanner := util.NewLogScanner(ctx, piper, `integration "resource-file-location-route" in phase Running`,
+			"Hello from test!", "Goodbye from test!")
+
+		args := os.Args
+		defer func() { os.Args = args }()
+
+		globalTest := os.Getenv("CAMEL_K_FORCE_GLOBAL_TEST") == "true"
+		if globalTest {
+			os.Args = []string{"kamel", "run", "-n", ns, file, "--dev", "--resource", fmt.Sprintf("file:%s@/tmp/file.txt", tmpFile.Name())}
+		} else {
+			os.Args = []string{"kamel", "run", "-n", ns, "--operator-id", operatorID, file, "--dev", "--resource", fmt.Sprintf("file:%s@/tmp/file.txt", filepath.ToSlash(tmpFile.Name()))}
+		}
+
+		go kamelRun.Execute()
+
+		Eventually(logScanner.IsFound(`integration "resource-file-location-route" in phase Running`), TestTimeoutMedium).Should(BeTrue())
+		Eventually(logScanner.IsFound("Hello from test!"), TestTimeoutMedium).Should(BeTrue())
+		Expect(logScanner.IsFound("Goodbye from test!")()).To(BeFalse())
+
+		// cool, now let's change the file to confirm the sync take place
+		assert.Nil(t, ioutil.WriteFile(tmpFile.Name(), []byte("Goodbye from test!"), 0o644))
+		Eventually(logScanner.IsFound("Goodbye from test!"), TestTimeoutMedium).Should(BeTrue())
+
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		// When the integration is deleted, then, also the autogenerated configmaps must be cleaned
+		Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
+	})
+
+	// This test makes sure that `kamel run --dev` runs in seconds after initial build is
+	// already done for the same integration.
+	t.Run("dev mode rebuild in seconds", func(t *testing.T) {
+		/*
+		 * !!! NOTE !!!
+		 * If you find this test flaky, instead of thinking it as simply unstable, investigate
+		 * why it does not finish in a few seconds and remove the bottlenecks which are lagging
+		 * the integration startup.
+		 */
+		RegisterTestingT(t)
+
+		// First run (warm up)
+		Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Expect(Kamel("delete", "yaml", "-n", ns).Execute()).To(Succeed())
+		Eventually(Integration(ns, "yaml")).Should(BeNil())
+		Eventually(IntegrationPod(ns, "yaml"), TestTimeoutMedium).Should(BeNil())
+
+		// Second run (rebuild)
+		ctx, cancel := context.WithCancel(TestContext)
+		defer cancel()
+		piper, pipew := io.Pipe()
+		defer pipew.Close()
+		defer piper.Close()
+
+		file := util.MakeTempCopy(t, "files/yaml.yaml")
+
+		kamelRun := KamelRunWithContext(ctx, operatorID, ns, file, "--dev")
+		kamelRun.SetOut(pipew)
+
+		logScanner := util.NewLogScanner(ctx, piper, `integration "yaml" in phase Running`, "Magicstring!")
+
+		args := os.Args
+		defer func() { os.Args = args }()
+
+		globalTest := os.Getenv("CAMEL_K_FORCE_GLOBAL_TEST") == "true"
+		if globalTest {
+			os.Args = []string{"kamel", "run", "-n", ns, file, "--dev"}
+		} else {
+			os.Args = []string{"kamel", "run", "-n", ns, "--operator-id", operatorID, file, "--dev"}
+		}
+
+		go kamelRun.Execute()
+
+		// Second run should start up within a few seconds
+		timeout := 10 * time.Second
+		Eventually(logScanner.IsFound(`integration "yaml" in phase Running`), timeout).Should(BeTrue())
+		Eventually(logScanner.IsFound("Magicstring!"), timeout).Should(BeTrue())
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/global/common/platformless_run_test.go b/e2e/common/cli/dump_test.go
similarity index 55%
copy from e2e/global/common/platformless_run_test.go
copy to e2e/common/cli/dump_test.go
index cd9694c44..9c0cec270 100644
--- a/e2e/global/common/platformless_run_test.go
+++ b/e2e/common/cli/dump_test.go
@@ -20,45 +20,42 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package cli
 
 import (
-	"os"
 	"testing"
 
 	. "github.com/onsi/gomega"
-	"github.com/stretchr/testify/assert"
 
 	corev1 "k8s.io/api/core/v1"
 
 	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/util/openshift"
 )
 
-func TestPlatformlessRun(t *testing.T) {
-	needsExternalRepo := os.Getenv("STAGING_RUNTIME_REPO") != "" || os.Getenv("KAMEL_INSTALL_MAVEN_REPOSITORIES") != ""
-	ocp, err := openshift.IsOpenShift(TestClient())
-	assert.Nil(t, err)
-	if needsExternalRepo || !ocp {
-		t.Skip("This test is for OpenShift only and cannot work when a custom platform configuration is needed")
-		return
-	}
-
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-platform-missing"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
+func TestKamelCLIDump(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("dump empty namespace", func(t *testing.T) {
+		dump := GetOutputString(Kamel("dump", "-n", ns))
 
-		// Delete the platform from the namespace before running the integration
-		Eventually(DeletePlatform(ns)).Should(BeTrue())
+		Expect(dump).To(ContainSubstring("Found 0 integrations:"))
+		Expect(dump).To(ContainSubstring("Found 0 deployments:"))
+	})
 
+	t.Run("dump non-empty namespace", func(t *testing.T) {
+		operatorID := "camel-k-cli-dump"
+		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
 		Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed())
 		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-		Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Eventually(IntegrationLogs(ns, "yaml")).Should(ContainSubstring("Magicstring!"))
+
+		dump := GetOutputString(Kamel("dump", "-n", ns))
 
-		// Platform should be recreated
-		Eventually(Platform(ns)).ShouldNot(BeNil())
-		Eventually(PlatformProfile(ns)).Should(Equal(v1.TraitProfile("")))
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		Expect(dump).To(ContainSubstring("Found 1 platforms"))
+		Expect(dump).To(ContainSubstring("Found 1 integrations"))
+		Expect(dump).To(ContainSubstring("name: yaml"))
+		Expect(dump).To(ContainSubstring("Magicstring!"))
 	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/namespace/install/cli/duplicate_parameters_test.go b/e2e/common/cli/duplicate_parameters_test.go
similarity index 99%
rename from e2e/namespace/install/cli/duplicate_parameters_test.go
rename to e2e/common/cli/duplicate_parameters_test.go
index 7e03e1d48..cb5cdd1a1 100644
--- a/e2e/namespace/install/cli/duplicate_parameters_test.go
+++ b/e2e/common/cli/duplicate_parameters_test.go
@@ -20,7 +20,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package cli
 
 import (
 	"context"
diff --git a/e2e/global/common/build/files/Java.java b/e2e/common/cli/files/Java.java
similarity index 100%
rename from e2e/global/common/build/files/Java.java
rename to e2e/common/cli/files/Java.java
diff --git a/e2e/namespace/install/cli/files/JavaDuplicateParams.java b/e2e/common/cli/files/JavaDuplicateParams.java
similarity index 100%
rename from e2e/namespace/install/cli/files/JavaDuplicateParams.java
rename to e2e/common/cli/files/JavaDuplicateParams.java
diff --git a/e2e/namespace/install/cli/files/TimerCustomKameletIntegration.java b/e2e/common/cli/files/TimerCustomKameletIntegration.java
similarity index 100%
rename from e2e/namespace/install/cli/files/TimerCustomKameletIntegration.java
rename to e2e/common/cli/files/TimerCustomKameletIntegration.java
diff --git a/e2e/namespace/install/cli/files/promote-route-edited.groovy b/e2e/common/cli/files/promote-route-edited.groovy
similarity index 100%
rename from e2e/namespace/install/cli/files/promote-route-edited.groovy
rename to e2e/common/cli/files/promote-route-edited.groovy
diff --git a/e2e/namespace/install/cli/files/promote-route.groovy b/e2e/common/cli/files/promote-route.groovy
similarity index 100%
rename from e2e/namespace/install/cli/files/promote-route.groovy
rename to e2e/common/cli/files/promote-route.groovy
diff --git a/e2e/global/common/config/files/resource-file-location-route.groovy b/e2e/common/cli/files/resource-file-location-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/resource-file-location-route.groovy
rename to e2e/common/cli/files/resource-file-location-route.groovy
diff --git a/e2e/namespace/install/cli/files/run.yaml b/e2e/common/cli/files/run.yaml
similarity index 100%
rename from e2e/namespace/install/cli/files/run.yaml
rename to e2e/common/cli/files/run.yaml
diff --git a/e2e/namespace/install/cli/files/timer-kamelet-usage.groovy b/e2e/common/cli/files/timer-kamelet-usage.groovy
similarity index 100%
copy from e2e/namespace/install/cli/files/timer-kamelet-usage.groovy
copy to e2e/common/cli/files/timer-kamelet-usage.groovy
diff --git a/e2e/global/common/files/yaml.yaml b/e2e/common/cli/files/yaml.yaml
similarity index 100%
rename from e2e/global/common/files/yaml.yaml
rename to e2e/common/cli/files/yaml.yaml
diff --git a/e2e/common/cli/get_test.go b/e2e/common/cli/get_test.go
new file mode 100644
index 000000000..1ea9716c1
--- /dev/null
+++ b/e2e/common/cli/get_test.go
@@ -0,0 +1,72 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package cli
+
+import (
+	"fmt"
+	"testing"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/onsi/gomega"
+
+	. "github.com/apache/camel-k/e2e/support"
+)
+
+func TestKamelCLIGet(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("get integration", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "../files/yaml.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		// regex is used for the compatibility of tests between OC and vanilla K8
+		// kamel get may have different output depending og the platform
+		kitName := Integration(ns, "yaml")().Status.IntegrationKit.Name
+		regex := fmt.Sprintf("^NAME\tPHASE\tKIT\n\\s*yaml\tRunning\t(%s/%s|%s)", ns, kitName, kitName)
+		Expect(GetOutputString(Kamel("get", "-n", ns))).To(MatchRegexp(regex))
+
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("get several integrations", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "../files/yaml.yaml").Execute()).To(Succeed())
+		Expect(KamelRunWithID(operatorID, ns, "../files/Java.java").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+
+		kitName1 := Integration(ns, "java")().Status.IntegrationKit.Name
+		kitName2 := Integration(ns, "yaml")().Status.IntegrationKit.Name
+		regex := fmt.Sprintf("^NAME\tPHASE\tKIT\n\\s*java\tRunning\t"+
+			"(%s/%s|%s)\n\\s*yaml\tRunning\t(%s/%s|%s)\n", ns, kitName1, kitName1, ns, kitName2, kitName2)
+		Expect(GetOutputString(Kamel("get", "-n", ns))).To(MatchRegexp(regex))
+
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("get no integrations", func(t *testing.T) {
+		Expect(GetOutputString(Kamel("get", "-n", ns))).NotTo(ContainSubstring("Running"))
+		Expect(GetOutputString(Kamel("get", "-n", ns))).NotTo(ContainSubstring("Building Kit"))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/common/cli/help_test.go b/e2e/common/cli/help_test.go
new file mode 100644
index 000000000..a66894652
--- /dev/null
+++ b/e2e/common/cli/help_test.go
@@ -0,0 +1,57 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package cli
+
+import (
+	"testing"
+
+	. "github.com/onsi/gomega"
+
+	. "github.com/apache/camel-k/e2e/support"
+)
+
+func TestKamelCLIHelp(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("default help message", func(t *testing.T) {
+		helpMsg := GetOutputString(Kamel("help"))
+		Expect(helpMsg).To(ContainSubstring("Apache Camel K is a lightweight integration platform, born on Kubernetes"))
+		Expect(helpMsg).To(ContainSubstring("Usage:"))
+		Expect(helpMsg).To(ContainSubstring("Available Commands:"))
+		Expect(helpMsg).To(ContainSubstring("Flags:"))
+	})
+
+	t.Run("'get' command help (short flag)", func(t *testing.T) {
+		helpMsg := GetOutputString(Kamel("get", "-h"))
+		Expect(helpMsg).To(ContainSubstring("Get the status of integrations deployed on Kubernetes"))
+		Expect(helpMsg).To(ContainSubstring("Usage:"))
+		Expect(helpMsg).To(ContainSubstring("Flags:"))
+	})
+
+	t.Run("'bind' command help (long flag)", func(t *testing.T) {
+		helpMsg := GetOutputString(Kamel("bind", "--help"))
+		Expect(helpMsg).To(ContainSubstring("Bind Kubernetes resources, such as Kamelets, in an integration flow."))
+		Expect(helpMsg).To(ContainSubstring("kamel bind [source] [sink] ... [flags]"))
+		Expect(helpMsg).To(ContainSubstring("Global Flags:"))
+	})
+}
diff --git a/e2e/common/cli/kamel-config.yaml b/e2e/common/cli/kamel-config.yaml
new file mode 100644
index 000000000..1be15da78
--- /dev/null
+++ b/e2e/common/cli/kamel-config.yaml
@@ -0,0 +1,3 @@
+kamel:
+  config:
+    default-namespace: camel-k-test-integration
diff --git a/e2e/namespace/install/cli/kamelet_test.go b/e2e/common/cli/kamelet_test.go
similarity index 50%
copy from e2e/namespace/install/cli/kamelet_test.go
copy to e2e/common/cli/kamelet_test.go
index 3a48ea918..aad161b90 100644
--- a/e2e/namespace/install/cli/kamelet_test.go
+++ b/e2e/common/cli/kamelet_test.go
@@ -20,10 +20,9 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package cli
 
 import (
-	"fmt"
 	"testing"
 
 	. "github.com/onsi/gomega"
@@ -33,37 +32,31 @@ import (
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 )
 
-// This test requires operator installation with a custom operator ID, thus needs
-// to be run under e2e/namespace.
 func TestKameletFromCustomRepository(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := fmt.Sprintf("camel-k-%s", ns)
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-		Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady))
-
-		kameletName := "timer-custom-source"
-		removeKamelet(kameletName, ns)
-
-		Eventually(Kamelet(kameletName, ns)).Should(BeNil())
-
-		// Add the custom repository
-		Expect(Kamel("kamelet", "add-repo",
-			"github:apache/camel-k/e2e/global/common/files/kamelets",
-			"-n", ns,
-			"-x", operatorID).Execute()).To(Succeed())
-
-		Expect(KamelRunWithID(operatorID, ns, "files/TimerCustomKameletIntegration.java").Execute()).To(Succeed())
-		Eventually(IntegrationPodPhase(ns, "timer-custom-kamelet-integration"), TestTimeoutLong).
-			Should(Equal(corev1.PodRunning))
-
-		Eventually(IntegrationLogs(ns, "timer-custom-kamelet-integration")).Should(ContainSubstring("hello world"))
-
-		// Remove the custom repository
-		Expect(Kamel("kamelet", "remove-repo",
-			"github:apache/camel-k/e2e/global/common/files/kamelets",
-			"-n", ns,
-			"-x", operatorID).Execute()).To(Succeed())
-	})
+	RegisterTestingT(t)
+
+	Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady))
+
+	kameletName := "timer-custom-source"
+	removeKamelet(kameletName, ns)
+
+	Eventually(Kamelet(kameletName, ns)).Should(BeNil())
+	// Add the custom repository
+	Expect(Kamel("kamelet", "add-repo",
+		"github:apache/camel-k/e2e/global/common/files/kamelets",
+		"-n", ns,
+		"-x", operatorID).Execute()).To(Succeed())
+
+	Expect(KamelRunWithID(operatorID, ns, "files/TimerCustomKameletIntegration.java").Execute()).To(Succeed())
+	Eventually(IntegrationPodPhase(ns, "timer-custom-kamelet-integration"), TestTimeoutLong).
+		Should(Equal(corev1.PodRunning))
+	Eventually(IntegrationLogs(ns, "timer-custom-kamelet-integration")).Should(ContainSubstring("hello world"))
+
+	// Remove the custom repository
+	Expect(Kamel("kamelet", "remove-repo",
+		"github:apache/camel-k/e2e/global/common/files/kamelets",
+		"-n", ns,
+		"-x", operatorID).Execute()).To(Succeed())
 }
 
 func removeKamelet(name string, ns string) {
diff --git a/e2e/namespace/install/cli/log_test.go b/e2e/common/cli/log_test.go
similarity index 51%
rename from e2e/namespace/install/cli/log_test.go
rename to e2e/common/cli/log_test.go
index 967128ca9..dc085c467 100644
--- a/e2e/namespace/install/cli/log_test.go
+++ b/e2e/common/cli/log_test.go
@@ -20,7 +20,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package cli
 
 import (
 	"strings"
@@ -34,27 +34,24 @@ import (
 )
 
 func TestKamelCLILog(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-cli-log"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("check integration log", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "../files/yaml.yaml").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			// first line of the integration logs
-			firstLine := strings.Split(IntegrationLogs(ns, "yaml")(), "\n")[0]
-			podName := IntegrationPod(ns, "yaml")().Name
-
-			logsCLI := GetOutputStringAsync(Kamel("log", "yaml", "-n", ns))
-			Eventually(logsCLI).Should(ContainSubstring("Monitoring pod " + podName))
-			Eventually(logsCLI).Should(ContainSubstring(firstLine))
-
-			logs := strings.Split(IntegrationLogs(ns, "yaml")(), "\n")
-			lastLine := logs[len(logs)-1]
-
-			logsCLI = GetOutputStringAsync(Kamel("log", "yaml", "-n", ns, "--tail", "5"))
-			Eventually(logsCLI).Should(ContainSubstring("Monitoring pod " + podName))
-			Eventually(logsCLI).Should(ContainSubstring(lastLine))
-		})
+	RegisterTestingT(t)
+
+	t.Run("check integration log", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "../files/yaml.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		// first line of the integration logs
+		firstLine := strings.Split(IntegrationLogs(ns, "yaml")(), "\n")[0]
+		podName := IntegrationPod(ns, "yaml")().Name
+
+		logsCLI := GetOutputStringAsync(Kamel("log", "yaml", "-n", ns))
+		Eventually(logsCLI).Should(ContainSubstring("Monitoring pod " + podName))
+		Eventually(logsCLI).Should(ContainSubstring(firstLine))
+
+		logs := strings.Split(IntegrationLogs(ns, "yaml")(), "\n")
+		lastLine := logs[len(logs)-1]
+
+		logsCLI = GetOutputStringAsync(Kamel("log", "yaml", "-n", ns, "--tail", "5"))
+		Eventually(logsCLI).Should(ContainSubstring("Monitoring pod " + podName))
+		Eventually(logsCLI).Should(ContainSubstring(lastLine))
 	})
 }
diff --git a/e2e/namespace/install/cli/offline_commands_test.go b/e2e/common/cli/offline_commands_test.go
similarity index 93%
rename from e2e/namespace/install/cli/offline_commands_test.go
rename to e2e/common/cli/offline_commands_test.go
index c3a1271f0..36a108c5a 100644
--- a/e2e/namespace/install/cli/offline_commands_test.go
+++ b/e2e/common/cli/offline_commands_test.go
@@ -20,7 +20,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package cli
 
 import (
 	"io/ioutil"
@@ -29,25 +29,34 @@ import (
 	"github.com/stretchr/testify/assert"
 
 	. "github.com/apache/camel-k/e2e/support"
+	. "github.com/onsi/gomega"
 )
 
 func TestKamelVersionWorksOffline(t *testing.T) {
+	RegisterTestingT(t)
+
 	assert.Nil(t, Kamel("version", "--kube-config", "non-existent-kubeconfig-file").Execute())
 }
 
 func TestKamelHelpTraitWorksOffline(t *testing.T) {
+	RegisterTestingT(t)
+
 	traitCmd := Kamel("help", "trait", "--all", "--kube-config", "non-existent-kubeconfig-file")
 	traitCmd.SetOut(ioutil.Discard)
 	assert.Nil(t, traitCmd.Execute())
 }
 
 func TestKamelHelpOptionWorksOffline(t *testing.T) {
+	RegisterTestingT(t)
+
 	traitCmd := Kamel("run", "Xxx.java", "--help")
 	traitCmd.SetOut(ioutil.Discard)
 	assert.Nil(t, traitCmd.Execute())
 }
 
 func TestKamelCompletionWorksOffline(t *testing.T) {
+	RegisterTestingT(t)
+
 	bashCmd := Kamel("completion", "bash", "--kube-config", "non-existent-kubeconfig-file")
 	bashCmd.SetOut(ioutil.Discard)
 	zshCmd := Kamel("completion", "zsh", "--kube-config", "non-existent-kubeconfig-file")
diff --git a/e2e/common/cli/run_test.go b/e2e/common/cli/run_test.go
new file mode 100644
index 000000000..f0105b228
--- /dev/null
+++ b/e2e/common/cli/run_test.go
@@ -0,0 +1,181 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package cli
+
+import (
+	"os"
+	"testing"
+
+	. "github.com/onsi/gomega"
+	. "github.com/onsi/gomega/gstruct"
+
+	appsv1 "k8s.io/api/apps/v1"
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+var sampleJar = "https://raw.githubusercontent.com/apache/camel-k/main/e2e/global/common/traits/files/jvm/sample-1.0.jar"
+
+func TestKamelCLIRun(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("Examples from GitHub", func(t *testing.T) {
+		t.Run("Java", func(t *testing.T) {
+			Expect(KamelRunWithID(operatorID, ns,
+				"github:apache/camel-k/e2e/namespace/install/files/Java.java").Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).
+				Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+			Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0))
+		})
+
+		t.Run("Java (RAW)", func(t *testing.T) {
+			Expect(KamelRunWithID(operatorID, ns,
+				"https://raw.githubusercontent.com/apache/camel-k/main/e2e/namespace/install/files/Java.java").Execute()).
+				To(Succeed())
+			Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).
+				Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+			Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0))
+		})
+
+		t.Run("Java (branch)", func(t *testing.T) {
+			Expect(KamelRunWithID(operatorID, ns,
+				"github:apache/camel-k/e2e/namespace/install/files/Java.java?branch=main").Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).
+				Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+			Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0))
+		})
+
+		// GIST does not like GITHUB_TOKEN apparently, we must temporary remove it
+		os.Setenv("GITHUB_TOKEN_TMP", os.Getenv("GITHUB_TOKEN"))
+		os.Unsetenv("GITHUB_TOKEN")
+
+		t.Run("Gist (ID)", func(t *testing.T) {
+			name := "github-gist-id"
+			Expect(KamelRunWithID(operatorID, ns, "--name", name,
+				"gist:e2c3f9a5fd0d9e79b21b04809786f17a").Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+				Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Tick!"))
+			Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0))
+		})
+
+		t.Run("Gist (URL)", func(t *testing.T) {
+			name := "github-gist-url"
+			Expect(KamelRunWithID(operatorID, ns, "--name", name,
+				"https://gist.github.com/lburgazzoli/e2c3f9a5fd0d9e79b21b04809786f17a").Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+				Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Tick!"))
+			Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0))
+		})
+
+		// Revert GITHUB TOKEN
+		os.Setenv("GITHUB_TOKEN", os.Getenv("GITHUB_TOKEN_TMP"))
+		os.Unsetenv("GITHUB_TOKEN_TMP")
+
+		// Clean up
+		Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0))
+	})
+
+	t.Run("Run and update", func(t *testing.T) {
+		name := "run"
+		Expect(KamelRunWithID(operatorID, ns, "files/run.yaml", "--name", name).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+			Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magic default"))
+
+		// Re-run the Integration with an updated configuration
+		Expect(KamelRunWithID(operatorID, ns, "files/run.yaml", "--name", name, "-p", "property=value").Execute()).
+			To(Succeed())
+
+		// Check the Deployment has progressed successfully
+		Eventually(DeploymentCondition(ns, name, appsv1.DeploymentProgressing), TestTimeoutShort).
+			Should(MatchFields(IgnoreExtras, Fields{
+				"Status": Equal(corev1.ConditionTrue),
+				"Reason": Equal("NewReplicaSetAvailable"),
+			}))
+
+		// Check the new configuration is taken into account
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutShort).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+			Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magic value"))
+
+		// Clean up
+		Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0))
+	})
+
+	/*
+	 * TODO
+	 * The dependency cannot be read by maven while building. See #3708
+	 *
+	 * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment.
+	 */
+	t.Run("Run with http dependency", func(t *testing.T) {
+		if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" {
+			t.Skip("WARNING: Test marked as problematic ... skipping")
+		}
+		Expect(KamelRunWithID(operatorID, ns, "../../../global/common/traits/files/jvm/Classpath.java",
+			"-d", sampleJar,
+		).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "classpath"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "classpath", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "classpath"), TestTimeoutShort).Should(ContainSubstring("Hello World!"))
+		Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0))
+	})
+
+	/*
+	 * TODO
+	 * The dependency cannot be read by maven while building. See #3708
+	 *
+	 * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment.
+	 */
+	t.Run("Run with http dependency using options", func(t *testing.T) {
+		if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" {
+			t.Skip("WARNING: Test marked as problematic ... skipping")
+		}
+		Expect(KamelRunWithID(operatorID, ns, "../../../global/common/traits/files/jvm/Classpath.java",
+			"-d", sampleJar,
+			"-d", "https://raw.githubusercontent.com/apache/camel-k/main/e2e/namespace/install/cli/files/Java.java|targetPath=/tmp/foo",
+		).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "classpath"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "classpath", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "classpath"), TestTimeoutShort).Should(ContainSubstring("Hello World!"))
+		Eventually(DeleteIntegrations(ns), TestTimeoutLong).Should(Equal(0))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/namespace/install/cli/version_test.go b/e2e/common/cli/version_test.go
similarity index 83%
rename from e2e/namespace/install/cli/version_test.go
rename to e2e/common/cli/version_test.go
index 1b77b3bf1..2d7adf83d 100644
--- a/e2e/namespace/install/cli/version_test.go
+++ b/e2e/common/cli/version_test.go
@@ -20,7 +20,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package cli
 
 import (
 	"testing"
@@ -32,10 +32,10 @@ import (
 )
 
 func TestKamelCLIVersion(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		t.Run("check version correctness", func(t *testing.T) {
-			version := GetOutputString(Kamel("version"))
-			Expect(version).To(ContainSubstring(defaults.Version))
-		})
+	RegisterTestingT(t)
+
+	t.Run("check version correctness", func(t *testing.T) {
+		version := GetOutputString(Kamel("version"))
+		Expect(version).To(ContainSubstring(defaults.Version))
 	})
 }
diff --git a/e2e/common/config/config_test.go b/e2e/common/config/config_test.go
new file mode 100644
index 000000000..a936c41ef
--- /dev/null
+++ b/e2e/common/config/config_test.go
@@ -0,0 +1,350 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package config
+
+import (
+	"io/ioutil"
+	"testing"
+
+	. "github.com/onsi/gomega"
+	"github.com/stretchr/testify/assert"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	"github.com/apache/camel-k/pkg/util/gzip"
+)
+
+func TestRunConfigExamples(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("Simple property", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "my.message=test-property").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("test-property"))
+	})
+
+	t.Run("Property file", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/property-file-route.groovy", "--property", "file:./files/my.properties").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "property-file-route"), TestTimeoutShort).Should(ContainSubstring("hello world"))
+	})
+
+	t.Run("Property precedence", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/property-file-route.groovy", "-p", "my.key.2=universe", "-p", "file:./files/my.properties").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "property-file-route"), TestTimeoutShort).Should(ContainSubstring("hello universe"))
+	})
+
+	t.Run("Property from ConfigMap", func(t *testing.T) {
+		var cmData = make(map[string]string)
+		cmData["my.message"] = "my-configmap-property-value"
+		CreatePlainTextConfigmap(ns, "my-cm-test-property", cmData)
+
+		Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "configmap:my-cm-test-property").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-configmap-property-value"))
+	})
+
+	t.Run("Property from ConfigMap as property file", func(t *testing.T) {
+		var cmData = make(map[string]string)
+		cmData["my.properties"] = "my.message=my-configmap-property-entry"
+		CreatePlainTextConfigmap(ns, "my-cm-test-properties", cmData)
+
+		Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "configmap:my-cm-test-properties").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-configmap-property-entry"))
+	})
+
+	t.Run("Property from Secret", func(t *testing.T) {
+		var secData = make(map[string]string)
+		secData["my.message"] = "my-secret-property-value"
+		CreatePlainTextSecret(ns, "my-sec-test-property", secData)
+
+		Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "secret:my-sec-test-property").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-secret-property-value"))
+	})
+
+	t.Run("Property from Secret as property file", func(t *testing.T) {
+		var secData = make(map[string]string)
+		secData["my.properties"] = "my.message=my-secret-property-entry"
+		CreatePlainTextSecret(ns, "my-sec-test-properties", secData)
+
+		Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "secret:my-sec-test-properties").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-secret-property-entry"))
+	})
+
+	// Configmap
+
+	// Store a configmap on the cluster
+	var cmData = make(map[string]string)
+	cmData["my-configmap-key"] = "my-configmap-content"
+	CreatePlainTextConfigmap(ns, "my-cm", cmData)
+
+	// Store a configmap with multiple values
+	var cmDataMulti = make(map[string]string)
+	cmDataMulti["my-configmap-key"] = "should-not-see-it"
+	cmDataMulti["my-configmap-key-2"] = "my-configmap-content-2"
+	CreatePlainTextConfigmap(ns, "my-cm-multi", cmDataMulti)
+
+	t.Run("Config configmap", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/config-configmap-route.groovy", "--config", "configmap:my-cm").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "config-configmap-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "config-configmap-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "config-configmap-route"), TestTimeoutShort).Should(ContainSubstring(cmData["my-configmap-key"]))
+	})
+
+	t.Run("Resource configmap", func(t *testing.T) {
+		// We can reuse the configmap created previously
+
+		Expect(KamelRunWithID(operatorID, ns, "./files/resource-configmap-route.groovy", "--resource", "configmap:my-cm").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "resource-configmap-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "resource-configmap-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "resource-configmap-route"), TestTimeoutShort).Should(ContainSubstring(cmData["my-configmap-key"]))
+	})
+
+	t.Run("Resource configmap with destination", func(t *testing.T) {
+		// We can reuse the configmap created previously
+
+		Expect(KamelRunWithID(operatorID, ns, "./files/resource-configmap-location-route.groovy", "--resource", "configmap:my-cm@/tmp/app").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "resource-configmap-location-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "resource-configmap-location-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "resource-configmap-location-route"), TestTimeoutShort).Should(ContainSubstring(cmData["my-configmap-key"]))
+	})
+
+	t.Run("Resource configmap with filtered key and destination", func(t *testing.T) {
+		// We'll use the configmap contaning 2 values filtering only 1 key
+
+		Expect(KamelRunWithID(operatorID, ns, "./files/resource-configmap-key-location-route.groovy", "--resource", "configmap:my-cm-multi/my-configmap-key-2@/tmp/app/test.txt").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "resource-configmap-key-location-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "resource-configmap-key-location-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "resource-configmap-key-location-route"), TestTimeoutShort).ShouldNot(ContainSubstring(cmDataMulti["my-configmap-key"]))
+		Eventually(IntegrationLogs(ns, "resource-configmap-key-location-route"), TestTimeoutShort).Should(ContainSubstring(cmDataMulti["my-configmap-key-2"]))
+	})
+
+	// Store a configmap as property file
+	var cmDataProps = make(map[string]string)
+	cmDataProps["my.properties"] = "my.key.1=hello\nmy.key.2=world"
+	CreatePlainTextConfigmap(ns, "my-cm-properties", cmDataProps)
+
+	t.Run("Config configmap as property file", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/config-configmap-properties-route.groovy", "--config", "configmap:my-cm-properties").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "config-configmap-properties-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "config-configmap-properties-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "config-configmap-properties-route"), TestTimeoutShort).Should(ContainSubstring("hello world"))
+	})
+
+	// Secret
+
+	// Store a secret on the cluster
+	var secData = make(map[string]string)
+	secData["my-secret-key"] = "very top secret"
+	CreatePlainTextSecret(ns, "my-sec", secData)
+
+	// Store a secret with multi values
+	var secDataMulti = make(map[string]string)
+	secDataMulti["my-secret-key"] = "very top secret"
+	secDataMulti["my-secret-key-2"] = "even more secret"
+	CreatePlainTextSecret(ns, "my-sec-multi", secDataMulti)
+
+	t.Run("Config secret", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/config-secret-route.groovy", "--config", "secret:my-sec").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "config-secret-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "config-secret-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "config-secret-route"), TestTimeoutShort).Should(ContainSubstring(secData["my-secret-key"]))
+	})
+
+	t.Run("Resource secret", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/resource-secret-route.groovy", "--resource", "secret:my-sec").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "resource-secret-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "resource-secret-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "resource-secret-route"), TestTimeoutShort).Should(ContainSubstring(secData["my-secret-key"]))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	// Config File
+
+	t.Run("Plain text configuration file", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/config-file-route.groovy", "--config", "file:./files/resources-data.txt").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "config-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "config-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "config-file-route"), TestTimeoutShort).Should(ContainSubstring("the file body"))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
+	})
+
+	t.Run("Secret with filtered key", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/config-secret-key-route.groovy", "--config", "secret:my-sec-multi/my-secret-key-2").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "config-secret-key-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "config-secret-key-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "config-secret-key-route"), TestTimeoutShort).ShouldNot(ContainSubstring(secDataMulti["my-secret-key"]))
+		Eventually(IntegrationLogs(ns, "config-secret-key-route"), TestTimeoutShort).Should(ContainSubstring(secDataMulti["my-secret-key-2"]))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	// Resource File
+
+	t.Run("Plain text resource file", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/resource-file-route.groovy", "--resource", "file:./files/resources-data.txt").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "resource-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "resource-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "resource-file-route"), TestTimeoutShort).Should(ContainSubstring("the file body"))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
+	})
+
+	t.Run("Plain text resource file with destination path", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/resource-file-location-route.groovy", "--resource", "file:./files/resources-data.txt@/tmp/file.txt").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "resource-file-location-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "resource-file-location-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "resource-file-location-route"), TestTimeoutShort).Should(ContainSubstring("the file body"))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
+	})
+
+	t.Run("Binary (zip) resource file", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/resource-file-binary-route.groovy", "--resource", "file:./files/resources-data.zip", "-d", "camel:zipfile").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "resource-file-binary-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "resource-file-binary-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "resource-file-binary-route"), TestTimeoutShort).Should(ContainSubstring("the file body"))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
+	})
+
+	t.Run("Base64 compressed binary resource file", func(t *testing.T) {
+		// We calculate the expected content
+		source, err := ioutil.ReadFile("./files/resources-data.txt")
+		assert.Nil(t, err)
+		expectedBytes, err := gzip.CompressBase64([]byte(source))
+		assert.Nil(t, err)
+
+		Expect(KamelRunWithID(operatorID, ns, "./files/resource-file-base64-encoded-route.groovy", "--resource", "file:./files/resources-data.txt", "--compression=true").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "resource-file-base64-encoded-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "resource-file-base64-encoded-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "resource-file-base64-encoded-route"), TestTimeoutShort).Should(ContainSubstring(string(expectedBytes)))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
+	})
+
+	t.Run("Plain text resource file with same content", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/resource-file-route.groovy", "--resource", "file:./files/resources-data.txt",
+			"--resource", "file:./files/resources-data-same.txt").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "resource-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "resource-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "resource-file-route"), TestTimeoutShort).Should(ContainSubstring("the file body"))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
+	})
+
+	// Build-Properties
+	t.Run("Build time property", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/build-property-route.groovy", "--build-property", "quarkus.application.name=my-super-application").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "build-property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "build-property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "build-property-route"), TestTimeoutShort).Should(ContainSubstring("my-super-application"))
+		// Don't delete - we need it for next test execution
+	})
+
+	// We need to check also that the property (which is available in the IntegrationKit) is correctly replaced and we don't reuse the same kit
+	t.Run("Build time property updated", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/build-property-route.groovy", "--name", "build-property-route-updated",
+			"--build-property", "quarkus.application.name=my-super-application-updated").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "build-property-route-updated"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "build-property-route-updated", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "build-property-route-updated"), TestTimeoutShort).Should(ContainSubstring("my-super-application-updated"))
+		// Verify the integration kits are different
+		Expect(IntegrationKit(ns, "build-property-route")).ShouldNot(Equal(IntegrationKit(ns, "build-property-route-updated")))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	// Build-Properties file
+	t.Run("Build time property file", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "file:./files/quarkus.properties").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-super-application"))
+	})
+
+	t.Run("Build time property file with precedence", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "quarkus.application.name=my-overridden-application", "--build-property", "file:./files/quarkus.properties").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutMedium).Should(ContainSubstring("my-overridden-application"))
+	})
+
+	t.Run("Build time property from ConfigMap", func(t *testing.T) {
+		var cmData = make(map[string]string)
+		cmData["quarkus.application.name"] = "my-cool-application"
+		CreatePlainTextConfigmap(ns, "my-cm-test-build-property", cmData)
+
+		Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "configmap:my-cm-test-build-property").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutLong).Should(ContainSubstring("my-cool-application"))
+	})
+
+	t.Run("Build time property from ConfigMap as property file", func(t *testing.T) {
+		var cmData = make(map[string]string)
+		cmData["my.properties"] = "quarkus.application.name=my-super-cool-application"
+		CreatePlainTextConfigmap(ns, "my-cm-test-build-properties", cmData)
+
+		Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "configmap:my-cm-test-build-properties").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-super-cool-application"))
+	})
+
+	t.Run("Build time property from Secret", func(t *testing.T) {
+		var secData = make(map[string]string)
+		secData["quarkus.application.name"] = "my-great-application"
+		CreatePlainTextSecret(ns, "my-sec-test-build-property", secData)
+
+		Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "secret:my-sec-test-build-property").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-great-application"))
+	})
+
+	t.Run("Build time property from Secret as property file", func(t *testing.T) {
+		var secData = make(map[string]string)
+		secData["my.properties"] = "quarkus.application.name=my-awsome-application"
+		CreatePlainTextSecret(ns, "my-sec-test-build-properties", secData)
+
+		Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "secret:my-sec-test-build-properties").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-awsome-application"))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/global/builder/doc.go b/e2e/common/config/default.go
similarity index 76%
rename from e2e/global/builder/doc.go
rename to e2e/common/config/default.go
index 757321637..58a809543 100644
--- a/e2e/global/builder/doc.go
+++ b/e2e/common/config/default.go
@@ -1,8 +1,6 @@
 //go:build integration
 // +build integration
 
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
 /*
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
@@ -20,5 +18,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-// Package builder contains e2e tests that should be executed with all builders in the matrix
-package builder
+package config
+
+const ns = "camel-k-test-integration"
+const operatorID = "camel-k-test-integration"
diff --git a/e2e/global/common/config/files/build-property-file-route.groovy b/e2e/common/config/files/build-property-file-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/build-property-file-route.groovy
rename to e2e/common/config/files/build-property-file-route.groovy
diff --git a/e2e/global/common/config/files/build-property-route.groovy b/e2e/common/config/files/build-property-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/build-property-route.groovy
rename to e2e/common/config/files/build-property-route.groovy
diff --git a/e2e/global/common/config/files/config-configmap-properties-route.groovy b/e2e/common/config/files/config-configmap-properties-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/config-configmap-properties-route.groovy
rename to e2e/common/config/files/config-configmap-properties-route.groovy
diff --git a/e2e/global/common/config/files/config-configmap-route.groovy b/e2e/common/config/files/config-configmap-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/config-configmap-route.groovy
rename to e2e/common/config/files/config-configmap-route.groovy
diff --git a/e2e/global/common/config/files/config-file-route.groovy b/e2e/common/config/files/config-file-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/config-file-route.groovy
rename to e2e/common/config/files/config-file-route.groovy
diff --git a/e2e/global/common/config/files/config-secret-key-route.groovy b/e2e/common/config/files/config-secret-key-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/config-secret-key-route.groovy
rename to e2e/common/config/files/config-secret-key-route.groovy
diff --git a/e2e/global/common/config/files/config-secret-route.groovy b/e2e/common/config/files/config-secret-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/config-secret-route.groovy
rename to e2e/common/config/files/config-secret-route.groovy
diff --git a/e2e/global/common/config/files/my.properties b/e2e/common/config/files/my.properties
similarity index 100%
rename from e2e/global/common/config/files/my.properties
rename to e2e/common/config/files/my.properties
diff --git a/e2e/global/common/config/files/property-file-route.groovy b/e2e/common/config/files/property-file-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/property-file-route.groovy
rename to e2e/common/config/files/property-file-route.groovy
diff --git a/e2e/global/common/config/files/property-route.groovy b/e2e/common/config/files/property-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/property-route.groovy
rename to e2e/common/config/files/property-route.groovy
diff --git a/e2e/global/common/config/files/quarkus.properties b/e2e/common/config/files/quarkus.properties
similarity index 100%
rename from e2e/global/common/config/files/quarkus.properties
rename to e2e/common/config/files/quarkus.properties
diff --git a/e2e/global/common/config/files/resource-configmap-key-location-route.groovy b/e2e/common/config/files/resource-configmap-key-location-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/resource-configmap-key-location-route.groovy
rename to e2e/common/config/files/resource-configmap-key-location-route.groovy
diff --git a/e2e/global/common/config/files/resource-configmap-location-route.groovy b/e2e/common/config/files/resource-configmap-location-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/resource-configmap-location-route.groovy
rename to e2e/common/config/files/resource-configmap-location-route.groovy
diff --git a/e2e/global/common/config/files/resource-configmap-route.groovy b/e2e/common/config/files/resource-configmap-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/resource-configmap-route.groovy
rename to e2e/common/config/files/resource-configmap-route.groovy
diff --git a/e2e/global/common/config/files/resource-file-base64-encoded-route.groovy b/e2e/common/config/files/resource-file-base64-encoded-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/resource-file-base64-encoded-route.groovy
rename to e2e/common/config/files/resource-file-base64-encoded-route.groovy
diff --git a/e2e/global/common/config/files/resource-file-binary-route.groovy b/e2e/common/config/files/resource-file-binary-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/resource-file-binary-route.groovy
rename to e2e/common/config/files/resource-file-binary-route.groovy
diff --git a/e2e/namespace/install/cli/files/resource-file-location-route.groovy b/e2e/common/config/files/resource-file-location-route.groovy
similarity index 100%
rename from e2e/namespace/install/cli/files/resource-file-location-route.groovy
rename to e2e/common/config/files/resource-file-location-route.groovy
diff --git a/e2e/global/common/config/files/resource-file-route.groovy b/e2e/common/config/files/resource-file-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/resource-file-route.groovy
rename to e2e/common/config/files/resource-file-route.groovy
diff --git a/e2e/global/common/config/files/resource-secret-route.groovy b/e2e/common/config/files/resource-secret-route.groovy
similarity index 100%
rename from e2e/global/common/config/files/resource-secret-route.groovy
rename to e2e/common/config/files/resource-secret-route.groovy
diff --git a/e2e/global/common/config/files/resources-data-same.txt b/e2e/common/config/files/resources-data-same.txt
similarity index 100%
rename from e2e/global/common/config/files/resources-data-same.txt
rename to e2e/common/config/files/resources-data-same.txt
diff --git a/e2e/global/common/config/files/resources-data.txt b/e2e/common/config/files/resources-data.txt
similarity index 100%
rename from e2e/global/common/config/files/resources-data.txt
rename to e2e/common/config/files/resources-data.txt
diff --git a/e2e/global/common/config/files/resources-data.zip b/e2e/common/config/files/resources-data.zip
similarity index 100%
rename from e2e/global/common/config/files/resources-data.zip
rename to e2e/common/config/files/resources-data.zip
diff --git a/e2e/global/knative/doc.go b/e2e/common/languages/default.go
similarity index 79%
copy from e2e/global/knative/doc.go
copy to e2e/common/languages/default.go
index 6fe4069e4..b8a53bf59 100644
--- a/e2e/global/knative/doc.go
+++ b/e2e/common/languages/default.go
@@ -1,8 +1,6 @@
 //go:build integration
 // +build integration
 
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
 /*
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
@@ -20,5 +18,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-// Package knative contains Knative related e2e tests
-package knative
+package languages
+
+const ns = "camel-k-test-integration"
+const operatorID = "camel-k-test-integration"
diff --git a/e2e/global/common/languages/files/Java.java b/e2e/common/languages/files/Java.java
similarity index 100%
rename from e2e/global/common/languages/files/Java.java
rename to e2e/common/languages/files/Java.java
diff --git a/e2e/global/common/languages/files/Prop.java b/e2e/common/languages/files/Prop.java
similarity index 100%
rename from e2e/global/common/languages/files/Prop.java
rename to e2e/common/languages/files/Prop.java
diff --git a/e2e/global/common/languages/files/groovy.groovy b/e2e/common/languages/files/groovy.groovy
similarity index 100%
rename from e2e/global/common/languages/files/groovy.groovy
rename to e2e/common/languages/files/groovy.groovy
diff --git a/e2e/global/common/languages/files/js-polyglot.js b/e2e/common/languages/files/js-polyglot.js
similarity index 100%
rename from e2e/global/common/languages/files/js-polyglot.js
rename to e2e/common/languages/files/js-polyglot.js
diff --git a/e2e/global/common/languages/files/js.js b/e2e/common/languages/files/js.js
similarity index 100%
rename from e2e/global/common/languages/files/js.js
rename to e2e/common/languages/files/js.js
diff --git a/e2e/global/common/languages/files/kotlin.kts b/e2e/common/languages/files/kotlin.kts
similarity index 100%
rename from e2e/global/common/languages/files/kotlin.kts
rename to e2e/common/languages/files/kotlin.kts
diff --git a/e2e/global/common/languages/files/prop.properties b/e2e/common/languages/files/prop.properties
similarity index 100%
rename from e2e/global/common/languages/files/prop.properties
rename to e2e/common/languages/files/prop.properties
diff --git a/e2e/global/common/languages/files/xml.xml b/e2e/common/languages/files/xml.xml
similarity index 100%
rename from e2e/global/common/languages/files/xml.xml
rename to e2e/common/languages/files/xml.xml
diff --git a/e2e/global/common/languages/files/yaml-polyglot.yaml b/e2e/common/languages/files/yaml-polyglot.yaml
similarity index 100%
rename from e2e/global/common/languages/files/yaml-polyglot.yaml
rename to e2e/common/languages/files/yaml-polyglot.yaml
diff --git a/e2e/global/common/languages/files/yaml.yaml b/e2e/common/languages/files/yaml.yaml
similarity index 100%
rename from e2e/global/common/languages/files/yaml.yaml
rename to e2e/common/languages/files/yaml.yaml
diff --git a/e2e/global/common/languages/groovy_test.go b/e2e/common/languages/groovy_test.go
similarity index 59%
rename from e2e/global/common/languages/groovy_test.go
rename to e2e/common/languages/groovy_test.go
index 5c35e67e3..eab2ad905 100644
--- a/e2e/global/common/languages/groovy_test.go
+++ b/e2e/common/languages/groovy_test.go
@@ -34,20 +34,18 @@ import (
 )
 
 func TestRunSimpleGroovyExamples(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-examples-groovy"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("run groovy", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/groovy.groovy").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "groovy"), TestTimeoutLong).Should(Equal(v1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "groovy", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "groovy"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("init run groovy", func(t *testing.T) {
-			RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageGroovy)
-		})
+	RegisterTestingT(t)
+
+	t.Run("run groovy", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/groovy.groovy").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "groovy"), TestTimeoutLong).Should(Equal(v1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "groovy", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "groovy"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+	})
+
+	t.Run("init run groovy", func(t *testing.T) {
+		RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageGroovy)
 	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/global/common/languages/init_test_support.go b/e2e/common/languages/init_test_support.go
similarity index 92%
rename from e2e/global/common/languages/init_test_support.go
rename to e2e/common/languages/init_test_support.go
index ea4c66901..d5f0794a1 100644
--- a/e2e/global/common/languages/init_test_support.go
+++ b/e2e/common/languages/init_test_support.go
@@ -36,13 +36,13 @@ import (
 	camelv1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 )
 
-func RunInitGeneratedExample(t *testing.T, operatorID string, ns string, lang camelv1.Language) {
+func RunInitGeneratedExample(t *testing.T, operatorId, ns string, lang camelv1.Language) {
 	dir := util.MakeTempDir(t)
 	itName := fmt.Sprintf("init%s", string(lang))          // e.g. initjava
 	fileName := fmt.Sprintf("%s.%s", itName, string(lang)) // e.g. initjava.java
 	file := path.Join(dir, fileName)
 	Expect(Kamel("init", file).Execute()).To(Succeed())
-	Expect(KamelRunWithID(operatorID, ns, file).Execute()).To(Succeed())
+	Expect(KamelRunWithID(operatorId, ns, file).Execute()).To(Succeed())
 	Eventually(IntegrationPodPhase(ns, itName), TestTimeoutLong).Should(Equal(v1.PodRunning))
 	Eventually(IntegrationLogs(ns, itName), TestTimeoutShort).Should(ContainSubstring(languageInitExpectedString(lang)))
 	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
diff --git a/e2e/global/common/languages/xml_test.go b/e2e/common/languages/java_test.go
similarity index 54%
copy from e2e/global/common/languages/xml_test.go
copy to e2e/common/languages/java_test.go
index 04371cae4..b0ddc0efc 100644
--- a/e2e/global/common/languages/xml_test.go
+++ b/e2e/common/languages/java_test.go
@@ -33,21 +33,26 @@ import (
 	camelv1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 )
 
-func TestRunSimpleXmlExamples(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-examples-xml"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("run xml", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/xml.xml").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "xml"), TestTimeoutLong).Should(Equal(v1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "xml", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "xml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("init run xml", func(t *testing.T) {
-			RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageXML)
-		})
+func TestRunSimpleJavaExamples(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("run java", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(v1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "java", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
 	})
+
+	t.Run("run java with properties", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/Prop.java", "--property", "file:files/prop.properties").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "prop"), TestTimeoutLong).Should(Equal(v1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "prop", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "prop"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+	})
+
+	t.Run("init run java", func(t *testing.T) {
+		RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageJavaSource)
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/global/common/languages/yaml_test.go b/e2e/common/languages/js_test.go
similarity index 57%
rename from e2e/global/common/languages/yaml_test.go
rename to e2e/common/languages/js_test.go
index 3a55ac330..2de409f81 100644
--- a/e2e/global/common/languages/yaml_test.go
+++ b/e2e/common/languages/js_test.go
@@ -33,21 +33,19 @@ import (
 	camelv1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 )
 
-func TestRunSimpleYamlExamples(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-examples-yaml"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("run yaml", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(v1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "yaml", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("init run yaml", func(t *testing.T) {
-			RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageYaml)
-		})
+func TestRunSimpleJavaScriptExamples(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("run js", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/js.js").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "js"), TestTimeoutLong).Should(Equal(v1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "js", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "js"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
 	})
+
+	t.Run("init run JavaScript", func(t *testing.T) {
+		RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageJavaScript)
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/global/common/languages/kotlin_test.go b/e2e/common/languages/kotlin_test.go
similarity index 59%
rename from e2e/global/common/languages/kotlin_test.go
rename to e2e/common/languages/kotlin_test.go
index 69cd58a2d..426afadd8 100644
--- a/e2e/global/common/languages/kotlin_test.go
+++ b/e2e/common/languages/kotlin_test.go
@@ -34,20 +34,18 @@ import (
 )
 
 func TestRunSimpleKotlinExamples(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-examples-kotlin"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("run kotlin", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/kotlin.kts").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "kotlin"), TestTimeoutLong).Should(Equal(v1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "kotlin", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "kotlin"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("init run Kotlin", func(t *testing.T) {
-			RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageKotlin)
-		})
+	RegisterTestingT(t)
+
+	t.Run("run kotlin", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/kotlin.kts").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "kotlin"), TestTimeoutLong).Should(Equal(v1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "kotlin", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "kotlin"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+	})
+
+	t.Run("init run Kotlin", func(t *testing.T) {
+		RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageKotlin)
 	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/global/common/languages/polyglot_test.go b/e2e/common/languages/polyglot_test.go
similarity index 57%
rename from e2e/global/common/languages/polyglot_test.go
rename to e2e/common/languages/polyglot_test.go
index 53a56e2ef..559fa6bef 100644
--- a/e2e/global/common/languages/polyglot_test.go
+++ b/e2e/common/languages/polyglot_test.go
@@ -34,17 +34,15 @@ import (
 )
 
 func TestRunPolyglotExamples(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-examples-polyglot"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("run polyglot", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "--name", "polyglot", "files/js-polyglot.js", "files/yaml-polyglot.yaml").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "polyglot"), TestTimeoutLong).Should(Equal(v1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "polyglot", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "polyglot"), TestTimeoutShort).Should(ContainSubstring("Magicpolyglot-yaml"))
-			Eventually(IntegrationLogs(ns, "polyglot"), TestTimeoutShort).Should(ContainSubstring("Magicpolyglot-js"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
+	RegisterTestingT(t)
+
+	t.Run("run polyglot", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "--name", "polyglot", "files/js-polyglot.js", "files/yaml-polyglot.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "polyglot"), TestTimeoutLong).Should(Equal(v1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "polyglot", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "polyglot"), TestTimeoutShort).Should(ContainSubstring("Magicpolyglot-yaml"))
+		Eventually(IntegrationLogs(ns, "polyglot"), TestTimeoutShort).Should(ContainSubstring("Magicpolyglot-js"))
 	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/global/common/languages/js_test.go b/e2e/common/languages/xml_test.go
similarity index 64%
rename from e2e/global/common/languages/js_test.go
rename to e2e/common/languages/xml_test.go
index d7569499a..29b8266f2 100644
--- a/e2e/global/common/languages/js_test.go
+++ b/e2e/common/languages/xml_test.go
@@ -33,21 +33,19 @@ import (
 	camelv1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 )
 
-func TestRunSimpleJavaScriptExamples(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-examples-js"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("run js", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/js.js").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "js"), TestTimeoutLong).Should(Equal(v1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "js", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "js"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("init run JavaScript", func(t *testing.T) {
-			RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageJavaScript)
-		})
+func TestRunSimpleXmlExamples(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("run xml", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/xml.xml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "xml"), TestTimeoutLong).Should(Equal(v1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "xml", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "xml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
 	})
+
+	t.Run("init run xml", func(t *testing.T) {
+		RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageXML)
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/global/common/languages/xml_test.go b/e2e/common/languages/yaml_test.go
similarity index 64%
rename from e2e/global/common/languages/xml_test.go
rename to e2e/common/languages/yaml_test.go
index 04371cae4..9e0ea9243 100644
--- a/e2e/global/common/languages/xml_test.go
+++ b/e2e/common/languages/yaml_test.go
@@ -33,21 +33,19 @@ import (
 	camelv1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 )
 
-func TestRunSimpleXmlExamples(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-examples-xml"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("run xml", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/xml.xml").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "xml"), TestTimeoutLong).Should(Equal(v1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "xml", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "xml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("init run xml", func(t *testing.T) {
-			RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageXML)
-		})
+func TestRunSimpleYamlExamples(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("run yaml", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(v1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "yaml", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
 	})
+
+	t.Run("init run yaml", func(t *testing.T) {
+		RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageYaml)
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/global/common/client_test.go b/e2e/common/misc/client_test.go
similarity index 60%
rename from e2e/global/common/client_test.go
rename to e2e/common/misc/client_test.go
index d0b19d967..5f3b38d65 100644
--- a/e2e/global/common/client_test.go
+++ b/e2e/common/misc/client_test.go
@@ -20,7 +20,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package misc
 
 import (
 	"testing"
@@ -34,32 +34,35 @@ import (
 	. "github.com/apache/camel-k/e2e/support"
 	"github.com/apache/camel-k/pkg/apis/camel/v1"
 	"github.com/apache/camel-k/pkg/client/camel/clientset/versioned"
+	. "github.com/onsi/gomega"
 )
 
 func TestClientFunctionalities(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		cfg, err := config.GetConfig()
-		assert.Nil(t, err)
-		camel, err := versioned.NewForConfig(cfg)
-		assert.Nil(t, err)
-
-		lst, err := camel.CamelV1().Integrations(ns).List(TestContext, metav1.ListOptions{})
-		assert.Nil(t, err)
-		assert.Empty(t, lst.Items)
-
-		integration, err := camel.CamelV1().Integrations(ns).Create(TestContext, &v1.Integration{
-			ObjectMeta: metav1.ObjectMeta{
-				Name: "dummy",
-			},
-		}, metav1.CreateOptions{})
-		assert.Nil(t, err)
-
-		lst, err = camel.CamelV1().Integrations(ns).List(TestContext, metav1.ListOptions{})
-		assert.Nil(t, err)
-		assert.NotEmpty(t, lst.Items)
-		assert.Equal(t, lst.Items[0].Name, integration.Name)
-
-		err = camel.CamelV1().Integrations(ns).Delete(TestContext, "dummy", metav1.DeleteOptions{})
-		assert.Nil(t, err)
-	})
+	RegisterTestingT(t)
+
+	cfg, err := config.GetConfig()
+	assert.Nil(t, err)
+	camel, err := versioned.NewForConfig(cfg)
+	assert.Nil(t, err)
+
+	lst, err := camel.CamelV1().Integrations(ns).List(TestContext, metav1.ListOptions{})
+	assert.Nil(t, err)
+	assert.Empty(t, lst.Items)
+
+	integration, err := camel.CamelV1().Integrations(ns).Create(TestContext, &v1.Integration{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: "dummy",
+		},
+	}, metav1.CreateOptions{})
+	assert.Nil(t, err)
+
+	lst, err = camel.CamelV1().Integrations(ns).List(TestContext, metav1.ListOptions{})
+	assert.Nil(t, err)
+	assert.NotEmpty(t, lst.Items)
+	assert.Equal(t, lst.Items[0].Name, integration.Name)
+
+	err = camel.CamelV1().Integrations(ns).Delete(TestContext, "dummy", metav1.DeleteOptions{})
+	assert.Nil(t, err)
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/common/misc/cron_test.go b/e2e/common/misc/cron_test.go
new file mode 100644
index 000000000..cd15107c0
--- /dev/null
+++ b/e2e/common/misc/cron_test.go
@@ -0,0 +1,75 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package misc
+
+import (
+	"testing"
+
+	. "github.com/onsi/gomega"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+func TestRunCronExample(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("cron", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/cron.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationCronJob(ns, "cron"), TestTimeoutMedium).ShouldNot(BeNil())
+		Eventually(IntegrationConditionStatus(ns, "cron", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "cron"), TestTimeoutMedium).Should(ContainSubstring("Magicstring!"))
+	})
+
+	t.Run("cron-yaml", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/cron-yaml.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationCronJob(ns, "cron-yaml"), TestTimeoutMedium).ShouldNot(BeNil())
+		Eventually(IntegrationConditionStatus(ns, "cron-yaml", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "cron-yaml"), TestTimeoutMedium).Should(ContainSubstring("Magicstring!"))
+	})
+
+	t.Run("cron-timer", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/cron-timer.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationCronJob(ns, "cron-timer"), TestTimeoutMedium).ShouldNot(BeNil())
+		Eventually(IntegrationConditionStatus(ns, "cron-timer", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "cron-timer"), TestTimeoutMedium).Should(ContainSubstring("Magicstring!"))
+	})
+
+	t.Run("cron-fallback", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/cron-fallback.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "cron-fallback"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "cron-fallback", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "cron-fallback"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+	})
+
+	t.Run("cron-quartz", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/cron-quartz.yaml").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "cron-quartz"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "cron-quartz", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "cron-quartz"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/global/knative/doc.go b/e2e/common/misc/default.go
similarity index 79%
copy from e2e/global/knative/doc.go
copy to e2e/common/misc/default.go
index 6fe4069e4..0514eb0e7 100644
--- a/e2e/global/knative/doc.go
+++ b/e2e/common/misc/default.go
@@ -1,8 +1,6 @@
 //go:build integration
 // +build integration
 
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
 /*
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
@@ -20,5 +18,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-// Package knative contains Knative related e2e tests
-package knative
+package misc
+
+const ns = "camel-k-test-integration"
+const operatorID = "camel-k-test-integration"
diff --git a/e2e/global/common/files/BadRoute.java b/e2e/common/misc/files/BadRoute.java
similarity index 100%
rename from e2e/global/common/files/BadRoute.java
rename to e2e/common/misc/files/BadRoute.java
diff --git a/e2e/global/common/files/Java.java b/e2e/common/misc/files/Java.java
similarity index 100%
copy from e2e/global/common/files/Java.java
copy to e2e/common/misc/files/Java.java
diff --git a/e2e/global/common/files/TimerCustomKameletIntegration.java b/e2e/common/misc/files/TimerCustomKameletIntegration.java
similarity index 100%
rename from e2e/global/common/files/TimerCustomKameletIntegration.java
rename to e2e/common/misc/files/TimerCustomKameletIntegration.java
diff --git a/e2e/global/common/files/TimerKameletIntegration.java b/e2e/common/misc/files/TimerKameletIntegration.java
similarity index 93%
rename from e2e/global/common/files/TimerKameletIntegration.java
rename to e2e/common/misc/files/TimerKameletIntegration.java
index c3412a929..b70e0e676 100644
--- a/e2e/global/common/files/TimerKameletIntegration.java
+++ b/e2e/common/misc/files/TimerKameletIntegration.java
@@ -22,7 +22,7 @@ import org.apache.camel.builder.RouteBuilder;
 public class TimerKameletIntegration extends RouteBuilder {
     @Override
     public void configure() throws Exception {
-        from("kamelet:timer-source?message=important%20message")
+        from("kamelet:my-timer-source?message=important%20message")
             .to("log:info");
     }
 }
diff --git a/e2e/global/common/files/Unresolvable.java b/e2e/common/misc/files/Unresolvable.java
similarity index 100%
rename from e2e/global/common/files/Unresolvable.java
rename to e2e/common/misc/files/Unresolvable.java
diff --git a/e2e/global/common/files/cron-fallback.yaml b/e2e/common/misc/files/cron-fallback.yaml
similarity index 100%
rename from e2e/global/common/files/cron-fallback.yaml
rename to e2e/common/misc/files/cron-fallback.yaml
diff --git a/e2e/global/common/files/cron-quartz.yaml b/e2e/common/misc/files/cron-quartz.yaml
similarity index 100%
rename from e2e/global/common/files/cron-quartz.yaml
rename to e2e/common/misc/files/cron-quartz.yaml
diff --git a/e2e/global/common/files/cron-timer.yaml b/e2e/common/misc/files/cron-timer.yaml
similarity index 100%
rename from e2e/global/common/files/cron-timer.yaml
rename to e2e/common/misc/files/cron-timer.yaml
diff --git a/e2e/global/common/files/cron-yaml.yaml b/e2e/common/misc/files/cron-yaml.yaml
similarity index 100%
rename from e2e/global/common/files/cron-yaml.yaml
rename to e2e/common/misc/files/cron-yaml.yaml
diff --git a/e2e/global/common/files/cron.yaml b/e2e/common/misc/files/cron.yaml
similarity index 100%
rename from e2e/global/common/files/cron.yaml
rename to e2e/common/misc/files/cron.yaml
diff --git a/e2e/global/common/files/kamelets/timer-custom-source.kamelet.yaml b/e2e/common/misc/files/kamelets/timer-custom-source.kamelet.yaml
similarity index 100%
rename from e2e/global/common/files/kamelets/timer-custom-source.kamelet.yaml
rename to e2e/common/misc/files/kamelets/timer-custom-source.kamelet.yaml
diff --git a/e2e/global/common/files/timer-source.kamelet.yaml b/e2e/common/misc/files/my-timer-source.kamelet.yaml
similarity index 99%
rename from e2e/global/common/files/timer-source.kamelet.yaml
rename to e2e/common/misc/files/my-timer-source.kamelet.yaml
index 63d9b309e..7a91a2e20 100644
--- a/e2e/global/common/files/timer-source.kamelet.yaml
+++ b/e2e/common/misc/files/my-timer-source.kamelet.yaml
@@ -18,7 +18,7 @@
 apiVersion: camel.apache.org/v1alpha1
 kind: Kamelet
 metadata:
-  name: timer-source
+  name: my-timer-source
   annotations:
     camel.apache.org/kamelet.support.level: "Preview"
     camel.apache.org/catalog.version: "0.3.0"
diff --git a/e2e/global/registry/files/FoobarDecryption.java b/e2e/common/misc/files/registry/FoobarDecryption.java
similarity index 100%
rename from e2e/global/registry/files/FoobarDecryption.java
rename to e2e/common/misc/files/registry/FoobarDecryption.java
diff --git a/e2e/global/registry/files/LaughingRoute.java b/e2e/common/misc/files/registry/LaughingRoute.java
similarity index 100%
rename from e2e/global/registry/files/LaughingRoute.java
rename to e2e/common/misc/files/registry/LaughingRoute.java
diff --git a/e2e/global/registry/files/classpath/Xslt.java b/e2e/common/misc/files/registry/classpath/Xslt.java
similarity index 100%
rename from e2e/global/registry/files/classpath/Xslt.java
rename to e2e/common/misc/files/registry/classpath/Xslt.java
diff --git a/e2e/global/registry/files/classpath/cheese.xsl b/e2e/common/misc/files/registry/classpath/cheese.xsl
similarity index 100%
rename from e2e/global/registry/files/classpath/cheese.xsl
rename to e2e/common/misc/files/registry/classpath/cheese.xsl
diff --git a/e2e/global/registry/files/laugh.txt b/e2e/common/misc/files/registry/laugh.txt
similarity index 100%
rename from e2e/global/registry/files/laugh.txt
rename to e2e/common/misc/files/registry/laugh.txt
diff --git a/e2e/global/registry/files/laughs/haha.txt b/e2e/common/misc/files/registry/laughs/haha.txt
similarity index 100%
rename from e2e/global/registry/files/laughs/haha.txt
rename to e2e/common/misc/files/registry/laughs/haha.txt
diff --git a/e2e/global/registry/files/laughs/hehe.txt b/e2e/common/misc/files/registry/laughs/hehe.txt
similarity index 100%
rename from e2e/global/registry/files/laughs/hehe.txt
rename to e2e/common/misc/files/registry/laughs/hehe.txt
diff --git a/e2e/global/registry/files/sample-decryption-1.0.jar b/e2e/common/misc/files/registry/sample-decryption-1.0.jar
similarity index 100%
rename from e2e/global/registry/files/sample-decryption-1.0.jar
rename to e2e/common/misc/files/registry/sample-decryption-1.0.jar
diff --git a/e2e/global/registry/files/sample-decryption-1.0.pom b/e2e/common/misc/files/registry/sample-decryption-1.0.pom
similarity index 100%
rename from e2e/global/registry/files/sample-decryption-1.0.pom
rename to e2e/common/misc/files/registry/sample-decryption-1.0.pom
diff --git a/e2e/global/registry/files/src/main/java/camelk/DeterministicDecryption.java b/e2e/common/misc/files/registry/src/main/java/camelk/DeterministicDecryption.java
similarity index 100%
rename from e2e/global/registry/files/src/main/java/camelk/DeterministicDecryption.java
rename to e2e/common/misc/files/registry/src/main/java/camelk/DeterministicDecryption.java
diff --git a/e2e/global/common/files/rest-consumer.yaml b/e2e/common/misc/files/rest-consumer.yaml
similarity index 100%
rename from e2e/global/common/files/rest-consumer.yaml
rename to e2e/common/misc/files/rest-consumer.yaml
diff --git a/e2e/global/common/files/rest-producer.yaml b/e2e/common/misc/files/rest-producer.yaml
similarity index 100%
rename from e2e/global/common/files/rest-producer.yaml
rename to e2e/common/misc/files/rest-producer.yaml
diff --git a/e2e/global/knative/files/yaml.yaml b/e2e/common/misc/files/yaml.yaml
similarity index 100%
rename from e2e/global/knative/files/yaml.yaml
rename to e2e/common/misc/files/yaml.yaml
diff --git a/e2e/common/misc/integration_fail_test.go b/e2e/common/misc/integration_fail_test.go
new file mode 100644
index 000000000..838b6a05d
--- /dev/null
+++ b/e2e/common/misc/integration_fail_test.go
@@ -0,0 +1,120 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package misc
+
+import (
+	"testing"
+	"time"
+
+	. "github.com/onsi/gomega"
+	"github.com/onsi/gomega/gstruct"
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+func TestBadRouteIntegration(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("run bad java route", func(t *testing.T) {
+		name := "bad-route"
+		Expect(KamelRunWithID(operatorID, ns, "files/BadRoute.java", "--name", name).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+			Should(Equal(corev1.ConditionFalse))
+
+		// Make sure the Integration can be scaled
+		Expect(ScaleIntegration(ns, name, 2)).To(Succeed())
+		// Check the scale cascades into the Deployment scale
+		Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(2))
+		// Check it also cascades into the Integration scale subresource Status field
+		Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 2)))
+		// Check the Integration stays in error phase
+		Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
+	})
+
+	t.Run("run missing dependency java route", func(t *testing.T) {
+		name := "java-route"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name,
+			"-d", "mvn:com.example:nonexistent:1.0").Execute()).To(Succeed())
+		// Integration in error
+		Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError))
+		kitName := IntegrationKit(ns, name)()
+		// Kit in error
+		Eventually(KitPhase(ns, kitName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseError))
+		//Build in error with 5 attempts
+		build := Build(ns, kitName)()
+		Eventually(build.Status.Phase, TestTimeoutShort).Should(Equal(v1.BuildPhaseError))
+		Eventually(build.Status.Failure.Recovery.Attempt, TestTimeoutShort).Should(Equal(5))
+	})
+
+	t.Run("run invalid dependency java route", func(t *testing.T) {
+		name := "invalid-dependency"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name,
+			"-d", "camel:non-existent").Execute()).To(Succeed())
+		// Integration in error with Initialization Failed condition
+		Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+			Should(Equal(corev1.ConditionFalse))
+		Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And(
+			WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)),
+			WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")),
+		))
+		// Kit shouldn't be created
+		Consistently(IntegrationKit(ns, name), 10*time.Second).Should(BeEmpty())
+
+		// Fixing the route should reconcile the Integration in Initialization Failed condition to Running
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+			Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+	})
+
+	t.Run("run unresolvable component java route", func(t *testing.T) {
+		name := "unresolvable-route"
+		Expect(KamelRunWithID(operatorID, ns, "files/Unresolvable.java", "--name", name).Execute()).To(Succeed())
+		// Integration in error with Initialization Failed condition
+		Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+			Should(Equal(corev1.ConditionFalse))
+		Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And(
+			WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)),
+			WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")),
+		))
+		// Kit shouldn't be created
+		Consistently(IntegrationKit(ns, name), 10*time.Second).Should(BeEmpty())
+
+		// Fixing the route should reconcile the Integration in Initialization Failed condition to Running
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+			Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/common/misc/kamelet_binding_test.go b/e2e/common/misc/kamelet_binding_test.go
new file mode 100644
index 000000000..936e41406
--- /dev/null
+++ b/e2e/common/misc/kamelet_binding_test.go
@@ -0,0 +1,170 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package misc
+
+import (
+	"testing"
+
+	. "github.com/onsi/gomega"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/util/kubernetes"
+)
+
+func TestKameletBinding(t *testing.T) {
+	RegisterTestingT(t)
+
+	// Error Handler testing
+	t.Run("test error handler", func(t *testing.T) {
+		Expect(createErrorProducerKamelet(ns, "my-own-error-producer-source")()).To(Succeed())
+		Expect(CreateLogKamelet(ns, "my-own-log-sink")()).To(Succeed())
+		from := corev1.ObjectReference{
+			Kind:       "Kamelet",
+			Name:       "my-own-error-producer-source",
+			APIVersion: v1alpha1.SchemeGroupVersion.String(),
+		}
+
+		to := corev1.ObjectReference{
+			Kind:       "Kamelet",
+			Name:       "my-own-log-sink",
+			APIVersion: v1alpha1.SchemeGroupVersion.String(),
+		}
+
+		errorHandler := map[string]interface{}{
+			"sink": map[string]interface{}{
+				"endpoint": map[string]interface{}{
+					"ref": map[string]string{
+						"kind":       "Kamelet",
+						"apiVersion": v1alpha1.SchemeGroupVersion.String(),
+						"name":       "my-own-log-sink",
+					},
+					"properties": map[string]string{
+						"loggerName": "kameletErrorHandler",
+					},
+				}}}
+
+		t.Run("throw error test", func(t *testing.T) {
+			Expect(BindKameletToWithErrorHandler(ns, "throw-error-binding", map[string]string{},
+				from, to,
+				map[string]string{"message": "throw Error"}, map[string]string{"loggerName": "integrationLogger"},
+				errorHandler)()).To(Succeed())
+
+			Eventually(IntegrationPodPhase(ns, "throw-error-binding"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationLogs(ns, "throw-error-binding"), TestTimeoutShort).Should(ContainSubstring("kameletErrorHandler"))
+			Eventually(IntegrationLogs(ns, "throw-error-binding"), TestTimeoutShort).ShouldNot(ContainSubstring("integrationLogger"))
+
+		})
+
+		t.Run("don't throw error test", func(t *testing.T) {
+			Expect(BindKameletToWithErrorHandler(ns, "no-error-binding", map[string]string{},
+				from, to,
+				map[string]string{"message": "true"}, map[string]string{"loggerName": "integrationLogger"},
+				errorHandler)()).To(Succeed())
+
+			Eventually(IntegrationPodPhase(ns, "no-error-binding"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationLogs(ns, "no-error-binding"), TestTimeoutShort).ShouldNot(ContainSubstring("kameletErrorHandler"))
+			Eventually(IntegrationLogs(ns, "no-error-binding"), TestTimeoutShort).Should(ContainSubstring("integrationLogger"))
+
+		})
+	})
+
+	// Kamelet binding with traits testing
+	t.Run("test kamelet binding with trait", func(t *testing.T) {
+		Expect(CreateTimerKamelet(ns, "my-own-timer-source")()).To(Succeed())
+		// Log sink kamelet exists from previous test
+
+		from := corev1.ObjectReference{
+			Kind:       "Kamelet",
+			Name:       "my-own-timer-source",
+			APIVersion: v1alpha1.SchemeGroupVersion.String(),
+		}
+
+		to := corev1.ObjectReference{
+			Kind:       "Kamelet",
+			Name:       "my-own-log-sink",
+			APIVersion: v1alpha1.SchemeGroupVersion.String(),
+		}
+
+		Expect(BindKameletTo(ns, "kb-with-traits",
+			map[string]string{"trait.camel.apache.org/camel.properties": "[\"camel.prop1=a\",\"camel.prop2=b\"]"},
+			from, to,
+			map[string]string{"message": "hello from test"}, map[string]string{"loggerName": "integrationLogger"})()).
+			To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, "kb-with-traits"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationLogs(ns, "kb-with-traits"), TestTimeoutShort).Should(ContainSubstring("hello from test"))
+		Eventually(IntegrationLogs(ns, "kb-with-traits"), TestTimeoutShort).Should(ContainSubstring("integrationLogger"))
+	})
+
+	// KameletBinding with wrong spec
+	t.Run("test KameletBinding with wrong spec", func(t *testing.T) {
+		name := "bad-klb"
+		kb := v1alpha1.NewKameletBinding(ns, name)
+		kb.Spec = v1alpha1.KameletBindingSpec{}
+		_, err := kubernetes.ReplaceResource(TestContext, TestClient(), &kb)
+		Eventually(err).Should(BeNil())
+		Eventually(KameletBindingPhase(ns, name), TestTimeoutShort).Should(Equal(v1alpha1.KameletBindingPhaseError))
+		Eventually(KameletBindingConditionStatus(ns, name, v1alpha1.KameletBindingConditionReady), TestTimeoutShort).ShouldNot(Equal(corev1.ConditionTrue))
+		Eventually(KameletBindingCondition(ns, name, v1alpha1.KameletBindingIntegrationConditionError), TestTimeoutShort).Should(
+			WithTransform(KameletBindingConditionMessage, And(
+				ContainSubstring("could not determine source URI"),
+				ContainSubstring("no ref or URI specified in endpoint"),
+			)))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
+
+func createErrorProducerKamelet(ns string, name string) func() error {
+	props := map[string]v1alpha1.JSONSchemaProp{
+		"message": {
+			Type: "string",
+		},
+	}
+
+	flow := map[string]interface{}{
+		"from": map[string]interface{}{
+			"uri": "timer:tick",
+			"steps": []map[string]interface{}{
+				{
+					"set-body": map[string]interface{}{
+						"constant": "{{message}}",
+					},
+				},
+				{
+					"set-body": map[string]interface{}{
+						"simple": "${mandatoryBodyAs(Boolean)}",
+					},
+				},
+				{
+					"to": "kamelet:sink",
+				},
+			},
+		},
+	}
+
+	return CreateKamelet(ns, name, flow, props, nil)
+}
diff --git a/e2e/common/misc/kamelet_binding_with_image_test.go b/e2e/common/misc/kamelet_binding_with_image_test.go
new file mode 100644
index 000000000..01d399ff3
--- /dev/null
+++ b/e2e/common/misc/kamelet_binding_with_image_test.go
@@ -0,0 +1,109 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package misc
+
+import (
+	"testing"
+
+	. "github.com/onsi/gomega"
+	"github.com/onsi/gomega/gstruct"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+)
+
+func TestBindingWithImage(t *testing.T) {
+	RegisterTestingT(t)
+
+	from := corev1.ObjectReference{
+		Kind:       "Kamelet",
+		Name:       "my-own-timer-source",
+		APIVersion: v1alpha1.SchemeGroupVersion.String(),
+	}
+
+	to := corev1.ObjectReference{
+		Kind:       "Kamelet",
+		Name:       "my-own-log-sink",
+		APIVersion: v1alpha1.SchemeGroupVersion.String(),
+	}
+
+	emptyMap := map[string]string{}
+
+	annotations1 := map[string]string{
+		"trait.camel.apache.org/container.image":      "docker.io/jmalloc/echo-server:0.3.2",
+		"trait.camel.apache.org/jvm.enabled":          "false",
+		"trait.camel.apache.org/kamelets.enabled":     "false",
+		"trait.camel.apache.org/dependencies.enabled": "false",
+		"test": "1",
+	}
+	annotations2 := map[string]string{
+		"trait.camel.apache.org/container.image":      "docker.io/jmalloc/echo-server:0.3.3",
+		"trait.camel.apache.org/jvm.enabled":          "false",
+		"trait.camel.apache.org/kamelets.enabled":     "false",
+		"trait.camel.apache.org/dependencies.enabled": "false",
+		"test": "2",
+	}
+	bindingID := "with-image-binding"
+
+	t.Run("run with initial image", func(t *testing.T) {
+		expectedImage := annotations1["trait.camel.apache.org/container.image"]
+
+		Expect(BindKameletTo(ns, bindingID, annotations1, from, to, emptyMap, emptyMap)()).
+			To(Succeed())
+		Eventually(IntegrationGeneration(ns, bindingID)).
+			Should(gstruct.PointTo(BeNumerically("==", 1)))
+		Eventually(Integration(ns, bindingID)).Should(WithTransform(Annotations, And(
+			HaveKeyWithValue("test", "1"),
+			HaveKeyWithValue("trait.camel.apache.org/container.image", expectedImage),
+		)))
+		Eventually(IntegrationStatusImage(ns, bindingID)).
+			Should(Equal(expectedImage))
+		Eventually(IntegrationPodPhase(ns, bindingID), TestTimeoutLong).
+			Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationPodImage(ns, bindingID)).
+			Should(Equal(expectedImage))
+	})
+
+	t.Run("run with new image", func(t *testing.T) {
+		expectedImage := annotations2["trait.camel.apache.org/container.image"]
+
+		Expect(BindKameletTo(ns, bindingID, annotations2, from, to, emptyMap, emptyMap)()).
+			To(Succeed())
+		Eventually(IntegrationGeneration(ns, bindingID)).
+			Should(gstruct.PointTo(BeNumerically("==", 1)))
+		Eventually(Integration(ns, bindingID)).Should(WithTransform(Annotations, And(
+			HaveKeyWithValue("test", "2"),
+			HaveKeyWithValue("trait.camel.apache.org/container.image", expectedImage),
+		)))
+		Eventually(IntegrationStatusImage(ns, bindingID)).
+			Should(Equal(expectedImage))
+		Eventually(IntegrationPodPhase(ns, bindingID), TestTimeoutLong).
+			Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationPodImage(ns, bindingID)).
+			Should(Equal(expectedImage))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/namespace/install/cli/kamelet_test.go b/e2e/common/misc/kamelet_test.go
similarity index 55%
rename from e2e/namespace/install/cli/kamelet_test.go
rename to e2e/common/misc/kamelet_test.go
index 3a48ea918..2975c7801 100644
--- a/e2e/namespace/install/cli/kamelet_test.go
+++ b/e2e/common/misc/kamelet_test.go
@@ -20,50 +20,47 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package misc
 
 import (
-	"fmt"
 	"testing"
 
 	. "github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
 
 	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 )
 
-// This test requires operator installation with a custom operator ID, thus needs
-// to be run under e2e/namespace.
-func TestKameletFromCustomRepository(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := fmt.Sprintf("camel-k-%s", ns)
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-		Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady))
+func TestKameletClasspathLoading(t *testing.T) {
+	RegisterTestingT(t)
+
+	// Basic
+	t.Run("test basic case", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/TimerKameletIntegration.java", "-t", "kamelets.enabled=false",
+			"--resource", "file:files/my-timer-source.kamelet.yaml@/kamelets/my-timer-source.kamelet.yaml",
+			"-p camel.component.kamelet.location=file:/kamelets",
+			"-d", "camel:yaml-dsl",
+			// kamelet dependencies
+			"-d", "camel:timer").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "timer-kamelet-integration"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationLogs(ns, "timer-kamelet-integration")).Should(ContainSubstring("important message"))
+	})
 
+	// Custom repo without operator ID
+	t.Run("test custom Kamelet repository without operator ID", func(t *testing.T) {
 		kameletName := "timer-custom-source"
 		removeKamelet(kameletName, ns)
-
 		Eventually(Kamelet(kameletName, ns)).Should(BeNil())
-
 		// Add the custom repository
-		Expect(Kamel("kamelet", "add-repo",
-			"github:apache/camel-k/e2e/global/common/files/kamelets",
-			"-n", ns,
-			"-x", operatorID).Execute()).To(Succeed())
-
+		Expect(Kamel("kamelet", "add-repo", "github:apache/camel-k/e2e/global/common/files/kamelets", "-n", ns).Execute()).To(Succeed())
 		Expect(KamelRunWithID(operatorID, ns, "files/TimerCustomKameletIntegration.java").Execute()).To(Succeed())
-		Eventually(IntegrationPodPhase(ns, "timer-custom-kamelet-integration"), TestTimeoutLong).
-			Should(Equal(corev1.PodRunning))
-
-		Eventually(IntegrationLogs(ns, "timer-custom-kamelet-integration")).Should(ContainSubstring("hello world"))
-
+		Eventually(IntegrationPodPhase(ns, "timer-custom-kamelet-integration"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationLogs(ns, "timer-custom-kamelet-integration")).Should(ContainSubstring("great message"))
 		// Remove the custom repository
-		Expect(Kamel("kamelet", "remove-repo",
-			"github:apache/camel-k/e2e/global/common/files/kamelets",
-			"-n", ns,
-			"-x", operatorID).Execute()).To(Succeed())
+		Expect(Kamel("kamelet", "remove-repo", "github:apache/camel-k/e2e/global/common/files/kamelets", "-n", ns).Execute()).To(Succeed())
 	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
 
 func removeKamelet(name string, ns string) {
diff --git a/e2e/global/common/kamelet_update_test.go b/e2e/common/misc/kamelet_update_test.go
similarity index 71%
rename from e2e/global/common/kamelet_update_test.go
rename to e2e/common/misc/kamelet_update_test.go
index a5e1fc121..b5542e296 100644
--- a/e2e/global/common/kamelet_update_test.go
+++ b/e2e/common/misc/kamelet_update_test.go
@@ -20,7 +20,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package misc
 
 import (
 	"testing"
@@ -35,21 +35,17 @@ import (
 const customLabel = "custom-label"
 
 func TestBundleKameletUpdate(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		Expect(createBundleKamelet(ns, "http-sink")()).To(Succeed()) // Going to be replaced
-		Expect(createUserKamelet(ns, "user-sink")()).To(Succeed())   // Left intact by the operator
+	RegisterTestingT(t)
 
-		operatorID := "camel-k-kamelet-update"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
+	Expect(createBundleKamelet(ns, "http-sink")()).To(Succeed()) // Going to be replaced
+	Expect(createUserKamelet(ns, "user-sink")()).To(Succeed())   // Left intact by the operator
 
-		Eventually(Kamelet("http-sink", ns)).
-			Should(WithTransform(KameletLabels, HaveKeyWithValue(customLabel, "true")))
-		Consistently(Kamelet("user-sink", ns), 5*time.Second, 1*time.Second).
-			Should(WithTransform(KameletLabels, HaveKeyWithValue(customLabel, "true")))
+	Eventually(Kamelet("http-sink", ns)).
+		Should(WithTransform(KameletLabels, HaveKeyWithValue(customLabel, "true")))
+	Consistently(Kamelet("user-sink", ns), 5*time.Second, 1*time.Second).
+		Should(WithTransform(KameletLabels, HaveKeyWithValue(customLabel, "true")))
 
-		// Cleanup
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
-	})
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
 
 func createBundleKamelet(ns string, name string) func() error {
diff --git a/e2e/global/common/build/maven_repository_test.go b/e2e/common/misc/maven_repository_test.go
similarity index 57%
copy from e2e/global/common/build/maven_repository_test.go
copy to e2e/common/misc/maven_repository_test.go
index 7cee488b7..3f584a052 100644
--- a/e2e/global/common/build/maven_repository_test.go
+++ b/e2e/common/misc/maven_repository_test.go
@@ -20,7 +20,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package build
+package misc
 
 import (
 	"testing"
@@ -34,20 +34,17 @@ import (
 )
 
 func TestRunExtraRepository(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-extra-repository"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		name := "java"
-		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-			"--maven-repository", "https://maven.repository.redhat.com/ga@id=redhat",
-			"--dependency", "mvn:jakarta.annotation:jakarta.annotation-api:1.3.5.redhat-00002",
-			"--name", name,
-		).Execute()).To(Succeed())
-
-		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-	})
+	RegisterTestingT(t)
+	name := "java"
+	Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+		"--maven-repository", "https://maven.repository.redhat.com/ga@id=redhat",
+		"--dependency", "mvn:jakarta.annotation:jakarta.annotation-api:1.3.5.redhat-00002",
+		"--name", name,
+	).Execute()).To(Succeed())
+
+	Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+	Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+	Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/global/common/platformless_run_test.go b/e2e/common/misc/platformless_run_test.go
similarity index 66%
rename from e2e/global/common/platformless_run_test.go
rename to e2e/common/misc/platformless_run_test.go
index cd9694c44..9aecd08b9 100644
--- a/e2e/global/common/platformless_run_test.go
+++ b/e2e/common/misc/platformless_run_test.go
@@ -20,7 +20,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package misc
 
 import (
 	"os"
@@ -37,6 +37,8 @@ import (
 )
 
 func TestPlatformlessRun(t *testing.T) {
+	RegisterTestingT(t)
+
 	needsExternalRepo := os.Getenv("STAGING_RUNTIME_REPO") != "" || os.Getenv("KAMEL_INSTALL_MAVEN_REPOSITORIES") != ""
 	ocp, err := openshift.IsOpenShift(TestClient())
 	assert.Nil(t, err)
@@ -45,20 +47,14 @@ func TestPlatformlessRun(t *testing.T) {
 		return
 	}
 
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-platform-missing"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		// Delete the platform from the namespace before running the integration
-		Eventually(DeletePlatform(ns)).Should(BeTrue())
-
-		Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed())
-		Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-		Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+	// Delete the platform from the namespace before running the integration
+	Eventually(DeletePlatform(ns)).Should(BeTrue())
+	Expect(KamelRunWithID(operatorID, ns, "files/yaml.yaml").Execute()).To(Succeed())
+	Eventually(IntegrationPodPhase(ns, "yaml"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+	Eventually(IntegrationLogs(ns, "yaml"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+	// Platform should be recreated
+	Eventually(Platform(ns)).ShouldNot(BeNil())
+	Eventually(PlatformProfile(ns)).Should(Equal(v1.TraitProfile("")))
 
-		// Platform should be recreated
-		Eventually(Platform(ns)).ShouldNot(BeNil())
-		Eventually(PlatformProfile(ns)).Should(Equal(v1.TraitProfile("")))
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-	})
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/common/misc/registry_maven_wagon_test.go b/e2e/common/misc/registry_maven_wagon_test.go
new file mode 100644
index 000000000..81b8fce1b
--- /dev/null
+++ b/e2e/common/misc/registry_maven_wagon_test.go
@@ -0,0 +1,141 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package misc
+
+import (
+	"fmt"
+	"path/filepath"
+	"testing"
+
+	. "github.com/onsi/gomega"
+	"github.com/stretchr/testify/assert"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	"github.com/apache/camel-k/pkg/util/openshift"
+)
+
+func TestImageRegistryIsAMavenRepository(t *testing.T) {
+	RegisterTestingT(t)
+	ocp, err := openshift.IsOpenShift(TestClient())
+	assert.Nil(t, err)
+	if ocp {
+		t.Skip("Avoid running on OpenShift until CA and secret are injected client side")
+		return
+	}
+
+	t.Run("image registry is a maven repository", func(t *testing.T) {
+		// Create integration that should decrypt an encrypted message to "foobar" and log it
+		name := "foobar-decryption"
+		jar, err := filepath.Abs("files/registry/sample-decryption-1.0.jar?skipPOM=true")
+		assert.Nil(t, err)
+		pom, err := filepath.Abs("files/registry/sample-decryption-1.0.pom")
+		assert.Nil(t, err)
+
+		Expect(KamelRunWithID(operatorID, ns, "files/registry/FoobarDecryption.java",
+			"--name", name,
+			"-d", fmt.Sprintf("file://%s", jar),
+			"-d", fmt.Sprintf("file://%s", pom),
+		).Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("foobar"))
+	})
+
+	t.Run("local files are mounted in the integration container at the default path", func(t *testing.T) {
+		name := "laughing-route-default-path"
+
+		Expect(KamelRunWithID(operatorID, ns, "files/registry/LaughingRoute.java",
+			"--name", name,
+			"-p", "location=.?filename=laugh.txt",
+			"-d", "file://files/registry/laugh.txt",
+		).Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("haha"))
+	})
+
+	t.Run("local files are mounted in the integration container at a custom path", func(t *testing.T) {
+		name := "laughing-route-custom-path"
+		customPath := "this/is/a/custom/path/"
+
+		Expect(KamelRunWithID(operatorID, ns, "files/registry/LaughingRoute.java",
+			"--name", name,
+			"-p", fmt.Sprintf("location=%s", customPath),
+			"-d", fmt.Sprintf("file://files/registry/laugh.txt?targetPath=%slaugh.txt", customPath),
+		).Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("haha"))
+	})
+
+	t.Run("local directory is mounted in the integration container", func(t *testing.T) {
+		name := "laughing-route-directory"
+
+		Expect(KamelRunWithID(operatorID, ns, "files/registry/LaughingRoute.java",
+			"--name", name,
+			"-p", "location=files/registry/",
+			"-d", fmt.Sprintf("file://files/registry/laughs/?targetPath=files/registry/"),
+		).Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("haha"))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("hehe"))
+	})
+
+	t.Run("pom file is extracted from JAR", func(t *testing.T) {
+		// Create integration that should decrypt foobar and log it
+		name := "foobar-decryption-pom-extraction"
+		jar, err := filepath.Abs("files/registry/sample-decryption-1.0.jar")
+		assert.Nil(t, err)
+
+		Expect(KamelRunWithID(operatorID, ns, "files/registry/FoobarDecryption.java",
+			"--name", name,
+			"-d", fmt.Sprintf("file://%s", jar),
+		).Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("foobar"))
+	})
+	t.Run("dependency can be used at build time", func(t *testing.T) {
+		// Create integration that should run an Xslt transformation whose template needs to be present at build time
+		name := "xslt"
+		Expect(KamelRunWithID(operatorID, ns, "files/registry/classpath/Xslt.java", "--name", name,
+			"-d", "file://files/registry/classpath/cheese.xsl?targetPath=xslt/cheese.xsl&classpath=true",
+		).Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("<cheese><item>A</item></cheese>"))
+	})
+
+	// Clean up
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/common/misc/rest_test.go b/e2e/common/misc/rest_test.go
new file mode 100644
index 000000000..583c19fd3
--- /dev/null
+++ b/e2e/common/misc/rest_test.go
@@ -0,0 +1,91 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package misc
+
+import (
+	"fmt"
+	"io"
+	"net/http"
+	"testing"
+	"time"
+
+	. "github.com/onsi/gomega"
+	"github.com/stretchr/testify/assert"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	"github.com/apache/camel-k/pkg/util/openshift"
+)
+
+func TestRunRest(t *testing.T) {
+	RegisterTestingT(t)
+
+	ocp, err := openshift.IsOpenShift(TestClient())
+	assert.Nil(t, err)
+
+	Expect(KamelRunWithID(operatorID, ns, "files/rest-consumer.yaml").Execute()).To(Succeed())
+	Eventually(IntegrationPodPhase(ns, "rest-consumer"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+
+	t.Run("Service works", func(t *testing.T) {
+		name := "John"
+		service := Service(ns, "rest-consumer")
+		Eventually(service, TestTimeoutShort).ShouldNot(BeNil())
+		Expect(KamelRunWithID(operatorID, ns, "files/rest-producer.yaml", "-p", "serviceName=rest-consumer", "-p", "name="+name).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "rest-producer"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationLogs(ns, "rest-consumer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("get %s", name)))
+		Eventually(IntegrationLogs(ns, "rest-producer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("%s Doe", name)))
+	})
+
+	if ocp {
+		t.Run("Route works", func(t *testing.T) {
+			name := "Peter"
+			route := Route(ns, "rest-consumer")
+			Eventually(route, TestTimeoutShort).ShouldNot(BeNil())
+			Eventually(RouteStatus(ns, "rest-consumer"), TestTimeoutMedium).Should(Equal("True"))
+			url := fmt.Sprintf("http://%s/customers/%s", route().Spec.Host, name)
+			Eventually(httpRequest(url), TestTimeoutMedium).Should(Equal(fmt.Sprintf("%s Doe", name)))
+			Eventually(IntegrationLogs(ns, "rest-consumer"), TestTimeoutShort).Should(ContainSubstring(fmt.Sprintf("get %s", name)))
+		})
+	}
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
+
+func httpRequest(url string) func() (string, error) {
+	return func() (string, error) {
+		client := &http.Client{Timeout: 3 * time.Second}
+		response, err := client.Get(url)
+		if err != nil {
+			return "", err
+		}
+		defer response.Body.Close()
+
+		body, err := io.ReadAll(response.Body)
+		if err != nil {
+			return "", err
+		}
+
+		return string(body), nil
+	}
+}
diff --git a/e2e/common/misc/scale_binding_test.go b/e2e/common/misc/scale_binding_test.go
new file mode 100644
index 000000000..307439030
--- /dev/null
+++ b/e2e/common/misc/scale_binding_test.go
@@ -0,0 +1,133 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package misc
+
+import (
+	"testing"
+
+	. "github.com/onsi/gomega"
+	"github.com/onsi/gomega/gstruct"
+	"github.com/stretchr/testify/assert"
+
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"github.com/apache/camel-k/pkg/client/camel/clientset/versioned"
+	"github.com/apache/camel-k/pkg/util/openshift"
+)
+
+func TestKameletBindingScale(t *testing.T) {
+	RegisterTestingT(t)
+
+	ocp, err := openshift.IsOpenShift(TestClient())
+	assert.Nil(t, err)
+	if ocp {
+		t.Skip("TODO: Temporarily disabled as this test is flaky on OpenShift 3")
+		return
+	}
+
+	name := "timer2log"
+	Expect(KamelBindWithID(operatorID, ns, "timer-source?message=HelloBinding", "log-sink", "--name", name).Execute()).To(Succeed())
+	Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+	Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+	Eventually(KameletBindingConditionStatus(ns, name, v1alpha1.KameletBindingConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+	Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("HelloBinding"))
+
+	t.Run("Update binding scale spec", func(t *testing.T) {
+		Expect(ScaleKameletBinding(ns, name, 3)).To(Succeed())
+		// Check the scale cascades into the Deployment scale
+		Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(3))
+		// Check it also cascades into the Integration scale subresource Status field
+		Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 3)))
+		// Check it also cascades into the KameletBinding scale subresource Status field
+		Eventually(KameletBindingStatusReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 3)))
+		// Check the readiness condition becomes truthy back
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
+		// Finally check the readiness condition becomes truthy back on kamelet binding
+		Eventually(KameletBindingConditionStatus(ns, name, v1alpha1.KameletBindingConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
+	})
+
+	t.Run("Scale kamelet binding with polymorphic client", func(t *testing.T) {
+		scaleClient, err := TestClient().ScalesClient()
+		Expect(err).To(BeNil())
+
+		// Patch the integration scale subresource
+		patch := "{\"spec\":{\"replicas\":2}}"
+		_, err = scaleClient.Scales(ns).Patch(TestContext, v1alpha1.SchemeGroupVersion.WithResource("kameletbindings"), name, types.MergePatchType, []byte(patch), metav1.PatchOptions{})
+		Expect(err).To(BeNil())
+
+		// Check the readiness condition is still truthy as down-scaling
+		Expect(KameletBindingConditionStatus(ns, name, v1alpha1.KameletBindingConditionReady)()).To(Equal(corev1.ConditionTrue))
+		// Check the Integration scale subresource Spec field
+		Eventually(IntegrationSpecReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 2)))
+		// Then check it cascades into the Deployment scale
+		Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(2))
+		// Check it cascades into the Integration scale subresource Status field
+		Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 2)))
+		// Finally check it cascades into the KameletBinding scale subresource Status field
+		Eventually(KameletBindingStatusReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 2)))
+	})
+
+	t.Run("Scale kamelet binding with Camel K client", func(t *testing.T) {
+		camel, err := versioned.NewForConfig(TestClient().GetConfig())
+		Expect(err).To(BeNil())
+
+		// Getter
+		bindingScale, err := camel.CamelV1alpha1().KameletBindings(ns).GetScale(TestContext, name, metav1.GetOptions{})
+		Expect(err).To(BeNil())
+		Expect(bindingScale.Spec.Replicas).To(BeNumerically("==", 2))
+		Expect(bindingScale.Status.Replicas).To(BeNumerically("==", 2))
+
+		// Setter
+		bindingScale.Spec.Replicas = 1
+		_, err = camel.CamelV1alpha1().KameletBindings(ns).UpdateScale(TestContext, name, bindingScale, metav1.UpdateOptions{})
+		Expect(err).To(BeNil())
+
+		// Check the readiness condition is still truthy as down-scaling in kamelet binding
+		Expect(KameletBindingConditionStatus(ns, name, v1alpha1.KameletBindingConditionReady)()).To(Equal(corev1.ConditionTrue))
+		// Check the KameletBinding scale subresource Spec field
+		Eventually(KameletBindingSpecReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 1)))
+		// Check the readiness condition is still truthy as down-scaling
+		Expect(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady)()).To(Equal(corev1.ConditionTrue))
+		// Check the Integration scale subresource Spec field
+		Eventually(IntegrationSpecReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 1)))
+		// Then check it cascades into the Deployment scale
+		Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(1))
+		// Finally check it cascades into the Integration scale subresource Status field
+		Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 1)))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/common/misc/scale_integration_test.go b/e2e/common/misc/scale_integration_test.go
new file mode 100644
index 000000000..c2d165311
--- /dev/null
+++ b/e2e/common/misc/scale_integration_test.go
@@ -0,0 +1,131 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package misc
+
+import (
+	"fmt"
+	"testing"
+
+	. "github.com/onsi/gomega"
+	"github.com/onsi/gomega/gstruct"
+
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	"github.com/apache/camel-k/pkg/client/camel/clientset/versioned"
+)
+
+func TestIntegrationScale(t *testing.T) {
+	RegisterTestingT(t)
+
+	name := "java"
+	Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed())
+	Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+	Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+	Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+	t.Run("Update integration scale spec", func(t *testing.T) {
+		RegisterTestingT(t)
+		Expect(ScaleIntegration(ns, name, 3)).To(Succeed())
+		// Check the readiness condition becomes falsy
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse))
+		// Check the scale cascades into the Deployment scale
+		Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(3))
+		// Check it also cascades into the Integration scale subresource Status field
+		Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 3)))
+		// Finally check the readiness condition becomes truthy back
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
+	})
+
+	t.Run("Scale integration with polymorphic client", func(t *testing.T) {
+		scaleClient, err := TestClient().ScalesClient()
+		Expect(err).To(BeNil())
+
+		// Patch the integration scale subresource
+		patch := "{\"spec\":{\"replicas\":2}}"
+		_, err = scaleClient.Scales(ns).Patch(TestContext, v1.SchemeGroupVersion.WithResource("integrations"), name, types.MergePatchType, []byte(patch), metav1.PatchOptions{})
+		Expect(err).To(BeNil())
+
+		// Check the readiness condition is still truthy as down-scaling
+		Expect(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady)()).To(Equal(corev1.ConditionTrue))
+		// Check the Integration scale subresource Spec field
+		Eventually(IntegrationSpecReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 2)))
+		// Then check it cascades into the Deployment scale
+		Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(2))
+		// Finally check it cascades into the Integration scale subresource Status field
+		Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 2)))
+	})
+
+	t.Run("Scale integration with Camel K client", func(t *testing.T) {
+		camel, err := versioned.NewForConfig(TestClient().GetConfig())
+		Expect(err).To(BeNil())
+
+		// Getter
+		integrationScale, err := camel.CamelV1().Integrations(ns).GetScale(TestContext, name, metav1.GetOptions{})
+		Expect(err).To(BeNil())
+		Expect(integrationScale.Spec.Replicas).To(BeNumerically("==", 2))
+		Expect(integrationScale.Status.Replicas).To(BeNumerically("==", 2))
+
+		// Setter
+		integrationScale.Spec.Replicas = 1
+		integrationScale, err = camel.CamelV1().Integrations(ns).UpdateScale(TestContext, name, integrationScale, metav1.UpdateOptions{})
+		Expect(err).To(BeNil())
+
+		// Check the readiness condition is still truthy as down-scaling
+		Expect(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady)()).To(Equal(corev1.ConditionTrue))
+		// Check the Integration scale subresource Spec field
+		Eventually(IntegrationSpecReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 1)))
+		// Then check it cascades into the Deployment scale
+		Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(1))
+		// Finally check it cascades into the Integration scale subresource Status field
+		Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
+			Should(gstruct.PointTo(BeNumerically("==", 1)))
+	})
+
+	t.Run("Scale integration with external image", func(t *testing.T) {
+		image := IntegrationPodImage(ns, name)()
+		Expect(image).NotTo(BeEmpty())
+		// Save resources by deleting the integration
+		Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed())
+
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", "pre-built", "-t", fmt.Sprintf("container.image=%s", image)).Execute()).To(Succeed())
+		Eventually(IntegrationPhase(ns, "pre-built"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning))
+		Eventually(IntegrationPodPhase(ns, "pre-built"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Expect(ScaleIntegration(ns, "pre-built", 0)).To(Succeed())
+		Eventually(IntegrationPod(ns, "pre-built"), TestTimeoutMedium).Should(BeNil())
+		Expect(ScaleIntegration(ns, "pre-built", 1)).To(Succeed())
+		Eventually(IntegrationPhase(ns, "pre-built"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning))
+		Eventually(IntegrationPodPhase(ns, "pre-built"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+
+		Expect(Kamel("delete", "pre-built", "-n", ns).Execute()).To(Succeed())
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/global/common/build/maven_repository_test.go b/e2e/common/misc/structured_logs_test.go
similarity index 51%
copy from e2e/global/common/build/maven_repository_test.go
copy to e2e/common/misc/structured_logs_test.go
index 7cee488b7..5fe26f631 100644
--- a/e2e/global/common/build/maven_repository_test.go
+++ b/e2e/common/misc/structured_logs_test.go
@@ -20,9 +20,10 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package build
+package misc
 
 import (
+	"fmt"
 	"testing"
 
 	. "github.com/onsi/gomega"
@@ -33,21 +34,31 @@ import (
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 )
 
-func TestRunExtraRepository(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-extra-repository"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		name := "java"
-		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-			"--maven-repository", "https://maven.repository.redhat.com/ga@id=redhat",
-			"--dependency", "mvn:jakarta.annotation:jakarta.annotation-api:1.3.5.redhat-00002",
-			"--name", name,
-		).Execute()).To(Succeed())
-
-		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-	})
+func TestStructuredLogs(t *testing.T) {
+	RegisterTestingT(t)
+
+	name := "java"
+	Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+		"-t", "logging.format=json").Execute()).To(Succeed())
+	Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+	Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+
+	pod := OperatorPod(ns)()
+	Expect(pod).NotTo(BeNil())
+
+	// pod.Namespace could be different from ns if using global operator
+	fmt.Printf("Fetching logs for operator pod %s in namespace %s", pod.Name, pod.Namespace)
+	logOptions := &corev1.PodLogOptions{
+		Container: "camel-k-operator",
+	}
+	logs, err := StructuredLogs(pod.Namespace, pod.Name, logOptions, false)
+	Expect(err).To(BeNil())
+	Expect(logs).NotTo(BeEmpty())
+
+	it := Integration(ns, name)()
+	Expect(it).NotTo(BeNil())
+	build := Build(ns, it.Status.IntegrationKit.Name)()
+	Expect(build).NotTo(BeNil())
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/global/common/tekton_test.go b/e2e/common/misc/tekton_test.go
similarity index 56%
rename from e2e/global/common/tekton_test.go
rename to e2e/common/misc/tekton_test.go
index 7b893c509..934564777 100644
--- a/e2e/global/common/tekton_test.go
+++ b/e2e/common/misc/tekton_test.go
@@ -20,10 +20,9 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package misc
 
 import (
-	"os"
 	"testing"
 
 	. "github.com/onsi/gomega"
@@ -33,31 +32,17 @@ import (
 
 // TestTektonLikeBehavior verifies that the kamel binary can be invoked from within the Camel K image.
 // This feature is used in Tekton pipelines.
-
-/*
- * TODO
- * Test has issues on OCP4.
- * Since that cluster installs via OLM, permissions are required for the
- * service account doing the install to access the OLM, eg. get:subscriptions.
- *
- * Need to change the service account used to execute this test as do not
- * want to extend the permissions of the operator service account
- *
- * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment.
- */
 func TestTektonLikeBehavior(t *testing.T) {
-	if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" {
-		t.Skip("WARNING: Test marked as problematic ... skipping")
-	}
+	RegisterTestingT(t)
+
+	Expect(CreateOperatorServiceAccount(ns)).To(Succeed())
+	Expect(CreateOperatorRole(ns)).To(Succeed())
+	Expect(CreateOperatorRoleBinding(ns)).To(Succeed())
 
-	WithNewTestNamespace(t, func(ns string) {
-		Expect(CreateOperatorServiceAccount(ns)).To(Succeed())
-		Expect(CreateOperatorRole(ns)).To(Succeed())
-		Expect(CreateOperatorRoleBinding(ns)).To(Succeed())
+	Eventually(OperatorPod(ns)).Should(BeNil())
+	Expect(CreateKamelPod(ns, "tekton-task", "install", "--skip-cluster-setup", "--force")).To(Succeed())
 
-		Eventually(OperatorPod(ns)).Should(BeNil())
-		Expect(CreateKamelPod(ns, "tekton-task", "install", "--skip-cluster-setup", "--force")).To(Succeed())
+	Eventually(OperatorPod(ns)).ShouldNot(BeNil())
 
-		Eventually(OperatorPod(ns)).ShouldNot(BeNil())
-	})
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/namespace/native/native_test_support.go b/e2e/common/startup_test.go
similarity index 66%
copy from e2e/namespace/native/native_test_support.go
copy to e2e/common/startup_test.go
index acd37558b..749f26d4c 100644
--- a/e2e/namespace/native/native_test_support.go
+++ b/e2e/common/startup_test.go
@@ -20,25 +20,28 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package native
+package common
 
 import (
+	"os"
+	"testing"
+
+	. "github.com/onsi/gomega"
 	corev1 "k8s.io/api/core/v1"
-	"strings"
 
 	. "github.com/apache/camel-k/e2e/support"
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 )
 
-var (
-	withFastJarLayout = KitWithLabels(map[string]string{v1.IntegrationKitLayoutLabel: v1.IntegrationKitLayoutFastJar})
-	withNativeLayout  = KitWithLabels(map[string]string{v1.IntegrationKitLayoutLabel: v1.IntegrationKitLayoutNative})
-)
-
-func getContainerCommand() func(pod *corev1.Pod) string {
-	return func(pod *corev1.Pod) string {
-		cmd := strings.Join(pod.Spec.Containers[0].Command, " ")
-		cmd = cmd + strings.Join(pod.Spec.Containers[0].Args, " ")
-		return cmd
-	}
+func TestDefaultCamelKInstallStartup(t *testing.T) {
+	RegisterTestingT(t)
+
+	ns := "camel-k-test-integration"
+	os.Setenv("CAMEL_K_TEST_NS", ns)
+	Expect(NewTestNamespace(false)).ShouldNot(BeNil())
+	Expect(KamelInstallWithID(ns, ns).Execute()).To(Succeed())
+	Eventually(OperatorPod(ns)).ShouldNot(BeNil())
+	Eventually(Platform(ns)).ShouldNot(BeNil())
+	Eventually(PlatformConditionStatus(ns, v1.IntegrationPlatformConditionReady), TestTimeoutShort).
+		Should(Equal(corev1.ConditionTrue))
 }
diff --git a/e2e/global/common/doc.go b/e2e/common/teardown_test.go
similarity index 78%
rename from e2e/global/common/doc.go
rename to e2e/common/teardown_test.go
index 9677808e3..76de53797 100644
--- a/e2e/global/common/doc.go
+++ b/e2e/common/teardown_test.go
@@ -20,5 +20,20 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-// Package common contains common e2e tests whose outcome does not depend on the builder that has been used, thus they that can be executed with a single builder in the CI
 package common
+
+import (
+	"os"
+	"testing"
+
+	. "github.com/onsi/gomega"
+
+	. "github.com/apache/camel-k/e2e/support"
+)
+
+func TestDefaultCamelKInstallTeardown(t *testing.T) {
+	RegisterTestingT(t)
+
+	ns := os.Getenv("CAMEL_K_TEST_NS")
+	Expect(DeleteNamespace(t, ns)).To(Succeed())
+}
diff --git a/e2e/common/traits/affinity_test.go b/e2e/common/traits/affinity_test.go
new file mode 100644
index 000000000..76013d2e0
--- /dev/null
+++ b/e2e/common/traits/affinity_test.go
@@ -0,0 +1,152 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package traits
+
+import (
+	"fmt"
+	"testing"
+
+	. "github.com/onsi/gomega"
+
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+func TestAffinityTrait(t *testing.T) {
+	RegisterTestingT(t)
+
+	var hostname string
+	if node, err := selectSchedulableNode(); err == nil {
+		hostname = node.Labels["kubernetes.io/hostname"]
+	} else {
+		// if 'get nodes' is not allowed, just skip tests for node affinity
+		hostname = ""
+	}
+
+	if hostname != "" {
+		t.Run("Run Java with node affinity", func(t *testing.T) {
+			Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+				"--name", "java1",
+				"-t", "affinity.enabled=true",
+				"-t", fmt.Sprintf("affinity.node-affinity-labels=kubernetes.io/hostname in(%s)", hostname)).Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, "java1"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, "java1", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, "java1"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+			pod := IntegrationPod(ns, "java1")()
+			Expect(pod.Spec.Affinity).NotTo(BeNil())
+			Expect(pod.Spec.Affinity.NodeAffinity).To(Equal(&corev1.NodeAffinity{
+				RequiredDuringSchedulingIgnoredDuringExecution: nodeSelector("kubernetes.io/hostname", corev1.NodeSelectorOpIn, hostname),
+			}))
+			Expect(pod.Spec.NodeName).To(Equal(hostname))
+
+			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		})
+	}
+
+	t.Run("Run Java with pod affinity", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", "java2",
+			"-t", "affinity.enabled=true",
+			"-t", "affinity.pod-affinity-labels=camel.apache.org/integration").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "java2"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "java2", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "java2"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		pod := IntegrationPod(ns, "java2")()
+		Expect(pod.Spec.Affinity).NotTo(BeNil())
+		Expect(pod.Spec.Affinity.PodAffinity).To(Equal(&corev1.PodAffinity{
+			RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{
+				podAffinityTerm("camel.apache.org/integration", metav1.LabelSelectorOpExists, "kubernetes.io/hostname"),
+			},
+		}))
+
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("Run Java with pod anti affinity", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", "java3",
+			"-t", "affinity.enabled=true",
+			"-t", "affinity.pod-anti-affinity-labels=camel.apache.org/integration").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "java3"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "java3", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "java3"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		pod := IntegrationPod(ns, "java3")()
+		Expect(pod.Spec.Affinity).NotTo(BeNil())
+		Expect(pod.Spec.Affinity.PodAntiAffinity).To(Equal(&corev1.PodAntiAffinity{
+			RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{
+				podAffinityTerm("camel.apache.org/integration", metav1.LabelSelectorOpExists, "kubernetes.io/hostname"),
+			},
+		}))
+
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+}
+
+func selectSchedulableNode() (*corev1.Node, error) {
+	nodes, err := TestClient().CoreV1().Nodes().List(TestContext, metav1.ListOptions{})
+	if err != nil {
+		return nil, err
+	}
+	for _, node := range nodes.Items {
+		if node.Spec.Taints == nil {
+			return &node, nil
+		}
+	}
+	return nil, fmt.Errorf("no node available")
+}
+
+func nodeSelector(key string, operator corev1.NodeSelectorOperator, value string) *corev1.NodeSelector {
+	return &corev1.NodeSelector{
+		NodeSelectorTerms: []corev1.NodeSelectorTerm{
+			{
+				MatchExpressions: []corev1.NodeSelectorRequirement{
+					{
+						Key:      key,
+						Operator: operator,
+						Values:   []string{value},
+					},
+				},
+			},
+		},
+	}
+}
+
+func podAffinityTerm(key string, operator metav1.LabelSelectorOperator, topologyKey string) corev1.PodAffinityTerm {
+	return corev1.PodAffinityTerm{
+		LabelSelector: &metav1.LabelSelector{
+			MatchExpressions: []metav1.LabelSelectorRequirement{
+				{
+					Key:      key,
+					Operator: operator,
+				},
+			},
+		},
+		TopologyKey: topologyKey,
+	}
+}
diff --git a/e2e/common/traits/container_test.go b/e2e/common/traits/container_test.go
new file mode 100644
index 000000000..ba66b1fb6
--- /dev/null
+++ b/e2e/common/traits/container_test.go
@@ -0,0 +1,100 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package traits
+
+import (
+	"testing"
+
+	. "github.com/onsi/gomega"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+func TestContainerTrait(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("Container image pull policy and resources configuration", func(t *testing.T) {
+		name := "java1"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"-t", "container.image-pull-policy=Always",
+			"-t", "container.request-cpu=0.005",
+			"-t", "container.request-memory=100Mi",
+			"-t", "container.limit-cpu=200m",
+			"-t", "container.limit-memory=500Mi",
+			"--name", name,
+		).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool {
+			if len(pod.Spec.Containers) != 1 {
+				return false
+			}
+			imagePullPolicy := pod.Spec.Containers[0].ImagePullPolicy
+			return imagePullPolicy == "Always"
+		}), TestTimeoutShort).Should(BeTrue())
+		Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool {
+			if len(pod.Spec.Containers) != 1 {
+				return false
+			}
+			limitsCpu := pod.Spec.Containers[0].Resources.Limits.Cpu()
+			requestsCpu := pod.Spec.Containers[0].Resources.Requests.Cpu()
+			return limitsCpu != nil && limitsCpu.String() == "200m" && requestsCpu != nil && requestsCpu.String() == "5m"
+		}), TestTimeoutShort).Should(BeTrue())
+		Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool {
+			if len(pod.Spec.Containers) != 1 {
+				return false
+			}
+			limitsMemory := pod.Spec.Containers[0].Resources.Limits.Memory()
+			requestsMemory := pod.Spec.Containers[0].Resources.Requests.Memory()
+			return limitsMemory != nil && limitsMemory.String() == "500Mi" && requestsMemory != nil && requestsMemory.String() == "100Mi"
+		}), TestTimeoutShort).Should(BeTrue())
+
+	})
+
+	t.Run("Container name", func(t *testing.T) {
+		name := "java2"
+		containerName := "my-container-name"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"-t", "container.name="+containerName,
+			"--name", name,
+		).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool {
+			if len(pod.Spec.Containers) != 1 {
+				return false
+			}
+			podContainerName := pod.Spec.Containers[0].Name
+			return podContainerName == containerName
+		}), TestTimeoutShort).Should(BeTrue())
+
+	})
+
+	// Clean-up
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/global/knative/doc.go b/e2e/common/traits/default.go
similarity index 79%
rename from e2e/global/knative/doc.go
rename to e2e/common/traits/default.go
index 6fe4069e4..64e0abe67 100644
--- a/e2e/global/knative/doc.go
+++ b/e2e/common/traits/default.go
@@ -1,8 +1,6 @@
 //go:build integration
 // +build integration
 
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
 /*
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
@@ -20,5 +18,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-// Package knative contains Knative related e2e tests
-package knative
+package traits
+
+const ns = "camel-k-test-integration"
+const operatorID = "camel-k-test-integration"
diff --git a/e2e/common/traits/deployment_test.go b/e2e/common/traits/deployment_test.go
new file mode 100644
index 000000000..3bedae5cb
--- /dev/null
+++ b/e2e/common/traits/deployment_test.go
@@ -0,0 +1,93 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package traits
+
+import (
+	appsv1 "k8s.io/api/apps/v1"
+	"testing"
+
+	. "github.com/onsi/gomega"
+	. "github.com/onsi/gomega/gstruct"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+func TestRecreateDeploymentStrategyTrait(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("Run with Recreate Deployment Strategy", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"-t", "deployment.strategy="+string(appsv1.RecreateDeploymentStrategyType)).
+			Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		Eventually(Deployment(ns, "java"), TestTimeoutMedium).Should(PointTo(MatchFields(IgnoreExtras,
+			Fields{
+				"Spec": MatchFields(IgnoreExtras,
+					Fields{
+						"Strategy": MatchFields(IgnoreExtras,
+							Fields{
+								"Type": Equal(appsv1.RecreateDeploymentStrategyType),
+							}),
+					}),
+			}),
+		))
+
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
+
+func TestRollingUpdateDeploymentStrategyTrait(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("Run with RollingUpdate Deployment Strategy", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"-t", "deployment.strategy="+string(appsv1.RollingUpdateDeploymentStrategyType)).
+			Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		Eventually(Deployment(ns, "java"), TestTimeoutMedium).Should(PointTo(MatchFields(IgnoreExtras,
+			Fields{
+				"Spec": MatchFields(IgnoreExtras,
+					Fields{
+						"Strategy": MatchFields(IgnoreExtras,
+							Fields{
+								"Type": Equal(appsv1.RollingUpdateDeploymentStrategyType),
+							}),
+					}),
+			}),
+		))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/global/common/build/maven_repository_test.go b/e2e/common/traits/error_handler_test.go
similarity index 64%
rename from e2e/global/common/build/maven_repository_test.go
rename to e2e/common/traits/error_handler_test.go
index 7cee488b7..0542682b9 100644
--- a/e2e/global/common/build/maven_repository_test.go
+++ b/e2e/common/traits/error_handler_test.go
@@ -20,7 +20,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package build
+package traits
 
 import (
 	"testing"
@@ -33,21 +33,21 @@ import (
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 )
 
-func TestRunExtraRepository(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-extra-repository"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
+func TestErrorHandlerTrait(t *testing.T) {
+	RegisterTestingT(t)
 
-		name := "java"
-		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-			"--maven-repository", "https://maven.repository.redhat.com/ga@id=redhat",
-			"--dependency", "mvn:jakarta.annotation:jakarta.annotation-api:1.3.5.redhat-00002",
+	t.Run("Run errored integration with error handler", func(t *testing.T) {
+		name := "error-handler"
+		Expect(KamelRunWithID(operatorID, ns, "files/ErroredRoute.java",
 			"--name", name,
+			"-t", "error-handler.enabled=true",
+			"-t", "error-handler.ref=defaultErrorHandler",
+			"-p", "camel.beans.defaultErrorHandler=#class:org.apache.camel.builder.DeadLetterChannelBuilder",
+			"-p", "camel.beans.defaultErrorHandler.deadLetterUri=log:my-special-error-handler-in-place?level=ERROR&showCaughtException=false&showBody=false&showBodyType=false&showExchangePattern=false",
 		).Execute()).To(Succeed())
-
 		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
 		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).ShouldNot(ContainSubstring("InvalidPayloadException"))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("my-special-error-handler-in-place"))
 	})
 }
diff --git a/e2e/common/traits/errored_trait_test.go b/e2e/common/traits/errored_trait_test.go
new file mode 100644
index 000000000..0a17c6535
--- /dev/null
+++ b/e2e/common/traits/errored_trait_test.go
@@ -0,0 +1,79 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package traits
+
+import (
+	"testing"
+
+	. "github.com/onsi/gomega"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+)
+
+func TestErroredTrait(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("Integration trait should fail", func(t *testing.T) {
+		name := "it-errored"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", name,
+			"-t", "kamelets.list=missing",
+		).Execute()).To(Succeed())
+		Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse))
+		Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And(
+			WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)),
+			WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")),
+		))
+	})
+
+	t.Run("KameletBinding trait should fail", func(t *testing.T) {
+		name := "kb-errored"
+		Expect(KamelBindWithID(operatorID, ns, "timer:foo", "log:bar",
+			"--name", name,
+			"-t", "kamelets.list=missing",
+		).Execute()).To(Succeed())
+		// KameletBinding
+		Eventually(KameletBindingPhase(ns, name), TestTimeoutShort).Should(Equal(v1alpha1.KameletBindingPhaseError))
+		Eventually(KameletBindingConditionStatus(ns, name, v1alpha1.KameletBindingConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse))
+		Eventually(KameletBindingCondition(ns, name, v1alpha1.KameletBindingConditionReady), TestTimeoutShort).Should(
+			WithTransform(KameletBindingConditionMessage, And(
+				ContainSubstring("error during trait customization"),
+				ContainSubstring("[missing] not found"),
+			)))
+		// Integration related
+		Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse))
+		Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And(
+			WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)),
+			WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")),
+		))
+	})
+
+	// Clean up
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/global/common/traits/files/ErroredRoute.java b/e2e/common/traits/files/ErroredRoute.java
similarity index 100%
rename from e2e/global/common/traits/files/ErroredRoute.java
rename to e2e/common/traits/files/ErroredRoute.java
diff --git a/e2e/global/common/traits/files/Java.java b/e2e/common/traits/files/Java.java
similarity index 100%
rename from e2e/global/common/traits/files/Java.java
rename to e2e/common/traits/files/Java.java
diff --git a/e2e/global/common/traits/files/Master.java b/e2e/common/traits/files/Master.java
similarity index 100%
rename from e2e/global/common/traits/files/Master.java
rename to e2e/common/traits/files/Master.java
diff --git a/e2e/global/common/traits/files/NeverReady.java b/e2e/common/traits/files/NeverReady.java
similarity index 100%
rename from e2e/global/common/traits/files/NeverReady.java
rename to e2e/common/traits/files/NeverReady.java
diff --git a/e2e/global/common/traits/files/PlatformHttpServer.java b/e2e/common/traits/files/PlatformHttpServer.java
similarity index 100%
rename from e2e/global/common/traits/files/PlatformHttpServer.java
rename to e2e/common/traits/files/PlatformHttpServer.java
diff --git a/e2e/global/common/traits/files/PodTest.groovy b/e2e/common/traits/files/PodTest.groovy
similarity index 100%
rename from e2e/global/common/traits/files/PodTest.groovy
rename to e2e/common/traits/files/PodTest.groovy
diff --git a/e2e/global/service-binding/files/ServiceBinding.java b/e2e/common/traits/files/ServiceBinding.java
similarity index 100%
rename from e2e/global/service-binding/files/ServiceBinding.java
rename to e2e/common/traits/files/ServiceBinding.java
diff --git a/e2e/global/common/traits/files/jvm/Classpath.java b/e2e/common/traits/files/jvm/Classpath.java
similarity index 100%
rename from e2e/global/common/traits/files/jvm/Classpath.java
rename to e2e/common/traits/files/jvm/Classpath.java
diff --git a/e2e/global/common/traits/files/jvm/sample-1.0.jar b/e2e/common/traits/files/jvm/sample-1.0.jar
similarity index 100%
rename from e2e/global/common/traits/files/jvm/sample-1.0.jar
rename to e2e/common/traits/files/jvm/sample-1.0.jar
diff --git a/e2e/global/common/traits/files/openapi/petstore-api.yaml b/e2e/common/traits/files/openapi/petstore-api.yaml
similarity index 100%
rename from e2e/global/common/traits/files/openapi/petstore-api.yaml
rename to e2e/common/traits/files/openapi/petstore-api.yaml
diff --git a/e2e/global/common/traits/files/openapi/petstore.groovy b/e2e/common/traits/files/openapi/petstore.groovy
similarity index 100%
rename from e2e/global/common/traits/files/openapi/petstore.groovy
rename to e2e/common/traits/files/openapi/petstore.groovy
diff --git a/e2e/global/common/traits/files/template-with-supplemental-groups.yaml b/e2e/common/traits/files/template-with-supplemental-groups.yaml
similarity index 100%
rename from e2e/global/common/traits/files/template-with-supplemental-groups.yaml
rename to e2e/common/traits/files/template-with-supplemental-groups.yaml
diff --git a/e2e/global/common/traits/files/template.yaml b/e2e/common/traits/files/template.yaml
similarity index 100%
rename from e2e/global/common/traits/files/template.yaml
rename to e2e/common/traits/files/template.yaml
diff --git a/e2e/common/traits/health_test.go b/e2e/common/traits/health_test.go
new file mode 100644
index 000000000..5f225b8ae
--- /dev/null
+++ b/e2e/common/traits/health_test.go
@@ -0,0 +1,328 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package traits
+
+import (
+	"encoding/json"
+	"fmt"
+	camelv1alpha1 "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
+	"testing"
+	"time"
+
+	. "github.com/onsi/gomega"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+func TestHealthTrait(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("Readiness condition with stopped route", func(t *testing.T) {
+		name := "java"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"-t", "health.enabled=true",
+			// Enable Jolokia for the test to stop the Camel route
+			"-t", "jolokia.enabled=true",
+			"-t", "jolokia.use-ssl-client-authentication=false",
+			"-t", "jolokia.protocol=http",
+		).Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+			Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		pod := IntegrationPod(ns, name)()
+
+		// Stop the Camel route
+		request := map[string]string{
+			"type":      "exec",
+			"mbean":     "org.apache.camel:context=camel-1,name=\"route1\",type=routes",
+			"operation": "stop()",
+		}
+		body, err := json.Marshal(request)
+		Expect(err).To(BeNil())
+
+		response, err := TestClient().CoreV1().RESTClient().Post().
+			AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod.Name)).
+			Body(body).
+			DoRaw(TestContext)
+		Expect(err).To(BeNil())
+		Expect(response).To(ContainSubstring(`"status":200`))
+
+		// Check the ready condition has turned false
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+			Should(Equal(corev1.ConditionFalse))
+		// And it contains details about the runtime state
+
+		//
+		// TODO
+		// Integration has different runtime state reporting on OCP4
+		//
+		// lastProbeTime: null
+		// lastTransitionTime: "2021-12-08T20:12:14Z"
+		// message: 'containers with unready status: [integration]'
+		// reason: ContainersNotReady
+		// status: "False"
+		// type: Ready
+		//
+		Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And(
+			WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)),
+			WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready"))))
+
+		Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(
+			Satisfy(func(c *v1.IntegrationCondition) bool {
+				if c.Status != corev1.ConditionFalse {
+					return false
+				}
+				if len(c.Pods) != 1 {
+					return false
+				}
+
+				var r *v1.HealthCheckResponse
+
+				for h := range c.Pods[0].Health {
+					if c.Pods[0].Health[h].Name == "camel-routes" {
+						r = &c.Pods[0].Health[h]
+					}
+				}
+
+				if r == nil {
+					return false
+				}
+
+				if r.Data == nil {
+					return false
+				}
+
+				var data map[string]interface{}
+				if err := json.Unmarshal(r.Data, &data); err != nil {
+					return false
+				}
+
+				return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped"
+			}))
+
+		Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
+
+		// Clean-up
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("Readiness condition with stopped binding", func(t *testing.T) {
+		name := "stopped-binding"
+
+		Expect(CreateTimerKamelet(ns, "my-own-timer-source")()).To(Succeed())
+		Expect(CreateLogKamelet(ns, "my-own-log-sink")()).To(Succeed())
+
+		from := corev1.ObjectReference{
+			Kind:       "Kamelet",
+			Name:       "my-own-timer-source",
+			APIVersion: camelv1alpha1.SchemeGroupVersion.String(),
+		}
+
+		fromParams := map[string]string{
+			"message": "Magicstring!",
+		}
+
+		to := corev1.ObjectReference{
+			Kind:       "Kamelet",
+			Name:       "my-own-log-sink",
+			APIVersion: camelv1alpha1.SchemeGroupVersion.String(),
+		}
+
+		toParams := map[string]string{
+			"loggerName": "binding",
+		}
+
+		annotations := map[string]string{
+			"trait.camel.apache.org/health.enabled":                        "true",
+			"trait.camel.apache.org/jolokia.enabled":                       "true",
+			"trait.camel.apache.org/jolokia.use-ssl-client-authentication": "false",
+			"trait.camel.apache.org/jolokia.protocol":                      "http",
+		}
+
+		Expect(BindKameletTo(ns, name, annotations, from, to, fromParams, toParams)()).
+			To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		pod := IntegrationPod(ns, name)()
+
+		// Stop the Camel route
+		request := map[string]string{
+			"type":      "exec",
+			"mbean":     "org.apache.camel:context=camel-1,name=\"binding\",type=routes",
+			"operation": "stop()",
+		}
+		body, err := json.Marshal(request)
+		Expect(err).To(BeNil())
+
+		response, err := TestClient().CoreV1().RESTClient().Post().
+			AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod.Name)).
+			Body(body).
+			DoRaw(TestContext)
+
+		Expect(err).To(BeNil())
+		Expect(response).To(ContainSubstring(`"status":200`))
+
+		// Check the ready condition has turned false
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
+			Should(Equal(corev1.ConditionFalse))
+		// And it contains details about the runtime state
+
+		Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And(
+			WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)),
+			WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready"))))
+
+		Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(
+			Satisfy(func(c *v1.IntegrationCondition) bool {
+				if c.Status != corev1.ConditionFalse {
+					return false
+				}
+				if len(c.Pods) != 1 {
+					return false
+				}
+
+				var r *v1.HealthCheckResponse
+
+				for h := range c.Pods[0].Health {
+					if c.Pods[0].Health[h].Name == "camel-routes" {
+						r = &c.Pods[0].Health[h]
+					}
+				}
+
+				if r == nil {
+					return false
+				}
+
+				if r.Data == nil {
+					return false
+				}
+
+				var data map[string]interface{}
+				if err := json.Unmarshal(r.Data, &data); err != nil {
+					return false
+				}
+
+				return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "binding"
+			}))
+
+		Eventually(KameletBindingCondition(ns, name, camelv1alpha1.KameletBindingConditionReady), TestTimeoutLong).Should(
+			Satisfy(func(c *camelv1alpha1.KameletBindingCondition) bool {
+				if c.Status != corev1.ConditionFalse {
+					return false
+				}
+				if len(c.Pods) != 1 {
+					return false
+				}
+
+				var r *v1.HealthCheckResponse
+
+				for h := range c.Pods[0].Health {
+					if c.Pods[0].Health[h].Name == "camel-routes" {
+						r = &c.Pods[0].Health[h]
+					}
+				}
+
+				if r == nil {
+					return false
+				}
+
+				if r.Data == nil {
+					return false
+				}
+
+				var data map[string]interface{}
+				if err := json.Unmarshal(r.Data, &data); err != nil {
+					return false
+				}
+
+				return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "binding"
+			}))
+
+		// Clean-up
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("Readiness condition with never ready route", func(t *testing.T) {
+		name := "never-ready"
+
+		Expect(KamelRunWithID(operatorID, ns, "files/NeverReady.java",
+			"-t", "health.enabled=true",
+		).Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning))
+		Consistently(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), 1*time.Minute).
+			Should(Equal(corev1.ConditionFalse))
+		Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError))
+
+		// Check that the error message is propagated from health checks even if deployment never becomes ready
+		Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And(
+			WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)),
+			WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready"))))
+
+		Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(
+			Satisfy(func(c *v1.IntegrationCondition) bool {
+				if c.Status != corev1.ConditionFalse {
+					return false
+				}
+				if len(c.Pods) != 1 {
+					return false
+				}
+
+				var r *v1.HealthCheckResponse
+
+				for h := range c.Pods[0].Health {
+					if c.Pods[0].Health[h].Name == "camel-routes" {
+						r = &c.Pods[0].Health[h]
+					}
+				}
+
+				if r == nil {
+					return false
+				}
+
+				if r.Data == nil {
+					return false
+				}
+
+				var data map[string]interface{}
+				if err := json.Unmarshal(r.Data, &data); err != nil {
+					return false
+				}
+
+				return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "never-ready"
+			}))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/global/common/traits/istio_test.go b/e2e/common/traits/istio_test.go
similarity index 52%
rename from e2e/global/common/traits/istio_test.go
rename to e2e/common/traits/istio_test.go
index c3a640adf..7e0fd5cf4 100644
--- a/e2e/global/common/traits/istio_test.go
+++ b/e2e/common/traits/istio_test.go
@@ -34,24 +34,22 @@ import (
 )
 
 func TestIstioTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-istio"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("Run Java with Istio", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-				"-t", "istio.enabled=true").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-			pod := IntegrationPod(ns, "java")()
-			Expect(pod.ObjectMeta.Annotations).NotTo(BeNil())
-			annotations := pod.ObjectMeta.Annotations
-			Expect(annotations["sidecar.istio.io/inject"]).To(Equal("true"))
-			Expect(annotations["traffic.sidecar.istio.io/includeOutboundIPRanges"]).To(Equal("10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"))
-
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
+	RegisterTestingT(t)
+
+	t.Run("Run Java with Istio", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"-t", "istio.enabled=true").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		pod := IntegrationPod(ns, "java")()
+		Expect(pod.ObjectMeta.Annotations).NotTo(BeNil())
+		annotations := pod.ObjectMeta.Annotations
+		Expect(annotations["sidecar.istio.io/inject"]).To(Equal("true"))
+		Expect(annotations["traffic.sidecar.istio.io/includeOutboundIPRanges"]).To(Equal("10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"))
+
 	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/global/common/structured_logs_test.go b/e2e/common/traits/jolokia_test.go
similarity index 51%
rename from e2e/global/common/structured_logs_test.go
rename to e2e/common/traits/jolokia_test.go
index dde73f87e..ddaf981e1 100644
--- a/e2e/global/common/structured_logs_test.go
+++ b/e2e/common/traits/jolokia_test.go
@@ -20,7 +20,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package common
+package traits
 
 import (
 	"fmt"
@@ -34,34 +34,27 @@ import (
 	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
 )
 
-func TestStructuredLogs(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		name := "java"
-		operatorID := "camel-k-logging"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-			"-t", "logging.format=json").Execute()).To(Succeed())
-		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-
-		pod := OperatorPod(ns)()
-		Expect(pod).NotTo(BeNil())
+func TestJolokiaTrait(t *testing.T) {
+	RegisterTestingT(t)
 
-		// pod.Namespace could be different from ns if using global operator
-		fmt.Printf("Fetching logs for operator pod %s in namespace %s", pod.Name, pod.Namespace)
-		logOptions := &corev1.PodLogOptions{
-			Container: "camel-k-operator",
-		}
-		logs, err := StructuredLogs(pod.Namespace, pod.Name, logOptions, false)
+	t.Run("Run Java with Jolokia", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"-t", "jolokia.enabled=true",
+			"-t", "jolokia.use-ssl-client-authentication=false",
+			"-t", "jolokia.protocol=http",
+			"-t", "jolokia.extended-client-check=false").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		pod := IntegrationPod(ns, "java")
+		response, err := TestClient().CoreV1().RESTClient().Get().
+			AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod().Name)).DoRaw(TestContext)
 		Expect(err).To(BeNil())
-		Expect(logs).NotTo(BeEmpty())
+		Expect(response).To(ContainSubstring(`"status":200`))
 
-		it := Integration(ns, name)()
-		Expect(it).NotTo(BeNil())
-		build := Build(ns, it.Status.IntegrationKit.Name)()
-		Expect(build).NotTo(BeNil())
-
-		// Clean up
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+
 }
diff --git a/e2e/global/common/traits/jvm_test.go b/e2e/common/traits/jvm_test.go
similarity index 51%
rename from e2e/global/common/traits/jvm_test.go
rename to e2e/common/traits/jvm_test.go
index b26f46a9f..6874573a5 100644
--- a/e2e/global/common/traits/jvm_test.go
+++ b/e2e/common/traits/jvm_test.go
@@ -36,28 +36,25 @@ import (
 )
 
 func TestJVMTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-jvm"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		// Store a configmap holding a jar
-		var cmData = make(map[string][]byte)
-		// We calculate the expected content
-		source, err := ioutil.ReadFile("./files/jvm/sample-1.0.jar")
-		assert.Nil(t, err)
-		cmData["sample-1.0.jar"] = source
-		err = CreateBinaryConfigmap(ns, "my-deps", cmData)
-		assert.Nil(t, err)
-
-		t.Run("JVM trait classpath", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/jvm/Classpath.java",
-				"--resource", "configmap:my-deps",
-				"-t", "jvm.classpath=/etc/camel/resources/my-deps/sample-1.0.jar",
-			).Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "classpath"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "classpath", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "classpath"), TestTimeoutShort).Should(ContainSubstring("Hello World!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
+	RegisterTestingT(t)
+
+	// Store a configmap holding a jar
+	var cmData = make(map[string][]byte)
+	// We calculate the expected content
+	source, err := ioutil.ReadFile("./files/jvm/sample-1.0.jar")
+	assert.Nil(t, err)
+	cmData["sample-1.0.jar"] = source
+	err = CreateBinaryConfigmap(ns, "my-deps", cmData)
+	assert.Nil(t, err)
+
+	t.Run("JVM trait classpath", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "./files/jvm/Classpath.java",
+			"--resource", "configmap:my-deps",
+			"-t", "jvm.classpath=/etc/camel/resources/my-deps/sample-1.0.jar",
+		).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "classpath"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, "classpath", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, "classpath"), TestTimeoutShort).Should(ContainSubstring("Hello World!"))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 	})
 }
diff --git a/e2e/common/traits/master_test.go b/e2e/common/traits/master_test.go
new file mode 100644
index 000000000..3c164d737
--- /dev/null
+++ b/e2e/common/traits/master_test.go
@@ -0,0 +1,69 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package traits
+
+import (
+	"testing"
+	"time"
+
+	. "github.com/onsi/gomega"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+)
+
+func TestMasterTrait(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("master works", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/Master.java").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "master"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationLogs(ns, "master"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("only one integration with master runs", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/Master.java",
+			"--name", "first",
+			"--label", "leader-group=same",
+			"-t", "master.label-key=leader-group",
+			"-t", "master.label-value=same",
+			"-t", "owner.target-labels=leader-group").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "first"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationLogs(ns, "first"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+		// Start a second integration with the same lock (it should not start the route)
+		Expect(KamelRunWithID(operatorID, ns, "files/Master.java",
+			"--name", "second",
+			"--label", "leader-group=same",
+			"-t", "master.label-key=leader-group",
+			"-t", "master.label-value=same",
+			"-t", "master.resource-name=first-lock",
+			"-t", "owner.target-labels=leader-group").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "second"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationLogs(ns, "second"), TestTimeoutShort).Should(ContainSubstring("started in"))
+		Eventually(IntegrationLogs(ns, "second"), 30*time.Second).ShouldNot(ContainSubstring("Magicstring!"))
+	})
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/common/traits/openapi_test.go b/e2e/common/traits/openapi_test.go
new file mode 100644
index 000000000..3587a2185
--- /dev/null
+++ b/e2e/common/traits/openapi_test.go
@@ -0,0 +1,89 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package traits
+
+import (
+	"io/ioutil"
+	"testing"
+
+	. "github.com/onsi/gomega"
+	"github.com/stretchr/testify/assert"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+)
+
+func TestOpenAPI(t *testing.T) {
+	RegisterTestingT(t)
+
+	Expect(KamelRunWithID(operatorID, ns,
+		"--name", "petstore",
+		"--open-api", "file:files/openapi/petstore-api.yaml",
+		"files/openapi/petstore.groovy",
+	).Execute()).To(Succeed())
+
+	Eventually(IntegrationPodPhase(ns, "petstore"), TestTimeoutLong).
+		Should(Equal(corev1.PodRunning))
+	Eventually(Deployment(ns, "petstore"), TestTimeoutLong).
+		Should(Not(BeNil()))
+
+	Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium).
+		Should(ContainSubstring("Started listPets (rest://get:/v1:/pets)"))
+	Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium).
+		Should(ContainSubstring("Started createPets (rest://post:/v1:/pets)"))
+	Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium).
+		Should(ContainSubstring("Started showPetById (rest://get:/v1:/pets/%7BpetId%7D)"))
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
+
+func TestOpenAPIConfigmap(t *testing.T) {
+	RegisterTestingT(t)
+
+	openapiContent, err := ioutil.ReadFile("./files/openapi/petstore-api.yaml")
+	assert.Nil(t, err)
+	var cmDataProps = make(map[string]string)
+	cmDataProps["petstore-api.yaml"] = string(openapiContent)
+	CreatePlainTextConfigmap(ns, "my-openapi", cmDataProps)
+
+	Expect(KamelRunWithID(operatorID, ns,
+		"--name", "petstore",
+		"--open-api", "configmap:my-openapi",
+		"files/openapi/petstore.groovy",
+	).Execute()).To(Succeed())
+
+	Eventually(IntegrationPodPhase(ns, "petstore"), TestTimeoutLong).
+		Should(Equal(corev1.PodRunning))
+	Eventually(Deployment(ns, "petstore"), TestTimeoutLong).
+		Should(Not(BeNil()))
+
+	Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium).
+		Should(ContainSubstring("Started listPets (rest://get:/v1:/pets)"))
+	Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium).
+		Should(ContainSubstring("Started createPets (rest://post:/v1:/pets)"))
+	Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium).
+		Should(ContainSubstring("Started showPetById (rest://get:/v1:/pets/%7BpetId%7D)"))
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/common/traits/pdb_test.go b/e2e/common/traits/pdb_test.go
new file mode 100644
index 000000000..83ae391bf
--- /dev/null
+++ b/e2e/common/traits/pdb_test.go
@@ -0,0 +1,162 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package traits
+
+import (
+	"net/http"
+	"testing"
+
+	. "github.com/onsi/gomega"
+	. "github.com/onsi/gomega/gstruct"
+
+	corev1 "k8s.io/api/core/v1"
+	policyv1 "k8s.io/api/policy/v1"
+	"k8s.io/apimachinery/pkg/api/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/util/intstr"
+
+	ctrl "sigs.k8s.io/controller-runtime/pkg/client"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+func TestPodDisruptionBudgetTrait(t *testing.T) {
+	RegisterTestingT(t)
+
+	name := "java"
+	Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+		"--name", name,
+		"-t", "pdb.enabled=true",
+		"-t", "pdb.min-available=2",
+	).Execute()).To(Succeed())
+
+	Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+	Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+	Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+	// Check PodDisruptionBudget
+	Eventually(podDisruptionBudget(ns, name), TestTimeoutShort).ShouldNot(BeNil())
+	pdb := podDisruptionBudget(ns, name)()
+	// Assert PDB Spec
+	Expect(pdb.Spec.MinAvailable).To(PointTo(Equal(intstr.FromInt(2))))
+	// Assert PDB Status
+	Eventually(podDisruptionBudget(ns, name), TestTimeoutShort).
+		Should(MatchFieldsP(IgnoreExtras, Fields{
+			"Status": MatchFields(IgnoreExtras, Fields{
+				"ObservedGeneration": BeNumerically("==", 1),
+				"DisruptionsAllowed": BeNumerically("==", 0),
+				"CurrentHealthy":     BeNumerically("==", 1),
+				"DesiredHealthy":     BeNumerically("==", 2),
+				"ExpectedPods":       BeNumerically("==", 1),
+			}),
+		}))
+
+	// Scale Integration
+	Expect(ScaleIntegration(ns, name, 2)).To(Succeed())
+	Eventually(IntegrationPods(ns, name), TestTimeoutMedium).Should(HaveLen(2))
+	Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
+		Should(PointTo(BeNumerically("==", 2)))
+	Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+
+	// Check PodDisruptionBudget
+	pdb = podDisruptionBudget(ns, name)()
+	Expect(pdb).NotTo(BeNil())
+	// Assert PDB Status according to the scale change
+	Eventually(podDisruptionBudget(ns, name), TestTimeoutShort).
+		Should(MatchFieldsP(IgnoreExtras, Fields{
+			"Status": MatchFields(IgnoreExtras, Fields{
+				"ObservedGeneration": BeNumerically("==", 1),
+				"DisruptionsAllowed": BeNumerically("==", 0),
+				"CurrentHealthy":     BeNumerically("==", 2),
+				"DesiredHealthy":     BeNumerically("==", 2),
+				"ExpectedPods":       BeNumerically("==", 2),
+			}),
+		}))
+
+	// Eviction attempt
+	pods := IntegrationPods(ns, name)()
+	Expect(pods).To(HaveLen(2))
+	err := TestClient().CoreV1().Pods(ns).EvictV1(TestContext, &policyv1.Eviction{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: pods[0].Name,
+		},
+	})
+	Expect(err).To(MatchError(&errors.StatusError{
+		ErrStatus: metav1.Status{
+			Status:  "Failure",
+			Message: "Cannot evict pod as it would violate the pod's disruption budget.",
+			Reason:  "TooManyRequests",
+			Code:    http.StatusTooManyRequests,
+			Details: &metav1.StatusDetails{
+				Causes: []metav1.StatusCause{
+					{
+						Type:    "DisruptionBudget",
+						Message: "The disruption budget java needs 2 healthy pods and has 2 currently",
+					},
+				},
+			},
+		},
+	}))
+
+	// Scale Integration to Scale > PodDisruptionBudgetSpec.MinAvailable
+	// for the eviction request to succeed once replicas are ready
+	Expect(ScaleIntegration(ns, name, 3)).To(Succeed())
+	Eventually(IntegrationPods(ns, name), TestTimeoutMedium).Should(HaveLen(3))
+	Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
+		Should(PointTo(BeNumerically("==", 3)))
+	Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+
+	pods = IntegrationPods(ns, name)()
+	Expect(pods).To(HaveLen(3))
+	Expect(TestClient().CoreV1().Pods(ns).EvictV1(TestContext, &policyv1.Eviction{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: pods[0].Name,
+		},
+	})).To(Succeed())
+
+	// Clean up
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
+
+func podDisruptionBudget(ns string, name string) func() *policyv1.PodDisruptionBudget {
+	return func() *policyv1.PodDisruptionBudget {
+		pdb := policyv1.PodDisruptionBudget{
+			TypeMeta: metav1.TypeMeta{
+				APIVersion: policyv1.SchemeGroupVersion.String(),
+				Kind:       "PodDisruptionBudget",
+			},
+			ObjectMeta: metav1.ObjectMeta{
+				Namespace: ns,
+				Name:      name,
+			},
+		}
+		err := TestClient().Get(TestContext, ctrl.ObjectKeyFromObject(&pdb), &pdb)
+		if err != nil && errors.IsNotFound(err) {
+			return nil
+		} else if err != nil {
+			panic(err)
+		}
+		return &pdb
+	}
+}
diff --git a/e2e/global/common/traits/pod_test.go b/e2e/common/traits/pod_test.go
similarity index 76%
rename from e2e/global/common/traits/pod_test.go
rename to e2e/common/traits/pod_test.go
index e27fd3166..b24b3c51e 100644
--- a/e2e/global/common/traits/pod_test.go
+++ b/e2e/common/traits/pod_test.go
@@ -34,6 +34,7 @@ import (
 )
 
 func TestPodTrait(t *testing.T) {
+	RegisterTestingT(t)
 
 	tc := []struct {
 		name         string
@@ -76,32 +77,29 @@ func TestPodTrait(t *testing.T) {
 		},
 	}
 
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-pod-template"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
+	name := "pod-template-test"
 
-		name := "pod-template-test"
+	for i := range tc {
+		test := tc[i]
 
-		for i := range tc {
-			test := tc[i]
+		t.Run(test.name, func(t *testing.T) {
+			Expect(KamelRunWithID(operatorID, ns, "files/PodTest.groovy",
+				"--name", name,
+				"--pod-template", test.templateName,
+			).Execute()).To(Succeed())
 
-			t.Run(test.name, func(t *testing.T) {
-				Expect(KamelRunWithID(operatorID, ns, "files/PodTest.groovy",
-					"--name", name,
-					"--pod-template", test.templateName,
-				).Execute()).To(Succeed())
+			// check integration is deployed
+			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
 
-				// check integration is deployed
-				Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-				Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+			test.assertions(t, ns, name)
 
-				test.assertions(t, ns, name)
+			// Clean up
+			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		})
+	}
 
-				// Clean up
-				Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-			})
-		}
-	})
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
 
 func getEnvVar(name string, spec corev1.PodSpec) string {
diff --git a/e2e/global/common/traits/prometheus_test.go b/e2e/common/traits/prometheus_test.go
similarity index 55%
rename from e2e/global/common/traits/prometheus_test.go
rename to e2e/common/traits/prometheus_test.go
index f4a9a1709..c84e5f2c9 100644
--- a/e2e/global/common/traits/prometheus_test.go
+++ b/e2e/common/traits/prometheus_test.go
@@ -42,42 +42,37 @@ import (
 )
 
 func TestPrometheusTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		ocp, err := openshift.IsOpenShift(TestClient())
-		assert.Nil(t, err)
-
-		// Do not create PodMonitor for the time being as CI test runs on OCP 3.11
-		createPodMonitor := false
-
-		operatorID := "camel-k-trait-prometheus"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-			"-t", "prometheus.enabled=true",
-			"-t", fmt.Sprintf("prometheus.pod-monitor=%v", createPodMonitor)).Execute()).To(Succeed())
-		Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-		Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-		Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-		t.Run("Metrics endpoint works", func(t *testing.T) {
-			pod := IntegrationPod(ns, "java")
-			response, err := TestClient().CoreV1().RESTClient().Get().
-				AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/q/metrics", ns, pod().Name)).DoRaw(TestContext)
-			if err != nil {
-				assert.Fail(t, err.Error())
-			}
-			assert.Contains(t, string(response), "camel.route.exchanges.total")
-		})
-
-		if ocp && createPodMonitor {
-			t.Run("PodMonitor is created", func(t *testing.T) {
-				sm := podMonitor(ns, "java")
-				Eventually(sm, TestTimeoutShort).ShouldNot(BeNil())
-			})
+	RegisterTestingT(t)
+
+	ocp, err := openshift.IsOpenShift(TestClient())
+	assert.Nil(t, err)
+	// Do not create PodMonitor for the time being as CI test runs on OCP 3.11
+	createPodMonitor := false
+	Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+		"-t", "prometheus.enabled=true",
+		"-t", fmt.Sprintf("prometheus.pod-monitor=%v", createPodMonitor)).Execute()).To(Succeed())
+	Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+	Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+	Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+	t.Run("Metrics endpoint works", func(t *testing.T) {
+		pod := IntegrationPod(ns, "java")
+		response, err := TestClient().CoreV1().RESTClient().Get().
+			AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/q/metrics", ns, pod().Name)).DoRaw(TestContext)
+		if err != nil {
+			assert.Fail(t, err.Error())
 		}
-
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+		assert.Contains(t, string(response), "camel.route.exchanges.total")
 	})
+
+	if ocp && createPodMonitor {
+		t.Run("PodMonitor is created", func(t *testing.T) {
+			sm := podMonitor(ns, "java")
+			Eventually(sm, TestTimeoutShort).ShouldNot(BeNil())
+		})
+	}
+
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
 
 func podMonitor(ns string, name string) func() *monitoringv1.PodMonitor {
diff --git a/e2e/common/traits/pull_secret_test.go b/e2e/common/traits/pull_secret_test.go
new file mode 100644
index 000000000..399910a48
--- /dev/null
+++ b/e2e/common/traits/pull_secret_test.go
@@ -0,0 +1,90 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package traits
+
+import (
+	"testing"
+
+	. "github.com/onsi/gomega"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	"github.com/apache/camel-k/pkg/util/openshift"
+)
+
+func TestPullSecretTrait(t *testing.T) {
+	RegisterTestingT(t)
+
+	ocp, err := openshift.IsOpenShift(TestClient())
+	Expect(err).To(BeNil())
+
+	t.Run("Image pull secret is set on pod", func(t *testing.T) {
+		name := "java1"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name,
+			"-t", "pull-secret.enabled=true",
+			"-t", "pull-secret.secret-name=dummy-secret").Execute()).To(Succeed())
+		// pod may not run because the pull secret is dummy
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Or(Equal(corev1.PodRunning), Equal(corev1.PodPending)))
+
+		pod := IntegrationPod(ns, name)()
+		Expect(pod.Spec.ImagePullSecrets).NotTo(BeEmpty())
+		Expect(pod.Spec.ImagePullSecrets[0].Name).To(Equal("dummy-secret"))
+	})
+
+	t.Run("Explicitly disable image pull secret", func(t *testing.T) {
+		name := "java2"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name,
+			"-t", "pull-secret.enabled=false").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		pod := IntegrationPod(ns, name)()
+		if ocp {
+			// OpenShift `default` service account has imagePullSecrets so it's always set
+			Expect(pod.Spec.ImagePullSecrets).NotTo(BeEmpty())
+		} else {
+			Expect(pod.Spec.ImagePullSecrets).To(BeNil())
+		}
+	})
+
+	if ocp {
+		// OpenShift always has an internal registry so image pull secret is set by default
+		t.Run("Image pull secret is automatically set by default", func(t *testing.T) {
+			name := "java3"
+			Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed())
+			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+			pod := IntegrationPod(ns, name)()
+			Expect(pod.Spec.ImagePullSecrets).NotTo(BeEmpty())
+			Expect(pod.Spec.ImagePullSecrets[0].Name).To(HavePrefix("default-dockercfg-"))
+		})
+	}
+
+	// Clean-up
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/common/traits/route_test.go b/e2e/common/traits/route_test.go
new file mode 100644
index 000000000..24be66492
--- /dev/null
+++ b/e2e/common/traits/route_test.go
@@ -0,0 +1,329 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package traits
+
+import (
+	"bytes"
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/tls"
+	"crypto/x509"
+	"crypto/x509/pkix"
+	"encoding/pem"
+	"fmt"
+	"math/big"
+	rand2 "math/rand"
+	"net/http"
+	"testing"
+	"time"
+
+	. "github.com/onsi/gomega"
+	"github.com/stretchr/testify/assert"
+
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+	"github.com/apache/camel-k/pkg/util/openshift"
+)
+
+const (
+	secretName      = "test-certificate"
+	integrationName = "platform-http-server"
+)
+
+var waitBeforeHttpRequest = TestTimeoutShort / 2
+
+type keyCertificatePair struct {
+	Key         []byte
+	Certificate []byte
+}
+
+// self-signed certificate used when making the https request
+var certPem []byte
+
+// the e2e tests run on OpenShift 3 and there is no object to retrieve the base domain name
+// to create a valid hostname to later have it validated when doing the HTTPS request.
+// As this e2e test validates the route object and not the certificate itself,
+// if the base domain name cannot be retrieved from dns/cluster, we can safely skip TLS verification.
+// if running on openshift4, there is the dns/cluster object to retrieve the base domain name,
+// then in this case the HTTP client validates the TLS certificate.
+var skipClientTLSVerification = true
+
+func TestRunRoutes(t *testing.T) {
+	RegisterTestingT(t)
+
+	ocp, err := openshift.IsOpenShift(TestClient())
+	if !ocp {
+		t.Skip("This test requires route object which is available on OpenShift only.")
+		return
+	}
+	assert.Nil(t, err)
+
+	operatorID := "camel-k-trait-route"
+	Expect(KamelInstallWithID(operatorID, ns, "--trait-profile=openshift").Execute()).To(Succeed())
+
+	// create a test secret of type tls with certificates
+	// this secret is used to setupt the route TLS object across diferent tests
+	secret, err := createSecret(ns)
+	assert.Nil(t, err)
+
+	// they refer to the certificates create in the secret and are reused the different tests
+	refKey := secretName + "/" + corev1.TLSPrivateKeyKey
+	refCert := secretName + "/" + corev1.TLSCertKey
+
+	// =============================
+	// Insecure Route / No TLS
+	// =============================
+	t.Run("Route unsecure http works", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		route := Route(ns, integrationName)
+		Eventually(route, TestTimeoutMedium).ShouldNot(BeNil())
+		// must wait a little time after route is created, before doing an http request,
+		// otherwise the route is unavailable and the http request will fail
+		time.Sleep(waitBeforeHttpRequest)
+		url := fmt.Sprintf("http://%s/hello?name=Simple", route().Spec.Host)
+		Eventually(httpRequest(url, false), TestTimeoutShort).Should(Equal("Hello Simple"))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
+	})
+
+	// =============================
+	// TLS Route Edge
+	// =============================
+	t.Run("Route Edge https works", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java", "-t", "route.tls-termination=edge").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		route := Route(ns, integrationName)
+		Eventually(route, TestTimeoutMedium).ShouldNot(BeNil())
+		// must wait a little time after route is created, before an http request,
+		// otherwise the route is unavailable and the http request will fail
+		time.Sleep(waitBeforeHttpRequest)
+		url := fmt.Sprintf("https://%s/hello?name=TLS_Edge", route().Spec.Host)
+		Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello TLS_Edge"))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
+	})
+
+	// =============================
+	// TLS Route Edge with custom certificate
+	// =============================
+	t.Run("Route Edge (custom certificate) https works", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
+			"-t", "route.tls-termination=edge",
+			"-t", "route.tls-certificate-secret="+refCert,
+			"-t", "route.tls-key-secret="+refKey,
+		).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		route := Route(ns, integrationName)
+		Eventually(route, TestTimeoutMedium).ShouldNot(BeNil())
+		// must wait a little time after route is created, before an http request,
+		// otherwise the route is unavailable and the http request will fail
+		time.Sleep(waitBeforeHttpRequest)
+		code := "TLS_EdgeCustomCertificate"
+		url := fmt.Sprintf("https://%s/hello?name=%s", route().Spec.Host, code)
+		Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello " + code))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
+	})
+
+	// =============================
+	// TLS Route Passthrough
+	// =============================
+	t.Run("Route passthrough https works", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
+			// the --resource mounts the certificates inside secret as files in the integration pod
+			"--resource", "secret:"+secretName+"@/etc/ssl/"+secretName,
+			// quarkus platform-http uses these two properties to setup the HTTP endpoint with TLS support
+			"-p", "quarkus.http.ssl.certificate.file=/etc/ssl/"+secretName+"/tls.crt",
+			"-p", "quarkus.http.ssl.certificate.key-file=/etc/ssl/"+secretName+"/tls.key",
+			"-t", "route.tls-termination=passthrough",
+			"-t", "container.port=8443",
+		).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		route := Route(ns, integrationName)
+		Eventually(route, TestTimeoutMedium).ShouldNot(BeNil())
+		// must wait a little time after route is created, before an http request,
+		// otherwise the route is unavailable and the http request will fail
+		time.Sleep(waitBeforeHttpRequest)
+		code := "TLS_Passthrough"
+		url := fmt.Sprintf("https://%s/hello?name=%s", route().Spec.Host, code)
+		Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello " + code))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
+	})
+
+	// =============================
+	// TLS Route Reencrypt
+	// =============================
+	t.Run("Route Reencrypt https works", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
+			// the --resource mounts the certificates inside secret as files in the integration pod
+			"--resource", "secret:"+secretName+"@/etc/ssl/"+secretName,
+			// quarkus platform-http uses these two properties to setup the HTTP endpoint with TLS support
+			"-p", "quarkus.http.ssl.certificate.file=/etc/ssl/"+secretName+"/tls.crt",
+			"-p", "quarkus.http.ssl.certificate.key-file=/etc/ssl/"+secretName+"/tls.key",
+			"-t", "route.tls-termination=reencrypt",
+			// the destination CA certificate which the route service uses to validate the HTTP endpoint TLS certificate
+			"-t", "route.tls-destination-ca-certificate-secret="+refCert,
+			"-t", "route.tls-certificate-secret="+refCert,
+			"-t", "route.tls-key-secret="+refKey,
+			"-t", "container.port=8443",
+		).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+
+		route := Route(ns, integrationName)
+		Eventually(route, TestTimeoutMedium).ShouldNot(BeNil())
+		// must wait a little time after route is created, before an http request,
+		// otherwise the route is unavailable and the http request will fail
+		time.Sleep(waitBeforeHttpRequest)
+		code := "TLS_Reencrypt"
+		url := fmt.Sprintf("https://%s/hello?name=%s", route().Spec.Host, code)
+		Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello " + code))
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
+	})
+	Expect(TestClient().Delete(TestContext, &secret)).To(Succeed())
+}
+
+func httpRequest(url string, tlsEnabled bool) func() (string, error) {
+	return func() (string, error) {
+		client, err := httpClient(tlsEnabled, 3*time.Second)
+		if err != nil {
+			return "", err
+		}
+		response, err := client.Get(url)
+		if err != nil {
+			return "", err
+		}
+		defer response.Body.Close()
+
+		buf := new(bytes.Buffer)
+		_, err = buf.ReadFrom(response.Body)
+		if err != nil {
+			return "", err
+		}
+		return buf.String(), nil
+	}
+}
+
+func httpClient(tlsEnabled bool, timeout time.Duration) (*http.Client, error) {
+	var client http.Client
+	if tlsEnabled {
+		var transCfg http.Transport
+		if skipClientTLSVerification {
+			transCfg = http.Transport{
+				TLSClientConfig: &tls.Config{
+					InsecureSkipVerify: true,
+				},
+			}
+		} else {
+			certPool := x509.NewCertPool()
+			certPool.AppendCertsFromPEM(certPem)
+			transCfg = http.Transport{
+				TLSClientConfig: &tls.Config{
+					RootCAs: certPool,
+				},
+			}
+		}
+		client = http.Client{Transport: &transCfg}
+	} else {
+		client = http.Client{}
+	}
+	client.Timeout = timeout
+	return &client, nil
+}
+
+func createSecret(ns string) (corev1.Secret, error) {
+	keyCertPair := generateSampleKeyAndCertificate(ns)
+	sec := corev1.Secret{
+		TypeMeta: metav1.TypeMeta{
+			Kind:       "Secret",
+			APIVersion: corev1.SchemeGroupVersion.String(),
+		},
+		ObjectMeta: metav1.ObjectMeta{
+			Namespace: ns,
+			Name:      secretName,
+		},
+		Type: corev1.SecretTypeTLS,
+		Data: map[string][]byte{
+			corev1.TLSPrivateKeyKey: keyCertPair.Key,
+			corev1.TLSCertKey:       keyCertPair.Certificate,
+		},
+	}
+	return sec, TestClient().Create(TestContext, &sec)
+}
+
+func generateSampleKeyAndCertificate(ns string) keyCertificatePair {
+	serialNumber := big.NewInt(rand2.Int63())
+	domainName, err := ClusterDomainName()
+	if err != nil {
+		fmt.Printf("Error retrieving cluster domain object, then the http client request will skip TLS validation: %s\n", err)
+		skipClientTLSVerification = true
+	}
+	var dnsHostname string
+	if len(domainName) > 0 {
+		dnsHostname = integrationName + "-" + ns + "." + domainName
+	} else {
+		dnsHostname = integrationName + "-" + ns
+	}
+	x509Certificate := x509.Certificate{
+		SerialNumber: serialNumber,
+		Subject: pkix.Name{
+			Organization: []string{"Camel K test"},
+		},
+		IsCA:                  true,
+		DNSNames:              []string{dnsHostname},
+		NotBefore:             time.Now(),
+		NotAfter:              time.Now().AddDate(1, 0, 0),
+		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
+		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
+		BasicConstraintsValid: true,
+	}
+
+	// generate the private key
+	certPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048)
+	if err != nil {
+		fmt.Printf("Error generating private key: %s\n", err)
+	}
+
+	privateKeyBytes := x509.MarshalPKCS1PrivateKey(certPrivateKey)
+	// encode for storing into secret
+	privateKeyPem := pem.EncodeToMemory(
+		&pem.Block{
+			Type:  "RSA PRIVATE KEY",
+			Bytes: privateKeyBytes,
+		},
+	)
+	certBytes, err := x509.CreateCertificate(rand.Reader, &x509Certificate, &x509Certificate, &certPrivateKey.PublicKey, certPrivateKey)
+	if err != nil {
+		fmt.Printf("Error generating certificate: %s\n", err)
+	}
+
+	// encode for storing into secret
+	certPem = pem.EncodeToMemory(&pem.Block{
+		Type:  "CERTIFICATE",
+		Bytes: certBytes,
+	})
+
+	return keyCertificatePair{
+		Key:         privateKeyPem,
+		Certificate: certPem,
+	}
+}
diff --git a/e2e/global/service-binding/service_binding_test.go b/e2e/common/traits/service_binding_test.go
similarity index 64%
rename from e2e/global/service-binding/service_binding_test.go
rename to e2e/common/traits/service_binding_test.go
index e8cb38c37..3970665e9 100644
--- a/e2e/global/service-binding/service_binding_test.go
+++ b/e2e/common/traits/service_binding_test.go
@@ -20,7 +20,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package service_binding
+package traits
 
 import (
 	"fmt"
@@ -36,10 +36,9 @@ import (
 )
 
 func TestServiceBindingTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-service-binding"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
+	RegisterTestingT(t)
 
+	t.Run("Integration Service Binding", func(t *testing.T) {
 		// Create our mock service config
 		host := "hostname"
 		port := "12324"
@@ -49,7 +48,7 @@ func TestServiceBindingTrait(t *testing.T) {
 				APIVersion: "v1",
 			},
 			ObjectMeta: metav1.ObjectMeta{
-				Name:      "mock-service-config",
+				Name:      "mock-service-config-it",
 				Namespace: ns,
 				Annotations: map[string]string{
 					"service.binding/host": "path={.data.service-host}",
@@ -63,7 +62,6 @@ func TestServiceBindingTrait(t *testing.T) {
 		}
 		serviceRef := fmt.Sprintf("%s:%s/%s", service.TypeMeta.Kind, ns, service.ObjectMeta.Name)
 		Expect(TestClient().Create(TestContext, service)).To(Succeed())
-
 		// Create integration and bind it to our service
 		name := "service-binding"
 		Expect(KamelRunWithID(operatorID, ns, "files/ServiceBinding.java",
@@ -74,8 +72,37 @@ func TestServiceBindingTrait(t *testing.T) {
 		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
 		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
 		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring(fmt.Sprintf("%s:%s", host, port)))
+	})
 
-		// Clean up
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	t.Run("Kamelet Binding Service Binding", func(t *testing.T) {
+		// Create our mock service config
+		message := "hello"
+		service := &corev1.ConfigMap{
+			TypeMeta: metav1.TypeMeta{
+				Kind:       "ConfigMap",
+				APIVersion: "v1",
+			},
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "mock-service-config-kb",
+				Namespace: ns,
+				Annotations: map[string]string{
+					"service.binding/message": "path={.data.message}",
+				},
+			},
+			Data: map[string]string{
+				"message": message,
+			},
+		}
+		serviceRef := fmt.Sprintf("%s:%s/%s", service.TypeMeta.Kind, ns, service.ObjectMeta.Name)
+		Expect(TestClient().Create(TestContext, service)).To(Succeed())
+		Expect(CreateTimerKamelet(ns, "my-timer-source")()).To(Succeed())
+		Expect(KamelBindWithID(operatorID, ns, "my-timer-source", "log:info",
+			"-p", "source.message=Hello+world",
+			"--connect", serviceRef).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "my-timer-source-to-log"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationLogs(ns, "my-timer-source-to-log")).Should(ContainSubstring("Body: Hello+world"))
 	})
+
+	// Clean up
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
 }
diff --git a/e2e/common/traits/service_test.go b/e2e/common/traits/service_test.go
new file mode 100644
index 000000000..df76acb18
--- /dev/null
+++ b/e2e/common/traits/service_test.go
@@ -0,0 +1,111 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package traits
+
+import (
+	"testing"
+
+	. "github.com/onsi/gomega"
+
+	corev1 "k8s.io/api/core/v1"
+
+	. "github.com/apache/camel-k/e2e/support"
+)
+
+func TestServiceTrait(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("NodePort service", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
+			"-t", "service.enabled=true",
+			"-t", "service.node-port=true").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+
+		//
+		// Service names can vary with the ExternalName Service
+		// sometimes being created first and being given the root name
+		//
+		Eventually(ServicesByType(ns, corev1.ServiceTypeNodePort), TestTimeoutLong).ShouldNot(BeEmpty())
+
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("Default service (ClusterIP)", func(t *testing.T) {
+		// Service trait is enabled by default
+		Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+
+		//
+		// Service names can vary with the ExternalName Service
+		// sometimes being created first and being given the root name
+		//
+		Eventually(ServicesByType(ns, corev1.ServiceTypeClusterIP), TestTimeoutLong).ShouldNot(BeEmpty())
+
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("NodePort service from Type", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
+			"-t", "service.enabled=true",
+			"-t", "service.type=NodePort").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+
+		//
+		// Service names can vary with the ExternalName Service
+		// sometimes being created first and being given the root name
+		//
+		Eventually(ServicesByType(ns, corev1.ServiceTypeNodePort), TestTimeoutLong).ShouldNot(BeEmpty())
+
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("ClusterIP service from Type", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
+			"-t", "service.enabled=true",
+			"-t", "service.type=ClusterIP").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+
+		//
+		// Service names can vary with the ExternalName Service
+		// sometimes being created first and being given the root name
+		//
+		Eventually(ServicesByType(ns, corev1.ServiceTypeClusterIP), TestTimeoutLong).ShouldNot(BeEmpty())
+
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+
+	t.Run("LoadBalancer service from Type", func(t *testing.T) {
+		Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
+			"-t", "service.enabled=true",
+			"-t", "service.type=LoadBalancer").Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+
+		//
+		// Service names can vary with the ExternalName Service
+		// sometimes being created first and being given the root name
+		//
+		Eventually(ServicesByType(ns, corev1.ServiceTypeLoadBalancer), TestTimeoutLong).ShouldNot(BeEmpty())
+
+		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+	})
+}
diff --git a/e2e/common/traits/toleration_test.go b/e2e/common/traits/toleration_test.go
new file mode 100644
index 000000000..ad44dc984
--- /dev/null
+++ b/e2e/common/traits/toleration_test.go
@@ -0,0 +1,129 @@
+//go:build integration
+// +build integration
+
+// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
+
+/*
+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.
+*/
+
+package traits
+
+import (
+	"testing"
+
+	. "github.com/onsi/gomega"
+	. "github.com/onsi/gomega/gstruct"
+
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/utils/pointer"
+
+	. "github.com/apache/camel-k/e2e/support"
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+)
+
+func TestTolerationTrait(t *testing.T) {
+	RegisterTestingT(t)
+
+	t.Run("Run Java with node toleration operation exists", func(t *testing.T) {
+		name := "java1"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", name,
+			"-t", "toleration.enabled=true",
+			"-t", "toleration.taints=camel.apache.org/master:NoExecute:300",
+		).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		pod := IntegrationPod(ns, name)()
+		Expect(pod.Spec.Tolerations).NotTo(BeNil())
+
+		Expect(pod.Spec.Tolerations).To(ContainElement(corev1.Toleration{
+			Key:               "camel.apache.org/master",
+			Operator:          corev1.TolerationOpExists,
+			Effect:            corev1.TaintEffectNoExecute,
+			TolerationSeconds: pointer.Int64(300),
+		}))
+	})
+
+	t.Run("Run Java with node toleration operation equals", func(t *testing.T) {
+		name := "java2"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", name,
+			"-t", "toleration.enabled=true",
+			"-t", "toleration.taints=camel.apache.org/master=test:NoExecute:300",
+		).Execute()).To(Succeed())
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		pod := IntegrationPod(ns, name)()
+		Expect(pod.Spec.Tolerations).NotTo(BeNil())
+
+		Expect(pod.Spec.Tolerations).To(ContainElement(corev1.Toleration{
+			Key:      "camel.apache.org/master",
+			Operator: corev1.TolerationOpEqual,
+			Value:    "test", Effect: corev1.TaintEffectNoExecute,
+			TolerationSeconds: pointer.Int64(300),
+		}))
+	})
+
+	t.Run("Run Java with master node toleration", func(t *testing.T) {
+		if len(Nodes()()) == 1 {
+			t.Skip("Skip master node toleration test on single-node cluster")
+		}
+
+		name := "java3"
+		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
+			"--name", name,
+			// Use the affinity trait to force the scheduling of the Integration pod onto a master node
+			"-t", "affinity.enabled=true",
+			"-t", "affinity.node-affinity-labels=node-role.kubernetes.io/master",
+			// And tolerate the corresponding taint
+			"-t", "toleration.enabled=true",
+			"-t", "toleration.taints=node-role.kubernetes.io/master:NoSchedule",
+		).Execute()).To(Succeed())
+
+		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
+		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+
+		pod := IntegrationPod(ns, name)()
+		Expect(pod).NotTo(BeNil())
+
+		// Check the Integration pod contains the toleration
+		Expect(pod.Spec.Tolerations).To(ContainElement(corev1.Toleration{
+			Key:      "node-role.kubernetes.io/master",
+			Operator: corev1.TolerationOpExists,
+			Effect:   corev1.TaintEffectNoSchedule,
+		}))
+
+		// Check the Integration pod is running on a master node
+		Expect(Node(pod.Spec.NodeName)()).NotTo(BeNil())
+		Expect(Node(pod.Spec.NodeName)()).To(PointTo(MatchFields(IgnoreExtras, Fields{
+			"Spec": MatchFields(IgnoreExtras, Fields{
+				"Taints": ContainElement(corev1.Taint{
+					Key:    "node-role.kubernetes.io/master",
+					Effect: corev1.TaintEffectNoSchedule,
+				}),
+			}),
+		})))
+	})
+
+	// Clean up
+	Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
+}
diff --git a/e2e/global/common/config/config_test.go b/e2e/global/common/config/config_test.go
deleted file mode 100644
index 38eb54e7b..000000000
--- a/e2e/global/common/config/config_test.go
+++ /dev/null
@@ -1,373 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package resources
-
-import (
-	"fmt"
-	"io/ioutil"
-	"testing"
-
-	. "github.com/onsi/gomega"
-	"github.com/stretchr/testify/assert"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/util/gzip"
-)
-
-func TestRunConfigExamples(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := fmt.Sprintf("camel-k-%s", ns)
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		// Properties
-
-		t.Run("Simple property", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "my.message=test-property").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("test-property"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Property file", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/property-file-route.groovy", "--property", "file:./files/my.properties").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "property-file-route"), TestTimeoutShort).Should(ContainSubstring("hello world"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Property precedence", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/property-file-route.groovy", "-p", "my.key.2=universe", "-p", "file:./files/my.properties").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "property-file-route"), TestTimeoutShort).Should(ContainSubstring("hello universe"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Property from ConfigMap", func(t *testing.T) {
-			var cmData = make(map[string]string)
-			cmData["my.message"] = "my-configmap-property-value"
-			CreatePlainTextConfigmap(ns, "my-cm-test-property", cmData)
-
-			Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "configmap:my-cm-test-property").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-configmap-property-value"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Property from ConfigMap as property file", func(t *testing.T) {
-			var cmData = make(map[string]string)
-			cmData["my.properties"] = "my.message=my-configmap-property-entry"
-			CreatePlainTextConfigmap(ns, "my-cm-test-properties", cmData)
-
-			Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "configmap:my-cm-test-properties").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-configmap-property-entry"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Property from Secret", func(t *testing.T) {
-			var secData = make(map[string]string)
-			secData["my.message"] = "my-secret-property-value"
-			CreatePlainTextSecret(ns, "my-sec-test-property", secData)
-
-			Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "secret:my-sec-test-property").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-secret-property-value"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Property from Secret as property file", func(t *testing.T) {
-			var secData = make(map[string]string)
-			secData["my.properties"] = "my.message=my-secret-property-entry"
-			CreatePlainTextSecret(ns, "my-sec-test-properties", secData)
-
-			Expect(KamelRunWithID(operatorID, ns, "./files/property-route.groovy", "-p", "secret:my-sec-test-properties").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "property-route"), TestTimeoutShort).Should(ContainSubstring("my-secret-property-entry"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		// Configmap
-
-		// Store a configmap on the cluster
-		var cmData = make(map[string]string)
-		cmData["my-configmap-key"] = "my-configmap-content"
-		CreatePlainTextConfigmap(ns, "my-cm", cmData)
-
-		// Store a configmap with multiple values
-		var cmDataMulti = make(map[string]string)
-		cmDataMulti["my-configmap-key"] = "should-not-see-it"
-		cmDataMulti["my-configmap-key-2"] = "my-configmap-content-2"
-		CreatePlainTextConfigmap(ns, "my-cm-multi", cmDataMulti)
-
-		t.Run("Config configmap", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/config-configmap-route.groovy", "--config", "configmap:my-cm").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "config-configmap-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "config-configmap-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "config-configmap-route"), TestTimeoutShort).Should(ContainSubstring(cmData["my-configmap-key"]))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Resource configmap", func(t *testing.T) {
-			// We can reuse the configmap created previously
-
-			Expect(KamelRunWithID(operatorID, ns, "./files/resource-configmap-route.groovy", "--resource", "configmap:my-cm").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "resource-configmap-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "resource-configmap-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "resource-configmap-route"), TestTimeoutShort).Should(ContainSubstring(cmData["my-configmap-key"]))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Resource configmap with destination", func(t *testing.T) {
-			// We can reuse the configmap created previously
-
-			Expect(KamelRunWithID(operatorID, ns, "./files/resource-configmap-location-route.groovy", "--resource", "configmap:my-cm@/tmp/app").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "resource-configmap-location-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "resource-configmap-location-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "resource-configmap-location-route"), TestTimeoutShort).Should(ContainSubstring(cmData["my-configmap-key"]))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Resource configmap with filtered key and destination", func(t *testing.T) {
-			// We'll use the configmap contaning 2 values filtering only 1 key
-
-			Expect(KamelRunWithID(operatorID, ns, "./files/resource-configmap-key-location-route.groovy", "--resource", "configmap:my-cm-multi/my-configmap-key-2@/tmp/app/test.txt").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "resource-configmap-key-location-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "resource-configmap-key-location-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "resource-configmap-key-location-route"), TestTimeoutShort).ShouldNot(ContainSubstring(cmDataMulti["my-configmap-key"]))
-			Eventually(IntegrationLogs(ns, "resource-configmap-key-location-route"), TestTimeoutShort).Should(ContainSubstring(cmDataMulti["my-configmap-key-2"]))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		// Store a configmap as property file
-		var cmDataProps = make(map[string]string)
-		cmDataProps["my.properties"] = "my.key.1=hello\nmy.key.2=world"
-		CreatePlainTextConfigmap(ns, "my-cm-properties", cmDataProps)
-
-		t.Run("Config configmap as property file", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/config-configmap-properties-route.groovy", "--config", "configmap:my-cm-properties").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "config-configmap-properties-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "config-configmap-properties-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "config-configmap-properties-route"), TestTimeoutShort).Should(ContainSubstring("hello world"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		// Secret
-
-		// Store a secret on the cluster
-		var secData = make(map[string]string)
-		secData["my-secret-key"] = "very top secret"
-		CreatePlainTextSecret(ns, "my-sec", secData)
-
-		// Store a secret with multi values
-		var secDataMulti = make(map[string]string)
-		secDataMulti["my-secret-key"] = "very top secret"
-		secDataMulti["my-secret-key-2"] = "even more secret"
-		CreatePlainTextSecret(ns, "my-sec-multi", secDataMulti)
-
-		t.Run("Config secret", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/config-secret-route.groovy", "--config", "secret:my-sec").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "config-secret-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "config-secret-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "config-secret-route"), TestTimeoutShort).Should(ContainSubstring(secData["my-secret-key"]))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Resource secret", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/resource-secret-route.groovy", "--resource", "secret:my-sec").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "resource-secret-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "resource-secret-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "resource-secret-route"), TestTimeoutShort).Should(ContainSubstring(secData["my-secret-key"]))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		// Config File
-
-		t.Run("Plain text configuration file", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/config-file-route.groovy", "--config", "file:./files/resources-data.txt").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "config-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "config-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "config-file-route"), TestTimeoutShort).Should(ContainSubstring("the file body"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-			Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
-		})
-
-		t.Run("Secret with filtered key", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/config-secret-key-route.groovy", "--config", "secret:my-sec-multi/my-secret-key-2").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "config-secret-key-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "config-secret-key-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "config-secret-key-route"), TestTimeoutShort).ShouldNot(ContainSubstring(secDataMulti["my-secret-key"]))
-			Eventually(IntegrationLogs(ns, "config-secret-key-route"), TestTimeoutShort).Should(ContainSubstring(secDataMulti["my-secret-key-2"]))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		// Resource File
-
-		t.Run("Plain text resource file", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/resource-file-route.groovy", "--resource", "file:./files/resources-data.txt").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "resource-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "resource-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "resource-file-route"), TestTimeoutShort).Should(ContainSubstring("the file body"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-			Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
-		})
-
-		t.Run("Plain text resource file with destination path", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/resource-file-location-route.groovy", "--resource", "file:./files/resources-data.txt@/tmp/file.txt").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "resource-file-location-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "resource-file-location-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "resource-file-location-route"), TestTimeoutShort).Should(ContainSubstring("the file body"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-			Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
-		})
-
-		t.Run("Binary (zip) resource file", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/resource-file-binary-route.groovy", "--resource", "file:./files/resources-data.zip", "-d", "camel:zipfile").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "resource-file-binary-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "resource-file-binary-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "resource-file-binary-route"), TestTimeoutShort).Should(ContainSubstring("the file body"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-			Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
-		})
-
-		t.Run("Base64 compressed binary resource file", func(t *testing.T) {
-			// We calculate the expected content
-			source, err := ioutil.ReadFile("./files/resources-data.txt")
-			assert.Nil(t, err)
-			expectedBytes, err := gzip.CompressBase64([]byte(source))
-			assert.Nil(t, err)
-
-			Expect(KamelRunWithID(operatorID, ns, "./files/resource-file-base64-encoded-route.groovy", "--resource", "file:./files/resources-data.txt", "--compression=true").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "resource-file-base64-encoded-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "resource-file-base64-encoded-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "resource-file-base64-encoded-route"), TestTimeoutShort).Should(ContainSubstring(string(expectedBytes)))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-			Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
-		})
-
-		t.Run("Plain text resource file with same content", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/resource-file-route.groovy", "--resource", "file:./files/resources-data.txt",
-				"--resource", "file:./files/resources-data-same.txt").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "resource-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "resource-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "resource-file-route"), TestTimeoutShort).Should(ContainSubstring("the file body"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-			Eventually(AutogeneratedConfigmapsCount(ns), TestTimeoutShort).Should(Equal(0))
-		})
-
-		// Build-Properties
-		t.Run("Build time property", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/build-property-route.groovy", "--build-property", "quarkus.application.name=my-super-application").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "build-property-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "build-property-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "build-property-route"), TestTimeoutShort).Should(ContainSubstring("my-super-application"))
-			// Don't delete - we need it for next test execution
-		})
-
-		// We need to check also that the property (which is available in the IntegrationKit) is correctly replaced and we don't reuse the same kit
-		t.Run("Build time property updated", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/build-property-route.groovy", "--name", "build-property-route-updated",
-				"--build-property", "quarkus.application.name=my-super-application-updated").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "build-property-route-updated"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "build-property-route-updated", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "build-property-route-updated"), TestTimeoutShort).Should(ContainSubstring("my-super-application-updated"))
-			// Verify the integration kits are different
-			Expect(IntegrationKit(ns, "build-property-route")).ShouldNot(Equal(IntegrationKit(ns, "build-property-route-updated")))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		// Build-Properties file
-		t.Run("Build time property file", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "file:./files/quarkus.properties").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-super-application"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Build time property file with precedence", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "quarkus.application.name=my-overridden-application", "--build-property", "file:./files/quarkus.properties").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutMedium).Should(ContainSubstring("my-overridden-application"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Build time property from ConfigMap", func(t *testing.T) {
-			var cmData = make(map[string]string)
-			cmData["quarkus.application.name"] = "my-cool-application"
-			CreatePlainTextConfigmap(ns, "my-cm-test-build-property", cmData)
-
-			Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "configmap:my-cm-test-build-property").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutLong).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutLong).Should(ContainSubstring("my-cool-application"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Build time property from ConfigMap as property file", func(t *testing.T) {
-			var cmData = make(map[string]string)
-			cmData["my.properties"] = "quarkus.application.name=my-super-cool-application"
-			CreatePlainTextConfigmap(ns, "my-cm-test-build-properties", cmData)
-
-			Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "configmap:my-cm-test-build-properties").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-super-cool-application"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Build time property from Secret", func(t *testing.T) {
-			var secData = make(map[string]string)
-			secData["quarkus.application.name"] = "my-great-application"
-			CreatePlainTextSecret(ns, "my-sec-test-build-property", secData)
-
-			Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "secret:my-sec-test-build-property").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-great-application"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Build time property from Secret as property file", func(t *testing.T) {
-			var secData = make(map[string]string)
-			secData["my.properties"] = "quarkus.application.name=my-awsome-application"
-			CreatePlainTextSecret(ns, "my-sec-test-build-properties", secData)
-
-			Expect(KamelRunWithID(operatorID, ns, "./files/build-property-file-route.groovy", "--build-property", "secret:my-sec-test-build-properties").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "build-property-file-route"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "build-property-file-route", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "build-property-file-route"), TestTimeoutShort).Should(ContainSubstring("my-awsome-application"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-	})
-}
diff --git a/e2e/global/common/cron_test.go b/e2e/global/common/cron_test.go
deleted file mode 100644
index 26664a423..000000000
--- a/e2e/global/common/cron_test.go
+++ /dev/null
@@ -1,93 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package common
-
-import (
-	"reflect"
-	"testing"
-
-	. "github.com/onsi/gomega"
-	"github.com/stretchr/testify/assert"
-
-	batchv1 "k8s.io/api/batch/v1"
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
-)
-
-func TestRunCronExample(t *testing.T) {
-	ok, err := kubernetes.IsAPIResourceInstalled(TestClient(), batchv1.SchemeGroupVersion.String(), reflect.TypeOf(batchv1.CronJob{}).Name())
-	assert.Nil(t, err)
-
-	if !ok {
-		t.Skip("This test requires CronJob batch/v1 API installed.")
-		return
-	}
-
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-cronjob"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("cron", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/cron.yaml").Execute()).To(Succeed())
-			Eventually(IntegrationCronJob(ns, "cron"), TestTimeoutMedium).ShouldNot(BeNil())
-			Eventually(IntegrationConditionStatus(ns, "cron", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "cron"), TestTimeoutMedium).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("cron-yaml", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/cron-yaml.yaml").Execute()).To(Succeed())
-			Eventually(IntegrationCronJob(ns, "cron-yaml"), TestTimeoutMedium).ShouldNot(BeNil())
-			Eventually(IntegrationConditionStatus(ns, "cron-yaml", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "cron-yaml"), TestTimeoutMedium).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("cron-timer", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/cron-timer.yaml").Execute()).To(Succeed())
-			Eventually(IntegrationCronJob(ns, "cron-timer"), TestTimeoutMedium).ShouldNot(BeNil())
-			Eventually(IntegrationConditionStatus(ns, "cron-timer", v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "cron-timer"), TestTimeoutMedium).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("cron-fallback", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/cron-fallback.yaml").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "cron-fallback"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "cron-fallback", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "cron-fallback"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("cron-quartz", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/cron-quartz.yaml").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "cron-quartz"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "cron-quartz", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "cron-quartz"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-	})
-}
diff --git a/e2e/global/common/integration_fail_test.go b/e2e/global/common/integration_fail_test.go
deleted file mode 100644
index ebfeda9f5..000000000
--- a/e2e/global/common/integration_fail_test.go
+++ /dev/null
@@ -1,137 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package common
-
-import (
-	"testing"
-	"time"
-
-	. "github.com/onsi/gomega"
-	"github.com/onsi/gomega/gstruct"
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-)
-
-func TestBadRouteIntegration(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-bad-route"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("run bad java route", func(t *testing.T) {
-			RegisterTestingT(t)
-			name := "bad-route"
-			Expect(KamelRunWithID(operatorID, ns, "files/BadRoute.java", "--name", name).Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
-				Should(Equal(corev1.ConditionFalse))
-
-			// Make sure the Integration can be scaled
-			Expect(ScaleIntegration(ns, name, 2)).To(Succeed())
-			// Check the scale cascades into the Deployment scale
-			Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(2))
-			// Check it also cascades into the Integration scale subresource Status field
-			Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 2)))
-			// Check the Integration stays in error phase
-			Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
-
-			// Clean up
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("run missing dependency java route", func(t *testing.T) {
-			RegisterTestingT(t)
-			name := "java-route"
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name,
-				"-d", "mvn:com.example:nonexistent:1.0").Execute()).To(Succeed())
-			// Integration in error
-			Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError))
-			kitName := IntegrationKit(ns, name)()
-			// Kit in error
-			Eventually(KitPhase(ns, kitName), TestTimeoutShort).Should(Equal(v1.IntegrationKitPhaseError))
-			//Build in error with 5 attempts
-			build := Build(ns, kitName)()
-			Eventually(build.Status.Phase, TestTimeoutShort).Should(Equal(v1.BuildPhaseError))
-			Eventually(build.Status.Failure.Recovery.Attempt, TestTimeoutShort).Should(Equal(5))
-
-			// Clean up
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("run invalid dependency java route", func(t *testing.T) {
-			RegisterTestingT(t)
-			name := "invalid-dependency"
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name,
-				"-d", "camel:non-existent").Execute()).To(Succeed())
-			// Integration in error with Initialization Failed condition
-			Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
-				Should(Equal(corev1.ConditionFalse))
-			Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And(
-				WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)),
-				WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")),
-			))
-			// Kit shouldn't be created
-			Consistently(IntegrationKit(ns, name), 10*time.Second).Should(BeEmpty())
-
-			// Fixing the route should reconcile the Integration in Initialization Failed condition to Running
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
-				Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-			// Clean up
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("run unresolvable component java route", func(t *testing.T) {
-			RegisterTestingT(t)
-			name := "unresolvable-route"
-			Expect(KamelRunWithID(operatorID, ns, "files/Unresolvable.java", "--name", name).Execute()).To(Succeed())
-			// Integration in error with Initialization Failed condition
-			Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
-				Should(Equal(corev1.ConditionFalse))
-			Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And(
-				WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)),
-				WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")),
-			))
-			// Kit shouldn't be created
-			Consistently(IntegrationKit(ns, name), 10*time.Second).Should(BeEmpty())
-
-			// Fixing the route should reconcile the Integration in Initialization Failed condition to Running
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
-				Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-			// Clean up
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-	})
-}
diff --git a/e2e/global/common/kamelet_binding_test.go b/e2e/global/common/kamelet_binding_test.go
deleted file mode 100644
index 6021da9ac..000000000
--- a/e2e/global/common/kamelet_binding_test.go
+++ /dev/null
@@ -1,181 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package common
-
-import (
-	"testing"
-
-	. "github.com/onsi/gomega"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-	"github.com/apache/camel-k/pkg/util/kubernetes"
-)
-
-func TestKameletBinding(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-kameletbinding"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		// Error Handler testing
-		t.Run("test error handler", func(t *testing.T) {
-			RegisterTestingT(t)
-			Expect(createErrorProducerKamelet(ns, "my-own-error-producer-source")()).To(Succeed())
-			Expect(CreateLogKamelet(ns, "my-own-log-sink")()).To(Succeed())
-			from := corev1.ObjectReference{
-				Kind:       "Kamelet",
-				Name:       "my-own-error-producer-source",
-				APIVersion: v1alpha1.SchemeGroupVersion.String(),
-			}
-
-			to := corev1.ObjectReference{
-				Kind:       "Kamelet",
-				Name:       "my-own-log-sink",
-				APIVersion: v1alpha1.SchemeGroupVersion.String(),
-			}
-
-			errorHandler := map[string]interface{}{
-				"sink": map[string]interface{}{
-					"endpoint": map[string]interface{}{
-						"ref": map[string]string{
-							"kind":       "Kamelet",
-							"apiVersion": v1alpha1.SchemeGroupVersion.String(),
-							"name":       "my-own-log-sink",
-						},
-						"properties": map[string]string{
-							"loggerName": "kameletErrorHandler",
-						},
-					}}}
-
-			t.Run("throw error test", func(t *testing.T) {
-				RegisterTestingT(t)
-
-				Expect(BindKameletToWithErrorHandler(ns, "throw-error-binding", map[string]string{},
-					from, to,
-					map[string]string{"message": "throw Error"}, map[string]string{"loggerName": "integrationLogger"},
-					errorHandler)()).To(Succeed())
-
-				Eventually(IntegrationPodPhase(ns, "throw-error-binding"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-				Eventually(IntegrationLogs(ns, "throw-error-binding"), TestTimeoutShort).Should(ContainSubstring("kameletErrorHandler"))
-				Eventually(IntegrationLogs(ns, "throw-error-binding"), TestTimeoutShort).ShouldNot(ContainSubstring("integrationLogger"))
-
-			})
-
-			t.Run("don't throw error test", func(t *testing.T) {
-				RegisterTestingT(t)
-
-				Expect(BindKameletToWithErrorHandler(ns, "no-error-binding", map[string]string{},
-					from, to,
-					map[string]string{"message": "true"}, map[string]string{"loggerName": "integrationLogger"},
-					errorHandler)()).To(Succeed())
-
-				Eventually(IntegrationPodPhase(ns, "no-error-binding"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-				Eventually(IntegrationLogs(ns, "no-error-binding"), TestTimeoutShort).ShouldNot(ContainSubstring("kameletErrorHandler"))
-				Eventually(IntegrationLogs(ns, "no-error-binding"), TestTimeoutShort).Should(ContainSubstring("integrationLogger"))
-
-			})
-
-			// Cleanup
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
-		})
-
-		// Kamelet binding with traits testing
-		t.Run("test kamelet binding with trait", func(t *testing.T) {
-			RegisterTestingT(t)
-			Expect(CreateTimerKamelet(ns, "my-own-timer-source")()).To(Succeed())
-			// Log sink kamelet exists from previous test
-
-			from := corev1.ObjectReference{
-				Kind:       "Kamelet",
-				Name:       "my-own-timer-source",
-				APIVersion: v1alpha1.SchemeGroupVersion.String(),
-			}
-
-			to := corev1.ObjectReference{
-				Kind:       "Kamelet",
-				Name:       "my-own-log-sink",
-				APIVersion: v1alpha1.SchemeGroupVersion.String(),
-			}
-
-			Expect(BindKameletTo(ns, "kb-with-traits",
-				map[string]string{"trait.camel.apache.org/camel.properties": "[\"camel.prop1=a\",\"camel.prop2=b\"]"},
-				from, to,
-				map[string]string{"message": "hello from test"}, map[string]string{"loggerName": "integrationLogger"})()).
-				To(Succeed())
-
-			Eventually(IntegrationPodPhase(ns, "kb-with-traits"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationLogs(ns, "kb-with-traits"), TestTimeoutShort).Should(ContainSubstring("hello from test"))
-			Eventually(IntegrationLogs(ns, "kb-with-traits"), TestTimeoutShort).Should(ContainSubstring("integrationLogger"))
-		})
-
-		// KameletBinding with wrong spec
-		t.Run("test KameletBinding with wrong spec", func(t *testing.T) {
-			RegisterTestingT(t)
-			name := "bad-klb"
-			kb := v1alpha1.NewKameletBinding(ns, name)
-			kb.Spec = v1alpha1.KameletBindingSpec{}
-			_, err := kubernetes.ReplaceResource(TestContext, TestClient(), &kb)
-			Eventually(err).Should(BeNil())
-			Eventually(KameletBindingPhase(ns, name), TestTimeoutShort).Should(Equal(v1alpha1.KameletBindingPhaseError))
-			Eventually(KameletBindingConditionStatus(ns, name, v1alpha1.KameletBindingConditionReady), TestTimeoutShort).ShouldNot(Equal(corev1.ConditionTrue))
-			Eventually(KameletBindingCondition(ns, name, v1alpha1.KameletBindingIntegrationConditionError), TestTimeoutShort).Should(
-				WithTransform(KameletBindingConditionMessage, And(
-					ContainSubstring("could not determine source URI"),
-					ContainSubstring("no ref or URI specified in endpoint"),
-				)))
-		})
-	})
-}
-
-func createErrorProducerKamelet(ns string, name string) func() error {
-	props := map[string]v1alpha1.JSONSchemaProp{
-		"message": {
-			Type: "string",
-		},
-	}
-
-	flow := map[string]interface{}{
-		"from": map[string]interface{}{
-			"uri": "timer:tick",
-			"steps": []map[string]interface{}{
-				{
-					"set-body": map[string]interface{}{
-						"constant": "{{message}}",
-					},
-				},
-				{
-					"set-body": map[string]interface{}{
-						"simple": "${mandatoryBodyAs(Boolean)}",
-					},
-				},
-				{
-					"to": "kamelet:sink",
-				},
-			},
-		},
-	}
-
-	return CreateKamelet(ns, name, flow, props, nil)
-}
diff --git a/e2e/global/common/kamelet_binding_with_image_test.go b/e2e/global/common/kamelet_binding_with_image_test.go
deleted file mode 100644
index 373b3894f..000000000
--- a/e2e/global/common/kamelet_binding_with_image_test.go
+++ /dev/null
@@ -1,118 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package common
-
-import (
-	"testing"
-
-	. "github.com/onsi/gomega"
-	"github.com/onsi/gomega/gstruct"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-)
-
-func TestBindingWithImage(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-binding-image"
-		bindingID := "with-image-binding"
-
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		from := corev1.ObjectReference{
-			Kind:       "Kamelet",
-			Name:       "my-own-timer-source",
-			APIVersion: v1alpha1.SchemeGroupVersion.String(),
-		}
-
-		to := corev1.ObjectReference{
-			Kind:       "Kamelet",
-			Name:       "my-own-log-sink",
-			APIVersion: v1alpha1.SchemeGroupVersion.String(),
-		}
-
-		emptyMap := map[string]string{}
-
-		annotations1 := map[string]string{
-			"trait.camel.apache.org/container.image":      "docker.io/jmalloc/echo-server:0.3.2",
-			"trait.camel.apache.org/jvm.enabled":          "false",
-			"trait.camel.apache.org/kamelets.enabled":     "false",
-			"trait.camel.apache.org/dependencies.enabled": "false",
-			"test": "1",
-		}
-		annotations2 := map[string]string{
-			"trait.camel.apache.org/container.image":      "docker.io/jmalloc/echo-server:0.3.3",
-			"trait.camel.apache.org/jvm.enabled":          "false",
-			"trait.camel.apache.org/kamelets.enabled":     "false",
-			"trait.camel.apache.org/dependencies.enabled": "false",
-			"test": "2",
-		}
-
-		t.Run("run with initial image", func(t *testing.T) {
-			expectedImage := annotations1["trait.camel.apache.org/container.image"]
-
-			RegisterTestingT(t)
-
-			Expect(BindKameletTo(ns, bindingID, annotations1, from, to, emptyMap, emptyMap)()).
-				To(Succeed())
-			Eventually(IntegrationGeneration(ns, bindingID)).
-				Should(gstruct.PointTo(BeNumerically("==", 1)))
-			Eventually(Integration(ns, bindingID)).Should(WithTransform(Annotations, And(
-				HaveKeyWithValue("test", "1"),
-				HaveKeyWithValue("trait.camel.apache.org/container.image", expectedImage),
-			)))
-			Eventually(IntegrationStatusImage(ns, bindingID)).
-				Should(Equal(expectedImage))
-			Eventually(IntegrationPodPhase(ns, bindingID), TestTimeoutLong).
-				Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationPodImage(ns, bindingID)).
-				Should(Equal(expectedImage))
-		})
-
-		t.Run("run with new image", func(t *testing.T) {
-			expectedImage := annotations2["trait.camel.apache.org/container.image"]
-
-			RegisterTestingT(t)
-
-			Expect(BindKameletTo(ns, bindingID, annotations2, from, to, emptyMap, emptyMap)()).
-				To(Succeed())
-			Eventually(IntegrationGeneration(ns, bindingID)).
-				Should(gstruct.PointTo(BeNumerically("==", 1)))
-			Eventually(Integration(ns, bindingID)).Should(WithTransform(Annotations, And(
-				HaveKeyWithValue("test", "2"),
-				HaveKeyWithValue("trait.camel.apache.org/container.image", expectedImage),
-			)))
-			Eventually(IntegrationStatusImage(ns, bindingID)).
-				Should(Equal(expectedImage))
-			Eventually(IntegrationPodPhase(ns, bindingID), TestTimeoutLong).
-				Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationPodImage(ns, bindingID)).
-				Should(Equal(expectedImage))
-		})
-
-		// Cleanup
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
-	})
-}
diff --git a/e2e/global/common/kamelet_test.go b/e2e/global/common/kamelet_test.go
deleted file mode 100644
index 778bc3419..000000000
--- a/e2e/global/common/kamelet_test.go
+++ /dev/null
@@ -1,82 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package common
-
-import (
-	"testing"
-
-	. "github.com/onsi/gomega"
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-)
-
-func TestKameletClasspathLoading(t *testing.T) {
-
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-kamelet"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		// Basic
-		t.Run("test basic case", func(t *testing.T) {
-
-			kameletName := "timer-source"
-			removeKamelet(kameletName, ns)
-			Eventually(Kamelet(kameletName, ns)).Should(BeNil())
-
-			Expect(KamelRunWithID(operatorID, ns, "files/TimerKameletIntegration.java", "-t", "kamelets.enabled=false",
-				"--resource", "file:files/timer-source.kamelet.yaml@/kamelets/timer-source.kamelet.yaml",
-				"-p camel.component.kamelet.location=file:/kamelets",
-				"-d", "camel:yaml-dsl",
-				// kamelet dependencies
-				"-d", "camel:timer").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "timer-kamelet-integration"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-
-			Eventually(IntegrationLogs(ns, "timer-kamelet-integration")).Should(ContainSubstring("important message"))
-		})
-
-		// Custom repo without operator ID
-		t.Run("test custom Kamelet repository without operator ID", func(t *testing.T) {
-
-			kameletName := "timer-custom-source"
-			removeKamelet(kameletName, ns)
-			Eventually(Kamelet(kameletName, ns)).Should(BeNil())
-
-			// Add the custom repository
-			Expect(Kamel("kamelet", "add-repo", "github:apache/camel-k/e2e/global/common/files/kamelets", "-n", ns).Execute()).To(Succeed())
-
-			Expect(KamelRunWithID(operatorID, ns, "files/TimerCustomKameletIntegration.java").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "timer-custom-kamelet-integration"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-
-			Eventually(IntegrationLogs(ns, "timer-custom-kamelet-integration")).Should(ContainSubstring("great message"))
-
-			// Remove the custom repository
-			Expect(Kamel("kamelet", "remove-repo", "github:apache/camel-k/e2e/global/common/files/kamelets", "-n", ns).Execute()).To(Succeed())
-		})
-	})
-}
-
-func removeKamelet(name string, ns string) {
-	kamelet := Kamelet(name, ns)()
-	TestClient().Delete(TestContext, kamelet)
-}
diff --git a/e2e/global/common/languages/java_test.go b/e2e/global/common/languages/java_test.go
deleted file mode 100644
index e498b87da..000000000
--- a/e2e/global/common/languages/java_test.go
+++ /dev/null
@@ -1,61 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package languages
-
-import (
-	"testing"
-
-	. "github.com/onsi/gomega"
-
-	v1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	camelv1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-)
-
-func TestRunSimpleJavaExamples(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-examples-java"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("run java", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(v1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "java", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("run java with properties", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/Prop.java", "--property", "file:files/prop.properties").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "prop"), TestTimeoutLong).Should(Equal(v1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "prop", camelv1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(v1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "prop"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("init run java", func(t *testing.T) {
-			RunInitGeneratedExample(t, operatorID, ns, camelv1.LanguageJavaSource)
-		})
-	})
-}
diff --git a/e2e/global/common/rest_test.go b/e2e/global/common/rest_test.go
deleted file mode 100644
index 770377fc0..000000000
--- a/e2e/global/common/rest_test.go
+++ /dev/null
@@ -1,100 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package common
-
-import (
-	"fmt"
-	"io"
-	"net/http"
-	"testing"
-	"time"
-
-	. "github.com/onsi/gomega"
-	"github.com/stretchr/testify/assert"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	"github.com/apache/camel-k/pkg/util/openshift"
-)
-
-func TestRunRest(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		var profile string
-		ocp, err := openshift.IsOpenShift(TestClient())
-		assert.Nil(t, err)
-		if ocp {
-			profile = "OpenShift"
-		} else {
-			profile = "Kubernetes"
-		}
-
-		operatorID := "camel-k-rest"
-		Expect(KamelInstallWithID(operatorID, ns, "--trait-profile", profile).Execute()).To(Succeed())
-		Expect(KamelRunWithID(operatorID, ns, "files/rest-consumer.yaml").Execute()).To(Succeed())
-		Eventually(IntegrationPodPhase(ns, "rest-consumer"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-
-		t.Run("Service works", func(t *testing.T) {
-			name := "John"
-			service := Service(ns, "rest-consumer")
-			Eventually(service, TestTimeoutShort).ShouldNot(BeNil())
-			Expect(KamelRunWithID(operatorID, ns, "files/rest-producer.yaml", "-p", "serviceName=rest-consumer", "-p", "name="+name).Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "rest-producer"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationLogs(ns, "rest-consumer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("get %s", name)))
-			Eventually(IntegrationLogs(ns, "rest-producer"), TestTimeoutLong).Should(ContainSubstring(fmt.Sprintf("%s Doe", name)))
-		})
-
-		if ocp {
-			t.Run("Route works", func(t *testing.T) {
-				name := "Peter"
-				route := Route(ns, "rest-consumer")
-				Eventually(route, TestTimeoutShort).ShouldNot(BeNil())
-				Eventually(RouteStatus(ns, "rest-consumer"), TestTimeoutMedium).Should(Equal("True"))
-				url := fmt.Sprintf("http://%s/customers/%s", route().Spec.Host, name)
-				Eventually(httpRequest(url), TestTimeoutMedium).Should(Equal(fmt.Sprintf("%s Doe", name)))
-				Eventually(IntegrationLogs(ns, "rest-consumer"), TestTimeoutShort).Should(ContainSubstring(fmt.Sprintf("get %s", name)))
-			})
-		}
-
-		// Cleanup
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
-	})
-}
-
-func httpRequest(url string) func() (string, error) {
-	return func() (string, error) {
-		client := &http.Client{Timeout: 3 * time.Second}
-		response, err := client.Get(url)
-		if err != nil {
-			return "", err
-		}
-		defer response.Body.Close()
-
-		body, err := io.ReadAll(response.Body)
-		if err != nil {
-			return "", err
-		}
-
-		return string(body), nil
-	}
-}
diff --git a/e2e/global/common/scale_binding_test.go b/e2e/global/common/scale_binding_test.go
deleted file mode 100644
index 1a0dafb4f..000000000
--- a/e2e/global/common/scale_binding_test.go
+++ /dev/null
@@ -1,140 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package common
-
-import (
-	"testing"
-
-	. "github.com/onsi/gomega"
-	"github.com/onsi/gomega/gstruct"
-	"github.com/stretchr/testify/assert"
-
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/types"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-	"github.com/apache/camel-k/pkg/client/camel/clientset/versioned"
-	"github.com/apache/camel-k/pkg/util/openshift"
-)
-
-func TestKameletBindingScale(t *testing.T) {
-	ocp, err := openshift.IsOpenShift(TestClient())
-	assert.Nil(t, err)
-	if ocp {
-		t.Skip("TODO: Temporarily disabled as this test is flaky on OpenShift 3")
-		return
-	}
-
-	WithNewTestNamespace(t, func(ns string) {
-		name := "binding"
-		operatorID := "camel-k-kamelet-scale"
-		Expect(KamelInstallWithIDAndKameletCatalog(operatorID, ns, "-w").Execute()).To(Succeed())
-		Expect(KamelBindWithID(operatorID, ns, "timer-source?message=HelloBinding", "log-sink", "--name", name).Execute()).To(Succeed())
-		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-		Eventually(KameletBindingConditionStatus(ns, name, v1alpha1.KameletBindingConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("HelloBinding"))
-
-		t.Run("Update binding scale spec", func(t *testing.T) {
-			RegisterTestingT(t)
-			Expect(ScaleKameletBinding(ns, name, 3)).To(Succeed())
-			// Check the scale cascades into the Deployment scale
-			Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(3))
-			// Check it also cascades into the Integration scale subresource Status field
-			Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 3)))
-			// Check it also cascades into the KameletBinding scale subresource Status field
-			Eventually(KameletBindingStatusReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 3)))
-			// Check the readiness condition becomes truthy back
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
-			// Finally check the readiness condition becomes truthy back on kamelet binding
-			Eventually(KameletBindingConditionStatus(ns, name, v1alpha1.KameletBindingConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
-		})
-
-		t.Run("Scale kamelet binding with polymorphic client", func(t *testing.T) {
-			RegisterTestingT(t)
-			scaleClient, err := TestClient().ScalesClient()
-			Expect(err).To(BeNil())
-
-			// Patch the integration scale subresource
-			patch := "{\"spec\":{\"replicas\":2}}"
-			_, err = scaleClient.Scales(ns).Patch(TestContext, v1alpha1.SchemeGroupVersion.WithResource("kameletbindings"), name, types.MergePatchType, []byte(patch), metav1.PatchOptions{})
-			Expect(err).To(BeNil())
-
-			// Check the readiness condition is still truthy as down-scaling
-			Expect(KameletBindingConditionStatus(ns, name, v1alpha1.KameletBindingConditionReady)()).To(Equal(corev1.ConditionTrue))
-			// Check the Integration scale subresource Spec field
-			Eventually(IntegrationSpecReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 2)))
-			// Then check it cascades into the Deployment scale
-			Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(2))
-			// Check it cascades into the Integration scale subresource Status field
-			Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 2)))
-			// Finally check it cascades into the KameletBinding scale subresource Status field
-			Eventually(KameletBindingStatusReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 2)))
-		})
-
-		t.Run("Scale kamelet binding with Camel K client", func(t *testing.T) {
-			RegisterTestingT(t)
-			camel, err := versioned.NewForConfig(TestClient().GetConfig())
-			Expect(err).To(BeNil())
-
-			// Getter
-			bindingScale, err := camel.CamelV1alpha1().KameletBindings(ns).GetScale(TestContext, name, metav1.GetOptions{})
-			Expect(err).To(BeNil())
-			Expect(bindingScale.Spec.Replicas).To(BeNumerically("==", 2))
-			Expect(bindingScale.Status.Replicas).To(BeNumerically("==", 2))
-
-			// Setter
-			bindingScale.Spec.Replicas = 1
-			_, err = camel.CamelV1alpha1().KameletBindings(ns).UpdateScale(TestContext, name, bindingScale, metav1.UpdateOptions{})
-			Expect(err).To(BeNil())
-
-			// Check the readiness condition is still truthy as down-scaling in kamelet binding
-			Expect(KameletBindingConditionStatus(ns, name, v1alpha1.KameletBindingConditionReady)()).To(Equal(corev1.ConditionTrue))
-			// Check the KameletBinding scale subresource Spec field
-			Eventually(KameletBindingSpecReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 1)))
-			// Check the readiness condition is still truthy as down-scaling
-			Expect(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady)()).To(Equal(corev1.ConditionTrue))
-			// Check the Integration scale subresource Spec field
-			Eventually(IntegrationSpecReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 1)))
-			// Then check it cascades into the Deployment scale
-			Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(1))
-			// Finally check it cascades into the Integration scale subresource Status field
-			Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 1)))
-		})
-
-		// Clean up
-		RegisterTestingT(t)
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-	})
-}
diff --git a/e2e/global/common/scale_integration_test.go b/e2e/global/common/scale_integration_test.go
deleted file mode 100644
index e9789f2ce..000000000
--- a/e2e/global/common/scale_integration_test.go
+++ /dev/null
@@ -1,139 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package common
-
-import (
-	"fmt"
-	"testing"
-
-	. "github.com/onsi/gomega"
-	"github.com/onsi/gomega/gstruct"
-
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/types"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/client/camel/clientset/versioned"
-)
-
-func TestIntegrationScale(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		name := "java"
-		operatorID := "camel-k-integration-scale"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-		Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed())
-		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-		t.Run("Update integration scale spec", func(t *testing.T) {
-			RegisterTestingT(t)
-			Expect(ScaleIntegration(ns, name, 3)).To(Succeed())
-			// Check the readiness condition becomes falsy
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse))
-			// Check the scale cascades into the Deployment scale
-			Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(3))
-			// Check it also cascades into the Integration scale subresource Status field
-			Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 3)))
-			// Finally check the readiness condition becomes truthy back
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutMedium).Should(Equal(corev1.ConditionTrue))
-		})
-
-		t.Run("Scale integration with polymorphic client", func(t *testing.T) {
-			RegisterTestingT(t)
-			scaleClient, err := TestClient().ScalesClient()
-			Expect(err).To(BeNil())
-
-			// Patch the integration scale subresource
-			patch := "{\"spec\":{\"replicas\":2}}"
-			_, err = scaleClient.Scales(ns).Patch(TestContext, v1.SchemeGroupVersion.WithResource("integrations"), name, types.MergePatchType, []byte(patch), metav1.PatchOptions{})
-			Expect(err).To(BeNil())
-
-			// Check the readiness condition is still truthy as down-scaling
-			Expect(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady)()).To(Equal(corev1.ConditionTrue))
-			// Check the Integration scale subresource Spec field
-			Eventually(IntegrationSpecReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 2)))
-			// Then check it cascades into the Deployment scale
-			Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(2))
-			// Finally check it cascades into the Integration scale subresource Status field
-			Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 2)))
-		})
-
-		t.Run("Scale integration with Camel K client", func(t *testing.T) {
-			RegisterTestingT(t)
-			camel, err := versioned.NewForConfig(TestClient().GetConfig())
-			Expect(err).To(BeNil())
-
-			// Getter
-			integrationScale, err := camel.CamelV1().Integrations(ns).GetScale(TestContext, name, metav1.GetOptions{})
-			Expect(err).To(BeNil())
-			Expect(integrationScale.Spec.Replicas).To(BeNumerically("==", 2))
-			Expect(integrationScale.Status.Replicas).To(BeNumerically("==", 2))
-
-			// Setter
-			integrationScale.Spec.Replicas = 1
-			integrationScale, err = camel.CamelV1().Integrations(ns).UpdateScale(TestContext, name, integrationScale, metav1.UpdateOptions{})
-			Expect(err).To(BeNil())
-
-			// Check the readiness condition is still truthy as down-scaling
-			Expect(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady)()).To(Equal(corev1.ConditionTrue))
-			// Check the Integration scale subresource Spec field
-			Eventually(IntegrationSpecReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 1)))
-			// Then check it cascades into the Deployment scale
-			Eventually(IntegrationPods(ns, name), TestTimeoutShort).Should(HaveLen(1))
-			// Finally check it cascades into the Integration scale subresource Status field
-			Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
-				Should(gstruct.PointTo(BeNumerically("==", 1)))
-		})
-
-		t.Run("Scale integration with external image", func(t *testing.T) {
-			RegisterTestingT(t)
-
-			image := IntegrationPodImage(ns, name)()
-			Expect(image).NotTo(BeEmpty())
-			// Save resources by deleting the integration
-			Expect(Kamel("delete", name, "-n", ns).Execute()).To(Succeed())
-
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", "pre-built", "-t", fmt.Sprintf("container.image=%s", image)).Execute()).To(Succeed())
-			Eventually(IntegrationPhase(ns, "pre-built"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning))
-			Eventually(IntegrationPodPhase(ns, "pre-built"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Expect(ScaleIntegration(ns, "pre-built", 0)).To(Succeed())
-			Eventually(IntegrationPod(ns, "pre-built"), TestTimeoutMedium).Should(BeNil())
-			Expect(ScaleIntegration(ns, "pre-built", 1)).To(Succeed())
-			Eventually(IntegrationPhase(ns, "pre-built"), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning))
-			Eventually(IntegrationPodPhase(ns, "pre-built"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-
-			Expect(Kamel("delete", "pre-built", "-n", ns).Execute()).To(Succeed())
-		})
-
-		// Clean up
-		RegisterTestingT(t)
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-	})
-}
diff --git a/e2e/global/common/traits/affinity_test.go b/e2e/global/common/traits/affinity_test.go
deleted file mode 100644
index f4584df6d..000000000
--- a/e2e/global/common/traits/affinity_test.go
+++ /dev/null
@@ -1,155 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"fmt"
-	"testing"
-
-	. "github.com/onsi/gomega"
-
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-)
-
-func TestAffinityTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-affinity"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		var hostname string
-		if node, err := selectSchedulableNode(); err == nil {
-			hostname = node.Labels["kubernetes.io/hostname"]
-		} else {
-			// if 'get nodes' is not allowed, just skip tests for node affinity
-			hostname = ""
-		}
-
-		if hostname != "" {
-			t.Run("Run Java with node affinity", func(t *testing.T) {
-				Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-					"--name", "java1",
-					"-t", "affinity.enabled=true",
-					"-t", fmt.Sprintf("affinity.node-affinity-labels=kubernetes.io/hostname in(%s)", hostname)).Execute()).To(Succeed())
-				Eventually(IntegrationPodPhase(ns, "java1"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-				Eventually(IntegrationConditionStatus(ns, "java1", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-				Eventually(IntegrationLogs(ns, "java1"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-				pod := IntegrationPod(ns, "java1")()
-				Expect(pod.Spec.Affinity).NotTo(BeNil())
-				Expect(pod.Spec.Affinity.NodeAffinity).To(Equal(&corev1.NodeAffinity{
-					RequiredDuringSchedulingIgnoredDuringExecution: nodeSelector("kubernetes.io/hostname", corev1.NodeSelectorOpIn, hostname),
-				}))
-				Expect(pod.Spec.NodeName).To(Equal(hostname))
-
-				Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-			})
-		}
-
-		t.Run("Run Java with pod affinity", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-				"--name", "java2",
-				"-t", "affinity.enabled=true",
-				"-t", "affinity.pod-affinity-labels=camel.apache.org/integration").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "java2"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "java2", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "java2"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-			pod := IntegrationPod(ns, "java2")()
-			Expect(pod.Spec.Affinity).NotTo(BeNil())
-			Expect(pod.Spec.Affinity.PodAffinity).To(Equal(&corev1.PodAffinity{
-				RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{
-					podAffinityTerm("camel.apache.org/integration", metav1.LabelSelectorOpExists, "kubernetes.io/hostname"),
-				},
-			}))
-
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Run Java with pod anti affinity", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-				"--name", "java3",
-				"-t", "affinity.enabled=true",
-				"-t", "affinity.pod-anti-affinity-labels=camel.apache.org/integration").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "java3"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "java3", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "java3"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-			pod := IntegrationPod(ns, "java3")()
-			Expect(pod.Spec.Affinity).NotTo(BeNil())
-			Expect(pod.Spec.Affinity.PodAntiAffinity).To(Equal(&corev1.PodAntiAffinity{
-				RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{
-					podAffinityTerm("camel.apache.org/integration", metav1.LabelSelectorOpExists, "kubernetes.io/hostname"),
-				},
-			}))
-
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-	})
-}
-
-func selectSchedulableNode() (*corev1.Node, error) {
-	nodes, err := TestClient().CoreV1().Nodes().List(TestContext, metav1.ListOptions{})
-	if err != nil {
-		return nil, err
-	}
-	for _, node := range nodes.Items {
-		if node.Spec.Taints == nil {
-			return &node, nil
-		}
-	}
-	return nil, fmt.Errorf("no node available")
-}
-
-func nodeSelector(key string, operator corev1.NodeSelectorOperator, value string) *corev1.NodeSelector {
-	return &corev1.NodeSelector{
-		NodeSelectorTerms: []corev1.NodeSelectorTerm{
-			{
-				MatchExpressions: []corev1.NodeSelectorRequirement{
-					{
-						Key:      key,
-						Operator: operator,
-						Values:   []string{value},
-					},
-				},
-			},
-		},
-	}
-}
-
-func podAffinityTerm(key string, operator metav1.LabelSelectorOperator, topologyKey string) corev1.PodAffinityTerm {
-	return corev1.PodAffinityTerm{
-		LabelSelector: &metav1.LabelSelector{
-			MatchExpressions: []metav1.LabelSelectorRequirement{
-				{
-					Key:      key,
-					Operator: operator,
-				},
-			},
-		},
-		TopologyKey: topologyKey,
-	}
-}
diff --git a/e2e/global/common/traits/container_test.go b/e2e/global/common/traits/container_test.go
deleted file mode 100644
index 36beb45ee..000000000
--- a/e2e/global/common/traits/container_test.go
+++ /dev/null
@@ -1,104 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"testing"
-
-	. "github.com/onsi/gomega"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-)
-
-func TestContainerTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-container"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("Container image pull policy and resources configuration", func(t *testing.T) {
-			name := "java1"
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-				"-t", "container.image-pull-policy=Always",
-				"-t", "container.request-cpu=0.005",
-				"-t", "container.request-memory=100Mi",
-				"-t", "container.limit-cpu=200m",
-				"-t", "container.limit-memory=500Mi",
-				"--name", name,
-			).Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool {
-				if len(pod.Spec.Containers) != 1 {
-					return false
-				}
-				imagePullPolicy := pod.Spec.Containers[0].ImagePullPolicy
-				return imagePullPolicy == "Always"
-			}), TestTimeoutShort).Should(BeTrue())
-			Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool {
-				if len(pod.Spec.Containers) != 1 {
-					return false
-				}
-				limitsCpu := pod.Spec.Containers[0].Resources.Limits.Cpu()
-				requestsCpu := pod.Spec.Containers[0].Resources.Requests.Cpu()
-				return limitsCpu != nil && limitsCpu.String() == "200m" && requestsCpu != nil && requestsCpu.String() == "5m"
-			}), TestTimeoutShort).Should(BeTrue())
-			Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool {
-				if len(pod.Spec.Containers) != 1 {
-					return false
-				}
-				limitsMemory := pod.Spec.Containers[0].Resources.Limits.Memory()
-				requestsMemory := pod.Spec.Containers[0].Resources.Requests.Memory()
-				return limitsMemory != nil && limitsMemory.String() == "500Mi" && requestsMemory != nil && requestsMemory.String() == "100Mi"
-			}), TestTimeoutShort).Should(BeTrue())
-
-		})
-
-		t.Run("Container name", func(t *testing.T) {
-			name := "java2"
-			containerName := "my-container-name"
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-				"-t", "container.name="+containerName,
-				"--name", name,
-			).Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Eventually(IntegrationPodHas(ns, name, func(pod *corev1.Pod) bool {
-				if len(pod.Spec.Containers) != 1 {
-					return false
-				}
-				podContainerName := pod.Spec.Containers[0].Name
-				return podContainerName == containerName
-			}), TestTimeoutShort).Should(BeTrue())
-
-		})
-
-		// Clean-up
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-
-	})
-}
diff --git a/e2e/global/common/traits/deployment_test.go b/e2e/global/common/traits/deployment_test.go
deleted file mode 100644
index 9d9a23c22..000000000
--- a/e2e/global/common/traits/deployment_test.go
+++ /dev/null
@@ -1,98 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	appsv1 "k8s.io/api/apps/v1"
-	"testing"
-
-	. "github.com/onsi/gomega"
-	. "github.com/onsi/gomega/gstruct"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-)
-
-func TestRecreateDeploymentStrategyTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-jolokia"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("Run with Recreate Deployment Strategy", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-				"-t", "deployment.strategy="+string(appsv1.RecreateDeploymentStrategyType)).
-				Execute()).To(Succeed())
-
-			Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-			Eventually(Deployment(ns, "java"), TestTimeoutMedium).Should(PointTo(MatchFields(IgnoreExtras,
-				Fields{
-					"Spec": MatchFields(IgnoreExtras,
-						Fields{
-							"Strategy": MatchFields(IgnoreExtras,
-								Fields{
-									"Type": Equal(appsv1.RecreateDeploymentStrategyType),
-								}),
-						}),
-				}),
-			))
-
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-	})
-}
-
-func TestRollingUpdateDeploymentStrategyTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-jolokia"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("Run with RollingUpdate Deployment Strategy", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-				"-t", "deployment.strategy="+string(appsv1.RollingUpdateDeploymentStrategyType)).
-				Execute()).To(Succeed())
-
-			Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-			Eventually(Deployment(ns, "java"), TestTimeoutMedium).Should(PointTo(MatchFields(IgnoreExtras,
-				Fields{
-					"Spec": MatchFields(IgnoreExtras,
-						Fields{
-							"Strategy": MatchFields(IgnoreExtras,
-								Fields{
-									"Type": Equal(appsv1.RollingUpdateDeploymentStrategyType),
-								}),
-						}),
-				}),
-			))
-
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-	})
-}
diff --git a/e2e/global/common/traits/error_handler_test.go b/e2e/global/common/traits/error_handler_test.go
deleted file mode 100644
index 36728da17..000000000
--- a/e2e/global/common/traits/error_handler_test.go
+++ /dev/null
@@ -1,59 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"testing"
-
-	. "github.com/onsi/gomega"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-)
-
-func TestErrorHandlerTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-errorhandler"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("Run errored integration with error handler", func(t *testing.T) {
-			name := "error-handler"
-			Expect(KamelRunWithID(operatorID, ns, "files/ErroredRoute.java",
-				"--name", name,
-				"-t", "error-handler.enabled=true",
-				"-t", "error-handler.ref=defaultErrorHandler",
-				"-p", "camel.beans.defaultErrorHandler=#class:org.apache.camel.builder.DeadLetterChannelBuilder",
-				"-p", "camel.beans.defaultErrorHandler.deadLetterUri=log:my-special-error-handler-in-place?level=ERROR&showCaughtException=false&showBody=false&showBodyType=false&showExchangePattern=false",
-			).Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).ShouldNot(ContainSubstring("InvalidPayloadException"))
-			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("my-special-error-handler-in-place"))
-		})
-
-		// Clean up
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-	})
-}
diff --git a/e2e/global/common/traits/errored_trait_test.go b/e2e/global/common/traits/errored_trait_test.go
deleted file mode 100644
index a94c18e19..000000000
--- a/e2e/global/common/traits/errored_trait_test.go
+++ /dev/null
@@ -1,82 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"testing"
-
-	. "github.com/onsi/gomega"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-)
-
-func TestErroredTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-errored"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("Integration trait should fail", func(t *testing.T) {
-			name := "it-errored"
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-				"--name", name,
-				"-t", "kamelets.list=missing",
-			).Execute()).To(Succeed())
-			Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse))
-			Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And(
-				WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)),
-				WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")),
-			))
-		})
-
-		t.Run("KameletBinding trait should fail", func(t *testing.T) {
-			name := "kb-errored"
-			Expect(KamelBindWithID(operatorID, ns, "timer:foo", "log:bar",
-				"--name", name,
-				"-t", "kamelets.list=missing",
-			).Execute()).To(Succeed())
-			// KameletBinding
-			Eventually(KameletBindingPhase(ns, name), TestTimeoutShort).Should(Equal(v1alpha1.KameletBindingPhaseError))
-			Eventually(KameletBindingConditionStatus(ns, name, v1alpha1.KameletBindingConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse))
-			Eventually(KameletBindingCondition(ns, name, v1alpha1.KameletBindingConditionReady), TestTimeoutShort).Should(
-				WithTransform(KameletBindingConditionMessage, And(
-					ContainSubstring("error during trait customization"),
-					ContainSubstring("[missing] not found"),
-				)))
-			// Integration related
-			Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionFalse))
-			Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(And(
-				WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionInitializationFailedReason)),
-				WithTransform(IntegrationConditionMessage, HavePrefix("error during trait customization")),
-			))
-		})
-
-		// Clean up
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-	})
-}
diff --git a/e2e/global/common/traits/health_test.go b/e2e/global/common/traits/health_test.go
deleted file mode 100644
index e1c852e0c..000000000
--- a/e2e/global/common/traits/health_test.go
+++ /dev/null
@@ -1,345 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"encoding/json"
-	"fmt"
-	camelv1alpha1 "github.com/apache/camel-k/pkg/apis/camel/v1alpha1"
-	"os"
-	"testing"
-	"time"
-
-	. "github.com/onsi/gomega"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-)
-
-/*
- * TODO
- * Test has issues on OCP4. See TODO comment in-test for details.
- *
- * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment.
- */
-func TestHealthTrait(t *testing.T) {
-	if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" {
-		t.Skip("WARNING: Test marked as problematic ... skipping")
-	}
-
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-health"
-
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("Readiness condition with stopped route", func(t *testing.T) {
-			name := "java"
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-				"-t", "health.enabled=true",
-				// Enable Jolokia for the test to stop the Camel route
-				"-t", "jolokia.enabled=true",
-				"-t", "jolokia.use-ssl-client-authentication=false",
-				"-t", "jolokia.protocol=http",
-			).Execute()).To(Succeed())
-
-			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
-				Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-			pod := IntegrationPod(ns, name)()
-
-			// Stop the Camel route
-			request := map[string]string{
-				"type":      "exec",
-				"mbean":     "org.apache.camel:context=camel-1,name=\"route1\",type=routes",
-				"operation": "stop()",
-			}
-			body, err := json.Marshal(request)
-			Expect(err).To(BeNil())
-
-			response, err := TestClient().CoreV1().RESTClient().Post().
-				AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod.Name)).
-				Body(body).
-				DoRaw(TestContext)
-			Expect(err).To(BeNil())
-			Expect(response).To(ContainSubstring(`"status":200`))
-
-			// Check the ready condition has turned false
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
-				Should(Equal(corev1.ConditionFalse))
-			// And it contains details about the runtime state
-
-			//
-			// TODO
-			// Integration has different runtime state reporting on OCP4
-			//
-			// lastProbeTime: null
-			// lastTransitionTime: "2021-12-08T20:12:14Z"
-			// message: 'containers with unready status: [integration]'
-			// reason: ContainersNotReady
-			// status: "False"
-			// type: Ready
-			//
-			Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And(
-				WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)),
-				WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready"))))
-
-			Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(
-				Satisfy(func(c *v1.IntegrationCondition) bool {
-					if c.Status != corev1.ConditionFalse {
-						return false
-					}
-					if len(c.Pods) != 1 {
-						return false
-					}
-
-					var r *v1.HealthCheckResponse
-
-					for h := range c.Pods[0].Health {
-						if c.Pods[0].Health[h].Name == "camel-routes" {
-							r = &c.Pods[0].Health[h]
-						}
-					}
-
-					if r == nil {
-						return false
-					}
-
-					if r.Data == nil {
-						return false
-					}
-
-					var data map[string]interface{}
-					if err := json.Unmarshal(r.Data, &data); err != nil {
-						return false
-					}
-
-					return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped"
-				}))
-
-			Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseError))
-
-			// Clean-up
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Readiness condition with stopped binding", func(t *testing.T) {
-			name := "stopped-binding"
-
-			Expect(CreateTimerKamelet(ns, "my-own-timer-source")()).To(Succeed())
-			Expect(CreateLogKamelet(ns, "my-own-log-sink")()).To(Succeed())
-
-			from := corev1.ObjectReference{
-				Kind:       "Kamelet",
-				Name:       "my-own-timer-source",
-				APIVersion: camelv1alpha1.SchemeGroupVersion.String(),
-			}
-
-			fromParams := map[string]string{
-				"message": "Magicstring!",
-			}
-
-			to := corev1.ObjectReference{
-				Kind:       "Kamelet",
-				Name:       "my-own-log-sink",
-				APIVersion: camelv1alpha1.SchemeGroupVersion.String(),
-			}
-
-			toParams := map[string]string{
-				"loggerName": "binding",
-			}
-
-			annotations := map[string]string{
-				"trait.camel.apache.org/health.enabled":                        "true",
-				"trait.camel.apache.org/jolokia.enabled":                       "true",
-				"trait.camel.apache.org/jolokia.use-ssl-client-authentication": "false",
-				"trait.camel.apache.org/jolokia.protocol":                      "http",
-			}
-
-			Expect(BindKameletTo(ns, name, annotations, from, to, fromParams, toParams)()).
-				To(Succeed())
-
-			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-			pod := IntegrationPod(ns, name)()
-
-			// Stop the Camel route
-			request := map[string]string{
-				"type":      "exec",
-				"mbean":     "org.apache.camel:context=camel-1,name=\"binding\",type=routes",
-				"operation": "stop()",
-			}
-			body, err := json.Marshal(request)
-			Expect(err).To(BeNil())
-
-			response, err := TestClient().CoreV1().RESTClient().Post().
-				AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod.Name)).
-				Body(body).
-				DoRaw(TestContext)
-
-			Expect(err).To(BeNil())
-			Expect(response).To(ContainSubstring(`"status":200`))
-
-			// Check the ready condition has turned false
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).
-				Should(Equal(corev1.ConditionFalse))
-			// And it contains details about the runtime state
-
-			Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And(
-				WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)),
-				WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready"))))
-
-			Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(
-				Satisfy(func(c *v1.IntegrationCondition) bool {
-					if c.Status != corev1.ConditionFalse {
-						return false
-					}
-					if len(c.Pods) != 1 {
-						return false
-					}
-
-					var r *v1.HealthCheckResponse
-
-					for h := range c.Pods[0].Health {
-						if c.Pods[0].Health[h].Name == "camel-routes" {
-							r = &c.Pods[0].Health[h]
-						}
-					}
-
-					if r == nil {
-						return false
-					}
-
-					if r.Data == nil {
-						return false
-					}
-
-					var data map[string]interface{}
-					if err := json.Unmarshal(r.Data, &data); err != nil {
-						return false
-					}
-
-					return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "binding"
-				}))
-
-			Eventually(KameletBindingCondition(ns, name, camelv1alpha1.KameletBindingConditionReady), TestTimeoutLong).Should(
-				Satisfy(func(c *camelv1alpha1.KameletBindingCondition) bool {
-					if c.Status != corev1.ConditionFalse {
-						return false
-					}
-					if len(c.Pods) != 1 {
-						return false
-					}
-
-					var r *v1.HealthCheckResponse
-
-					for h := range c.Pods[0].Health {
-						if c.Pods[0].Health[h].Name == "camel-routes" {
-							r = &c.Pods[0].Health[h]
-						}
-					}
-
-					if r == nil {
-						return false
-					}
-
-					if r.Data == nil {
-						return false
-					}
-
-					var data map[string]interface{}
-					if err := json.Unmarshal(r.Data, &data); err != nil {
-						return false
-					}
-
-					return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "binding"
-				}))
-
-			// Clean-up
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Readiness condition with never ready route", func(t *testing.T) {
-			name := "never-ready"
-
-			Expect(KamelRunWithID(operatorID, ns, "files/NeverReady.java",
-				"-t", "health.enabled=true",
-			).Execute()).To(Succeed())
-
-			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationPhase(ns, name), TestTimeoutShort).Should(Equal(v1.IntegrationPhaseRunning))
-			Consistently(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), 1*time.Minute).
-				Should(Equal(corev1.ConditionFalse))
-			Eventually(IntegrationPhase(ns, name), TestTimeoutLong).Should(Equal(v1.IntegrationPhaseError))
-
-			// Check that the error message is propagated from health checks even if deployment never becomes ready
-			Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(And(
-				WithTransform(IntegrationConditionReason, Equal(v1.IntegrationConditionRuntimeNotReadyReason)),
-				WithTransform(IntegrationConditionMessage, Equal("1/1 pods are not ready"))))
-
-			Eventually(IntegrationCondition(ns, name, v1.IntegrationConditionReady), TestTimeoutLong).Should(
-				Satisfy(func(c *v1.IntegrationCondition) bool {
-					if c.Status != corev1.ConditionFalse {
-						return false
-					}
-					if len(c.Pods) != 1 {
-						return false
-					}
-
-					var r *v1.HealthCheckResponse
-
-					for h := range c.Pods[0].Health {
-						if c.Pods[0].Health[h].Name == "camel-routes" {
-							r = &c.Pods[0].Health[h]
-						}
-					}
-
-					if r == nil {
-						return false
-					}
-
-					if r.Data == nil {
-						return false
-					}
-
-					var data map[string]interface{}
-					if err := json.Unmarshal(r.Data, &data); err != nil {
-						return false
-					}
-
-					return data["check.kind"].(string) == "READINESS" && data["route.status"].(string) == "Stopped" && data["route.id"].(string) == "never-ready"
-				}))
-
-			// Clean-up
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-	})
-}
diff --git a/e2e/global/common/traits/jolokia_test.go b/e2e/global/common/traits/jolokia_test.go
deleted file mode 100644
index 533b306cf..000000000
--- a/e2e/global/common/traits/jolokia_test.go
+++ /dev/null
@@ -1,61 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"fmt"
-	"testing"
-
-	. "github.com/onsi/gomega"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-)
-
-func TestJolokiaTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-jolokia"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("Run Java with Jolokia", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-				"-t", "jolokia.enabled=true",
-				"-t", "jolokia.use-ssl-client-authentication=false",
-				"-t", "jolokia.protocol=http",
-				"-t", "jolokia.extended-client-check=false").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "java"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, "java", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, "java"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-			pod := IntegrationPod(ns, "java")
-			response, err := TestClient().CoreV1().RESTClient().Get().
-				AbsPath(fmt.Sprintf("/api/v1/namespaces/%s/pods/%s/proxy/jolokia/", ns, pod().Name)).DoRaw(TestContext)
-			Expect(err).To(BeNil())
-			Expect(response).To(ContainSubstring(`"status":200`))
-
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-	})
-}
diff --git a/e2e/global/common/traits/master_test.go b/e2e/global/common/traits/master_test.go
deleted file mode 100644
index 731ec7adf..000000000
--- a/e2e/global/common/traits/master_test.go
+++ /dev/null
@@ -1,84 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"os"
-	"testing"
-	"time"
-
-	. "github.com/onsi/gomega"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-)
-
-func TestMasterTrait(t *testing.T) {
-	/*
-	* TODO
-	* The test just keeps randomly failing, either on kind or OCP4 clusters.
-	* The integration times out before spinning up or tests for the Magicstring
-	* fail.
-	*
-	* Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment.
-	 */
-	if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" {
-		t.Skip("WARNING: Test marked as problematic ... skipping")
-	}
-
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-master"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("master works", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/Master.java").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "master"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationLogs(ns, "master"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("only one integration with master runs", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/Master.java",
-				"--name", "first",
-				"--label", "leader-group=same",
-				"-t", "master.label-key=leader-group",
-				"-t", "master.label-value=same",
-				"-t", "owner.target-labels=leader-group").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "first"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationLogs(ns, "first"), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-			// Start a second integration with the same lock (it should not start the route)
-			Expect(KamelRunWithID(operatorID, ns, "files/Master.java",
-				"--name", "second",
-				"--label", "leader-group=same",
-				"-t", "master.label-key=leader-group",
-				"-t", "master.label-value=same",
-				"-t", "master.resource-name=first-lock",
-				"-t", "owner.target-labels=leader-group").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "second"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationLogs(ns, "second"), TestTimeoutShort).Should(ContainSubstring("started in"))
-			Eventually(IntegrationLogs(ns, "second"), 30*time.Second).ShouldNot(ContainSubstring("Magicstring!"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-	})
-}
diff --git a/e2e/global/common/traits/openapi_test.go b/e2e/global/common/traits/openapi_test.go
deleted file mode 100644
index d9bf91303..000000000
--- a/e2e/global/common/traits/openapi_test.go
+++ /dev/null
@@ -1,118 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"io/ioutil"
-	"os"
-	"testing"
-
-	. "github.com/onsi/gomega"
-	"github.com/stretchr/testify/assert"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-)
-
-/*
- * TODO
- * Despite the kit and integration being correctly built and the
- * integration phase changed to running, no pod is being created.
- *
- * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment.
- */
-func TestOpenAPI(t *testing.T) {
-	if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" {
-		t.Skip("WARNING: Test marked as problematic ... skipping")
-	}
-
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-openapi"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		Expect(KamelRunWithID(operatorID, ns,
-			"--name", "petstore",
-			"--open-api", "file:files/openapi/petstore-api.yaml",
-			"files/openapi/petstore.groovy",
-		).Execute()).To(Succeed())
-
-		Eventually(IntegrationPodPhase(ns, "petstore"), TestTimeoutLong).
-			Should(Equal(corev1.PodRunning))
-		Eventually(Deployment(ns, "petstore"), TestTimeoutLong).
-			Should(Not(BeNil()))
-
-		Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium).
-			Should(ContainSubstring("Started listPets (rest://get:/v1:/pets)"))
-		Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium).
-			Should(ContainSubstring("Started createPets (rest://post:/v1:/pets)"))
-		Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium).
-			Should(ContainSubstring("Started showPetById (rest://get:/v1:/pets/%7BpetId%7D)"))
-
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-	})
-}
-
-/*
- * TODO
- * Despite the kit and integration being correctly built and the
- * integration phase changed to running, no pod is being created.
- *
- * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment.
- */
-func TestOpenAPIConfigmap(t *testing.T) {
-	if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" {
-		t.Skip("WARNING: Test marked as problematic ... skipping")
-	}
-
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-openapi-configmap"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		openapiContent, err := ioutil.ReadFile("./files/openapi/petstore-api.yaml")
-		assert.Nil(t, err)
-		var cmDataProps = make(map[string]string)
-		cmDataProps["petstore-api.yaml"] = string(openapiContent)
-		CreatePlainTextConfigmap(ns, "my-openapi", cmDataProps)
-
-		Expect(KamelRunWithID(operatorID, ns,
-			"--name", "petstore",
-			"--open-api", "configmap:my-openapi",
-			"files/openapi/petstore.groovy",
-		).Execute()).To(Succeed())
-
-		Eventually(IntegrationPodPhase(ns, "petstore"), TestTimeoutLong).
-			Should(Equal(corev1.PodRunning))
-		Eventually(Deployment(ns, "petstore"), TestTimeoutLong).
-			Should(Not(BeNil()))
-
-		Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium).
-			Should(ContainSubstring("Started listPets (rest://get:/v1:/pets)"))
-		Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium).
-			Should(ContainSubstring("Started createPets (rest://post:/v1:/pets)"))
-		Eventually(IntegrationLogs(ns, "petstore"), TestTimeoutMedium).
-			Should(ContainSubstring("Started showPetById (rest://get:/v1:/pets/%7BpetId%7D)"))
-
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-	})
-}
diff --git a/e2e/global/common/traits/pdb_test.go b/e2e/global/common/traits/pdb_test.go
deleted file mode 100644
index e0a69993c..000000000
--- a/e2e/global/common/traits/pdb_test.go
+++ /dev/null
@@ -1,175 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"net/http"
-	"os"
-	"testing"
-
-	. "github.com/onsi/gomega"
-	. "github.com/onsi/gomega/gstruct"
-
-	corev1 "k8s.io/api/core/v1"
-	policyv1 "k8s.io/api/policy/v1"
-	"k8s.io/apimachinery/pkg/api/errors"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/apimachinery/pkg/util/intstr"
-
-	ctrl "sigs.k8s.io/controller-runtime/pkg/client"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-)
-
-/*
- * TODO
- * Test has issues on OCP4. Scaling test on ~L87 keeps failing
- *
- * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment.
- */
-func TestPodDisruptionBudgetTrait(t *testing.T) {
-	if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" {
-		t.Skip("WARNING: Test marked as problematic ... skipping")
-	}
-
-	WithNewTestNamespace(t, func(ns string) {
-		name := "java"
-		operatorID := "camel-k-trait-pod-disruption"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-		Expect(KamelRunWithID(operatorID, ns, "files/Java.java",
-			"--name", name,
-			"-t", "pdb.enabled=true",
-			"-t", "pdb.min-available=2",
-		).Execute()).To(Succeed())
-
-		Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-		Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-		// Check PodDisruptionBudget
-		Eventually(podDisruptionBudget(ns, name), TestTimeoutShort).ShouldNot(BeNil())
-		pdb := podDisruptionBudget(ns, name)()
-		// Assert PDB Spec
-		Expect(pdb.Spec.MinAvailable).To(PointTo(Equal(intstr.FromInt(2))))
-		// Assert PDB Status
-		Eventually(podDisruptionBudget(ns, name), TestTimeoutShort).
-			Should(MatchFieldsP(IgnoreExtras, Fields{
-				"Status": MatchFields(IgnoreExtras, Fields{
-					"ObservedGeneration": BeNumerically("==", 1),
-					"DisruptionsAllowed": BeNumerically("==", 0),
-					"CurrentHealthy":     BeNumerically("==", 1),
-					"DesiredHealthy":     BeNumerically("==", 2),
-					"ExpectedPods":       BeNumerically("==", 1),
-				}),
-			}))
-
-		// Scale Integration
-		Expect(ScaleIntegration(ns, name, 2)).To(Succeed())
-		Eventually(IntegrationPods(ns, name), TestTimeoutMedium).Should(HaveLen(2))
-		Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
-			Should(PointTo(BeNumerically("==", 2)))
-		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-
-		// Check PodDisruptionBudget
-		pdb = podDisruptionBudget(ns, name)()
-		Expect(pdb).NotTo(BeNil())
-		// Assert PDB Status according to the scale change
-		Eventually(podDisruptionBudget(ns, name), TestTimeoutShort).
-			Should(MatchFieldsP(IgnoreExtras, Fields{
-				"Status": MatchFields(IgnoreExtras, Fields{
-					"ObservedGeneration": BeNumerically("==", 1),
-					"DisruptionsAllowed": BeNumerically("==", 0),
-					"CurrentHealthy":     BeNumerically("==", 2),
-					"DesiredHealthy":     BeNumerically("==", 2),
-					"ExpectedPods":       BeNumerically("==", 2),
-				}),
-			}))
-
-		// Eviction attempt
-		pods := IntegrationPods(ns, name)()
-		Expect(pods).To(HaveLen(2))
-		err := TestClient().CoreV1().Pods(ns).EvictV1(TestContext, &policyv1.Eviction{
-			ObjectMeta: metav1.ObjectMeta{
-				Name: pods[0].Name,
-			},
-		})
-		Expect(err).To(MatchError(&errors.StatusError{
-			ErrStatus: metav1.Status{
-				Status:  "Failure",
-				Message: "Cannot evict pod as it would violate the pod's disruption budget.",
-				Reason:  "TooManyRequests",
-				Code:    http.StatusTooManyRequests,
-				Details: &metav1.StatusDetails{
-					Causes: []metav1.StatusCause{
-						{
-							Type:    "DisruptionBudget",
-							Message: "The disruption budget java needs 2 healthy pods and has 2 currently",
-						},
-					},
-				},
-			},
-		}))
-
-		// Scale Integration to Scale > PodDisruptionBudgetSpec.MinAvailable
-		// for the eviction request to succeed once replicas are ready
-		Expect(ScaleIntegration(ns, name, 3)).To(Succeed())
-		Eventually(IntegrationPods(ns, name), TestTimeoutMedium).Should(HaveLen(3))
-		Eventually(IntegrationStatusReplicas(ns, name), TestTimeoutShort).
-			Should(PointTo(BeNumerically("==", 3)))
-		Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-
-		pods = IntegrationPods(ns, name)()
-		Expect(pods).To(HaveLen(3))
-		Expect(TestClient().CoreV1().Pods(ns).EvictV1(TestContext, &policyv1.Eviction{
-			ObjectMeta: metav1.ObjectMeta{
-				Name: pods[0].Name,
-			},
-		})).To(Succeed())
-
-		// Clean up
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-	})
-}
-
-func podDisruptionBudget(ns string, name string) func() *policyv1.PodDisruptionBudget {
-	return func() *policyv1.PodDisruptionBudget {
-		pdb := policyv1.PodDisruptionBudget{
-			TypeMeta: metav1.TypeMeta{
-				APIVersion: policyv1.SchemeGroupVersion.String(),
-				Kind:       "PodDisruptionBudget",
-			},
-			ObjectMeta: metav1.ObjectMeta{
-				Namespace: ns,
-				Name:      name,
-			},
-		}
-		err := TestClient().Get(TestContext, ctrl.ObjectKeyFromObject(&pdb), &pdb)
-		if err != nil && errors.IsNotFound(err) {
-			return nil
-		} else if err != nil {
-			panic(err)
-		}
-		return &pdb
-	}
-}
diff --git a/e2e/global/common/traits/pull_secret_test.go b/e2e/global/common/traits/pull_secret_test.go
deleted file mode 100644
index 6388204ce..000000000
--- a/e2e/global/common/traits/pull_secret_test.go
+++ /dev/null
@@ -1,93 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"testing"
-
-	. "github.com/onsi/gomega"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-	"github.com/apache/camel-k/pkg/util/openshift"
-)
-
-func TestPullSecretTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		ocp, err := openshift.IsOpenShift(TestClient())
-		Expect(err).To(BeNil())
-
-		operatorID := "camel-k-trait-pull-secret"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("Image pull secret is set on pod", func(t *testing.T) {
-			name := "java1"
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name,
-				"-t", "pull-secret.enabled=true",
-				"-t", "pull-secret.secret-name=dummy-secret").Execute()).To(Succeed())
-			// pod may not run because the pull secret is dummy
-			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Or(Equal(corev1.PodRunning), Equal(corev1.PodPending)))
-
-			pod := IntegrationPod(ns, name)()
-			Expect(pod.Spec.ImagePullSecrets).NotTo(BeEmpty())
-			Expect(pod.Spec.ImagePullSecrets[0].Name).To(Equal("dummy-secret"))
-		})
-
-		t.Run("Explicitly disable image pull secret", func(t *testing.T) {
-			name := "java2"
-			Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name,
-				"-t", "pull-secret.enabled=false").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-			Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-			pod := IntegrationPod(ns, name)()
-			if ocp {
-				// OpenShift `default` service account has imagePullSecrets so it's always set
-				Expect(pod.Spec.ImagePullSecrets).NotTo(BeEmpty())
-			} else {
-				Expect(pod.Spec.ImagePullSecrets).To(BeNil())
-			}
-		})
-
-		if ocp {
-			// OpenShift always has an internal registry so image pull secret is set by default
-			t.Run("Image pull secret is automatically set by default", func(t *testing.T) {
-				name := "java3"
-				Expect(KamelRunWithID(operatorID, ns, "files/Java.java", "--name", name).Execute()).To(Succeed())
-				Eventually(IntegrationPodPhase(ns, name), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-				Eventually(IntegrationConditionStatus(ns, name, v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-				Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
-
-				pod := IntegrationPod(ns, name)()
-				Expect(pod.Spec.ImagePullSecrets).NotTo(BeEmpty())
-				Expect(pod.Spec.ImagePullSecrets[0].Name).To(HavePrefix("default-dockercfg-"))
-			})
-		}
-
-		// Clean-up
-		Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-	})
-}
diff --git a/e2e/global/common/traits/route_test.go b/e2e/global/common/traits/route_test.go
deleted file mode 100644
index fa24aa2a7..000000000
--- a/e2e/global/common/traits/route_test.go
+++ /dev/null
@@ -1,341 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"bytes"
-	"crypto/rand"
-	"crypto/rsa"
-	"crypto/tls"
-	"crypto/x509"
-	"crypto/x509/pkix"
-	"encoding/pem"
-	"fmt"
-	"math/big"
-	rand2 "math/rand"
-	"net/http"
-	"os"
-	"testing"
-	"time"
-
-	. "github.com/onsi/gomega"
-	"github.com/stretchr/testify/assert"
-
-	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-	"github.com/apache/camel-k/pkg/util/openshift"
-)
-
-const (
-	secretName      = "test-certificate"
-	integrationName = "platform-http-server"
-)
-
-var waitBeforeHttpRequest = TestTimeoutShort / 2
-
-type keyCertificatePair struct {
-	Key         []byte
-	Certificate []byte
-}
-
-// self-signed certificate used when making the https request
-var certPem []byte
-
-// the e2e tests run on OpenShift 3 and there is no object to retrieve the base domain name
-// to create a valid hostname to later have it validated when doing the HTTPS request.
-// As this e2e test validates the route object and not the certificate itself,
-// if the base domain name cannot be retrieved from dns/cluster, we can safely skip TLS verification.
-// if running on openshift4, there is the dns/cluster object to retrieve the base domain name,
-// then in this case the HTTP client validates the TLS certificate.
-var skipClientTLSVerification = true
-
-/*
- * TODO
- * Test needs to be modified as route for unsecured http is not created on OCP.
- * Already skipped when executed using Kind since cluster does not support route API.
- *
- * Adding CAMEL_K_TEST_SKIP_PROBLEMATIC env var for the moment.
- */
-func TestRunRoutes(t *testing.T) {
-	if os.Getenv("CAMEL_K_TEST_SKIP_PROBLEMATIC") == "true" {
-		t.Skip("WARNING: Test marked as problematic ... skipping")
-	}
-
-	WithNewTestNamespace(t, func(ns string) {
-		ocp, err := openshift.IsOpenShift(TestClient())
-		if !ocp {
-			t.Skip("This test requires route object which is available on OpenShift only.")
-			return
-		}
-		assert.Nil(t, err)
-
-		operatorID := "camel-k-trait-route"
-		Expect(KamelInstallWithID(operatorID, ns, "--trait-profile=openshift").Execute()).To(Succeed())
-
-		// create a test secret of type tls with certificates
-		// this secret is used to setupt the route TLS object across diferent tests
-		secret, err := createSecret(ns)
-		assert.Nil(t, err)
-
-		// they refer to the certificates create in the secret and are reused the different tests
-		refKey := secretName + "/" + corev1.TLSPrivateKeyKey
-		refCert := secretName + "/" + corev1.TLSCertKey
-
-		// =============================
-		// Insecure Route / No TLS
-		// =============================
-		t.Run("Route unsecure http works", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			route := Route(ns, integrationName)
-			Eventually(route, TestTimeoutMedium).ShouldNot(BeNil())
-			// must wait a little time after route is created, before doing an http request,
-			// otherwise the route is unavailable and the http request will fail
-			time.Sleep(waitBeforeHttpRequest)
-			url := fmt.Sprintf("http://%s/hello?name=Simple", route().Spec.Host)
-			Eventually(httpRequest(url, false), TestTimeoutShort).Should(Equal("Hello Simple"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
-		})
-
-		// =============================
-		// TLS Route Edge
-		// =============================
-		t.Run("Route Edge https works", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java", "-t", "route.tls-termination=edge").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			route := Route(ns, integrationName)
-			Eventually(route, TestTimeoutMedium).ShouldNot(BeNil())
-			// must wait a little time after route is created, before an http request,
-			// otherwise the route is unavailable and the http request will fail
-			time.Sleep(waitBeforeHttpRequest)
-			url := fmt.Sprintf("https://%s/hello?name=TLS_Edge", route().Spec.Host)
-			Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello TLS_Edge"))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
-		})
-
-		// =============================
-		// TLS Route Edge with custom certificate
-		// =============================
-		t.Run("Route Edge (custom certificate) https works", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
-				"-t", "route.tls-termination=edge",
-				"-t", "route.tls-certificate-secret="+refCert,
-				"-t", "route.tls-key-secret="+refKey,
-			).Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			route := Route(ns, integrationName)
-			Eventually(route, TestTimeoutMedium).ShouldNot(BeNil())
-			// must wait a little time after route is created, before an http request,
-			// otherwise the route is unavailable and the http request will fail
-			time.Sleep(waitBeforeHttpRequest)
-			code := "TLS_EdgeCustomCertificate"
-			url := fmt.Sprintf("https://%s/hello?name=%s", route().Spec.Host, code)
-			Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello " + code))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
-		})
-
-		// =============================
-		// TLS Route Passthrough
-		// =============================
-		t.Run("Route passthrough https works", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
-				// the --resource mounts the certificates inside secret as files in the integration pod
-				"--resource", "secret:"+secretName+"@/etc/ssl/"+secretName,
-				// quarkus platform-http uses these two properties to setup the HTTP endpoint with TLS support
-				"-p", "quarkus.http.ssl.certificate.file=/etc/ssl/"+secretName+"/tls.crt",
-				"-p", "quarkus.http.ssl.certificate.key-file=/etc/ssl/"+secretName+"/tls.key",
-				"-t", "route.tls-termination=passthrough",
-				"-t", "container.port=8443",
-			).Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-			route := Route(ns, integrationName)
-			Eventually(route, TestTimeoutMedium).ShouldNot(BeNil())
-			// must wait a little time after route is created, before an http request,
-			// otherwise the route is unavailable and the http request will fail
-			time.Sleep(waitBeforeHttpRequest)
-			code := "TLS_Passthrough"
-			url := fmt.Sprintf("https://%s/hello?name=%s", route().Spec.Host, code)
-			Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello " + code))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
-		})
-
-		// =============================
-		// TLS Route Reencrypt
-		// =============================
-		t.Run("Route Reencrypt https works", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
-				// the --resource mounts the certificates inside secret as files in the integration pod
-				"--resource", "secret:"+secretName+"@/etc/ssl/"+secretName,
-				// quarkus platform-http uses these two properties to setup the HTTP endpoint with TLS support
-				"-p", "quarkus.http.ssl.certificate.file=/etc/ssl/"+secretName+"/tls.crt",
-				"-p", "quarkus.http.ssl.certificate.key-file=/etc/ssl/"+secretName+"/tls.key",
-				"-t", "route.tls-termination=reencrypt",
-				// the destination CA certificate which the route service uses to validate the HTTP endpoint TLS certificate
-				"-t", "route.tls-destination-ca-certificate-secret="+refCert,
-				"-t", "route.tls-certificate-secret="+refCert,
-				"-t", "route.tls-key-secret="+refKey,
-				"-t", "container.port=8443",
-			).Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, integrationName), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-
-			route := Route(ns, integrationName)
-			Eventually(route, TestTimeoutMedium).ShouldNot(BeNil())
-			// must wait a little time after route is created, before an http request,
-			// otherwise the route is unavailable and the http request will fail
-			time.Sleep(waitBeforeHttpRequest)
-			code := "TLS_Reencrypt"
-			url := fmt.Sprintf("https://%s/hello?name=%s", route().Spec.Host, code)
-			Eventually(httpRequest(url, true), TestTimeoutShort).Should(Equal("Hello " + code))
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).Should(BeNil())
-		})
-		Expect(TestClient().Delete(TestContext, &secret)).To(Succeed())
-	})
-}
-
-func httpRequest(url string, tlsEnabled bool) func() (string, error) {
-	return func() (string, error) {
-		client, err := httpClient(tlsEnabled, 3*time.Second)
-		if err != nil {
-			return "", err
-		}
-		response, err := client.Get(url)
-		if err != nil {
-			return "", err
-		}
-		defer response.Body.Close()
-
-		buf := new(bytes.Buffer)
-		_, err = buf.ReadFrom(response.Body)
-		if err != nil {
-			return "", err
-		}
-		return buf.String(), nil
-	}
-}
-
-func httpClient(tlsEnabled bool, timeout time.Duration) (*http.Client, error) {
-	var client http.Client
-	if tlsEnabled {
-		var transCfg http.Transport
-		if skipClientTLSVerification {
-			transCfg = http.Transport{
-				TLSClientConfig: &tls.Config{
-					InsecureSkipVerify: true,
-				},
-			}
-		} else {
-			certPool := x509.NewCertPool()
-			certPool.AppendCertsFromPEM(certPem)
-			transCfg = http.Transport{
-				TLSClientConfig: &tls.Config{
-					RootCAs: certPool,
-				},
-			}
-		}
-		client = http.Client{Transport: &transCfg}
-	} else {
-		client = http.Client{}
-	}
-	client.Timeout = timeout
-	return &client, nil
-}
-
-func createSecret(ns string) (corev1.Secret, error) {
-	keyCertPair := generateSampleKeyAndCertificate(ns)
-	sec := corev1.Secret{
-		TypeMeta: metav1.TypeMeta{
-			Kind:       "Secret",
-			APIVersion: corev1.SchemeGroupVersion.String(),
-		},
-		ObjectMeta: metav1.ObjectMeta{
-			Namespace: ns,
-			Name:      secretName,
-		},
-		Type: corev1.SecretTypeTLS,
-		Data: map[string][]byte{
-			corev1.TLSPrivateKeyKey: keyCertPair.Key,
-			corev1.TLSCertKey:       keyCertPair.Certificate,
-		},
-	}
-	return sec, TestClient().Create(TestContext, &sec)
-}
-
-func generateSampleKeyAndCertificate(ns string) keyCertificatePair {
-	serialNumber := big.NewInt(rand2.Int63())
-	domainName, err := ClusterDomainName()
-	if err != nil {
-		fmt.Printf("Error retrieving cluster domain object, then the http client request will skip TLS validation: %s\n", err)
-		skipClientTLSVerification = true
-	}
-	var dnsHostname string
-	if len(domainName) > 0 {
-		dnsHostname = integrationName + "-" + ns + "." + domainName
-	} else {
-		dnsHostname = integrationName + "-" + ns
-	}
-	x509Certificate := x509.Certificate{
-		SerialNumber: serialNumber,
-		Subject: pkix.Name{
-			Organization: []string{"Camel K test"},
-		},
-		IsCA:                  true,
-		DNSNames:              []string{dnsHostname},
-		NotBefore:             time.Now(),
-		NotAfter:              time.Now().AddDate(1, 0, 0),
-		ExtKeyUsage:           []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
-		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
-		BasicConstraintsValid: true,
-	}
-
-	// generate the private key
-	certPrivateKey, err := rsa.GenerateKey(rand.Reader, 2048)
-	if err != nil {
-		fmt.Printf("Error generating private key: %s\n", err)
-	}
-
-	privateKeyBytes := x509.MarshalPKCS1PrivateKey(certPrivateKey)
-	// encode for storing into secret
-	privateKeyPem := pem.EncodeToMemory(
-		&pem.Block{
-			Type:  "RSA PRIVATE KEY",
-			Bytes: privateKeyBytes,
-		},
-	)
-	certBytes, err := x509.CreateCertificate(rand.Reader, &x509Certificate, &x509Certificate, &certPrivateKey.PublicKey, certPrivateKey)
-	if err != nil {
-		fmt.Printf("Error generating certificate: %s\n", err)
-	}
-
-	// encode for storing into secret
-	certPem = pem.EncodeToMemory(&pem.Block{
-		Type:  "CERTIFICATE",
-		Bytes: certBytes,
-	})
-
-	return keyCertificatePair{
-		Key:         privateKeyPem,
-		Certificate: certPem,
-	}
-}
diff --git a/e2e/global/common/traits/service_test.go b/e2e/global/common/traits/service_test.go
deleted file mode 100644
index 1ae022531..000000000
--- a/e2e/global/common/traits/service_test.go
+++ /dev/null
@@ -1,114 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"testing"
-
-	. "github.com/onsi/gomega"
-
-	corev1 "k8s.io/api/core/v1"
-
-	. "github.com/apache/camel-k/e2e/support"
-)
-
-func TestServiceTrait(t *testing.T) {
-	WithNewTestNamespace(t, func(ns string) {
-		operatorID := "camel-k-trait-service"
-		Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed())
-
-		t.Run("NodePort service", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
-				"-t", "service.enabled=true",
-				"-t", "service.node-port=true").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-
-			//
-			// Service names can vary with the ExternalName Service
-			// sometimes being created first and being given the root name
-			//
-			Eventually(ServicesByType(ns, corev1.ServiceTypeNodePort), TestTimeoutLong).ShouldNot(BeEmpty())
-
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("Default service (ClusterIP)", func(t *testing.T) {
-			// Service trait is enabled by default
-			Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-
-			//
-			// Service names can vary with the ExternalName Service
-			// sometimes being created first and being given the root name
-			//
-			Eventually(ServicesByType(ns, corev1.ServiceTypeClusterIP), TestTimeoutLong).ShouldNot(BeEmpty())
-
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("NodePort service from Type", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
-				"-t", "service.enabled=true",
-				"-t", "service.type=NodePort").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-
-			//
-			// Service names can vary with the ExternalName Service
-			// sometimes being created first and being given the root name
-			//
-			Eventually(ServicesByType(ns, corev1.ServiceTypeNodePort), TestTimeoutLong).ShouldNot(BeEmpty())
-
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("ClusterIP service from Type", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
-				"-t", "service.enabled=true",
-				"-t", "service.type=ClusterIP").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-
-			//
-			// Service names can vary with the ExternalName Service
-			// sometimes being created first and being given the root name
-			//
-			Eventually(ServicesByType(ns, corev1.ServiceTypeClusterIP), TestTimeoutLong).ShouldNot(BeEmpty())
-
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-
-		t.Run("LoadBalancer service from Type", func(t *testing.T) {
-			Expect(KamelRunWithID(operatorID, ns, "files/PlatformHttpServer.java",
-				"-t", "service.enabled=true",
-				"-t", "service.type=LoadBalancer").Execute()).To(Succeed())
-			Eventually(IntegrationPodPhase(ns, "platform-http-server"), TestTimeoutLong).Should(Equal(corev1.PodRunning))
-
-			//
-			// Service names can vary with the ExternalName Service
-			// sometimes being created first and being given the root name
-			//
-			Eventually(ServicesByType(ns, corev1.ServiceTypeLoadBalancer), TestTimeoutLong).ShouldNot(BeEmpty())
-
-			Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed())
-		})
-	})
-}
diff --git a/e2e/global/common/traits/toleration_test.go b/e2e/global/common/traits/toleration_test.go
deleted file mode 100644
index 60b0e7918..000000000
--- a/e2e/global/common/traits/toleration_test.go
+++ /dev/null
@@ -1,144 +0,0 @@
-//go:build integration
-// +build integration
-
-// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration"
-
-/*
-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.
-*/
-
-package traits
-
-import (
-	"os"
-	"testing"
-
-	. "github.com/onsi/gomega"
-	. "github.com/onsi/gomega/gstruct"
-
-	corev1 "k8s.io/api/core/v1"
-	"k8s.io/utils/pointer"
-
-	. "github.com/apache/camel-k/e2e/support"
-	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
-)
-
-/*
- * TODO
... 2852 lines suppressed ...