Skip to main content

An extension library for adding ease of use Appium-Python-Client

Project description

# AppiumExtended  

Представляем вам библиотеку расширяющую возможности фреймворка [Appium-Python-Client](https://github.com/appium/python-client). С AppiumExtended вам будут доступны новые удобные функции и возможности, которые позволят более эффективно и легко автоматизировать ваши тесты. Позвольте вашим разработчикам сосредоточиться на более сложных задачах, а наша библиотека облегчит взаимодействие с Appium и сделает процесс автоматизации более приятным и эффективным. Дайте вашим тестам возможность раскрыть свой полный потенциал с помощью этого интуитивного расширения для [Appium-Python-Client](https://pypi.org/project/Appium-Python-Client/).

Требуется установить appium cli с плагинами: appium-device-farm, appium-dashboard.

```
npm i -g appium@next
appium driver install uiautomator2
appium plugin install --source=npm appium-device-farm
appium plugin install --source=npm appium-dashboard
```

# Установка AppiumExtended

Существует три способа установки AppiumExtended.

1. Установка из [PyPi](https://pypi.org/), как ['AppiumExtended'](https://pypi.org/project/AppiumExtended/).

```shell
pip install appium_extended
```

Историю выпусков можно посмотреть [здесь](https://pypi.org/project/AppiumExtended/#history)

2. Установка исходного кода, через [PyPi](https://pypi.org/). Из ['AppiumExtended'](https://pypi.org/project/AppiumExtended/), скачайте и разархивируйте исходный архив (AppiumExtended-X.X.tar.gz).

```shell
tar -xvf appium_extended-X.X.tar.gz
cd appium_extended-X.X
python setup.py install
```

3. Установка исходного кода из [GitHub](https://github.com/molokov-klim/appium_extended).

```shell
git clone https://github.com/molokov-klim/appium_extended.git
cd appium_extended
python setup.py install
```

---

# Содержание

### [class `AppiumExtended`](https://github.com/molokov-klim/appium_extended#class-appiumextended)

- [connect](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-connect)
- [disconnect](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-disconnect)
- [is_running](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-is_running)
- [get_element](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_element)
- [find_and_get_element](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-find_and_get_element)
- [get_elements](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_elements)
- [get_image_coordinates](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_image_coordinates)
- [get_inner_image_coordinates](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_inner_image_coordinates)
- [get_many_coordinates_of_image](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_many_coordinates_of_image)
- [get_text_coordinates](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_text_coordinates)
- [get_screenshot_as_base64_decoded](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_screenshot_as_base64_decoded)
- [get_element_contains](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_element_contains)
- [get_elements_contains](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_elements_contains)
- [is_element_within_screen](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-is_element_within_screen)
- [is_text_on_screen](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-is_text_on_screen)
- [is_image_on_the_screen](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-is_image_on_the_screen)
- [tap](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-tap)
- [swipe](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-swipe)
- [swipe_top_to_bottom](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-swipe_top_to_bottom)
- [swipe_bottom_to_top](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-swipe_bottom_to_top)
- [swipe_right_to_left](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-swipe_right_to_left)
- [swipe_left_to_right](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-swipe_left_to_right)
- [wait_for](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-wait_for)
- [wait_for_not](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-wait_for_not)
- [wait_return_true](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-wait_return_true)
- [draw_by_coordinates](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-draw_by_coordinates)
- [input_by_virtual_keyboard](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-input_by_virtual_keyboard)

---

### [class `WebElementExtended`](https://github.com/molokov-klim/appium_extended#class-webelementextended)

- [get_element](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_element-1)
- [get_attributes](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_attributes)
- [click](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-click)
- [double_click](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-double_click)
- [click_and_move](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-click_and_move)
- [adb_tap](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-adb_tap)
- [adb_multi_tap](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-adb_multi_tap)
- [adb_swipe](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-adb_swipe)
- [tap](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-tap-1)
- [double_tap](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-double_tap)
- [tap_and_move](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-tap_and_move)
- [get_elements](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_elements-1)
- [scroll_down](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-scroll_down)
- [scroll_up](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-scroll_up)
- [scroll_to_bottom](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-scroll_to_bottom)
- [scroll_to_top](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-scroll_to_top)
- [scroll_until_find](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-scroll_until_find)
- [get_parent](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_parent)
- [get_parents](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_parents)
- [get_sibling](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_sibling)
- [get_siblings](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_siblings)
- [get_cousin](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_cousin)
- [get_cousins](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_cousins)
- [is_contains](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-is_contains)
- [zoom](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-zoom)
- [unzoom](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-unzoom)
- [get_center](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_center)
- [get_coordinates](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_coordinates)

---

### [class `AppiumServer`](https://github.com/molokov-klim/appium_extended#class-appiumserver)

- [start](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-start)
- [is_alive](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-is_alive)
- [stop](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-stop)
- [wait_until_alive](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-wait_until_alive)

---

### [class `AppiumNavigator`](https://github.com/molokov-klim/appium_extended#class-appiumnavigator)

- [add_page](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-add_page)
- [navigate](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-navigate)
- [find_path](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-find_path)
- [perform_navigation](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-perform_navigation)

---

### [class `Aapt`](https://github.com/molokov-klim/appium_extended#class-aapt)

- [get_package_name](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_package_name)
- [get_launchable_activity](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_launchable_activity)

---

### [class `Terminal`](https://github.com/molokov-klim/appium_extended#class-terminal)

- [adb_shell](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-adb_shell)
- [push](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-push)
- [pull](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-pull)
- [start_activity](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-start_activity)
- [get_current_app_package](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_current_app_package)
- [close_app](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-close_app)
- [reboot_app](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-reboot_app)
- [uninstall_app](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-uninstall_app)
- [is_app_installed](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-is_app_installed)
- [press_home](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-press_home)
- [press_back](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-press_back)
- [press_menu](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-press_menu)
- [input_keycode_num](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-input_keycode_num_)
- [input_keycode](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-input_keycode)
- [input_by_virtual_keyboard](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-input_by_virtual_keyboard-1)
- [input_text](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-input_text)
- [tap](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-tap-2)
- [swipe](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-swipe-1)
- [check_vpn](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-check_vpn)
- [stop_logcat](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-stop_logcat)
- [know_pid](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-know_pid)
- [is_process_exist](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-is_process_exist)
- [run_background_process](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-run_background_process)
- [kill_by_pid](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-kill_by_pid)
- [kill_all](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-kill_all)
- [delete_files_from_internal_storage](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-delete_files_from_internal_storage)
- [delete_file_from_internal_storage](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-delete_file_from_internal_storage)
- [record_video](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-record_video)
- [stop_video](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-stop_video)
- [reboot](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-reboot)
- [get_screen_resolution](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_screen_resolution)

---

### [class `Adb`](https://github.com/molokov-klim/appium_extended#class-adb)

1. [install_app](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-install_app-1)
2. [is_app_installed](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-is_app_installed-1)
3. [uninstall_app](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-uninstall_app-1)
4. [get_device_model](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_device_model)
5. [push](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-push-1)
6. [pull](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-pull-1)
7. [start_activity](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-start_activity-1)
8. [close_app](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-close_app-1)
9. [reboot_app](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-reboot_app-1)
10. [press_home](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-press_home-1)
11. [press_back](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-press_back-1)
12. [press_menu](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-press_menu-1)
13. [input_keycode_num](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-input_keycode_num_-1)
14. [input_keycode](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-input_keycode-1)
15. [input_by_virtual_keyboard](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-input_by_virtual_keyboard-2)
16. [input_text](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-input_text-1)
17. [tap](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-tap-3)
18. [swipe](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-swipe-2)
19. [get_current_app_package](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_current_app_package-1)
20. [check_vpn](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-check_vpn-1)
21. [stop_logcat](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-stop_logcat-1)
22. [reload_adb](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-reload_adb)
23. [know_pid](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-know_pid-1)
25. [is_process_exist](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-is_process_exist-1)
26. [run_background_process](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-run_background_process-1)
27. [kill_by_pid](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-kill_by_pid-1)
28. [kill_by_name](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-kill_by_name)
29. [kill_all](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-kill_all-1)
30. [delete_files_from_internal_storage](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-delete_files_from_internal_storage-1)
31. [pull_video](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-pull_video)
32. [stop_video](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-stop_video-1)
33. [record_video](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-record_video-1)
34. [reboot](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-reboot-1)
35. [get_screen_resolution](https://github.com/molokov-klim/appium_extended#%D0%BC%D0%B5%D1%82%D0%BE%D0%B4-get_screen_resolution-1)

---

# class AppiumExtended()
Класс работы с Appium, предоставляющий базовые методы для взаимодействия с устройством.

## Инициализация: `__init__()`

### Параметры
- `logger`: Журнал для записи сообщений (по умолчанию `None`).
- `log_level`: Уровень логирования (по умолчанию `logging.INFO`).
- `log_path`: Путь для сохранения журнала (по умолчанию пустая строка).

## Метод: `connect()`

### Параметры

- `capabilities`: Словарь, содержащий набор возможностей устройства для подключения.
- `server_ip`: IP-адрес сервера Appium (по умолчанию `'127.0.0.1'`).
- `server_port`: Порт сервера Appium (по умолчанию `4723`).
- `server_log_level`: Уровень логирования сервера (по умолчанию `'error'`).
- `remote`: Флаг, указывающий на удаленное подключение к серверу (по умолчанию `False`).
- `keep_alive_server`: Флаг, указывающий оставлять ли сервер включенным после дисконнекта (по умолчанию `True`).

### Пример использования
```python
app = AppiumExtended()

capabilities = {
"platformName": "android",
"appium:automationName": "uiautomator2",
...
}

app.connect(capabilities=capabilities)
```

```python
logger = logging.getLogger(__name__)
log_level = logging.INFO
log_path = os.path.join('path', 'to', 'log')

app = AppiumExtended(logger=logger,
log_level=log_level,
log_path=log_path)

path_to_apk = os.path.join('path', 'to', 'apk')

capabilities = {
"platformName": "android",
"appium:automationName": "uiautomator2",
"appium:deviceName": app.adb.get_device_model(),
"appium:udid": app.adb.get_device_uuid(),
"appium:app": path_to_apk,
"appium:appPackage": app.aapt.get_package_name(path_to_apk)
"appium:appWaitActivity": app.aapt.get_launchable_activity(path_to_apk)
"appium: autoGrantPermissions": True,
"appium: newCommandTimeout": 99999,
}

server_ip='10.77.124.78',
server_port=4723,
server_log_level='error',
remote=True,
keep_alive_server=True

app.connect(capabilities=capabilities,
server_ip=server_ip,
server_port=server_port,
server_log_level=server_log_level,
remote=remote,
keep_alive_server=keep_alive_server)
```

### Детали реализации

Метод включает следующие основные этапы:

1. Сохранение настроек сервера в соответствующих свойствах объекта.
2. Инициализация и, при необходимости, запуск локального сервера Appium.
3. Подключение к серверу Appium и инициализация драйвера `webdriver.Remote`.
4. Инициализация дополнительных объектов (`Terminal` и `AppiumHelpers`) с созданным драйвером.
5. Запись в лог информации о подключении и номере сессии драйвера.

### Дополнительная информация

В связи с использованием appium-device-farm указывать device udid необязательно.
```python
capabilities = {
"platformName": "android",
"appium:automationName": "uiautomator2",
}
```


## Метод: `disconnect()`

Метод `disconnect` отвечает за отключение от устройства.

### Пример использования

```python
app.disconnect()
```

### Детали реализации

1. Проверка, установлен ли драйвер (`self.driver`). Если драйвер установлен, то выполняется его завершение с помощью метода `quit()` и затем драйвер обнуляется. В процессе выполнения этих операций в лог записывается информация о номере сессии, от которой происходит отключение.
2. Если не установлено значение `self.keep_alive_server`, то останавливается работа сервера с помощью метода `stop()`.

### Исключения

Метод не генерирует исключения напрямую, но может пробросить исключения, сгенерированные внутренними вызовами, например, при ошибке остановки сервера.


## Метод: `is_running()`

Метод `is_running` проверяет, активна ли текущая сессия драйвера.

### Возвращаемое значение

Возвращает `True` если текущая сессия драйвера активна, и `False` в противном случае.

### Пример использования

```python
if device.is_running():
print("Устройство активно")
else:
print("Устройство не активно")
```

### Исключения

Метод может генерировать исключения, в случае если `self.driver` не инициализирован. Также исключения могут быть сгенерированы внутренними вызовами метода `is_running` из объекта `self.driver`, например, при проблемах сети или сервера.


## Метод: `get_element()`

Этот метод обеспечивает поиск элемента в текущей структуре DOM. Метод должен получать либо локатор, либо значения `by` и `value`.

### Параметры

`locator`: Определяет локатор элемента. Это может быть:
- кортеж - локатор в виде ('атрибут', 'значение')
- объект WebElement
- словарь, содержащий пары атрибут: значение
- строка - путь до файла с изображением элемента.

`by`: Тип локатора для поиска элемента (всегда в связке с `value`). Может быть типом MobileBy, AppiumBy, By, или строкой.

`value`: Значение локатора или словарь аргументов, если используется AppiumBy.XPATH. Может быть строкой, словарём или `None`.

`timeout_elem`: Время ожидания элемента в секундах.

`timeout_method`: Время ожидания метода поиска элемента в секундах.

`elements_range`: Ограничивает поиск элемента в указанном диапазоне. Используется при поиске по изображению. Может быть кортежем, списком, словарём или `None`.

`contains`: Используется для поиска по словарю. Если `True`, ищет элемент, содержащий фрагмент значения.

### Возвращаемое значение

Возвращает объект WebElementExtended или `None`, если элемент не был найден.

### Пример использования

```python
element = app.get_element(locator=("id", "foo"))
element = app.get_element(element)
element = app.get_element(locator={'text': 'foo'})
element = app.get_element(locator='/path/to/file/pay_agent.png')
element = app.get_element(locator=part_image, elements_range={'class':'android.widget.FrameLayout', 'package':'ru.app.debug'})
element = app.get_element(by="id", value="ru.sigma.app.debug:id/backButton")
element = app.get_element(by=MobileBy.ID, value="ru.sigma.app.debug:id/backButton")
element = app.get_element(by=AppiumBy.ID, value="ru.sigma.app.debug:id/backButton")
element = app.get_element(by=By.ID, value="ru.sigma.app.debug:id/backButton")
```

### Исключения

Метод может генерировать исключения, в случае если введены некорректные аргументы или возникают ошибки при обработке элементов (например, `NoSuchElementException`, `TimeoutException` или `WebDriverException`).

## Метод: `find_and_get_element()`

Этот метод используется для поиска элемента. Если элемент не найден, метод будет скроллить все скроллируемые элементы, пока не найдет искомый элемент или пока не будет проскроллено все доступное пространство.

### Параметры

- `locator` (Union[Tuple, WebElement, 'WebElementExtended', Dict[str, str], str]): Это местоположение или определение элемента, который нужно найти. Это может быть кортеж, экземпляр WebElement, словарь или строка.

- `timeout` (int, опционально): Это максимальное время ожидания для поиска элемента. По умолчанию это 10 секунд.

### Возвращаемое значение

Метод возвращает экземпляр `WebElementExtended`, если элемент найден. Если элемент не найден после прокрутки всей доступной страницы, возвращается `None`.

### Пример использования

```python
element = app.find_and_get_element(locator={'id': 'element_id'})
```

### Дополнительная информация

Внутри этого метода сначала проверяется, виден ли элемент на экране с помощью `is_element_within_screen()`. Если это так, то элемент возвращается с помощью `get_element()`.

Если элемент не виден на экране, то метод производит поиск во всех доступных для прокрутки элементах страницы. Если элемент найден в каком-то из этих элементов, он возвращается. Если элемент не найден после прокрутки всей доступной страницы, метод возвращает `None`.



## Метод: `get_elements()`

Этот метод обеспечивает поиск элементов в текущей структуре DOM. Метод может получать либо локатор, либо пару значений `by` и `value`.

### Параметры

- `locator`: Определяет локатор элементов. Это может быть:
- Кортеж - локатор в виде ('атрибут', 'значение')
- Список объектов WebElement
- Словарь, содержащий пары атрибут: значение
- Строка - путь до файла с изображением элемента.
- `by`: Тип локатора для поиска элемента (всегда используется в связке с `value`). Может быть типом MobileBy, AppiumBy, By, или строкой.
- `value`: Значение локатора или словарь аргументов, если используется AppiumBy.XPATH. Может быть строкой, словарём или `None`.
- `timeout_elements`: Время ожидания в секундах для появления каждого элемента.
- `timeout_method`: Общее время ожидания в секундах для выполнения всего метода.
- `elements_range`: Ограничивает поиск элементов в указанном диапазоне. Используется при поиске по изображению. Может быть кортежем, списком, словарём или `None`.
- `contains`: Используется для поиска по словарю. Если `True`, ищет элементы, содержащие фрагмент значения.

### Возвращаемое значение

Возвращает список объектов WebElementExtended, или `None`, если элементы не были найдены.

### Пример использования

```python
elements = app.get_elements(locator=("id", "foo"))
elements = app.get_elements(locator={'text': 'foo'})
elements = app.get_elements(locator='/path/to/file/pay_agent.png')
elements = app.get_elements(locator=part_image, elements_range={'class':'android.widget.FrameLayout', 'package':'ru.app.debug'})
elements = app.get_elements(by="id", value="ru.sigma.app.debug:id/backButton")
elements = app.get_elements(by=MobileBy.ID, value="ru.sigma.app.debug:id/backButton")
elements = app.get_elements(by=AppiumBy.ID, value="ru.sigma.app.debug:id/backButton")
elements = app.get_elements(by=By.ID, value="ru.sigma.app.debug:id/backButton")
```

### Исключения

Метод может генерировать исключения, в случае если введены некорректные аргументы или возникают ошибки при обработке элементов (например, `NoSuchElementException`, `TimeoutException` или `WebDriverException`).


## Метод: `get_image_coordinates()`

Этот метод находит координаты наиболее вероятного совпадения частичного изображения в полном изображении. Используется для поиска элементов или участков интерфейса на экране по изображению.

### Параметры

- `image`: Путь к файлу частичного изображения, которое нужно найти внутри полного изображения. Может быть байтами, массивом `np.ndarray`, объектом `Image.Image`, или строкой (путь к файлу).

- `full_image`: Путь к файлу полного изображения. Может быть байтами, массивом `np.ndarray`, объектом `Image.Image`, или строкой (путь к файлу). Если `None`, то будет использовано текущее скриншотное изображение.

- `threshold`: Минимальный порог совпадения, необходимый для считывания совпадения допустимым. По умолчанию равно 0.7.


### Возвращаемое значение

Возвращает кортеж с координатами наиболее вероятного совпадения в формате (x1, y1, x2, y2) или `None`, если совпадение не найдено.

### Пример использования

```python
coords = app.get_image_coordinates(image="/path/to/partial/image.png", full_image="/path/to/full/image.png", threshold=0.8)
```

### Дополнительная информация

Этот метод использует декоратор `retry`, который выполняет функцию до тех пор, пока она не вернет результат, отличный от `None` или `False`, или пока не будет достигнуто максимальное количество попыток (3 попытки по умолчанию). После каждой неудачной попытки происходит пауза на 1 секунду.

### Исключения

Метод может генерировать исключения при обработке изображений или при работе с файлами.

## Метод: `get_inner_image_coordinates()`

Этот метод сначала находит изображение на экране (внешнее изображение), а затем находит другое изображение (внутреннее изображение) внутри обнаруженного изображения.

### Параметры

- `outer_image_path`: Путь к файлу с изображением, которое нужно найти на экране. Может быть байтами, массивом `np.ndarray`, объектом `Image.Image`, или строкой (путь к файлу).

- `inner_image_path`: Путь к файлу с изображением, которое нужно найти внутри внешнего изображения. Может быть байтами, массивом `np.ndarray`, объектом `Image.Image`, или строкой (путь к файлу).

- `threshold`: Пороговое значение сходства для шаблонного сопоставления. По умолчанию 0.9.

### Возвращаемое значение

Возвращает координаты внутреннего изображения относительно экрана в формате ((x1, y1), (x2, y2)). Если внутреннее изображение не найдено, возвращает `None`.

### Пример использования

```python
coords = app.get_inner_image_coordinates(outer_image_path="/path/to/outer/image.png", inner_image_path="/path/to/inner/image.png", threshold=0.8)
```

### Дополнительная информация

Этот метод использует декоратор `retry`, который выполняет функцию до тех пор, пока она не вернет результат, отличный от `None` или `False`, или пока не будет достигнуто максимальное количество попыток (3 попытки по умолчанию). После каждой неудачной попытки происходит пауза на 1 секунду.

### Исключения

Метод может генерировать исключения при обработке изображений или при работе с файлами.


## Метод: `get_many_coordinates_of_image()`

Этот метод находит все вхождения частичного изображения внутри полного изображения.

### Параметры

- `image`: Путь к файлу частичного изображения, которое нужно найти внутри полного изображения. Может быть байтами, массивом `np.ndarray`, объектом `Image.Image`, или строкой (путь к файлу).

- `full_image`: Путь к файлу полного изображения. Может быть байтами, массивом `np.ndarray`, объектом `Image.Image`, или строкой (путь к файлу). Если `None`, то будет сделан скриншот экрана и использован как полное изображение.

- `cv_threshold`: Минимальный порог совпадения, необходимый для считывания совпадения допустимым. По умолчанию равно 0.7.

- `coord_threshold`: Целое число, представляющее максимальное различие между значениями x и y двух кортежей, чтобы они считались слишком близкими друг к другу. По умолчанию равно 5.

### Возвращаемое значение

Возвращает список кортежей, содержащий расположение каждого найденного совпадения. Если совпадений не найдено, возвращается `None`.

### Пример использования

```python
matches = app.get_many_coordinates_of_image(image="/path/to/image.png", full_image="/path/to/full/image.png", cv_threshold=0.7, coord_threshold=5)
```

### Дополнительная информация

Этот метод использует декоратор `retry`, который выполняет функцию до тех пор, пока она не вернет результат, отличный от `None` или `False`, или пока не будет достигнуто максимальное количество попыток (3 попытки по умолчанию). После каждой неудачной попытки происходит пауза на 1 секунду.


### Исключения

Метод может генерировать исключения при обработке изображений или при работе с файлами.


## Метод: `get_text_coordinates()`

Этот метод возвращает координаты области, содержащей указанный текст на предоставленном изображении или снимке экрана.

### Параметры

- `text`: Искомый текст.

- `language`: Язык для распознавания текста. По умолчанию 'rus'.

- `image`: Изображение, на котором осуществляется поиск текста. Может быть байтами, строкой (путь к файлу), объектом `Image.Image` или массивом `np.ndarray`. Если не указано, будет использован снимок экрана. По умолчанию `None`.

- `ocr`: Булев флаг, определяющий, следует ли использовать распознавание оптических символов (OCR) для извлечения текста из изображения. По умолчанию `True`.

### Возвращаемое значение

Возвращает кортеж из четырех целых чисел, представляющих координаты области с текстом (верхний левый угол и нижний правый угол). Если текст не найден, возвращается `None`.

### Пример использования

```python
coordinates = app.get_text_coordinates(text="Hello, world!", language="eng", image="/path/to/image.png", ocr=True)
```

### Дополнительная информация

Если флаг `ocr` установлен в `False`, метод будет использовать внутреннюю реализацию поиска элемента для извлечения координат области, содержащей искомый текст.


## Метод: `get_screenshot_as_base64_decoded()`

Этот метод возвращает текущий снимок экрана в браузере, декодированный из формата base64 в байты.

### Параметры

Метод не требует никаких параметров.

### Возвращаемое значение

Возвращает байты, представляющие снимок экрана. Эти байты могут быть использованы для создания изображения.

### Пример использования

```python
screenshot = app.get_screenshot_as_base64_decoded()
```

### Дополнительная информация

Этот метод используется внутри других методов класса для получения текущего снимка экрана при работе с изображениями.



## Метод: `get_element_contains()`

Этот метод пока не реализован. Ожидается, что он будет использоваться для поиска и возврата родительского элемента, который содержит определённый дочерний элемент.

### Параметры

На данный момент в методе нет параметров.

### Возвращаемое значение

На данный момент метод возвращает ошибку `NotImplementedError` при вызове, так как он ещё не реализован.

### Пример использования

```python
# Этот метод еще не реализован, поэтому его нельзя вызвать.
```

### Дополнительная информация

В текущей реализации метод возвращает исключение `NotImplementedError` с сообщением "This method is not implemented yet". Это означает, что метод ещё не реализован. Предполагается, что в будущем он будет реализован для поиска и возврата родительского элемента, содержащего определённый дочерний элемент.



## Метод: `get_elements_contains()`

Этот метод пока не реализован. Ожидается, что он будет использоваться для поиска и возврата всех родительских элементов, которые содержат определённые дочерние элементы.

### Параметры

На данный момент в методе нет параметров.

### Возвращаемое значение

На данный момент метод возвращает ошибку `NotImplementedError` при вызове, так как он ещё не реализован.

### Пример использования

```python
# Этот метод еще не реализован, поэтому его нельзя вызвать.
```

### Дополнительная информация

В текущей реализации метод возвращает исключение `NotImplementedError` с сообщением "This method is not implemented yet". Это означает, что метод ещё не реализован. Предполагается, что в будущем он будет реализован для поиска и возврата всех родительских элементов, содержащих определённые дочерние элементы.


## Метод: `is_element_within_screen()`

Этот метод проверяет, находится ли заданный элемент полностью на экране.

### Параметры

- `locator` (`Union[Tuple, WebElement, 'WebElementExtended', Dict[str, str], str]`): Локатор или элемент, который нужно проверить. Может быть кортежем, объектом WebElement, объектом WebElementExtended, словарем или строкой.
- `timeout` (`int`, необязательный): Время ожидания появления элемента в секундах. По умолчанию равно 10.

### Возвращаемое значение

- `bool`: Возвращает `True`, если элемент находится на видимой части экрана, и `False` в противном случае.

### Пример использования

```python
# Допустим, мы хотим проверить, находится ли элемент с id 'some_id' на видимой части экрана.
is_visible = app.is_element_within_screen(locator=('id', 'some_id'))
```

### Дополнительная информация

Метод сначала получает размеры экрана, затем ищет элемент с помощью предоставленного локатора. Если элемент не найден или не отображается, метод возвращает `False`. Если элемент найден и отображается, метод проверяет, находятся ли координаты элемента в пределах размеров экрана. Если элемент находится за пределами экрана, метод возвращает `False`. В противном случае, если элемент находится в пределах видимой области экрана, метод возвращает `True`.


## Метод: `is_text_on_screen()`

Этот метод проверяет, присутствует ли заданный текст на экране.

### Параметры

- `text` (`str`): Текст, который нужно найти на экране.
- `ocr` (`bool`, необязательный): Определяет, производить ли поиск текста на изображении или в DOM. Если `True`, распознавание текста производится с помощью библиотеки `pytesseract`. Если `False`, производится поиск элемента по xpath. Значение по умолчанию: `True`.
- `language` (`str`, необязательный): Язык для распознавания текста. По умолчанию 'rus'.

### Возвращаемое значение

- `bool`: Возвращает `True`, если заданный текст найден на экране. В противном случае возвращает `False`.

### Пример использования

```python
# Допустим, мы хотим проверить, находится ли текст 'Hello' на экране.
is_present = app.is_text_on_screen(text='Hello')
```

### Дополнительная информация

Метод использует разные подходы в зависимости от значения параметра `ocr`. Если `ocr=True`, то он использует библиотеку `pytesseract` для распознавания текста на изображении экрана. Если `ocr=False`, то он производит поиск элемента по xpath, используя текст как значение атрибута 'text' элемента.


## Метод: `is_image_on_the_screen()`

Этот метод сравнивает, присутствует ли заданное изображение на экране.

### Параметры

- `image` (`Union[bytes, np.ndarray, Image.Image, str]`): Изображение для поиска. Это может быть имя файла, байтовый поток, массив numpy или объект PIL Image.
- `threshold` (`float`, необязательный): Пороговое значение схожести части изображения со снимком экрана. По умолчанию 0.9.

### Возвращаемое значение

- `bool`: Возвращает `True`, если изображение найдено на экране. В противном случае возвращает `False`.

### Пример использования

```python
# Допустим, мы хотим проверить, находится ли изображение 'button.png' на экране.
is_present = app.is_image_on_the_screen(image='button.png')
```

### Дополнительная информация

Метод сначала делает снимок текущего экрана, затем преобразует его и искомое изображение в оттенки серого для лучшего сопоставления. Затем используется метод `cv2.matchTemplate` для сопоставления мелкого изображения и снимка экрана. Затем используется `cv2.minMaxLoc` для извлечения максимального коэффициента схожести и его координат. Если максимальное значение превышает заданный порог, метод возвращает `True`, в противном случае `False`.

## Метод: `tap()`

Этот метод выполняет действие "тап" или "клик" по определенным координатам, элементу или изображению на экране.

### Параметры

- `locator` (`Union[Tuple[str, str], WebElementExtended, WebElement, Dict[str, str], str]`, необязательный): Элемент или локатор, на который нужно нажать.
- `x` (`int`, необязательный): X координата точки, по которой следует нажать.
- `y` (`int`, необязательный): Y координата точки, по которой следует нажать.
- `image` (`Union[bytes, np.ndarray, Image.Image, str]`, необязательный): Изображение, на котором следует нажать.
- `duration` (`Optional[int]`, необязательный): Продолжительность нажатия в миллисекундах.
- `timeout` (`int`, необязательный): Время ожидания в секундах перед тем как метод вернет `None`, если изображение не найдено на экране. По умолчанию равно 5.

### Возвращаемое значение

- `Union['AppiumExtended', None]`: Возвращает экземпляр класса `AppiumExtended`, если действие "тап" или "клик" успешно выполнено. В противном случае возвращает `None`.

### Пример использования

```python
# Нажатие на элемент с указанным локатором
app.tap(locator=('id', 'button'))

# Нажатие по координатам
app.tap(x=100, y=200)

# Нажатие на изображение
app.tap(image='button.png')
```

### Дополнительная информация

Этот метод использует внутренний метод `_extract_point_coordinates_by_typing()` для получения координат точки, по которой следует нажать, если был передан `locator` или `image`. Если указано изображение, метод будет ожидать его появления на экране в течение указанного времени ожидания, прежде чем выполнить действие "тап". Затем вызывается внутренний метод `_tap()` для выполнения действия "тап" по заданным координатам.

## Метод: `swipe()`

Этот метод выполняет свайп (перетаскивание) элемента или изображения на экране.

### Параметры

- `start_position`: Позиция начала свайпа. Может быть задана в различных форматах:
- Если `start_position` является кортежем и оба его элемента являются строками, то он представляет собой локатор элемента. В этом случае будет выполнен поиск элемента и используется его позиция.
- Если `start_position` является словарем, то считается, что это локатор элемента, основанный на атрибутах. Например, {'text': 'some text'} или {'class': 'SomeClass', 'visible': 'true'}. В этом случае будет выполнен поиск элемента по указанным атрибутам, и используется его позиция.
- Если `start_position` является экземпляром класса WebElement или WebElementExtended, то используется его позиция.
- Если `start_position` является строкой, массивом байтов (bytes), массивом NumPy (np.ndarray) или объектом класса Image.Image, то считается, что это изображение. В этом случае будет вычислен центр изображения и используется его позиция.
- Если `start_position` является кортежем, и оба его элемента являются целыми числами, то считается, что это координаты в формате (x_coordinate, y_coordinate).
- `end_position`: Позиция конца свайпа. Принимает те же форматы, что и `start_position`. По умолчанию None.
- `direction`: Направление свайпа. Принимает значения от 0 до 360 градусов. Если указано направление, то будет вычислена конечная точка свайпа на основе текущего размера окна и указанного расстояния. По умолчанию None.
- `distance`: Расстояние свайпа. Принимается в пикселях. Используется только в сочетании с параметром `direction`. По умолчанию None.
- `duration`: Продолжительность свайпа в миллисекундах. По умолчанию 0.

### Возвращаемое значение

- `AppiumExtended`: Экземпляр класса AppiumExtended.

### Примечания

- В качестве конечной позиции свайпа должен быть указан `end_position` или пара `direction, distance`.
- `str` принимается как путь к изображению на экране и вычисляется его центр, а не как локатор элемента

### Пример использования

```python
# Свайп элемента на экране по указанным координатам
app.swipe(start_position=(100, 200), end_position=(300, 400))

# Свайп по направлению и расстоянию
app.swipe(start_position=('xpath', '//button[@id="submit"]'), direction=90, distance=100)

# Свайп изображения
app.swipe(start_position='image.png', end_position=(300, 400))
```

### Дополнительная информация

Метод обязательно должен принимать либо end_postition, либо direction и distance

## Метод: `swipe_top_to_bottom()`

Этот метод выполняет свайп (перетаскивание) с верхней части экрана к нижней.

### Параметры

Метод не принимает параметров.

### Возвращаемое значение

- `None`

### Примечания

- Метод использует функцию `adb.get_screen_resolution()` для определения размера экрана.
- Позиция начала свайпа (`start_position`) вычисляется как 10% от высоты экрана.
- Позиция конца свайпа (`end_position`) вычисляется как 90% от высоты экрана.

### Пример использования

```python
# Свайп сверху вниз на экране
app.swipe_top_to_bottom()
```

## Метод: `swipe_bottom_to_top()`

Этот метод выполняет свайп (перетаскивание) с нижней части экрана к верхней.

### Параметры

Метод не принимает параметров.

### Возвращаемое значение

- `None`

### Примечания

- Метод использует функцию `adb.get_screen_resolution()` для определения размера экрана.
- Позиция начала свайпа (`start_position`) вычисляется как 90% от высоты экрана.
- Позиция конца свайпа (`end_position`) вычисляется как 10% от высоты экрана.
- Может использоваться для выдвигания шторки.

### Пример использования

```python
# Свайп снизу вверх на экране
app.swipe_bottom_to_top()
```


## Метод: `swipe_right_to_left()`

Этот метод выполняет свайп (перетаскивание) с правой части экрана к левой.

### Параметры

Метод не принимает параметров.

### Возвращаемое значение

- `None`

### Примечания

- Метод использует функцию `adb.get_screen_resolution()` для определения размера экрана.
- Позиция начала свайпа (`start_position`) вычисляется как 90% от ширины экрана.
- Позиция конца свайпа (`end_position`) вычисляется как 10% от ширины экрана.

### Пример использования

```python
# Свайп справа налево на экране
app.swipe_right_to_left()
```

## Метод: `swipe_left_to_right()`

Этот метод выполняет свайп (перетаскивание) с левой части экрана к правой.

### Параметры

Метод не принимает параметров.

### Возвращаемое значение

- `None`

### Примечания

- Метод использует функцию `adb.get_screen_resolution()` для определения размера экрана.
- Позиция начала свайпа (`start_position`) вычисляется как 10% от ширины экрана.
- Позиция конца свайпа (`end_position`) вычисляется как 90% от ширины экрана.

### Пример использования

```python
# Свайп слева направо на экране
app.swipe_left_to_right()
```


## Метод: `wait_for()`

Этот метод ожидает появления на экране указанного локатора или изображения.

### Параметры

- `locator`: Локатор(ы), которые нужно ожидать. Может быть одним локатором или списком локаторов. Принимает форматы, аналогичные `start_position` в методе `swipe()`. По умолчанию None.
- `image`: Изображение(я), которые нужно ожидать. Может быть одним изображением или списком изображений. Принимает строку, массив байтов (bytes), массив NumPy (np.ndarray) или объект класса Image.Image. По умолчанию None.
- `timeout`: Максимальное время ожидания в секундах. По умолчанию 10.
- `contains`: Если True, проверяет, содержит ли элемент указанный локатор. Если False, проверяет, точно ли соответствует элемент указанному локатору. По умолчанию True.
- `full_image`: Основное изображение, на котором будет искаться `image`. Принимает строку, массив байтов (bytes), массив NumPy (np.ndarray) или объект класса Image.Image. По умолчанию None.

### Возвращаемое значение

- `bool`: True, если элемент(ы) или изображение(я) найдены в течение периода ожидания, иначе False.

### Примечания

- Этот метод использует приватный метод `_wait_for()`, который реализует основную логику ожидания.

### Пример использования

```python
# Ожидание появления элемента по локатору
app.wait_for(locator=('xpath', '//button[@id="submit"]'), timeout=30)

# Ожидание появления изображения
app.wait_for(image='image.png', timeout=20)

# Ожидание появления нескольких элементов и изображений
app.wait_for(locator=[('id', 'button1'), ('id', 'button2')], image=['image1.png', 'image2.png'], timeout=40)
```


## Метод: `wait_for_not()`

Этот метод ожидает, пока указанный локатор или изображение не исчезнет с экрана или из DOM.

### Параметры

- `locator`: Локатор(ы), которые нужно ожидать. Может быть одним локатором или списком локаторов. Принимает форматы, аналогичные `start_position` в методе `swipe()`. По умолчанию None.
- `image`: Изображение(я), которые нужно ожидать. Может быть одним изображением или списком изображений. Принимает строку, массив байтов (bytes), массив NumPy (np.ndarray) или объект класса Image.Image. По умолчанию None.
- `timeout`: Максимальное время ожидания в секундах. По умолчанию 10.
- `contains`: Если True, проверяет, содержит ли элемент указанный локатор. Если False, проверяет, точно ли соответствует элемент указанному локатору. По умолчанию True.

### Возвращаемое значение

- `bool`: True, если элемент(ы) или изображение(я) исчезли в течение периода ожидания, иначе False.

### Пример использования

```python
# Ожидание исчезновения элемента по локатору
app.wait_for_not(locator=('xpath', '//button[@id="submit"]'), timeout=30)

# Ожидание исчезновения изображения
app.wait_for_not(image='image.png', timeout=20)

# Ожидание исчезновения нескольких элементов и изображений
app.wait_for_not(locator=[('id', 'button1'), ('id', 'button2')], image=['image1.png', 'image2.png'], timeout=40)
```


## Метод: `wait_return_true()`

Этот метод ожидает, когда другой метод вернет True.

### Параметры

- `method`: ссылка на метод, который мы ожидаем.
- `timeout`: максимальное время ожидания в секундах. По умолчанию равно 10.

### Возвращаемое значение

- `bool`: возвращает True, если метод возвращает True в течение периода времени, указанного в timeout. В противном случае возвращает False.

### Пример использования

```python
# Ожидаем, когда метод `check_login_status` вернет True в течение 20 секунд
result = AppiumExtended.wait_return_true(obj.check_login_status, timeout=20)

# Если `check_login_status` вернет True в течение 20 секунд, тогда `result` будет True, иначе `result` будет False.

app.wait_return_true(obj.is_connected, timeout=30)
```

Обратите внимание, что это статический метод, что означает, что он принадлежит классу, а не экземпляру класса. Это значит, что вам не нужен экземпляр класса, чтобы вызвать этот метод. Вы можете просто вызвать его на самом классе, как показано в примере выше.


## Метод: `draw_by_coordinates()`

Этот метод рисует прямоугольник на указанном изображении или скриншоте экрана. Прямоугольник задается координатами или верхней левой и нижней правой точками. Результирующее изображение сохраняется по указанному пути.

### Параметры

- `image`: Изображение, на котором будет рисоваться прямоугольник. Может быть представлено в форматах bytes, str (путь к файлу) или PIL Image. Если не указано, используется скриншот экрана. По умолчанию равно None.
- `coordinates`: Координаты прямоугольника в виде кортежа (x1, y1, x2, y2). По умолчанию равно None.
- `top_left`: Координаты верхней левой точки прямоугольника в виде кортежа (x, y). По умолчанию равно None.
- `bottom_right`: Координаты нижней правой точки прямоугольника в виде кортежа (x, y). По умолчанию равно None.
- `path`: Путь для сохранения результирующего изображения. По умолчанию равно None.

### Возвращаемое значение

- `AppiumExtended`: Возвращает экземпляр класса `AppiumExtended` для дальнейших вызовов методов.

### Пример использования

```python
appium_extended = AppiumExtended(driver)
image = driver.get_screenshot_as_base64().encode('utf-8')
appium_extended.draw_by_coordinates(image=image, coordinates=(123, 123, 123, 123), path='pictures')
```

В этом примере мы делаем скриншот экрана, рисуем на нем прямоугольник с указанными координатами и сохраняем полученное изображение в директории "pictures".


## Метод: `input_by_virtual_keyboard()`

Этот метод пока не реализован. Ожидается, что он будет использоваться для поиска и возврата родительского элемента, который содержит определённый дочерний элемент.

### Параметры

На данный момент в методе нет параметров.

### Возвращаемое значение

На данный момент метод возвращает ошибку `NotImplementedError` при вызове, так как он ещё не реализован.

### Пример использования

```python
# Этот метод еще не реализован, поэтому его нельзя вызвать.
```

### Дополнительная информация

В текущей реализации метод возвращает исключение `NotImplementedError` с сообщением "This method is not implemented yet". Это означает, что метод ещё не реализован. Предполагается, что в будущем он будет реализован для ввода данных с помощью виртуальной клавиатуры.


# class WebElementExtended

`WebElementExtended` - это класс, расширяющий базовый класс `WebElement` дополнительными возможностями. Он объединяет несколько классов, предоставляя различные методы взаимодействия с веб-элементами.
Инициализируется в AppiumExtended.

## Метод: `get_element()`

Этот метод извлекает элемент из другого элемента. Должен принимать как минимум либо локатор, либо значения параметров by и value.

### Параметры

- `locator`: Определяет локатор элемента. Может быть кортежем, WebElement, словарем или строкой.
- Кортеж: Локатор в форме ('стратегия', 'значение'), например, ('xpath', '//*'), ('id', 'elem_id') и т.д.
- WebElement / WebElementExtended: Объект веб-элемента.
- Словарь: Содержит пары атрибут: значение элемента, например, {'text':'foo', 'enabled':'true'}.
- Строка: Путь до файла с изображением элемента.
- По умолчанию: None.
- `by`: Тип локатора для поиска элемента. Используется в связке с параметром `value`. Может быть MobileBy, AppiumBy, By или строкой. По умолчанию: None.
- `value`: Значение локатора или словарь аргументов, если используется AppiumBy.XPATH. Может быть строкой, словарем или None. По умолчанию: None.
- `timeout_elem`: Максимальное время ожидания элемента в секундах. По умолчанию: 10.
- `timeout_method`: Максимальное время ожидания выполнения метода поиска элемента в секундах. По умолчанию: 600.
- `elements_range`: Ограничивает поиск элемента в указанном диапазоне (для поиска по изображению). Может быть кортежем, списком, словарем или None. По умолчанию: None.
- `contains`: Если True, проверяет, содержит ли элемент указанные атрибуты. Если False, проверяет, точно ли соответствует элемент указанным атрибутам. По умолчанию: True.

### Возвращаемое значение

- `WebElementExtended` или `None`: Возвращает WebElementExtended, если элемент был найден в течение указанного времени ожидания, в противном случае возвращает None.

### Примечания

- Этот метод использует внутренний метод для реализации основной логики поиска элементов.

### Пример использования

```python
# Ожидание появления элемента по локатору
inner_element = element.get_element(locator=("id", "foo"), timeout_elem=30)

# Ожидание появления элемента по WebElement
inner_element = element.get_element(locator=element, timeout_elem=20)

# Ожидание появления нескольких элементов и изображений
inner_element = element.get_element(locator={'text': 'foo'}, elements_range={'class':'android.widget.FrameLayout', 'package':'ru.app.debug'}, timeout_elem=40)
```

## Метод: `get_attributes()`

Этот метод получает атрибуты элемента. Если хотя бы один из желаемых атрибутов не найден, метод возвращает все атрибуты элемента.

### Параметры

- `desired_attributes`: Список названий атрибутов, которые нужно получить. Если параметр не указан, метод вернет все атрибуты элемента. По умолчанию: None.

### Возвращаемое значение

- `dict`: Словарь, содержащий атрибуты элемента и их значения. Если указан `desired_attributes` и соответствующие атрибуты найдены у элемента, возвращает словарь только с запрашиваемыми атрибутами. Если `desired_attributes` не указан или желаемый атрибут не найден, возвращает словарь со всеми атрибутами.

### Пример использования

```python
# Получение атрибутов 'text', 'bounds', 'class' у элемента
attributes = element.get_attributes(['text', 'bounds', 'class'])

# Получение всех атрибутов элемента
all_attributes = element.get_attributes()
```

## Метод: `click()`

Этот метод осуществляет нажатие на заданный элемент.

### Параметры

- `duration`: Время нажатия в секундах. Если параметр равен нулю, осуществляется обычное нажатие, иначе происходит нажатие с удержанием на указанное количество секунд. По умолчанию равно 0.
- `decorator_args`: Параметры для декоратора, включая время ожидания нового окна (`timeout_window`) и количество попыток нажатия (`tries`). Используется только при `wait = True`. По умолчанию None.
- `wait`: Флаг, указывающий, следует ли ожидать изменения окна после нажатия. Если `True`, будет использован метод `_click_to_element_and_wait()`, иначе `_click_to_element()`. По умолчанию False.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, представляющий элемент, на котором было произведено действие.
- В случае, если не удалось выполнить действие, генерируется AssertionError.

### Примечания

- В случае, если указан `wait = True` и не предоставлены `decorator_args`, используются стандартные параметры декоратора: `timeout_window` равно 5 и `tries` равно 5.

### Пример использования

```python
# Нажатие на элемент с ожиданием изменения окна и кастомными параметрами декоратора
decorator_args = {"timeout_window": 5, "tries": 5}
element.click(duration=0, wait=True, decorator_args=decorator_args)
```

## Метод: `double_click()`

Этот метод выполняет двойное нажатие (double click) на заданный элемент.

### Параметры

- `decorator_args`: Параметры для декоратора, включая время ожидания нового окна (`timeout_window`) и количество попыток нажатия (`tries`). Используется только при `wait = True`. По умолчанию `timeout_window` равно 5 и `tries` равно 5.
- `wait`: Флаг, указывающий, следует ли ожидать изменения окна после нажатия. Если `True`, будет использован метод `_double_click_to_element_and_wait()`, иначе `_double_click_to_element()`. По умолчанию False.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, представляющий элемент, на котором было произведено действие.
- В случае, если не удалось выполнить действие, генерируется AssertionError.

### Примечания

- В случае, если указан `wait = True` и не предоставлены `decorator_args`, используются стандартные параметры декоратора: `timeout_window` равно 5 и `tries` равно 5.

### Пример использования

```python
# Двойное нажатие на элемент без ожидания изменения окна
element.double_click(wait=False)

# Двойное нажатие на элемент с ожиданием изменения окна и кастомными параметрами декоратора
decorator_args = {"timeout_window": 7, "tries": 3}
element.double_click(wait=True, decorator_args=decorator_args)
```

## Метод: `click_and_move()`

Этот метод нажимает левую кнопку мыши, перемещает курсор к указанной цели и отпускает кнопку.

### Параметры

- `locator`: Локатор для поиска целевого элемента на веб-странице. Он может быть кортежем, `WebElement`, `WebElementExtended`, словарем или строкой. Не обязательный параметр.
- `x`: Абсолютная координата по оси X для перемещения курсора. Не обязательный параметр.
- `y`: Абсолютная координата по оси Y для перемещения курсора. Не обязательный параметр.
- `direction`: Направление в градусах для перемещения курсора, где 0/360 - вверх, 90 - вправо, 180 - вниз, 270 - влево. Не обязательный параметр.
- `distance`: Расстояние в пикселях для перемещения курсора. Не обязательный параметр.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, представляющий элемент, на котором было произведено действие.
- В случае, если не удалось выполнить действие, генерируется AssertionError.

### Пример использования

```python
# Кликнуть и переместить к элементу, найденному по локатору
element.click_and_move(locator="//button[@id='submit']")

# Кликнуть и переместить на указанные координаты
element.click_and_move(x=100, y=200)

# Кликнуть и переместить в указанном направлении на указанное расстояние
element.click_and_move(direction=90, distance=100)
```

### Примечание

Целью перемещения может быть WebElement, абсолютные координаты (x, y) или направление и расстояние. Если предоставлены направление и расстояние, функция вычисляет целевую позицию на основе вектора, определенного этими значениями. Если предоставлены абсолютные координаты (x, y), курсор перемещается в указанные позиции. Если предоставлен локатор, функция перемещается к найденному элементу на веб-странице.

## Метод: `adb_tap()`

Deprecated!
Метод устарел. Будет удален в следующих версиях.
Вместо него будет реализован метод выполняющий нажатие через driver.execute_script()

Этот метод выполняет нажатие на элемент, используя ADB (Android Debug Bridge).


### Параметры

- `decorator_args`: Дополнительные аргументы для использования в декораторе. Это словарь, который может содержать следующие ключи:
- `timeout_window`: Время ожидания нового окна (умножается на количество попыток).
- `tries`: Количество попыток нажатия (по умолчанию 3).
Этот параметр не обязателен.
- `wait`: Флаг, указывающий, нужно ли ожидать изменения окна. Необязательный параметр, по умолчанию False.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, представляющий элемент, на котором было произведено действие.
- В случае, если не удалось выполнить действие, генерируется AssertionError.

### Пример использования

```python
# Нажать на элемент с помощью ADB и не ожидать изменения окна
element.adb_tap()

# Нажать на элемент с помощью ADB и ожидать изменения окна
element.adb_tap(wait=True)

# Нажать на элемент с помощью ADB, ожидать изменения окна и установить время ожидания и количество попыток
element.adb_tap(decorator_args={"timeout_window": 5, "tries": 5}, wait=True)
```

### Примечание

ADB (Android Debug Bridge) - это инструмент командной строки, который используется для взаимодействия с устройством. В данном контексте он используется для симуляции взаимодействия пользователя с интерфейсом Android.

## Метод: `adb_multi_tap()`

Этот метод выполняет многократные нажатия (обычно два или три) на элемент, используя ADB (Android Debug Bridge).

### Аргументы

- `decorator_args (dict, optional)`: Дополнительные аргументы для декоратора. Если `None`, то будут преобразованы в `decorator_args = {"timeout_window": 5, "tries": 5}`, где `timeout_window` - время ожидания изменения окна в секундах, а `tries` - количество попыток выполнения метода для изменения окна.
- `wait (bool, optional)`: Флаг, указывающий, нужно ли ожидать изменение окна после нажатия. По умолчанию `False`.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, представляющий элемент, на котором было произведено действие.
- В случае, если не удалось выполнить действие, генерируется AssertionError.

### Пример использования

```python
# Выполнить многократные нажатия на элемент с помощью ADB
element.adb_multi_tap(decorator_args={"timeout_window": 10, "tries": 3}, wait=True)
```

### Примечание

ADB (Android Debug Bridge) - это инструмент командной строки, который используется для взаимодействия с устройством. В данном контексте он используется для симуляции взаимодействия пользователя с интерфейсом Android. Многократные нажатия могут быть полезны для выделения текста или активации специальных функций в приложении.

## Метод: `adb_swipe()`

Этот метод выполняет свайп (прокрутку) на элементе или по определенному направлению, используя ADB (Android Debug Bridge).

### Аргументы

- `locator (Union[Tuple, WebElement, 'WebElementExtended', Dict[str, str], str], optional)`: Локатор элемента, к которому необходимо прокрутить. Это может быть `Tuple`, `WebElement`, `WebElementExtended`, словарь с `str` или просто `str`. Если `None`, прокрутка производится от центра корневого элемента.
- `x (int, optional)`: Координата X целевой позиции прокрутки.
- `y (int, optional)`: Координата Y целевой позиции прокрутки.
- `direction (int, optional)`: Направление прокрутки в градусах (от 0 до 360).
- `distance (int, optional)`: Расстояние прокрутки в пикселях.
- `duration (int, optional)`: Длительность прокрутки в секундах. По умолчанию равна 1.
- `contains (bool, optional)`: Флаг, указывающий, должен ли локатор содержать текст элемента. По умолчанию `True`.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, представляющий элемент, на котором было произведено действие.
- В случае, если не удалось выполнить действие, генерируется AssertionError.

### Пример использования

```python
# Прокрутить до элемента с текстом "Submit"
element.adb_swipe(locator="Submit", duration=2)

# Прокрутить вниз на 500 пикселей за 1 секунду
element.adb_swipe(direction=180, distance=500, duration=1)
```

### Примечание

ADB (Android Debug Bridge) - это инструмент командной строки, который используется для взаимодействия с устройством. В данном контексте он используется для симуляции взаимодействия пользователя с интерфейсом Android. Прокрутка может быть полезной для навигации по странице или меню приложения.

## Метод: `tap()`

Этот метод выполняет нажатие (tap) на центре данного веб-элемента.

### Аргументы

- `duration (int, optional)`: Длительность нажатия в миллисекундах. По умолчанию равна 0 (моментальное нажатие).
- `decorator_args (dict, optional)`: Дополнительные аргументы для использования в декораторе. По умолчанию равно `None`. Если необходимо ожидание результата после нажатия, в словаре можно указать "timeout_window" - время ожидания изменения окна, и "tries" - количество попыток для изменения окна.
- `wait (bool, optional)`: Флаг, указывающий, следует ли ожидать результат после нажатия. По умолчанию равно `False`.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, представляющий элемент, на котором было произведено действие.
- В случае, если не удалось выполнить действие, генерируется AssertionError.

### Пример использования

```python
# Моментальное нажатие на элемент
element.tap()

# Нажатие на элемент на протяжении 500 миллисекунд
element.tap(duration=500)

# Нажатие на элемент с ожиданием изменения окна в течение 5 секунд
element.tap(duration=500, decorator_args={"timeout_window": 5, "tries": 5}, wait=True)
```

### Примечание

Методы `_tap`, `_tap_to_element_and_wait`, `_tap_to_element` и `__tap` используются внутри этого метода для выполнения нажатия и обработки различных сценариев, связанных с ожиданием результатов и обработкой исключений.

## Метод: `double_tap()`

Этот метод выполняет двойное нажатие (double tap) на центре данного веб-элемента.

### Аргументы

- `decorator_args (dict, optional)`: Дополнительные аргументы для использования в декораторе. По умолчанию равно `None`. Если необходимо ожидание результата после нажатия, в словаре можно указать "timeout_window" - время ожидания изменения окна, и "tries" - количество попыток для изменения окна.
- `wait (bool, optional)`: Флаг, указывающий, следует ли ожидать результат после нажатия. По умолчанию равно `False`.
- `pause (float, optional)`: Пауза между двумя нажатиями в секундах. По умолчанию равно 0.2.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, представляющий элемент, на котором было произведено действие.
- В случае, если не удалось выполнить действие, генерируется AssertionError.

### Пример использования

```python
# Двойное нажатие на элемент с паузой в 0.3 секунды между нажатиями
element.double_tap(pause=0.3)

# Двойное нажатие на элемент с ожиданием изменения окна в течение 5 секунд
element.double_tap(decorator_args={"timeout_window": 5, "tries": 5}, wait=True, pause=0.3)
```

### Примечание

Методы `_double_tap`, `_double_tap_to_element_and_wait`, `_double_tap_to_element` и `__double_tap` используются внутри этого метода для выполнения двойного нажатия и обработки различных сценариев, связанных с ожиданием результатов и обработкой исключений.

## Метод: `tap_and_move()`

Этот метод выполняет операцию "нажать и переместить" на веб-элементе или на указанных координатах.

### Аргументы

- `locator (Union[Tuple, WebElement, 'WebElementExtended', Dict[str, str], str], optional)`: Локатор элемента, на который будет выполнено нажатие и перемещение. По умолчанию равно `None`.
- `x (int, optional)`: Координата X для нажатия и перемещения. По умолчанию равно `None`.
- `y (int, optional)`: Координата Y для нажатия и перемещения. По умолчанию равно `None`.
- `direction (int, optional)`: Направление перемещения в градусах (0 - вверх, 90 - вправо, 180 - вниз, 270 - влево). По умолчанию равно `None`.
- `distance (int, optional)`: Расстояние перемещения в пикселях. По умолчанию равно `None`.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, представляющий элемент, на котором было произведено действие.
- В случае, если не удалось выполнить действие, генерируется AssertionError.

### Пример использования

```python
# Нажатие и перемещение на элемент с локатором
element.tap_and_move(locator=("xpath", "//div[@class='target']"))

# Нажатие и перемещение к координатам (50, 100)
element.tap_and_move(x=50, y=100)

# Нажатие и перемещение на расстояние 200 пикселей вниз
element.tap_and_move(direction=180, distance=200)
```

### Примечание

Метод `_tap_and_move` используется внутри этого метода для выполнения нажатия и перемещения, обработки различных сценариев в зависимости от предоставленных аргументов и обработки исключений.

## Метод: `get_elements()`

Этот метод обеспечивает поиск элементов в элементе.

### Аргументы

- `locator (Union[Tuple, List[WebElement], Dict[str, str], str], optional)`: Локатор элементов. Может быть кортежем, списком Веб-Элементов, словарем с атрибутом и значением, или строкой как путь до файла с изображением элемента. По умолчанию равно `None`.
- `by (Union[MobileBy, AppiumBy, By, str], optional)`: Тип локатора для поиска элемента (всегда в связке с `value`). По умолчанию равно `None`.
- `value (Union[str, Dict, None], optional)`: Значение локатора или словарь аргументов, если используется `AppiumBy.XPATH`. По умолчанию равно `None`.
- `timeout_elements (int, optional)`: Время ожидания для поиска каждого отдельного элемента. По умолчанию равно `10`.
- `timeout_method (int, optional)`: Общее время ожидания метода. По умолчанию равно `600`.
- `elements_range (Union[Tuple, List[WebElement], Dict[str, str], None], optional)`: Диапазон для поиска элементов. По умолчанию равно `None`.
- `contains (bool, optional)`: Если `True`, то поиск будет осуществляться по фрагменту текста или атрибута, а не их полному соответствию. По умолчанию равно `True`.

### Возвращаемое значение

- Возвращает список экземпляров `WebElementExtended`, представляющих найденные элементы. В случае, если элементы не найдены, возвращает пустой список.

### Пример использования

```python
# Поиск элементов по ID
elements = app.get_elements(locator=("id", "foo"))

# Поиск элементов по тексту
elements = app.get_elements(locator={'text': 'foo'})

# Поиск элементов по изображению
elements = app.get_elements(locator='/path/to/file/pay_agent.png')

# Поиск элементов с использованием типа локатора и значения
elements = app.get_elements(by="id", value="ru.sigma.app.debug:id/backButton")
```

## Метод: `scroll_down()`

Этот метод выполняет скроллинг элемента вниз. Тап и ведение от нижнего внутреннего элемента до верхнего внутреннего элемента.

### Аргументы

- `locator (Union[Tuple, WebElementExtended, Dict[str, str], str], optional)`: Локатор или элемент для прокрутки. Может быть кортежем, экземпляром `WebElementExtended`, словарем с атрибутом и значением, или строкой. Если не указан, то будет вычислен автоматически. По умолчанию равно `None`.
- `duration (int, optional)`: Продолжительность прокрутки в миллисекундах. Если не указана, прокрутка будет произведена без задержки. По умолчанию равно `None`.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, если скроллинг выполнен успешно.
- В случае, если не удалось выполнить действие, генерируется AssertionError.

### Пример использования

```python
# Скроллинг элемента с заданным локатором
app.scroll_down(locator=("id", "foo"), duration=1000)

# Скроллинг конкретного элемента
element = app.get_element(locator=("id", "foo"))
app.scroll_down(locator=element, duration=1000)

# Скроллинг элемента с заданным атрибутом и значением
app.scroll_down(locator={'class': 'foo'}, duration=1000)
```

## Метод: `scroll_up()`

Этот метод выполняет скроллинг элемента вверх. Тап и ведение от верхнего внутреннего элемента до нижнего внутреннего элемента.

### Аргументы

- `locator (Union[Tuple, WebElementExtended, Dict[str, str], str], optional)`: Локатор или элемент для прокрутки. Может быть кортежем, экземпляром `WebElementExtended`, словарем с атрибутом и значением, или строкой. Если не указан, то будет вычислен автоматически. По умолчанию равно `None`.
- `duration (int, optional)`: Продолжительность прокрутки в миллисекундах. Если не указана, прокрутка будет произведена без задержки. По умолчанию равно `None`.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, если скроллинг выполнен успешно.
- В случае, если не удалось выполнить действие, генерируется AssertionError.

### Пример использования

```python
# Скроллинг элемента с заданным локатором вверх
app.scroll_up(locator=("id", "foo"), duration=1000)

# Скроллинг конкретного элемента вверх
element = app.get_element(locator=("id", "foo"))
app.scroll_up(locator=element, duration=1000)

# Скроллинг элемента с заданным атрибутом и значением вверх
app.scroll_up(locator={'class': 'foo'}, duration=1000)
```

## Метод: `scroll_to_bottom()`

Этот метод выполняет скроллинг элемента до самого нижнего положения.

### Аргументы

- `locator (Union[Tuple, WebElementExtended, Dict[str, str], str], optional)`: Локатор или элемент для прокрутки. Может быть кортежем, экземпляром `WebElementExtended`, словарем с атрибутом и значением, или строкой. По умолчанию равно `None`.
- `timeout_method (int, optional)`: Время ожидания выполнения метода в секундах. Если время ожидания истекает, а скроллинг не достигает нижнего положения, метод возвращает ошибку. По умолчанию равно `120`.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, если скроллинг выполнен успешно. В случае ошибки выбрасывает исключение AsserionError.

### Пример использования

```python
# Скроллинг элемента с заданным локатором до нижнего положения
app.scroll_to_bottom(locator=("id", "foo"), timeout_method=120)

# Скроллинг конкретного элемента до нижнего положения
element = app.get_element(locator=("id", "foo"))
app.scroll_to_bottom(locator=element, timeout_method=120)

# Скроллинг элемента с заданным атрибутом и значением до нижнего положения
app.scroll_to_bottom(locator={'class': 'foo'}, timeout_method=120)
```

## Метод: `scroll_to_top()`

Этот метод выполняет скроллинг элемента до самого верхнего положения.

### Аргументы

- `locator (Union[Tuple, WebElementExtended, Dict[str, str], str], optional)`: Локатор или элемент для прокрутки. Может быть кортежем, экземпляром `WebElementExtended`, словарем с атрибутом и значением, или строкой. По умолчанию равно `None`.
- `timeout_method (int, optional)`: Время ожидания выполнения метода в секундах. Если время ожидания истекает, а скроллинг не достигает верхнего положения, метод возвращает ошибку. По умолчанию равно `120`.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, если скроллинг выполнен успешно. В случае ошибки выбрасывает исключение AssertionError.

### Пример использования

```python
# Скроллинг элемента с заданным локатором до верхнего положения
app.scroll_to_top(locator=("id", "foo"), timeout_method=120)

# Скроллинг конкретного элемента до верхнего положения
element = app.get_element(locator=("id", "foo"))
app.scroll_to_top(locator=element, timeout_method=120)

# Скроллинг элемента с заданным атрибутом и значением до верхнего положения
app.scroll_to_top(locator={'class': 'foo'}, timeout_method=120)
```


## Метод: `scroll_until_find()`

Этот метод выполняет скроллинг элемента вниз и вверх, пока не найдет элемент, указанный в аргументе `locator`, или пока не истечет таймаут.

### Аргументы

- `locator (Union[Tuple, WebElementExtended, Dict[str, str], str])`: Локатор или элемент, который следует найти. Может быть кортежем, экземпляром `WebElementExtended`, словарем с атрибутом и значением, или строкой.
- `roll_locator (Union[Tuple, WebElementExtended, Dict[str, str], str], optional)`: Локатор или элемент, который следует прокручивать. Если не указан, прокручивается первый дочерний элемент. Может быть кортежем, экземпляром `WebElementExtended`, словарем с атрибутом и значением, или строкой. По умолчанию равно `None`.
- `timeout_method (int, optional)`: Время ожидания выполнения метода в секундах. Если время ожидания истекает, а элемент не найден, метод возвращает `None`. По умолчанию равно `120`.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, если элемент найден. Возвращает `None`, если элемент не найден в течение заданного времени.

### Пример использования

```python
# Поиск элемента с заданным локатором, прокручивая элемент с другим локатором
app.scroll_until_find(locator=("id", "target"), roll_locator=("id", "foo"), timeout_method=120)

# Поиск конкретного элемента, прокручивая другой конкретный элемент
element_to_find = app.get_element(locator=("id", "target"))
element_to_scroll = app.get_element(locator=("id", "foo"))
app.scroll_until_find(locator=element_to_find, roll_locator=element_to_scroll, timeout_method=120)

# Поиск элемента с заданным атрибутом и значением, прокручивая элемент с другим атрибутом и значением
app.scroll_until_find(locator={'class': 'target'}, roll_locator={'class': 'foo'}, timeout_method=120)
```

## Метод: `get_parent()

Этот метод возвращает первый родительский элемент текущего элемента в дереве DOM.

### Аргументы

Метод не принимает никаких аргументов.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, который представляет родительский элемент.

### Пример использования

```python
# Получение родительского элемента
parent_element = app.get_parent()
```

## Метод: `get_parents()

Этот метод возвращает все родительские элементы текущего элемента в дереве DOM, начиная от ближайшего и до корневого элемента.

### Аргументы

Метод не принимает никаких аргументов.

### Возвращаемое значение

- Возвращает список экземпляров `WebElementExtended`, каждый из которых представляет родительский элемент на различных уровнях вверх по дереву DOM.

### Пример использования

```python
# Получение всех родительских элементов
parent_elements = app.get_parents()
```

## Метод: `get_sibling()

Этот метод возвращает соседний (родственный) элемент текущего элемента, соответствующий заданным атрибутам. Возвращаются только непосредственные соседи (братья или сестры) в пределах того же родительского элемента.

### Аргументы

- `attributes` (`dict`): Словарь, содержащий атрибуты и их значения, которые должны быть найдены у искомого соседнего элемента. Например, `{'class': 'myClass', 'name': 'myName'}` ищет элемент, у которого атрибут `class` равен `myClass` и `name` равен `myName`.

- `contains` (`bool`, необязательный): Флаг, указывающий, использовать ли функцию `contains` XPath для атрибутов. Если `True`, метод будет искать элементы, значение атрибута которых содержит указанное значение (а не полное совпадение). По умолчанию равно `True`.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, представляющий найденный соседний элемент. Если такой элемент не найден, возвращается `None`.

### Пример использования

```python
# Получение соседнего элемента с классом 'myClass'
sibling_element = app.get_sibling({'class': 'myClass'})

# Получение соседнего элемента, имя которого содержит 'myName'
sibling_element = app.get_sibling({'name': 'myName'}, contains=True)
```

## Метод: `get_siblings()

Этот метод возвращает все соседние (родственные) элементы текущего элемента. Возвращаются только непосредственные соседи (братья или сестры) в пределах того же родительского элемента.

### Аргументы

Метод не требует аргументов.

### Возвращаемое значение

- Возвращает список экземпляров `WebElementExtended`, каждый из которых представляет одного из родственных элементов текущего элемента. Если таких элементов не найдено, возвращается пустой список.

### Пример использования

```python
# Получение всех соседних элементов текущего элемента
sibling_elements = app.get_siblings()
```

## Метод: `get_cousin()

Этот метод предназначен для поиска "кузена" текущего элемента в дереве DOM. Кузен в данном контексте определяется как элемент, находящийся на одинаковом уровне вложенности от общего предка.

### Аргументы

- `ancestor` - Предок, относительно которого определяется "кузенство". Может быть представлен в виде кортежа (списка атрибутов и их значений), экземпляра WebElement или WebElementExtended, словаря (атрибутов и их значений) или строки (XPath выражения).

- `cousin` - Словарь атрибутов, определяющий искомого кузена. Ключи словаря - это названия атрибутов, значения - соответствующие значения этих атрибутов.

- `contains` - Булевый флаг, который определяет, следует ли использовать функцию `contains` при формировании XPath выражения для поиска кузена. Если `True`, то будет искаться частичное совпадение атрибутов. Если `False`, то будет искаться полное совпадение. По умолчанию `True`.

### Возвращаемое значение

- Возвращает экземпляр `WebElementExtended`, представляющий кузена текущего элемента. Если кузен не найден, возвращается `None`.

### Пример использования

```python
# Ищем кузена текущего элемента, имеющего класс 'desired-class' и находящегося на одинаковой глубине вложенности от общего предка с классом 'parent-class'
cousin_element = app.get_cousin(ancestor={'class': 'parent-class'}, cousin={'class': 'desired-class'})
```

## Метод: `get_cousins()

Этот метод предназначен для поиска "кузенов" текущего элемента в дереве DOM. Кузен в данном контексте определяется как элемент, находящийся на одинаковом уровне вложенности от общего предка.

### Аргументы

- `ancestor` - Предок, относительно которого определяется "кузенство". Может быть представлен в виде кортежа (списка атрибутов и их значений), экземпляра WebElement или WebElementExtended, словаря (атрибутов и их значений) или строки (XPath выражения).

- `cousin` - Словарь атрибутов, определяющий искомого кузена. Ключи словаря - это названия атрибутов, значения - соответствующие значения этих атрибутов.

- `contains` - Булевый флаг, который определяет, следует ли использовать функцию `contains` при формировании XPath выражения для поиска кузенов. Если `True`, то будет искаться частичное совпадение атрибутов. Если `False`, то будет искаться полное совпадение. По умолчанию `True`.

### Возвращаемое значение

- Возвращает список экземпляров `WebElementExtended`, представляющих кузенов текущего элемента. Если кузены не найдены, возвращается пустой список.

### Пример использования

```python
# Ищем кузенов текущего элемента, имеющих класс 'desired-class' и находящихся на одинаковой глубине вложенности от общего предка с классом 'parent-class'
cousin_elements = app.get_cousins(ancestor={'class': 'parent-class'}, cousin={'class': 'desired-class'})
```

## Метод: `is_contains()

Этот метод проверяет, содержит ли текущий элемент другой элемент, определенный локатором `locator`.

### Аргументы

- `locator` - Локатор дочернего элемента. Может быть представлен в виде кортежа (списка атрибутов и их значений), экземпляра WebElement или WebElementExtended, словаря (атрибутов и их значений) или строки (XPath выражения).

- `contains` - Булевый флаг, который определяет, следует ли использовать функцию `contains` при формировании XPath выражения для поиска элемента. Если `True`, то будет искаться частичное совпадение атрибутов. Если `False`, то будет искаться полное совпадение. По умолчанию `True`.

### Возвращаемое значение

- Возвращает `True`, если текущий элемент содержит искомый дочерний элемент, и `False` в противном случае.

### Пример использования

```python
# Проверяем, содержит ли текущий элемент дочерний элемент с классом 'child-class'
if app.is_contains(locator={'class': 'child-class'}):
print("Child element is present")
else:
print("Child element is not present")
```

## Метод: `zoom()`

Вызывает `NotImplementedError` так как метод не реализован.
Этот метод в будущем реализует функцию увеличения (zoom) на элементе страницы.

### Аргументы

- `hold` - Булевый параметр, который определяет, следует ли удерживать увеличение после его выполнения. Если `True`, увеличение будет удерживаться. Если `False`, увеличение не будет удерживаться после выполнения действия.

### Возвращаемое значение

- Вызывает `NotImplementedError` так как метод не реализован.

### Пример использования

```python
Метод не реализован
```

## Метод: `unzoom()`

Вызывает `NotImplementedError` так как метод не реализован.
Этот метод в будущем реализует функцию увеличения (zoom) на элементе страницы.

### Аргументы

- `hold` - Булевый параметр, который определяет, следует ли удерживать увеличение после его выполнения. Если `True`, увеличение будет удерживаться. Если `False`, увеличение не будет удерживаться после выполнения действия.

### Возвращаемое значение

- Вызывает `NotImplementedError` так как метод не реализован.

### Пример использования

```python
Метод не реализован
```

## Метод: `get_center()

Этот метод вычисляет координаты центра текущего элемента страницы.

### Возвращаемое значение

- Возвращает кортеж в формате `(x, y)`, где `x` и `y` - это координаты центра элемента. Если во время выполнения произошла ошибка, метод вернёт `None`.

### Пример использования

```python
# Получаем координаты центра элемента
center_coordinates = element.get_center()

# Печатаем координаты центра
if center_coordinates is not None:
print("The center of the element is located at: ", center_coordinates)
else:
print("An error occurred while getting the center of the element.")
```

## Метод: `get_coordinates()

Этот метод используется для получения координат текущего элемента веб-страницы.

### Возвращаемое значение

- Возвращает кортеж в формате `(left, top, right, bottom)`, где:
- `left` - расстояние от левого края окна браузера до левого края элемента,
- `top` - расстояние от верхнего края окна браузера до верхнего края элемента,
- `right` - расстояние от левого края окна браузера до правого края элемента,
- `bottom` - расстояние от верхнего края окна браузера до нижнего края элемента.

Если во время выполнения произошла ошибка, метод вернёт `None`.

### Пример использования

```python
# Получаем координаты элемента
element_coordinates = element.get_coordinates()

# Печатаем координаты элемента
if element_coordinates is not None:
print("The coordinates of the element are: ", element_coordinates)
else:
print("An error occurred while getting the coordinates of the element.")
```


# class AppiumServer

## Описание класса

Класс `AppiumServer` предназначен для управления сервером Appium. Он позволяет запускать и останавливать сервер Appium с заданными параметрами, проверять его доступность и логировать процесс.

## Атрибуты

- `logger`: Объект для записи логов, основанный на настройках, указанных в `config.APPIUM_LOG_NAME`.

- `port`: Порт, на котором будет запущен сервер Appium. По умолчанию равен `4723`.

- `log_level`: Уровень детализации логирования. По умолчанию равен `'error'`.


## Конструктор

### `__init__()`

Инициализирует новый экземпляр класса `AppiumServer`.

**Параметры:**

- `port: int` - Порт, на котором будет запущен сервер Appium. По умолчанию равен `4723`.

- `log_level: str` - Уровень детализации логирования. По умолчанию равен `'error'`.

## Метод: `start()`

Этот метод запускает сервер Appium.

### Параметры

Метод не принимает параметров.

### Возвращаемое значение

- `bool`: Возвращает `True`, если сервер Appium был успешно запущен. В противном случае возвращает `False`.

### Пример использования

```python
# Запустить сервер Appium
is_started = app.start()
```

### Дополнительная информация

Метод запускает команду `appium server` с рядом параметров в отдельном подпроцессе, используя `subprocess.Popen`. Если процесс запуска успешен, метод возвращает `True`. В случае исключения типа `subprocess.CalledProcessError` или `OSError`, метод записывает ошибку в лог и возвращает `False`.

## Метод: `is_alive()`

Этот метод проверяет статус сервера Appium.

### Параметры

Метод не принимает параметров.

### Возвращаемое значение

- `bool`: Возвращает `True`, если сервер Appium доступен и готов к использованию. В противном случае возвращает `False`.

### Пример использования

```python
# Проверить статус сервера Appium
is_ready = app.is_alive()
```

### Дополнительная информация

Метод отправляет GET-запрос на "http://127.0.0.1:4723/wd/hub/sessions" для проверки статуса сервера Appium. Если сервер отвечает с кодом статуса 200, метод возвращает `True`. Если сервер отвечает с другим кодом статуса, метод записывает предупреждение в лог и возвращает `False`. В случае исключения `requests.exceptions.RequestException`, метод записывает ошибку в лог и возвращает `False`.

## Метод: `stop()`

Этот метод останавливает сервер Appium.

### Параметры

Метод не принимает параметров.

### Возвращаемое значение

- `bool`: Возвращает `True`, если сервер Appium был успешно остановлен. В противном случае возвращает `False`.

### Пример использования

```python
# Остановить сервер Appium
is_stopped = app.stop()
```

### Дополнительная информация

Метод запускает команду 'taskkill /F /IM node.exe' в подпроцессе, используя `subprocess.check_output`. Если процесс остановки успешен, метод возвращает `True`. В случае исключения типа `subprocess.CalledProcessError`, метод возвращает `False`.

## Метод: `wait_until_alive()`

Этот метод ожидает, пока сервер Appium не станет доступным.

### Параметры

- `timeout` (`int`, необязательный): Максимальное время ожидания в секундах, в течение которого метод будет проверять статус сервера. Значение по умолчанию: `60`.
- `poll` (`int`, необязательный): Интервал времени в секундах между проверками статуса сервера. Значение по умолчанию: `2`.

### Возвращаемое значение

- `bool`: Возвращает `True`, если сервер Appium стал доступным в течение заданного времени ожидания. В противном случае возвращает `False`.

### Пример использования

```python
# Ожидать, пока сервер Appium не станет доступным в течение 60 секунд с интервалом проверки 2 секунды
is_ready = app.wait_until_alive(timeout=60, poll=2)
```

### Дополнительная информация

Метод использует вспомогательный метод `is_alive()` для проверки статуса сервера. Он будет продолжать проверку статуса сервера каждые `poll` секунд в течение `timeout` секунд или до тех пор, пока сервер не станет доступным. Если сервер становится доступным в течение времени ожидания, метод возвращает `True`. Если сервер так и не становится доступным после истечения времени ожидания, метод возвращает `False`.


## class `AppiumNavigator`

Этот класс предоставляет функционал навигации для приложения, управляемого через сервер Appium.

### Атрибуты

- `app` (`AppiumExtended`): Экземпляр класса `AppiumExtended`, который предоставляет API для взаимодействия с сервером Appium.
- `graph_manager` (`AppiumGraph`): Объект для управления графом приложения.
- `logger` (`logging.Logger`): Логгер для записи логов.
- `image` (`AppiumImage`): Объект для работы с изображениями в контексте Appium.

## Конструктор

### `__init__()`

Инициализирует новый экземпляр класса `AppiumNavigator`.

**Параметры:**

- `app` (`AppiumExtended`): Экземпляр класса `AppiumExtended`, который предоставляет API для взаимодействия с сервером Appium.

## Метод: `add_page()`

Этот метод добавляет вершину в граф навигации приложения.

### Параметры

- `page` (`str`): Название страницы (экрана или окна), которую нужно добавить в граф.
- `edges` (`List[str]`): Список страниц (экранов или окон), к которым можно перейти с текущей страницы. Страницы представлены их названиями.

### Возвращаемое значение

Метод не возвращает значения.

### Пример использования

```python
# Добавить новую страницу в граф навигации приложения
navigator.add_page(page='HomePage', edges=['SettingsPage', 'ProfilePage'])
```

### Дополнительная информация

Метод использует `graph_manager` для добавления новой вершины в граф навигации приложения. Вершина представляет собой страницу (экран / окно) в приложении. Метод принимает название страницы и список других страниц, к которым можно перейти с текущей страницы.

## Метод: `navigate()`

Этот метод выполняет навигацию от текущей страницы к указанной целевой странице в приложении.

### Параметры

- `current_page` (`Type[YourPageClass]`): Класс текущей страницы, на которой находится пользователь.
- `destination_page` (`Type[YourPageClass]`): Класс целевой страницы, на которую пользователь хочет перейти.
- `timeout` (`int`, необязательный): Максимальное время ожидания перехода, по умолчанию 55 секунд.

### Возвращаемое значение

Метод не возвращает значения.

### Исключения

- `ValueError`: Если не удается найти путь от текущей страницы к целевой странице.

### Пример использования

```python
# Перейти с главной страницы на страницу настроек
navigator.navigate(current_page=HomePage, destination_page=SettingsPage)
```

### Дополнительная информация

Метод использует поиск пути и последовательное выполнение шагов навигации, чтобы перейти от текущей страницы к целевой. Если указанная целевая страница совпадает с текущей, никаких действий не выполняется.

Вначале метод находит путь от текущей страницы к целевой с использованием `find_path()`. Если путь не найден, генерируется исключение `ValueError`. После того как путь найден, метод `perform_navigation()` выполняет навигацию, следуя найденному пути.

Примечание: `YourPageClass` в параметрах `current_page` и `destination_page` следует заменить на конкретные классы страниц в вашем приложении.

## Метод: `find_path()`

Этот метод использует поиск в ширину (BFS) для нахождения пути от стартовой страницы до целевой.

### Параметры

- `start_page` (`Any`): Начальная страница поиска пути.
- `target_page` (`Any`): Целевая страница, которую нужно достичь.

### Возвращаемое значение

- `Optional[List[Any]]`: Список страниц, образующих путь от стартовой до целевой страницы. Если путь не найден, возвращает `None`.

### Пример использования

```python
# Найти путь от главной страницы до страницы настроек
path = navigator.find_path(start_page=HomePage, target_page=SettingsPage)
```

### Дополнительная информация

Метод обходит граф переходов между страницами, сохраняя текущий путь и посещенные страницы. Если стартовая страница совпадает с целевой, никаких действий не выполняется.

Вначале метод создает множество для отслеживания посещенных страниц и очередь для выполнения поиска в ширину. Затем, пока очередь не пуста, метод извлекает текущую страницу и путь от стартовой страницы до нее. Получает переходы (соседние страницы) для текущей страницы и проверяет каждую соседнюю страницу. Если соседняя страница является целевой, возвращает полный путь. Если соседняя страница не была посещена, добавляет ее в очередь для дальнейшего поиска. Если путь не найден, возвращает `None`.

Примечание: `start_page` и `target_page` должны быть конкретными классами страниц в вашем приложении.

## Метод: `perform_navigation()`

Этот метод выполняет навигацию по заданному пути.

### Параметры

- `path` (`List[Any]`): Список страниц, образующих путь для навигации. Каждый элемент списка представляет страницу, а порядок элементов в списке определяет последовательность переходов от одной страницы к другой.
- `timeout` (`int`, необязательный): Максимальное время ожидания перехода, по умолчанию 55 секунд.

### Возвращаемое значение

- `None`

### Пример использования

```python
# Предположим, мы уже нашли путь от главной страницы до страницы настроек
path = [HomePage, MenuPage, SettingsPage]
# Выполняем навигацию по этому пути
navigator.perform_navigation(path)
```

### Дополнительная информация

Метод принимает список страниц, который представляет собой путь для навигации. Он выполняет переходы между соседними страницами, чтобы достичь целевой страницы. Проходит по пути и выполняет переходы между соседними страницами. Если метод перехода между текущей и следующей страницами не найден, выводит сообщение об ошибке. После выполнения каждого перехода ожидает появления изображения целевой страницы.

Примечания:
- Элементы списка `path` должны быть конкретными классами страниц в вашем приложении.
- Рекомендуется вместо него использовать метод navigate()

# Пример карты приложения
`#app_map.py`
```python
from pages.page_1 import page_1
from pages.page_2 import page_2
from pages.page_3 import page_3
class ExampleAppMap(AppiumExtended):

def __init__(self):
super().__init__()
self.page_1 = None
self.page_2 = None
self.page_3 = None
self.driver = None
self.navigator: AppiumNavigator = None
self.current_path = os.path.dirname(os.path.abspath(inspect.getframeinfo(inspect.currentframe()).filename))
self.page_images_path = os.path.join(self.current_path, ConstMapPath.FOLDER_TRANSACTION_IMAGES)
self.pages_ndarray_images = None

def connect(self, capabilities: dict):
super().connect(capabilities=capabilities)
# LOGIC
self.navigator = AppiumNavigator(app=self)
# PAGES
self.page_1 = Page1(self)
self.page_2 = Page2(self)
self.page_3 = Page3(self)
# EDGES
self.page_1.edges = {
self.page_2: self.go_1_2,
}
self.page_2.edges = {
self.page_1: self.go_2_1,
self.page_3: self.go_2_3
}
self.page_3.edges = {
self.page_2 = self.go_3_2
}
# INIT PAGES
self.navigator.add_page(page=self.page_1,
edges=self.page_1.edges)
self.navigator.add_page(page=self.page_2,
edges=self.page_2.edges)
self.navigator.add_page(page=self.page_3,
edges=self.page_3.edges)
self.pages_ndarray_images = {
self.page_1: self._get_ndarray_images(self.page_1.page_images),
self.page_2: self._get_ndarray_images(self.page_2.page_images),
self.page_3: self._get_ndarray_images(self.page_3.page_images),
}

def go_1_2(self):
...

def go_2_1(self):
...

def go_2_3(self):
...

def go_3_2(self):
...
```

Структура файлов page:
-pages
-page_1
-action_images
action_image_1.png
action_image_2.png
-images
current_page_fragment_image_1.png
current_page_fragment_image_2.png
page_1.py

`#page_1.py`
```python
class Page1(PageBase):
edges: list

def __init__(self, app):
super().__init__(app)
self.app = app
self.current_path = os.path.dirname(os.path.abspath(inspect.getframeinfo(inspect.currentframe()).filename))
self.page_images_path = os.path.join(self.current_path, 'images')
self.page_action_images_path = os.path.join(self.current_path, 'action_images')
self.page_images = self._get_page_images(self.page_images_path)

def is_current_page(self) -> bool:
return self._is_current_page(self.page_images)

def some_logic_on_page(self):
...
```

`#page_base.py`
```python
class PageBase(object):
def __init__(self, app):
self.app: AppiumExtended = app
self.page_images_path: str
self.page_images: list[str]
self.logger = logging.getLogger(config.LOGGER_NAME)

def _is_current_page(self, page_images, max_attempts=3) -> bool:
attempts = 0

while attempts < max_attempts:
if len(page_images) == 0:
return False

all_images_found = True # Предполагаем, что все изображения найдены

for image in page_images:
if not self.app.image.is_image_on_the_screen(image=image):
all_images_found = False
break # Прерываем цикл, если хотя бы одно изображение не найдено

if all_images_found:
return True

attempts += 1
time.sleep(1) # Подождать 1 секунду перед следующей попыткой

return False

@staticmethod
def _get_page_images(page_images_path):
page_images = []
if os.path.exists(page_images_path):
page_images = os.listdir(page_images_path)
for index, image_name in enumerate(page_images):
page_images[index] = os.path.join(page_images_path, image_name)
return page_images
```


# class Aapt
Класс


## Метод: `get_package_name()`

Статический метод, получает название пакета APK-файла с помощью команды aapt. Используется для извлечения информации о пакете из файла APK.

### Параметры

- `path_to_apk`: Путь до APK-файла, из которого требуется извлечь название пакета. Должен быть строкой, содержащей путь к файлу.

### Возвращаемое значение

Возвращает строку, содержащую название пакета, извлеченное из APK-файла. Если название пакета не может быть извлечено, возвращается `None`.

### Пример использования

```python
package_name = get_package_name(path_to_apk="/path/to/apk/file.apk")
print(package_name)
```

### Дополнительная информация

Этот метод выполняет системную команду с использованием утилиты `aapt` (Android Asset Packaging Tool). В процессе работы создаются логи, которые сохраняются с использованием модуля `logging`.

### Исключения

Метод может генерировать исключения, если указанный файл APK не найден, не может быть прочитан или не содержит ожидаемой информации о пакете. Все такие исключения должны быть обработаны в вызывающем коде. Дополнительно, если утилита `aapt` не установлена или не доступна для вызова в системе, метод может не работать корректно.

## Метод: `get_launchable_activity()`

Статический метод, получает название запускаемой активности из APK-файла с помощью команды `aapt`. Используется для извлечения информации о запускаемой активности из файла APK.

### Параметры

- `path_to_apk`: Путь до APK-файла, из которого требуется извлечь название запускаемой активности. Должен быть строкой, содержащей путь к файлу.

### Возвращаемое значение

Возвращает строку, содержащую название запускаемой активности, извлеченное из APK-файла. Если название активности не может быть извлечено, возвращается `None`.

### Пример использования

```python
launchable_activity = YourClassName.get_launchable_activity(path_to_apk="/path/to/apk/file.apk")
print(launchable_activity)
```

### Дополнительная информация

Этот метод выполняет системную команду с использованием утилиты `aapt` (Android Asset Packaging Tool). В процессе работы создаются логи, которые сохраняются с использованием модуля `logging`.

### Исключения

Метод может генерировать исключения, если указанный файл APK не найден, не может быть прочитан или не содержит ожидаемой информации о запускаемой активности. Все такие исключения должны быть обработаны в вызывающем коде. Дополнительно, если утилита `aapt` не установлена или не доступна для вызова в системе, метод может не работать корректно.

Пожалуйста, замените `YourClassName` на имя вашего класса.



# class Terminal
Класс отвечает за работу с устройством, командами adb подаваемыми через Appium server.

## Метод: `adb_shell()`

Этот метод класса `Terminal` позволяет выполнить команду adb shell через драйвер Appium. Используется для взаимодействия с устройством на уровне adb.

### Параметры

- `command`: Команда adb shell, которую требуется выполнить. Должна быть строкой, представляющей собой команду adb shell.

- `args`: Аргументы команды adb shell. Должны быть представлены в виде строки. По умолчанию, значение этого параметра — пустая строка.

### Возвращаемое значение

Возвращает значение, возвращаемое драйвером Appium при выполнении скрипта. Тип возвращаемого значения может зависеть от конкретной команды adb shell, но, как правило, это строка, содержащая вывод выполненной команды.

### Пример использования

```python
output = Terminal(driver).adb_shell(command="pm list packages", args="-3")
print(output)
```

### Дополнительная информация

Этот метод использует возможности драйвера Appium для выполнения adb shell команд. В зависимости от команды и аргументов, которые передаются в этот метод, он может быть использован для выполнения широкого спектра задач, связанных с управлением устройством на уровне adb.

### Исключения

Метод может генерировать исключения, если указанная команда adb shell не может быть выполнена или возвращает ошибку. Все такие исключения должны быть обработаны в вызывающем коде.

## Метод: `push()`

Этот метод класса `Terminal` позволяет копировать файл или директорию с локальной машины на подключенное устройство через Appium сервер.

### Параметры

- `source`: Путь к копируемому файлу или директории на локальной машине. Должен быть представлен в виде строки.

- `destination`: Путь назначения на устройстве, куда будет скопирован файл или директория. Должен быть представлен в виде строки.

### Возвращаемое значение

Возвращает `True`, если файл или директория были успешно скопированы. В противном случае возвращается `False`.

### Пример использования

```python
terminal = Terminal(driver)
copy_result = terminal.push(source="/local/path/to/file.txt", destination="/device/path/to/file.txt")
if copy_result:
print("File was successfully copied.")
else:
print("File copying failed.")
```

### Дополнительная информация

Этот метод использует возможности драйвера Appium для копирования файлов или директорий на подключенное устройство. В случае возникновения ошибок в процессе копирования (например, если исходный файл не существует или назначение недоступно), метод возвращает `False` и записывает информацию об ошибке в лог.

### Исключения

Метод может генерировать исключение `IOError`, если возникают проблемы с чтением исходного файла или записью в целевую директорию на устройстве. Это исключение обрабатывается внутри метода, и информация о нем записывается в лог.

## Метод: `pull()`

Этот метод класса `Terminal` позволяет извлекать файл с подключенного устройства и сохранять его на локальной машине через Appium сервер.

### Параметры

- `source`: Путь к файлу на устройстве, который требуется извлечь. Должен быть представлен в виде строки.

- `destination`: Путь, по которому файл должен быть сохранен на локальной машине. Должен быть представлен в виде строки.

### Возвращаемое значение

Возвращает `True`, если файл успешно извлечен и сохранен на локальной машине. В противном случае возвращается `False`.

### Пример использования

```python
terminal = Terminal(driver)
pull_result = terminal.pull(source="/device/path/to/file.txt", destination="/local/path/to/file.txt")
if pull_result:
print("File was successfully pulled.")
else:
print("File pulling failed.")
```

### Дополнительная информация

Этот метод использует возможности драйвера Appium для извлечения файлов с подключенного устройства. Сначала он извлекает файл с устройства в виде строки в формате base64, затем декодирует эту строку и записывает полученные данные в файл по указанному локальному пути. Если в процессе возникают ошибки (например, если исходный файл не существует или назначение недоступно), метод возвращает `False` и записывает информацию об ошибке в лог.

### Исключения

Метод может генерировать исключение `IOError`, если возникают проблемы с записью файла на локальной машине. Это исключение обрабатывается внутри метода, и информация о нем записывается в лог.

## Метод: `start_activity()`

Этот метод класса `Terminal` предназначен для запуска определенной активности в приложении на подключенном устройстве с использованием adb shell команды.

### Параметры

- `package`: Название пакета приложения, в котором находится активность. Должен быть представлен в виде строки.

- `activity`: Название активности, которую нужно запустить. Должно быть представлено в виде строки.

### Возвращаемое значение

Возвращает `True`, если активность была успешно запущена. В противном случае возвращается `False`.

### Пример использования

```python
terminal = Terminal(driver)
activity_started = terminal.start_activity(package="com.example", activity=".MainActivity")
if activity_started:
print("Activity was successfully started.")
else:
print("Activity starting failed.")
```

### Дополнительная информация

Метод использует adb shell команду `am start` для запуска активности. В случае успешного выполнения команды метод возвращает `True`. Если команда не может быть выполнена (например, если указанное приложение или активность не существуют), метод возвращает `False` и записывает информацию об ошибке в лог.

### Исключения

Метод может генерировать исключение `KeyError`, если в процессе выполнения adb shell команды возникают проблемы. Это исключение обрабатывается внутри метода, и информация о нем записывается в лог.

## Метод: `get_current_app_package()`

Метод класса `Terminal` предназначен для получения имени пакета текущего запущенного приложения на подключенном устройстве.

### Возвращаемое значение

Возвращает строку, содержащую имя пакета текущего запущенного приложения. В случае ошибки возвращает `None`.

### Пример использования

```python
terminal = Terminal(driver)
current_app_package = terminal.get_current_app_package()
if current_app_package:
print(f"The current running app package is {current_app_package}.")
else:
print("Failed to get the current running app package.")
```

### Дополнительная информация

Метод использует команду adb shell `dumpsys window windows` для получения информации о текущем активном окне на устройстве. Эта информация анализируется, и из неё извлекается имя пакета запущенного приложения. Если информацию не удалось извлечь (например, если нет активного окна или приложения), метод возвращает `None`.

### Исключения

Метод может генерировать исключение `KeyError`, если в процессе выполнения команды adb shell возникают проблемы. Это исключение обрабатывается внутри метода, и информация о нем записывается в лог.

## Метод: `close_app()`

Метод класса `Terminal`, который принудительно закрывает приложение на подключенном устройстве с помощью указанного имени пакета.

### Параметры

- `package`: Строка, содержащая имя пакета приложения, которое необходимо закрыть.

### Возвращаемое значение

Возвращает `True`, если приложение было успешно закрыто, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.close_app("com.example.myapp"):
print("The app was successfully closed.")
else:
print("Failed to close the app.")
```

### Дополнительная информация

Метод использует команду adb shell `am force-stop`, чтобы принудительно остановить приложение с указанным именем пакета.

### Исключения

Метод может генерировать исключение `KeyError`, если в процессе выполнения команды adb shell возникают проблемы. Это исключение обрабатывается внутри метода, и информация о нем записывается в лог.

## Метод: `reboot_app()`

Метод класса `Terminal`, который перезапускает указанное приложение, сначала принудительно закрывая его, а затем запуская указанную активность.

### Параметры

- `package`: Строка, содержащая имя пакета приложения, которое необходимо перезапустить.

- `activity`: Строка, содержащая имя активности приложения, которую необходимо запустить.

### Возвращаемое значение

Возвращает `True`, если перезапуск приложения выполнен успешно, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.reboot_app("com.example.myapp", "com.example.myapp.MainActivity"):
print("The app was successfully rebooted.")
else:
print("Failed to reboot the app.")
```

### Дополнительная информация

Этот метод сначала закрывает приложение с использованием метода `close_app()`, а затем пытается его перезапустить с использованием метода `start_activity()`. Если какой-либо из этих методов возвращает `False`, метод `reboot_app()` также вернет `False`.

### Исключения

Метод может генерировать исключение, если в процессе его выполнения возникают проблемы. В частности, если методы `close_app()` или `start_activity()` возвращают `False`, метод `reboot_app()` также вернет `False`.

## Метод: `uninstall_app()`

Метод класса `Terminal`, который удаляет указанное приложение с помощью ADB (Android Debug Bridge).

### Параметры

- `package`: Строка, содержащая имя пакета приложения, которое необходимо удалить.

### Возвращаемое значение

Возвращает `True`, если приложение успешно удалено, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.uninstall_app("com.example.myapp"):
print("The app was successfully uninstalled.")
else:
print("Failed to uninstall the app.")
```

### Дополнительная информация

Этот метод использует метод `remove_app()` из `driver` для удаления приложения. Если удаление успешно, метод `remove_app()` не возвращает значение, в противном случае он может вызвать исключение.

### Исключения

Метод может генерировать исключение, если в процессе его выполнения возникают проблемы. Если метод `remove_app()` вызывает исключение, это исключение будет логироваться, а метод `uninstall_app()` вернет `False`.

## Метод: `install_app()`

Метод класса `Terminal`, который устанавливает указанное приложение с помощью Appium.

### Параметры

- `app_path`: Строка, содержащая путь до APK-файла приложения, которое необходимо установить.

### Возвращаемое значение

Возвращает `True`, если приложение успешно установлено, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.install_app("/path/to/myapp.apk"):
print("The app was successfully installed.")
else:
print("Failed to install the app.")
```

### Дополнительная информация

Этот метод использует метод `install_app()` из `driver` для установки приложения. Если установка успешна, метод `install_app()` не возвращает значение, в противном случае он может вызвать исключение.

### Исключения

Метод может генерировать исключение, если в процессе его выполнения возникают проблемы. Если метод `install_app()` вызывает исключение, это исключение будет логироваться, а метод `install_app()` вернет `False`.

## Метод: `is_app_installed()`

Метод класса `Terminal`, предназначенный для проверки установки указанного пакета приложения с помощью Appium.

### Параметры

- `package` (тип: `str`): Имя пакета приложения, для которого нужно проверить установку.

### Возвращаемое значение

Возвращает значение `True`, если указанный пакет приложения установлен на устройстве, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.is_app_installed("com.example.myapp"):
print("The app is installed.")
else:
print("The app is not installed.")
```

### Дополнительная информация

Метод `is_app_installed()` использует команду `pm list packages` для получения списка установленных пакетов приложений. Затем он фильтрует список и проверяет, содержится ли указанный пакет среди установленных. Если пакет найден в списке, метод вернет `True`, в противном случае вернет `False`.

### Исключения

Метод может вызывать исключение типа `KeyError`, если в процессе выполнения возникли проблемы с доступом к списку пакетов. В случае возникновения исключения, оно будет залогировано, и метод `is_app_installed()` вернет значение `False`.

**Примечание:** Для корректной работы метода `is_app_installed()`, убедитесь, что устройство подключено к Appium и правильно настроено для выполнения команд через ADB.

## Метод: `press_home()`

Метод класса `Terminal`, который эмулирует нажатие кнопки "Домой" на устройстве, используя Android Debug Bridge (ADB).

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Возвращает `True`, если команда была успешно выполнена, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.press_home():
print("Home button was successfully pressed.")
else:
print("Failed to press the home button.")
```

### Дополнительная информация

Этот метод отправляет команду `input_keycode` с кодом "KEYCODE_HOME" к драйверу Appium. Если команда выполнена успешно, метод `input_keycode` не возвращает значение, в противном случае он может вызвать исключение.

### Исключения

Метод может вызвать исключение, если возникают проблемы при выполнении его. Если метод `input_keycode` вызывает исключение, это исключение будет залогировано, а метод `press_home()` вернет `False`.

## Метод: `press_back()`

Метод класса `Terminal`, который эмулирует нажатие кнопки "Назад" на устройстве, используя Android Debug Bridge (ADB).

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Возвращает `True`, если команда была успешно выполнена, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.press_back():
print("Back button was successfully pressed.")
else:
print("Failed to press the back button.")
```

### Дополнительная информация

Этот метод отправляет команду `input_keycode` с кодом "KEYCODE_BACK" к драйверу Appium. Если команда выполнена успешно, метод `input_keycode` не возвращает значение, в противном случае он может вызвать исключение.

### Исключения

Метод может вызвать исключение, если возникают проблемы при выполнении его. Если метод `input_keycode` вызывает исключение, это исключение будет залогировано, а метод `press_back()` вернет `False`.

## Метод: `press_menu()`

Метод класса `Terminal`, который эмулирует нажатие кнопки "Меню" на устройстве, используя Android Debug Bridge (ADB).

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Возвращает `True`, если команда была успешно выполнена, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.press_menu():
print("Menu button was successfully pressed.")
else:
print("Failed to press the menu button.")
```

### Дополнительная информация

Этот метод отправляет команду `input_keycode` с кодом "KEYCODE_MENU" к драйверу Appium. Если команда выполнена успешно, метод `input_keycode` не возвращает значение, в противном случае он может вызвать исключение.

### Исключения

Метод может вызвать исключение, если возникают проблемы при выполнении его. Если метод `input_keycode` вызывает исключение, это исключение будет залогировано, а метод `press_menu()` вернет `False`.

## Метод: `input_keycode_num_()`

Этот метод класса `Terminal` имитирует нажатие клавиши на числовой клавиатуре устройства с использованием Android Debug Bridge (ADB).

### Параметры

Метод принимает следующие параметры:

- `num (int)`: числовое значение нажимаемой клавиши.

### Возвращаемое значение

Возвращает `True`, если команда была успешно выполнена, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.input_keycode_num_(5):
print("Клавиша с числом 5 была успешно нажата.")
else:
print("Не удалось нажать клавишу с числом 5.")
```

### Дополнительная информация

Этот метод отправляет команду `adb_shell` с командой `input` и аргументом `keyevent KEYCODE_NUMPAD_{num}` в драйвер Appium. Если команда успешно выполнена, метод `adb_shell` не возвращает значение, в противном случае, он может вызвать исключение.

### Исключения

Метод может вызвать исключение, если при его выполнении возникли проблемы. Если метод `adb_shell` вызывает исключение, это исключение будет залогировано, и метод `input_keycode_num_()` вернет `False`.

## Метод: `input_keycode()`

Метод класса `Terminal`, который имитирует ввод указанного кода клавиши на устройстве с помощью Android Debug Bridge (ADB).

### Параметры

Метод принимает следующий параметр:

- `keycode (str)`: код клавиши для ввода. Это может быть любой код клавиши, поддерживаемый ADB, включая, но не ограничиваясь, такими как "KEYCODE_HOME", "KEYCODE_BACK", "KEYCODE_MENU" и т. д.

### Возвращаемое значение

Метод возвращает `True`, если команда была успешно выполнена, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.input_keycode("KEYCODE_HOME"):
print("Клавиша Home была успешно нажата.")
else:
print("Не удалось нажать клавишу Home.")
```

### Дополнительная информация

Метод отправляет команду `adb_shell` с командой `input` и аргументом `keyevent {keycode}` в драйвер Appium. Если команда успешно выполнена, метод `adb_shell` не возвращает значение, в противном случае, он может вызвать исключение.

### Исключения

Метод может вызвать исключение `KeyError`, если при его выполнении возникли проблемы. Если метод `adb_shell` вызывает исключение, это исключение будет залогировано, и метод `input_keycode()` вернет `False`.

## Метод: `input_by_virtual_keyboard()`

Метод класса `Terminal`, который эмулирует ввод строки символов с помощью виртуальной клавиатуры на устройстве.

### Параметры

Метод принимает следующие параметры:

- `key (str)`: Строка символов, которые требуется ввести.
- `keyboard (dict)`: Словарь, отображающий символы на координаты нажатия на экране. Ключами словаря являются символы, а значениями - кортежи, содержащие координаты x и y на экране для каждого символа.

### Возвращаемое значение

Метод возвращает `True`, если ввод символов был выполнен успешно, и `False` в противном случае.

### Пример использования

```python
keyboard_mapping = {
"a": (100, 200),
"b": (120, 220),
...
}
terminal = Terminal(driver)
if terminal.input_by_virtual_keyboard("abc", keyboard_mapping):
print("Ввод символов 'abc' выполнен успешно.")
else:
print("Ошибка при вводе символов 'abc'.")
```

### Дополнительная информация

В данном методе используется функция `tap()`, которая выполняет нажатие на указанные координаты на экране. Для каждого символа во входной строке метод вызывает функцию `tap()` с координатами, соответствующими этому символу.

### Исключения

Метод может вызвать исключение `KeyError`, если при его выполнении возникли проблемы, например, если указанный символ отсутствует в словаре `keyboard`. Если метод `tap()` вызывает исключение, это исключение будет залогировано, и метод `input_by_virtual_keyboard()` вернет `False`.

## Метод: `input_text()`

Метод класса `Terminal`, который эмулирует ввод указанного текста на устройстве с использованием ADB (Android Debug Bridge).

### Параметры

Метод принимает следующий параметр:

- `text (str)`: Строка текста, которую нужно ввести на устройстве.

### Возвращаемое значение

Метод возвращает `True`, если команда была успешно выполнена, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.input_text("Hello, world!"):
print("Текст 'Hello, world!' успешно введен.")
else:
print("Ошибка при вводе текста 'Hello, world!'.")
```

### Дополнительная информация

В данном методе используется функция `adb_shell()`, которая отправляет ADB команду в shell Android устройства. С помощью ADB команды "input text" мы можем ввести текст на устройстве.

### Исключения

Метод может вызвать исключение `KeyError`, если при его выполнении возникли проблемы. Если возникает исключение, оно будет залогировано, и метод `input_text()` вернет `False`.

## Метод: `tap()`

Это метод класса `Terminal`, который эмулирует нажатие на указанные координаты на устройстве с использованием ADB (Android Debug Bridge).

### Параметры

Метод принимает следующие параметры:

- `x (int)`: Координата по оси X точки, по которой нужно нажать.
- `y (int)`: Координата по оси Y точки, по которой нужно нажать.

### Возвращаемое значение

Метод возвращает `True`, если команда была успешно выполнена, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.tap(200, 300):
print("Нажатие на координаты (200, 300) успешно выполнено.")
else:
print("Ошибка при нажатии на координаты (200, 300).")
```

### Дополнительная информация

В данном методе используется функция `adb_shell()`, которая отправляет ADB команду в shell Android устройства. С помощью ADB команды "input tap" мы можем выполнить нажатие на определенные координаты экрана.

### Исключения

Метод может вызвать исключение `KeyError`, если при его выполнении возникли проблемы. Если возникает исключение, оно будет залогировано, и метод `tap()` вернет `False`.

## Метод: `swipe()`

Это метод класса `Terminal`, который эмулирует жест свайпа (или перетаскивания) с одной точки на экране до другой на устройстве с использованием ADB (Android Debug Bridge).

### Параметры

Метод принимает следующие параметры:

- `start_x (Union[str, int])`: Координата по оси X начальной точки свайпа.
- `start_y (Union[str, int])`: Координата по оси Y начальной точки свайпа.
- `end_x (Union[str, int])`: Координата по оси X конечной точки свайпа.
- `end_y (Union[str, int])`: Координата по оси Y конечной точки свайпа.
- `duration (int)`: Длительность свайпа в миллисекундах. По умолчанию равна 300 мс.

### Возвращаемое значение

Метод возвращает `True`, если команда была успешно выполнена, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.swipe(200, 300, 400, 500, 1000):
print("Свайп с координат (200, 300) до координат (400, 500) выполнен успешно.")
else:
print("Ошибка при выполнении свайпа.")
```

### Дополнительная информация

В данном методе используется функция `adb_shell()`, которая отправляет ADB команду в shell Android устройства. С помощью ADB команды "input swipe" мы можем выполнить свайп по экрану от одних координат до других.

### Исключения

Метод может вызвать исключение `KeyError`, если при его выполнении возникли проблемы. Если возникает исключение, оно будет залогировано, и метод `swipe()` вернет `False`.

## Метод: `check_vpn()`

Это метод класса `Terminal`, который проверяет, активно ли VPN-соединение на устройстве, используя ADB (Android Debug Bridge).

### Параметры

Метод принимает следующий параметр:

- `ip_address (str)`: IP-адрес для проверки VPN-соединения. Если он не указан, то используется значение по умолчанию.

### Возвращаемое значение

Метод возвращает `True`, если VPN-соединение активно, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.check_vpn('192.168.0.1'):
print("VPN-соединение активно.")
else:
print("VPN-соединение не активно.")
```

### Дополнительная информация

В данном методе используется функция `adb_shell()`, которая отправляет ADB команду в shell Android устройства. С помощью команды "netstat" мы можем проверить состояние сетевых соединений устройства.

### Исключения

Метод может вызвать исключение `KeyError`, если при его выполнении возникли проблемы. Если возникает исключение, оно будет залогировано, и метод `check_vpn()` вернет `False`.

## Метод: `stop_logcat()`

Это метод класса `Terminal`, который останавливает выполнение logcat на устройстве, используя ADB (Android Debug Bridge).

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Метод возвращает `True`, если выполнение logcat остановлено успешно, и `False` в противном случае.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.stop_logcat():
print("logcat остановлен успешно.")
else:
print("Не удалось остановить logcat.")
```

### Дополнительная информация

Метод `stop_logcat()` сначала получает список всех выполняющихся процессов на устройстве с помощью команды `ps`. Затем он проходит через этот список и отправляет сигнал `SIGINT` каждому процессу `logcat`, который он находит, чтобы остановить его.

### Исключения

Метод может вызвать исключение `KeyError`, если при его выполнении возникли проблемы. Если возникает исключение, оно будет залогировано, и метод `stop_logcat()` вернет `False`.

## Метод: `know_pid()`

Это метод класса `Terminal`, который ищет и возвращает идентификатор процесса (PID) по его имени с помощью команды `adb shell ps`.

### Параметры

* `name (str)`: Имя процесса, PID которого необходимо найти.

### Возвращаемое значение

Метод возвращает `int` или `None`. Если процесс с указанным именем найден, метод возвращает его PID (как целое число). Если процесс не найден, метод возвращает `None`.

### Пример использования

```python
terminal = Terminal(driver)
pid = terminal.know_pid("com.example.app")
if pid is not None:
print(f"PID процесса 'com.example.app': {pid}")
else:
print("Процесс 'com.example.app' не найден.")
```

### Дополнительная информация

Метод `know_pid()` получает список всех выполняющихся процессов на устройстве с помощью команды `adb shell ps`, затем проходит по этому списку и ищет процесс с указанным именем. Если такой процесс найден, метод возвращает его PID. Если процесс не найден, метод возвращает `None`.

### Исключения

Метод не обрабатывает исключения и, таким образом, может вызвать любое исключение, которое может вызвать `adb_shell(command)`.


## Метод: `is_process_exist()`

Это метод класса `Terminal`, который проверяет, существует ли процесс с указанным именем, используя команду `adb shell ps`.

### Параметры

* `name (str)`: Имя процесса, которое требуется проверить на существование.

### Возвращаемое значение

Метод возвращает `bool`. Если процесс с указанным именем существует, метод возвращает `True`. В противном случае, если процесс не найден, метод возвращает `False`.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.is_process_exist("com.example.app"):
print("Процесс 'com.example.app' существует.")
else:
print("Процесс 'com.example.app' не существует.")
```

### Дополнительная информация

Метод `is_process_exist(name)` получает список всех выполняющихся процессов на устройстве с помощью команды `adb shell ps`, затем проверяет, есть ли процесс с указанным именем в этом списке. Если процесс с заданным именем найден, метод возвращает `True`, иначе возвращает `False`.

### Исключения

Метод не обрабатывает исключения и, таким образом, может вызвать любое исключение, которое может возникнуть при выполнении `adb_shell(command)`.

**Примечание:** В описании метода `is_process_exist(name)` вместо `is_process_exist() > True` и `is_process_exist() > False`, используются логгеры для вывода отладочной информации. В реальной реализации эти строки не будут отображаться. Они присутствуют в данном контексте только для демонстрации логгирования.

## Метод: `run_background_process()`

Это метод класса `Terminal`, который запускает процесс в фоновом режиме на устройстве Android.

### Параметры

* `command (str)`: Команда для выполнения на устройстве.
* `args (str)`: Дополнительные аргументы для команды. По умолчанию `""`.
* `process (str)`: Название процесса, который будет запущен. По умолчанию `""`. Если значение `process` равно `""`, то не будет проверяться его запуск в системе.

### Возвращаемое значение

Метод возвращает `bool`. Если процесс был успешно запущен, метод возвращает `True`. В противном случае, если процесс не удалось запустить или указанный процесс не был найден, метод возвращает `False`.

### Пример использования

```python
terminal = Terminal(driver)
command_to_run = "my_background_command arg1 arg2"
if terminal.run_background_process(command_to_run, args="--option"):
print("Процесс был успешно запущен.")
else:
print("Произошла ошибка при запуске процесса или процесс не найден.")
```

### Дополнительная информация

Метод `run_background_process(command, args="", process="")` выполняет переданную команду `command` на устройстве Android с дополнительными аргументами `args`. Команда запускается в фоновом режиме с использованием `nohup` и перенаправлением вывода в `/dev/null` для игнорирования вывода в консоль.

Если параметр `process` не равен пустой строке, метод после запуска процесса проверяет его существование через метод `is_process_exist(name=process)`. Если процесс не найден, метод вернет `False`. В противном случае, если процесс успешно запущен или параметр `process` равен пустой строке, метод вернет `True`.

Метод может вызывать исключение `KeyError`, и в таком случае он будет логировать ошибку и возвращать `False`.


## Метод: `kill_by_pid()`

Это метод класса `Terminal`, который посылает сигнал SIGINT процессу с указанным идентификатором процесса (PID), используя команду `adb shell kill`.

### Параметры

* `pid (int)`: Идентификатор процесса (PID), который нужно остановить.

### Возвращаемое значение

Метод возвращает `bool`. Если команда выполнена успешно и процесс остановлен, возвращается `True`. В противном случае - `False`.

### Пример использования

```python
terminal = Terminal(driver)
pid = terminal.know_pid("com.example.app")
if pid is not None:
if terminal.kill_by_pid(pid):
print(f"Процесс с PID {pid} успешно остановлен.")
else:
print(f"Не удалось остановить процесс с PID {pid}.")
else:
print("Процесс 'com.example.app' не найден.")
```

### Дополнительная информация

Метод `kill_by_pid()` отправляет команду `kill -s SIGINT {pid}` на устройство через `adb shell` для остановки процесса с указанным идентификатором процесса.

### Исключения

Метод обрабатывает исключение `KeyError`, которое может быть вызвано методом `adb_shell(command, args)`. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `kill_all()`

Этот метод класса `Terminal` предназначен для остановки всех процессов, соответствующих заданному имени или шаблону имени, с помощью команды `adb shell pkill`.

### Параметры

* `name (str)`: Имя или шаблон имени процесса, который необходимо остановить.

### Возвращаемое значение

Метод возвращает `bool`. Если команда выполнена успешно и все процессы остановлены, возвращается `True`. В противном случае - `False`.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.kill_all("com.example.app"):
print("Все процессы 'com.example.app' успешно остановлены.")
else:
print("Не удалось остановить все процессы 'com.example.app'.")
```

### Дополнительная информация

Метод `kill_all()` отправляет команду `pkill -f {name}` на устройство через `adb shell` для остановки всех процессов, соответствующих заданному имени или шаблону имени.

### Исключения

Метод обрабатывает исключение `KeyError`, которое может быть вызвано методом `adb_shell(command, args)`. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `delete_files_from_internal_storage()`

Этот метод класса `Terminal` предназначен для удаления файлов из внутреннего хранилища устройства с помощью команды `adb shell rm`.

### Параметры

* `path (str)`: Путь к папке во внутреннем хранилище, из которой необходимо удалить файлы.

### Возвращаемое значение

Метод возвращает `bool`. Если команда выполнена успешно и файлы удалены, возвращается `True`. В противном случае - `False`.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.delete_files_from_internal_storage("/sdcard/Download/"):
print("Файлы успешно удалены из '/sdcard/Download/'.")
else:
print("Не удалось удалить файлы из '/sdcard/Download/'.")
```

### Дополнительная информация

Метод `delete_files_from_internal_storage()` отправляет команду `rm -rf {path}*` на устройство через `adb shell` для удаления всех файлов в указанном каталоге.

### Исключения

Метод обрабатывает исключение `KeyError`, которое может быть вызвано методом `adb_shell(command, args)`. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `delete_file_from_internal_storage()`

Этот метод класса `Terminal` предназначен для удаления конкретного файла из внутреннего хранилища устройства с помощью команды `adb shell rm`.

### Параметры

* `path (str)`: Путь к папке во внутреннем хранилище, из которой необходимо удалить файл.
* `filename (str)`: Имя файла, который необходимо удалить.

### Возвращаемое значение

Метод возвращает `bool`. Если команда выполнена успешно и файл удален, возвращается `True`. В противном случае - `False`.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.delete_file_from_internal_storage("/sdcard/Download/", "myfile.txt"):
print("Файл 'myfile.txt' успешно удален из '/sdcard/Download/'.")
else:
print("Не удалось удалить файл 'myfile.txt' из '/sdcard/Download/'.")
```

### Дополнительная информация

Метод `delete_file_from_internal_storage()` отправляет команду `rm -rf {path}/{filename}` на устройство через `adb shell` для удаления указанного файла в указанном каталоге.

### Исключения

Метод обрабатывает исключение `KeyError`, которое может быть вызвано методом `adb_shell(command, args)`. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `record_video()`

Этот метод класса `Terminal` предназначен для начала записи видео с экрана устройства.

### Параметры

* `**options (Any)`: Опциональные аргументы для настройки записи видео. Обратитесь к документации Appium для получения полного списка доступных параметров.

### Возвращаемое значение

Метод возвращает `bool`. Если запись видео успешно начата, возвращается `True`. В противном случае - `False`.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.record_video():
print("Запись видео успешно начата.")
else:
print("Не удалось начать запись видео.")
```

### Дополнительная информация

Метод `record_video()` использует метод `start_recording_screen()` из библиотеки Appium для начала записи видео.

### Исключения

Метод обрабатывает исключение `KeyError`, которое может быть вызвано методом `start_recording_screen()`. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `stop_video()`

Этот метод класса `Terminal` предназначен для остановки записи видео с экрана устройства и возвращения записанного видео в формате base64.

### Параметры

* `**options (Any)`: Опциональные аргументы для настройки остановки записи видео. Эти могут включать параметры, такие как 'withFile' и другие. Обратитесь к документации Appium для получения полного списка доступных параметров.

### Возвращаемое значение

Метод возвращает `Union[bytes, None]`. Если запись видео успешно остановлена, возвращается видео в виде декодированных из base64 байтов. В противном случае возвращается `None`.

### Пример использования

```python
terminal = Terminal(driver)
video_bytes = terminal.stop_video()
if video_bytes is not None:
with open('output.mp4', 'wb') as f:
f.write(video_bytes)
print("Видео успешно остановлено и сохранено.")
else:
print("Не удалось остановить запись видео.")
```

### Дополнительная информация

Метод `stop_video()` использует метод `stop_recording_screen()` из библиотеки Appium для остановки записи видео. Этот метод возвращает видео в виде строки, закодированной в base64. Метод `stop_video()` затем декодирует эту строку в байты и возвращает их.

### Исключения

Метод обрабатывает исключение `KeyError`, которое может быть вызвано методом `stop_recording_screen()`. Если исключение возникает, оно логируется и метод возвращает `None`.

## Метод: `reboot()`

Этот метод класса `Terminal` предназначен для перезагрузки устройства с использованием ADB.

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Метод возвращает `bool`. Если перезагрузка устройства успешно запущена, возвращается `True`. В противном случае возвращается `False`.

### Пример использования

```python
terminal = Terminal(driver)
if terminal.reboot():
print("Устройство успешно перезагружено.")
else:
print("Не удалось запустить перезагрузку устройства.")
```

### Дополнительная информация

Метод `reboot()` использует команду `reboot` ADB для перезагрузки устройства.

### Исключения

Метод обрабатывает исключение `KeyError`, которое может быть вызвано методом `adb_shell()`. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `get_screen_resolution()`

Этот метод класса `Terminal` предназначен для получения разрешения экрана устройства с использованием ADB.

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Метод возвращает кортеж из двух целых чисел (`tuple[int, int]`) или `None`. Кортеж содержит ширину и высоту экрана в пикселях. Если происходит ошибка, возвращается `None`.

### Пример использования

```python
terminal = Terminal(driver)
resolution = terminal.get_screen_resolution()
if resolution:
print(f"Разрешение экрана устройства: {resolution[0]}x{resolution[1]}")
else:
print("Не удалось получить разрешение экрана.")
```

### Дополнительная информация

Метод `get_screen_resolution()` использует команду `wm size` ADB для получения разрешения экрана устройства.

### Исключения

Метод обрабатывает исключение `KeyError`, которое может быть вызвано методом `adb_shell()`. Если исключение возникает, оно логируется и метод возвращает `None`.


# class Adb
Предназначен для взаимодействия с Android Debug Bridge (ADB). Этот класс будет использовать для выполнения различных команд на устройстве Android.

## Метод: `install_app()`

Этот метод класса `Adb` предназначен для установки приложения на устройство с использованием ADB.

### Параметры

Метод принимает следующие параметры:

1. `apk_path (str)`: Путь к APK-файлу приложения на компьютере.

### Возвращаемое значение

Метод возвращает `True` (`bool`), если приложение успешно установлено, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
if adb.install_app("path_to_apk"):
print("Приложение успешно установлено.")
else:
print("Не удалось установить приложение.")
```

### Дополнительная информация

Метод `install_app()` использует команду `adb install` для установки APK-файла на устройство.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может быть вызвано методом `subprocess.check_output()`. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `is_app_installed()`

Этот метод класса `Adb` предназначен для проверки, установлено ли указанное приложение на подключенном устройстве Android с использованием ADB.

### Параметры

Метод принимает следующий параметр:

- `package` (`str`): Имя пакета приложения, которое нужно проверить.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если приложение установлено на устройстве.
- `False` - если приложение не установлено на устройстве или произошла ошибка при проверке.

### Пример использования

```python
adb = Adb()
is_installed = adb.is_app_installed("com.example.app")
if is_installed:
print("Приложение установлено на устройстве.")
else:
print("Приложение не установлено на устройстве.")
```

### Дополнительная информация

Метод `is_app_installed()` использует команду `adb shell pm list packages` для получения списка всех установленных приложений на устройстве. Затем он проверяет, присутствует ли имя пакета в этом списке.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может быть вызвано методом `subprocess.check_output()`. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `uninstall_app()`

Этот метод класса `Adb` предназначен для удаления приложения на подключенном устройстве Android.

### Параметры

Метод принимает следующий параметр:

- `package` (`str`): Имя пакета приложения, которое вы хотите удалить.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если приложение было успешно удалено с устройства.
- `False` - если произошла ошибка при удалении приложения.

### Пример использования

```python
adb = Adb()
success = adb.uninstall_app("com.example.app")
if success:
print("Приложение успешно удалено с устройства.")
else:
print("Не удалось удалить приложение с устройства.")
```

### Дополнительная информация

Метод `uninstall_app()` использует команду `adb uninstall` для удаления указанного приложения.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду удаления приложения. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `get_device_model()`

Этот метод класса `Adb` предназначен для получения модели подключенного устройства Android с использованием ADB.

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Метод возвращает модель устройства в виде строки (`str`) или `None`, если происходит ошибка при получении модели устройства.

### Пример использования

```python
adb = Adb()
model = adb.get_device_model()
if model:
print(f"Модель устройства: {model}")
else:
print("Не удалось получить модель устройства.")
```

### Дополнительная информация

Метод `get_device_model()` использует команду `adb shell getprop ro.product.model` для получения модели устройства.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может быть вызвано методом `subprocess.check_output()`. Если исключение возникает, оно логируется и метод возвращает `None`.

## Метод: `push()`

Этот метод класса `Adb` предназначен для копирования файла или директории с вашего компьютера на подключенное устройство Android с использованием ADB.

### Параметры

Метод принимает следующие параметры:

- `source` (`str`): Путь на вашем компьютере к файлу или директории, который вы хотите скопировать.
- `destination` (`str`): Путь назначения на устройстве, куда вы хотите скопировать файл или директорию.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если файл или директория были успешно скопированы на устройство.
- `False` - если произошла ошибка при копировании файла или директории.

### Пример использования

```python
adb = Adb()
success = adb.push("/path/to/local/file.txt", "/path/to/device/file.txt")
if success:
print("Файл успешно скопирован на устройство.")
else:
print("Не удалось скопировать файл на устройство.")
```

### Дополнительная информация

Метод `push()` использует команду `adb push` для копирования файла или директории на устройство.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может быть вызвано методом `subprocess.run()`. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `pull()`

Этот метод класса `Adb` предназначен для копирования файла или директории с подключенного устройства Android на ваш компьютер с использованием ADB.

### Параметры

Метод принимает следующие параметры:

- `source` (`str`): Путь на устройстве к файлу или директории, которые вы хотите скопировать.
- `destination` (`str`): Путь назначения на вашем компьютере, куда вы хотите скопировать файл или директорию.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если файл или директория были успешно скопированы с устройства.
- `False` - если произошла ошибка при копировании файла или директории.

### Пример использования

```python
adb = Adb()
success = adb.pull("/path/to/device/file.txt", "/path/to/local/file.txt")
if success:
print("Файл успешно скопирован с устройства.")
else:
print("Не удалось скопировать файл с устройства.")
```

### Дополнительная информация

Метод `pull()` использует команду `adb pull` для копирования файла или директории с устройства.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может быть вызвано методом `subprocess.run()`. Если исключение возникает, оно логируется и метод возвращает `False`.


## Метод: `start_activity()`

Этот метод класса `Adb` предназначен для запуска конкретной активности на подключенном устройстве Android с использованием ADB.

### Параметры

Метод принимает следующие параметры:

- `package` (`str`): Имя пакета активности, которую вы хотите запустить.
- `activity` (`str`): Имя активности, которую вы хотите запустить.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если активность была успешно запущена на устройстве.
- `False` - если произошла ошибка при запуске активности.

### Пример использования

```python
adb = Adb()
success = adb.start_activity("com.example.app", "com.example.app.MainActivity")
if success:
print("Активность успешно запущена на устройстве.")
else:
print("Не удалось запустить активность на устройстве.")
```

### Дополнительная информация

Метод `start_activity()` использует команду `adb shell am start` для запуска активности на устройстве. Параметр `-n` используется для указания имени активности в формате `[package]/[activity]`.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может быть вызвано методом `subprocess.check_output()`. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `close_app()`

Этот метод класса `Adb` предназначен для принудительного завершения указанного пакета на подключенном устройстве Android с использованием ADB.

### Параметры

Метод принимает следующие параметры:

- `package` (`str`): Имя пакета приложения, которое вы хотите закрыть.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если приложение было успешно закрыто на устройстве.
- `False` - если произошла ошибка при закрытии приложения.

### Пример использования

```python
adb = Adb()
success = adb.close_app("com.example.app")
if success:
print("Приложение успешно закрыто на устройстве.")
else:
print("Не удалось закрыть приложение на устройстве.")
```

### Дополнительная информация

Метод `close_app()` использует команду `adb shell am force-stop` для принудительного завершения указанного пакета на устройстве.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может быть вызвано методом `subprocess.run()`. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `reboot_app()`

Этот метод класса `Adb` предназначен для перезапуска приложения на подключенном устройстве Android. Он делает это, закрывая приложение, а затем запуская указанную активность.

### Параметры

Метод принимает следующие параметры:

- `package` (`str`): Имя пакета приложения, которое вы хотите перезапустить.
- `activity` (`str`): Имя активности внутри пакета приложения, которую вы хотите запустить после закрытия приложения.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если приложение было успешно перезапущено на устройстве.
- `False` - если произошла ошибка при перезапуске приложения.

### Пример использования

```python
adb = Adb()
success = adb.reboot_app("com.example.app", "com.example.app.MainActivity")
if success:
print("Приложение успешно перезапущено на устройстве.")
else:
print("Не удалось перезапустить приложение на устройстве.")
```

### Дополнительная информация

Метод `reboot_app()` использует методы `close_app()` и `start_activity()` класса `Adb` для выполнения своей функции.

### Исключения

Метод не обрабатывает исключения напрямую, но вызываемые им методы `close_app()` и `start_activity()` обрабатывают исключения `subprocess.CalledProcessError`. Если эти методы возвращают `False`, что указывает на появление исключения, то `reboot_app()` также возвращает `False`.

## Метод: `press_home()`

Этот метод класса `Adb` предназначен для отправки события нажатия кнопки Home на подключенном устройстве Android.

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если событие нажатия кнопки Home было успешно отправлено на устройство.
- `False` - если произошла ошибка при отправке события.

### Пример использования

```python
adb = Adb()
success = adb.press_home()
if success:
print("Событие нажатия кнопки Home успешно отправлено.")
else:
print("Не удалось отправить событие нажатия кнопки Home.")
```

### Дополнительная информация

Метод `press_home()` использует команду `adb shell input keyevent KEYCODE_HOME` для отправки события нажатия кнопки Home.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду отправки события. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `press_back()`

Этот метод класса `Adb` предназначен для отправки события нажатия кнопки Back на подключенном устройстве Android.

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если событие нажатия кнопки Back было успешно отправлено на устройство.
- `False` - если произошла ошибка при отправке события.

### Пример использования

```python
adb = Adb()
success = adb.press_back()
if success:
print("Событие нажатия кнопки Back успешно отправлено.")
else:
print("Не удалось отправить событие нажатия кнопки Back.")
```

### Дополнительная информация

Метод `press_back()` использует команду `adb shell input keyevent KEYCODE_BACK` для отправки события нажатия кнопки Back.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду отправки события. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `press_menu()`

Этот метод класса `Adb` предназначен для отправки события нажатия кнопки Menu на подключенном устройстве Android.

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если событие нажатия кнопки Menu было успешно отправлено на устройство.
- `False` - если произошла ошибка при отправке события.

### Пример использования

```python
adb = Adb()
success = adb.press_menu()
if success:
print("Событие нажатия кнопки Menu успешно отправлено.")
else:
print("Не удалось отправить событие нажатия кнопки Menu.")
```

### Дополнительная информация

Метод `press_menu()` использует команду `adb shell input keyevent KEYCODE_MENU` для отправки события нажатия кнопки Menu.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду отправки события. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `input_keycode_num_()`

Этот метод класса `Adb` предназначен для отправки события нажатия числовой клавиши на подключенном устройстве Android.

### Параметры

- `num` (int): Числовое значение клавиши для нажатия. Допустимые значения: от 0 до 9 и специальные символы (ADD, COMMA, DIVIDE, DOT, ENTER, EQUALS).

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если событие нажатия числовой клавиши было успешно отправлено на устройство.
- `False` - если произошла ошибка при отправке события.

### Пример использования

```python
adb = Adb()
success = adb.input_keycode_num_(5)
if success:
print("Событие нажатия числовой клавиши успешно отправлено.")
else:
print("Не удалось отправить событие нажатия числовой клавиши.")
```

### Дополнительная информация

Метод `input_keycode_num_()` использует команду `adb shell input keyevent KEYCODE_NUMPAD_{num}` для отправки события нажатия числовой клавиши.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду отправки события. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `input_keycode()`

Этот метод класса `Adb` предназначен для ввода определенного кода клавиши на подключенном устройстве Android.

### Параметры

- `keycode` (str): Код клавиши для ввода. Примеры допустимых значений: "KEYCODE_HOME", "KEYCODE_BACK", "KEYCODE_VOLUME_UP" и т.д.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если команда ввода клавиши была успешно выполнена.
- `False` - если произошла ошибка при выполнении команды.

### Пример использования

```python
adb = Adb()
success = adb.input_keycode("KEYCODE_HOME")
if success:
print("Команда ввода клавиши успешно выполнена.")
else:
print("Не удалось выполнить команду ввода клавиши.")
```

### Дополнительная информация

Метод `input_keycode()` использует команду `adb shell input keyevent {keycode}` для ввода кода клавиши на устройстве.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду ввода клавиши. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `input_by_virtual_keyboard()`

Этот метод класса `Adb` предназначен для ввода строки символов с помощью виртуальной клавиатуры на подключенном устройстве Android.

### Параметры

- `text` (str): Строка символов для ввода.
- `keyboard` (dict): Словарь с маппингом символов на координаты нажатий на виртуальной клавиатуре. Каждому символу в словаре соответствует кортеж из двух чисел, представляющих координаты нажатия (x, y).

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если ввод выполнен успешно.
- `False` - если произошла ошибка при вводе символов.

### Пример использования

```python
keyboard_mapping = {
'a': (100, 200),
'b': (150, 200),
# ...
}
adb = Adb()
success = adb.input_by_virtual_keyboard("ab", keyboard_mapping)
if success:
print("Ввод символов выполнен успешно.")
else:
print("Не удалось выполнить ввод символов.")
```

### Дополнительная информация

Метод `input_by_virtual_keyboard()` использует функцию `tap()` класса `Adb` для ввода каждого символа, проходя по всем символам в заданной строке `text`.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке ввода символа. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `input_text()`

Этот метод класса `Adb` предназначен для ввода текста на подключенном устройстве Android.

### Параметры

- `text` (str): Текст для ввода на устройстве.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если команда была успешно выполнена.
- `False` - если произошла ошибка при выполнении команды.

### Пример использования

```python
adb = Adb()
success = adb.input_text("Hello, World!")
if success:
print("Ввод текста выполнен успешно.")
else:
print("Не удалось выполнить ввод текста.")
```

### Дополнительная информация

Метод `input_text()` использует команду `adb shell input text` для ввода текста на устройстве Android. Пожалуйста, убедитесь, что текст, который вы хотите ввести, не содержит специальных символов, которые могут нарушить работу команды ADB.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `tap()`

Этот метод класса `Adb` предназначен для совершения нажатия на экран устройства в заданных координатах.

### Параметры

- `x` (str, int): Координата по оси X, где требуется произвести нажатие. Может быть как числом, так и строкой.
- `y` (str, int): Координата по оси Y, где требуется произвести нажатие. Может быть как числом, так и строкой.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если команда была успешно выполнена.
- `False` - если произошла ошибка при выполнении команды.

### Пример использования

```python
adb = Adb()
success = adb.tap(100, 200)
if success:
print("Нажатие выполнено успешно.")
else:
print("Не удалось выполнить нажатие.")
```

### Дополнительная информация

Метод `tap()` использует команду `adb shell input tap` для совершения нажатия на экране устройства в указанных координатах.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `swipe()`

Этот метод класса `Adb` предназначен для выполнения свайпа (перетаскивания) на экране устройства.

### Параметры

- `start_x` (str, int): Координата X начальной точки свайпа. Может быть как числом, так и строкой.
- `start_y` (str, int): Координата Y начальной точки свайпа. Может быть как числом, так и строкой.
- `end_x` (str, int): Координата X конечной точки свайпа. Может быть как числом, так и строкой.
- `end_y` (str, int): Координата Y конечной точки свайпа. Может быть как числом, так и строкой.
- `duration` (int, optional): Длительность свайпа в миллисекундах. По умолчанию равна 300.

### Возвращаемое значение

Метод возвращает логическое значение `bool`:
- `True` - если команда была успешно выполнена.
- `False` - если произошла ошибка при выполнении команды.

### Пример использования

```python
adb = Adb()
success = adb.swipe(100, 200, 300, 400)
if success:
print("Свайп выполнен успешно.")
else:
print("Не удалось выполнить свайп.")
```

### Дополнительная информация

Метод `swipe()` использует команду `adb shell input swipe` для выполнения свайпа на экране устройства от начальной точки к конечной.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `get_current_app_package()`

Этот метод класса `Adb` предназначен для получения названия пакета текущего запущенного приложения на устройстве.

### Параметры

Метод не требует параметров.

### Возвращаемое значение

Метод возвращает строку, представляющую название пакета текущего запущенного приложения, или `None`, если произошла ошибка.

### Пример использования

```python
adb = Adb()
package = adb.get_current_app_package()
if package:
print(f"Текущее приложение: {package}")
else:
print("Не удалось определить текущее приложение.")
```

### Дополнительная информация

Метод `get_current_app_package()` использует команду `adb shell dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp' | grep -e 'mFo'` для получения информации о текущем запущенном приложении. Затем он анализирует результат этой команды, чтобы извлечь название пакета приложения.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, оно логируется и метод возвращает `None`.

## Метод: `check_vpn()`

Этот метод класса `Adb` предназначен для проверки, установлено ли VPN-соединение на устройстве.

### Параметры

- `ip_address` (str, по умолчанию `''`): IP-адрес для проверки VPN-соединения. Если параметр не указан, используется значение из конфигурации.

### Возвращаемое значение

Метод возвращает булевое значение: `True`, если VPN-соединение активно, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
vpn_status = adb.check_vpn('192.168.1.1')
if vpn_status:
print("VPN-соединение активно.")
else:
print("VPN-соединение не активно.")
```

### Дополнительная информация

Метод `check_vpn()` использует команду `adb shell netstat | grep -w -e [ip_address]` для проверки активности VPN-соединения. Если в выводе команды присутствует слово "ESTABLISHED", метод возвращает `True`, что означает, что VPN-соединение активно.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `stop_logcat()`

Этот метод класса `Adb` предназначен для остановки выполнения `logcat` на устройстве.

### Параметры

Метод не принимает параметров.

### Возвращаемое значение

Метод возвращает булевое значение: `True`, если выполнение `logcat` остановлено успешно, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
logcat_status = adb.stop_logcat()
if logcat_status:
print("logcat успешно остановлен.")
else:
print("Не удалось остановить logcat.")
```

### Дополнительная информация

Метод `stop_logcat()` сначала использует команду `adb shell ps | grep logcat` для получения списка процессов `logcat`. Затем, для каждого найденного процесса, он отправляет сигнал `SIGINT`, используя команду `adb shell kill -s SIGINT [pid]`.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, оно логируется и метод возвращает `False`.

## Метод: `reload_adb()`

Этот метод класса `Adb` предназначен для перезапуска adb-сервера на устройстве.

### Параметры

Метод не принимает параметров.

### Возвращаемое значение

Метод возвращает булевое значение: `True`, если adb-сервер успешно перезапущен, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
adb_status = adb.reload_adb()
if adb_status:
print("adb-сервер успешно перезапущен.")
else:
print("Не удалось перезапустить adb-сервер.")
```

### Дополнительная информация

Метод `reload_adb()` сначала использует команду `adb kill-server` для остановки adb-сервера. Затем, после паузы в три секунды, используется команда `adb start-server` для перезапуска adb-сервера.

### Исключения

Метод обрабатывает исключение `subprocess.CalledProcessError`, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, оно логируется и метод возвращает `False`.


## Метод: `know_pid()`

Этот метод находит Process ID (PID) процесса по его имени, используя `adb shell ps`.

### Параметры

Метод принимает следующие параметры:

- `name`: Имя процесса, PID которого нужно найти.

### Возвращаемое значение

Метод возвращает PID процесса, если он найден, или `None`, если процесс не найден.

### Пример использования

```python
adb = Adb()
process_pid = adb.know_pid("my_process")
if process_pid:
print("PID процесса 'my_process' найден.")
else:
print("Процесс 'my_process' не найден.")
```

### Дополнительная информация

Метод `know_pid()` выполняет команду `adb shell ps` и затем проходит через вывод, пытаясь найти строку, которая содержит имя указанного процесса. Если такая строка найдена, метод извлекает PID из этой строки и возвращает его.

### Исключения

Метод обрабатывает исключение, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, информация об ошибке логируется и метод возвращает `False`. Также, если процесс с указанным именем не найден, метод возвращает `None`.

## Метод: `know_pid()`

Этот метод находит Process ID (PID) процесса по его имени, используя `adb shell ps`.

### Параметры

Метод принимает следующие параметры:

- `name` (str): Имя процесса, PID которого нужно найти.

### Возвращаемое значение

Метод возвращает PID процесса, если он найден, или `None`, если процесс не найден.

### Пример использования

```python
adb = Adb()
process_pid = adb.know_pid("my_process")
if process_pid:
print("PID процесса 'my_process' найден.")
else:
print("Процесс 'my_process' не найден.")
```

### Дополнительная информация

Метод `know_pid()` выполняет команду `adb shell ps` и затем проходит через вывод, пытаясь найти строку, которая содержит имя указанного процесса. Если такая строка найдена, метод извлекает PID из этой строки и возвращает его.

### Исключения

Метод обрабатывает исключение, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, информация об ошибке логируется и метод возвращает `False`. Также, если процесс с указанным именем не найден, метод возвращает `None`.

### Метод: `is_process_exist()`

Проверяет, запущен ли процесс, используя `adb shell ps`.

#### Параметры

- `name` (str): Имя процесса.

#### Возвращаемое значение

Метод возвращает `True`, если процесс с указанным именем существует, и `False` в ином случае.

#### Пример использования

```python
adb = Adb()
if adb.is_process_exist("my_process"):
print("Процесс 'my_process' существует.")
else:
print("Процесс 'my_process' не существует.")
```

Данный метод `is_process_exist()` используется внутри метода `know_pid()` для определения наличия процесса с заданным именем.


## Метод: `run_background_process()`

Запускает процесс в фоновом режиме на устройстве Android с использованием ADB.

### Параметры

- `command` (str): Команда для выполнения на устройстве.
- `process` (str): Название процесса, который будет запущен. По умолчанию пустая строка (`""`). Если `process == ""`, то не будет проверяться его запуск в системе.

### Возвращаемое значение

Метод возвращает `True`, если процесс был успешно запущен, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
command = "my_script.sh"
process_name = "my_process"
if adb.run_background_process(command, process_name):
print(f"Процесс '{process_name}' был успешно запущен.")
else:
print(f"Не удалось запустить процесс '{process_name}'.")
```

### Дополнительная информация

Метод `run_background_process()` запускает процесс в фоновом режиме на устройстве Android с использованием команды `adb shell` и `nohup` для выполнения команды без привязки к текущей сессии терминала. Вывод команды перенаправляется в `/dev/null`, чтобы не создавать логов в текущей сессии.

Если указан аргумент `process`, метод проверяет наличие процесса с указанным именем, используя метод `is_process_exist(name)`, чтобы убедиться, что процесс был успешно запущен.

В случае возникновения исключения при выполнении команды, метод возвращает `False`, а также логирует информацию об ошибке.


## Метод: `kill_by_pid()`

Этот метод отправляет сигнал SIGINT для остановки процесса по указанному идентификатору PID с помощью ADB.

### Параметры

Метод принимает следующий параметр:

- `pid`: Идентификатор PID процесса для остановки.

### Возвращаемое значение

Метод возвращает `True`, если процесс успешно остановлен, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
process_status = adb.kill_by_pid("1234")
if process_status:
print("Процесс с PID '1234' успешно остановлен.")
else:
print("Не удалось остановить процесс с PID '1234'.")
```

### Дополнительная информация

Метод `kill_by_pid()` выполняет команду `adb shell kill -s SIGINT <pid>`, чтобы отправить сигнал SIGINT указанному процессу. Этот сигнал останавливает процесс.

### Исключения

Метод обрабатывает исключение, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, информация об ошибке логируется и метод возвращает `False`.

## Метод: `kill_by_name()`

Этот метод останавливает все процессы с указанным именем на устройстве с помощью ADB.

### Параметры

Метод принимает следующий параметр:

- `name`: Имя процесса для остановки.

### Возвращаемое значение

Метод возвращает `True`, если все процессы успешно остановлены, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
process_status = adb.kill_by_name("my_process")
if process_status:
print("Все процессы с именем 'my_process' успешно остановлены.")
else:
print("Не удалось остановить процессы с именем 'my_process'.")
```

### Дополнительная информация

Метод `kill_by_name()` выполняет команду `adb shell pkill -l SIGINT <name>`, чтобы остановить все процессы с указанным именем.

### Исключения

Метод обрабатывает исключение, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, информация об ошибке логируется и метод возвращает `False`.

## Метод: `kill_all()`

Этот метод останавливает все процессы, соответствующие указанному имени или шаблону имени, на устройстве с помощью ADB.

### Параметры

Метод принимает следующий параметр:

- `name`: Имя процесса или шаблон имени для остановки.

### Возвращаемое значение

Метод возвращает `True`, если все процессы успешно остановлены, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
process_status = adb.kill_all("my_process")
if process_status:
print("Все процессы, соответствующие имени 'my_process', успешно остановлены.")
else:
print("Не удалось остановить процессы, соответствующие имени 'my_process'.")
```

### Дополнительная информация

Метод `kill_all()` выполняет команду `adb shell pkill -f <name>`, чтобы остановить все процессы, соответствующие указанному имени или шаблону имени.

### Исключения

Метод обрабатывает исключение, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, информация об ошибке логируется и метод возвращает `False`.

## Метод: `delete_files_from_internal_storage()`

Этот метод удаляет файлы из внутреннего хранилища устройства с помощью ADB.

### Параметры

Метод принимает следующий параметр:

- `path`: Путь к файлам для удаления.

### Возвращаемое значение

Метод возвращает `True`, если файлы успешно удалены, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
delete_status = adb.delete_files_from_internal_storage("/sdcard/MyFiles/")
if delete_status:
print("Файлы успешно удалены из '/sdcard/MyFiles/'.")
else:
print("Не удалось удалить файлы из '/sdcard/MyFiles/'.")
```

### Дополнительная информация

Метод `delete_files_from_internal_storage()` выполняет команду `adb shell rm -rf <path>*` для удаления всех файлов в указанной директории.

### Исключения

Метод обрабатывает исключение, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, информация об ошибке логируется и метод возвращает `False`.

## Метод: `pull_video()`

Этот метод копирует видеофайлы с устройства на компьютер с помощью ADB.

### Параметры

Метод принимает следующие параметры:

- `wherefrom` (необязательный): Путь к исходной директории на устройстве, откуда нужно скопировать видеофайлы. Если не указан, по умолчанию используется путь '/sdcard/Movies/'.
- `destination`: Путь для сохранения скопированных видеофайлов на компьютере.
- `delete` (необязательный): Флаг, указывающий, следует ли удалять видеофайлы после копирования с устройства. По умолчанию значение `True`.

### Возвращаемое значение

Метод возвращает `True`, если видеофайлы успешно скопированы, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
copy_status = adb.pull_video("/sdcard/MyVideos/", "/home/user/Videos/")
if copy_status:
print("Видеофайлы успешно скопированы в '/home/user/Videos/'.")
else:
print("Не удалось скопировать видеофайлы в '/home/user/Videos/'.")
```

### Дополнительная информация

Метод `pull_video()` сначала выполняет команду `adb pull <wherefrom> <destination>` для копирования видеофайлов из указанной директории на устройстве в указанную директорию на компьютере. Если флаг `delete` установлен в `True`, после копирования видеофайлы удаляются из исходной директории на устройстве командой `adb shell rm -rf <wherefrom>*`.

### Исключения

Метод обрабатывает исключение, которое может возникнуть при попытке выполнить команды ADB. Если исключение возникает при выполнении любой из команд, информация об ошибке логируется и метод возвращает `False`.

## Метод: `stop_video()`

Этот метод останавливает запись видео на устройстве с помощью ADB.

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Метод возвращает `True`, если запись видео успешно остановлена, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
stop_status = adb.stop_video()
if stop_status:
print("Запись видео успешно остановлена.")
else:
print("Не удалось остановить запись видео.")
```

### Дополнительная информация

Метод `stop_video()` выполняет команду `adb shell pkill -l SIGINT screenrecord` для остановки записи видео.

### Исключения

Метод обрабатывает исключение, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, информация об ошибке логируется и метод возвращает `False`.

## Метод: `record_video()`

Этот метод начинает запись видео на устройстве с помощью ADB.

### Параметры

- `filename` (`str`): Имя файла, в который будет сохранено видео на устройстве.

### Возвращаемое значение

Метод возвращает `True`, если запись видео успешно начата, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
record_status = adb.record_video("test_video.mp4")
if record_status:
print("Запись видео успешно начата.")
else:
print("Не удалось начать запись видео.")
```

### Дополнительная информация

Метод `record_video()` выполняет команду `adb shell screenrecord /sdcard/Movies/{filename}`, чтобы начать запись видео.

### Исключения

Метод обрабатывает исключение, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, информация об ошибке логируется и метод возвращает `False`.

## Метод: `reboot()`

Этот метод перезагружает устройство с помощью ADB.

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Метод возвращает `True`, если перезагрузка устройства успешно запущена, и `False` в противном случае.

### Пример использования

```python
adb = Adb()
reboot_status = adb.reboot()
if reboot_status:
print("Перезагрузка устройства успешно запущена.")
else:
print("Не удалось запустить перезагрузку устройства.")
```

### Дополнительная информация

Метод `reboot()` выполняет команду `adb shell reboot`, чтобы перезагрузить устройство.

### Исключения

Метод обрабатывает исключение, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, информация об ошибке логируется и метод возвращает `False`.

## Метод: `get_screen_resolution()`

Этот метод возвращает разрешение экрана устройства с использованием ADB.

### Параметры

Метод не принимает никаких параметров.

### Возвращаемое значение

Метод возвращает кортеж с двумя целыми числами, представляющими ширину и высоту экрана в пикселях. Если при выполнении возникает ошибка, метод возвращает `None`.

### Пример использования

```python
adb = Adb()
screen_resolution = adb.get_screen_resolution()
if screen_resolution:
width, height = screen_resolution
print(f"Разрешение экрана устройства: {width}x{height}.")
else:
print("Не удалось получить разрешение экрана устройства.")
```

### Дополнительная информация

Метод `get_screen_resolution()` выполняет команду `adb shell wm size`, чтобы получить физическое разрешение экрана устройства.

### Исключения

Метод обрабатывает исключение, которое может возникнуть при попытке выполнить команду ADB. Если исключение возникает, информация об ошибке логируется и метод возвращает `None`.

Project details


Release history Release notifications | RSS feed

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

AppiumExtended-0.1.34.tar.gz (170.6 kB view hashes)

Uploaded Source

Built Distribution

AppiumExtended-0.1.34-py3-none-any.whl (115.3 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page