diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 17ba90391061277fec6618d51573573e190d60f1..b7e6265f4d3fd15baa5af6341f4477071021612c 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -138,6 +138,13 @@ tests_debug:
     - cargo cucumber -i balance*
     - cargo cucumber -i monetary*
     - cargo cucumber -i transfer*
+  after_script:
+    - cd target/debug/deps/
+    - mv $(ls -t @(cucumber_tests!(*.d))) ../../../build/duniter-cucumber
+  artifacts:
+    paths:
+      - build/
+    expire_in: 3 day
 
 tests_release:
   extends: .env
diff --git a/Cargo.lock b/Cargo.lock
index fe2675c9178aa6568777a766051268de027127b7..ef1ee7c1be3b8786b2492ab4f06f0fd8c327b614 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1007,6 +1007,16 @@ dependencies = [
  "cipher",
 ]
 
+[[package]]
+name = "ctrlc"
+version = "3.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b37feaa84e6861e00a1f5e5aa8da3ee56d605c9992d33e082786754828e20865"
+dependencies = [
+ "nix",
+ "winapi 0.3.9",
+]
+
 [[package]]
 name = "cuckoofilter"
 version = "0.5.0"
@@ -1324,6 +1334,8 @@ name = "duniter-end2end-tests"
 version = "3.0.0"
 dependencies = [
  "async-trait",
+ "clap",
+ "ctrlc",
  "cucumber",
  "env_logger",
  "notify",
@@ -3071,9 +3083,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 
 [[package]]
 name = "libc"
-version = "0.2.112"
+version = "0.2.126"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
+checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
 
 [[package]]
 name = "libloading"
@@ -4054,6 +4066,17 @@ version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ab250442c86f1850815b5d268639dff018c0627022bc1940eb2d642ca1ce12f0"
 
+[[package]]
+name = "nix"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f17df307904acd05aa8e32e97bb20f2a0df1728bbc2d771ae8f9a90463441e9"
+dependencies = [
+ "bitflags",
+ "cfg-if 1.0.0",
+ "libc",
+]
+
 [[package]]
 name = "nodrop"
 version = "0.1.14"
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 6e5dec0124ed549f3a428c777cf14932d3efa55f..771bf413be35fef33e7f51a4ecab2160c8eb1ba2 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -40,7 +40,7 @@ LABEL description="Crypto-currency software (based on Substrate framework) to op
 RUN adduser --home /var/lib/duniter duniter
 
 # Configuration
-# rpc, rpc-ws, p2p, telemetry 
+# rpc, rpc-ws, p2p, telemetry
 EXPOSE 9933 9944 30333 9615
 VOLUME /var/lib/duniter
 ENTRYPOINT ["docker-entrypoint"]
@@ -48,4 +48,5 @@ USER duniter
 
 # Intall
 COPY --from=build /root/build/duniter /usr/local/bin/duniter
+COPY --from=build /root/build/duniter-cucumber /usr/local/bin/duniter-cucumber
 COPY docker/docker-entrypoint /usr/local/bin/
diff --git a/end2end-tests/Cargo.toml b/end2end-tests/Cargo.toml
index 8f31c4d3d6526ff002e965c4b334c68c1ed52e09..8d7b445eeded82e13bb22a059caefa39ad27fd7d 100644
--- a/end2end-tests/Cargo.toml
+++ b/end2end-tests/Cargo.toml
@@ -10,6 +10,8 @@ version = '3.0.0'
 
 [dev-dependencies]
 async-trait = "0.1"
+clap = { version = "3.0", features = ["derive"] }
+ctrlc = "3.2.2"
 cucumber = "0.11"
 env_logger = "0.9.0"
 notify = "4.0"
diff --git a/end2end-tests/tests/cucumber_tests.rs b/end2end-tests/tests/cucumber_tests.rs
index d1bfa134e828c7c21568dfa57343de21c2f6d772..35939841c250a7faa7768f5fb3c2a4299c5cae05 100644
--- a/end2end-tests/tests/cucumber_tests.rs
+++ b/end2end-tests/tests/cucumber_tests.rs
@@ -23,6 +23,10 @@ use sp_keyring::AccountKeyring;
 use std::convert::Infallible;
 use std::path::PathBuf;
 use std::str::FromStr;
+use std::sync::{
+    atomic::{AtomicBool, Ordering},
+    Arc,
+};
 
 #[derive(WorldInit)]
 pub struct DuniterWorld(Option<DuniterWorldInner>);
@@ -203,10 +207,28 @@ async fn monetary_mass_should_be(world: &mut DuniterWorld, amount: u64, cents: u
     Ok(())
 }
 
+#[derive(clap::Args)]
+struct CustomOpts {
+    /// Keep running
+    #[clap(short, long)]
+    keep_running: bool,
+}
+
 #[tokio::main(flavor = "current_thread")]
 async fn main() {
     //env_logger::init();
 
+    let opts = cucumber::cli::Opts::<_, _, _, CustomOpts>::parsed();
+    let keep_running = opts.custom.keep_running;
+
+    // Handle crtl+C
+    let running = Arc::new(AtomicBool::new(true));
+    let running_clone = running.clone();
+    ctrlc::set_handler(move || {
+        running_clone.store(false, Ordering::SeqCst);
+    })
+    .expect("Error setting Ctrl-C handler");
+
     DuniterWorld::cucumber()
         //.fail_on_skipped()
         .max_concurrent_scenarios(4)
@@ -219,12 +241,17 @@ async fn main() {
             ));
             Box::pin(world.init(Some(genesis_conf_file_path)))
         })
-        .after(|_feature, _rule, _scenario, maybe_world| {
+        .after(move |_feature, _rule, _scenario, maybe_world| {
+            if keep_running {
+                while running.load(Ordering::SeqCst) {}
+            }
+
             if let Some(world) = maybe_world {
                 world.kill();
             }
             Box::pin(std::future::ready(()))
         })
+        .with_cli(opts)
         .run_and_exit("cucumber-features")
         .await;
 }