diff --git a/Dockerfile b/Dockerfile
index e4b39a8..9277094 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM grafana/k6:0.47.0-with-browser
+FROM grafana/k6:0.56.0-with-browser
 
 ENV TERM=xterm-256color
 ENV PROJECT_DIR=/home/k6
diff --git a/docker-compose.local.yml b/docker-compose.local.yml
deleted file mode 100644
index aa90d9d..0000000
--- a/docker-compose.local.yml
+++ /dev/null
@@ -1,85 +0,0 @@
-version: '3.4'
-
-services:
-  k6:
-    container_name: "loadtesting_environment"
-    build:
-      context: .
-      dockerfile: Dockerfile
-    networks:
-      - loadtesting
-      # - spryker_demo_private
-      # - spryker_demo_public
-      # - spryker_b2b_marketplace_dev_private
-      # - spryker_b2c_marketplace_dev_private
-      # - spryker_b2b_dev_private
-      # - spryker_b2c_dev_private
-      # - spryker_b2b_marketplace_private
-      # - spryker_b2c_marketplace_private
-      # - spryker_b2b_private
-      # - spryker_b2c_private
-
-    environment:
-        - K6_SCRIPT=${K6_SCRIPT}
-        - K6_HOSTENV=${K6_HOSTENV:-local}
-        - K6_INSECURE_SKIP_TLS_VERIFY=true
-        - K6_STATSD_ENABLE_TAGS=true
-        - K6_OUT=
-        - K6_STATSD_ADDR=${K6_STATSD_ADDR}
-        - K6_STATSD_NAMESPACE=${K6_STATSD_NAMESPACE}
-        - K6_HTTP_DEBUG=${K6_HTTP_DEBUG}
-        - K6_NO_THRESHOLDS=${K6_NO_THRESHOLDS:-true}
-        - DATA_EXCHANGE_PAYLOAD_PUT_CHUNK_SIZE=${DATA_EXCHANGE_PAYLOAD_PUT_CHUNK_SIZE:-100}
-        - DATA_EXCHANGE_PAYLOAD_PATCH_CHUNK_SIZE=${DATA_EXCHANGE_PAYLOAD_PATCH_CHUNK_SIZE:-100}
-        - DATA_EXCHANGE_PAYLOAD_CHUNK_SIZE=${DATA_EXCHANGE_PAYLOAD_CHUNK_SIZE:-100}
-        - DATA_EXCHANGE_TARGET_CATALOG_SIZE_POST=${DATA_EXCHANGE_TARGET_CATALOG_SIZE_POST:-3000}
-        - DATA_EXCHANGE_TARGET_CATALOG_SIZE_PUT_PATCH=${DATA_EXCHANGE_TARGET_CATALOG_SIZE_PUT_PATCH:-1000}
-        - DATA_EXCHANGE_THREADS_PATCH=${DATA_EXCHANGE_THREADS_PATCH:-1}
-        - DATA_EXCHANGE_THREADS_PUT=${DATA_EXCHANGE_THREADS_PUT:-1}
-        - DATA_EXCHANGE_THREADS_POST=${DATA_EXCHANGE_THREADS_POST:-1}
-        - DATA_EXCHANGE_TWO_LOCALES=${DATA_EXCHANGE_TWO_LOCALES:-1}
-        - DATA_EXCHANGE_CONCRETE_MAX_AMOUNT=${DATA_EXCHANGE_CONCRETE_MAX_AMOUNT:-1}
-        - DATA_EXCHANGE_DEBUG=${DATA_EXCHANGE_DEBUG:-0}
-        - GIT_HASH=${GIT_HASH:-'-'}
-        - GIT_BRANCH=${GIT_BRANCH:-'-'}
-        - GIT_REPO=${GIT_REPO:-'-'}
-        - GIT_TAG=${GIT_TAG:-'-'}
-        - SPRYKER_TEST_RUN_ID=${SPRYKER_TEST_RUN_ID:-'-'}
-        - SPRYKER_TEST_RUNNER_HOSTNAME=${SPRYKER_TEST_RUNNER_HOSTNAME:-'-'}
-        - BASIC_AUTH_USERNAME=${BASIC_AUTH_USERNAME}
-        - BASIC_AUTH_PASSWORD=${BASIC_AUTH_PASSWORD}
-    volumes:  
-      - .:/home/k6
-    ports:
-      - "6565:6565"
- 
-networks:
-  loadtesting:
-  spryker-cloud_private:
-    external: true
-  spryker-cloud_public:
-    external: true
-  spryker_public:
-    external: true
-  spryker_private:
-    external: true
-  spryker_demo_public:
-    external: true
-  spryker_demo_private:
-    external: true
-  spryker_b2b_marketplace_private:
-    external: true
-  spryker_b2b_marketplace_dev_private:
-    external: true
-  spryker_b2c_marketplace_dev_private:
-    external: true
-  spryker_b2c_dev_private:
-    external: true
-  spryker_b2b_dev_private:
-    external: true
-  spryker_b2c_marketplace_private:
-    external: true
-  spryker_b2c_private:
-    external: true
-  spryker_b2b_private:
-    external: true
diff --git a/docker-compose.yml b/docker-compose.yml
index a710f6d..d22e17a 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,5 +1,3 @@
-version: '3.4'
-
 services:
   k6:
     container_name: "loadtesting_environment"
@@ -8,30 +6,30 @@ services:
       dockerfile: Dockerfile
     networks:
       - loadtesting
