diff --git a/webdriver/tests/bidi/browsing_context/locate_nodes/invalid.py b/webdriver/tests/bidi/browsing_context/locate_nodes/invalid.py
index 2eb2c3d806caf4..c1c545e9bb9967 100644
--- a/webdriver/tests/bidi/browsing_context/locate_nodes/invalid.py
+++ b/webdriver/tests/bidi/browsing_context/locate_nodes/invalid.py
@@ -71,12 +71,51 @@ async def test_params_locator_accessability_value_invalid_type(
)
+@pytest.mark.parametrize("value", [None, False, 42, "", []])
+async def test_params_locator_context_invalid_type(bidi_session, inline,
+ top_context, value):
+ await navigate_to_page(bidi_session, inline, top_context)
+
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.browsing_context.locate_nodes(
+ context=top_context["context"],
+ locator={"type": "context", "value": value}
+ )
+
+
+@pytest.mark.parametrize("value", [None, False, 42, {}, []])
+async def test_params_locator_context_value_invalid_type(bidi_session, inline,
+ top_context, value):
+ await navigate_to_page(bidi_session, inline, top_context)
+
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.browsing_context.locate_nodes(
+ context=top_context["context"],
+ locator={"type": "context", "value": {
+ "context": value
+ }}
+ )
+
+
+@pytest.mark.parametrize("value", ["non_exiting_context"])
+async def test_params_locator_context_value_invalid_context(bidi_session,
+ inline, top_context, value):
+ await navigate_to_page(bidi_session, inline, top_context)
+
+ with pytest.raises(error.NoSuchFrameException):
+ await bidi_session.browsing_context.locate_nodes(
+ context=top_context["context"],
+ locator={"type": "context", "value": {
+ "context": value
+ }}
+ )
+
@pytest.mark.parametrize("type,value", [
("css", "a*b"),
("xpath", ""),
("innerText", ""),
("accessibility", {}),
- ("context", {})
+ ("context", {"context": ""})
])
async def test_params_locator_value_invalid_value(bidi_session, inline, top_context, type, value):
await navigate_to_page(bidi_session, inline, top_context)
@@ -218,3 +257,22 @@ async def test_params_start_nodes_dom_node_not_element(
locator={"type": "css", "value": "div"},
start_nodes=[remote_reference],
)
+
+
+@pytest.mark.asyncio
+async def test_locate_by_context_invalid_context(bidi_session, inline, top_context, iframe):
+ iframe_url = inline(iframe("
foo
"))
+ page_url = inline(f"")
+
+ await bidi_session.browsing_context.navigate(
+ context=top_context["context"], url=page_url, wait="complete"
+ )
+
+ contexts = await bidi_session.browsing_context.get_tree(root=top_context["context"])
+ iframe2_context = contexts[0]["children"][0]["children"][0]
+
+ with pytest.raises(error.InvalidArgumentException):
+ await bidi_session.browsing_context.locate_nodes(
+ context=top_context["context"],
+ locator={"type": "context", "value": { "context": iframe2_context["context"] }}
+ )
diff --git a/webdriver/tests/bidi/browsing_context/locate_nodes/locator.py b/webdriver/tests/bidi/browsing_context/locate_nodes/locator.py
index 6cbe799958a8ff..117a2d10fa996d 100644
--- a/webdriver/tests/bidi/browsing_context/locate_nodes/locator.py
+++ b/webdriver/tests/bidi/browsing_context/locate_nodes/locator.py
@@ -241,8 +241,8 @@ async def test_locate_by_accessibility_attributes(
@pytest.mark.parametrize("domain", ["", "alt"], ids=["same_origin", "cross_origin"])
@pytest.mark.asyncio
async def test_locate_by_context(bidi_session, inline, top_context, domain):
- iframe_url_1 = inline("foo
", domain=domain)
- page_url = inline(f"")
+ iframe_url_1 = inline("foo
", domain=domain)
+ page_url = inline(f"")
await bidi_session.browsing_context.navigate(
context=top_context["context"], url=page_url, wait="complete"
@@ -261,7 +261,89 @@ async def test_locate_by_context(bidi_session, inline, top_context, domain):
"type": "node",
"sharedId": any_string,
"value": {
- "attributes": {"src": any_string},
+ "attributes": {"src": any_string, "id": "target"},
+ "childNodeCount": 0,
+ "localName": "iframe",
+ "namespaceURI": "http://www.w3.org/1999/xhtml",
+ "nodeType": 1,
+ }
+ }
+ ]
+
+ recursive_compare(expected, result["nodes"])
+
+
+@pytest.mark.parametrize("domain", ["", "alt"], ids=["same_origin", "cross_origin"])
+@pytest.mark.asyncio
+async def test_locate_by_context_in_iframe(bidi_session, inline, top_context, domain):
+ iframe_url_2 = inline("foo
", domain=domain)
+ iframe_url_1 = inline(f"")
+ page_url = inline(f"")
+
+ await bidi_session.browsing_context.navigate(
+ context=top_context["context"], url=page_url, wait="complete"
+ )
+
+ contexts = await bidi_session.browsing_context.get_tree(root=top_context["context"])
+ iframe1_context = contexts[0]["children"][0]
+ iframe2_context = contexts[0]["children"][0]["children"][0]
+
+ result = await bidi_session.browsing_context.locate_nodes(
+ context=iframe1_context["context"],
+ locator={"type": "context", "value": { "context": iframe2_context["context"] }}
+ )
+
+ expected = [
+ {
+ "type": "node",
+ "sharedId": any_string,
+ "value": {
+ "attributes": {"src": any_string, "id": "target"},
+ "childNodeCount": 0,
+ "localName": "iframe",
+ "namespaceURI": "http://www.w3.org/1999/xhtml",
+ "nodeType": 1,
+ }
+ }
+ ]
+
+ recursive_compare(expected, result["nodes"])
+
+
+@pytest.mark.parametrize("domain", ["", "alt"], ids=["same_origin", "cross_origin"])
+@pytest.mark.parametrize("mode", ["open", "closed"])
+@pytest.mark.asyncio
+async def test_locate_by_context_in_shadow_dom(bidi_session, inline, top_context, domain, mode):
+ iframe_url_1 = inline(f"foo
", domain=domain)
+ page_url = inline(f"""
+
+
+ """)
+
+ await bidi_session.browsing_context.navigate(
+ context=top_context["context"], url=page_url, wait="complete"
+ )
+
+ contexts = await bidi_session.browsing_context.get_tree(root=top_context["context"])
+ iframe1_context = contexts[0]["children"][0]
+
+ result = await bidi_session.browsing_context.locate_nodes(
+ context=top_context["context"],
+ locator={"type": "context", "value": { "context": iframe1_context["context"] }}
+ )
+
+ expected = [
+ {
+ "type": "node",
+ "sharedId": any_string,
+ "value": {
+ "attributes": {"src": any_string, "id": "target"},
"childNodeCount": 0,
"localName": "iframe",
"namespaceURI": "http://www.w3.org/1999/xhtml",