Use arsenic.http for HTTP authentication
mainarsenic.http module provides helpers for handling HTTP authentication. It defines an abstract base class Auth and a concrete implementation BasicAuth for standard Basic Authentication.repository·main·Indexed 16 days ago
https://github.com/hennge/arsenicAn asynchronous WebDriver client built on top of asyncio for browser automation. Arsenic enables testing web applications, load testing, web scraping, and website automation using the Webdriver specification. It supports managing multiple web drivers concurrently and integrating browser control into asynchronous web servers without blocking the event loop. Key features include support for action chains for mouse and keyboard sequences, and integration with pytest-asyncio for testing async web applications.
arsenic.http module provides helpers for handling HTTP authentication. It defines an abstract base class Auth and a concrete implementation BasicAuth for standard Basic Authentication.Arsenic is designed for several automation use cases using real web browsers via the Webdriver specification:
A Tick represents an action tick that can contain multiple actions across different devices. You can combine actions from different devices (e.g., a keyboard press and a mouse movement) into a single Tick using the bitwise OR operator (|).
# Combining a keyboard key down and a mouse move into one tick
tick = keyboard.down('a') | mouse.move_to(element)Arsenic allows you to control web browsers from asynchronous Python code (e.g., using asyncio, aiohttp, or Tornado).
Critical Constraint: While the arsenic library itself is asynchronous, the underlying web drivers are not. This means you must call the arsenic APIs in sequence within your async tasks. The primary benefit of using arsenic is the ability to manage multiple web drivers concurrently (asynchronously) or to integrate web driver control into an asynchronous web server without blocking the event loop.
Arsenic supports action chains, which allow you to define a sequence of mouse and/or keyboard actions to be performed either in sequence or in parallel.
Note on Browser Support: Action chains are natively supported by only a few browsers. For other browsers, Arsenic attempts to emulate these actions using older APIs, but emulation is limited to a single mouse input.
WebDriver, do not instantiate the arsenic.webdriver.WebDriver class directly. Instead, use arsenic.get_session or arsenic.start_session to create and manage the session for you.Arsenic is an asynchronous webdriver client built on asyncio. You can start a local browser session by using get_session with a driver service (like Geckodriver) and a browser implementation (like Firefox).
To use it, wrap the session in an async with block to ensure proper cleanup. Within the session, you can navigate to URLs using await session.get(), locate elements with timeouts using await session.wait_for_element(), and interact with elements like retrieving text via await element.get_text().
from arsenic import get_session
from arsenic.browsers import Firefox
from arsenic.services import Geckodriver
async def example():
# Runs geckodriver and starts a firefox session
async with get_session(Geckodriver(), Firefox()) as session:
# go to example.com
await session.get('http://example.com')
# wait up to 5 seconds to get the h1 element from the page
h1 = await session.wait_for_element(5, 'h1')
# print the text of the h1 element
print(await h1.get_text())To use arsenic, you need Python 3.6, Firefox, and geckodriver.
chmod +x geckodriver.python3.6 -m venv env.env/bin/pip install --upgrade pip.env/bin/pip install --pre arsenic.python3.6 -m venv env
env/bin/pip install --upgrade pip
env/bin/pip install --pre arsenicTo implement drag and drop functionality, combine arsenic.actions.Mouse with arsenic.actions.chain and execute the sequence using arsenic.session.Session.preform_actions.
Below is a helper function pattern for moving the mouse to an element and dragging it by a specific pixel offset.
from arsenic.actions import Mouse, chain
async def drag_and_drop(session, element, offset_x, offset_y):
mouse = Mouse()
actions = chain(
mouse.move_to(element),
mouse.click_and_hold(),
mouse.move_by_offset(offset_x, offset_y),
mouse.release()
)
await session.preform_actions(actions)Unlike Unix systems where local services work automatically, Windows requires you to explicitly provide the absolute path to the service binary (e.g., geckodriver.exe) when instantiating a service.
from arsenic import get_session, services, browsers
async def example():
service = services.Geckodriver(
binary='C:\\geckodriver\\geckodriver.exe'
)
browser = browsers.Firefox()
async with get_session(service, browser) as session:
...To extend the test suite with a new browser, modify tests/conftest.py:
pytest.fixture decorator for the async def session function.params list.yields a Session object.To limit the test execution to a single browser, use the pytest -k flag to filter by the session name. For example, to run only Chrome tests, use chrome_session.
poetry run pytest -k chrome_session