-#      - spryker_b2b_marketplace_private
-#      - spryker_b2b_marketplace_dev_private
-#      - spryker_b2c_marketplace_dev_private
-#      - spryker_b2b_dev_private
-#      - spryker_b2c_dev_private
-#      - spryker_b2b_marketplace_private
-#      - spryker_b2c_marketplace_private
-#      - spryker_b2b_private
-#      - spryker_b2c_private
+      - spryker_b2b_dev_private
+      - spryker_b2b_dev_public
+      # - spryker_demo_private
+      # - spryker_demo_public
+      # - spryker_b2b_marketplace_dev_private
+      # - spryker_b2c_marketplace_dev_private
+      # - spryker_b2b_dev_private
+      # - spryker_b2c_dev_private
+      # - spryker_b2b_marketplace_private
+      # - spryker_b2c_marketplace_private
+      # - spryker_b2b_private
+      # - spryker_b2c_private
+
     environment:
         - K6_SCRIPT=${K6_SCRIPT}
-        - K6_HOSTENV=${K6_HOSTENV}
+        - K6_HOSTENV=${K6_HOSTENV:-local}
+        - K6_INSECURE_SKIP_TLS_VERIFY=true
         - K6_STATSD_ENABLE_TAGS=true
-        - K6_OUT=${K6_OUT}
+        - K6_OUT=
         - K6_STATSD_ADDR=${K6_STATSD_ADDR}
         - K6_STATSD_NAMESPACE=${K6_STATSD_NAMESPACE}
         - K6_HTTP_DEBUG=${K6_HTTP_DEBUG}
-        - K6_NO_THRESHOLDS=${K6_NO_THRESHOLDS}
-        - GIT_HASH=${GIT_HASH}
-        - GIT_BRANCH=${GIT_BRANCH}
-        - GIT_REPO=${GIT_REPO}
-        - GIT_TAG=${GIT_TAG}
-        - BASIC_AUTH_USERNAME=${BASIC_AUTH_USERNAME}
-        - BASIC_AUTH_PASSWORD=${BASIC_AUTH_PASSWORD}
+        - K6_BROWSER_DEBUG=${K6_BROWSER_DEBUG}
+        - K6_NO_THRESHOLDS=${K6_NO_THRESHOLDS:-true}
         - DATA_EXCHANGE_PAYLOAD_PUT_CHUNK_SIZE=${DATA_EXCHANGE_PAYLOAD_PUT_CHUNK_SIZE:-100}
         - DATA_EXCHANGE_PAYLOAD_PATCH_CHUNK_SIZE=${DATA_EXCHANGE_PAYLOAD_PATCH_CHUNK_SIZE:-100}
         - DATA_EXCHANGE_PAYLOAD_CHUNK_SIZE=${DATA_EXCHANGE_PAYLOAD_CHUNK_SIZE:-100}
@@ -43,52 +41,38 @@ services:
         - DATA_EXCHANGE_TWO_LOCALES=${DATA_EXCHANGE_TWO_LOCALES:-1}
         - DATA_EXCHANGE_CONCRETE_MAX_AMOUNT=${DATA_EXCHANGE_CONCRETE_MAX_AMOUNT:-1}
         - DATA_EXCHANGE_DEBUG=${DATA_EXCHANGE_DEBUG:-0}
+        - GIT_HASH=${GIT_HASH:-'-'}
+        - GIT_BRANCH=${GIT_BRANCH:-'-'}
+        - GIT_REPO=${GIT_REPO:-'-'}
+        - GIT_TAG=${GIT_TAG:-'-'}
+        - SPRYKER_TEST_RUN_ID=${SPRYKER_TEST_RUN_ID:-'-'}
+        - SPRYKER_TEST_RUNNER_HOSTNAME=${SPRYKER_TEST_RUNNER_HOSTNAME:-'-'}
+        - BASIC_AUTH_USERNAME=${BASIC_AUTH_USERNAME}
+        - BASIC_AUTH_PASSWORD=${BASIC_AUTH_PASSWORD}
+        - K6_BROWSER_ENABLED=true
     volumes:  
       - .:/home/k6
     ports:
       - "6565:6565"
-    links:
-      - "nrstatsd"
-      - "newrelic"
-
-  newrelic-php-daemon:
-    image: newrelic/php-daemon
-    networks:
-      - loadtesting
-
-  nrstatsd:
-    container_name: "new_relic_statsd"
-    image: newrelic/nri-statsd:latest
-    environment: 
-      - NR_ACCOUNT_ID=${NR_ACCOUNT_ID}
-      # It appears to be a bug in the statsd image. Despite calling the API key, it only works with a New Relic license key.
-      - NR_API_KEY=${NRIA_LICENSE_KEY}
-      - NR_EU_REGION=${NR_EU_REGION}
-      - NR_LOG_METRICS=true
-    hostname: "localpocmachine"
-    ports:
-      - 8125:8125/udp
-    networks:
-      - loadtesting
-    restart: unless-stopped
-  
-  newrelic:
-    container_name: newrelic-infra
-    image: newrelic/infrastructure:latest
-    cap_add:
-      - SYS_PTRACE
-    network_mode: host
-    pid: host 
-    privileged: true
-    volumes:
-      - "/:/host:ro"
-      - "/var/run/docker.sock:/var/run/docker.sock"
-    environment:
-      - NRIA_LICENSE_KEY=${NRIA_LICENSE_KEY}
-    restart: unless-stopped
-
+ 
 networks:
   loadtesting:
+  spryker_b2b_dev_private:
+    external: true
+  spryker_b2b_dev_public:
+    external: true
+#  spryker-cloud_private:
+#    external: true
+#  spryker-cloud_public:
+#    external: true
+#  spryker_public:
+#    external: true
+#  spryker_private:
+#    external: true
+#  spryker_demo_public:
+#    external: true
+#  spryker_demo_private:
+#    external: true
 #  spryker_b2b_marketplace_private:
 #    external: true
 #  spryker_b2b_marketplace_dev_private:
@@ -99,8 +83,6 @@ networks:
 #    external: true
 #  spryker_b2b_dev_private:
 #    external: true
