webdriver: Support errors that are fatal i.e. should result in session teardown.
authorJames Graham <james@hoppipolla.co.uk>
Wed, 20 May 2015 12:06:41 +0100
changeset 428031 8a65b8a87230f0e1b3ca46f578c7a1c2c718976e
parent 428030 1aa846f7f9a588b8b395b42ec8fdeb8e7b4f7032
child 428032 9f97b54d7032a079eb54694e1b45354d40da0604
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
webdriver: Support errors that are fatal i.e. should result in session teardown. Source-Repo: https://github.com/mozilla/webdriver-rust Source-Revision: 043d4007dba6bca256a7e8f838ad1ef12a7a8930
testing/webdriver/src/error.rs
testing/webdriver/src/server.rs
--- a/testing/webdriver/src/error.rs
+++ b/testing/webdriver/src/error.rs
@@ -25,102 +25,122 @@ pub enum ErrorStatus {
     SessionNotCreated,
     StaleElementReference,
     Timeout,
     UnableToSetCookie,
     UnexpectedAlertOpen,
     UnknownError,
     UnknownPath,
     UnknownMethod,
-    UnsupportedOperation,
+    UnsupportedOperation
+}
+
+impl ErrorStatus {
+    pub fn status_code(&self) -> &'static str {
+        match self {
+            &ErrorStatus::ElementNotSelectable => "element not selectable",
+            &ErrorStatus::ElementNotVisible => "element not visible",
+            &ErrorStatus::InvalidArgument => "invalid argument",
+            &ErrorStatus::InvalidCookieDomain => "invalid cookie domain",
+            &ErrorStatus::InvalidElementCoordinates => "invalid element coordinates",
+            &ErrorStatus::InvalidElementState => "invalid element state",
+            &ErrorStatus::InvalidSelector => "invalid selector",
+            &ErrorStatus::InvalidSessionId => "invalid session id",
+            &ErrorStatus::JavascriptError => "javascript error",
+            &ErrorStatus::MoveTargetOutOfBounds => "move target out of bounds",
+            &ErrorStatus::NoSuchAlert => "no such alert",
+            &ErrorStatus::NoSuchElement => "no such element",
+            &ErrorStatus::NoSuchFrame => "no such frame",
+            &ErrorStatus::NoSuchWindow => "no such window",
+            &ErrorStatus::ScriptTimeout => "script timeout",
+            &ErrorStatus::SessionNotCreated => "session not created",
+            &ErrorStatus::StaleElementReference => "stale element reference",
+            &ErrorStatus::Timeout => "timeout",
+            &ErrorStatus::UnableToSetCookie => "unable to set cookie",
+            &ErrorStatus::UnexpectedAlertOpen => "unexpected alert open",
+            &ErrorStatus::UnknownError => "unknown error",
+            &ErrorStatus::UnknownPath => "unknown command",
+            &ErrorStatus::UnknownMethod => "unknown command",
+            &ErrorStatus::UnsupportedOperation => "unsupported operation"
+        }
+    }
+
+    pub fn http_status(&self) -> StatusCode {
+        match self {
+            &ErrorStatus::ElementNotSelectable => StatusCode::BadRequest,
+            &ErrorStatus::ElementNotVisible => StatusCode::BadRequest,
+            &ErrorStatus::InvalidArgument => StatusCode::BadRequest,
+            &ErrorStatus::InvalidCookieDomain => StatusCode::BadRequest,
+            &ErrorStatus::InvalidElementCoordinates => StatusCode::BadRequest,
+            &ErrorStatus::InvalidElementState => StatusCode::BadRequest,
+            &ErrorStatus::InvalidSelector => StatusCode::BadRequest,
+            &ErrorStatus::InvalidSessionId => StatusCode::NotFound,
+            &ErrorStatus::JavascriptError => StatusCode::InternalServerError,
+            &ErrorStatus::MoveTargetOutOfBounds => StatusCode::InternalServerError,
+            &ErrorStatus::NoSuchAlert => StatusCode::BadRequest,
+            &ErrorStatus::NoSuchElement => StatusCode::NotFound,
+            &ErrorStatus::NoSuchFrame => StatusCode::BadRequest,
+            &ErrorStatus::NoSuchWindow => StatusCode::BadRequest,
+            &ErrorStatus::ScriptTimeout => StatusCode::RequestTimeout,
+            &ErrorStatus::SessionNotCreated => StatusCode::InternalServerError,
+            &ErrorStatus::StaleElementReference => StatusCode::BadRequest,
+            &ErrorStatus::Timeout => StatusCode::RequestTimeout,
+            &ErrorStatus::UnableToSetCookie => StatusCode::InternalServerError,
+            &ErrorStatus::UnexpectedAlertOpen => StatusCode::InternalServerError,
+            &ErrorStatus::UnknownError => StatusCode::InternalServerError,
+            &ErrorStatus::UnknownPath => StatusCode::NotFound,
+            &ErrorStatus::UnknownMethod => StatusCode::MethodNotAllowed,
+            &ErrorStatus::UnsupportedOperation => StatusCode::InternalServerError
+        }
+    }
 }
 
 pub type WebDriverResult<T> = Result<T, WebDriverError>;
 
 #[derive(Debug)]
 pub struct WebDriverError {
     pub status: ErrorStatus,
-    pub message: String
+    pub message: String,
+    delete_session: bool
 }
 
 impl fmt::Display for WebDriverError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         self.message.fmt(f)
     }
 }
 
 impl WebDriverError {
     pub fn new(status: ErrorStatus, message: &str) -> WebDriverError {
         WebDriverError {
             status: status,
-            message: message.to_string()
+            message: message.to_string(),
+            delete_session: false
         }
     }
 
     pub fn status_code(&self) -> &'static str {
-        match self.status {
-            ErrorStatus::ElementNotSelectable => "element not selectable",
-            ErrorStatus::ElementNotVisible => "element not visible",
-            ErrorStatus::InvalidArgument => "invalid argument",
-            ErrorStatus::InvalidCookieDomain => "invalid cookie domain",
-            ErrorStatus::InvalidElementCoordinates => "invalid element coordinates",
-            ErrorStatus::InvalidElementState => "invalid element state",
-            ErrorStatus::InvalidSelector => "invalid selector",
-            ErrorStatus::InvalidSessionId => "invalid session id",
-            ErrorStatus::JavascriptError => "javascript error",
-            ErrorStatus::MoveTargetOutOfBounds => "move target out of bounds",
-            ErrorStatus::NoSuchAlert => "no such alert",
-            ErrorStatus::NoSuchElement => "no such element",
-            ErrorStatus::NoSuchFrame => "no such frame",
-            ErrorStatus::NoSuchWindow => "no such window",
-            ErrorStatus::ScriptTimeout => "script timeout",
-            ErrorStatus::SessionNotCreated => "session not created",
-            ErrorStatus::StaleElementReference => "stale element reference",
-            ErrorStatus::Timeout => "timeout",
-            ErrorStatus::UnableToSetCookie => "unable to set cookie",
-            ErrorStatus::UnexpectedAlertOpen => "unexpected alert open",
-            ErrorStatus::UnknownError => "unknown error",
-            ErrorStatus::UnknownPath => "unknown command",
-            ErrorStatus::UnknownMethod => "unknown command",
-            ErrorStatus::UnsupportedOperation => "unsupported operation",
-        }
+        self.status.status_code()
     }
 
     pub fn http_status(&self) -> StatusCode {
-        match self.status {
-            ErrorStatus::ElementNotSelectable => StatusCode::BadRequest,
-            ErrorStatus::ElementNotVisible => StatusCode::BadRequest,
-            ErrorStatus::InvalidArgument => StatusCode::BadRequest,
-            ErrorStatus::InvalidCookieDomain => StatusCode::BadRequest,
-            ErrorStatus::InvalidElementCoordinates => StatusCode::BadRequest,
-            ErrorStatus::InvalidElementState => StatusCode::BadRequest,
-            ErrorStatus::InvalidSelector => StatusCode::BadRequest,
-            ErrorStatus::InvalidSessionId => StatusCode::NotFound,
-            ErrorStatus::JavascriptError => StatusCode::InternalServerError,
-            ErrorStatus::MoveTargetOutOfBounds => StatusCode::InternalServerError,
-            ErrorStatus::NoSuchAlert => StatusCode::BadRequest,
-            ErrorStatus::NoSuchElement => StatusCode::NotFound,
-            ErrorStatus::NoSuchFrame => StatusCode::BadRequest,
-            ErrorStatus::NoSuchWindow => StatusCode::BadRequest,
-            ErrorStatus::ScriptTimeout => StatusCode::RequestTimeout,
-            ErrorStatus::SessionNotCreated => StatusCode::InternalServerError,
-            ErrorStatus::StaleElementReference => StatusCode::BadRequest,
-            ErrorStatus::Timeout => StatusCode::RequestTimeout,
-            ErrorStatus::UnableToSetCookie => StatusCode::InternalServerError,
-            ErrorStatus::UnexpectedAlertOpen => StatusCode::InternalServerError,
-            ErrorStatus::UnknownError => StatusCode::InternalServerError,
-            ErrorStatus::UnknownPath => StatusCode::NotFound,
-            ErrorStatus::UnknownMethod => StatusCode::MethodNotAllowed,
-            ErrorStatus::UnsupportedOperation => StatusCode::InternalServerError,
-        }
+        self.status.http_status()
     }
 
     pub fn to_json_string(&self) -> String {
         self.to_json().to_string()
     }
