
Привет, Хабр! Меня зовут Михаил Химей, и я работаю тестировщиком в команде МТех (МВидео). В процессе проведения регрессионных тестов я подумал, что сохранение всей информации в блокноте или браузере гугла может быть не самым удобным решением. Моя первая мысль была о том, как можно упростить этот процесс, сделав так, чтобы с помощью горячей клавиши можно было быстро получить доступ к необходимым данным.
Так, сначала я решил поискать готовые решения, которые могли бы облегчить мне работу. После нескольких часов поиска, который не дал особого результата, мне пришла идея: почему бы самому не создать такое приложение? После этого я пошел искать библиотеку, которая позволила бы мне реализовать задуманное и здесь время потраченное на поиск окупило себя: я нашел библиотеку keyboard — в первое время мне не требовалась графическая оболочка, достаточно было того, что оно запускается прямо из VSCode.
Когда я написал первую версию приложения, я понял, что она вполне удобна в использовании. Однако, если мне нужно было вносить изменения в настроенные параметры программы или изменять горячие клавиши, то это было несколько неудобно, так как приходилось лезть в код программы.
Реализация интерфейса
В связи с озвученными ранее трудностями, я задался новой целью: создать легкий и интуитивно понятный графический интерфейс. Для этого я нашел и в дальнейшем использовал библиотеку eel. Данная библиотека позволила мне создать интерфейс, который легко адаптировать под свои нужды. И благодаря ей в Capykey появилась возможность быстро менять информацию и горячие клавиши.



У кого то может появится вопрос, что это за мишки, но это не мишки, это капибары.
Изначально должна была отображаться какая-нибудь буква, либо горячие клавиши, но Лена (моя жена, в далее по тексту буду часто использовать это имя) сказала не быть занудой и добавить капибар, так и появилось название программы Capykey(Capybara + hotkey) с иконками капибар.
Изначально, я пользовался только горячими клавишами, у меня была вот такая классная дополнительная клава с клавишами от F13-F26. И при нажатии на клавишу вставлялась нужная мне ссылка или текстовые данные. С ней было работать очень удобно, но Лена её решила забрать себе, когда начала в своей работе использовать моё приложение.

Без этой дополнительной клавиатуры мне стало неудобно вставлять текст с помощью горячих клавиш (хотя тут конечно субъективно, ибо мой знакомый использует Numpad и ему в принципе достаточно), а заказывать и ждать не хотелось, было решено посмотреть, что ещё есть в библиотеке keyboard. Так, я обнаружил, что я могу добавить функционал по созданию аббревиатур, которые автоматически заменяются на нужные значения.
Самый простой пример того, как это работает: я создам аббревиатуру ДДК, на которую поставляю значение “Добрый день, коллеги”. Далее я зайду в чат с коллегами, напишу ДДК и после нажатия пробела три буквы превратятся в предложение.
Это оказалось намного удобнее изначального способа с горячей клавишей и в будущем позволило мне более гибко настраивать действия в приложении:


Запуск приложений по горячим клавишам
Затем для того чтобы сделать управление приложениями еще более удобным, я решил добавить функциональность запуска приложений/файлов по горячим клавишам. Первая версия этой функции не была совершенной, так как требовала вручную прописывать полный путь к исполняемому файлу или приложению, поэтому, спустя время, было решено автоматизировать этот процесс.
Мне удалось внедрить задуманное, но первая версия этого автоматического поиска пути к файлу или программе мне не нравилась, так как поиск пути программ занимал от 2 до 5 минут. Поработав над этой функциональностью снова, я сократил это время, и теперь поиск занимает не больше минуты. Помимо этого, к автоматическому поиску я добавил более удобную возможность задания пути вручную, с помощью выбора из проводника:

Расширение функционала
Так как спустя какое то время Лена, также работающая тестировщиком, обратила внимание на мою программу и начала активно ее использовать, я понял, что теперь моя программа должна быть более стабильной и удобной не только для меня, но и для других пользователей.
Тут нужно небольшое пояснение, скриншоты которые я приложил, это версия Capykey которая выглядит уже хорошо из старых версий у меня осталась одна картинка:

После анализа статистики (не большой, но все же статистики) использования программы как мной, так и близких с друзьями, стало ясно, что есть потенциал для добавления новых функций.
Кроме того, многочисленные спорные решения, которые я принимал в начале разработки и которые, казалось, не имели практической ценности, начали находить своё применение. Например, возможность работы с командной строкой с помощью горячих клавиш выглядела спорно, но мой знакомый с помощью этого запускает свой сервер, то есть выяснилось, что каждый, кто начал пользоваться программой нашел в ней что-то для себя, даже если ранее я считал, что этот функционал бесполезен.
В тот момент я подумал, что моя программа уже достаточно функциональна, но, как оказалось, это была только начальная точка.
Спустя какое-то время, когда я использовал буфер обмена на своем телефоне, мне пришла идея добавить подобную функцию в свой инструмент. Этот буфер обмена мог бы сохранять всю скопированную информацию, и пользователь мог бы легко извлечь её в любой момент. (Позднее я узнал, что операционная система Windows уже имеет подобную функцию, но на тот момент моя мотивация не знала границ, и я реализовал этот функционал в своей программе)
Дальше я начал думать, что можно вообще сделать с этим буфером, зачем мне пользоваться им, если можно использовать буфер от windows, и так было решено добавить всякие фичи, такие как, возможность редактирования, перевод, создания переменных на основе скопированных данных, а самое ключевое это скрестить буфер и макросы, но об этом чуть позже.





Также помимо большого буфера было решено создать мини-буфер, чтобы было удобно запускать его из трея, помимо этого я решил сделать возможность вызывать его с помощью CTRL+ALT. (Мини буфер был написан с использованием библиотеки customtkinter)

Позже я столкнулся с тем, что мне нужно перенести данные, забитые в Capykey с компьютера на ноутбук и понял, что это реализовано не очень удобно, ибо если переносишь файл, он перезаписывался. Так я сделал полноценную возможность сохранять и загружать файл с возможностью перезаписи или создания как копии:

Улучшаем структуру
Затем, после 4 месяцев использования Capykey, я пришел к тому, что хранение информации на одной общей странице приложения напоминает свалку, раньше на одной странице могло быть сразу и ссылки на стенды, товары, запуск программ для работы, запуск личных программ.
Так решение было очевидным — создать структуру папок, чтобы более удобно организовать макросы в соответствии с их функциональностью:

От идеи до воплощения прошло немного времени и сейчас можно создать разные страницы (папки), например, в одной у меня стенды, в другой тестовые данные и если мне не нужна данная страница (папка) в текущий момент, я просто выключаю её и могу не запускать ненужные макросы.

Также чтобы разгрести весь завал на одной странице пришлось реализовать кнопку переноса из одной папки в другую:


Чуть ранее я уже завел речь о том что я добавил функцию буфера и описал ее возможности в общем, пришло время рассказать про буфер + макрос подробнее. Это дается труднее всего для понимания тем, кто пользуется моей программой, но я постараюсь объяснить понятно, что я сделал:
Для лучшего понимания давайте рассмотрим на примере запроса SQL:
У нас есть сокращение SF, на которое забито значение с запросом, которое часто может использоваться у тех, кто работает с БД:
SELECT * FROM demo
.Но тут проблема, а если таблица не demo, а имеет какое-то другое название? Тут как раз нам поможет переменная
{{bufer}}
, мы задаем значение:SELECT * FROM {{bufer}}
Далее мы можем просто скопировать название таблицы, вводим
SF
нажимаем пробел и в итоговом тексте будет выведен наш запрос с корректным названием таблицы, которое мы копировали в буфер.Для того чтобы связать буфер и макрос, достаточно при создании/редактирования макроса добавить в нужное место переменную
{{bufer}}
, что позволяет получить данные из текущего буфера обмена. Важно заметить, что тут есть минус в виде задержки в 3 секунды на обновление данных, но я все еще активно борюсь с этим.Но даже с этим минусом мне достаточно скопировать трейс-айди из запроса и нажать горячую клавишу, чтобы вставить готовую ссылку и перейти на страницу логов, что очень упрощает работу:

Также у данной фичи есть разновидности, если скопировать данные через точку запятой, можно получить массив буфера и расположить его в разных местах с помощью переменной
{{buferArray_0}}
например запрос SQL:SELECT * FROME {{buferArray_0}} WHERE {{buferArray_1}} LIKE {{buferArray_2}}
Далее копируем значения в такой форме
demo;test;id
и вместо переменной buferArray_n
мы выведем результат со значениемSELECT * FROME demo WHERE test LIKE id

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

Например, мы создали макрос с информацией о товарах
Mvideo.ru/product/1331
Mvideo.ru/product/1222
И тут бац, нам нужно
mvideo.ru
изменить на mvideo2.ru
вроде мелочь, но необходимо заходить в каждый макрос и менять, а если их 20 штук, то придется потратить энное время, чтобы изменить везде, вот для этого и нужна переменная, в которую мы можем придумать любое название, например {{stand}}
, добавить его в макрос {{stand}}/product/1331
, и теперь нам достаточно изменить информацию в переменной и он автоматом изменит везде.Также благодаря переменным появились следующие функции: «Рандом слова»,
randomSTR_text
— указывается в названии переменной, randomSTR_
обязательная часть, text-
любое название, В поле «Введите текст вывода» указывается слова/предложения, разделителем считается ";"
Пример: «Валерия; Арина; Ярослав»
«Рандом числа»,
randomINT_text
— указывается в названии переменной, randomINT_ обязательная часть, text- любое название,В поле «Введите текст вывода» указывается 2 числа и обязательное значение которые отвечает на целое число или с запятой int/float разделителем считается ";"
Пример: «100;200;int». Также в макросе можно указать
{{day}}
и получить текущий день или {{month}}
текущий месяц в виде числа или {{year}}
текущий год.Эти функции делают использование инструмента более гибким и мощным, позволяя автоматизировать множество задач.
Заключение
Кажется, это может вызвать улыбку или, возможно, вы думаете, что существуют аналогичные программы. Так, уже позже я понял, что некоторый функционал есть у программы Punto Switcher. Но все же, это был прикольный вызов, и я рад, что у моей программы есть несколько пользователей, которым она понравилась и которые активно используют её, ведь изначально писал её только для себя.
Capykey значительно упростил мою работу. Можно забыть о необходимости помнить, где хранятся данные о каждом пользователе или огромном количестве товаров, как в моем случае. Эта программа помогла мне значительно увеличить эффективность и скорость проведения тестирования.