diff --git a/README.md b/README.md
index ea5566a6..8e599550 100644
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@
  * object_complex.robot - операции над простым объектом
  * object_simple.robot - операции над большим объектом
  * withdraw.robot - оперция Deposit и Withdraw с счета NeoFS
- * netmap_simple.robot - проверка Placement policy 
+ * netmap_simple.robot - проверка Placement policy
  * replication.robot - базовый тесткейс проверки репликации объектов
 
 ### Запуск тесткейсов в докере
@@ -54,6 +54,21 @@
 export BUILD_NEOFS_NODE=<commit or branch>
 ```
 
+### Запуск smoke-тестов
+
+Есть сьют со smoke-тестами для CDN-гейтов `robot/testsuites/smoke/selectelcdn_smoke.robot`.
+Ему требуются отдельные переменные, в отличие от сьютов NeoFS, которые запускаются на
+девэнве. Чтобы библиотеки кейвордов их использовали, нужно установить переменную
+окружения
+```
+export ROBOT_PROFILE=selectel_smoke
+```
+По умолчанию кейворды используют переменные из файла `robot/resources/lib/neofs_int_vars.py`.
+```
+robot --outputdir artifacts/ robot/testsuites/smoke/selectelcdn_smoke.robot
+```
+
+
 ### Генерация документации
 
 Для генерации документации по шагам:
@@ -110,4 +125,4 @@ On keywords definition, one should specify variable type, e.g. path: str
 
 ### Robot-framework User Guide
 
-http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html
\ No newline at end of file
+http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html
diff --git a/robot/resources/lib/gates.py b/robot/resources/lib/gates.py
new file mode 100644
index 00000000..d33b9ddf
--- /dev/null
+++ b/robot/resources/lib/gates.py
@@ -0,0 +1,41 @@
+#!/usr/bin/python3
+
+import logging
+import os
+import requests
+
+from robot.api.deco import keyword
+from robot.api import logger
+import robot.errors
+from robot.libraries.BuiltIn import BuiltIn
+
+
+ROBOT_AUTO_KEYWORDS = False
+
+if os.getenv('ROBOT_PROFILE') == 'selectel_smoke':
+    from selectelcdn_smoke_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT,
+    NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT, HTTP_GATE)
+else:
+    from neofs_int_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT,
+    NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT, HTTP_GATE)
+
+
+@keyword('Get via HTTP Gate')
+def get_via_http_gate(cid: str, oid: str):
+    """
+    This function gets given object from HTTP gate
+    :param cid:      CID to get object from
+    :param oid:      object OID
+    """
+    resp = requests.get(f'{HTTP_GATE}/get/{cid}/{oid}')
+    if not resp.ok:
+        logger.info(f"""Failed to get object via HTTP gate:
+                request: {resp.request.path_url},
+                response: {resp.text},
+                status code: {resp.status_code} {resp.reason}""")
+        return
+
+    filename = os.path.curdir + f"/{cid}_{oid}"
+    with open(filename, "w+") as f:
+        f.write(resp.text)
+    return filename
diff --git a/robot/resources/lib/neofs.py b/robot/resources/lib/neofs.py
index 775a22b8..4ca9f094 100644
--- a/robot/resources/lib/neofs.py
+++ b/robot/resources/lib/neofs.py
@@ -8,12 +8,17 @@ import uuid
 import hashlib
 from robot.api.deco import keyword
 from robot.api import logger
-import random 
+import random
 
+if os.getenv('ROBOT_PROFILE') == 'selectel_smoke':
+    from selectelcdn_smoke_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT,
+    NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT)
+else:
+    from neofs_int_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT,
+    NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT)
 
 ROBOT_AUTO_KEYWORDS = False
 
-NEOFS_ENDPOINT = "s01.neofs.devenv:8080"
 CLI_PREFIX = ""
 
 @keyword('Form WIF from String')
@@ -27,7 +32,7 @@ def form_wif_from_string(private_key: str):
     logger.info("Output: %s" % output)
 
     m = re.search(r'WIF\s+(\w+)', output)
-    if m.start() != m.end(): 
+    if m.start() != m.end():
         wif = m.group(1)
     else:
         raise Exception("Can not get WIF.")
@@ -46,7 +51,7 @@ def get_scripthash(privkey: str):
     logger.info("Output: %s" % output)
 
     m = re.search(r'ScriptHash3.0   (\w+)', output)
-    if m.start() != m.end(): 
+    if m.start() != m.end():
         scripthash = m.group(1)
     else:
         raise Exception("Can not get ScriptHash.")
@@ -175,7 +180,7 @@ def get_eacl(private_key: bytes, cid: str):
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=150, shell=True)
         output = complProc.stdout
         logger.info("Output: %s" % output)
-        
+
         return output
 
     except subprocess.CalledProcessError as e:
@@ -184,7 +189,7 @@ def get_eacl(private_key: bytes, cid: str):
         else:
             raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
 
- 
+
 
 @keyword('Set eACL')
 def set_eacl(private_key: str, cid: str, eacl: str, add_keys: str = ""):
@@ -199,7 +204,7 @@ def set_eacl(private_key: str, cid: str, eacl: str, add_keys: str = ""):
 
 
 @keyword('Form BearerToken file for all ops')
-def form_bearertoken_file_for_all_ops(file_name: str, private_key: str, cid: str, action: str, target_role: str, lifetime_exp: str ):  
+def form_bearertoken_file_for_all_ops(file_name: str, private_key: str, cid: str, action: str, target_role: str, lifetime_exp: str ):
 
     eacl = get_eacl(private_key, cid)
     input_records = ""
@@ -307,10 +312,10 @@ def form_bearertoken_file_for_all_ops(file_name: str, private_key: str, cid: str
 
     return file_name
 
- 
+
 
 @keyword('Form BearerToken file filter for all ops')
-def form_bearertoken_file_filter_for_all_ops(file_name: str, private_key: str, cid: str, action: str, target_role: str, lifetime_exp: str, matchType: str, key: str, value: str):  
+def form_bearertoken_file_filter_for_all_ops(file_name: str, private_key: str, cid: str, action: str, target_role: str, lifetime_exp: str, matchType: str, key: str, value: str):
 
     # SEARCH should be allowed without filters to use GET, HEAD, DELETE, and SEARCH? Need to clarify.
 
@@ -471,8 +476,8 @@ def form_bearertoken_file_filter_for_all_ops(file_name: str, private_key: str, c
 
 
 @keyword('Form eACL json file')
-def form_eacl_json_file(file_name: str, operation: str, action: str, matchType: str, key: str, value: str, target_role: str): 
- 
+def form_eacl_json_file(file_name: str, operation: str, action: str, matchType: str, key: str, value: str, target_role: str):
+
     myjson = """
 {
   "records": [
@@ -509,9 +514,9 @@ def form_eacl_json_file(file_name: str, operation: str, action: str, matchType:
 def get_range(private_key: str, cid: str, oid: str, range_file: str, bearer: str, range_cut: str):
 
     bearer_token = ""
-    if bearer: 
+    if bearer:
         bearer_token = f"--bearer {bearer}"
- 
+
     Cmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} object range --cid {cid} --oid {oid} {bearer_token} --range {range_cut} --file {range_file} '
     logger.info("Cmd: %s" % Cmd)
 
@@ -526,10 +531,10 @@ def get_range(private_key: str, cid: str, oid: str, range_file: str, bearer: str
 
 @keyword('Create container')
 def create_container(private_key: str, basic_acl:str="", rule:str="REP 2 IN X CBF 1 SELECT 2 FROM * AS X"):
-    
+
     if basic_acl != "":
         basic_acl = "--basic-acl " + basic_acl
-    
+
     createContainerCmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} container create --policy "{rule}" {basic_acl} --await'
     logger.info("Cmd: %s" % createContainerCmd)
     complProc = subprocess.run(createContainerCmd, check=True, universal_newlines=True,
@@ -549,7 +554,7 @@ def container_existing(private_key: str, cid: str):
     complProc = subprocess.run(Cmd, check=True, universal_newlines=True,
             stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
     logger.info("Output: %s" % complProc.stdout)
-    
+
     _find_cid(complProc.stdout, cid)
     return
 
@@ -569,14 +574,14 @@ def generate_file_of_bytes(size):
         fout.write(os.urandom(size))
 
     logger.info("Random binary file with size %s bytes has been generated." % str(size))
-    return filename
+    return os.path.abspath(os.getcwd()) + '/' + filename
 
 
 @keyword('Search object')
 def search_object(private_key: str, cid: str, keys: str, bearer: str, filters: str, *expected_objects_list ):
 
     bearer_token = ""
-    if bearer: 
+    if bearer:
         bearer_token = f"--bearer {bearer}"
 
 
@@ -594,7 +599,7 @@ def search_object(private_key: str, cid: str, keys: str, bearer: str, filters: s
         if expected_objects_list:
             found_objects = re.findall(r'(\w{43,44})', complProc.stdout)
 
-             
+
             if sorted(found_objects) == sorted(expected_objects_list):
                 logger.info("Found objects list '{}' is equal for expected list '{}'".format(found_objects, expected_objects_list))
             else:
@@ -603,7 +608,7 @@ def search_object(private_key: str, cid: str, keys: str, bearer: str, filters: s
 
 
     except subprocess.CalledProcessError as e:
-        raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))    
+        raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
 
 '''
 @keyword('Verify Head Tombstone')
@@ -620,23 +625,20 @@ def verify_head_tombstone(private_key: str, cid: str, oid: str):
             logger.info("Tombstone header 'Type=Tombstone Value=MARKED' was parsed from command output")
         else:
             raise Exception("Tombstone header 'Type=Tombstone Value=MARKED' was not found in the command output: \t%s" % (complProc.stdout))
-   
+
     except subprocess.CalledProcessError as e:
         raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
-'''
 
-
-'''
 @keyword('Verify linked objects')
 def verify_linked_objects(private_key: bytes, cid: str, oid: str, payload_size: float):
-    
+
     payload_size = int(float(payload_size))
 
     # Get linked objects from first
     postfix = f'object head --cid {cid} --oid {oid} --full-headers'
     output = _exec_cli_cmd(private_key, postfix)
     child_obj_list = []
-    
+
     for m in re.finditer(r'Type=Child ID=([\w-]+)', output):
         child_obj_list.append(m.group(1))
 
@@ -647,7 +649,7 @@ def verify_linked_objects(private_key: bytes, cid: str, oid: str, payload_size:
         raise Exception("Child objects was not found.")
     else:
         logger.info("Child objects: %s" % child_obj_list)
- 
+
     # HEAD and validate each child object:
     payload = 0
     parent_id = "00000000-0000-0000-0000-000000000000"
@@ -665,7 +667,7 @@ def verify_linked_objects(private_key: bytes, cid: str, oid: str, payload_size:
     if not first_obj:
         raise Exception("Can not find first object with zero Parent ID.")
     else:
-        
+
         _check_linked_object(first_obj, child_obj_list_headers, payload_size, payload, parent_id)
 
     return child_obj_list_headers.keys()
@@ -682,11 +684,11 @@ def _check_linked_object(obj:str, child_obj_list_headers:dict, payload_size:int,
         logger.info("Previous ID is equal for expected: %s" % parent_id)
 
     m = re.search(r'PayloadLength=(\d+)', output)
-    if m.start() != m.end(): 
+    if m.start() != m.end():
         payload += int(m.group(1))
     else:
         raise Exception("Can not get payload for the object %s." % obj)
- 
+
     if payload > payload_size:
         raise Exception("Payload exceeds expected total payload %s." % payload_size)
 
@@ -695,10 +697,10 @@ def _check_linked_object(obj:str, child_obj_list_headers:dict, payload_size:int,
             raise Exception("Incorrect previos ID in the last child object %s." % obj)
         else:
             logger.info("Next ID is correct for the final child object: %s" % obj)
-    
+
     else:
         m = re.search(r'Type=Next ID=([\w-]+)', output)
-        if m: 
+        if m:
             # next object should be in the expected list
             logger.info(m.group(1))
             if m.group(1) not in child_obj_list_headers.keys():
@@ -735,13 +737,13 @@ def head_object(private_key: str, cid: str, oid: str, bearer: str, user_headers:
                 logger.info("User header %s was parsed from command output" % key)
             else:
                 raise Exception("User header %s was not found in the command output: \t%s" % (key, complProc.stdout))
-   
+
         return complProc.stdout
 
     except subprocess.CalledProcessError as e:
         raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
 
-    
+
 
 
 @keyword('Parse Object System Header')
@@ -770,7 +772,6 @@ def parse_object_system_header(header: str):
         result_header['OwnerID'] = m.group(1)
     else:
         raise Exception("no OwnerID was parsed from object header: \t%s" % output)
-    
     # PayloadLength
     m = re.search(r'Size: (\d+)', header)
     if m.start() != m.end(): # e.g., if match found something
@@ -778,7 +779,7 @@ def parse_object_system_header(header: str):
     else:
         raise Exception("no PayloadLength was parsed from object header: \t%s" % output)
 
-    # CreatedAtUnixTime 
+    # CreatedAtUnixTime
     m = re.search(r'Timestamp=(\d+)', header)
     if m.start() != m.end(): # e.g., if match found something
         result_header['CreatedAtUnixTime'] = m.group(1)
@@ -795,7 +796,6 @@ def parse_object_system_header(header: str):
     logger.info("Result: %s" % result_header)
     return result_header
 
-
 @keyword('Delete object')
 def delete_object(private_key: str, cid: str, oid: str, bearer: str):
 
@@ -809,7 +809,7 @@ def delete_object(private_key: str, cid: str, oid: str, bearer: str):
                     stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
         logger.info("Output: %s" % complProc.stdout)
     except subprocess.CalledProcessError as e:
-        raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output)) 
+        raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
 
 
 @keyword('Get file hash')
@@ -826,46 +826,17 @@ def verify_file_hash(filename, expected_hash):
     else:
         raise Exception("File hash '{}' is not equal to {}".format(file_hash, expected_hash))
 
-'''
-@keyword('Create storage group')
-def create_storage_group(private_key: bytes, cid: str, *objects_list):
-    objects = ""
-
-    for oid in objects_list:
-        objects = f'{objects} --oid {oid}'
-
-    ObjectCmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} sg put --cid {cid} {objects}'
-    complProc = subprocess.run(ObjectCmd, check=True, universal_newlines=True,
-            stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
-    logger.info("Output: %s" % complProc.stdout)
-    sgid = _parse_oid(complProc.stdout)
-    return sgid
-
-
-@keyword('Get storage group')
-def get_storage_group(private_key: bytes, cid: str, sgid: str):
-    ObjectCmd = f'{CLI_PREFIX}neofs-cli --host {NEOFS_ENDPOINT} --key {binascii.hexlify(private_key).decode()} sg get --cid {cid} --sgid {sgid}'
-    logger.info("Cmd: %s" % ObjectCmd)
-    try:
-        complProc = subprocess.run(ObjectCmd, check=True, universal_newlines=True,
-                    stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
-        logger.info("Output: %s" % complProc.stdout)
-    except subprocess.CalledProcessError as e:
-        raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
-'''
-
-
 @keyword('Cleanup File')
 # remove temp files
 def cleanup_file(filename: str):
     if os.path.isfile(filename):
         try:
             os.remove(filename)
-        except OSError as e:  
+        except OSError as e:
             raise Exception("Error: '%s' - %s." % (e.filename, e.strerror))
-    else:    
+    else:
         raise Exception("Error: '%s' file not found" % filename)
-   
+
     logger.info("File '%s' has been deleted." % filename)
 
 
@@ -895,10 +866,10 @@ def put_object(private_key: str, path: str, cid: str, bearer: str, user_headers:
 
 @keyword('Get Range Hash')
 def get_range_hash(private_key: str, cid: str, oid: str, bearer_token: str, range_cut: str):
- 
-    if bearer_token: 
+
+    if bearer_token:
         bearer_token = f"--bearer {bearer}"
- 
+
     ObjectCmd = f'neofs-cli --rpc-endpoint {NEOFS_ENDPOINT} --key {private_key} object hash --cid {cid} --oid {oid} --range {range_cut} {bearer_token}'
 
     logger.info("Cmd: %s" % ObjectCmd)
@@ -909,7 +880,6 @@ def get_range_hash(private_key: str, cid: str, oid: str, bearer_token: str, rang
     except subprocess.CalledProcessError as e:
         raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
 
-
 @keyword('Get object from NeoFS')
 def get_object(private_key: str, cid: str, oid: str, bearer_token: str, read_object: str):
 
@@ -940,7 +910,7 @@ def _exec_cli_cmd(private_key: bytes, postfix: str):
 
     except subprocess.CalledProcessError as e:
         raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
-    
+
     return complProc.stdout
 
 
@@ -978,7 +948,7 @@ def _parse_oid(output: str):
         oid = m.group(1)
     else:
         raise Exception("no OID was parsed from command output: \t%s" % output)
-        
+
     return oid
 
 def _parse_cid(output: str):
@@ -991,7 +961,7 @@ def _parse_cid(output: str):
     if not m.start() != m.end(): # e.g., if match found something
         raise Exception("no CID was parsed from command output: \t%s" % (output))
     cid = m.group(1)
-        
+
     return cid
 
 def _get_storage_nodes(private_key: bytes):
@@ -1003,7 +973,7 @@ def _get_storage_nodes(private_key: bytes):
     #logger.info("Netmap: %s" % output)
     #for m in re.finditer(r'"address":"/ip4/(\d+\.\d+\.\d+\.\d+)/tcp/(\d+)"', output):
     #    storage_nodes.append(m.group(1)+":"+m.group(2))
-    
+
     #if not storage_nodes:
     #    raise Exception("Storage nodes was not found.")
 
@@ -1039,9 +1009,9 @@ def _search_object(node:str, private_key: str, cid:str, oid: str):
 
         elif ( re.search(r'timed out after 30 seconds', e.output) or re.search(r'no route to host', e.output) ):
             logger.warn("Node is unavailable")
-            
+
         else:
             raise Exception("command '{}' return with error (code {}): {}".format(e.cmd, e.returncode, e.output))
 
 
-    
\ No newline at end of file
+
diff --git a/robot/resources/lib/neofs_int_vars.py b/robot/resources/lib/neofs_int_vars.py
new file mode 100644
index 00000000..7e2ea29d
--- /dev/null
+++ b/robot/resources/lib/neofs_int_vars.py
@@ -0,0 +1,9 @@
+#!/usr/bin/python3
+import os
+
+NEOFS_ENDPOINT = "s01.neofs.devenv:8080"
+NEOGO_CLI_PREFIX = "docker exec -it main_chain neo-go"
+NEO_MAINNET_ENDPOINT = "main_chain.neofs.devenv:30333"
+
+NEOFS_NEO_API_ENDPOINT = 'http://main_chain.neofs.devenv:30333'
+HTTP_GATE = ''
diff --git a/robot/resources/lib/payment_neogo.py b/robot/resources/lib/payment_neogo.py
index 9c2ae859..8bad043f 100644
--- a/robot/resources/lib/payment_neogo.py
+++ b/robot/resources/lib/payment_neogo.py
@@ -4,24 +4,27 @@ import subprocess
 import pexpect
 import re
 import uuid
+import logging
+import requests
+import json
+import os
 
 from robot.api.deco import keyword
 from robot.api import logger
-
-import logging
 import robot.errors
-import requests
-import json
-
 from robot.libraries.BuiltIn import BuiltIn
 
 ROBOT_AUTO_KEYWORDS = False
 
+if os.getenv('ROBOT_PROFILE') == 'selectel_smoke':
+    from selectelcdn_smoke_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT,
+    NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT)
+else:
+    from neofs_int_vars import (NEOGO_CLI_PREFIX, NEO_MAINNET_ENDPOINT,
+    NEOFS_NEO_API_ENDPOINT, NEOFS_ENDPOINT)
 
 
 NEOFS_CONTRACT = "5f490fbd8010fd716754073ee960067d28549b7d"
-NEOGO_CLI_PREFIX = "docker exec -it main_chain neo-go"
-NEO_MAINNET_ENDPOINT = "main_chain.neofs.devenv:30333"
 
 @keyword('Init wallet')
 def init_wallet():
@@ -30,7 +33,7 @@ def init_wallet():
     cmd = ( f"{NEOGO_CLI_PREFIX} wallet init -w {filename}" )
 
     logger.info(f"Executing shell command: {cmd}")
-    out = _run_sh(cmd) 
+    out = _run_sh(cmd)
     logger.info(f"Command completed with output: {out}")
     return filename
 
@@ -55,11 +58,11 @@ def dump_address(wallet: str):
     cmd = ( f"{NEOGO_CLI_PREFIX} wallet dump -w {wallet}" )
 
     logger.info(f"Executing command: {cmd}")
-    out = _run_sh(cmd) 
+    out = _run_sh(cmd)
     logger.info(f"Command completed with output: {out}")
 
     m = re.search(r'"address": "(\w+)"', out)
-    if m.start() != m.end(): 
+    if m.start() != m.end():
         address = m.group(1)
     else:
         raise Exception("Can not get address.")
@@ -76,8 +79,7 @@ def dump_privkey(wallet: str, address: str):
 
     return out
 
-
-@keyword('Transfer Mainnet Gas') 
+@keyword('Transfer Mainnet Gas')
 def transfer_mainnet_gas(wallet: str, address: str, address_to: str, amount: int):
     cmd = ( f"{NEOGO_CLI_PREFIX} wallet nep5 transfer -w {wallet} -r http://main_chain.neofs.devenv:30333 --from {address} "
             f"--to {address_to} --token gas --amount {amount}" )
@@ -91,7 +93,7 @@ def transfer_mainnet_gas(wallet: str, address: str, address_to: str, amount: int
 
     return out
 
-@keyword('Withdraw Mainnet Gas') 
+@keyword('Withdraw Mainnet Gas')
 def withdraw_mainnet_gas(wallet: str, address: str, scripthash: str, amount: int):
     cmd = ( f"{NEOGO_CLI_PREFIX} contract invokefunction -w {wallet} -a {address} -r http://main_chain.neofs.devenv:30333 "
             f"{NEOFS_CONTRACT} withdraw {scripthash} int:{amount}  -- {scripthash}" )
@@ -100,56 +102,6 @@ def withdraw_mainnet_gas(wallet: str, address: str, scripthash: str, amount: int
     out = _run_sh_with_passwd('', cmd)
     logger.info(f"Command completed with output: {out}")
 
-    m = re.match(r'^Sent invocation transaction (\w{64})$', out)
-    if m is None:
-        raise Exception("Can not get Tx.") 
-    
-    tx = m.group(1)
-
-    return tx
-
-
-@keyword('Mainnet Balance')
-def mainnet_balance(address: str):
-    request = 'curl -X POST '+NEO_MAINNET_ENDPOINT+' --cacert ca/nspcc-ca.pem -H \'Content-Type: application/json\' -d \'{ "jsonrpc": "2.0", "id": 5, "method": "getnep5balances", "params": [\"'+address+'\"] }\''
-    logger.info(f"Executing request: {request}")
-
-    complProc = subprocess.run(request, check=True, universal_newlines=True,
-            stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
-
-    out = complProc.stdout
-    logger.info(out)
-
-    m = re.search(r'"668e0c1f9d7b70a99dd9e06eadd4c784d641afbc","amount":"([\d\.]+)"', out)
-    if not m.start() != m.end(): 
-        raise Exception("Can not get mainnet gas balance.")
-
-    amount = m.group(1)
-        
-    return amount
-
-
-@keyword('Expexted Mainnet Balance')
-def expected_mainnet_balance(address: str, expected: float):
-    
-    amount = mainnet_balance(address)
-
-    if float(amount) != float(expected):
-        raise Exception(f"Expected amount ({expected}) of GAS has not been found. Found {amount}.")
-
-    return True
-
-
-@keyword('NeoFS Deposit') 
-def neofs_deposit(wallet: str, address: str, scripthash: str, amount: int):
-    cmd = ( f"{NEOGO_CLI_PREFIX} contract invokefunction -w {wallet} -a {address} "
-            f"-r http://main_chain.neofs.devenv:30333 {NEOFS_CONTRACT} " 
-            f"deposit {scripthash} int:{amount} bytes: -- {scripthash}")
-
-    logger.info(f"Executing command: {cmd}")
-    out = _run_sh_with_passwd('', cmd)
-    logger.info(f"Command completed with output: {out}")
-
     m = re.match(r'^Sent invocation transaction (\w{64})$', out)
     if m is None:
         raise Exception("Can not get Tx.")
@@ -158,6 +110,52 @@ def neofs_deposit(wallet: str, address: str, scripthash: str, amount: int):
 
     return tx
 
+@keyword('Mainnet Balance')
+def mainnet_balance(address: str):
+    request = 'curl -X POST '+NEO_MAINNET_ENDPOINT+' --cacert ca/nspcc-ca.pem -H \'Content-Type: application/json\' -d \'{ "jsonrpc": "2.0", "id": 5, "method": "getnep5balances", "params": [\"'+address+'\"] }\''
+    logger.info(f"Executing request: {request}")
+
+    complProc = subprocess.run(request, check=True, universal_newlines=True,
+            stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
+
+    out = complProc.stdout
+    logger.info(out)
+
+    m = re.search(r'"668e0c1f9d7b70a99dd9e06eadd4c784d641afbc","amount":"([\d\.]+)"', out)
+    if not m.start() != m.end():
+        raise Exception("Can not get mainnet gas balance.")
+
+    amount = m.group(1)
+
+    return amount
+
+
+@keyword('Expexted Mainnet Balance')
+def expected_mainnet_balance(address: str, expected: float):
+    amount = mainnet_balance(address)
+
+    if float(amount) != float(expected):
+        raise Exception(f"Expected amount ({expected}) of GAS has not been found. Found {amount}.")
+
+    return True
+
+@keyword('NeoFS Deposit')
+def neofs_deposit(wallet: str, address: str, scripthash: str, amount: int, wallet_pass:str=''):
+    cmd = ( f"{NEOGO_CLI_PREFIX} contract invokefunction -w {wallet} -a {address} "
+            f"-r {NEOFS_NEO_API_ENDPOINT} {NEOFS_CONTRACT} "
+            f"deposit {scripthash} int:{amount} bytes: -- {scripthash}")
+
+    logger.info(f"Executing command: {cmd}")
+    out = _run_sh_with_passwd(wallet_pass, cmd)
+    logger.info(f"Command completed with output: {out}")
+
+    m = re.match(r'^Sent invocation transaction (\w{64})$', out)
+    if m is None:
+        raise Exception("Can not get Tx.")
+
+    tx = m.group(1)
+
+    return tx
 
 @keyword('Transaction accepted in block')
 def transaction_accepted_in_block(tx_id):
@@ -169,11 +167,10 @@ def transaction_accepted_in_block(tx_id):
     """
 
     logger.info("Transaction id: %s" % tx_id)
-    
+
     TX_request = 'curl -X POST '+NEO_MAINNET_ENDPOINT+' --cacert ca/nspcc-ca.pem -H \'Content-Type: application/json\' -d \'{ "jsonrpc": "2.0", "id": 5, "method": "gettransactionheight", "params": [\"'+ tx_id +'\"] }\''
-    
+
     logger.info(f"Executing command: {TX_request}")
-    
 
     complProc = subprocess.run(TX_request, check=True, universal_newlines=True,
             stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
@@ -185,7 +182,6 @@ def transaction_accepted_in_block(tx_id):
 
     logger.info("Transaction has been found in the block %s." % response['result'] )
     return response['result']
-    
 
 @keyword('Get Transaction')
 def get_transaction(tx_id: str):
@@ -199,8 +195,6 @@ def get_transaction(tx_id: str):
     complProc = subprocess.run(TX_request, check=True, universal_newlines=True,
             stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=15, shell=True)
     logger.info(complProc.stdout)
-    
-
 
 @keyword('Get Balance')
 def get_balance(privkey: str):
@@ -232,19 +226,18 @@ def expected_balance(privkey: str, init_amount: float, deposit_size: float):
 
     return deposit_change
 
-
 def _get_balance_request(privkey: str):
     '''
     Internal method.
     '''
-    Cmd = f'neofs-cli --key {privkey} --rpc-endpoint s01.neofs.devenv:8080 accounting balance'
+    Cmd = f'neofs-cli --key {privkey} --rpc-endpoint {NEOFS_ENDPOINT} accounting balance'
     logger.info("Cmd: %s" % Cmd)
     complProc = subprocess.run(Cmd, check=True, universal_newlines=True,
                 stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=150, shell=True)
     output = complProc.stdout
     logger.info("Output: %s" % output)
-    
-    
+
+
     m = re.match(r'(-?[\d.\.?\d*]+)', output )
     if m is None:
         BuiltIn().fatal_error('Can not parse balance: "%s"' % output)
@@ -254,7 +247,6 @@ def _get_balance_request(privkey: str):
 
     return balance
 
-
 def _run_sh(args):
     complProc = subprocess.run(args, check=True, universal_newlines=True,
                 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
@@ -264,7 +256,6 @@ def _run_sh(args):
         return errors
     return output
 
-
 def _run_sh_with_passwd(passwd, cmd):
     p = pexpect.spawn(cmd)
     p.expect(".*")
diff --git a/robot/resources/lib/selectelcdn_smoke_vars.py b/robot/resources/lib/selectelcdn_smoke_vars.py
new file mode 100644
index 00000000..d9ad407b
--- /dev/null
+++ b/robot/resources/lib/selectelcdn_smoke_vars.py
@@ -0,0 +1,9 @@
+#!/usr/bin/python3
+
+NEOFS_ENDPOINT = "92.53.71.51:18080"
+NEOGO_CLI_PREFIX = "neo-go"
+NEO_MAINNET_ENDPOINT = "http://92.53.71.51:20332"
+
+# selectel main chain on lobachevsky-1
+NEOFS_NEO_API_ENDPOINT = "http://92.53.71.51:20332"
+HTTP_GATE = 'http://92.53.71.51:38080'
diff --git a/robot/testsuites/smoke/selectelcdn_smoke.robot b/robot/testsuites/smoke/selectelcdn_smoke.robot
new file mode 100644
index 00000000..56424862
--- /dev/null
+++ b/robot/testsuites/smoke/selectelcdn_smoke.robot
@@ -0,0 +1,33 @@
+# -*- coding: robot -*-
+
+*** Settings ***
+Variables   ../../variables/common.py
+Variables   ../../variables/selectelcdn_smoke.py
+
+
+Library     ${RESOURCES}/neofs.py
+Library     ${RESOURCES}/payment_neogo.py
+Library     ${RESOURCES}/gates.py
+
+
+*** Test cases ***
+
+NeoFS Storage Smoke
+    [Documentation]     Creates container and does PUT, GET and LIST on it via CLI and via HTTP Gate
+    [Timeout]   5 min
+
+
+    ${TX_DEPOSIT} =     NeoFS Deposit                       ${WALLET}               ${ADDR}     ${SCRIPT_HASH}      50      one
+                        Wait Until Keyword Succeeds         1 min          15 sec
+                        ...  Transaction accepted in block  ${TX_DEPOSIT}
+                        Get Transaction                     ${TX_DEPOSIT}
+
+    ${CID} =            Create container                    ${PRIV_KEY}     public
+                        Wait Until Keyword Succeeds         2 min          30 sec
+                        ...  Container Existing             ${PRIV_KEY}    ${CID}
+
+    ${FILE} =           Generate file of bytes              1024
+    ${S_OID} =          Put object to NeoFS                 ${PRIV_KEY}    ${FILE}       ${CID}            ${EMPTY}         ${EMPTY}
+                        Get object from NeoFS               ${PRIV_KEY}    ${CID}        ${S_OID}           ${EMPTY}       s_file_read
+
+    ${FILEPATH} =       Get via HTTP Gate                   ${CID}      ${S_OID}
diff --git a/robot/variables/common.py b/robot/variables/common.py
index 0baa11f7..ee30c5d1 100644
--- a/robot/variables/common.py
+++ b/robot/variables/common.py
@@ -9,11 +9,9 @@ CERT="%s/../../ca" % ROOT
 # in case when test is run from root in docker
 ABSOLUTE_FILE_PATH="/robot/testsuites/integration"
 
-JF_TOKEN = os.getenv('JF_TOKEN') 
-REG_USR = os.getenv('REG_USR') 
-REG_PWD = os.getenv('REG_PWD') 
-NEOFS_ENDPOINT = "s01.fs.localtest.nspcc.ru:8080"
-NEOFS_NEO_API_ENDPOINT = "https://fs.localtest.nspcc.ru/neo_rpc/"
+JF_TOKEN = os.getenv('JF_TOKEN')
+REG_USR = os.getenv('REG_USR')
+REG_PWD = os.getenv('REG_PWD')
 
 MORPH_BLOCK_TIMEOUT = "10sec"
-NEOFS_EPOCH_TIMEOUT = "30sec"
\ No newline at end of file
+NEOFS_EPOCH_TIMEOUT = "30sec"
diff --git a/robot/variables/selectelcdn_smoke.py b/robot/variables/selectelcdn_smoke.py
new file mode 100644
index 00000000..279142c6
--- /dev/null
+++ b/robot/variables/selectelcdn_smoke.py
@@ -0,0 +1,8 @@
+#!/usr/bin/python3
+
+# wallet that has assets in selectel mainnet
+WALLET = 'wallets/selectel_mainnet_wallet.json'
+# address from this wallet anf its representations
+ADDR = 'NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc'
+SCRIPT_HASH = 'eb88a496178256213f674eb302e44f9d85cf8aaa'
+PRIV_KEY = 'KxyjQ8eUa4FHt3Gvioyt1Wz29cTUrE4eTqX3yFSk1YFCsPL8uNsY'
diff --git a/wallets/selectel_mainnet_wallet.json b/wallets/selectel_mainnet_wallet.json
new file mode 100644
index 00000000..1612925d
--- /dev/null
+++ b/wallets/selectel_mainnet_wallet.json
@@ -0,0 +1,72 @@
+{
+  "version": "3.0",
+  "accounts": [
+    {
+      "address": "NbTiM6h8r99kpRtb428XcsUk1TzKed2gTc",
+      "key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
+      "label": "",
+      "contract": {
+        "script": "DCECs2Ir9AF73+MXxYrtX0x1PyBrfbiWBG+n13S7xL9/jcILQZVEDXg=",
+        "parameters": [
+          {
+            "name": "parameter0",
+            "type": "Signature"
+          }
+        ],
+        "deployed": false
+      },
+      "lock": false,
+      "isdefault": false
+    },
+    {
+      "address": "NUVPACMnKFhpuHjsRjhUvXz1XhqfGZYVtY",
+      "key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
+      "label": "",
+      "contract": {
+        "script": "EwwhAhA6f33QFlWFl/eWDSfFFqQ5T9loueZRVetLAT5AQEBuDCECp7xV/oaE4BGXaNEEujB5W9zIZhnoZK3SYVZyPtGFzWIMIQKzYiv0AXvf4xfFiu1fTHU/IGt9uJYEb6fXdLvEv3+NwgwhA9kMB99j5pDOd5EuEKtRrMlEtmhgI3tgjE+PgwnnHuaZFAtBE43vrw==",
+        "parameters": [
+          {
+            "name": "parameter0",
+            "type": "Signature"
+          },
+          {
+            "name": "parameter1",
+            "type": "Signature"
+          },
+          {
+            "name": "parameter2",
+            "type": "Signature"
+          }
+        ],
+        "deployed": false
+      },
+      "lock": false,
+      "isdefault": false
+    },
+    {
+      "address": "NVNvVRW5Q5naSx2k2iZm7xRgtRNGuZppAK",
+      "key": "6PYN7LvaWqBNw7Xb7a52LSbPnP91kyuzYi3HncGvQwQoYAY2W8DncTgpux",
+      "label": "",
+      "contract": {
+        "script": "EQwhArNiK/QBe9/jF8WK7V9MdT8ga324lgRvp9d0u8S/f43CEQtBE43vrw==",
+        "parameters": [
+          {
+            "name": "parameter0",
+            "type": "Signature"
+          }
+        ],
+        "deployed": false
+      },
+      "lock": false,
+      "isdefault": false
+    }
+  ],
+  "scrypt": {
+    "n": 16384,
+    "r": 8,
+    "p": 8
+  },
+  "extra": {
+    "Tokens": null
+  }
+}