Это была пятница, шесть вечера. Я сидел перед монитором и чувствовал себя следователем, который зашёл в тупик.
Три часа назад я нашёл странное поведение в приложении. Открыл Jira, но пока заполнял поля - мысль ушла. На рабочем столе уже лежало 15 скриншотов с именами вроде «Снимок экрана 154312.png». Я открыл их наугад, но уже не помнил, к какому запросу какой относится.
«Я потерял контекст». Баг есть, даже помню, как воспроизвести. Но чтобы восстановить цепочку «действие → реакция сервера → скриншот → вывод» - нужен ещё час.
Знакомо? Я инженер по тестированию, работаю со сложными продуктовыми сценариями, где один баг тянет за собой цепочку из запросов, скриншотов и логов. И с этим сталкиваюсь регулярно.
Проблема не в том, чтобы найти баг. Проблема - зафиксировать ход рассуждений вместе со всеми артефактами так, чтобы через неделю не пришлось восстанавливать контекст с нуля.
Меня зовут Александр. Я перепробовал Jira, Confluence, Notion и просто папки на диске. Всё либо медленно, либо хаотично, либо зависит от интернета. Поэтому я собрал свой локальный редактор - под себя, под тестирование. Делюсь историей и кейсом.
Инструмент я выложил в открытый доступ, ссылка будет в конце. Это не продажа, не условно-бесплатно и не лидогенерация. Просто рабочий пет-проект, которым я сам пользуюсь каждый день.
Почему стандартные инструменты перестали работать
После той пятницы я задумался: почему так вышло?
Ведь у меня под рукой был весь джентльменский набор тестировщика. Я перебрал десяток готовых решений, чем обычно пользуются коллеги, но каждый инструмент имел свои минусы:
Jira и Confluence. Они отличные, но... медленные. Пока я заполню все поля, прикреплю файлы, оформлю описание - я теряю нить рассуждений. Это инструменты для результата, а не для процесса мышления.
Облачные блокноты (Notion, Miro или тот же Google Docs). Они классные для визуализации, но зависимы от интернета. Плюс корпоративная безопасность часто блокирует загрузку файлов или требует согласований.
Файлы на диске. Самый гибкий, но самый хаотичный вариант. Папка Проект_Х → внутри Скриншоты, Логи, Заметки → внутри куча файлов с непонятными датами. Через неделю вернуться к проекту и быстро продолжить работу - сложно и трудозатратно.
Мне нужно было что-то другое. Инструмент, который будет:
Локальным. Чтобы не зависеть от облаков и был всегда под рукой.
Скоростным. Мысль должна фиксироваться быстрее, чем исчезать.
Связным. Чтобы скриншот, JSON ответа и моя заметка лежали рядом.
Визуальным. Чтобы я мог видеть структуру своих мыслей, а не просто читать текст и собирать данные из разных мест.
Потом подумал: а почему бы не собрать такое самому? Под себя. Как удобный рабочий стол, где всё разложено по полкам, но при этом не мешает думать.
Так родилась идея своего редактора, со специализированными инструментами.
Как все начиналось и что под капотом
Я начал изучать различные технологии, фреймворки и подходы. Параллельно посмотрел готовые решения: Obsidian, Logseq, Notion - но они либо не заточены под тестирование, либо требуют доработки плагинами, либо тяжёлые для бытового использования.
Нужно было найти основу, чтобы собрать редактор полностью под себя - быстрый, локальный, с возможностью встраивать свою логику прямо в текст.
Перебрав технологические варианты, я остановился на Flutter. Вот основные причины.
Кроссплатформенность. Flutter позволяет писать один код и собирать под все десктопные платформы без переписывания. Именно эта идея - один код для Windows, macOS и Linux - стала для меня решающей. Статья на Хабре https://habr.com/ru/companies/friflex/articles/966152/ как раз это подтверждала, и я окончательно утвердился в выборе Flutter.
Производительность. Flutter использует собственный движок рендеринга и компилируется в нативный код, что обеспечивает плавность интерфейса даже при работе с тяжелыми блоками . Для редактора, где важно мгновенно отображать изменения, это критично.
Гибкий текстовый редактор. Пакет flutter_quill дал готовую основу с возможностью встраивать свои интерактивные блоки - документация позволяет довольно просто создавать кастомные элементы прямо в тексте. Не пришлось изобретать велосипед.
Архитектура: модульные блоки. Каждый блок - самостоятельный модуль: проверка, дефект, просто текст. Они не зависят друг от друга. Хочешь новый тип блока? Просто создаёшь класс в отдельной папке и регистрируешь его одной строкой - он сразу появляется в редакторе.
Помните главную боль? В Jira я терял мысль, пока сохранял данные. А если страница заметок вырастает до сотен блоков - любая задержка сохранения снова выбивает из контекста.
Поэтому скорость сохранения стала критичным требованием.
Как хранятся данные: диффы вместо монолитов
Чтобы не тормозить при сохранении больших страниц, я сделал дифференциальную систему:
Есть базовый файл content.json - полный слепок страницы
Все изменения пишутся как отдельные диффы (файлы с дельтами)
При загрузке система собирает базовый контент + все диффы по порядку
Когда диффов накапливается много, система автоматически создаёт новый полный снепшот и сбрасывает цепочку. Это даёт:
Моментальное сохранение — на диск пишутся килобайты вместо мегабайтов
Встроенную историю — можно будет добавить откат изменений
Та же история с паузой между действиями. Если сохранение будет дёргать диск после каждого нажатия клавиши - редактор начнёт подтормаживать, и я снова выпаду из процесса.
Моментальное сохранение
Работает через дебаунс: при любом изменении запускается таймер на 2 секунды. Если за это время были новые правки - таймер сбрасывается. Если нет - происходит сохранение. Пока печатаешь - ничего не дёргает диск. Остановился на пару секунд - данные зафиксированы.
Порядок на диске
/storage/
├── items.json # Список всех папок и страниц
├── [page_id]/ # Папка конкретной страницы
│ ├── meta.json # Метаданные: название, даты
│ ├── content.json # Полный слепок контента
│ ├── diff_chain.json # Список диффов в цепочке
│ ├── diff/ # Отдельные файлы диффов
│ │ ├── 1700000000000.diff.json
│ │ └── 1700000001000.diff.json
│ ├── attachments/ # Прикреплённые файлы
│ │ ├── screenshot1.png
│ │ └── log.txt
У каждой страницы своя папка с данными, внутри:
Всё разложено по полкам. Даже если открыть папку в проводнике - сразу понятно, что где лежит.
Код, конечно, писал не я один - без помощи ИИ (спасибо, Deepseek) пришлось бы в разы дольше разбираться с нюансами используемых библиотек. Так что значительную часть рутины отдал нейросети - сам занимался архитектурой и логикой.
Разбор одного рабочего кейса - Тестирование формы авторизации
Хватит теории. Давайте посмотрим, как мое приложение работает на реальной задаче, которых возникает у любого тестировщика в день по несколько штук.
Я намеренно выбрал простой кейс - форму авторизации по номеру телефона, чтобы не углубляться в сложную бизнес-логику, а сфокусироваться именно на процессе работы с инструментом.
1. Анализ требований и генерация идей (вход в контекст)
Утром я получаю задачу: «Проверить новую форму авторизации по номеру телефона». Раньше я создал бы папку «Авторизация_20251023» на рабочем столе и текстовый файлик с мыслями. Теперь я действую иначе: открываю своё приложение (оно всегда запущено и висит на втором мониторе) и создаю новую страницу. На это уходит 3 секунды (локальность и скорость).

