nodriver與瀏覽器內建的 JavaScript Alerts互動

比照 network 的範例, 修改成 cdp.page 就可以 work 了, 範例傳送門:
https://github.com/ultrafunkamsterdam/nodriver/blob/main/example/network_monitor.py

資料來源:
https://stackoverflow.com/questions/78597671/how-to-handle-alerts-in-nodriver

import nodriver as uc
import asyncio

class NodriverAlert(): 
    def __init__(self):
        self.browser = None
        self.alert_message = None

    async def js_alert_message(self, event: uc.cdp.page):
        if 'JavascriptDialogOpening' in str(type(event)):
            # print(f'Alert class return: {event}')
            self.alert_message = event.message
            print(f'The alert message is: {self.alert_message}')
        
        elif 'JavascriptDialogClosed' in str(type(event)):
            print(event)
            print('Close alert')
            event.result = True
        
        else: 
            print(event)

    async def js_alert_message_click(self, event: uc.cdp.page):
        if self.alert_message != None:
            try:
                response = await asyncio.wait_for(self.tab.send(uc.cdp.page.handle_java_script_dialog(accept=False)), timeout=10.0)
            except asyncio.TimeoutError:
                response = 'timeout'
            print(f'Alert OK! - response: {response}')
        else:
            print('sem alert')

        
    async def main(self):
        url = 'https://testpages.herokuapp.com/styled/alerts/alert-test.html'
        self.browser = await uc.start()
        self.tab = await self.browser.get(url)

        # We'll need to add a handler
        self.tab.add_handler(uc.cdp.page, self.js_alert_message)
        self.tab.add_handler(uc.cdp.page, self.js_alert_message_click)

        # Now, display an alert
        print('Click to show alert...')
        show_alert_box_btn = await self.tab.find('#alertexamples')
        try:
            await asyncio.wait_for(show_alert_box_btn.mouse_click(), timeout=5)
        except asyncio.TimeoutError:
            pass
        print('Finish!')


example = NodriverAlert()
asyncio.run(example.main())

print(example.alert_message)

nodriver(無瀏覽器 Web 自動化)環境下,通常無法直接與瀏覽器內建的 JavaScript Alerts(如 alert()confirm()prompt() 互動,因為這些功能依賴於 GUI 瀏覽器的行為。然而,你可以使用以下方式來處理這些警示框(alerts):

1. 確保 JavaScript 禁用 Alerts

如果你使用的是 playwrightpuppeteer 無頭模式(headless),你可以在 contextpage 層級攔截 alert() 等函數:

await page.evaluate(() => {
  window.alert = () => {};
  window.confirm = () => true;
  window.prompt = () => "default input";
});

這樣可以防止 alert() 阻塞你的自動化流程。


2. 使用 evaluate 模擬回應

如果你的測試涉及 confirm()prompt(),你可以使用 evaluate() 來預設回應:

await page.evaluate(() => {
  window.confirm = () => true; // 模擬點擊 "確定"
  window.prompt = () => "Test Input"; // 模擬輸入框
});

3. nodriver 進行 API 層級測試

如果你的環境完全無 GUI 瀏覽器(例如 nodriver 只處理 API 請求),那麼應該從 API 層面檢查:

  • 檢查後端 API 是否返回錯誤(避免前端觸發 alert())。
  • 直接發送 fetch 請求,驗證後端返回的錯誤訊息。

範例:

import requests

response = requests.get("https://example.com/api/trigger-alert")
print(response.json())  # 確保 API 沒有返回錯誤訊息

4. 確保測試環境移除 Alerts

如果 nodriver 測試仍然會遇到警告彈窗,可能是測試環境仍在執行完整瀏覽器,你可以:

  • 檢查測試環境是否真的在「無 GUI 模式」(headless)。
  • beforeEach 之類的 setup 階段執行 window.alert = () => {};

這樣就能讓 nodriver 在測試時不受 alerts 影響!🎯

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *