Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WebDriver BiDi] addPreloadScript supports contexts #41932

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tools/webdriver/webdriver/bidi/modules/script.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ def add_preload_script(
self,
function_declaration: str,
arguments: Optional[List[Mapping[str, Any]]] = None,
contexts: Optional[List[str]] = None,
sandbox: Optional[str] = None
) -> Mapping[str, Any]:
params: MutableMapping[str, Any] = {
Expand All @@ -104,6 +105,8 @@ def add_preload_script(

if arguments is not None:
params["arguments"] = arguments
if contexts is not None:
params["contexts"] = contexts
if sandbox is not None:
params["sandbox"] = sandbox

Expand Down
111 changes: 111 additions & 0 deletions webdriver/tests/bidi/script/add_preload_script/contexts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import pytest

from webdriver.bidi.modules.script import ContextTarget


@pytest.mark.asyncio
@pytest.mark.parametrize("domain", ["", "alt"], ids=["same_origin", "cross_origin"])
async def test_top_context_with_iframes(
bidi_session, add_preload_script, new_tab,
inline, iframe, domain):

iframe_content = f"<div>{domain}</div>"
url = inline(f"{iframe(iframe_content, domain=domain)}")

await add_preload_script(
function_declaration="() => { window.bar='foo'; }",
contexts=[new_tab["context"]])

await bidi_session.browsing_context.navigate(
context=new_tab["context"],
url=url,
wait="complete",
)

# Check that preload script applied the changes to the context
result = await bidi_session.script.evaluate(
expression="window.bar",
target=ContextTarget(new_tab["context"]),
await_promise=True,
)
assert result == {"type": "string", "value": "foo"}

contexts = await bidi_session.browsing_context.get_tree(
root=new_tab["context"])

assert len(contexts[0]["children"]) == 1
frame_context = contexts[0]["children"][0]

# Check that preload script applied the changes to the iframe
result = await bidi_session.script.evaluate(
expression="window.bar",
target=ContextTarget(frame_context["context"]),
await_promise=True,
)
assert result == {"type": "string", "value": "foo"}


@pytest.mark.asyncio
@pytest.mark.parametrize("type_hint", ["tab", "window"])
async def test_page_script_context_isolation(bidi_session, add_preload_script,
top_context, type_hint,
test_page):
await add_preload_script(function_declaration="() => { window.baz = 42; }",
contexts=[top_context['context']])

new_context = await bidi_session.browsing_context.create(
type_hint=type_hint)

# Navigate both contexts to ensure preload script is triggered
await bidi_session.browsing_context.navigate(
context=top_context['context'],
url=test_page,
wait="complete",
)
await bidi_session.browsing_context.navigate(
context=new_context["context"],
url=test_page,
wait="complete",
)

# Check that preload script applied the changes to the context
result = await bidi_session.script.evaluate(
expression="window.baz",
target=ContextTarget(top_context["context"]),
await_promise=True,
)
assert result == {"type": "number", "value": 42}

# Check that preload script did *not* apply the changes to the other context
result = await bidi_session.script.evaluate(
expression="window.baz",
target=ContextTarget(new_context["context"]),
await_promise=True,
)
assert result == {type: "undefined"}


@pytest.mark.asyncio
async def test_identical_contexts(
bidi_session, add_preload_script, new_tab,
inline):

url = inline(f"<div>test</div>")

await add_preload_script(
function_declaration="() => { window.foo = window.foo ? window.foo + 1 : 1; }",
contexts=[new_tab["context"], new_tab["context"]])

await bidi_session.browsing_context.navigate(
context=new_tab["context"],
url=url,
wait="complete",
)

# Check that preload script applied the changes to the context only once
result = await bidi_session.script.evaluate(
expression="window.foo",
target=ContextTarget(new_tab["context"]),
await_promise=True,
)
assert result == {"type": "number", "value": "1"}
58 changes: 57 additions & 1 deletion webdriver/tests/bidi/script/add_preload_script/invalid.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ async def test_params_arguments_channel_ownership_invalid_value(bidi_session):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.script.add_preload_script(
function_declaration="() => {}",
arguments=[{"type": "channel", "value": {"ownership": "_UNKNOWN_"}}],
arguments=[{"type": "channel", "value": {
"ownership": "_UNKNOWN_"}}],
Lightning00Blade marked this conversation as resolved.
Show resolved Hide resolved
)


Expand Down Expand Up @@ -186,6 +187,61 @@ async def test_params_arguments_channel_include_shadow_tree_invalid_value(bidi_s
)


@pytest.mark.parametrize("contexts", [False, 42, '_UNKNOWN_', {}])
async def test_params_contexts_invalid_type(bidi_session, contexts):
Lightning00Blade marked this conversation as resolved.
Show resolved Hide resolved
with pytest.raises(error.InvalidArgumentException):
await bidi_session.script.add_preload_script(
function_declaration="() => {}",
contexts=contexts
Lightning00Blade marked this conversation as resolved.
Show resolved Hide resolved
),


Lightning00Blade marked this conversation as resolved.
Show resolved Hide resolved
async def test_params_contexts_empty_list(bidi_session):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.script.add_preload_script(
function_declaration="() => {}",
contexts=[]
Lightning00Blade marked this conversation as resolved.
Show resolved Hide resolved
),


@pytest.mark.parametrize("value", [None, False, 42, {}, []])
async def test_params_contexts_context_invalid_type(bidi_session, value):
with pytest.raises(error.InvalidArgumentException):
await bidi_session.script.add_preload_script(
function_declaration="() => {}",
contexts=[value]
),


@pytest.mark.parametrize("value", ["", "somestring"])
async def test_params_contexts_context_invalid_value(bidi_session, value):
Lightning00Blade marked this conversation as resolved.
Show resolved Hide resolved
with pytest.raises(error.InvalidArgumentException):
await bidi_session.script.add_preload_script(
function_declaration="() => {}",
contexts=[value]
),


async def test_params_contexts_context_non_top_level(bidi_session, new_tab, test_page_same_origin_frame):
await bidi_session.browsing_context.navigate(
context=new_tab["context"],
url=test_page_same_origin_frame,
wait="complete",
)

contexts = await bidi_session.browsing_context.get_tree(root=new_tab["context"])

assert len(contexts) == 1
assert len(contexts[0]["children"]) == 1
child_info = contexts[0]["children"][0]

with pytest.raises(error.InvalidArgumentException):
await bidi_session.script.add_preload_script(
function_declaration="() => {}",
contexts=[child_info['context']]
),


@pytest.mark.parametrize("sandbox", [False, 42, {}, []])
async def test_params_sandbox_invalid_type(bidi_session, sandbox):
with pytest.raises(error.InvalidArgumentException):
Expand Down
3 changes: 2 additions & 1 deletion webdriver/tests/support/fixtures_bidi.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,11 @@
async def add_preload_script(bidi_session):
preload_scripts_ids = []

async def add_preload_script(function_declaration, arguments=None, sandbox=None):
async def add_preload_script(function_declaration, arguments=None, contexts=None, sandbox=None):
script = await bidi_session.script.add_preload_script(
function_declaration=function_declaration,
arguments=arguments,
contexts=contexts,
sandbox=sandbox,
)
preload_scripts_ids.append(script)
Expand Down
Loading