///|
/// WebDriver request routing
/// Parses HTTP method + path into WebDriverCommand
///|
/// Parse HTTP request into WebDriverRequest
pub fn parse_request(
method_str : String,
path : String,
body : String,
) -> WebDriverRequest {
let http_method = match method_str.to_upper() {
"GET" => Get
"POST" => Post
"DELETE" => Delete
_ => Get // Default to GET for unknown methods
}
let command = parse_command(http_method, path)
{ http_method, command, body }
}
///|
/// Parse path into WebDriverCommand
fn parse_command(http_method : HttpMethod, path : String) -> WebDriverCommand {
// Remove leading slash and split by '/'
let path : String = if path.has_prefix("/") && path.length() > 1 {
let buf = StringBuilder::new()
let mut skip_first = true
for c in path.iter() {
if skip_first {
skip_first = false
continue
}
buf.write_char(c)
}
buf.to_string()
} else if path == "/" {
""
} else {
path
}
let parts = split_path(path)
match (http_method, parts) {
// Status
(Get, ["status"]) => Status
// Session management
(Post, ["session"]) => NewSession
(Get, ["session", session_id]) => GetSession(session_id~)
(Delete, ["session", session_id]) => DeleteSession(session_id~)
// Timeouts
(Get, ["session", session_id, "timeouts"]) => GetTimeouts(session_id~)
(Post, ["session", session_id, "timeouts"]) => SetTimeouts(session_id~)
// Navigation
(Post, ["session", session_id, "url"]) => NavigateTo(session_id~)
(Get, ["session", session_id, "url"]) => GetCurrentUrl(session_id~)
(Post, ["session", session_id, "back"]) => Back(session_id~)
(Post, ["session", session_id, "forward"]) => Forward(session_id~)
(Post, ["session", session_id, "refresh"]) => Refresh(session_id~)
(Get, ["session", session_id, "title"]) => GetTitle(session_id~)
// Window
(Get, ["session", session_id, "window"]) => GetWindowHandle(session_id~)
(Delete, ["session", session_id, "window"]) => CloseWindow(session_id~)
(Post, ["session", session_id, "window"]) => SwitchToWindow(session_id~)
(Get, ["session", session_id, "window", "handles"]) =>
GetWindowHandles(session_id~)
(Post, ["session", session_id, "window", "new"]) => NewWindow(session_id~)
(Post, ["session", session_id, "frame"]) => SwitchToFrame(session_id~)
(Post, ["session", session_id, "frame", "parent"]) =>
SwitchToParentFrame(session_id~)
(Get, ["session", session_id, "window", "rect"]) =>
GetWindowRect(session_id~)
(Post, ["session", session_id, "window", "rect"]) =>
SetWindowRect(session_id~)
(Post, ["session", session_id, "window", "maximize"]) =>
MaximizeWindow(session_id~)
(Post, ["session", session_id, "window", "minimize"]) =>
MinimizeWindow(session_id~)
(Post, ["session", session_id, "window", "fullscreen"]) =>
FullscreenWindow(session_id~)
// Element finding
(Post, ["session", session_id, "element"]) => FindElement(session_id~)
(Post, ["session", session_id, "elements"]) => FindElements(session_id~)
(Post, ["session", session_id, "element", element_id, "element"]) =>
FindElementFromElement(session_id~, element_id~)
(Post, ["session", session_id, "element", element_id, "elements"]) =>
FindElementsFromElement(session_id~, element_id~)
(Get, ["session", session_id, "element", "active"]) =>
GetActiveElement(session_id~)
// Element properties
(Get, ["session", session_id, "element", element_id, "selected"]) =>
IsElementSelected(session_id~, element_id~)
(Get, ["session", session_id, "element", element_id, "attribute", name]) =>
GetElementAttribute(session_id~, element_id~, name~)
(Get, ["session", session_id, "element", element_id, "property", name]) =>
GetElementProperty(session_id~, element_id~, name~)
(Get, ["session", session_id, "element", element_id, "css", name]) =>
GetElementCssValue(session_id~, element_id~, name~)
(Get, ["session", session_id, "element", element_id, "text"]) =>
GetElementText(session_id~, element_id~)
(Get, ["session", session_id, "element", element_id, "name"]) =>
GetElementTagName(session_id~, element_id~)
(Get, ["session", session_id, "element", element_id, "rect"]) =>
GetElementRect(session_id~, element_id~)
(Get, ["session", session_id, "element", element_id, "enabled"]) =>
IsElementEnabled(session_id~, element_id~)
// Element interaction
(Post, ["session", session_id, "element", element_id, "click"]) =>
ElementClick(session_id~, element_id~)
(Post, ["session", session_id, "element", element_id, "clear"]) =>
ElementClear(session_id~, element_id~)
(Post, ["session", session_id, "element", element_id, "value"]) =>
ElementSendKeys(session_id~, element_id~)
// Document
(Get, ["session", session_id, "source"]) => GetPageSource(session_id~)
(Post, ["session", session_id, "execute", "sync"]) =>
ExecuteScript(session_id~)
(Post, ["session", session_id, "execute", "async"]) =>
ExecuteAsyncScript(session_id~)
// Cookies
(Get, ["session", session_id, "cookie"]) => GetAllCookies(session_id~)
(Get, ["session", session_id, "cookie", name]) =>
GetNamedCookie(session_id~, name~)
(Post, ["session", session_id, "cookie"]) => AddCookie(session_id~)
(Delete, ["session", session_id, "cookie", name]) =>
DeleteCookie(session_id~, name~)
(Delete, ["session", session_id, "cookie"]) => DeleteAllCookies(session_id~)
// Actions
(Post, ["session", session_id, "actions"]) => PerformActions(session_id~)
(Delete, ["session", session_id, "actions"]) => ReleaseActions(session_id~)
// Alerts
(Post, ["session", session_id, "alert", "dismiss"]) =>
DismissAlert(session_id~)
(Post, ["session", session_id, "alert", "accept"]) =>
AcceptAlert(session_id~)
(Get, ["session", session_id, "alert", "text"]) => GetAlertText(session_id~)
(Post, ["session", session_id, "alert", "text"]) =>
SendAlertText(session_id~)
// Screenshot
(Get, ["session", session_id, "screenshot"]) => TakeScreenshot(session_id~)
(Get, ["session", session_id, "element", element_id, "screenshot"]) =>
TakeElementScreenshot(session_id~, element_id~)
// Print
(Post, ["session", session_id, "print"]) => PrintPage(session_id~)
// Unknown
_ => Unknown(path~)
}
}
///|
/// Split path by '/'
fn split_path(path : String) -> Array[String] {
let parts : Array[String] = []
let current = StringBuilder::new()
for c in path {
if c == '/' {
let s = current.to_string()
if !s.is_empty() {
parts.push(s)
}
current.reset()
} else {
current.write_char(c)
}
}
let s = current.to_string()
if !s.is_empty() {
parts.push(s)
}
parts
}