Karate如何截取含垂直滚动页及水平滚动表格的完整页面截图
Karate全页(含嵌套滚动区域)截图实现
你现有默认截图逻辑仅能捕获当前视口内容,代码如下:
* def bytes = screenshot(false) * def writeToPath = karate.write(bytes, path)
针对需要同时捕获页面垂直滚动内容、XPath定位的嵌套表格水平滚动内容的需求,可直接使用以下两种方案:
方案1:基于CDP的低成本实现(推荐,仅适配Chromium内核浏览器,无额外依赖)
利用Karate原生支持的Chrome DevTools Protocol调用能力,不需要引入第三方包,直接在.feature文件中即可完成全页截图,核心逻辑是先临时撑开所有滚动容器确保全量内容渲染,再调用CDP截图接口开启captureBeyondViewport参数捕获超出视口的内容,截图完成后还原页面样式避免影响后续用例。
可直接复用的代码:
# 替换为你自己的表格相对XPath、截图保存路径 * def tableXpath = "//div[@class='content-wrap']//table" * def savePath = 'full-page-screenshot.png' # 临时撑开页面+表格滚动容器,保存原有样式用于后续还原 * def preRender = """ function(xpath) { // 重置页面根节点滚动限制 document.documentElement.style.height = 'auto'; document.body.style.height = 'auto'; document.documentElement.style.overflow = 'visible'; document.body.style.overflow = 'visible'; window.scrollTo(0, 0); // 定位目标表格,撑开其外层滚动容器 const table = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; const tableScrollWrap = table.parentElement; const originStyles = { wrapOverflow: tableScrollWrap.style.overflow, wrapWidth: tableScrollWrap.style.width, wrapHeight: tableScrollWrap.style.height }; tableScrollWrap.style.overflow = 'visible'; tableScrollWrap.style.width = 'max-content'; tableScrollWrap.style.height = 'max-content'; return originStyles; } """ * def originStyleMap = preRender(tableXpath) # 等待页面重排、懒加载内容渲染完成,可根据页面实际加载速度调整时长 * delay(500) # 调用CDP接口捕获包含视口外内容的全页截图 * def cdpScreenshotConfig = { format: 'png', captureBeyondViewport: true, fromSurface: true } * def cdpRes = driver.send('Page.captureScreenshot', cdpScreenshotConfig) * def imgBytes = java.util.Base64.getDecoder().decode(cdpRes.data) * karate.write(imgBytes, savePath) # 还原页面原有样式 * def restorePage = """ function(styleMap, xpath) { const table = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; const tableScrollWrap = table.parentElement; tableScrollWrap.style.overflow = styleMap.wrapOverflow; tableScrollWrap.style.width = styleMap.wrapWidth; tableScrollWrap.style.height = styleMap.wrapHeight; document.documentElement.style.height = ''; document.body.style.height = ''; document.documentElement.style.overflow = ''; document.body.style.overflow = ''; } """ * restorePage(originStyleMap, tableXpath)
适配说明
- 如果页面存在多层嵌套滚动容器,只需要在
preRender函数中补充对应容器的样式撑开逻辑即可 - 如果截图存在空白块,适当调大
delay等待时长,或增加图片、异步内容加载完成的判断逻辑即可
方案2:跨浏览器兼容实现
如果需要兼容Firefox等非Chromium内核浏览器,可以采用分块滚动拼接的方案:
- 先计算页面总垂直滚动高度、目标表格的总水平滚动宽度
- 按视口尺寸分步滚动页面和表格容器,逐块捕获视口截图
- 借助本地图片处理工具(如ImageMagick)或Java图片处理类库(如image4j)将分块截图拼接为完整全页图
该方案兼容性更强,但实现复杂度更高,需要手动处理滚动坐标对齐、拼接边界重合的问题,无强兼容需求时优先选择方案1即可。
常见问题
- 为什么Karate自带的
screenshot(true)全页参数无法捕获完整表格内容?
原生全页截图逻辑仅处理页面根节点的垂直滚动,不会自动识别页面内部的嵌套滚动容器,因此内部带水平滚动的表格会被截断。
内容的提问来源于stack exchange,提问作者Aommie
相关产品推荐
相关产品推荐

