CDP-Patches
CDP-Patches copied to clipboard
Patching CDP (Chrome DevTools Protocol) leaks on OS level. Easy to use with Playwright, Selenium, and other web automation tools.
CDP-Patches v1.0
Install it from PyPI
pip install cdp-patches
Or for Full Linting
(Includes: playwright, botright, selenium, selenium_driverless)
pip install cdp-patches[automation_linting]
Leak Patches
Input Package
Concept: Input Domain Leaks
Bypass CDP Leaks in Input domains
For an interaction event e
, the page coordinates won't ever equal the screen coordinates, unless Chrome is in fullscreen.
However, all CDP
input commands just set it the same by default (see crbug#1477537).
var is_bot = (e.pageY == e.screenY && e.pageX == e.screenX)
if (is_bot && 1 >= outerHeight - innerHeight){ // fullscreen
is_bot = false
}
Furthermore, CDP can't dispatch CoalescedEvent
's (demo).
As we don't want to patch Chromium itsself, let's just dispatch this event at OS-level!
Usage
from cdp_patches.input import SyncInput
sync_input = SyncInput(pid=pid)
# Or
sync_input = SyncInput(browser=browser)
# Dispatch Inputs
sync_input.click("left", 100, 100) # Left click at (100, 100)
sync_input.double_click("left", 100, 100) # Left double-click at (100, 100)
sync_input.down("left", 100, 100) # Left mouse button down at (100, 100)
sync_input.up("left", 100, 100) # Left mouse button up at (100, 100)
sync_input.move(100, 100) # Move mouse to (100, 100)
sync_input.scroll("down", 10) # Scroll down by 10 lines
sync_input.type("Hello World!") # Type "Hello World!"
Async Usage
import asyncio
from cdp_patches.input import AsyncInput
async def main():
async_input = await AsyncInput(pid=pid)
# Or
async_input = await AsyncInput(browser=browser)
# Dispatch Inputs
await async_input.click("left", 100, 100) # Left click at (100, 100)
await async_input.double_click("left", 100, 100) # Left double-click at (100, 100)
await async_input.down("left", 100, 100) # Left mouse button down at (100, 100)
await async_input.up("left", 100, 100) # Left mouse button up at (100, 100)
await async_input.move(100, 100) # Move mouse to (100, 100)
await async_input.scroll("down", 10) # Scroll down by 10 lines
await async_input.type("Hello World!") # Type "Hello World!"
if __name__ == '__main__':
asyncio.run(main())
TODO
- [ ] Improve mouse movement timings.
- [ ] Implement extensive testing.
Owner: Vinyzu
Co-Maintainer: Kaliiiiiiiiii
[!IMPORTANT]
By the nature of OS-level events (which can only impact actionable windows), this package can only be used with headful browsers.
[!WARNING]
PressingSHIFT
orCAPSLOCK
manually on Windows affectsinput.type(text) as well.
[!WARNING]
Because Chrome does not recognize Input Events to specific tabs, these methods can only be used on the active tab. Chrome Tabs do have their own process with a process id (pid), but these can not be controlled using Input Events as they´re just engines.
Read the Documentation
Development
Read the CONTRIBUTING.md file.
Copyright and License
© Vinyzu
(Commercial Usage is allowed, but source, license and copyright has to made available. Botright does not provide and Liability or Warranty)