146 lines
4.5 KiB
Python
146 lines
4.5 KiB
Python
# 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 asyncio
|
|
import multiprocessing
|
|
import os
|
|
import signal
|
|
import sys
|
|
from typing import Any, Dict
|
|
|
|
import pytest
|
|
|
|
from playwright.async_api import async_playwright
|
|
from playwright.sync_api import sync_playwright
|
|
|
|
|
|
def _test_signals_async(
|
|
browser_name: str, launch_arguments: Dict, wait_queue: "multiprocessing.Queue[str]"
|
|
) -> None:
|
|
# On Windows, hint to mypy and pyright that they shouldn't check this function
|
|
if sys.platform == "win32":
|
|
return
|
|
|
|
os.setpgrp()
|
|
sigint_received = False
|
|
|
|
def my_sig_handler(signum: int, frame: Any) -> None:
|
|
nonlocal sigint_received
|
|
sigint_received = True
|
|
|
|
signal.signal(signal.SIGINT, my_sig_handler)
|
|
|
|
async def main() -> None:
|
|
playwright = await async_playwright().start()
|
|
browser = await playwright[browser_name].launch(
|
|
**launch_arguments,
|
|
handle_sigint=False,
|
|
)
|
|
context = await browser.new_context()
|
|
page = await context.new_page()
|
|
notified = False
|
|
try:
|
|
while not sigint_received:
|
|
if not notified:
|
|
wait_queue.put("ready")
|
|
notified = True
|
|
await page.wait_for_timeout(100)
|
|
finally:
|
|
wait_queue.put("close context")
|
|
await context.close()
|
|
wait_queue.put("close browser")
|
|
await browser.close()
|
|
wait_queue.put("close playwright")
|
|
await playwright.stop()
|
|
wait_queue.put("all done")
|
|
|
|
asyncio.run(main())
|
|
|
|
|
|
def _test_signals_sync(
|
|
browser_name: str, launch_arguments: Dict, wait_queue: "multiprocessing.Queue[str]"
|
|
) -> None:
|
|
# On Windows, hint to mypy and pyright that they shouldn't check this function
|
|
if sys.platform == "win32":
|
|
return
|
|
|
|
os.setpgrp()
|
|
sigint_received = False
|
|
|
|
def my_sig_handler(signum: int, frame: Any) -> None:
|
|
nonlocal sigint_received
|
|
sigint_received = True
|
|
|
|
signal.signal(signal.SIGINT, my_sig_handler)
|
|
|
|
playwright = sync_playwright().start()
|
|
browser = playwright[browser_name].launch(
|
|
**launch_arguments,
|
|
handle_sigint=False,
|
|
)
|
|
context = browser.new_context()
|
|
page = context.new_page()
|
|
notified = False
|
|
try:
|
|
while not sigint_received:
|
|
if not notified:
|
|
wait_queue.put("ready")
|
|
notified = True
|
|
page.wait_for_timeout(100)
|
|
finally:
|
|
wait_queue.put("close context")
|
|
context.close()
|
|
wait_queue.put("close browser")
|
|
browser.close()
|
|
wait_queue.put("close playwright")
|
|
playwright.stop()
|
|
wait_queue.put("all done")
|
|
|
|
|
|
def _create_signals_test(
|
|
target: Any, browser_name: str, launch_arguments: Dict
|
|
) -> None:
|
|
# On Windows, hint to mypy and pyright that they shouldn't check this function
|
|
if sys.platform == "win32":
|
|
return
|
|
|
|
wait_queue: "multiprocessing.Queue[str]" = multiprocessing.Queue()
|
|
process = multiprocessing.Process(
|
|
target=target, args=[browser_name, launch_arguments, wait_queue]
|
|
)
|
|
process.start()
|
|
assert process.pid is not None
|
|
logs = [wait_queue.get()]
|
|
os.killpg(os.getpgid(process.pid), signal.SIGINT)
|
|
process.join()
|
|
while not wait_queue.empty():
|
|
logs.append(wait_queue.get())
|
|
assert logs == [
|
|
"ready",
|
|
"close context",
|
|
"close browser",
|
|
"close playwright",
|
|
"all done",
|
|
]
|
|
assert process.exitcode == 0
|
|
|
|
|
|
@pytest.mark.skipif(sys.platform == "win32", reason="there is no SIGINT on Windows")
|
|
def test_signals_sync(browser_name: str, launch_arguments: Dict) -> None:
|
|
_create_signals_test(_test_signals_sync, browser_name, launch_arguments)
|
|
|
|
|
|
@pytest.mark.skipif(sys.platform == "win32", reason="there is no SIGINT on Windows")
|
|
def test_signals_async(browser_name: str, launch_arguments: Dict) -> None:
|
|
_create_signals_test(_test_signals_async, browser_name, launch_arguments)
|