使用 playwright 检查元素类是否包含字符串

Oct*_*ane 8 javascript dom playwright

我正在尝试获取第 18 天的元素,并检查它是否已在其类中禁用。

<div class="react-datepicker__day react-datepicker__day--tue" aria-label="day-16" role="option">16</div>
<div class="react-datepicker__day react-datepicker__day--wed react-datepicker__day--today" aria-label="day-17" role="option">17</div>
<div class="react-datepicker__day react-datepicker__day--thu react-datepicker__day--disabled" aria-label="day-18" role="option">18</div>
Run Code Online (Sandbox Code Playgroud)

这是我的代码,假设

this.xpath = 'xpath=.//*[contains(@class, "react-datepicker__day") and not (contains(@class, "outside-month")) and ./text()="18"]'
Run Code Online (Sandbox Code Playgroud)
  async isDateAvailable () {
    const dayElt = await this.page.$(this.xpath)
    console.log(dayElt.classList.contains('disabled'))) \\this should return true
Run Code Online (Sandbox Code Playgroud)

我似乎无法让它发挥作用。错误提示 TypeError: 无法读取未定义的属性“包含”。你能帮我指出我在这里做错了什么吗?

Joy*_*ful 16

看起来你可以写

await expect(page.locator('.selector-name')).toHaveClass(/target-class/)
Run Code Online (Sandbox Code Playgroud)

/target-class/- 斜杠是必需的,因为它是正则表达式

为了通过一个调用检查几个类,我使用这个助手(这是因为 api 方式对我不起作用https://playwright.dev/docs/test-assertions#locator-assertions-to-have-class):

async function expectHaveClasses(locator: Locator, className: string) {
    // get current classes of element
    const attrClass = await locator.getAttribute('class')
    const elementClasses: string[] = attrClass ? attrClass.split(' ') : []
    const targetClasses: string[] = className.split(' ')
    // Every class should be present in the current class list
    const isValid = targetClasses.every(classItem => elementClasses.includes(classItem))

    expect(isValid).toBeTruthy()
}
Run Code Online (Sandbox Code Playgroud)

className可以编写几个用空格分隔的类:

const result = await expectHaveClasses(page.locator('.item'), 'class-a class-b')
Run Code Online (Sandbox Code Playgroud)


Max*_*itt 6

您必须在浏览器内对其进行评估。$将返回一个 ElementHandle,它是浏览器 DOM 元素的包装器,因此您必须evaluate在其上使用 eg then 。或者简单地$eval查找元素,将其传递到在浏览器 JavaScript 引擎内执行的回调中。这意味着类似的事情会起作用:

// @ts-check
const playwright = require("playwright");

(async () => {
  const browser = await playwright.chromium.launch();
  const context = await browser.newContext();
  const page = await context.newPage();
  await page.setContent(`
      <div id="a1" class="foo"></div>
    `)
  console.log(
    await page.$eval("#a1", el => el.classList.contains("foo1"))
  )
  await browser.close();
})();
Run Code Online (Sandbox Code Playgroud)