autoreg-skills-max: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok60915d52e8425
2026-10-20 02:16:32 +03:00
commit f58eafeb48
565 changed files with 60064 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
---
name: playwright-react-spa
description: Браузерная автоматизация React/Next.js SPA через Playwright — обход controlled inputs, детекция навигации, клики по кнопкам, отладка.
triggers:
- playwright + react
- fill() не работает
- type() не работает
- controlled input
- кнопка не кликается
- страница не детектит переход
- SPA навигация
- OpenAI регистрация
- Camoufox
- headed browser registration
- авторег ChatGPT
references:
- openai-reg-flow.md — схема регистрации OpenAI, таблицы БД, формат кодов
---
# Playwright: автоматизация React SPA
Ключевые паттерны для работы с React/Next.js одностраничниками, где стандартные Playwright-методы (`fill`, `type`, `click`) не работают из-за React-controlled компонентов.
## 1. JS injection — обход React controlled inputs
React перехватывает `input.value` через свой synthetic event system. Playwright `fill()` / `type()` могут не сработать или сброситься. Решение: использовать `page.evaluate()` с native setter'ом.
```python
page.evaluate(f"""
(() => {{
const otp = '{code}';
const inputs = document.querySelectorAll('input[inputmode="numeric"], input[autocomplete="one-time-code"], input[type="tel"], input[type="number"], input[type="text"]');
for (const input of inputs) {{
if (input.offsetParent !== null) {{
const nativeSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value').set;
nativeSetter.call(input, otp);
input.dispatchEvent(new Event('input', {{ bubbles: true }}));
input.dispatchEvent(new Event('change', {{ bubbles: true }}));
break;
}}
}}
}})()
""")
```
**Порядок важен**: `page.wait_for_selector(..., state="visible", timeout=10000)` перед injection, затем `page.wait_for_load_state("networkidle")` а не `domcontentloaded`.
## 2. Детекция навигации в SPA
React SPA меняет контент без смены URL. `page.url` может оставаться `/email-verification`, а заголовок уже `How old are you?`. Всегда проверять **оба**:
```python
current_url = page.url
page_title = page.title()
if ("target-path" not in current_url) or ("expected title" in page_title.lower()):
return success
```
Никогда не полагаться только на URL.
## 3. Клик по кнопкам в React SPA
Playwright `locator.click()` часто падает с таймаутом даже когда элемент видим. Приоритет: **JS `btn.click()` > `form.requestSubmit()` > Playwright selectors**.
```python
page.evaluate("""
(() => {
const buttons = document.querySelectorAll('button');
for (const btn of buttons) {
const text = (btn.textContent || '').toLowerCase();
if (text.includes('continue') || text.includes('finish creating account') || btn.type === 'submit') {
if (btn.offsetParent !== null) {
btn.click();
return 'clicked:' + text.trim().substring(0,30);
}
}
}
// Fallback: submit the form
const forms = document.querySelectorAll('form');
for (const f of forms) {
if (f.offsetParent !== null) {
f.requestSubmit();
return 'form_submitted';
}
}
return 'no_button';
})()
""")
```
## 4. Python .pyc cache — всегда чистить перед рестартом
После правок `.py` файлов Python может грузить старый `.pyc`. Перед перезапуском сервера:
```bash
find "/path/to/project" -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null
find "/path/to/project" -name "*.pyc" -delete 2>/dev/null
```
## 5. Отладка: скриншоты и HTML-дампы
Когда автоматизация падает на странице — сохранять **и скриншот, и HTML**:
```python
page.screenshot(path=f"debug_{ts}.png", full_page=True)
with open(f"debug_{ts}.html", "w") as f:
f.write(page.content())
```
⚠️ `page.content()` возвращает **статический HTML** (React shell), не rendered DOM. Для понимания реального состояния страницы — смотреть **только скриншот**. HTML показывает лишь заголовок `<title>`.
## 6. Ожидание загрузки React-компонентов
```python
# Неправильно — только DOM
page.wait_for_load_state("domcontentloaded", timeout=5000)
# Правильно — ждать сеть + специфичные элементы
page.wait_for_load_state("networkidle", timeout=15000)
page.wait_for_selector("input[inputmode='numeric'], input[autocomplete='one-time-code']", state="visible", timeout=10000)
time.sleep(2) # дополнительно для React hydration
```
## Pitfalls
- **Не ждать только `domcontentloaded`** — React рендерит асинхронно, контента ещё нет.
- **Не проверять только `page.url`** — SPA меняет контент без смены URL, проверять `page.title()`.
- **Не использовать `element.fill()` / `element.type()`** на React controlled inputs — использовать JS native setter.
- **Исключение — multi-box OTP-сетки (auto-advance)**: `keyboard.type(code)` гонит с авто-advance/перемещением фокуса и ТИХО переставляет цифры — страница показывает «Invalid one-time code», а введённая последовательность ≠ ожидаемой. Надёжный способ = посимвольный `locator.fill(char)` в каждый видимый инпут (nth(k) по `input:visible`), затем ждать автосабмит ~6с; при ошибке не перенабирать, а resend + повторный поллинг почты с фильтром свежести (min_ts).
- **Playwright `click()` на кнопках** часто таймаутит даже на видимых элементах — предпочитать JS `btn.click()`.
- **Python кеширует `.pyc`** — после правок всегда чистить `__pycache__`.
- **`page.content()` показывает React shell**, а не rendered DOM — для отладки смотреть скриншот.
- **"Illegal invocation" в `page.evaluate()`**: `Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, 'value').set` бросает "Illegal invocation" когда вызывается из `page.evaluate()` в Playwright (this-binding ломается). Это работает в MCP-браузере (`evaluate_script`) но НЕ в Playwright. Для Playwright использовать `page.fill()` + `page.click()` или `page.evaluate()` с `arguments` вместо замыкания.
- **Headless Chromium блокируется Cloudflare**: использовать `launch(channel="chrome", headless=False)` для обхода.

