aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/webdriver_handlers.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/webdriver_handlers.rs')
-rw-r--r--components/script/webdriver_handlers.rs134
1 files changed, 103 insertions, 31 deletions
diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs
index 6b4264d945e..322839aa078 100644
--- a/components/script/webdriver_handlers.rs
+++ b/components/script/webdriver_handlers.rs
@@ -81,7 +81,7 @@ fn find_node_by_unique_id(
match documents.find_document(pipeline) {
Some(doc) => find_node_by_unique_id_in_document(&doc, node_id),
None => {
- if ScriptThread::has_node_id(&node_id) {
+ if ScriptThread::has_node_id(pipeline, &node_id) {
Err(ErrorStatus::StaleElementReference)
} else {
Err(ErrorStatus::NoSuchElement)
@@ -94,14 +94,15 @@ pub(crate) fn find_node_by_unique_id_in_document(
document: &Document,
node_id: String,
) -> Result<DomRoot<Node>, ErrorStatus> {
+ let pipeline = document.window().pipeline_id();
match document
.upcast::<Node>()
.traverse_preorder(ShadowIncluding::Yes)
- .find(|node| node.unique_id() == node_id)
+ .find(|node| node.unique_id(pipeline) == node_id)
{
Some(node) => Ok(node),
None => {
- if ScriptThread::has_node_id(&node_id) {
+ if ScriptThread::has_node_id(pipeline, &node_id) {
Err(ErrorStatus::StaleElementReference)
} else {
Err(ErrorStatus::NoSuchElement)
@@ -129,7 +130,10 @@ fn matching_links(
content == link_text
}
})
- .map(|node| node.upcast::<Node>().unique_id())
+ .map(|node| {
+ node.upcast::<Node>()
+ .unique_id(node.owner_doc().window().pipeline_id())
+ })
}
fn all_matching_links(
@@ -329,20 +333,25 @@ unsafe fn jsval_to_webdriver_inner(
Ok(WebDriverJSValue::ArrayLike(result))
} else if let Ok(element) = root_from_object::<Element>(*object, cx) {
Ok(WebDriverJSValue::Element(WebElement(
- element.upcast::<Node>().unique_id(),
+ element
+ .upcast::<Node>()
+ .unique_id(element.owner_document().window().pipeline_id()),
)))
} else if let Ok(window) = root_from_object::<Window>(*object, cx) {
let window_proxy = window.window_proxy();
if window_proxy.is_browsing_context_discarded() {
return Err(WebDriverJSError::StaleElementReference);
- } else if window_proxy.browsing_context_id() == window_proxy.webview_id() {
- Ok(WebDriverJSValue::Window(WebWindow(
- window.Document().upcast::<Node>().unique_id(),
- )))
} else {
- Ok(WebDriverJSValue::Frame(WebFrame(
- window.Document().upcast::<Node>().unique_id(),
- )))
+ let pipeline = window.pipeline_id();
+ if window_proxy.browsing_context_id() == window_proxy.webview_id() {
+ Ok(WebDriverJSValue::Window(WebWindow(
+ window.Document().upcast::<Node>().unique_id(pipeline),
+ )))
+ } else {
+ Ok(WebDriverJSValue::Frame(WebFrame(
+ window.Document().upcast::<Node>().unique_id(pipeline),
+ )))
+ }
}
} else if object_has_to_json_property(cx, global_scope, object.handle()) {
let name = CString::new("toJSON").unwrap();
@@ -598,7 +607,7 @@ pub(crate) fn handle_find_element_css(
.QuerySelector(DOMString::from(selector))
.map_err(|_| ErrorStatus::InvalidSelector)
})
- .map(|node| node.map(|x| x.upcast::<Node>().unique_id())),
+ .map(|node| node.map(|x| x.upcast::<Node>().unique_id(pipeline))),
)
.unwrap();
}
@@ -640,7 +649,7 @@ pub(crate) fn handle_find_element_tag_name(
.elements_iter()
.next()
})
- .map(|node| node.map(|x| x.upcast::<Node>().unique_id())),
+ .map(|node| node.map(|x| x.upcast::<Node>().unique_id(pipeline))),
)
.unwrap();
}
@@ -664,7 +673,7 @@ pub(crate) fn handle_find_elements_css(
.map(|nodes| {
nodes
.iter()
- .map(|x| x.upcast::<Node>().unique_id())
+ .map(|x| x.upcast::<Node>().unique_id(pipeline))
.collect()
}),
)
@@ -706,7 +715,7 @@ pub(crate) fn handle_find_elements_tag_name(
.map(|nodes| {
nodes
.elements_iter()
- .map(|x| x.upcast::<Node>().unique_id())
+ .map(|x| x.upcast::<Node>().unique_id(pipeline))
.collect::<Vec<String>>()
}),
)
@@ -725,7 +734,7 @@ pub(crate) fn handle_find_element_element_css(
find_node_by_unique_id(documents, pipeline, element_id).and_then(|node| {
node.query_selector(DOMString::from(selector))
.map_err(|_| ErrorStatus::InvalidSelector)
- .map(|node| node.map(|x| x.upcast::<Node>().unique_id()))
+ .map(|node| node.map(|x| x.upcast::<Node>().unique_id(pipeline)))
}),
)
.unwrap();
@@ -764,7 +773,7 @@ pub(crate) fn handle_find_element_element_tag_name(
.GetElementsByTagName(DOMString::from(selector), can_gc)
.elements_iter()
.next()
- .map(|x| x.upcast::<Node>().unique_id())),
+ .map(|x| x.upcast::<Node>().unique_id(pipeline))),
None => Err(ErrorStatus::UnknownError),
}),
)
@@ -786,7 +795,7 @@ pub(crate) fn handle_find_element_elements_css(
.map(|nodes| {
nodes
.iter()
- .map(|x| x.upcast::<Node>().unique_id())
+ .map(|x| x.upcast::<Node>().unique_id(pipeline))
.collect()
})
}),
@@ -826,7 +835,7 @@ pub(crate) fn handle_find_element_elements_tag_name(
Some(element) => Ok(element
.GetElementsByTagName(DOMString::from(selector), can_gc)
.elements_iter()
- .map(|x| x.upcast::<Node>().unique_id())
+ .map(|x| x.upcast::<Node>().unique_id(pipeline))
.collect::<Vec<String>>()),
None => Err(ErrorStatus::UnknownError),
}),
@@ -834,24 +843,87 @@ pub(crate) fn handle_find_element_elements_tag_name(
.unwrap();
}
-pub(crate) fn handle_focus_element(
+/// <https://www.w3.org/TR/webdriver2/#dfn-get-element-shadow-root>
+pub(crate) fn handle_get_element_shadow_root(
documents: &DocumentCollection,
pipeline: PipelineId,
element_id: String,
- reply: IpcSender<Result<(), ErrorStatus>>,
+ reply: IpcSender<Result<Option<String>, ErrorStatus>>,
+) {
+ reply
+ .send(
+ find_node_by_unique_id(documents, pipeline, element_id).and_then(|node| match node
+ .downcast::<Element>(
+ ) {
+ Some(element) => Ok(element
+ .GetShadowRoot()
+ .map(|x| x.upcast::<Node>().unique_id(pipeline))),
+ None => Err(ErrorStatus::NoSuchElement),
+ }),
+ )
+ .unwrap();
+}
+
+pub(crate) fn handle_will_send_keys(
+ documents: &DocumentCollection,
+ pipeline: PipelineId,
+ element_id: String,
+ text: String,
+ strict_file_interactability: bool,
+ reply: IpcSender<Result<bool, ErrorStatus>>,
can_gc: CanGc,
) {
reply
.send(
find_node_by_unique_id(documents, pipeline, element_id).and_then(|node| {
- match node.downcast::<HTMLElement>() {
- Some(element) => {
- // Need a way to find if this actually succeeded
- element.Focus(can_gc);
- Ok(())
- },
- None => Err(ErrorStatus::UnknownError),
+ // Step 6: Let file be true if element is input element
+ // in the file upload state, or false otherwise
+ let file_input = node
+ .downcast::<HTMLInputElement>()
+ .filter(|&input_element| input_element.input_type() == InputType::File);
+
+ // Step 7: If file is false or the session's strict file interactability
+ if file_input.is_none() || strict_file_interactability {
+ match node.downcast::<HTMLElement>() {
+ Some(element) => {
+ // Need a way to find if this actually succeeded
+ element.Focus(can_gc);
+ },
+ None => return Err(ErrorStatus::UnknownError),
+ }
}
+
+ // Step 8 (file input)
+ if let Some(file_input) = file_input {
+ // Step 8.1: Let files be the result of splitting text
+ // on the newline (\n) character.
+ let files: Vec<DOMString> = text.split("\n").map(|s| s.into()).collect();
+
+ // Step 8.2
+ if files.is_empty() {
+ return Err(ErrorStatus::InvalidArgument);
+ }
+
+ // Step 8.3 - 8.4
+ if !file_input.Multiple() && files.len() > 1 {
+ return Err(ErrorStatus::InvalidArgument);
+ }
+
+ // Step 8.5
+ // TODO: Should return invalid argument error if file doesn't exist
+
+ // Step 8.6 - 8.7
+ // Input and change event already fired in `htmlinputelement.rs`.
+ file_input.SelectFiles(files, can_gc);
+
+ // Step 8.8
+ return Ok(false);
+ }
+
+ // TODO: Check non-typeable form control
+ // TODO: Check content editable
+
+ Ok(true)
}),
)
.unwrap();
@@ -867,7 +939,7 @@ pub(crate) fn handle_get_active_element(
documents
.find_document(pipeline)
.and_then(|document| document.GetActiveElement())
- .map(|element| element.upcast::<Node>().unique_id()),
+ .map(|element| element.upcast::<Node>().unique_id(pipeline)),
)
.unwrap();
}
@@ -1395,7 +1467,7 @@ pub(crate) fn handle_element_click(
Ok(None)
},
- None => Ok(Some(node.unique_id())),
+ None => Ok(Some(node.unique_id(pipeline))),
}
}),
)