使用 Puppeteer 时等待文本出现
Posted
技术标签:
【中文标题】使用 Puppeteer 时等待文本出现【英文标题】:Wait for text to appear when using Puppeteer 【发布时间】:2018-03-31 05:17:18 【问题描述】:我想知道是否有与 Selenium 类似的方式来等待特定元素出现文本。我已经尝试过这样的事情,但它似乎并没有等待:
await page.waitForSelector('.count', visible: true);
【问题讨论】:
作为参考,将visible: true
与非特定选择器一起使用时存在一个未解决的问题 - 即可能匹配多个元素的选择器:它只检查第一个匹配元素的可见性:github.com/GoogleChrome/puppeteer/issues/4356跨度>
【参考方案1】:
您可以使用waitForFunction
。见https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitforfunctionpagefunction-options-args
包括@elena 的解决方案以确保答案的完整性:
await page.waitForFunction('document.querySelector(".count").innerText.length == 7');
【讨论】:
我用过await page.waitForFunction('document.querySelector(".count").innerText.length == 7');
等着在屏幕上的任何地方看到文字怎么办?
您可以使用page.waitFor
并传递一个从DOM 中查找文本内容的函数。 Docs here【参考方案2】:
除了nilobarp的答案中提出的方法之外,还有两种方法可以做到这一点:
page.waitForSelector
使用伪选择器:empty
可以找到不包含子节点或文本的元素。结合:not
选择器,我们可以使用page.waitForSelector
来查询非空的选择器:
await page.waitForSelector('.count:not(:empty)');
XPath 表达式
如果您不仅想确保元素不为空,还想检查它包含的文本,您可以使用 XPath 表达式,使用 page.waitForXPath
:
await page.waitForXPath("//*[@class='count' and contains(., 'Expected text')]");
只有在页面上有一个元素具有class="count"
属性并包含文本Expected text
时,此行才会解析。
【讨论】:
【参考方案3】:使用waitForFunction()
可以做到的最佳解决方案(避免奇怪的函数作为字符串):
const selector = '.count';
await page.waitForFunction(
selector => document.querySelector(selector).value.length > 0,
,
selector
);
取决于文本的类型,将value
替换为innerText
。
查看puppeteer API
【讨论】:
【参考方案4】:page.waitFor()
您也可以简单地使用page.waitFor()
传递一个函数或等待等待的 CSS 选择器。
等待函数
如果元素是input
字段,我们可以在检查value
是否存在之前检查.count
元素是否存在以避免潜在错误:
await page.waitFor(() =>
const count = document.querySelector('.count');
return count && count.value.length;
);
如果元素不是input
字段,我们可以在检查innerText
是否存在之前检查.count
元素是否存在以避免潜在错误:
await page.waitFor(() =>
const count = document.querySelector('.count');
return count && count.innerText.length;
);
等待 CSS 选择器
如果元素是包含placeholder
的input
字段,并且您想检查value
当前是否存在,则可以使用:not(:placeholder-shown)
:
await page.waitFor('.count:not(:placeholder-shown)');
如果元素是一个不包含placeholder
的input
字段,并且您想检查value
属性是否包含字符串,您可以使用:not([value=""])
:
await page.waitFor('.count:not([value=""])');
如果元素不是没有任何子元素节点的input
字段,我们可以使用:not(:empty)
等待元素包含文本:
await page.waitFor('.count:not(:empty)');
page.waitForXPath()
等待 XPath
否则,您可以使用 page.waitForXPath()
等待 XPath 表达式在页面上定位元素。
即使元素上存在除count
之外的其他类,以下 XPath 表达式也将起作用。换句话说,它将像.count
一样工作,而不是[class="count"]
。
如果元素是input
字段,可以使用下面的表达式等待value
属性包含字符串:
await page.waitForXPath('//*[contains(concat(" ", normalize-space(@class), " "), " test ") and string-length(@value) > 0]')
如果元素不是 input
字段,则可以使用以下表达式等待元素包含文本:
await page.waitForXPath('//*[contains(concat(" ", normalize-space(@class), " "), " count ") and string-length(text()) > 0]');
【讨论】:
【参考方案5】:await page.waitFor((name) =>
return document.querySelector('.top .name')?.textContent == name;
, timeout: 60000, test_client2.name);
【讨论】:
【参考方案6】:简单而且效果很好。
await page.waitForXPath('//*[contains(text(), "要检查的文本")]');
【讨论】:
以上是关于使用 Puppeteer 时等待文本出现的主要内容,如果未能解决你的问题,请参考以下文章
是什么原因让华为测试工程师都说puppeteer比selenium好呢?