Первым делом я не пишу тест-кейсы, я просто начинаю фиксировать требования, мысли и вопросы:

Я оформляю не только текстом, а сразу добавляю блоки проверок - это специальные элементы в моём приложении, которые содержат кнопки для отметки о выполнении и область для вложения файлов. Это и есть реализация принципа «связности»: я заранее создаю структуру, в которую потом буду складывать доказательства (фактические результаты).
2. Процесс тестирования: фиксация результатов «на лету»
Запускаю сборку. Начинаю двигаться по своему списку.
Ввожу тестовый номер в 11 цифр. Нажимаю «Получить код». Код успешно отправлен и получен. Я выполняю действия:
Делаю скриншот, сразу с копированием в буфер обмена
Отмечаю проверку как выполненную
Нажимаю “Вставить” и скриншот сразу прикрепляется к выполняемой проверке

И далее аналогично по остальным проверкам заполняя результаты и прикладывая все необходимые файлы.
Весь мой рабочий процесс теперь выглядит как единый поток: мысль -> действие (ввод данных) -> результат (скриншот или другие вложения) -> новая мысль (заметка о баге или вопросе). И всё это в одном окне, в хронологическом порядке.
3. Возврат к контексту через неделю
Проходит неделя. Меня отвлекали на другие срочные задачи. И тут разработчик пишет: «Я всё поправил по авторизации.».
Редактор у меня уже открыт, нахожу документ по авторизации и… я мгновенно возвращаюсь в контекст. Я вижу все записи, проверки, файлы … а главное все визуально понятно - что проверено, какие были проблемы и что осталось проверить

Мне не нужно лезть в старые чаты, искать скриншоты в куче папок или вспоминать, что я имел в виду под «кривой авторизацией». Вся история исследования, со всеми артефактами и выводами, лежит передо мной. Именно это ощущение - исчезновение страха «потерять контекст» и было главной целью создания приложения.
Почему это сработало?
Потому что инструмент перестал быть просто местом для хранения информации. Он стал средой, где мысль материализуется и остается связанной с доказательствами. Я не трачу силы на организацию хаоса, я трачу их на исследование продукта.
Оглядываясь на этот кейс, я понял, что все те пункты, которых мне не хватало в стандартных инструментах, здесь закрылись сами собой:
Локальность. Всё хранится на диске, интернет не нужен — хоть на даче работай.
Скорость. Мысль фиксируется мгновенно: не надо ждать, пока загрузится Jira или откроется нужная папка.
Связность. Скриншот, JSON ответа и заметка теперь действительно лежат рядом - в одном документе, привязанные к конкретной проверке.
Визуальность. Я вижу структуру: где проверки пройдены, где нет, к чему приложены файлы и что осталось без внимания.
А как у вас? Как вы фиксируете результаты исследовательского тестирования? Пишете сразу в баг-трекинг, ведёте черновики или надеетесь на память? Поделитесь в комментариях - интересно, кто как выкручивается.
Что осталось за кадром (пока)
Как обычно в pet-проектах, идей гораздо больше, чем рук. Самая амбициозная - локальный AI-ассистент, который анализирует содержимое страницы и помогает с тест-дизайном.
Задумка такая: через llama.cpp подключаешь локальную модель, а она смотрит на твои проверки, дефекты и запросы - и подсказывает, чего не хватает, подсвечивает противоречия или предлагает граничные случаи. Код даже начал писать, но быстро понял: стабильность базовых функций важнее экспериментов с нейросетями.
Так что AI пока в заморозке. Но когда редактор перестанет падать, а блоки будут вставляться без сюрпризов - обязательно вернусь к этой идее.
Если есть желание пощупать инструмент своими руками, бету можно забрать по ссылке https://qabox.ru/. Буду рад обратной связи и живым баг-репортам.