CloakBrowser 开发踩坑笔记

CloakBrowser 开发踩坑笔记

CloakBrowser 可以在启动浏览器时开启:

csharp 复制代码
const context = await launchPersistentContext({
  humanize: true,
  userDataDir,
})

开启后,点击由 Humanize 层处理。Playwright 中一些合法的 Locator 写法,在 Humanize 模式下不能直接使用。

下面记录开发中出现过的错误代码、报错和修改方式。


1. 对列表元素使用 nth() 点击,触发 ElementNotReceivingEventsError

错误代码

csharp 复制代码
const cards = page.locator('.job-card-box')

await cards.nth(5).click()

错误堆栈

ini 复制代码
ElementNotReceivingEventsError

selector:
.job-card-box >> nth=5

pointer-events check failed
element is not receiving pointer events

Humanize 点击时拿到的是 .job-card-box >> nth=5,同时 .job-card-box 只是卡片容器,真正接收鼠标事件的是卡片里的可点击节点。

修改后的代码

csharp 复制代码
const target = page.locator(
  '.job-card-box:nth-child(6) .job-info',
)

await target.waitFor({
  state: 'visible',
})

await target.scrollIntoViewIfNeeded()

await target.click()

把 Playwright 的 >> nth=5 改成浏览器原生 CSS,并把点击目标从卡片容器改成真正接收点击的 .job-info


2. 保存动态页面的 DOM 节点后再点击,触发 ElementNotAttachedError

错误代码

scss 复制代码
const card = await page
  .locator('.job-card-box')
  .nth(0)
  .elementHandle()

await loadJobDetail()

await card?.click()

错误堆栈

arduino 复制代码
ElementNotAttachedError

Element is not attached to the DOM
while performing humanized click

职位列表刷新后,React 删除了原来的 DOM 节点,又创建了外观相同的新节点,旧的 ElementHandle 仍然指向已经移除的节点。

修改后的代码

scss 复制代码
const selector =
  '.job-card-box:nth-child(1) .job-info'

await page
  .locator(selector)
  .waitFor({
    state: 'visible',
  })

await page
  .locator(selector)
  .click()

点击前重新执行 Locator 查询,让 Playwright 获取当前 DOM 中的节点,而不是继续使用已经失效的 ElementHandle


3. 使用 .filter({ hasText }) 后继续点击,Humanize 无法处理 Locator 过滤链

错误代码

python 复制代码
await page
  .locator('.expect-item')
  .filter({
    hasText: 'Android(北京)',
  })
  .click()

错误堆栈

css 复制代码
Error: unsupported locator operation in humanized mode

locator:
locator('.expect-item').filter({ hasText: 'Android(北京)' })

.filter() 属于 Playwright Locator 的过滤逻辑,不是浏览器原生选择器,Humanize 层不能完整处理这条 Locator 链。

修改后的代码

csharp 复制代码
await page
  .getByText('Android(北京)')
  .click()

如果页面提供稳定属性:

csharp 复制代码
await page
  .locator(
    '.expect-item[data-id="android-beijing"]',
  )
  .click()

把 Locator 过滤运算换成文字定位或原生 CSS 属性选择器,让 Humanize 只处理一个明确的目标。


4. 在 Humanize 中使用 :visible,选择器解析失败

错误代码

csharp 复制代码
await page
  .locator('.op-btn-chat:visible')
  .click()

错误堆栈

makefile 复制代码
Error: unsupported selector

selector:
.op-btn-chat:visible

:visible 是 Playwright 扩展的选择器语法,不属于浏览器标准 CSS,Humanize 不能按 Playwright 的 Selector Engine 解析它。

修改后的代码

csharp 复制代码
const button =
  page.locator('.op-btn-chat')

await button.waitFor({
  state: 'visible',
})

await button.click()

选择器只保留原生 CSS,可见性判断改由 waitFor({ state: 'visible' }) 完成。


5. 使用 :nth-match() 定位列表元素,Humanize 无法解析选择器

错误代码

csharp 复制代码
await page
  .locator(
    ':nth-match(.job-card-box, 3)',
  )
  .click()

错误堆栈

ruby 复制代码
Error: unsupported selector

selector:
:nth-match(.job-card-box, 3)

:nth-match() 是 Playwright 提供的扩展伪类,浏览器原生 CSS 不认识这段语法。

修改后的代码

csharp 复制代码
await page
  .locator(
    '.job-card-box:nth-child(3) .job-info',
  )
  .click()

把 Playwright 扩展伪类换成浏览器能够直接解析的 :nth-child()


6. 使用 >> 拼接选择器,Humanize 无法处理 Playwright Selector Engine 语法

错误代码

csharp 复制代码
await page
  .locator(
    '.job-card-box >> .job-info',
  )
  .click()

错误堆栈

