WebdriverIO 的 ocrGetText 命令:基于 @wdio/ocr-service 从屏幕截图中提取可见文本
【免费下载链接】webdriverioNext-gen browser and mobile automation test framework for Node.js项目地址: https://gitcode.com/GitHub_Trending/we/webdriverio
ocrGetText是 WebdriverIO OCR 测试生态(@wdio/ocr-service)提供的五个自定义命令之一,它通过光学字符识别(OCR)把当前屏幕/设备上所有可见文字一次性提取出来,返回一个包含全部识别文本的字符串。当被测的移动原生应用或桌面 Web 站点缺少可用的唯一标识符(id、data-testid、稳定的 CSS 选择器)时,这个命令可以直接用"看得见的文字"完成断言与调试。读完本文,你将掌握ocrGetText的调用方式、输出结构、contrast/haystack/language三个核心选项的完整用法,以及该命令在@wdio/ocr-service整体工作流中的位置和底层实现原理。
1. 命令背景:ocrGetText属于哪套工具
ocrGetText并不是 WebdriverIO 内核内置的浏览器命令,而是由第三方服务@wdio/ocr-service在启动时注册到browser/driver对象上的自定义命令。该服务面向"元素缺乏唯一标识符"的自动化场景:它利用 OCR 技术,根据屏幕上的可见文本来搜索、等待并交互元素,弥补常规 选择器机制 的不足。
根据 what-is-wdio-ocr-service.md 的说明,该服务共提供五个自定义命令,ocrGetText是其中唯一"纯读取"、不涉及点击与输入的命令:
| 命令 | 作用 |
|---|---|
browser.ocrGetText | 提取屏幕上全部可见文本 |
browser.ocrGetElementPositionByText | 按文本定位元素坐标 |
browser.ocrWaitForTextDisplayed | 等待某段文本出现 |
browser.ocrClickOnText | 点击匹配文本的元素 |
browser.ocrSetValue | 向匹配文本的输入框写入值 |
服务注册命令时会在 WebdriverIO 日志中留下 INFO 记录,例如 getting-started.md 中展示的日志:
[0-0] 2024-05-24T06:55:12.750Z INFO @wdio/ocr-service: Adding browser command "ocrGetText" to browser object2. 基本用法
ocrGetText的签名很简单:接收一个可选的参数对象,返回一个Promise<string>(识别出的全部文本)。最简单的调用不需要任何参数:
const result = await browser.ocrGetText(); console.log("result = ", JSON.stringify(result, null, 2));命令执行后,示例输出如下(识别的是 WebdriverIO 官网首页的文字):
result = "VS docs API Blog Contribute Community Sponsor v8 *Engishy CV} Q OQ G asearch Next-gen browser and mobile automation Welcome! How can | help? i test framework for Node.js Get Started Why WebdriverI0? View on GitHub Watch on YouTube"从结果可以看到两点重要事实:
- 返回的是拼接后的整段字符串,而不是带坐标的结构化数据。如果需要在某段文本在屏幕上的精确坐标,应改用
ocrGetElementPositionByText。 - OCR 存在识别误差:示例中
Engishy、WebdriverI0等明显是误识别,|可能是图标。OCR 是概率性的,因此该服务在"按文本定位/点击"的环节引入了模糊匹配(Fuse.js)来兜底,而ocrGetText的裸结果需要自行结合断言做容错处理。
2.1 运行日志
每次调用都会在 WebdriverIO 的webdriver日志通道中记录COMMAND与RESULT,方便调试:
[0-0] 2024-05-25T17:38:25.970Z INFO webdriver: COMMAND ocrGetText() ...................... [0-0] 2024-05-25T17:38:26.738Z INFO webdriver: RESULT VS docs API Blog Contribute Community Sponsor v8 *Engishy CV} Q OQ G asearch Next-gen browser and mobile automation Welcome! How can | help? i test framework for Node.js Get Started Why WebdriverI0? View on GitHub Watch on YouTubeCOMMAND与RESULT之间的......表示服务内部完成了截屏、图像优化与 Tesseract 识别。参考 getting-started.md 中的日志,服务还会以@wdio/ocr-service为 logger 名输出更详细的处理耗时与产物路径:
[0-0] 2024-05-24T06:55:13.667Z INFO @wdio/ocr-service:getData: Using system installed version of Tesseract [0-0] 2024-05-24T06:55:14.019Z INFO @wdio/ocr-service:getData: It took '0.351s' to process the image. [0-0] 2024-05-24T06:55:14.019Z INFO @wdio/ocr-service:getData: OCR Image with found text can be found here: [0-0] .tmp/ocr/desktop-1716533713585.png处理后的标注图片默认写入imagesFolder(默认{project-root}/.tmp/ocr),可用于人工核对识别效果。
3. 选项详解
ocrGetText支持三个可选参数:contrast、haystack、language。
3.1contrast
| 属性 | 值 |
|---|---|
| 类型 | number |
| 必填 | 否 |
| 默认值 | 0.25 |
控制 OCR 前的图像对比度:值越高图像越暗,值越低图像越亮,取值范围为-1到1。提高对比度有助于在噪点较多的背景中找到文字。该参数与服务级配置contrast的语义完全一致(默认也是0.25,见 getting-started.md),在命令级传入会覆盖服务级默认值。
await browser.ocrGetText({ contrast: 0.5 });为什么需要调整对比度:Tesseract 对"文字与背景颜色区分不明显"的图像识别效果很差。FAQ(ocr-faq.md)中特别指出,浅色文字配浅色背景、深色文字配深色背景往往难以识别,而白字深底很容易识别。因此在定位前先把图像处理成高对比度的黑白图,是
@wdio/ocr-service处理管线中的关键一步。
3.2haystack
| 属性 | 值 |
|---|---|
| 类型 | WebdriverIO.Element \| ChainablePromiseElement \| Rectangle |
| 必填 | 否 |
指定 OCR 需要检索的屏幕区域("草垛"),可以是一个元素,也可以是包含x、y、width、height的矩形对象。缩小搜索范围能显著降低识别耗时、减少误报,是官方推荐的性能优化手段(详见 more-test-optimization.md)。
// 传入 WebdriverIO 元素(ChainablePromiseElement 或 await 后的 Element) await browser.ocrGetText({ haystack: $("elementSelector") }); // OR await browser.ocrGetText({ haystack: await $("elementSelector") }); // OR 传入矩形 await browser.ocrGetText({ haystack: { x: 10, y: 50, width: 300, height: 75, }, });需要注意原文档中haystack的"必填"标记写作了类型说明(Mandatory: WebdriverIO.Element | ...),实际从语义看它是可选参数——不提供时会对整个屏幕进行 OCR,官方 FAQ 也提到"处理过大区域可能找不到文本,此时应通过提供haystack缩小范围"。
3.3language
| 属性 | 值 |
|---|---|
| 类型 | string |
| 必填 | 否 |
| 默认值 | eng |
指定 Tesseract 使用的识别语言。支持的语言由 Tesseract 的语言数据文件({languageCode}.traineddata)决定。服务导出了SUPPORTED_OCR_LANGUAGES常量,建议通过它引用语言代码,避免手写拼错:
import { SUPPORTED_OCR_LANGUAGES } from "@wdio/ocr-service"; await browser.ocrGetText({ // 使用荷兰语识别 language: SUPPORTED_OCR_LANGUAGES.DUTCH, });关于{languageCode}.traineddata:这是 Tesseract 的语言训练数据文件,包含字符集数据、语言模型、特征提取器与训练数据。FAQ(ocr-faq.md)建议将其纳入版本控制,以保证团队与不同环境之间 OCR 结果的一致性、可复现性。
4. 底层原理:一次ocrGetText背后发生了什么
根据 what-is-wdio-ocr-service.md 对服务整体流程的描述,ocrGetText的识别管线可以拆成四步:
- 截屏:对当前屏幕/设备创建截图;如果提供了
haystack(元素或矩形),则只截取该区域。 - 图像优化:把截图转换为高对比度的黑白图,以减少背景噪点对 OCR 的干扰;对比度可通过
contrast按命令自定义。 - OCR 识别:调用 Tesseract.js(Node 版)或本机安装的 Tesseract,提取屏幕上所有文本,并把识别出的文字高亮标注到图像上;支持多种语言。
- 模糊匹配:如需定位/点击(其他命令),再用 Fuse.js 的模糊逻辑找出与目标字符串"近似相等"的匹配(例如搜索
Username也能命中Usename)。
其中第 3 步的 OCR 引擎选择规则为:服务默认检测系统是否装有 Tesseract 本地安装,有则优先使用本地版(处理更快),否则回退到随包自动安装的 Tesseract.js。这解释了前面日志中Using system installed version of Tesseract这一行的含义。
关于引擎的选型依据,除了 getting-started.md 的 note 说明("如果本机没有安装 Tesseract,将自动使用 Node.js 版 Tesseract.js"),也可参考性能优化文档 more-test-optimization.md:Node.js 并不擅长重型图像处理,使用本地 Tesseract 可把示例脚本的执行时间从 5.9s 降到 3.9s(约 34% 的缩减),裁剪haystack则从 5.9s 降到 4.8s(约 19% 的缩减)。这两种手段对ocrGetText同样有效——尤其是用haystack只处理局部区域,对提取特定区块文本非常有帮助。
需要说明的是:
@wdio/ocr-service本身不在本仓库的packages/目录内(本仓库仅包含其文档与使用示例,完整实现托管在独立的 visual-testing 仓库中)。因此本文以仓库内 ocr-testing 文档目录与 ocr.js 示例为准进行说明。
5. 完整示例:安装、配置与一次实战调用
5.1 安装与启用服务
以开发依赖安装@wdio/ocr-service(安装 WebdriverIO 主框架的方法见 GettingStarted.md):
npm install @wdio/ocr-service --save-dev在wdio.conf.js/wdio.conf.ts的services数组中注册"ocr"并配置选项。仓库中的 ocr.js 给出了标准写法:
import { defineConfig } from '@wdio/config' export const config = defineConfig({ //... services: [ // your other services [ 'ocr', { contrast: 0.25, imagesFolder: '.tmp/', language: 'eng', }, ], ], })服务级配置项与ocrGetText命令级参数一一对应:
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
contrast | number | 0.25 | 图像对比度,取值范围-1~1 |
imagesFolder | string | {project-root}/.tmp/ocr | OCR 结果(标注图)存放目录;若自定义,服务会自动追加ocr子目录 |
language | string | eng | Tesseract 识别语言 |
5.2 使用 TypeScript
为获得类型提示,把@wdio/ocr-service加入tsconfig.json的types:
{ "compilerOptions": { "types": ["node", "@wdio/globals/types", "@wdio/ocr-service"] } }5.3 组合实战:断言页面可见文本
把提取文本与断言、等待类命令结合,即可实现"看不到选择器就看文字"的测试策略:
import { browser, expect } from '@wdio/globals' describe('OCR text extraction', () => { it('should extract visible text from the screen', async () => { await browser.url('https://webdriver.io') // 提取整屏文本 const fullText = await browser.ocrGetText() console.log(fullText) // 只提取顶部导航区域,更快更准 const navText = await browser.ocrGetText({ haystack: { x: 0, y: 0, width: 1920, height: 80 }, contrast: 0.5, }) console.log(navText) }) })由于ocrGetText返回整段字符串,配合expect(string).toContain(...)即可完成可见文本断言;若 OCR 识别有轻微误差,可结合正则或自定义容错逻辑。官方 FAQ 的建议是:尽量多用 WebdriverIO 原生命令/选择器,仅在找不到唯一选择器或选择器过于脆弱时才使用 OCR 命令。
6. 相关命令与 FAQ 速查
ocrGetText适合"提取文本、快速判断页面状态",其余四兄弟则覆盖完整交互闭环:
- 定位坐标:
ocrGetElementPositionByText返回包含dprPosition、originalPosition、matchedString、score、searchValue、filePath的结构化结果,其中score(如85.71)表示模糊匹配得分,多个匹配时会自动选取得分最高者。 - 等待出现:
ocrWaitForTextDisplayed内部复用ocrGetElementPositionByText,支持timeout(默认 18000ms)与自定义timeoutMsg。 - 点击文本:
ocrClickOnText支持clickDuration(默认 500ms,可用于长按)、relativePosition(基于匹配元素向上/下/左/右偏移点击)、以及整套fuzzyFindOptions。 - 输入文本:
ocrSetValue自动"点中元素 → 聚焦 → 写入值",支持submitValue(末尾追加回车)。
关于模糊匹配,四个交互命令共用的fuzzyFindOptions参数(同样适用于定位/点击/输入命令)常用项如下,ocrGetText虽然本身不做匹配,但理解它们有助于把提取结果与后续命令衔接好:
| 选项 | 默认值 | 含义 |
|---|---|---|
distance | 100 | 匹配必须与模糊位置(location)相距多近,0表示必须精确落在该位置 |
location | 0 | 期望在文本中的哪个大致位置找到模式 |
threshold | 0.6 | 匹配算法放弃的阈值;0要求完全精确,1.0匹配任何内容 |
isCaseSensitive | false | 是否区分大小写 |
minMatchCharLength | 2 | 只返回超过该长度的匹配(设为2可忽略单字符匹配) |
findAllMatches | false | 为true时即使已找到完美匹配也继续搜索到模式末尾 |
遇到"文本找不到"的排查顺序(参考 ocr-faq.md):先确认是否图像区域过大(改用haystack缩小);再检查文字与背景的对比度(调高contrast,甚至设为1);移动端输入框点击后键盘不弹出时,通常是点击时长被判成长按,可通过ocrClickOnText/ocrSetValue的clickDuration调短解决。另外,若想不跑测试就快速验证某张图片能识别出哪些文本,官方提供了 CLI 向导:安装服务后运行npx ocr-service,即可通过文件选择器或手动输入路径加载图片,并可选配置haystack与高级模式(详见 cli-wizard.md)。
7. 小结
ocrGetText是@wdio/ocr-service中最直接的"读屏幕"命令:一次调用即可把屏幕或指定区域(haystack)内所有可见文本提取为字符串,通过contrast控制预处理对比度、language切换识别语言。它特别适用于元素缺乏稳定选择器的 Web 桌面站点与移动原生应用场景。使用时牢记三点:OCR 结果存在概率性误差,断言需留容错;haystack裁剪是兼顾速度与准确率的关键实践;性能瓶颈明显时可优先使用本机安装的 Tesseract。将它与ocrGetElementPositionByText、ocrWaitForTextDisplayed、ocrClickOnText、ocrSetValue组合,即可构建一套完整的"按可见文本驱动自动化"的测试方案。
【免费下载链接】webdriverioNext-gen browser and mobile automation test framework for Node.js项目地址: https://gitcode.com/GitHub_Trending/we/webdriverio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考