"""Headless browser shutdown regression; never opens visible windows or external sites.""" import json, os, subprocess, time from pathlib import Path HELPER=Path(__file__).resolve().parents[1]/'tools/playwright/browser_helper.mjs' def processes(): rows={} for line in subprocess.check_output(['ps','-axo','pid=,ppid=,command='],text=True).splitlines(): pid,parent,cmd=line.strip().split(None,2);rows[int(pid)]=(int(parent),cmd) return rows def main(): env={**os.environ,'GROKBOY_BROWSER_HEADED':'0'};env.pop('GROKBOY_BROWSER_PROFILE',None) for mode in ('close','eof','signal','single'): args=['node',str(HELPER)] if mode=='single':args+=['--cmd',json.dumps({'id':'1','op':'navigate','url':'data:text/html,cleanup fixture'})] p=subprocess.Popen(args,env=env,stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True) tracked=set() try: if mode=='single': while p.poll() is None: tracked.update(pid for pid,(parent,cmd) in processes().items() if parent==p.pid and ('chrome' in cmd.lower() or 'chromium' in cmd.lower())) time.sleep(.02) assert p.returncode==0,p.stderr.read() else: p.stdin.write(json.dumps({'id':'1','op':'navigate','url':'data:text/html,cleanup fixture'})+'\n');p.stdin.flush() assert json.loads(p.stdout.readline())['ok'] tracked={pid for pid,(parent,cmd) in processes().items() if parent==p.pid and ('chrome' in cmd.lower() or 'chromium' in cmd.lower())} assert tracked,'must observe actual browser process' if mode=='close': p.stdin.write('{"id":"2","op":"close"}\n');p.stdin.flush();assert json.loads(p.stdout.readline())['ok'];p.stdin.close() elif mode=='eof':p.stdin.close() else:p.terminate() p.wait(timeout=10) deadline=time.monotonic()+5 while tracked.intersection(processes()) and time.monotonic()