View File

@@ -0,0 +1,42 @@
# OpenAI ChatGPT Registration — Browser Flow Details
## Registration state machine (NextAuth)
1. **chatgpt.com** → click "Sign up" → email form
2. **auth.openai.com/email-verification** — submit email → get CSRF token → redirect
3. **email-verification page** — shows "Check your inbox" title initially
4. After OTP code received via IMAP → fill code → page transitions to:
5. **"How old are you?"** (age/DOB) — URL STILL has `email-verification`!
6. **about_you** — full name + birthdate form
7. **"Finish creating account"** button → redirect to chatgpt.com
## Critical observation
After OTP is accepted, the page title changes to "How old are you? - OpenAI" but the URL remains `https://auth.openai.com/email-verification`. URL-based navigation detection fails — MUST check `page.title()`.
## Button text variants observed
- OTP page: "Continue" (visible after code filled)
- Age page: "Continue"
- About you page: **"Finish creating account"** — different from "Continue"!
## IMAP verification codes
- Code format: 6 digits (e.g., `023178`, `255115`, `310238`, `672062`, `048042`)
- Received from: `noreply@openai.com` or similar
- Subject typically contains "verification code" or "security code"
- IMAP `wait_for_code` timeout: 120 seconds default
- t-online.de emails are throttled/blocked by OpenAI (observed: 3/15 successful delivery)
## DB schema (account_manager.db)
Key tables:
- `accounts` — id, platform, email, password, user_id
- `account_credentials` — account_id, scope, credential_type, key, value, is_primary
- `account_overviews` — lifecycle_status, validity_status, plan_state
- `provider_settings` — IMAP config in config_json (imap_pool_file, imap_host, imap_port)
- `tasks` — id, type, status, progress_current/total, success_count, error_count
## Provider settings fix done
Changed `imap_pool_file` from `C:/Users/User/Desktop/solenne_de_emails.txt` to `C:/Users/User/Desktop/GPT-AUTOREG/emails.txt` in `provider_settings.config_json`.