量角器 - Chromium 89 - w3c 合规性和 browser.actions

Protractor - Chromium 89 - w3c compliance and browser.actions

我有一个测试需要点击复选框。 如果我只是做 $('.my-cb').click() 我得到 Element <input type="checkbox" > is not clickable at point (...). Other element would receive the click: <div>...</div>

这就是我这样做的原因

browser.actions().mouseMove($('.my-cb')).click().perform()

因为使用 browser.actions,我需要禁用 chrome 的 w3c 合规性,因为它在 75.X 版本开始出现故障。此时已经很好用了。

config.capabilities = {
  browserName: 'chrome',
  chromeOptions: {
    args: ['--disable-web-security', '--ignore-certificate-errors'],
    w3c: false,
  },
  ...
}

现在我更新了 Chrome 75 -> 89。 虽然这适用于我的本地 Windows 环境,但它在 linux CI 上失败了 Failed: unknown command: Cannot call non W3C standard command while in W3C mode

所以实际上我需要的是禁用 w3c 合规性(因为上面的配置停止工作)或替换 browser.actions() 调用。 我一直在寻找其他方法来禁用 Chrome 89 中的 w3c 合规性,但没有找到任何有用的东西。只有其他人遇到同样的问题。

"@angular/core": "^10.2.4",
"protractor": "~7.0.0",

chromedriver_89.0.4389.23

------------编辑---------

  1. 事实证明,我的 selenium 服务器已升级,现在传递 chrome 配置的正确方法是使用 'goog:chromeOptions' 而不是 chromeOptions。这样我就可以再次禁用 w3c 合规性。
    'goog:chromeOptions': {
      args: ['--disable-web-security', '--ignore-certificate-errors'],
      w3c: false,
    },
  1. 与此同时,将@Sergey Pleshakov 的回答与 等其他答案相结合,我从 browser.actions 用法切换到普通 browser.executeScript 用法时取得了不错的效果。 @Sergey Pleshakov 提出的 jsClick 对于复选框效果很好,但对于下拉菜单我需要做更多。 由于我的测试是点击一个带有多个选项卡的大表单,因此有必要等待选项向下滚动和向上滚动。最后我完成了这样的代码:
export const jsClick = $element =>
  browser.executeScript('return arguments[0].click();', $element.getWebElement())

export const jsMove = async $element => {
  await browser.executeScript(
    `if(document.createEvent) {
      var evObj = document.createEvent('MouseEvents');
      evObj.initEvent('mouseover', true, false);
      arguments[0].dispatchEvent(evObj); 
    } else if (document.createEventObject) { 
      arguments[0].fireEvent('onmouseover'); 
    }`,
    $element.getWebElement()
  )
  return browser.sleep(1000)
}

export const scrollIntoView = function(el) {
  return browser.executeScript(function(el) {
    el.scrollIntoView()
  }, el.getWebElement())
}
await scrollIntoView(input)
await jsMove(input)
await browser.wait(until.elementToBeClickable(input), 5000, WAITING_TOO_LONG_FOR_ELEMENT)
await input.click()

const optionByCss = by.cssContainingText('mat-option .mat-option-text', value);
await browser.wait(until.visibilityOf(element(optionByCss)), 5000, WAITING_TOO_LONG_FOR_ELEMENT)
const option = await element(optionByCss)
await jsMove(option)
await option.click()
await browser.wait(until.invisibilityOf(element(optionByCss)), 5000, WAITING_TOO_LONG_FOR_ELEMENT)

然而,在 Chrome 中使用 browser.actions().mouseMove($('.cls')).click().perform() 时,这样做过于复杂化是非常可悲的。我真的不明白为什么这个 API 没有移植到其他浏览器。

非常感谢您抽出宝贵时间。

你的问题是因为在你的元素之上有一个包装元素。它甚至可以是隐形的。但是量角器不能点击它。您可以做的是顶部声明 js 单击(在控制台中注入脚本)。然后直接点击任何元素。 jsClick 不关心您正在单击的元素的交互性和可见性

    let jsClick = ($element) => browser.executeScript(
        "arguments[0].click();",
        $element.getWebElement()
    );

    let $option = $("option[value='395']");

    await jsClick($option);