Записывает действия пользователя на веб-страницах и воспроизводит их. Stateless — флоу хранятся на внешнем API.
- Открой
chrome://extensions - Включи Developer mode (тумблер справа сверху)
- Нажми Load unpacked
- Выбери папку
record-and-repeat-chrome-ext - Расширение появится с иконкой пазла — готово
- Открой страницу, на которой хочешь записать действия (напр. LinkedIn)
- Кликни на иконку расширения в тулбаре Chrome (пазл → Record & Repeat)
- Нажми Start Recording — кнопка станет красной, на иконке появится бейдж
REC - Делай что обычно делаешь — кликай, заполняй поля, выбирай из дропдаунов
- Клики записываются автоматически
- Ввод текста записывается когда уходишь из поля (клик в другое место или Tab)
- Enter / Tab / Escape тоже записываются
- Переходы между страницами записываются автоматически
- Когда закончил — снова кликни на иконку расширения и нажми Stop Recording
- Результат:
- Если настроен endpoint — флоу сохранится, получишь Flow ID
- Если нет — нажми Copy JSON чтобы скопировать записанный сценарий
- Открой любую вкладку
- Кликни на иконку расширения
- Вставь Flow ID (или через "paste JSON" — вставь JSON напрямую)
- Нажми Execute
- Расширение откроет нужную страницу и выполнит все шаги
- Прогресс виден в попапе (Step 3/10: click "Submit"...)
- Если элемент не найден и настроен Gemini API key — сработает LLM fallback
Кликни Settings внизу попапа:
| Поле | Зачем |
|---|---|
| API Endpoint | URL сервера для хранения флоу. POST /flows для сохранения, GET /flows/:id для загрузки |
| Gemini API key | Ключ от Google AI Studio для LLM fallback. Если элемент не найден обычными способами, расширение спросит Gemini Flash где он. Получить ключ |
Оба поля опциональны. Без endpoint — копируй JSON руками. Без Gemini key — LLM fallback просто не работает.
Сохранение:
POST {endpoint}/flows
Content-Type: application/json
{
"steps": [...],
"metadata": {
"startUrl": "https://...",
"recordedAt": "2026-03-28T...",
"stepCount": 12
}
}
→ { "id": "abc123" }
Загрузка:
GET {endpoint}/flows/{id}
→ { "steps": [...], "metadata": {...} }
При воспроизведении расширение пробует найти элемент в таком порядке:
- ID —
#submit-btn - data-testid —
[data-testid="login-form"] - aria-label —
[aria-label="Close dialog"] - name —
[name="email"] - placeholder —
[placeholder="Enter your email"] - CSS selector — записанный при записи
- XPath — записанный при записи
- Текст — точное совпадение, потом частичное
- LLM fallback — если ничего не сработало: снимок страницы → Gemini Flash → новый CSS selector
Каждая стратегия ретраится 10 секунд (элемент может появиться с задержкой).
{
"action": "click",
"find": {
"tag": "BUTTON",
"id": "submit-btn",
"text": "Submit Application",
"ariaLabel": "Submit your application",
"selector": "#submit-btn",
"xpath": "//*[@id=\"submit-btn\"]"
},
"timestamp": 1711648005000
}Действия: click, fill (+ value), select (+ value, optionText), keypress (+ key), navigate (+ url), wait.
Один сценарий можно использовать для разных данных — подставляй переменные через {{name}}:
Flow с параметрами:
{
"parameters": {
"jobTitle": "Software Engineer",
"location": "Remote",
"company": "Acme Corp"
},
"steps": [
{
"action": "fill",
"find": { "id": "job-title" },
"value": "{{jobTitle}}"
},
{
"action": "fill",
"find": { "name": "location" },
"value": "{{location}}"
},
{
"action": "click",
"find": { "text": "Post Job" }
}
]
}При выполнении (в поле Parameters popup'а):
{
"jobTitle": "Senior Developer",
"location": "New York"
}Результат: "Software Engineer" → "Senior Developer", "Remote" → "New York", "company" остаётся "Acme Corp" (дефолт).
Использование:
- Запиши процесс создания вакансии один раз
- Вручную замени захардкоженные значения на
{{jobTitle}},{{description}}и т.д. - Запускай с разными параметрами — один flow на все вакансии
manifest.json — MV3 манифест, permissions, content scripts
content.js — запись действий + воспроизведение + DOM-to-MD + LLM fallback
background.js — координация, API, Gemini вызовы
popup.html/css — UI расширения
popup.js — логика попапа