WebGraph is a Python library for structured web automation using Selenium.
It combines a graph-based approach for defining action sequences with a flexible element locator system.
Warning
WebGraph is a personal project developed for personal use and is currently in development.
This software is a personal project currently in development and not ready for a production environment. As this is in development and for personal use, any element can change without notice, until an eventually 1.0 version.
- Graph-based automation: Define browser interactions as nodes in a directed graph (
WebGraph). - Conditional execution: Run actions only when conditions are met.
- Fallback handling & retries: Specify fallback actions with max retry limits.
- State sharing: Pass a dictionary across nodes to persist data.
- Flexible element locating: Use the
Elementclass to define HTML elements via tag, id, classes, attributes, XPath, and index. - Multiple WebElement support: A single
Elementdefinition can resolve to multiple SeleniumWebElements. - Indexed actions: Every element action supports an
indexparameter to precisely target which resolved element to interact with. - Asynchronous support: All actions and conditions can be sync or async.
pip install git+https://github.com/NikBellini/web-graph.git
Make sure the appropriate WebDriver (Chrome, Firefox, etc.) is installed.
Element provides a structured way to locate HTML elements for Selenium automation.
The element lookup is lazy: elements are not searched until a method that needs them is executed.
-
An
Elementcan match one or more SeleniumWebElements. -
Resolution always produces a list of WebElements internally.
-
If multiple elements are found, you can:
- Provide a default
indexin theElementdefinition, - Specify an
indexdirectly when calling an action or condition method or - Execute the action or condition directly on all the HTML elements.
- Provide a default
This makes it possible to define a single logical element (e.g. a list of buttons) and interact with a specific one, or all of them, at runtime.
from web_graph.elements import Element
buttons = Element(
tag="button",
class_names=["action-btn"]
)
# Click the first matching button
click_first = buttons.click(index=0)
# Check visibility of the second button
is_second_visible = buttons.is_displayed(index=1)tagidnameclass_namesattrsxpathindexcontains_textmatches_textcontains_htmlmatches_html
All methods return callables that accept a WebDriver (and optionally state).
They do not execute immediately.
-
retrieve(driver, index=None)-
Returns a Selenium
WebElement -
Raises:
ElementNotFoundErrorElementError
-
-
is_displayed(index: int | None = None)- Returns a function that checks if the element is visible.
-
is_enabled(index: int | None = None)- Returns a function that checks if the element is enabled/interactable.
-
click(index: int | None = None)- Returns a function that clicks the selected element.
There are also a list of specific classes that expand the Element class:
ButtonInput
When using a specific class and the XPath to identify specific elements, be sure that the XPath points to an element with the given tag. If for example an
Inputelement points to abutton, when executing an action, errors can occur. This is a user responsability.
- Either XPath or other attributes can be provided, not both.
- At least one attribute or XPath must be specified.
Because every method internally uses
retrieve, the exceptions raised by actions and conditions methods are the same raised byretrieve.
Represents a list of executable actions in a WebGraph.
from web_graph import ActionNode
from elements.element import Element
button = Element(tag="button", id="submit")
node = ActionNode(
name="ClickSubmit",
actions=[button.click()],
conditions=[lambda driver, state: True], # Optional
fallback_actions=[lambda driver, state: print("Fallback executed")], # Optional
fallback_action_max_retries=3 # Optional
)name: The name of the node.actions: List of callables executed by the node.conditions: Optional list of callables returning a boolean.fallback_actions: Optional list of callables executed if the node fails.fallback_action_max_retries: Maximum number of fallback retries.
driverandstatecan be omitted inaction,conditionandfallback_action. If needed,driverandstatecan be defined as kwargs in the function signature. Passing any other argument will raise an error.
run(driver, state): Executes the node actions.run_conditions(driver, state): Evaluates the conditions (defaults toTrueif not defined).run_fallbacks(driver, state): Executes fallback actions.
Manages execution flow of interconnected ActionNodes.
from selenium import webdriver
from web_graph.graph import WebGraph, ActionNode
driver = webdriver.Chrome()
graph = WebGraph(driver)
fill_node = ActionNode(name="FillForm", actions=[fill_form])
submit_node = ActionNode(name="SubmitForm", actions=[click_submit])
graph.add_edge_node(fill_node)
graph.add_edge_node(submit_node)
await graph.run()If you only need a simple list of actions (without conditions or fallbacks), you can add a step.
A step is a minimal ActionNode with just a name and actions.
from selenium import webdriver
from web_graph.graph import WebGraph, ActionNode
driver = webdriver.Chrome()
graph = WebGraph(driver)
graph.add_step("Form", [fill_form, click_submit])
await graph.run()The created ActionNode is automatically attached to the last added or current node.
- Conditional branching
- Sequential execution
- Fallback retries
- Shared state across nodes
-
add_edge_node(node, starting_node=None)- Adds a node to the graph.
- If
starting_nodeis not provided, the node is attached to the last added node. - The default starting node is
START.
-
add_step(name, actions)- Adds a minimal
ActionNodeand attaches it to the current node. - Returns the created
ActionNode.
- Adds a minimal
-
set_current_node(node)- Sets the given node as the current node if it exists in the graph.
-
run()- Executes the graph starting from the
STARTnode.
- Executes the graph starting from the
START: Entry point of the graph.END: Marks the end of execution.
ElementNotFoundError: Raised if no element matches the locator.MaxFallbackRetriesReachedError: Raised when max fallback retries are exceeded.
- Define common actions like scroll, reload, navigation, etc.
- Introduce specialized
Elementsubclasses such asButton,Input, etc. - Improve and expand README examples.