diff --git a/.github/workflows/jdi-python.yml b/.github/workflows/jdi-python.yml
index fc0b5d2..0ba0509 100644
--- a/.github/workflows/jdi-python.yml
+++ b/.github/workflows/jdi-python.yml
@@ -12,33 +12,32 @@ on:
 jobs:
   build:
 
-    runs-on: windows-latest
+    runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: ['3.7', '3.8', '3.x']
+        python-version: ['3.11']
+        browser: [chrome, firefox]
 
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v4
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@v2
+      uses: actions/setup-python@v5
       with:
         python-version: ${{ matrix.python-version }}
     - name: Install dependencies
       run: |
         python -m pip install --upgrade pip
-        pip install -r requirements.txt
         pip install -r requirements-dev.txt
-    - name: Download Chrome driver
-      run: |
-        cd utils
-        python get_driver.py
-    # TODO: use virtual machine for tests run
     - name: Run unit tests
       run: |
         pytest -v --cov=. --cov-config=.coveragerc --cov-report=html -m unit
-      shell: cmd
+      shell: bash
+    - name: Run tests excluding 'unit' tests on ${{ matrix.browser }}
+      run: |
+        pytest -v -m "not unit" --browser=${{ matrix.browser }}
+      shell: bash
     - name: Save debug log file
-      uses: actions/upload-artifact@v2
+      uses: actions/upload-artifact@v4
       with:
         name: logs
         path: debug.log
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b67bd8f..8adabf7 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -3,7 +3,7 @@
 ## Getting started
 
 Before you begin:
