Closed boludoz closed 3 months ago
mhh nope, there's more needed than that. This will only work for input, not key events & is detectable.
Sorry, I thought insert was even more detectable, I'll just add it to my personal code as a monkey patch to make completing OTPs easier.
mhh nope, there's more needed than that. This will only work for input, not key events & is detectable.
Sorry, I thought insert was even more detectable, I'll just add it to my personal code as a monkey patch to make completing OTPs easier.
Indeed, elem.write
might be more detectable.
Tho, I'd prefer to directly implement it the right way:)
Will do as soon I find some time👀
mhh nope, there's more needed than that. This will only work for input, not key events & is detectable.
Sorry, I thought insert was even more detectable, I'll just add it to my personal code as a monkey patch to make completing OTPs easier.
Indeed,
elem.write
might be more detectable. Tho, I'd prefer to directly implement it the right way:)Will do as soon I find some time👀
This code is wonderful. I only found two problems with this driver, the first is the click, it doesn't always click, suppose there is a banner and a button below it, the code will fail silently. The other issue is asynchronicity within the same code, certain codes that will be executed simultaneously will generate an error in the websocket but I know that it is a feature that you plan to improve when you have time. But as I told you, this code is a lost gem, the mere fact that it is undetectable and the concept you implemented in managing iframes is incredible.
You could use the CDP kit and add it here, that would make your job a lot easier because it is generated automatically.
I congratulate you for this excellent job, I'm nobody but you should be working in security companies or something like that, I hope you are already doing it.
And if you want, I can make a complete implementation of send_keys, you just have to tell me what feature you want me to add and if you like the result, you can add it without commitment.
And if you want, I can make a complete implementation of send_keys, you just have to tell me what feature you want me to add and if you like the result, you can add it without commitment.
Basend on the following code:
async def keyboard(driver, text):
if text == 'Enter':
key_event = {
"type": "keyDown",
"code": "Enter",
"windowsVirtualKeyCode": 13,
"key": "Enter",
"modifiers": 0
}
await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event)
await asyncio.sleep(uniform(0.02, 0.7))
# Simulate key press for the actual character
key_event["type"] = "char"
key_event["text"] = text
await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event)
await asyncio.sleep(uniform(0.02, 0.7))
del key_event['text']
# Simulate key release
key_event["type"] = "keyUp"
await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event)
await asyncio.sleep(uniform(0.02, 0.7))
elif text == 'Tab':
key_event = {
"type": "keyDown",
"code": "Tab",
"windowsVirtualKeyCode": 9,
"key": "Tab",
"modifiers": 0
}
await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event)
await asyncio.sleep(uniform(0.02, 0.7))
# Simulate key release
key_event["type"] = "keyUp"
await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event)
await asyncio.sleep(uniform(0.02, 0.7))
else:
key_mapping = {
'a': ('KeyA', 65), 'b': ('KeyB', 66), 'c': ('KeyC', 67), 'd': ('KeyD', 68), 'e': ('KeyE', 69),
'f': ('KeyF', 70), 'g': ('KeyG', 71), 'h': ('KeyH', 72), 'i': ('KeyI', 73), 'j': ('KeyJ', 74),
'k': ('KeyK', 75), 'l': ('KeyL', 76), 'm': ('KeyM', 77), 'n': ('KeyN', 78), 'o': ('KeyO', 79),
'p': ('KeyP', 80), 'q': ('KeyQ', 81), 'r': ('KeyR', 82), 's': ('KeyS', 83), 't': ('KeyT', 84),
'u': ('KeyU', 85), 'v': ('KeyV', 86), 'w': ('KeyW', 87), 'x': ('KeyX', 88), 'y': ('KeyY', 89),
'z': ('KeyZ', 90), 'A': ('KeyA', 65), 'B': ('KeyB', 66), 'C': ('KeyC', 67), 'D': ('KeyD', 68),
'E': ('KeyE', 69), 'F': ('KeyF', 70), 'G': ('KeyG', 71), 'H': ('KeyH', 72), 'I': ('KeyI', 73),
'J': ('KeyJ', 74), 'K': ('KeyK', 75), 'L': ('KeyL', 76), 'M': ('KeyM', 77), 'N': ('KeyN', 78),
'O': ('KeyO', 79), 'P': ('KeyP', 80), 'Q': ('KeyQ', 81), 'R': ('KeyR', 82), 'S': ('KeyS', 83),
'T': ('KeyT', 84), 'U': ('KeyU', 85), 'V': ('KeyV', 86), 'W': ('KeyW', 87), 'X': ('KeyX', 88),
'Y': ('KeyY', 89), 'Z': ('KeyZ', 90), '0': ('Digit0', 48), '1': ('Digit1', 49), '2': ('Digit2', 50),
'3': ('Digit3', 51), '4': ('Digit4', 52), '5': ('Digit5', 53), '6': ('Digit6', 54), '7': ('Digit7', 55),
'8': ('Digit8', 56), '9': ('Digit9', 57), '!': ('Digit1', 49), '"': ('Quote', 222), '#': ('Digit3', 51),
'$': ('Digit4', 52), '%': ('Digit5', 53), '&': ('Digit7', 55), "'": ('Quote', 222), '(': ('Digit9', 57),
')': ('Digit0', 48), '*': ('Digit8', 56), '+': ('Equal', 187), ',': ('Comma', 188), '-': ('Minus', 189),
'.': ('Period', 190), '/': ('Slash', 191), ':': ('Semicolon', 186), ';': ('Semicolon', 186), '<': ('Comma', 188),
'=': ('Equal', 187), '>': ('Period', 190), '?': ('Slash', 191), '@': ('Digit2', 50), '[': ('BracketLeft', 219),
'\\': ('Backslash', 220), ']': ('BracketRight', 221), '^': ('Digit6', 54), '_': ('Minus', 189), '`': ('Backquote', 192),
'{': ('BracketLeft', 219), '|': ('Backslash', 220), '}': ('BracketRight', 221), '~': ('Backquote', 192), ' ': ('Space', 32)
}
for letter in text:
if letter in key_mapping:
key_code, virtual_key_code = key_mapping[letter]
# Determine if shift key is needed
shift_pressed = False
if letter.isupper() or letter in '~!@#$%^&*()_+{}|:"<>?':
shift_pressed = True
await driver.execute_cdp_cmd("Input.dispatchKeyEvent", {
"type": "keyDown",
"code": "ShiftLeft",
"windowsVirtualKeyCode": 16,
"key": "Shift",
"modifiers": 8 if shift_pressed else 0
})
await asyncio.sleep(uniform(0.05, 0.1)) # Simulate human typing speed
key_event = {
"type": "keyDown",
"code": key_code,
"windowsVirtualKeyCode": virtual_key_code,
"key": letter,
"modifiers": 8 if shift_pressed else 0
}
# Send keydown event
await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event)
await asyncio.sleep(uniform(0.05, 0.1))
# Simulate key press for the actual character
key_event["type"] = "char"
key_event["text"] = letter
await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event)
await asyncio.sleep(uniform(0.05, 0.1))
del key_event['text']
# Simulate key release
key_event["type"] = "keyUp"
await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event)
await asyncio.sleep(uniform(0.05, 0.1))
# Release the shift key if it was pressed
if shift_pressed:
await driver.execute_cdp_cmd("Input.dispatchKeyEvent", {
"type": "keyUp",
"code": "ShiftLeft",
"windowsVirtualKeyCode": 16,
"key": "Shift",
"modifiers": 0
})
await asyncio.sleep(uniform(0.05, 0.1)) # Simulate human typing speed
add a class similar to https://github.com/kaliiiiiiiiii/Selenium-Driverless/blob/29204358375fbfcf4025a95a64a128faec6e7f38/src/selenium_driverless/input/keyboard.py
Would be nice to support a custom keyboar layout as well.
Then, add an instance of that class as selenium_driverless.types.target.Target.keyboard
=> add async Target.send_keys
=> make elem.send_keys
first click on it & then Target.send_keys
Notes:
dev
branchYou could use the CDP kit and add it here, that would make your job a lot easier because it is generated automatically.
Mh I prefer to control all the stuff fully & build from scratch. Tho, adding this as an option ofc is considerable.
I congratulate you for this excellent job, I'm nobody but you should be working in security companies or something like that, I hope you are already doing it.
Well fun fact: I'm still in school haha👀
And if you want, I can make a complete implementation of send_keys, you just have to tell me what feature you want me to add and if you like the result, you can add it without commitment.
Basend on the following code:
async def keyboard(driver, text): if text == 'Enter': key_event = { "type": "keyDown", "code": "Enter", "windowsVirtualKeyCode": 13, "key": "Enter", "modifiers": 0 } await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event) await asyncio.sleep(uniform(0.02, 0.7)) # Simulate key press for the actual character key_event["type"] = "char" key_event["text"] = text await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event) await asyncio.sleep(uniform(0.02, 0.7)) del key_event['text'] # Simulate key release key_event["type"] = "keyUp" await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event) await asyncio.sleep(uniform(0.02, 0.7)) elif text == 'Tab': key_event = { "type": "keyDown", "code": "Tab", "windowsVirtualKeyCode": 9, "key": "Tab", "modifiers": 0 } await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event) await asyncio.sleep(uniform(0.02, 0.7)) # Simulate key release key_event["type"] = "keyUp" await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event) await asyncio.sleep(uniform(0.02, 0.7)) else: key_mapping = { 'a': ('KeyA', 65), 'b': ('KeyB', 66), 'c': ('KeyC', 67), 'd': ('KeyD', 68), 'e': ('KeyE', 69), 'f': ('KeyF', 70), 'g': ('KeyG', 71), 'h': ('KeyH', 72), 'i': ('KeyI', 73), 'j': ('KeyJ', 74), 'k': ('KeyK', 75), 'l': ('KeyL', 76), 'm': ('KeyM', 77), 'n': ('KeyN', 78), 'o': ('KeyO', 79), 'p': ('KeyP', 80), 'q': ('KeyQ', 81), 'r': ('KeyR', 82), 's': ('KeyS', 83), 't': ('KeyT', 84), 'u': ('KeyU', 85), 'v': ('KeyV', 86), 'w': ('KeyW', 87), 'x': ('KeyX', 88), 'y': ('KeyY', 89), 'z': ('KeyZ', 90), 'A': ('KeyA', 65), 'B': ('KeyB', 66), 'C': ('KeyC', 67), 'D': ('KeyD', 68), 'E': ('KeyE', 69), 'F': ('KeyF', 70), 'G': ('KeyG', 71), 'H': ('KeyH', 72), 'I': ('KeyI', 73), 'J': ('KeyJ', 74), 'K': ('KeyK', 75), 'L': ('KeyL', 76), 'M': ('KeyM', 77), 'N': ('KeyN', 78), 'O': ('KeyO', 79), 'P': ('KeyP', 80), 'Q': ('KeyQ', 81), 'R': ('KeyR', 82), 'S': ('KeyS', 83), 'T': ('KeyT', 84), 'U': ('KeyU', 85), 'V': ('KeyV', 86), 'W': ('KeyW', 87), 'X': ('KeyX', 88), 'Y': ('KeyY', 89), 'Z': ('KeyZ', 90), '0': ('Digit0', 48), '1': ('Digit1', 49), '2': ('Digit2', 50), '3': ('Digit3', 51), '4': ('Digit4', 52), '5': ('Digit5', 53), '6': ('Digit6', 54), '7': ('Digit7', 55), '8': ('Digit8', 56), '9': ('Digit9', 57), '!': ('Digit1', 49), '"': ('Quote', 222), '#': ('Digit3', 51), '$': ('Digit4', 52), '%': ('Digit5', 53), '&': ('Digit7', 55), "'": ('Quote', 222), '(': ('Digit9', 57), ')': ('Digit0', 48), '*': ('Digit8', 56), '+': ('Equal', 187), ',': ('Comma', 188), '-': ('Minus', 189), '.': ('Period', 190), '/': ('Slash', 191), ':': ('Semicolon', 186), ';': ('Semicolon', 186), '<': ('Comma', 188), '=': ('Equal', 187), '>': ('Period', 190), '?': ('Slash', 191), '@': ('Digit2', 50), '[': ('BracketLeft', 219), '\\': ('Backslash', 220), ']': ('BracketRight', 221), '^': ('Digit6', 54), '_': ('Minus', 189), '`': ('Backquote', 192), '{': ('BracketLeft', 219), '|': ('Backslash', 220), '}': ('BracketRight', 221), '~': ('Backquote', 192), ' ': ('Space', 32) } for letter in text: if letter in key_mapping: key_code, virtual_key_code = key_mapping[letter] # Determine if shift key is needed shift_pressed = False if letter.isupper() or letter in '~!@#$%^&*()_+{}|:"<>?': shift_pressed = True await driver.execute_cdp_cmd("Input.dispatchKeyEvent", { "type": "keyDown", "code": "ShiftLeft", "windowsVirtualKeyCode": 16, "key": "Shift", "modifiers": 8 if shift_pressed else 0 }) await asyncio.sleep(uniform(0.05, 0.1)) # Simulate human typing speed key_event = { "type": "keyDown", "code": key_code, "windowsVirtualKeyCode": virtual_key_code, "key": letter, "modifiers": 8 if shift_pressed else 0 } # Send keydown event await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event) await asyncio.sleep(uniform(0.05, 0.1)) # Simulate key press for the actual character key_event["type"] = "char" key_event["text"] = letter await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event) await asyncio.sleep(uniform(0.05, 0.1)) del key_event['text'] # Simulate key release key_event["type"] = "keyUp" await driver.execute_cdp_cmd("Input.dispatchKeyEvent", key_event) await asyncio.sleep(uniform(0.05, 0.1)) # Release the shift key if it was pressed if shift_pressed: await driver.execute_cdp_cmd("Input.dispatchKeyEvent", { "type": "keyUp", "code": "ShiftLeft", "windowsVirtualKeyCode": 16, "key": "Shift", "modifiers": 0 }) await asyncio.sleep(uniform(0.05, 0.1)) # Simulate human typing speed
add a class similar to https://github.com/kaliiiiiiiiii/Selenium-Driverless/blob/29204358375fbfcf4025a95a64a128faec6e7f38/src/selenium_driverless/input/keyboard.py
Would be nice to support a custom keyboar layout as well.
Then, add an instance of that class as
selenium_driverless.types.target.Target.keyboard
=> add
async Target.send_keys
=> makeelem.send_keys
first click on it & thenTarget.send_keys
Notes:
- Development should be based on
dev
branch- usage of semaphore//lock recommended
But not everyone uses those characters.
mhh nope, there's more needed than that. This will only work for input, not key events & is detectable.