Playwright Python 驱动 WebRTC 自动化测试:从权限到弱网重连的完整链路

发布时间:2026/9/11 16:24:23
Playwright Python 驱动 WebRTC 自动化测试:从权限到弱网重连的完整链路 Playwright Python 驱动 WebRTC 自动化测试从权限到弱网重连的完整链路【免费下载链接】playwright-pythonPython version of the Playwright testing and automation library.项目地址: https://gitcode.com/GitHub_Trending/pl/playwright-python昨晚的回归测试跑到一半远端视频突然黑屏卡住你盯着屏幕反复点重呼却怎么也复现不出刚才那条故障时序。这类实时音视频问题靠手动测试几乎抓不住而 Playwright Python 恰好能把它变可控在导航前预设媒体权限、用 evaluate 监听 ICE交互式连接建立Interactive Connectivity Establishment状态机、再用路由拦截模拟弱网把整条通话链路推进可复现的自动化流程。WebRTC 测试到底难在哪这一节先回答为什么 WebRTC 测试不适合只靠手动点。难在三点设备依赖、时序敏感、状态不可见。摄像头、麦克风要么靠真机要么靠模拟源权限弹窗在自动化里没人点ICE 协商是异步过程状态在connecting和connected之间跳转往往只持续几十毫秒肉眼根本抓不到再加上弱网、掉线、重连这些组合手动测试跑一轮要占掉一整个下午还说不清失败到底是哪一环的问题。维度手动测试Playwright Python 自动化设备与权限依赖真实摄像头/麦克风弹窗靠人点无头浏览器 上下文预设权限零人工故障复现靠记忆和截图时序抓不住脚本固化步骤失败可反复回放状态观测肉眼判断好像连上了evaluate 轮询 ICE 状态机断言留痕弱网 / 断线拔网线、切飞行模式路由拦截随时注入、随时恢复从零搭一个 WebRTC 测试沙盒这一节解决环境准备装上 Playwright Python十分钟搭出能跑 WebRTC 页面的最小框架。先装库并下载浏览器驱动pip install playwright playwright install chromium无头模式下 Chromium 依然能枚举模拟媒体设备、能完整跑 WebRTC 链路所以沙盒不必依赖真机摄像头。下面这段 10 行骨架可以直接复制运行它把启动 → 授权 → 加载 → 自检一次串完# webrtc_sandbox.pyWebRTC 自动化测试最小骨架 from playwright.sync_api import sync_playwright with sync_playwright() as p: browser p.chromium.launch(headlessTrue) context browser.new_context(permissions[camera, microphone]) page context.new_page() page.goto(http://localhost:8080/call) # 换成你的被测页面 device page.evaluate(() navigator.mediaDevices.enumerateDevices()[0]) print(首个媒体设备:, device) context.close() browser.close()跑通它你就有了后面所有断言的落脚地一个权限干净、状态可查的浏览器页面。打通一条完整通话链路这一节按授权 → 建连 → 收流三步把一次通话验证成可断言的自动化流程。预设媒体权限让授权在导航之前发生摄像头权限弹窗必须在goto之前就被授掉否则无头模式下没人替你点允许整条链路卡死在第一步# 权限随上下文授予origin 与被测应用域名严格一致 context browser.new_context( permissions[camera, microphone], originhttp://localhost:8080, ) page context.new_page() page.goto(http://localhost:8080/call)仓库里的 tests/async/test_browsercontext.py 有大量上下文权限与配置的现成用例遇到授了权却无效时可以对照检查参数写法。监听 ICE 连接状态把连上了吗变成断言别用sleep猜连接时机直接挂事件监听等 ICE 状态机自己喊停。仓库的 tests/async/test_wait_for_function.py 演示了page.evaluate挂 Promise 回调的写法思路完全一致# 监听 ICE 状态机直到进入稳定态才放行 ice_state page.evaluate( () new Promise(resolve { const pc window.peerConnection; const onState () { if ([connected, completed].includes(pc.iceConnectionState)) { pc.removeEventListener(iceconnectionstatechange, onState); resolve(pc.iceConnectionState); } }; pc.addEventListener(iceconnectionstatechange, onState); }) ) assert ice_state in (connected, completed), f建连失败: {ice_state}注意监听器要在拿到终态后手动解绑否则页面后续重连时回调会再次触发。校验媒体流可见性确认真的出画了建连成功不等于出画视频元素可能可见但一帧没收到。用expect断元素可见再用videoWidth排除黑屏# 远端视频必须可见且真的收到帧 from playwright.sync_api import expect remote page.locator(#remote-video) expect(remote).to_be_visible(timeout15000) frame_w remote.evaluate(el el.videoWidth) assert frame_w 0, video 元素可见但未收到视频帧videoWidth 0是判断流真的到了的最朴素也最可靠的信号比查readyState更直观。给链路做压力测试弱网模拟与故障注入这一节回答怎么判断链路稳不稳在弱网下通话能不能扛住、条件恢复后能不能自愈。Playwright 的context.route拦截所有请求注入延迟即可模拟弱网解除拦截即恢复整个过程不需要碰真实网络# 弱网注入与恢复 def weak_net(route): page.wait_for_timeout(2000) # 每个请求追加 2s 延迟 route.continue_() context.route(**/*, weak_net) page.wait_for_timeout(4000) context.unroute(**/*, weak_net) # 恢复网络 page.wait_for_timeout(3000) recovered page.evaluate(() window.peerConnection.iceConnectionState) assert recovered in (connected, completed), 链路未在弱网后恢复判断链路稳不稳看两个信号弱网期间 ICE 状态没有跌到failed/disconnected后一去不返恢复后状态能回到connected。前者说明抗抖动能力后者说明重连机制真的在工作。仓库 tests/async/test_unroute_behavior.py 专门覆盖了解除路由后的各种边界行为写断言前值得翻一眼。多人通话与屏幕共享等进阶玩法这一节把单链路扩展成多对端双Page模拟两端用户屏幕共享则把选择器弹窗交给已有的文件选择 API 处理。两个页面同属一个 context权限只授一次若需要模拟互相独立的设备环境可以各自开新 context# 双页面模拟同一房间的两端 room http://localhost:8080/room/42 alice context.new_page() alice.goto(room) alice.click(button#join) bob context.new_page() bob.goto(room) bob.click(button#join) # 各自断言对方的视频已出画 expect(alice.locator(#remote-video)).to_be_visible(timeout15000) expect(bob.locator(#remote-video)).to_be_visible(timeout15000)对比维度单链路用例双页面对战用例页面数12权限弹窗每 context 一次共享 context 只弹一次断言重点本地出画双方互相出画、无串流屏幕共享场景里选择要共享的内容通常以文件选择器形式弹出参考 tests/async/test_input.py 中set_input_files的用法即可把选择操作也自动化掉。常见坑位速查下面这张表收拢了日常踩得最多的六类问题排查时按方向走一遍通常能定位坑位现象排查方向ICE 协商失败状态卡checking或failed检查信令通道是否打通、SDP 交换是否完成、STUN/TURN 是否可达权限弹窗未处理getUserMedia被拒、本地流为空确认new_context授予权限早于goto且origin与页面域名一致媒体流超时远端 video 可见但一直黑屏区分元素未渲染与渲染但无帧查videoWidth与readyState弱网抖动误判延迟注入后断言大量超时路由里追加的延迟要计入页面内所有等待时间或给断言放宽超时多页面互相干扰双端测试偶发失败检查两个页面是否意外共享了同一origin的媒体设备或标签页无头环境无声有画面无音频无头 Chromium 音频管道受限音频类断言建议在headlessFalse下单独跑Playwright Python 把实时音视频测试里最烦的三件事——预设媒体权限、监听 ICE 状态机、注入弱网故障——都收敛成了几行 API你缺的只是把链路拆成可断言的步骤。API 细节以官方文档为准仓库tests/目录下的现成用例可以直接当模板参考动手中踩到新坑欢迎到仓库提 issue 或 PR。【免费下载链接】playwright-pythonPython version of the Playwright testing and automation library.项目地址: https://gitcode.com/GitHub_Trending/pl/playwright-python创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考