-#  spryker_b2b_marketplace_private:
-#    external: true
 #  spryker_b2c_marketplace_private:
 #    external: true
 #  spryker_b2c_private:
diff --git a/docker-compose_main.yml b/docker-compose_main.yml
new file mode 100644
index 0000000..a937fb8
--- /dev/null
+++ b/docker-compose_main.yml
@@ -0,0 +1,115 @@
+version: '3.4'
+
+services:
+  k6:
+    container_name: "loadtesting_environment"
+    build:
+      context: .
+      dockerfile: Dockerfile
+    networks:
+      - loadtesting
+      - spryker_b2b_dev_private
+      - spryker_b2b_dev_public
+#      - spryker_b2b_marketplace_private
+#      - spryker_b2b_marketplace_dev_private
+#      - spryker_b2c_marketplace_dev_private
+#      - spryker_b2b_dev_private
+#      - spryker_b2c_dev_private
+#      - spryker_b2b_marketplace_private
+#      - spryker_b2c_marketplace_private
+#      - spryker_b2b_private
+#      - spryker_b2c_private
+    environment:
+        - K6_SCRIPT=${K6_SCRIPT}
+        - K6_HOSTENV=${K6_HOSTENV}
+        - K6_STATSD_ENABLE_TAGS=true
+        - K6_OUT=${K6_OUT}
+        - K6_STATSD_ADDR=${K6_STATSD_ADDR}
+        - K6_STATSD_NAMESPACE=${K6_STATSD_NAMESPACE}
+        - K6_HTTP_DEBUG=${K6_HTTP_DEBUG}
+        - K6_NO_THRESHOLDS=${K6_NO_THRESHOLDS}
+        - GIT_HASH=${GIT_HASH}
+        - GIT_BRANCH=${GIT_BRANCH}
+        - GIT_REPO=${GIT_REPO}
+        - GIT_TAG=${GIT_TAG}
+        - BASIC_AUTH_USERNAME=${BASIC_AUTH_USERNAME}
+        - BASIC_AUTH_PASSWORD=${BASIC_AUTH_PASSWORD}
+        - DATA_EXCHANGE_PAYLOAD_PUT_CHUNK_SIZE=${DATA_EXCHANGE_PAYLOAD_PUT_CHUNK_SIZE:-100}
+        - DATA_EXCHANGE_PAYLOAD_PATCH_CHUNK_SIZE=${DATA_EXCHANGE_PAYLOAD_PATCH_CHUNK_SIZE:-100}
+        - DATA_EXCHANGE_PAYLOAD_CHUNK_SIZE=${DATA_EXCHANGE_PAYLOAD_CHUNK_SIZE:-100}
+        - DATA_EXCHANGE_TARGET_CATALOG_SIZE_POST=${DATA_EXCHANGE_TARGET_CATALOG_SIZE_POST:-3000}
+        - DATA_EXCHANGE_TARGET_CATALOG_SIZE_PUT_PATCH=${DATA_EXCHANGE_TARGET_CATALOG_SIZE_PUT_PATCH:-1000}
+        - DATA_EXCHANGE_THREADS_PATCH=${DATA_EXCHANGE_THREADS_PATCH:-1}
+        - DATA_EXCHANGE_THREADS_PUT=${DATA_EXCHANGE_THREADS_PUT:-1}
+        - DATA_EXCHANGE_THREADS_POST=${DATA_EXCHANGE_THREADS_POST:-1}
+        - DATA_EXCHANGE_TWO_LOCALES=${DATA_EXCHANGE_TWO_LOCALES:-1}
+        - DATA_EXCHANGE_CONCRETE_MAX_AMOUNT=${DATA_EXCHANGE_CONCRETE_MAX_AMOUNT:-1}
+        - DATA_EXCHANGE_DEBUG=${DATA_EXCHANGE_DEBUG:-0}
+    volumes:  
+      - .:/home/k6
+    ports:
+      - "6565:6565"
+    links:
+      - "nrstatsd"
+      - "newrelic"
+
+  newrelic-php-daemon:
+    image: newrelic/php-daemon
+    networks:
+      - loadtesting
+
+  nrstatsd:
+    container_name: "new_relic_statsd"
+    image: newrelic/nri-statsd:latest
+    environment: 
+      - NR_ACCOUNT_ID=${NR_ACCOUNT_ID}
+      # It appears to be a bug in the statsd image. Despite calling the API key, it only works with a New Relic license key.
+      - NR_API_KEY=${NRIA_LICENSE_KEY}
+      - NR_EU_REGION=${NR_EU_REGION}
+      - NR_LOG_METRICS=true
+    hostname: "localpocmachine"
+    ports:
+      - 8125:8125/udp
+    networks:
+      - loadtesting
+    restart: unless-stopped
+  
+  newrelic:
+    container_name: newrelic-infra
+    image: newrelic/infrastructure:latest
+    cap_add:
+      - SYS_PTRACE
+    network_mode: host
+    pid: host 
+    privileged: true
+    volumes:
+      - "/:/host:ro"
+      - "/var/run/docker.sock:/var/run/docker.sock"
+    environment:
+      - NRIA_LICENSE_KEY=${NRIA_LICENSE_KEY}
+    restart: unless-stopped
+
+networks:
+  loadtesting:
+  spryker_b2b_dev_private:
+    external: true
+  spryker_b2b_dev_public:
+    external: true
+#  spryker_b2b_marketplace_private:
+#    external: true
+#  spryker_b2b_marketplace_dev_private:
+#    external: true
+#  spryker_b2c_marketplace_dev_private:
+#    external: true
+#  spryker_b2c_dev_private:
+#    external: true
+#  spryker_b2b_dev_private:
+#    external: true
+#  spryker_b2b_marketplace_private:
+#    external: true
+#  spryker_b2c_marketplace_private:
+#    external: true
+#  spryker_b2c_private:
+#    external: true
+#  spryker_b2b_private:
+#    external: true
diff --git a/environments/B2B.json b/environments/B2B.json
index a0f9940..a59a659 100644
--- a/environments/B2B.json
+++ b/environments/B2B.json
@@ -4,7 +4,8 @@
         "storefrontApiUrl": "http://glue.%store%.spryker.local",
         "backofficeUrl": "http://backoffice.%store%.spryker.local",
         "backofficeApiUrl": "http://backend-api.%store%.spryker.local",