+
+    pub fn set_delete_session(&mut self) {
+        self.delete_session = true
+    }
+
+    pub fn delete_session(&self) -> bool {
+        self.delete_session
+    }
 }
 
 impl ToJson for WebDriverError {
     fn to_json(&self) -> Json {
         let mut data = BTreeMap::new();
         data.insert("status".to_string(), self.status_code().to_json());
         data.insert("message".to_string(), self.message.to_json());
         Json::Object(data)
--- a/testing/webdriver/src/server.rs
+++ b/testing/webdriver/src/server.rs
@@ -60,35 +60,42 @@ impl<T: WebDriverHandler> Dispatcher<T> 
                         Err(e) => Err(e)
                     };
 
                     match resp {
                         Ok(WebDriverResponse::NewSession(ref new_session)) => {
                             self.session = Some(Session::new(new_session.sessionId.clone()));
                         },
                         Ok(WebDriverResponse::DeleteSession) => {
-                            debug!("Deleting session");
-                            self.handler.delete_session(&self.session);
-                            self.session = None;
+                            self.delete_session();
                         },
+                        Err(ref x) if x.delete_session() => {
+                            self.delete_session();
+                        }
                         _ => {}
                     }
 
                     if resp_chan.send(resp).is_err() {
                         error!("Sending response to the main thread failed");
                     };
                 },
                 Ok(DispatchMessage::Quit) => {
                     break;
                 },
                 Err(_) => panic!("Error receiving message in handler")
             }
         }
     }
 
+    fn delete_session(&mut self) {
+        debug!("Deleting session");
+        self.handler.delete_session(&self.session);
+        self.session = None;
+    }
+
     fn check_session(&self, msg: &WebDriverMessage) -> WebDriverResult<()> {
         match msg.session_id {
             Some(ref msg_session_id) => {
                 match self.session {
                     Some(ref existing_session) => {
                         if existing_session.id != *msg_session_id {
                             Err(WebDriverError::new(
                                 ErrorStatus::InvalidSessionId,