比照 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
如果你使用的是 playwright
或 puppeteer
無頭模式(headless),你可以在 context
或 page
層級攔截 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 影響!🎯