I’ve been trying to find a headless browser that can handle JavaScript pop-ups but I’m having trouble. I tested a couple of Docker images with browsers. One was totally headless and the other had Chrome running with xvfb. The problem is that neither of them seem to work with pop-ups created by window.open. When I check driver.window_handles there’s always just one element.
I’m using Python with Selenium WebDriver for this. Maybe I should try without Docker? Has anyone had any luck with this? I’d really appreciate any tips or suggestions on how to get a headless browser working with pop-ups. It’s been a real headache trying to figure this out on my own.
# Example code snippet
a = webdriver.ChromeOptions()
a.add_argument('--headless')
d = webdriver.Chrome(options=a)
d.get('https://example.com')
d.execute_script('window.open()')
print(len(d.window_handles)) # Always prints 1
I’ve had success using Playwright for handling pop-ups in headless mode. It’s designed to work with multiple browsers and has robust support for pop-ups and new windows.
Here’s a quick example in Python:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.goto('https://example.com')
with page.expect_popup() as popup_info:
page.evaluate('window.open(\"https://example.com/popup\")')
popup = popup_info.value
print(f'Number of contexts: {len(browser.contexts)}')
print(f'Number of pages: {len(browser.contexts[0].pages)}')
browser.close()
This approach has been reliable for me, capturing pop-ups consistently in headless mode. Give it a try and see if it resolves your issue.
I’ve actually faced a similar issue when working with headless browsers and pop-ups. From my experience, the problem often lies in how JavaScript handles pop-ups in a headless environment. One solution that worked for me was using Puppeteer instead of Selenium.
Puppeteer is specifically designed for headless Chrome/Chromium and has better support for handling pop-ups. It allowed me to interact with new windows more reliably. Here’s a basic example of how you might approach this with Puppeteer:
import asyncio
from pyppeteer import launch
async def handle_popups():
browser = await launch(headless=True)
page = await browser.newPage()
await page.goto('https://example.com')
# Listen for new pages (pop-ups)
async def handle_new_page(target):
if target.type == 'page':
new_page = await target.page()
# Do something with the new page
browser.on('targetcreated', handle_new_page)
# Trigger pop-up
await page.evaluate('window.open("https://example.com/popup")')
# Wait and close
await asyncio.sleep(5)
await browser.close()
asyncio.get_event_loop().run_until_complete(handle_popups())
This approach has been more reliable for me when dealing with pop-ups in a headless environment. Hope this helps!