prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Use SiteDriver class instead of seleniumrequests.Remote
  It will bring ability to use `shopelectro.selenium` classes in tests. 
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `shopelectro/selenium/pages/order.py`
  Content:
  ```
  1 from shopelectro.models import PaymentOptions
  2 from shopelectro.selenium.elements import Input, Button
  3 from shopelectro.selenium.pages import Page
  4 
  5 from selenium.webdriver.common.by import By
  6 
  7 from pages.models import CustomPage
  8 
  9 # @todo #682:120m Implement and reuse shopelectro.selenium.OrderPage for selenium tests.
  10 
  11 
  12 class OrderPage(Page):
  13 
  14     def __init__(self, driver):
  15         super().__init__(driver)
  16         self.submit_button = Button(self.driver, (By.ID, 'submit-order'))
  17 
  18     @property
  19     def path(self):
  20         return CustomPage.objects.get(slug='order').url
  21 
  22     def fill_contacts(
  23         self, name='Name', city='Санкт-Петербург', phone='2222222222', email='test@test.test',
  24     ):
  25         contacts = {
  26             'id_name': name,
  27             'id_city': city,
  28             'id_phone': phone,
  29             'id_email': email,
  30         }
  31 
  32         for id_, value in contacts.items():
  33             Input(self.driver, (By.ID, id_)).send_keys(value)
  34 
  35     def make_order(self):
  36         self.submit_button.click()
  37 
  38     def select_payment_type(self, payment_option: PaymentOptions):
  39         if payment_option not in PaymentOptions:
  40             raise ValueError(
  41                 'An invalid payment type provided.'
  42                 f'It should be one of: {PaymentOptions}'
  43             )
  44 
  45         item = Button(
  46             self.driver,
  47             (By.CSS, f'input[name="payment_type"][value="{payment_option.name}"]'),
  48         )
  49         item.click()
  50
  ```
  
  Path: `shopelectro/selenium/pages/page.py`
  Content:
  ```
  1 from shopelectro.selenium import SiteDriver
  2 
  3 from selenium.webdriver.common.by import By
  4 from selenium.webdriver.support import expected_conditions as EC
  5 
  6 
  7 class Page:
  8     """
  9     Represent a typical Shopelectro's page.
  10 
  11     Contains cross-page elements: header, footer, ...
  12     """
  13 
  14     def __init__(self, driver: SiteDriver):
  15         if not isinstance(driver, SiteDriver):
  16             raise TypeError('Driver must be an instance of shopelectro.selenium.SiteDriver')
  17         self.driver = driver
  18         self.path: str
  19 
  20     def load(self):
  21         if not self.path:
  22             raise ValueError(f'Set a page path to {self.__class__.__name__}')
  23         self.driver.get(self.path)
  24         self.driver.wait.until(EC.visibility_of_element_located(
  25             (By.TAG_NAME, 'body')
  26         ))
  27
  ```
  
  Path: `shopelectro/selenium/pages/success.py`
  Content:
  ```
  1 from shopelectro.selenium.pages import Page
  2 
  3 from pages.models import CustomPage
  4 
  5 
  6 class SuccessPage(Page):
  7 
  8     @property
  9     def path(self):
  10         CustomPage.objects.get(slug='order-success').url
  11 
  12     def is_success(self):
  13         return 'Заказ принят' in self.driver.find_element_by_tag_name('h1').text
  14
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/shopelectro/selenium/pages/order.py b/shopelectro/selenium/pages/order.py
  --- a/shopelectro/selenium/pages/order.py
  +++ b/shopelectro/selenium/pages/order.py
  @@ -3,6 +3,7 @@
   from shopelectro.selenium.pages import Page
   
   from selenium.webdriver.common.by import By
  +from selenium.webdriver.support import expected_conditions as EC
   
   from pages.models import CustomPage
   
  @@ -34,6 +35,7 @@
   
       def make_order(self):
           self.submit_button.click()
  +        self.driver.wait.until(EC.url_changes(self.path))
   
       def select_payment_type(self, payment_option: PaymentOptions):
           if payment_option not in PaymentOptions:
  diff --git a/shopelectro/selenium/pages/page.py b/shopelectro/selenium/pages/page.py
  --- a/shopelectro/selenium/pages/page.py
  +++ b/shopelectro/selenium/pages/page.py
  @@ -1,3 +1,5 @@
  +from functools import wraps
  +
   from shopelectro.selenium import SiteDriver
   
   from selenium.webdriver.common.by import By
  @@ -17,10 +19,17 @@
           self.driver = driver
           self.path: str
   
  +    def wait_loaded(self):
  +        def loaded(driver):
  +            is_sync = EC.url_contains(self.path)
  +            is_rendered = EC.visibility_of_element_located(
  +                (By.TAG_NAME, 'body')
  +            )
  +            return is_sync(driver) and is_rendered(driver)
  +        self.driver.wait.until(loaded)
  +
       def load(self):
           if not self.path:
               raise ValueError(f'Set a page path to {self.__class__.__name__}')
           self.driver.get(self.path)
  -        self.driver.wait.until(EC.visibility_of_element_located(
  -            (By.TAG_NAME, 'body')
  -        ))
  +        self.wait_loaded()
  diff --git a/shopelectro/selenium/pages/success.py b/shopelectro/selenium/pages/success.py
  --- a/shopelectro/selenium/pages/success.py
  +++ b/shopelectro/selenium/pages/success.py
  @@ -1,3 +1,6 @@
  +from selenium.webdriver.common.by import By
  +from selenium.webdriver.support import expected_conditions as EC
  +
   from shopelectro.selenium.pages import Page
   
   from pages.models import CustomPage
  @@ -7,7 +10,10 @@
   
       @property
       def path(self):
  -        CustomPage.objects.get(slug='order-success').url
  +        return CustomPage.objects.get(slug='order-success').url
   
       def is_success(self):
  -        return 'Заказ принят' in self.driver.find_element_by_tag_name('h1').text
  +        h1 = self.driver.wait.until(
  +            EC.visibility_of_element_located((By.TAG_NAME, 'h1'))
  +        ).text
  +        return 'Заказ принят' in h1
  
verification_info: {"golden_diff": "diff --git a/shopelectro/selenium/pages/order.py b/shopelectro/selenium/pages/order.py\n--- a/shopelectro/selenium/pages/order.py\n+++ b/shopelectro/selenium/pages/order.py\n@@ -3,6 +3,7 @@\n from shopelectro.selenium.pages import Page\n \n from selenium.webdriver.common.by import By\n+from selenium.webdriver.support import expected_conditions as EC\n \n from pages.models import CustomPage\n \n@@ -34,6 +35,7 @@\n \n     def make_order(self):\n         self.submit_button.click()\n+        self.driver.wait.until(EC.url_changes(self.path))\n \n     def select_payment_type(self, payment_option: PaymentOptions):\n         if payment_option not in PaymentOptions:\ndiff --git a/shopelectro/selenium/pages/page.py b/shopelectro/selenium/pages/page.py\n--- a/shopelectro/selenium/pages/page.py\n+++ b/shopelectro/selenium/pages/page.py\n@@ -1,3 +1,5 @@\n+from functools import wraps\n+\n from shopelectro.selenium import SiteDriver\n \n from selenium.webdriver.common.by import By\n@@ -17,10 +19,17 @@\n         self.driver = driver\n         self.path: str\n \n+    def wait_loaded(self):\n+        def loaded(driver):\n+            is_sync = EC.url_contains(self.path)\n+            is_rendered = EC.visibility_of_element_located(\n+                (By.TAG_NAME, 'body')\n+            )\n+            return is_sync(driver) and is_rendered(driver)\n+        self.driver.wait.until(loaded)\n+\n     def load(self):\n         if not self.path:\n             raise ValueError(f'Set a page path to {self.__class__.__name__}')\n         self.driver.get(self.path)\n-        self.driver.wait.until(EC.visibility_of_element_located(\n-            (By.TAG_NAME, 'body')\n-        ))\n+        self.wait_loaded()\ndiff --git a/shopelectro/selenium/pages/success.py b/shopelectro/selenium/pages/success.py\n--- a/shopelectro/selenium/pages/success.py\n+++ b/shopelectro/selenium/pages/success.py\n@@ -1,3 +1,6 @@\n+from selenium.webdriver.common.by import By\n+from selenium.webdriver.support import expected_conditions as EC\n+\n from shopelectro.selenium.pages import Page\n \n from pages.models import CustomPage\n@@ -7,7 +10,10 @@\n \n     @property\n     def path(self):\n-        CustomPage.objects.get(slug='order-success').url\n+        return CustomPage.objects.get(slug='order-success').url\n \n     def is_success(self):\n-        return '\u0417\u0430\u043a\u0430\u0437 \u043f\u0440\u0438\u043d\u044f\u0442' in self.driver.find_element_by_tag_name('h1').text\n+        h1 = self.driver.wait.until(\n+            EC.visibility_of_element_located((By.TAG_NAME, 'h1'))\n+        ).text\n+        return '\u0417\u0430\u043a\u0430\u0437 \u043f\u0440\u0438\u043d\u044f\u0442' in h1\n", "issue": "Use SiteDriver class instead of seleniumrequests.Remote\nIt will bring ability to use `shopelectro.selenium` classes in tests. \n", "before_files": [{"content": "from shopelectro.models import PaymentOptions\nfrom shopelectro.selenium.elements import Input, Button\nfrom shopelectro.selenium.pages import Page\n\nfrom selenium.webdriver.common.by import By\n\nfrom pages.models import CustomPage\n\n# @todo #682:120m Implement and reuse shopelectro.selenium.OrderPage for selenium tests.\n\n\nclass OrderPage(Page):\n\n    def __init__(self, driver):\n        super().__init__(driver)\n        self.submit_button = Button(self.driver, (By.ID, 'submit-order'))\n\n    @property\n    def path(self):\n        return CustomPage.objects.get(slug='order').url\n\n    def fill_contacts(\n        self, name='Name', city='\u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433', phone='2222222222', email='test@test.test',\n    ):\n        contacts = {\n            'id_name': name,\n            'id_city': city,\n            'id_phone': phone,\n            'id_email': email,\n        }\n\n        for id_, value in contacts.items():\n            Input(self.driver, (By.ID, id_)).send_keys(value)\n\n    def make_order(self):\n        self.submit_button.click()\n\n    def select_payment_type(self, payment_option: PaymentOptions):\n        if payment_option not in PaymentOptions:\n            raise ValueError(\n                'An invalid payment type provided.'\n                f'It should be one of: {PaymentOptions}'\n            )\n\n        item = Button(\n            self.driver,\n            (By.CSS, f'input[name=\"payment_type\"][value=\"{payment_option.name}\"]'),\n        )\n        item.click()\n", "path": "shopelectro/selenium/pages/order.py"}, {"content": "from shopelectro.selenium import SiteDriver\n\nfrom selenium.webdriver.common.by import By\nfrom selenium.webdriver.support import expected_conditions as EC\n\n\nclass Page:\n    \"\"\"\n    Represent a typical Shopelectro's page.\n\n    Contains cross-page elements: header, footer, ...\n    \"\"\"\n\n    def __init__(self, driver: SiteDriver):\n        if not isinstance(driver, SiteDriver):\n            raise TypeError('Driver must be an instance of shopelectro.selenium.SiteDriver')\n        self.driver = driver\n        self.path: str\n\n    def load(self):\n        if not self.path:\n            raise ValueError(f'Set a page path to {self.__class__.__name__}')\n        self.driver.get(self.path)\n        self.driver.wait.until(EC.visibility_of_element_located(\n            (By.TAG_NAME, 'body')\n        ))\n", "path": "shopelectro/selenium/pages/page.py"}, {"content": "from shopelectro.selenium.pages import Page\n\nfrom pages.models import CustomPage\n\n\nclass SuccessPage(Page):\n\n    @property\n    def path(self):\n        CustomPage.objects.get(slug='order-success').url\n\n    def is_success(self):\n        return '\u0417\u0430\u043a\u0430\u0437 \u043f\u0440\u0438\u043d\u044f\u0442' in self.driver.find_element_by_tag_name('h1').text\n", "path": "shopelectro/selenium/pages/success.py"}], "after_files": [{"content": "from shopelectro.models import PaymentOptions\nfrom shopelectro.selenium.elements import Input, Button\nfrom shopelectro.selenium.pages import Page\n\nfrom selenium.webdriver.common.by import By\nfrom selenium.webdriver.support import expected_conditions as EC\n\nfrom pages.models import CustomPage\n\n# @todo #682:120m Implement and reuse shopelectro.selenium.OrderPage for selenium tests.\n\n\nclass OrderPage(Page):\n\n    def __init__(self, driver):\n        super().__init__(driver)\n        self.submit_button = Button(self.driver, (By.ID, 'submit-order'))\n\n    @property\n    def path(self):\n        return CustomPage.objects.get(slug='order').url\n\n    def fill_contacts(\n        self, name='Name', city='\u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433', phone='2222222222', email='test@test.test',\n    ):\n        contacts = {\n            'id_name': name,\n            'id_city': city,\n            'id_phone': phone,\n            'id_email': email,\n        }\n\n        for id_, value in contacts.items():\n            Input(self.driver, (By.ID, id_)).send_keys(value)\n\n    def make_order(self):\n        self.submit_button.click()\n        self.driver.wait.until(EC.url_changes(self.path))\n\n    def select_payment_type(self, payment_option: PaymentOptions):\n        if payment_option not in PaymentOptions:\n            raise ValueError(\n                'An invalid payment type provided.'\n                f'It should be one of: {PaymentOptions}'\n            )\n\n        item = Button(\n            self.driver,\n            (By.CSS, f'input[name=\"payment_type\"][value=\"{payment_option.name}\"]'),\n        )\n        item.click()\n", "path": "shopelectro/selenium/pages/order.py"}, {"content": "from functools import wraps\n\nfrom shopelectro.selenium import SiteDriver\n\nfrom selenium.webdriver.common.by import By\nfrom selenium.webdriver.support import expected_conditions as EC\n\n\nclass Page:\n    \"\"\"\n    Represent a typical Shopelectro's page.\n\n    Contains cross-page elements: header, footer, ...\n    \"\"\"\n\n    def __init__(self, driver: SiteDriver):\n        if not isinstance(driver, SiteDriver):\n            raise TypeError('Driver must be an instance of shopelectro.selenium.SiteDriver')\n        self.driver = driver\n        self.path: str\n\n    def wait_loaded(self):\n        def loaded(driver):\n            is_sync = EC.url_contains(self.path)\n            is_rendered = EC.visibility_of_element_located(\n                (By.TAG_NAME, 'body')\n            )\n            return is_sync(driver) and is_rendered(driver)\n        self.driver.wait.until(loaded)\n\n    def load(self):\n        if not self.path:\n            raise ValueError(f'Set a page path to {self.__class__.__name__}')\n        self.driver.get(self.path)\n        self.wait_loaded()\n", "path": "shopelectro/selenium/pages/page.py"}, {"content": "from selenium.webdriver.common.by import By\nfrom selenium.webdriver.support import expected_conditions as EC\n\nfrom shopelectro.selenium.pages import Page\n\nfrom pages.models import CustomPage\n\n\nclass SuccessPage(Page):\n\n    @property\n    def path(self):\n        return CustomPage.objects.get(slug='order-success').url\n\n    def is_success(self):\n        h1 = self.driver.wait.until(\n            EC.visibility_of_element_located((By.TAG_NAME, 'h1'))\n        ).text\n        return '\u0417\u0430\u043a\u0430\u0437 \u043f\u0440\u0438\u043d\u044f\u0442' in h1\n", "path": "shopelectro/selenium/pages/success.py"}]}