-        "stores": ["eu", "us"]
+        "stores": ["eu", "us"],
+        "backofficeSessionKey": "backoffice-%store%-spryker-local"
     },
     "testing": {
         "storefrontUrl": "https://yves.%store%.spryker-b2bperformance.cloud.spryker.toys",
diff --git a/helpers/admin-helper.js b/helpers/admin-helper.js
index bc59fe3..595badc 100644
--- a/helpers/admin-helper.js
+++ b/helpers/admin-helper.js
@@ -1,4 +1,69 @@
-export default class AdminHelper {
+import { sleep } from 'k6';
+import { browser } from 'k6/browser';
+
+const formSelector = 'form[name="auth"]';
+const usernameInputSelector = `${formSelector} input[name="auth[username]"]`;
+const passwordInputSelector = `${formSelector} input[name="auth[password]"]`;
+const authSubmitSelector = `${formSelector} button[type="submit"]`;
+
+const firstSalesOrderViewButtonSelector = '.dataTable tbody tr:nth-child(1) .btn-view';
+const omsFormSubmitSelector = 'button#oms_trigger_form_submit';
+
+class ContextStorage {
+    #context;
+    #page;
+
+    constructor(context, page) {
+        this.#context = context;
+        this.#page = page;
+    }
+
+    setContext(context) {
+        this.#context = context;
+    }
+
+    getContext() {
+        return this.#context;
+    }
+
+    setPage(page) {
+        this.#page = page;
+    }
+
+    getPage() {
+        return this.#page;
+    }
+}
+
+export class AdminHelper {
+    constructor(urlHelper, http, assertionsHelper, browserHelper) {
+        this.urlHelper = urlHelper;
+        this.http = http;
+        this.assertionsHelper = assertionsHelper;
+        this.browserHelper = browserHelper;
+
+        this.session = null;
+        this.contextStorage = new ContextStorage(null, null);
+
+        this.backofficeSessionKey = 'backoffice-eu-spryker-local';
+
+        const backofficeBaseUrl = this.urlHelper.getBackofficeBaseUrl();
+
+        const loginUrl = backofficeBaseUrl + '/security-gui/login';
+        const loginCheckUrl = backofficeBaseUrl + '/login_check';
+        const salesUrl = backofficeBaseUrl + '/sales';
+        const salesTableUrl = backofficeBaseUrl + '/sales/index/table';
+        const salesDetailUrl = backofficeBaseUrl + '/sales/detail';
+        const omsTriggerUrl = backofficeBaseUrl + '/oms/trigger/submit-trigger-event-for-order';
+
+        this.loginUrl = loginUrl;
+        this.loginCheckUrl = loginCheckUrl;
+        this.salesUrl = salesUrl;
+        this.salesTableUrl = salesTableUrl;
+        this.salesDetailUrl = salesDetailUrl;
+        this.omsTriggerUrl = omsTriggerUrl;
+    }
+
     getDefaultAdminEmail() {
         return __ENV.DEFAULT_ADMIN_EMAIL ? __ENV.DEFAULT_ADMIN_EMAIL : 'admin@spryker.com';
     }
@@ -6,4 +71,130 @@ export default class AdminHelper {
     getDefaultAdminPassword() {
         return __ENV.DEFAULT_ADMIN_PASSWORD ? __ENV.DEFAULT_ADMIN_PASSWORD : 'change123';
     }
+
+    async loginBackoffice() {
+        const context = await browser.newContext();
+        this.contextStorage.setContext(context);
+        const page = await context.newPage();
+        this.contextStorage.setPage(page);
+
+        await page.goto(this.loginUrl);
+        await page.waitForSelector(formSelector, {timeout: 5000});
+
+        await page.locator(usernameInputSelector).type(this.getDefaultAdminEmail());
+        await page.locator(passwordInputSelector).type(this.getDefaultAdminPassword());
+        await page.locator(authSubmitSelector).click();
+
+        await page.waitForLoadState('networkidle', {timeout: 5000});
+    }
+
+    async goToSalesPage() {
+        const page = this.contextStorage.getPage();
+
+        page.on('metric', (metric) => {
+            metric.tag({
+                name: this.salesTableUrl,
+                matches: [
+                    {
+                        url: new RegExp(this.salesTableUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
+                        method: 'GET',
+                    },
+                ],
+            });
+        });
+
+        await page.goto(this.salesUrl, { timeout: 5000 });
+        await page.waitForLoadState('networkidle', { timeout: 2000 });
+    }
+
+    async openFirstSalesOrder() {
+        let self = this;
+
+        const page = this.contextStorage.getPage();
+        const buttonLocator = await page.locator(firstSalesOrderViewButtonSelector);
+
+        page.on('metric', (metric) => {
+            metric.tag({
+                name: self.salesDetailUrl,
+                matches: [
+                    {
+                        url: new RegExp(self.salesDetailUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'),
+                        method: 'GET',
+                    },
+                ],
+            });
+        });
+
+        await buttonLocator.waitFor({state: 'visible'});
+        await buttonLocator.click(firstSalesOrderViewButtonSelector);
+
+        await page.waitForLoadState('networkidle', { timeout: 2000 });
+    }
+
+    async waitForOrderHasOmsTriggerButton() {
+        const page = this.contextStorage.getPage();
+
+        await page.locator(omsFormSubmitSelector).waitFor({state: 'visible'});
+
+        await this.recursiveWaitForSelectorWithText(omsFormSubmitSelector, 'Pay', 60 );
+    }
+
+    async payForTheOrder() {
+        const page = this.contextStorage.getPage();
+
+        await page.waitForLoadState('networkidle', { timeout: 5000 });
+
+        page.on('metric', (metric) => {
+            metric.tag({
+                name: this.omsTriggerUrl,
+                matches: [
+                    {url: new RegExp(this.omsTriggerUrl.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), method: 'POST'},
+                ],
+            });
+        });
+
+        // const submitButtons = await page.$$(omsFormSubmitSelector);
+        // const submitButton = await this.findButtonByText(submitButtons, 'Pay');
+
+        const payButton = await page.locator('#order-overview > .row .ibox-content > .row > .col-md-12 .ibox-content form:nth-child(2) button');
+
+        await payButton.click({
+            force: true,
+            noWaitAfter: true,
+        });
+
+        await page.waitForLoadState('networkidle', { timeout: 5000 });
+    }
+
+    async recursiveWaitForSelectorWithText(selector, text, maxRetries = 10) {
+        const page = this.contextStorage.getPage();
+
+        for (let attempt = 0; attempt < maxRetries; attempt++) {
+            const submitButtons = await page.$$(selector);
+            for (let i = 0; i < submitButtons.length; i++) {
+                if ((await submitButtons[i].innerText()) === text) {
+                    return;
+                }
+            }
+
+            sleep(1);
+            await page.reload();
+        }
+    }
+
+    async findButtonByText(buttons, text) {
+        for (let i = 0; i < buttons.length; i++) {
+            if ((await buttons[i].innerText()) === text) {
+                return buttons[i];
+            }
+        }
+
+        return null;
+    }
+
+    async takeScreenshot(fileName = new Date().toString() + 'screenshot.png') {
+        const page = this.contextStorage.getPage();
+        await page.screenshot({ path: 'results/' + fileName });
+        console.log(`Screenshot saved to ${fileName}`);
+    }
 }
diff --git a/helpers/browser-helper.js b/helpers/browser-helper.js
index 2415cea..0fc0c29 100644
--- a/helpers/browser-helper.js
+++ b/helpers/browser-helper.js
@@ -1,10 +1,14 @@
-import {browser} from 'k6/experimental/browser';
+import { browser } from 'k6/browser';
 
 export class BrowserHelper {
     constructor(urlHelper, customerHelper, assertionsHelper) {
         this.urlHelper = urlHelper;
         this.customerHelper = customerHelper;
         this.assertionsHelper = assertionsHelper;
+
+        this.url = '';
+        this.context = null;
+        this.page = null;
     }
 
     async getLoggedInUserContext() {
diff --git a/package-lock.json b/package-lock.json
index b4d1cbe..df446ad 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,6 +5,7 @@
   "packages": {
     "": {
       "devDependencies": {
+        "@types/k6": "^0.54.2",
         "eslint": "^8.39.0"
       }
     },
@@ -132,6 +133,13 @@
         "node": ">= 8"
       }
     },
+    "node_modules/@types/k6": {
+      "version": "0.54.2",
+      "resolved": "https://registry.npmjs.org/@types/k6/-/k6-0.54.2.tgz",
+      "integrity": "sha512-B5LPxeQm97JnUTpoKNE1UX9jFp+JiJCAXgZOa2P7aChxVoPQXKfWMzK+739xHq3lPkKj1aV+HeOxkP56g/oWBg==",
+      "dev": true,
+      "license": "MIT"
+    },
     "node_modules/acorn": {
       "version": "8.8.2",
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
@@ -265,10 +273,11 @@
       "dev": true
     },
     "node_modules/cross-spawn": {
-      "version": "7.0.3",
-      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+      "version": "7.0.6",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+      "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
       "dev": true,
+      "license": "MIT",
       "dependencies": {
         "path-key": "^3.1.0",
         "shebang-command": "^2.0.0",
@@ -894,10 +903,11 @@
       }
     },
     "node_modules/punycode": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
-      "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=6"
       }
@@ -1091,10 +1101,11 @@
       }
     },
     "node_modules/word-wrap": {
-      "version": "1.2.3",
-      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
-      "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+      "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
       "dev": true,
+      "license": "MIT",
       "engines": {
         "node": ">=0.10.0"
       }
diff --git a/package.json b/package.json
index c84445b..418cdbf 100644
--- a/package.json
+++ b/package.json
@@ -1,5 +1,6 @@
 {
   "devDependencies": {
+    "@types/k6": "^0.54.2",
     "eslint": "^8.39.0"
   }
 }
diff --git a/page-objects/abstract-page.js b/page-objects/abstract-page.js
new file mode 100644
index 0000000..4aecde5
--- /dev/null
+++ b/page-objects/abstract-page.js
@@ -0,0 +1,10 @@
+export class AbstractPage {
+    constructor(page, baseUrl) {
+        this.page = page;
+        this.baseUrl = baseUrl;
+    }
+
+    setPage(page) {
+        this.page = page;
+    }
+}
\ No newline at end of file
diff --git a/page-objects/backoffice/login-page.js b/page-objects/backoffice/login-page.js
new file mode 100644
index 0000000..c8dc615
--- /dev/null
+++ b/page-objects/backoffice/login-page.js
@@ -0,0 +1,26 @@
+import { AbstractPage } from '../abstract-page';
+
+const url = '/security-gui/login';
+
+const formSelector = 'form[name="auth"]';
+const inputEmailSelector = `${formSelector} input[name="auth[username]"]`;
+const inputPasswordSelector = `${formSelector} input[name="auth[password]"]`;
+const submitButtonSelector = `${formSelector} button[type="submit"]`;
+
+export class LoginPage extends AbstractPage {
+    async open() {
+        await this.page.goto(`${this.baseUrl}${url}`);
+    }
+
+    async fillEmail(email) {
+        await this.page.locator(inputEmailSelector).type(email);
+    }
+
+    async fillPassword(password) {
+        await this.page.locator(inputPasswordSelector).type(password);
+    }
+
+    async submitForm() {
+        await this.page.locator(submitButtonSelector).click();
+    }
+}
\ No newline at end of file
diff --git a/shell/functions.sh b/shell/functions.sh
index ffaab42..6353fec 100644
--- a/shell/functions.sh
+++ b/shell/functions.sh
@@ -87,11 +87,11 @@ build_k6_docker_command() {
 
     command="docker-compose run --rm \
             -v $(pwd):/scripts \
-            -u $(id -u):$(id -g) \
             -e 'SPRYKER_TEST_RUN_ID=$testRunId' \
             -e 'SPRYKER_TEST_RUNNER_HOSTNAME=$(hostname)' \
             -e 'SPRYKER_TEST_PATH=$relativePath' \
             -e 'K6_BROWSER_ENABLED=true' \
+            -e 'K6_BROWSER_HEADLESS=true' \
             k6 run $relativePath \
             --summary-trend-stats='avg,min,med,max,p(90),p(95),count' \
             --out json='$reportFile'"
@@ -99,6 +99,44 @@ build_k6_docker_command() {
     echo "$command"
 }
 
+build_k6_local_command() {
+    local relativePath="$1"
+    local reportFile="$2"
+    local testRunId="$3"
+
+    # Check if 'k6' executable is available
+    if ! command -v k6 &>/dev/null; then
+        echo >&2
+        echo -e "\e[33mError: 'k6' is not installed or not in PATH. Please install 'k6' and try again.\e[0m" >&2
+        return 1
+    fi
+
+    if [ -z "$testRunId" ]; then
+        testRunId=$(generate_uuid)  # Call generate_uuid to get a UUID
+            echo >&2
+            echo -e "\e[33m--------------------------------------------------------------------------------\e[0m" >&2
+            echo -e "\e[33mYou did not specify the test run id.\e[0m" >&2
+            echo -e "\e[33mA UUId will be generated and used.\e[0m" >&2
+            echo -e "\e[33m--------------------------------------------------------------------------------\e[0m" >&2
+            return 1;
+    fi
+
+    command="K6_HOSTENV=local \
+    K6_BROWSER_HEADLESS=false \
+    KK6_BROWSER_ARGS=\"--enable-automation\" \
+    PROJECT_DIR=$(pwd) \
+    GIT_REPO=B2B \
+    GIT_BRANCH=B2B \
+    GIT_HASH=B2B \
+    SPRYKER_TEST_RUN_ID=$testRunId \
+    SPRYKER_TEST_RUNNER_HOSTNAME=$(hostname) \
+    k6 run $relativePath \
+    --summary-trend-stats='avg,min,med,max,p(90),p(95),count' \
+    --out json='$reportFile'"
+
+    echo "$command"
+}
+
 # Helper method to create a folder if it does not exist
 create_folder_if_not_existant() {
     local folder="$1"
diff --git a/shell/run-a-single-test.sh b/shell/run-a-single-test.sh
index f82313b..3f5b63e 100755
--- a/shell/run-a-single-test.sh
+++ b/shell/run-a-single-test.sh
@@ -2,12 +2,25 @@
 
 source shell/functions.sh
 
-# Check if an argument was provided to the script
-if [ $# -eq 1 ]; then
-    # Use the argument as the "file" variable
-    file="$1"
-else
-    # Prompt the user for input and store it in the "file" variable
+# Initialize default values
+local_mode=false
+
+# Parse command-line arguments
+while [[ "$#" -gt 0 ]]; do
+    case "$1" in
+        --local)
+            local_mode=true
+            shift
+            ;;
+        *)
+            file="$1"
+            shift
+            ;;
+    esac
+done
+
+# Prompt the user for input if no file argument was provided
+if [ -z "$file" ]; then
     echo -n "Enter the path to the test file (e.g., /tests/b2b/sapi/tests/cart/B2B-SAPI4-carts.js): "
     read file
 fi
@@ -23,12 +36,21 @@ $(create_folder_if_not_existant "$outputFolder")
 # Get the path of the current file relative to the original directory
 testFile=${file#$(pwd)/}
 
-# Construct the docker command
-if ! command=$(build_k6_docker_command "$testFile" "$reportFile" "$testRunId"); then
-    exit 1;
-fi
+# Check if --local flag is set
+if $local_mode; then
+    if ! command=$(build_k6_local_command "$testFile" "$reportFile" "$testRunId"); then
+        exit 1
+    fi
 
-echo "Running command: '$command'"
+    echo "Running command in local mode: '$command'"
+else
+    # Construct the docker command
+    if ! command=$(build_k6_docker_command "$testFile" "$reportFile" "$testRunId"); then
+        exit 1;
+    fi
+
+    echo "Running command: '$command'"
+fi
 
 # Record the start time
 start_timer
diff --git a/tests/abstract-scenario.js b/tests/abstract-scenario.js
index cec01cb..7ed9247 100644
--- a/tests/abstract-scenario.js
+++ b/tests/abstract-scenario.js
@@ -8,7 +8,7 @@ import { Trend } from 'k6/metrics';
 import CustomerHelper from '../helpers/customer-helper.js';
 import { AssertionsHelper } from '../helpers/assertions-helper.js';
 import { BapiHelper } from '../helpers/bapi-helper.js';
-import AdminHelper from '../helpers/admin-helper.js';
+import { AdminHelper } from '../helpers/admin-helper.js';
 
 export class AbstractScenario {
     // eslint-disable-next-line no-unused-vars
@@ -27,12 +27,13 @@ export class AbstractScenario {
         this.environmentConfig = loadEnvironmentConfig(this.environment);
         this.urlHelper = new UrlHelper(this.environmentConfig);
         this.customerHelper = new CustomerHelper();
-        this.adminHelper = new AdminHelper();
         this.assertionsHelper = new AssertionsHelper();
+        this.browserHelper = new BrowserHelper(this.urlHelper, this.customerHelper, this.assertionsHelper);
+        this.adminHelper = new AdminHelper(this.urlHelper, this.http, this.assertionsHelper, this.browserHelper);
         this.cartHelper = new CartHelper(this.urlHelper, this.http, this.customerHelper, this.assertionsHelper);
         this.bapiHelper = new BapiHelper(this.urlHelper, this.http, this.adminHelper, this.assertionsHelper);
         this.storefrontHelper = new StorefrontHelper(this.urlHelper, this.http, this.customerHelper, this.assertionsHelper);
-        this.browserHelper = new BrowserHelper(this.urlHelper, this.customerHelper, this.assertionsHelper);
+
     }
 
     createTrendMetric(name) {
diff --git a/tests/b2b/backoffice/tests/order-management/tests/order-management-list.js b/tests/b2b/backoffice/tests/order-management/tests/order-management-list.js
new file mode 100644
index 0000000..bb0934a
--- /dev/null
+++ b/tests/b2b/backoffice/tests/order-management/tests/order-management-list.js
@@ -0,0 +1,32 @@
+import { SharedOrderManagementListScenario } from '../../../../../cross-product/backoffice/scenarios/order-management/shared-order-management-list-scenario.js';
+import { CheckoutScenario } from '../../../../sapi/scenarios/checkout/checkout-scenario.js';
+import { loadDefaultOptions } from '../../../../../../lib/utils.js';
+export { handleSummary } from '../../../../../../helpers/summary-helper.js';
+
+const sharedCheckoutScenario = new CheckoutScenario('B2B');
+const sharedOrderManagementListScenario = new SharedOrderManagementListScenario('B2B', sharedCheckoutScenario);
+const backofficeUrl = sharedOrderManagementListScenario.urlHelper.getBackofficeBaseUrl();
+
+export const options = loadDefaultOptions();
+options.scenarios = {
+    Order_Management_List: {
+        exec: 'executeSharedOrderManagementListScenario',
+        executor: 'shared-iterations',
+        vus: 1,
+        iterations: 10,
+        options: {
+            browser: {
+                type: 'chromium',
+            },
+        },
+    },
+};
+
+options.thresholds = {
+    [`browser_http_req_duration{url:${backofficeUrl}/sales}`]: ['avg<600'],
+    [`browser_http_req_duration{url:${backofficeUrl}/sales/index/table}`]: ['avg<600'],
+}
+
+export async function executeSharedOrderManagementListScenario() {
+    await sharedOrderManagementListScenario.execute();
+}
\ No newline at end of file
diff --git a/tests/b2b/backoffice/tests/order-management/tests/order-management-pay.js b/tests/b2b/backoffice/tests/order-management/tests/order-management-pay.js
new file mode 100644
index 0000000..295e207
--- /dev/null
+++ b/tests/b2b/backoffice/tests/order-management/tests/order-management-pay.js
@@ -0,0 +1,32 @@
+import { SharedOrderManagementPayScenario } from '../../../../../cross-product/backoffice/scenarios/order-management/shared-order-management-pay-scenario.js';
+import { CheckoutScenario } from '../../../../sapi/scenarios/checkout/checkout-scenario.js';
+import { loadDefaultOptions } from '../../../../../../lib/utils.js';
+export { handleSummary } from '../../../../../../helpers/summary-helper.js';
+
+const sharedCheckoutScenario = new CheckoutScenario('B2B');
+const sharedOrderManagementPayScenario = new SharedOrderManagementPayScenario('B2B', sharedCheckoutScenario);
+const backofficeUrl = sharedOrderManagementPayScenario.urlHelper.getBackofficeBaseUrl();
+
+export const options = loadDefaultOptions();
+options.scenarios = {
+    Order_Management_Pay: {
+        exec: 'executeSharedOrderManagementPayScenario',
+        executor: 'shared-iterations',
+        vus: 1,
+        iterations: 1,
+        options: {
+            browser: {
+                type: 'chromium',
+            },
+        },
+    },
+};
+
+options.thresholds = {
+    [`browser_http_req_duration{url:${backofficeUrl}/sales/detail}`]: ['avg<600'],
+    [`browser_http_req_duration{url:${backofficeUrl}/oms/trigger/submit-trigger-event-for-order}`]: ['avg<600'],
+}
+
+export async function executeSharedOrderManagementPayScenario() {
+    await sharedOrderManagementPayScenario.execute();
+}
\ No newline at end of file
diff --git a/tests/b2b/backoffice/tests/order-management/tests/test.js b/tests/b2b/backoffice/tests/order-management/tests/test.js
new file mode 100644
index 0000000..0fb735b
--- /dev/null
+++ b/tests/b2b/backoffice/tests/order-management/tests/test.js
@@ -0,0 +1,103 @@
+// this file is only for testing custom scripts
+import { browser } from 'k6/browser';
+
+export const options = {
+    scenarios: {
+        default: {
+            executor: 'per-vu-iterations',
+            options: {
+                browser: {
+                    type: 'chromium',
+                },
+            },
+        },
+    },
+};
+
+export default async function () {
+    console.log('Opening a new browser context');
+    const context = await browser.newContext();
+    console.log('Opening a new page');
+    const page = await context.newPage();
+
+    // Listen to browser console messages
+    page.on('console', (msg) => console.log(`[Browser Console]: ${msg.type()}: ${msg.text()}`));
+
+    try {
+        // Navigate to login page
+        await page.goto('http://backoffice.eu.spryker.local/security-gui/login');
+        await page.waitForLoadState('domcontentloaded', { timeout: 5000 });
+
+        // Login actions
+        await page.locator('input[name="auth[username]"]').fill('admin@spryker.com');
+        await page.locator('input[name="auth[password]"]').fill('change123');
+        await page.locator('form[name="auth"] button[type="submit"]').click();
+        await page.screenshot({ path: 'results/screenshot.png' });
+
+        // Navigate to sales page
+        await page.goto('http://backoffice.eu.spryker.local/sales');
+        await page.waitForLoadState('networkidle', { timeout: 5000 });
+        await page.screenshot({ path: 'results/sales.png' });
+
+        // Navigate to sales details page
+        await page.locator('.dataTable tbody tr:nth-child(1) .btn-view').click();
+        await page.waitForLoadState('networkidle', { timeout: 5000 });
+        await page.screenshot({ path: 'results/sales-detail.png' });
+
+        console.log('Triggering the ship event');
+
+        // Custom retry logic for waiting and clicking the button
+        const buttonLocator = page.locator('#oms_trigger_form_submit');
+        let retries = 0;
+        let maxRetries = 5;
+
+        while (retries < maxRetries) {
+            try {
+                console.log(`Checking for the button (attempt ${retries + 1})...`);
+
+                // Wait for the button to be present in the DOM
+                await buttonLocator.waitFor({ state: 'attached', timeout: 5000 });
+                console.log('Button is present in the DOM.');
+
+                // Check if button is visible and interactable
+                const isVisible = await buttonLocator.isVisible();
+                if (isVisible) {
+                    console.log('Button is visible, attempting to click...');
+                    await buttonLocator.click();
+                    console.log('Button clicked!');
+                    break; // Exit retry loop if successful
+                } else {
+                    console.log('Button is not visible. Retrying...');
+                }
+            } catch (error) {
+                console.log('Error interacting with the button:', error.message);
+            }
+
+            // Increment retry count and delay between retries
+            retries++;
+            if (retries < maxRetries) {
+                console.log('Retrying in 2 seconds...');
+                await page.waitForTimeout(2000);
+            } else {
+                throw new Error('Max retries reached, button not clickable');
+            }
+        }
+
+        // Wait for network to be idle after the action
+        console.log('Waiting for the network to be idle');
+        await page.waitForLoadState('networkidle', { timeout: 10000 });
+        await page.screenshot({ path: 'results/sales-detail-oms.png' });
+    } catch (error) {
+        console.error(
+            'Error during page operations:',
+            error.stack || error.message || JSON.stringify(error, null, 2)
+        );
+    } finally {
+        if (page) {
+            await page.close();
+        }
+        if (context) {
+            await context.close();
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/cross-product/backoffice/scenarios/order-management/shared-order-management-list-scenario.js b/tests/cross-product/backoffice/scenarios/order-management/shared-order-management-list-scenario.js
new file mode 100644
index 0000000..f3cce82
--- /dev/null
+++ b/tests/cross-product/backoffice/scenarios/order-management/shared-order-management-list-scenario.js
@@ -0,0 +1,42 @@
+import { AbstractScenario } from '../../../../abstract-scenario.js';
+import { group } from 'k6';
+
+const numberOfOrders = 1;
+
+export class SharedOrderManagementListScenario extends AbstractScenario {
+    constructor(environment, checkoutScenario) {
+        super(environment);
+        this.checkoutScenario = checkoutScenario;
+        this.ordersCreated = false;
+    }
+
+    async createOrders() {
+        let self = this;
+
+        group('Create Orders', function () {
+            for (let i = 0; i < numberOfOrders; i++) {
+                self.checkoutScenario.execute(1);
+            }
+        });
+
+        this.ordersCreated = true;
+    }
+
+    async execute() {
+        let self = this;
+
+        if (!this.ordersCreated) {
+            await this.createOrders();
+        }
+
+        try {
+            await self.adminHelper.loginBackoffice();
+            await self.adminHelper.goToSalesPage();
+        } finally {
+            let context = self.adminHelper.contextStorage.getContext();
+            await self.adminHelper.contextStorage.getPage().close();
+            await context.close();
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/tests/cross-product/backoffice/scenarios/order-management/shared-order-management-pay-scenario.js b/tests/cross-product/backoffice/scenarios/order-management/shared-order-management-pay-scenario.js
new file mode 100644
index 0000000..0c1dcad
--- /dev/null
+++ b/tests/cross-product/backoffice/scenarios/order-management/shared-order-management-pay-scenario.js
@@ -0,0 +1,44 @@
+import { AbstractScenario } from '../../../../abstract-scenario.js';
+import { group, sleep } from 'k6';
+
+export class SharedOrderManagementPayScenario extends AbstractScenario {
+    constructor(environment, checkoutScenario) {
+        super(environment);
+        this.checkoutScenario = checkoutScenario;
+    }
+
+    createOrders() {
+        let self = this;
+
+        group('Create Order', function () {
+            self.checkoutScenario.execute(1);
+        });
+    }
+
+    async execute() {
+        let self = this;
+
+        this.createOrders();
+
+        try {
+            await self.adminHelper.loginBackoffice();
+            sleep(1);
+            await self.adminHelper.goToSalesPage();
+            sleep(1);
+            await self.adminHelper.openFirstSalesOrder();
+            sleep(1);
+            await self.adminHelper.waitForOrderHasOmsTriggerButton();
+            sleep(1);
+            await self.adminHelper.payForTheOrder();
+            sleep(1);
+
+        } catch (error) {
+            console.log(error);
+            self.adminHelper.takeScreenshot('error.png');
+        } finally {
+            const context = self.adminHelper.contextStorage.getContext();
+            await self.adminHelper.contextStorage.getPage().close();
+            await context.close();
+        }
+    }
+}
\ No newline at end of file