makefile 复制代码
Error: unsupported selector syntax

selector:
.job-card-box >> .job-info

>> 是 Playwright 的选择器组合语法,不是 CSS 后代选择器,Humanize 不能直接把它交给浏览器解析。

修改后的代码

csharp 复制代码
await page
  .locator(
    '.job-card-box .job-info',
  )
  .click()

用标准 CSS 的空格后代选择器替代 Playwright 的 >> 语法。


7. nth() 后继续调用 .locator(),Humanize 收到多层 Locator 链

错误代码

scss 复制代码
await page
  .locator('.job-card-box')
  .nth(index)
  .locator('.job-info')
  .click()

错误堆栈

css 复制代码
Error: failed to resolve humanized click target

locator:
locator('.job-card-box')
  .nth(index)
  .locator('.job-info')

目标经过 locator → nth → locator 多次计算,Humanize 需要重新解析 Playwright 的 Locator 链,目标解析在点击阶段失败。

修改后的代码

javascript 复制代码
const selector =
  `.job-card-box:nth-child(${index + 1}) .job-info`

await page
  .locator(selector)
  .click()

把多层 Locator 运算压成一个完整 CSS,让点击阶段只处理一个选择器。


8. 元素位于滚动区域边缘,Humanize 移动鼠标后目标位置发生变化

错误代码

csharp 复制代码
await page
  .locator('.job-card-box:nth-child(8) .job-info')
  .click()

错误堆栈

arduino 复制代码
Error: click target moved during humanized interaction

target position changed before pointer down

Humanize 在移动鼠标的过程中触发页面滚动,目标元素的位置随滚动变化,最终点击坐标和元素位置不再重合。

修改后的代码

csharp 复制代码
const target = page.locator(
  '.job-card-box:nth-child(8) .job-info',
)

await target.waitFor({
  state: 'visible',
})

await target.scrollIntoViewIfNeeded()

await target.click()

先把目标滚进视口,再开始 Humanize 点击,减少鼠标移动期间的页面位置变化。


9. 按钮被浮层覆盖时直接点击,鼠标事件落到遮罩层

错误代码

csharp 复制代码
await page
  .locator('.op-btn-chat')
  .click()

页面此时仍有:

css 复制代码
<div class="loading-mask"></div>

错误堆栈

ini 复制代码
Error: pointer intercepted

<div class="loading-mask">
intercepts pointer events

按钮已经出现在 DOM 中,但遮罩层仍盖在按钮上,Humanize 产生的真实鼠标事件被遮罩层接收。

修改后的代码

csharp 复制代码
await page
  .locator('.loading-mask')
  .waitFor({
    state: 'hidden',
  })

await page
  .locator('.op-btn-chat')
  .click()

等待遮罩层退出点击区域后再执行鼠标操作,让按钮成为当前坐标下真正接收事件的元素。


10. frameLocator() 中直接执行 Humanize 点击,目标无法跨 Frame 解析

错误代码

csharp 复制代码
await page
  .frameLocator('#login-frame')
  .locator('.submit')
  .click()

错误堆栈

makefile 复制代码
Error: humanized click target could not be resolved

FrameLocator:
#login-frame

Locator:
.submit

FrameLocator 属于 Playwright 的跨 Frame 定位抽象,Humanize 点击需要处理页面、iframe 和内部节点三层目标。

修改后的代码

javascript 复制代码
const frame = page
  .frames()
  .find(item =>
    item.url().includes('login'),
  )

if (!frame) {
  throw new Error('frame not found')
}

await frame
  .locator('.submit')
  .click()

先取得实际的 Frame 对象,再在 Frame 内执行普通 Locator,去掉 FrameLocator 这一层定位包装。

相关推荐
Made in Haven71222 分钟前
HTML课程笔记补2
前端·笔记·html
Cry丶31 分钟前
Vue 3 业务管理页面实战:组件拆分、父子通信与弹窗复用
前端·javascript·vue.js·父子通信·组件拆分·弹窗复用
雪芽蓝域zzs41 分钟前
Vue前端配置路由通配捕获 404
前端·javascript·vue.js
计算机魔术师42 分钟前
Anthropic 发布电商 Agent 架构与生产实践指南,并开源 commerce-agents 参考实现
前端
IMPYLH1 小时前
HTML 的 <ol> 元素
前端·html
IMPYLH1 小时前
HTML 的 <object> 元素
前端·html
DevOpenClub1 小时前
PDF 多格式解析如何避免混用输出:TEXT、HTML、XML 与 TAG 数据契约
xml·前端·数据库·pdf·html
用户252632753471 小时前
请问同一台服务器能同时部署前后端项目并支持https吗?
前端
Sincerelyplz1 小时前
【Pipecat】基于Pipecat的voice agent实践
前端·后端·agent