--   Python 3.8 is used for this project.
+-   Python 3.11 is used for this project.
 -   For EPAM employees only: have you read the [Best Practices for Managing Secrets](https://elearn.epam.com/courses/course-v1:EPAM+5SCSS+0620/courseware/4b94c749c309409ea878fb7916be316b/ae4553f7cd524229b42f260b0ac692ed/1?activate_block_id=block-v1%3AEPAM%2B5SCSS%2B0620%2Btype%40vertical%2Bblock%40c04f1498c7d04ac4bf87b652741d90bb)?
 -   Check out the [existing issues](https://github.com/jdi-testing/jdi-python/issues).
 
@@ -19,10 +19,6 @@ When you're done making changes, open your PR and get it reviewed.
 
 In order to test the project, run pytest.
 
-Please don't forget to set up the environment variable `TEST_PASSWORD`. For example:
-
-For Windows `set TEST_PASSWORD=<password>`
-
 ```bash
 pytest <path to the project>/tests --no-header --no-summary -q
 ```
diff --git a/JDI/core/settings/jdi_settings.py b/JDI/core/settings/jdi_settings.py
index 9f6b391..92a7148 100644
--- a/JDI/core/settings/jdi_settings.py
+++ b/JDI/core/settings/jdi_settings.py
@@ -1,19 +1,19 @@
 import logging
 from pathlib import Path
 
-logger = logging.Logger(__name__)
-
+logger = logging.getLogger(__name__)
 
 class PropertyPath:
     def __init__(self, filename="jdi.properties"):
-        self._filename = Path(filename)
+        project_root = Path(__file__).parents[3]
+        self._filename = project_root / filename
 
     def get_property_file(self):
-        logger.info("Directory to search {dir_to_search}".format(dir_to_search=self._filename))
+        logger.info(f"Directory to search {self._filename.parent}")
         if self._filename.exists():
             return self._filename
         else:
-            raise FileNotFoundError("There is not property file with name '" + self._filename + "' in your project")
+            raise FileNotFoundError(f"There is no property file with name '{self._filename}' in your project")
 
 
 class JDISettings:
@@ -46,7 +46,13 @@ def get_driver_path():
     def get_setting_by_name(setting_name):
         if not JDISettings._jdi_settings:
             JDISettings._read_jdi_settings()
-        return JDISettings._jdi_settings.get(setting_name, None)
+        value = JDISettings._jdi_settings.get(setting_name, None)
+        if value.lower() in ("true", "yes", "1"):
+            return True
+        elif value.lower() in ("false", "no", "0"):
+            return False
+        else:
+            return value
 
     @staticmethod
     def get_current_timeout_sec():
diff --git a/JDI/web/selenium/driver/selenium_driver_factory.py b/JDI/web/selenium/driver/selenium_driver_factory.py
index b6c89d7..9ce1190 100644
--- a/JDI/web/selenium/driver/selenium_driver_factory.py
+++ b/JDI/web/selenium/driver/selenium_driver_factory.py
@@ -1,14 +1,16 @@
-import os
-
 from selenium.webdriver.chrome.options import Options as ChromeOptions
+from selenium.webdriver.chrome.service import Service
 from selenium.webdriver.chrome.webdriver import WebDriver as ChromeDriver
 from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
 from selenium.webdriver.firefox.options import Options as FirefoxOptions
+from selenium.webdriver.firefox.service import Service as FirefoxService
+from selenium.webdriver.firefox.webdriver import WebDriver as FirefoxDriver
 from selenium.webdriver.remote.webdriver import WebDriver as RemoteDriver
+from webdriver_manager.chrome import ChromeDriverManager
+from webdriver_manager.firefox import GeckoDriverManager
 
 from JDI.core.settings.jdi_settings import JDISettings
 from JDI.web.selenium.driver.driver_types import DriverTypes
-from JDI.web.selenium.driver.web_driver_provider import WebDriverProvider
 
 
 class SeleniumDriverFactory:
@@ -17,7 +19,6 @@ def __init__(self):
         self.options = None
         self.current_driver = None
         self.browser_size = None
-        self.drivers_path = JDISettings.get_driver_path()
         self.capabilities = {}
 
     def register_driver(self, driver_name, options, capabilities, executor):
@@ -28,64 +29,60 @@ def register_driver(self, driver_name, options, capabilities, executor):
         else:
             if driver_name == DriverTypes.chrome.name:
                 self.current_driver = self.register_chrome_driver()
-            if driver_name == DriverTypes.firefox.name:
+            elif driver_name == DriverTypes.firefox.name:
                 self.current_driver = self.register_firefox_driver()
         return driver_name
 
     def set_driver_options_and_capabilities(self, driver_name, options, capabilities, executor):
         if driver_name == DriverTypes.chrome.name:
             self.options = ChromeOptions()
-            # TODO: move hardcoded arguments to params
             self.options.add_argument("start-maximized")
             self.options.add_argument("disable-gpu")
-            self.add_options(options) if options else True
-            if not capabilities and executor is not None:
+            if options:
+                self.add_options(options)
+            if not capabilities and executor is None:
                 self.capabilities = DesiredCapabilities.CHROME
-        if driver_name == DriverTypes.firefox.name:
+        elif driver_name == DriverTypes.firefox.name:
             self.options = FirefoxOptions()
-            self.add_options(options) if options else True
-            if not capabilities and executor is not None:
+            self.options.add_argument("-start-maximized")
+            if options:
+                self.add_options(options)
+            if not capabilities and executor is None:
                 self.capabilities = DesiredCapabilities.FIREFOX
         if capabilities:
             self.capabilities = capabilities
 
     def add_options(self, options):
-        for arg in options:
+        for arg in options.arguments:
             self.options.add_argument(arg)
 
     def register_chrome_driver(self):
-        chrome_driver = WebDriverProvider.get_chrome_driver_path()
-        os.environ["webdriver.chrome.driver"] = chrome_driver
-        return self.__web_driver_settings(ChromeDriver(executable_path=chrome_driver,
-                                                       options=self.options,
-                                                       desired_capabilities=self.capabilities))
+        service = Service(ChromeDriverManager().install())
+        return self.__web_driver_settings(ChromeDriver(service=service, options=self.options))
 
     def register_firefox_driver(self):
-        raise NotImplementedError
+        service = FirefoxService(GeckoDriverManager().install())
+        return self.__web_driver_settings(FirefoxDriver(service=service, options=self.options))
 
     def register_remote_driver(self, executor):
-        chrome_driver = WebDriverProvider.get_chrome_driver_path()
-        os.environ["webdriver.chrome.driver"] = chrome_driver
         driver = self.__web_driver_settings(RemoteDriver(command_executor=executor,
-                                                         options=self.options,
                                                          desired_capabilities=self.capabilities,
+                                                         options=self.options,
                                                          keep_alive=True))
         return driver
 
     def __web_driver_settings(self, driver):
-        if self.browser_size is None:
-            driver.maximize_window()
+        if self.browser_size:
+            driver.set_window_size(*self.browser_size)
         else:
-            driver.set_window_size(self.browser_size)
+            driver.maximize_window()
         driver.implicitly_wait(JDISettings.get_current_timeout_sec())
         return driver
 
     def get_driver(self, options=None, capabilities=None, executor=None):
-        if self.current_driver is not None:
-            return self.current_driver
-        else:
+        if not self.current_driver:
             self.register_driver(driver_name=DriverTypes.chrome.name,
                                  options=options,
                                  capabilities=capabilities,
                                  executor=executor)
-            return self.current_driver
+        return self.current_driver
diff --git a/JDI/web/selenium/driver/web_driver_provider.py b/JDI/web/selenium/driver/web_driver_provider.py
index e88acc5..af7a374 100644
--- a/JDI/web/selenium/driver/web_driver_provider.py
+++ b/JDI/web/selenium/driver/web_driver_provider.py
@@ -1,11 +1,9 @@
-import os
+from webdriver_manager.chrome import ChromeDriverManager
 import sys
 
-from JDI.core.settings.jdi_settings import JDISettings
-
-
 class WebDriverProvider:
     @staticmethod
     def get_chrome_driver_path():
-        chrome = "/chromedriver.exe" if sys.platform.startswith("win") else "chromedriver"
-        return os.path.join(JDISettings.get_driver_path(), chrome)
+        chrome = ChromeDriverManager().install()
+        return chrome
+
diff --git a/JDI/web/selenium/elements/common/text_field.py b/JDI/web/selenium/elements/common/text_field.py
index f6f3440..299d519 100644
--- a/JDI/web/selenium/elements/common/text_field.py
+++ b/JDI/web/selenium/elements/common/text_field.py
@@ -11,7 +11,7 @@ def __init__(self, by_locator=None, by_label=None, web_element=None):
     def input(self, text):
         self.input_action(text)
 
-    def input_action(self,text):
+    def input_action(self, text):
         self.get_web_element().send_keys(text)
 
     @scenario(action_name="Send keys to the element")
diff --git a/JDI/web/selenium/elements/composite/web_page.py b/JDI/web/selenium/elements/composite/web_page.py
index c9e0040..a58c1a0 100644
--- a/JDI/web/selenium/elements/composite/web_page.py
+++ b/JDI/web/selenium/elements/composite/web_page.py
@@ -70,27 +70,27 @@ def open(self):
         self.get_driver().get(self.url)
 
     def verify_opened(self):
-        result = False
+        url_check_passed = False
         if self.check_url_type == CheckPageTypes.EQUAL:
-            result = self.check_url()
+            url_check_passed = self.check_url()
         elif self.check_url_type == CheckPageTypes.MATCH:
-            result = self.match_url()
+            url_check_passed = self.match_url()
         elif self.check_url_type == CheckPageTypes.CONTAINS:
-            result = self.contains_url()
-        if not result:
+            url_check_passed = self.contains_url()
+
+        if not url_check_passed:
             return False
 
         if self.title is None:
             return True
 
-        if self.check_title_type == CheckPageTypes.EQUAL:
-            return self.check_title()
-        if self.check_title_type == CheckPageTypes.MATCH:
-            return self.match_title()
-        if self.check_title_type == CheckPageTypes.CONTAINS:
-            return self.contains_title()
-
-        return False
+        title_check_methods = {
+            CheckPageTypes.EQUAL: self.check_title,
+            CheckPageTypes.MATCH: self.match_title,
+            CheckPageTypes.CONTAINS: self.contains_title
+        }
+        title_check_method = title_check_methods.get(self.check_title_type, lambda: False)
+        return title_check_method()
 
     def should_be_opened(self):
         try:
diff --git a/JDI/web/selenium/settings/web_settings.py b/JDI/web/selenium/settings/web_settings.py
index a12b86b..e5b72fa 100644
--- a/JDI/web/selenium/settings/web_settings.py
+++ b/JDI/web/selenium/settings/web_settings.py
@@ -1,9 +1,13 @@
+import sys
+
 from selenium.webdriver.remote.command import Command
 
 from JDI.core.logger.jdi_logger import JDILogger
 from JDI.core.settings.jdi_settings import JDISettings
 from JDI.web.selenium.driver.selenium_driver_factory import \
     SeleniumDriverFactory
+from selenium.webdriver.chrome.options import Options as ChromeOptions
+from selenium.webdriver.firefox.options import Options as FirefoxOptions
 
 
 class WebSettings(JDISettings):
@@ -21,7 +25,19 @@ def set_driver_factory(driver_factory):
 
     @staticmethod
     def use_driver(options=None, capabilities=None, executor=None):
-        driver_name = JDISettings.get_setting_by_name("driver")
+        if options is None:
+            options = ChromeOptions() if JDISettings.get_setting_by_name(
+                "driver") == "chrome" else FirefoxOptions()
+
+        headless = JDISettings.get_setting_by_name("headless")
+
+        if headless:
+            options.add_argument("--headless")
+
+        driver_name = next(
+            (arg.split("=")[1] for arg in sys.argv if arg.startswith("--browser")),
+            JDISettings.get_setting_by_name("driver"))
+
         JDISettings._driver_factory = SeleniumDriverFactory()
         WebSettings.set_driver_factory(JDISettings._driver_factory)
         return JDISettings._driver_factory.register_driver(driver_name, options, capabilities, executor)
diff --git a/README.md b/README.md
index af3f0f7..cbbd510 100644
--- a/README.md
+++ b/README.md
@@ -4,3 +4,18 @@
 
 # JDI 2.0
 Powerful Framework for UI Automation Testing on Python
+
+## Getting started
+Before you begin:
+- Python 3.11 is used for this project. To install Python on MacOs you can use [Homebrew](https://brew.sh/), on Windows you can use [Chocolatey](https://chocolatey.org/).
+- run git clone https://github.com/jdi-testing/jdi-python.git or fork the repository and clone it afterwards.
+- create a virtual environment for the project. You can use [virtualenv](https://virtualenv.pypa.io/en/latest/) or [venv](https://docs.python.org/3/library/venv.html) for that.
+- set up Python interpreter to use Python 3.11 in your IDE.
+- run `pip install -r requirements.txt` to install all required dependencies.
+
+## You can simply run tests to see how it works
+1. inside your IDE
+2. using pytest
+ - activate your virtual environment by running `source venv/bin/activate` on MacOs or `venv\Scripts\activate` on Windows
+ - run `pytest` in the terminal (eg. `pytest ./tests/jdi_uitests_webtests/test/common/`       - to run all tests in the specified directory)
+ - be sure that you are in a project root directory when running the command
\ No newline at end of file
diff --git a/jdi.properties b/jdi.properties
index 7bd6377..b3b6c5e 100644
--- a/jdi.properties
+++ b/jdi.properties
@@ -1,7 +1,10 @@
 driver=chrome
 ; domain=https://www.epam.com/
-domain=https://jdi-framework.github.io/tests
+domain=https://jdi-testing.github.io/jdi-light
 timeout_wait_element=5
 timeout_wait_pageLoad=5
 drivers_folder=.\
-driver_getLatest=true
\ No newline at end of file
+driver_getLatest=true
+headless=True
+user=Roman
+password=Jdi1234
\ No newline at end of file
diff --git a/pytest.ini b/pytest.ini
index 032fadd..29aeb62 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -1,4 +1,6 @@
 [pytest]
 markers =
     unit: marks unit tests
-    web: marks JDI tests
\ No newline at end of file
+    web: marks JDI tests
+log_cli = true
+log_cli_level = INFO
\ No newline at end of file
diff --git a/requirements-dev-win.txt b/requirements-dev-win.txt
new file mode 100644
index 0000000..279c44b
--- /dev/null
+++ b/requirements-dev-win.txt
@@ -0,0 +1,2 @@
+-r requirements-dev.txt
+pywin32==306
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 8a9653f..bb81d8f 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,31 +1,28 @@
+-r requirements.txt
 appdirs==1.4.4
-astroid==2.4.2
-black==20.8b1
-certifi==2020.12.5
-chardet==4.0.0
-click==7.1.2
-colorama==0.4.4
-comtypes==1.1.8
-flake8==3.8.4
-idna==2.10
-isort==5.7.0
-lazy-object-proxy==1.4.3
-mccabe==0.6.1
-mypy==0.800
-mypy-extensions==0.4.3
-pathspec==0.8.1
-pycodestyle==2.6.0
-pyflakes==2.2.0
-pylint==2.6.0
-pyperclip==1.8.1
-pywin32==302
-regex==2020.11.13
-requests==2.25.1
-selenium==3.141.0
-six==1.15.0
+astroid==3.1.0
+black==24.2.0
+certifi==2024.2.2
+chardet==5.2.0
+click==8.1.7
+colorama==0.4.6
+comtypes==1.3.1
+flake8==7.0.0
+idna==3.6
+isort==5.13.2
+lazy-object-proxy==1.10.0
+mccabe==0.7.0
+mypy==1.9.0
+mypy-extensions==1.0.0
+pathspec==0.12.1
+pycodestyle==2.11.1
+pyflakes==3.2.0
+pylint==3.1.0
+pyperclip==1.8.2
+regex==2023.12.25
+six==1.16.0
 toml==0.10.2
-typed-ast==1.4.3
-typing-extensions==3.7.4.3
-wrapt==1.12.1
-pytest
+typed-ast==1.5.5
+typing-extensions==4.10.0
+wrapt==1.16.0
 pytest-cov
diff --git a/requirements.txt b/requirements.txt
index 4579c61..5d76bce 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,3 +1,4 @@
-pywin32==302
-selenium==3.141.0
-requests==2.25.1
+selenium==4.18.1
+requests==2.31.0
+pytest==8.1.1
+webdriver_manager==4.0.1
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 0000000..115dfd8
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,6 @@
+
+# conftest.py
+def pytest_addoption(parser):
+    parser.addoption("--browser", action="store", default="chrome",
+                     help="Type of browser: chrome or firefox")
+
diff --git a/tests/core/test_jdi_settings.py b/tests/core/test_jdi_settings.py
index b01ada8..113aca7 100644
--- a/tests/core/test_jdi_settings.py
+++ b/tests/core/test_jdi_settings.py
@@ -1,3 +1,4 @@
+import os
 from pathlib import Path
 
 import pytest
@@ -14,5 +15,9 @@ def test_creation_with_param(self):
         p = PropertyPath("test.txt")
         assert p._filename.name == "test.txt"
 
+    @pytest.mark.skipif(os.getcwd() == os.path.dirname(__file__),
+                        reason="Tests require current directory to be the same as the test directory")
     def test_get_property_file(self):
-        assert PropertyPath().get_property_file() == Path("jdi.properties")
+        if PropertyPath().get_property_file() != Path("jdi.properties").absolute():
+            raise AssertionError(
+                "Property file path does not match expected absolute path of 'jdi.properties'.")
diff --git a/tests/jdi_uitest_web_examples/main/site/epam/custom_elements/tree_dropdown.py b/tests/jdi_uitest_web_examples/main/site/epam/custom_elements/tree_dropdown.py
index 65dca52..ee28275 100644
--- a/tests/jdi_uitest_web_examples/main/site/epam/custom_elements/tree_dropdown.py
+++ b/tests/jdi_uitest_web_examples/main/site/epam/custom_elements/tree_dropdown.py
@@ -2,6 +2,7 @@
 
 from JDI.web.selenium.elements.complex.base_selector import BaseSelector
 from JDI.web.selenium.elements.complex.dropdown import Dropdown
+from selenium.webdriver.common.by import By as Strategy
 
 
 class TreeDropdown(Dropdown):
@@ -27,5 +28,5 @@ def select_action(self, names):
             el.set_parent(self)
 
             web_el = el.get_element(split[i])
-            if "dropdown-invisible-group" not in web_el.find_element_by_xpath("..").get_attribute("class"):
+            if "dropdown-invisible-group" not in web_el.find_element(Strategy.XPATH, "..").get_attribute("class"):
                 web_el.click()
diff --git a/tests/jdi_uitests_webtests/main/entities/contact.py b/tests/jdi_uitests_webtests/main/entities/contact.py
index cd524d6..a69f03c 100644
--- a/tests/jdi_uitests_webtests/main/entities/contact.py
+++ b/tests/jdi_uitests_webtests/main/entities/contact.py
@@ -5,6 +5,6 @@ def __init__(self, name, last_name, description):
         self.description = description
 
     def __str__(self):
-        return "Summary: 3\nName: {0}\nLast Name: {1}\nDescription: {2}".format(
-            self.first_name, self.last_name, self.description
+        return "Summary: 3\nLast Name: {0}\nDescription: {1}\nVegetables:".format(
+            self.last_name, self.description
         )
diff --git a/tests/jdi_uitests_webtests/main/entities/user.py b/tests/jdi_uitests_webtests/main/entities/user.py
index 39ba2db..05bf062 100644
--- a/tests/jdi_uitests_webtests/main/entities/user.py
+++ b/tests/jdi_uitests_webtests/main/entities/user.py
@@ -1,4 +1,4 @@
-import os
+from JDI.core.settings.jdi_settings import JDISettings
 
 
 class User:
@@ -7,8 +7,5 @@ def default():
         return User()
 
     def __init__(self):
-        self.login = "epam"
-        self.password = os.getenv("TEST_PASSWORD")
-        self.name = "Name"
-        self.last_name = "Last Name"
-        self.description = "Description"
+        self.login = JDISettings.get_setting_by_name("user")
+        self.password = JDISettings.get_setting_by_name("password")
diff --git a/tests/jdi_uitests_webtests/main/enums/entities.py b/tests/jdi_uitests_webtests/main/enums/entities.py
index dc12390..729c193 100644
--- a/tests/jdi_uitests_webtests/main/enums/entities.py
+++ b/tests/jdi_uitests_webtests/main/enums/entities.py
@@ -9,7 +9,7 @@ class Nature(Enum):
 
 
 class Metals(Enum):
-    COL = "Col"
+    METALS = "Metals"
     GOLD = "Gold"
     SILVER = "Silver"
     BRONZE = "Bronze"
diff --git a/tests/jdi_uitests_webtests/main/enums/preconditions.py b/tests/jdi_uitests_webtests/main/enums/preconditions.py
index 55ad12d..06c9b97 100644
--- a/tests/jdi_uitests_webtests/main/enums/preconditions.py
+++ b/tests/jdi_uitests_webtests/main/enums/preconditions.py
@@ -6,13 +6,14 @@
 from JDI.web.selenium.preconditions.web_preconditions import WebPreconditions
 
 
-class Preconditions(Enum):
-    HOME_PAGE = ("/index.htm",)
-    CONTACT_PAGE = ("/page1.htm",)
-    METALS_AND_COLORS_PAGE = ("/page2.htm",)
-    SUPPORT_PAGE = ("/page3.htm",)
-    DATES_PAGE = "/page4.htm"
-    SIMPLE_TABLE_PAGE = "/page6.htm"
+class Preconditions(str, Enum):
+    HOME_PAGE = ("/index.html",)
+    CONTACT_PAGE = ("/contacts.html",)
+    METALS_AND_COLORS_PAGE = ("/metals-colors.html",)
+    SUPPORT_PAGE = ("/support.html",)
+    DATES_PAGE = "/dates.html"
+    SIMPLE_TABLE_PAGE = "/simple-table.html"
+    SEARCH_PAGE = "/search.html"
 
     def is_in_state(self):
         str_value = self.value[0] if isinstance(self.value, tuple) else self.value
diff --git a/tests/jdi_uitests_webtests/main/page_objects/epam_jdi_site.py b/tests/jdi_uitests_webtests/main/page_objects/epam_jdi_site.py
index 5634e21..425c418 100644
--- a/tests/jdi_uitests_webtests/main/page_objects/epam_jdi_site.py
+++ b/tests/jdi_uitests_webtests/main/page_objects/epam_jdi_site.py
@@ -1,6 +1,7 @@
 from JDI.web.selenium.elements.api_interact.find_element_by import By
 from JDI.web.selenium.elements.complex.text_list import TextList
 from JDI.web.selenium.elements.composite.web_site import WebSite
+from tests.jdi_uitests_webtests.main.enums.preconditions import Preconditions
 from tests.jdi_uitests_webtests.main.page_objects.pages import (
     ContactFormPage,
     DatesPage,
@@ -9,6 +10,7 @@
     MetalColorPage,
     SupportPage,
 )
+from tests.jdi_uitests_webtests.main.page_objects.pages.search_page import SearchPage
 from tests.jdi_uitests_webtests.main.page_objects.pages.simple_table_page import SimpleTablePage
 from tests.jdi_uitests_webtests.main.page_objects.sections.footer import Footer
 from tests.jdi_uitests_webtests.main.page_objects.sections.header import Header
@@ -16,12 +18,17 @@
 
 class EpamJDISite(WebSite):
     # pages
-    home_page = HomePage(url="/index.htm", title="Index Page")
-    metals_colors_page = MetalColorPage(url="/page2.htm", title="Metal and Colors")
-    contact_form_page = ContactFormPage(url="/page1.htm", title="Contact Form")
-    support_page = SupportPage(url="/page3.htm", title="Support")
-    dates_page = DatesPage(url="/page4.htm", title="Simple Table")
-    simple_table_page = SimpleTablePage(url="/page6.htm", title="Simple Table")
+    home_page = HomePage(url=Preconditions.HOME_PAGE.value, title="Home Page")
+    metals_colors_page = MetalColorPage(url=Preconditions.METALS_AND_COLORS_PAGE.value,
+                                        title="Metal and Colors")
+    contact_form_page = ContactFormPage(url=Preconditions.CONTACT_PAGE.value,
+                                        title="Contact Form")
+    support_page = SupportPage(url=Preconditions.SUPPORT_PAGE.value, title="Support")
+    dates_page = DatesPage(url=Preconditions.DATES_PAGE.value, title="Dates")
+    simple_table_page = SimpleTablePage(url=Preconditions.SIMPLE_TABLE_PAGE.value,
+                                        title="Simple Table")
+    search_page = SearchPage(url=Preconditions.SEARCH_PAGE.value,
+                                        title="Simple Table")
 
     # elements
     actions_log = TextList(By.css(".logs li"))
diff --git a/tests/jdi_uitests_webtests/main/page_objects/pages/contact_form_page.py b/tests/jdi_uitests_webtests/main/page_objects/pages/contact_form_page.py
index 8cb47b5..f2749a4 100644
--- a/tests/jdi_uitests_webtests/main/page_objects/pages/contact_form_page.py
+++ b/tests/jdi_uitests_webtests/main/page_objects/pages/contact_form_page.py
@@ -2,7 +2,6 @@
 from JDI.web.selenium.elements.common.text_area import TextArea
 from JDI.web.selenium.elements.common.text_field import TextField
 from JDI.web.selenium.elements.composite.web_page import WebPage
-from tests.jdi_uitests_webtests.main.entities.contact import Contact
 from tests.jdi_uitests_webtests.main.page_objects.sections.contact_form import ContactForm, ContactFormTwoButtons
 
 
@@ -10,9 +9,9 @@ class ContactFormPage(WebPage):
     def __init__(self, url, title):
         super(ContactFormPage, self).__init__(url=url, title=title)
 
-    description = TextArea(By.id("Description"))
+    description = TextArea(By.id("description"))
 
-    name_text_field = TextField(By.id("Name"))
+    name_text_field = TextField(By.id("first-name"))
 
     contact_form = ContactForm(By.css("main form"))
 
diff --git a/tests/jdi_uitests_webtests/main/page_objects/pages/login.py b/tests/jdi_uitests_webtests/main/page_objects/pages/login.py
index 73e99ff..8a82c4c 100644
--- a/tests/jdi_uitests_webtests/main/page_objects/pages/login.py
+++ b/tests/jdi_uitests_webtests/main/page_objects/pages/login.py
@@ -7,9 +7,9 @@
 
 class Login(Form):
 
-    login = TextField(By.id("Login"))
+    login = TextField(By.id("name"))
 
-    password = TextField(By.id("Password"))
+    password = TextField(By.id("password"))
 
     button = Button(By.css(".btn-login"))
 
diff --git a/tests/jdi_uitests_webtests/main/page_objects/pages/metals_color_page.py b/tests/jdi_uitests_webtests/main/page_objects/pages/metals_color_page.py
index 15b4f26..5951728 100644
--- a/tests/jdi_uitests_webtests/main/page_objects/pages/metals_color_page.py
+++ b/tests/jdi_uitests_webtests/main/page_objects/pages/metals_color_page.py
@@ -9,6 +9,7 @@
 from JDI.web.selenium.elements.complex.dropdown import Dropdown
 from JDI.web.selenium.elements.composite.web_page import WebPage
 from tests.jdi_uitests_webtests.main.page_objects.sections.summary import Summary
+from selenium.webdriver.common.by import By as Strategy
 
 
 class CheckBoxMetalColor(CheckBox):
@@ -16,7 +17,7 @@ def is_check_action(self):
         driver = JDISettings.get_driver_factory().get_driver()
         return (
             False
-            if driver.find_element_by_xpath("//*[@id='elements-checklist']//*[*[text()='Water']]/input").get_attribute(
+            if driver.find_element(Strategy.XPATH, "//*[@id='elements-checklist']//*[*[text()='Water']]/input").get_attribute(
                 "checked"
             )
             is None
@@ -26,7 +27,7 @@ def is_check_action(self):
 
 class CheckListMetalColor(CheckList):
     def is_element_selected(self, el):
-        return el.find_element_by_xpath("../input").is_selected()
+        return el.find_element(Strategy.XPATH, "../input").is_selected()
 
 
 class ComboBoxMetalColor(ComboBox):
diff --git a/tests/jdi_uitests_webtests/main/page_objects/pages/search_page.py b/tests/jdi_uitests_webtests/main/page_objects/pages/search_page.py
new file mode 100644
index 0000000..e36bb92
--- /dev/null
+++ b/tests/jdi_uitests_webtests/main/page_objects/pages/search_page.py
@@ -0,0 +1,8 @@
+from JDI.web.selenium.elements.composite.web_page import WebPage
+
+
+class SearchPage(WebPage):
+    def __init__(self, url, title):
+        super(SearchPage, self).__init__(url=url, title=title)
+
+    # TODO: Implement SearchPage
diff --git a/tests/jdi_uitests_webtests/main/page_objects/sections/contact_form.py b/tests/jdi_uitests_webtests/main/page_objects/sections/contact_form.py
index 7652f8b..33c15ea 100644
--- a/tests/jdi_uitests_webtests/main/page_objects/sections/contact_form.py
+++ b/tests/jdi_uitests_webtests/main/page_objects/sections/contact_form.py
@@ -9,9 +9,9 @@ class ContactForm(Form):
     def __init__(self, by_locator=None):
         super(ContactForm, self).__init__(by_locator)
 
-    first_name = TextField(By.id("Name"))
-    last_name = TextField(By.id("LastName"))
-    description = TextArea(By.id("Description"))
+    first_name = TextField(By.id("first-name"))
+    last_name = TextField(By.id("last-name"))
+    description = TextArea(By.id("description"))
 
     submit = Button(By.xpath("//*[text()='Submit']"))
 
@@ -23,9 +23,9 @@ class ContactFormTwoButtons(Form):
     def __init__(self, by_locator=None):
         super(ContactFormTwoButtons, self).__init__(by_locator)
 
-    first_name = TextField(By.id("Name"))
-    last_name = TextField(By.id("LastName"))
-    description = TextArea(By.id("Description"))
+    first_name = TextField(By.id("first-name"))
+    last_name = TextField(By.id("last-name"))
+    description = TextArea(By.id("description"))
 
     submit = Button(By.xpath("//*[text()='Submit']"))
     calculate = Button(By.xpath("//*[text()='Calculate']"))
diff --git a/tests/jdi_uitests_webtests/main/page_objects/sections/summary.py b/tests/jdi_uitests_webtests/main/page_objects/sections/summary.py
index ba3e311..fbabac3 100644
--- a/tests/jdi_uitests_webtests/main/page_objects/sections/summary.py
+++ b/tests/jdi_uitests_webtests/main/page_objects/sections/summary.py
@@ -5,6 +5,7 @@
 from JDI.web.selenium.elements.complex.radio_buttons import RadioButtons
 from JDI.web.selenium.elements.complex.selector import Selector
 from JDI.web.selenium.elements.composite.section import Section
+from selenium.webdriver.common.by import By as Strategy
 
 ERROR_MSG = "No elements selected. Override getSelectedAction or place locator to <select> tag"
 
@@ -18,11 +19,11 @@ def get_selected(self):
         element = list(filter(lambda x: x.is_selected(), self.get_input_web_elements()))
         if len(element) == 0:
             raise ValueError(ERROR_MSG)
-        return element[0].find_element_by_xpath("..").text
+        return element[0].find_element(Strategy.XPATH, "..").text
 
     def is_selected_action(self, element) -> bool:
         actual_text = (
-            list(filter(lambda x: x.is_selected(), self.get_input_web_elements()))[0].find_element_by_xpath("..").text
+            list(filter(lambda x: x.is_selected(), self.get_input_web_elements()))[0].find_element(Strategy.XPATH, "..").text
         )
         if isinstance(element, str):
             return actual_text == element
@@ -40,14 +41,14 @@ def get_selected_index(self):
 class RadioButtonsSummary(SelectElements, RadioButtons):
     def get_input_web_elements(self):
         return list(
-            map(lambda el: el.find_element_by_tag_name("input"), super(RadioButtonsSummary, self).get_web_elements())
+            map(lambda el: el.find_element(Strategy.TAG_NAME, "input"), super(RadioButtonsSummary, self).get_web_elements())
         )
 
 
 class SelectorSummary(SelectElements, Selector):
     def get_input_web_elements(self):
         return list(
-            map(lambda el: el.find_element_by_tag_name("input"), super(SelectorSummary, self).get_web_elements())
+            map(lambda el: el.find_element(Strategy.TAG_NAME, "input"), super(SelectorSummary, self).get_web_elements())
         )
 
 
diff --git a/tests/jdi_uitests_webtests/test/common/image_test.py b/tests/jdi_uitests_webtests/test/common/image_test.py
index e3c5d10..34828be 100644
--- a/tests/jdi_uitests_webtests/test/common/image_test.py
+++ b/tests/jdi_uitests_webtests/test/common/image_test.py
@@ -9,7 +9,7 @@
 @pytest.mark.web
 class ImageTests(InitTests):
     ALT = "ALT"
-    SRC = "https://jdi-framework.github.io/tests/images/Logo_Epam_Color.svg"
+    SRC = "https://jdi-testing.github.io/jdi-light/images/Logo_Epam_Color.svg"
 
     clickable_item = EpamJDISite.home_page.logo_image
 
diff --git a/tests/jdi_uitests_webtests/test/complex/combo_box_test.py b/tests/jdi_uitests_webtests/test/complex/combo_box_test.py
index 19a7d7e..63c354f 100644
--- a/tests/jdi_uitests_webtests/test/complex/combo_box_test.py
+++ b/tests/jdi_uitests_webtests/test/complex/combo_box_test.py
@@ -11,8 +11,8 @@
 @pytest.mark.web
 class ComboBoxTests(InitTests):
 
-    add_options = ["Col", "Gold", "Silver", "Bronze", "Selen"]
-    add_options_string = "Col, Gold, Silver, Bronze, Selen"
+    add_options = ["Metals", "Gold", "Silver", "Bronze", "Selen"]
+    add_options_string = "Metals, Gold, Silver, Bronze, Selen"
 
     combo_box = EpamJDISite.metals_colors_page.combo_box
 
@@ -59,10 +59,10 @@ def test_get_selected_index(self):
         )
 
     def test_is_selected(self):
-        Assert.assert_equal(self.combo_box.is_selected("Col"), True)
+        Assert.assert_equal(self.combo_box.is_selected("Metals"), True)
 
     def test_is_selected_enum(self):
-        Assert.assert_equal(self.combo_box.is_selected(Metals.COL), True)
+        Assert.assert_equal(self.combo_box.is_selected(Metals.METALS), True)
 
     def test_get_value(self):
-        Assert.assert_equal(self.combo_box.get_value(), "Col")
+        Assert.assert_equal(self.combo_box.get_value(), "Metals")
diff --git a/tests/jdi_uitests_webtests/test/composite/form_test.py b/tests/jdi_uitests_webtests/test/composite/form_test.py
index 5cbe411..42467c0 100644
--- a/tests/jdi_uitests_webtests/test/composite/form_test.py
+++ b/tests/jdi_uitests_webtests/test/composite/form_test.py
@@ -5,7 +5,6 @@
 from tests.jdi_uitests_webtests.main.enums.entities import Buttons
 from tests.jdi_uitests_webtests.main.enums.preconditions import Preconditions
 from tests.jdi_uitests_webtests.main.page_objects.epam_jdi_site import EpamJDISite
-from tests.jdi_uitests_webtests.main.utils.common_action_data import CommonActionsData
 from tests.jdi_uitests_webtests.test.init_tests import InitTests
 
 
@@ -38,7 +37,7 @@ def test_submit_string(self):
         self.form.submit_form(self.contact.description)
         Assert.assert_equal(
             EpamJDISite.contact_form_page.result.get_text(),
-            "Summary: 3\nDescription: {0}".format(self.contact.description),
+            "Summary: 3\nDescription: {0}\nVegetables:".format(self.contact.description),
         )
 
     def test_verify(self):
diff --git a/tests/jdi_uitests_webtests/test/composite/page_test.py b/tests/jdi_uitests_webtests/test/composite/page_test.py
index ac03829..5dfbd31 100644
--- a/tests/jdi_uitests_webtests/test/composite/page_test.py
+++ b/tests/jdi_uitests_webtests/test/composite/page_test.py
@@ -27,7 +27,7 @@ def setUp(self):
 
     def test_refresh(self):
         EpamJDISite.contact_form_page.contact_form.submit.click()
-        Assert.assert_equal(EpamJDISite.contact_form_page.result.get_text(), "Summary: 3")
+        Assert.assert_equal(EpamJDISite.contact_form_page.result.get_text(), "Summary: 3\nVegetables:")
         EpamJDISite.contact_form_page.refresh()
         Assert.assert_equal(EpamJDISite.contact_form_page.result.get_text(), "")
         EpamJDISite.contact_form_page.check_opened()
diff --git a/tests/jdi_uitests_webtests/test/composite/pagination_test.py b/tests/jdi_uitests_webtests/test/composite/pagination_test.py
index 3c09d96..e64fb37 100644
--- a/tests/jdi_uitests_webtests/test/composite/pagination_test.py
+++ b/tests/jdi_uitests_webtests/test/composite/pagination_test.py
@@ -7,8 +7,8 @@
 from tests.jdi_uitests_webtests.test.init_tests import InitTests
 
 
-def check_page_opened(num):
-    Assert.assert_true(JDISettings.get_driver_factory().get_driver().current_url.endswith("/page{0}.htm".format(num)))
+def check_page_opened(verifier):
+    Assert.assert_true(JDISettings.get_driver_factory().get_driver().current_url.endswith(verifier))
 
 
 @pytest.mark.web
@@ -20,17 +20,19 @@ def setUp(self):
         Preconditions.SIMPLE_TABLE_PAGE.is_in_state()
 
     def test_next(self):
+        self.pagination.first()
         self.pagination.next()
-        check_page_opened(7)
+        check_page_opened("dates.html")
 
     def test_previous(self):
+        self.pagination.last()
         self.pagination.previous()
-        check_page_opened(5)
+        check_page_opened("table-pages.html")
 
     def test_first(self):
         self.pagination.first()
-        check_page_opened(1)
+        check_page_opened("support.html")
 
     def test_last(self):
         self.pagination.last()
-        check_page_opened(2)
+        check_page_opened("performance.html")
diff --git a/tests/jdi_uitests_webtests/test/composite/search_test.py b/tests/jdi_uitests_webtests/test/composite/search_test.py
index 1f976e9..ea7b485 100644
--- a/tests/jdi_uitests_webtests/test/composite/search_test.py
+++ b/tests/jdi_uitests_webtests/test/composite/search_test.py
@@ -13,4 +13,4 @@ def setUp(self):
 
     def test_fill(self):
         EpamJDISite.header.search_section.find("something")
-        EpamJDISite.support_page.check_opened()
+        EpamJDISite.search_page.check_opened()
diff --git a/tests/jdi_uitests_webtests/test/conftest.py b/tests/jdi_uitests_webtests/test/conftest.py
index d630999..edd490d 100644
--- a/tests/jdi_uitests_webtests/test/conftest.py
+++ b/tests/jdi_uitests_webtests/test/conftest.py
@@ -1,5 +1,4 @@
 import logging
-import unittest
 
 import pytest
 
@@ -7,8 +6,6 @@
 from JDI.web.selenium.settings.web_settings import WebSettings
 from tests.jdi_uitests_webtests.main.entities.user import User
 from tests.jdi_uitests_webtests.main.page_objects.epam_jdi_site import EpamJDISite
-from tests.jdi_uitests_webtests.main.page_objects.w3c_site.w3c_site import W3cSite
-
 
 logger = logging.getLogger(__name__)
 
@@ -16,7 +13,7 @@
 @pytest.fixture(scope="class")
 def site():
     WebSite.init(EpamJDISite)
-    logger.info("Run Tests from '{}' file".format(__name__))
+    logger.info(f"Run Tests from '{__name__}' file, browser: {WebSettings.get_driver_factory().current_driver.name}")
     EpamJDISite.home_page.open()
     EpamJDISite.login_page.submit(User.default())
 
diff --git a/tests/test_get_driver.py b/tests/test_get_driver.py
deleted file mode 100644
index 787db3e..0000000
--- a/tests/test_get_driver.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import os
-
-import pytest
-
-from utils import get_driver
-
-
-@pytest.mark.unit
-class TestChrome:
-    def test_download_chromedriver(self):
-        get_driver.download_driver("https://chromedriver.storage.googleapis.com/91.0.4472.19/chromedriver_win32.zip")
-        assert os.path.exists("chromedriver_win32.zip") is True
-        assert os.path.exists("chromedriver.exe") is True
-
-    def test_get_last_release(self):
-        assert get_driver.get_last_release() != ""
-
-    def test_get_last_release_for_build(self):
-        assert get_driver.get_last_release(build="91").startswith("91.")
-
-    def test_compose_driver_download_link(self):
-        assert (
-            get_driver.compose_download_link("91.0.4472.19")
-            == "https://chromedriver.storage.googleapis.com/91.0.4472.19/chromedriver_win32.zip"
-        )
diff --git a/utils/__init__.py b/utils/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/utils/get_driver.py b/utils/get_driver.py
deleted file mode 100644
index 2098247..0000000
--- a/utils/get_driver.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# TODO: get last chromedriver version
-# TODO: get particular chromedriver version
-# TODO: download chromedriver and save to path
-# TODO: download and install chrome
-# TODO: argparse
-import zipfile
-
-import requests
-
-CHROMEDRIVER_URL = "https://chromedriver.storage.googleapis.com"
-
-
-def download_driver(link, extract_path="."):
-    filename = link.split("/")[-1]
-    r = requests.get(link, stream=True)
-    with open(filename, "wb") as f:
-        for chunk in r.iter_content():
-            f.write(chunk)
-    with zipfile.ZipFile(filename, "r") as zf:
-        zf.extractall(path=extract_path)
-
-
-def get_last_release(build=None) -> str:
-    # TODO: if build is set get last version for this build
-    if not build:
-        r = requests.get(f"{CHROMEDRIVER_URL}/LATEST_RELEASE")
-    else:
-        r = requests.get(f"{CHROMEDRIVER_URL}/LATEST_RELEASE_{build}")
-    return r.text
-
-
-def compose_download_link(build) -> str:
-    return f"{CHROMEDRIVER_URL}/{build}/chromedriver_win32.zip"
-
-
-if __name__ == "__main__":
-    release = get_last_release("87.0.4280")
-    download_link = compose_download_link(build=release)
-    download_driver(download_link)