Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

import os
import signal
import subprocess
import time
import pytest
IS_WINDOWS = os.name == "nt"
if IS_WINDOWS:
SIGNALS = [signal.CTRL_BREAK_EVENT]
else:
SIGNALS = [signal.SIGINT, signal.SIGTERM]
def is_process_alive(pid):
if IS_WINDOWS:
try:
output = subprocess.check_output(
["tasklist", "/FI", f"PID eq {pid}"], text=True
)
return str(pid) in output
except subprocess.CalledProcessError:
return False
try:
os.kill(pid, 0)
return True
except OSError:
return False
def wait_for_process_exit(pid, timeout=10):
end_time = time.time() + timeout
while time.time() < end_time:
if not is_process_alive(pid):
return True
time.sleep(0.1)
return False
@pytest.mark.parametrize("signal", SIGNALS)
def test_firefox_quits_on_signal(configuration, geckodriver, signal):
popen_kwargs = {}
if IS_WINDOWS:
# Start geckodriver in its own process group so that
# CTRL_BREAK_EVENT is only delivered to it and not to the
# parent cmd.exe, which would otherwise prompt
# "Terminate batch job (Y/N)?" and hang.
popen_kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP
driver = geckodriver(config=configuration, popen_kwargs=popen_kwargs)
driver.new_session()
firefox_pid = driver.session.capabilities["moz:processID"]
driver.proc.send_signal(signal)
assert wait_for_process_exit(firefox_pid), (
"Firefox process still running after geckodriver was terminated"
)