Pathfinding & Multi-State Activation
Introductionโ
Brobot's pathfinding system is designed to handle the reality of modern GUIs where actions often activate multiple UI elements simultaneously. Unlike traditional page-based navigation where you go from Page A to Page B, real applications often display multiple panels, sidebars, and overlays at once.
In Brobot 1.1.0, there is no concept of a "primary target state" in transitions. All states activated by a transition are treated equally for pathfinding purposes.
How Pathfinding Worksโ
The State Graphโ
Brobot builds a directed graph where:
- Nodes are States (UI configurations)
- Edges are Transitions (actions that change the UI)
Multi-State Activationโ
When a transition executes, it can activate multiple states simultaneously:
import io.github.jspinak.brobot.annotations.*;
import org.springframework.stereotype.Component;
@Component
@TransitionSet(state = LoginState.class)
public class LoginTransitions {
@Autowired
private Action action;
@Autowired
private LoginState loginState;
/**
* Verify we've arrived at the Login state.
*/
@IncomingTransition(description = "Verify login screen is visible")
public boolean verifyLoginScreen() {
return action.find(loginState.getLoginButton()).isSuccess();
}
/**
* Login transition that activates multiple states.
* Transitions FROM LoginState TO Dashboard (and related states).
*/
@OutgoingTransition(
activate = {
DashboardState.class,
NavigationBarState.class,
StatusPanelState.class,
NotificationAreaState.class
}
)
public boolean login() {
return action.click(loginState.getLoginButton()).isSuccess();
}
}
Path Discovery Algorithmโ
When you call navigator.openState("TargetState")
, Brobot:
- Indexes ALL Activated States: Each transition is indexed by every state it activates
- Explores All Paths: The pathfinder considers transitions through ANY activated state
- Finds Shortest Path: Returns the path with the lowest total path cost
Example: Finding Paths Through Multi-State Transitionsโ
// Given these transitions:
// State A โ activates [B, C, D]
// State B โ activates [E]
// State C โ activates [F]
// State D โ activates [G]
// State E โ activates [TargetState]
// When calling:
navigator.openState("TargetState");
// Pathfinder considers these paths:
// A โ B โ E โ TargetState โ (Found via B)
// A โ C โ F โ ... (Dead end)
// A โ D โ G โ ... (Dead end)
// Result: Path A โ B โ E โ TargetState is used
Important Concepts for Developersโ
1. Path Success vs. Complete Activationโ
Critical Understanding: Path success only requires the NEXT NODE in the path to be activated, not all activated states.
// Transition from A activates [B, C, D, E]
// Path is A โ B โ F
// During traversal:
// 1. Execute transition from A
// 2. Verify B is active โ (Path continues)
// 3. Don't need to verify C, D, E for path success
// 4. If C, D, or E fail, path still succeeds (but log warnings)
2. IncomingTransitions Execute for ALL Activated Statesโ
When a transition activates multiple states, each state's @IncomingTransition
executes:
// Transition activates Dashboard, Sidebar, Header
// Execution order:
// 1. OutgoingTransition executes (leaving source state)
// 2. Dashboard.verifyArrival() executes
// 3. Sidebar.verifyArrival() executes
// 4. Header.verifyArrival() executes
// All must succeed for complete transition success
Practical Implicationsโ
1. More Paths Availableโ
Your automation has more navigation options:
// If Login โ [Dashboard, Menu, Profile]
// Then you can reach Menu states via Login, even if
// Login's "main purpose" seems to be Dashboard
2. Flexible Navigationโ
States can be reached through unexpected routes:
// UserProfile might be reached via:
// - Direct navigation: Menu โ UserProfile
// - Side effect: Dashboard โ [Settings, UserProfile]
// - Multi-activation: Login โ [Dashboard, UserProfile, Notifications]
3. Design Considerationsโ
When to Use Multi-State Activationโ
โ Good Use Cases:
- Login opens multiple panels simultaneously
- Tab switches that keep navigation visible
- Modals that overlay existing content
- Dashboards with multiple independent widgets
โ Avoid When:
- States are sequential (load one, then another)
- Activation depends on conditions
- States are mutually exclusive
Understanding Path Choicesโ
The pathfinder chooses paths based on:
- Reachability: Can we get there from current active states?
- Path Length: Fewer transitions preferred
- Transition Costs: Lower path costs preferred
Best Practicesโ
// Good: Logical grouping of related states
@OutgoingTransition(
activate = {
EmailComposeState.class, // Main panel
EmailToolbarState.class, // Related toolbar
RecipientListState.class // Related sidebar
}
)
public boolean openEmailCompose() {
return action.click(composeButton).isSuccess();
}
// Bad: Unrelated states that happen to appear together
@OutgoingTransition(
activate = {
EmailComposeState.class,
StockTickerState.class, // Unrelated - BAD!
WeatherWidgetState.class // Unrelated - BAD!
}
)
public boolean openEmailWithUnrelatedStuff() {
return action.click(composeButton).isSuccess();
}
Debugging Pathfindingโ
# application.properties
logging.level.io.github.jspinak.brobot.navigation.path=TRACE
logging.level.io.github.jspinak.brobot.navigation.transition=TRACE
This will enable TRACE-level logging for:
- Path package: PathFinder algorithm, path calculation, graph traversal
- Transition package: Transition execution, state activation/deactivation
For even more detailed debugging, you could also add:
# Enable all navigation logging
logging.level.io.github.jspinak.brobot.navigation=TRACE
# Or be more specific
logging.level.io.github.jspinak.brobot.navigation.path.PathFinder=TRACE
logging.level.io.github.jspinak.brobot.navigation.transition.TransitionExecutor=TRACE
logging.level.io.github.jspinak.brobot.navigation.transition.StateNavigator=TRACE
Summaryโ
Brobot's pathfinding system embraces the complexity of modern GUIs by:
- Treating all activated states equally - No artificial "primary" target
- Indexing transitions by ALL activated states - More paths available
- Verifying path progression, not complete activation - Flexible navigation
- Executing IncomingTransitions for all activated states - Proper verification
This design makes your automation more robust and adaptable to real-world GUI behaviors where multiple elements appear and disappear together.