mirror of
https://github.com/servo/servo.git
synced 2025-09-27 07:10:19 +01:00
webdriver: Elegantly handle "element screenshot" when bounding box has area zero (#39499)
It is possible that the bounding rectangle of an element has area 0. This PR avoids panic in this case. It is worth to mention that the panic itself won't kill the entire program for interaction, but only the webdriver thread. Testing: Manually tested on the case of #39495 Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
This commit is contained in:
parent
4c25039d35
commit
2e8fac9395
3 changed files with 28 additions and 10 deletions
|
@ -1059,6 +1059,15 @@ impl Servo {
|
|||
pub fn execute_webdriver_command(&self, command: WebDriverCommandMsg) {
|
||||
if let WebDriverCommandMsg::TakeScreenshot(webview_id, page_rect, response_sender) = command
|
||||
{
|
||||
if let Some(ref rect) = page_rect {
|
||||
if rect.height() == 0.0 || rect.width() == 0.0 {
|
||||
error!("Taking screenshot of bounding box with zero area");
|
||||
if let Err(e) = response_sender.send(Err(())) {
|
||||
error!("Sending reply to create png failed {e:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let res = self
|
||||
.compositor
|
||||
.borrow_mut()
|
||||
|
@ -1067,7 +1076,7 @@ impl Servo {
|
|||
error!("Error retrieving PNG: {:?}", e);
|
||||
}
|
||||
let img = res.unwrap_or(None);
|
||||
if let Err(e) = response_sender.send(img) {
|
||||
if let Err(e) = response_sender.send(Ok(img)) {
|
||||
error!("Sending reply to create png failed ({:?}).", e);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -144,7 +144,7 @@ pub enum WebDriverCommandMsg {
|
|||
TakeScreenshot(
|
||||
WebViewId,
|
||||
Option<Rect<f32, CSSPixel>>,
|
||||
IpcSender<Option<RasterImage>>,
|
||||
IpcSender<Result<Option<RasterImage>, ()>>,
|
||||
),
|
||||
/// Create a new webview that loads about:blank. The embedder will use
|
||||
/// the provided channels to return the top level browsing context id
|
||||
|
|
|
@ -2320,14 +2320,23 @@ impl Handler {
|
|||
|
||||
for _ in 0..iterations {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
|
||||
self.send_message_to_embedder(WebDriverCommandMsg::TakeScreenshot(
|
||||
webview_id, rect, sender,
|
||||
))?;
|
||||
|
||||
if let Some(x) = wait_for_ipc_response(receiver)? {
|
||||
match wait_for_ipc_response(receiver)? {
|
||||
Ok(output_img) => {
|
||||
if let Some(x) = output_img {
|
||||
img = Some(x);
|
||||
break;
|
||||
}
|
||||
},
|
||||
Err(()) => {
|
||||
return Err(WebDriverError::new(
|
||||
ErrorStatus::UnknownError,
|
||||
"The bounding box of element has either 0 width or 0 height",
|
||||
));
|
||||
},
|
||||
};
|
||||
|
||||
thread::sleep(Duration::from_millis(interval));
|
||||
|
@ -2384,8 +2393,6 @@ impl Handler {
|
|||
&self,
|
||||
element: &WebElement,
|
||||
) -> WebDriverResult<WebDriverResponse> {
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
|
||||
// Step 1. If session's current top-level browsing context is no longer open,
|
||||
// return error with error code no such window.
|
||||
let webview_id = self.webview_id()?;
|
||||
|
@ -2394,7 +2401,9 @@ impl Handler {
|
|||
// Step 2. Try to handle any user prompts with session.
|
||||
self.handle_any_user_prompts(webview_id)?;
|
||||
|
||||
// Step 3 - 4
|
||||
// Step 3. Trying to get element.
|
||||
// Step 4. Scroll into view into element.
|
||||
let (sender, receiver) = ipc::channel().unwrap();
|
||||
let cmd =
|
||||
WebDriverScriptCommand::ScrollAndGetBoundingClientRect(element.to_string(), sender);
|
||||
self.browsing_context_script_command(cmd, VerifyBrowsingContextIsOpen::Yes)?;
|
||||
|
@ -2409,7 +2418,7 @@ impl Handler {
|
|||
serde_json::to_value(encoded)?,
|
||||
)))
|
||||
},
|
||||
Err(error) => Err(WebDriverError::new(error, "Element not found")),
|
||||
Err(error) => Err(WebDriverError::new(error, "")),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue