feature: действие typing — ввод как у человека, кириллица (#14)
fill остаётся мгновенным. typing подводит курсор по кривой, кликает в поле, стирает старое значение и набирает текст посимвольно с паузами; символы вне раскладки (кириллица) больше не роняют ввод. Значение typing маскируется в логах. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
49a2f3024a
commit
1075267d27
8 files changed
+74
-25
No files matched your search
@@ -170,3 +170,16 @@ def test_window_held_between_tasks(env):
|
||||
|
||||
assert client.delete("/v2/sessions/current").json() == {"closed": True}
|
||||
assert env.pool.used == 0
|
||||
|
||||
|
||||
def test_typing_like_a_human(client):
|
||||
"""typing: клик по полю и посимвольный ввод, включая кириллицу; поле сначала очищается."""
|
||||
data = solve(client, url="https://httpbin.org/forms/post", actions=[
|
||||
{"type": "fill", "selector": "input[name=custname]", "value": "old value"},
|
||||
{"type": "typing", "selector": "input[name=custname]", "value": "Иван Smith-2"},
|
||||
{"type": "submit", "selector": "form button"},
|
||||
{"type": "inner_text", "selector": "body"},
|
||||
])
|
||||
assert data["status"] == "ok", data
|
||||
assert json.loads(data["actions"][-1]["result"])["form"]["custname"] == "Иван Smith-2"
|
||||
assert data["actions"][1]["duration_ms"] > 12 * 50 # посимвольно, с паузами
|
||||
@@ -13,6 +13,7 @@ def solve(**kwargs) -> SolveRequest:
|
||||
({"type": "wait_for"}, "requires: selector"),
|
||||
({"type": "fill", "selector": "#q"}, "requires: value"),
|
||||
({"type": "fill", "selector": "#q", "value": ""}, "requires: value"),
|
||||
({"type": "typing", "selector": "#q"}, "requires: value"),
|
||||
({"type": "click"}, "requires: selector"),
|
||||
({"type": "delay"}, "requires: value"),
|
||||
({"type": "delay", "value": "abc"}, "integer"),
|
||||
@@ -29,6 +30,8 @@ def test_invalid_action(action, error):
|
||||
@pytest.mark.parametrize("action", [
|
||||
{"type": "wait_for", "selector": "a", "timeout": 10},
|
||||
{"type": "fill", "selector": "#q", "value": "x"},
|
||||
{"type": "typing", "selector": "#q", "value": "Привет"},
|
||||
{"type": "inner_text", "selector": "h1"},
|
||||
{"type": "delay", "value": "0"},
|
||||
{"type": "pass_challenge"},
|
||||
{"type": "captcha", "selector": "#c", "value": "hcaptcha"},
|
||||
|
||||
@@ -180,11 +180,14 @@ def test_secrets_not_logged_nor_stored(env, monkeypatch, caplog):
|
||||
post(
|
||||
env, proxy="http://someuser:TopSecret1@host:3128", captcha="KEYSECRET2", html=True,
|
||||
cookies=[{"name": "sid", "value": "CookieSecret3", "url": "https://example.com"}],
|
||||
actions=[{"type": "fill", "selector": "#p", "value": "PassSecret4"}],
|
||||
actions=[
|
||||
{"type": "fill", "selector": "#p", "value": "PassSecret4"},
|
||||
{"type": "typing", "selector": "#p", "value": "PassSecret5"},
|
||||
],
|
||||
)
|
||||
log = caplog.text
|
||||
assert "Incoming payload" in log and "Outgoing payload" in log
|
||||
for secret in ("someuser", "TopSecret1", "KEYSECRET2", "CookieSecret3", "PassSecret4", "secret-cookie", "<body>page"):
|
||||
for secret in ("someuser", "TopSecret1", "KEYSECRET2", "CookieSecret3", "PassSecret4", "PassSecret5", "secret-cookie", "<body>page"):
|
||||
assert secret not in log
|
||||
|
||||
# в Redis — только результат (там cookies и html страницы), но не секреты запроса
|
||||
|
||||
Reference in new issue
Block a user