Skip to content

Commit

Permalink
test: add async dispatch event tests (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
rwoll committed Aug 4, 2020
1 parent 5938297 commit 1870817
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 2 deletions.
4 changes: 3 additions & 1 deletion playwright/element_handle.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ async def innerHTML(self) -> str:
return await self._channel.send("innerHTML")

async def dispatchEvent(self, type: str, eventInit: Dict = None) -> None:
await self._channel.send("dispatchEvent", dict(type=type, eventInit=eventInit))
await self._channel.send(
"dispatchEvent", dict(type=type, eventInit=serialize_argument(eventInit))
)

async def scrollIntoViewIfNeeded(self, timeout: int = None) -> None:
await self._channel.send("scrollIntoViewIfNeeded", locals_to_params(locals()))
Expand Down
3 changes: 2 additions & 1 deletion playwright/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ async def dispatchEvent(
self, selector: str, type: str, eventInit: Dict = None, timeout: int = None
) -> None:
await self._channel.send(
"dispatchEvent", dict(selector=selector, type=type, eventInit=eventInit)
"dispatchEvent",
dict(selector=selector, type=type, eventInit=serialize_argument(eventInit)),
)

async def evalOnSelector(
Expand Down
41 changes: 41 additions & 0 deletions tests/assets/drag-n-drop.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<style>
div:not(.mouse-helper) {
margin: 0em;
padding: 2em;
}
#source {
color: blue;
border: 1px solid black;
}
#target {
border: 1px solid black;
}
</style>

<script>

function dragstart_handler(ev) {
ev.currentTarget.style.border = "dashed";
ev.dataTransfer.setData("text/plain", ev.target.id);
}

function dragover_handler(ev) {
ev.preventDefault();
}

function drop_handler(ev) {
console.log("Drop");
ev.preventDefault();
var data = ev.dataTransfer.getData("text");
ev.target.appendChild(document.getElementById(data));
ev.dataTransfer.clearData();
}
</script>

<body>
<div>
<p id="source" ondragstart="dragstart_handler(event);" draggable="true">
Select this element, drag it to the Drop Zone and then release the selection to move the element.</p>
</div>
<div id="target" ondrop="drop_handler(event);" ondragover="dragover_handler(event);">Drop Zone</div>
</body>
172 changes: 172 additions & 0 deletions tests/async/test_dispatch_event.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# Copyright (c) Microsoft Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import pytest


async def test_should_dispatch_click_event(page, server):
await page.goto(server.PREFIX + "/input/button.html")
await page.dispatchEvent("button", "click")
assert await page.evaluate("() => result") == "Clicked"


async def test_should_dispatch_click_event_properties(page, server):
await page.goto(server.PREFIX + "/input/button.html")
await page.dispatchEvent("button", "click")
assert await page.evaluate("() => bubbles")
assert await page.evaluate("() => cancelable")
assert await page.evaluate("() => composed")


async def test_should_dispatch_click_svg(page):
await page.setContent(
"""
<svg height="100" width="100">
<circle onclick="javascript:window.__CLICKED=42" cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
"""
)
await page.dispatchEvent("circle", "click")
assert await page.evaluate("() => window.__CLICKED") == 42


async def test_should_dispatch_click_on_a_span_with_an_inline_element_inside(page):
await page.setContent(
"""
<style>
span::before {
content: 'q';
}
</style>
<span onclick='javascript:window.CLICKED=42'></span>
"""
)
await page.dispatchEvent("span", "click")
assert await page.evaluate("() => window.CLICKED") == 42


async def test_should_dispatch_click_after_navigation(page, server):
await page.goto(server.PREFIX + "/input/button.html")
await page.dispatchEvent("button", "click")
await page.goto(server.PREFIX + "/input/button.html")
await page.dispatchEvent("button", "click")
assert await page.evaluate("() => result") == "Clicked"


async def test_should_dispatch_click_after_a_cross_origin_navigation(page, server):
await page.goto(server.PREFIX + "/input/button.html")
await page.dispatchEvent("button", "click")
await page.goto(server.CROSS_PROCESS_PREFIX + "/input/button.html")
await page.dispatchEvent("button", "click")
assert await page.evaluate("() => result") == "Clicked"


async def test_should_not_fail_when_element_is_blocked_on_hover(page, server):
await page.setContent(
"""<style>
container { display: block; position: relative; width: 200px; height: 50px; }
div, button { position: absolute; left: 0; top: 0; bottom: 0; right: 0; }
div { pointer-events: none; }
container:hover div { pointer-events: auto; background: red; }
</style>
<container>
<button onclick="window.clicked=true">Click me</button>
<div></div>
</container>"""
)
await page.dispatchEvent("button", "click")
assert await page.evaluate("() => window.clicked")


async def test_should_dispatch_click_when_node_is_added_in_shadow_dom(page, server):
await page.goto(server.EMPTY_PAGE)
watchdog = page.dispatchEvent("span", "click")
await page.evaluate(
"""() => {
const div = document.createElement('div');
div.attachShadow({mode: 'open'});
document.body.appendChild(div);
}"""
)
await page.evaluate("() => new Promise(f => setTimeout(f, 100))")
await page.evaluate(
"""() => {
const span = document.createElement('span');
span.textContent = 'Hello from shadow';
span.addEventListener('click', () => window.clicked = true);
document.querySelector('div').shadowRoot.appendChild(span);
}"""
)
await watchdog
assert await page.evaluate("() => window.clicked")


async def test_should_be_atomic(selectors, page, utils):
await utils.register_selector_engine(
selectors,
"dispatchEvent",
"""{
create(root, target) { },
query(root, selector) {
const result = root.querySelector(selector);
if (result)
Promise.resolve().then(() => result.onclick = "");
return result;
},
queryAll(root, selector) {
const result = Array.from(root.querySelectorAll(selector));
for (const e of result)
Promise.resolve().then(() => result.onclick = "");
return result;
}
}""",
)
await page.setContent('<div onclick="window._clicked=true">Hello</div>')
await page.dispatchEvent("dispatchEvent=div", "click")
assert await page.evaluate("() => window._clicked")


@pytest.mark.skip_browser("webkit")
async def test_should_dispatch_drag_drop_events(page, server):
await page.goto(server.PREFIX + "/drag-n-drop.html")
dataTransfer = await page.evaluateHandle("() => new DataTransfer()")
await page.dispatchEvent("#source", "dragstart", {"dataTransfer": dataTransfer})
await page.dispatchEvent("#target", "drop", {"dataTransfer": dataTransfer})
assert await page.evaluate(
"""() => {
return source.parentElement === target;
}"""
)


@pytest.mark.skip_browser("webkit")
async def test_should_dispatch_drag_and_drop_events_element_handle(page, server):
await page.goto(server.PREFIX + "/drag-n-drop.html")
dataTransfer = await page.evaluateHandle("() => new DataTransfer()")
source = await page.querySelector("#source")
await source.dispatchEvent("dragstart", {"dataTransfer": dataTransfer})
target = await page.querySelector("#target")
await target.dispatchEvent("drop", {"dataTransfer": dataTransfer})
assert await page.evaluate(
"""() => {
return source.parentElement === target;
}"""
)


async def test_should_dispatch_click_event_element_handle(page, server):
await page.goto(server.PREFIX + "/input/button.html")
button = await page.querySelector("button")
await button.dispatchEvent("click")
assert await page.evaluate("() => result") == "Clicked"

0 comments on commit 1870817

Please sign in to comment.