这是 ChromeDriver 91 的问题,2021 年 5 月 3 日在 Chromium bug tracker 中首次报告。
我在this article 中更详细地描述了问题和可能的解决方案/解决方法。
简而言之,Chromium 团队认为 ChromeDriver 属性端点的recent change 对GetElementAttribute 命令的行为产生了负面影响,这导致WebElement.getAttribute 方法返回null 而不是实际值属性。
该问题影响使用JsonWireProtocol 的工具,例如Selenium WebDriver 3,Protractor 使用under the hood。
Chromium 团队推荐的解决方案是改用 Selenium WebDriver 4,并且有一个 ongoing effort 可以让 Protractor 也使用它(如果您在 GitHub 上,请考虑为这张票投票)。需要注意的是 Selenium WebDriver 4 deprecates a number of APIs,因此需要更新测试以避免使用这些(即browser.actions())。
Selenium WebDriver 3 兼容修复 has been proposed too,但在撰写本文时(2021 年 6 月 8 日)不可用。
如果您想在官方修复可用之前将 Chromium/ChromeDriver 91 与 Protractor 一起使用,您有以下三种选择:
使用 W3C 协议
您可以在protractor.conf.js 中显式启用对 W3C 协议的支持(而不是受影响的 JsonWireProtocol):
capabilities: {
'browserName': 'chrome',
'goog:chromeOptions': {
w3c: true,
args: [
'--headless',
]
},
}
警告:某些 API,如 browser.actions() 与 W3C 模式不兼容,启用此模式后会中断。
退回到注入 JavaScript
当getAttribute() 返回null 时,您可以更改测试以回退到通过JavaScript 检索属性值。
const attribute = await element.getAttribute(name).then(value => {
if (value !== null) {
return value;
}
return browser.executeScript(`
function getAttribute(webElement, attributeName) {
return webElement.getAttribute(attributeName);
})
`, element, name);
})
这类似于Serenity/JS acceptance testing framework 的做法under the hood。
在 Serenity/JS 中使用量角器
我已经在Serenity/JS 中实现了上述后备策略(查看GitHub),所以如果您使用带有Serenity/JS 的Protractor,您需要将任何@serenity-js/* 模块更新到版本2.29.0它只适用于 Chromium 91。
例如,如果您有这样的小部件:
<input type="checkbox" id="confirm" />
使用 Serenity/JS 和 Protractor,您可以检索任何小部件的属性,如下所示:
import { actorCalled } from '@serenity-js/core';
import { Ensure, equals } from '@serenity-js/assertions';
import { Target } from '@serenity-js/protractor';
import { by } from 'protractor';
const confirmation = Target.the('confirmation checkbox')
.located(by.id('confirm'));
// in the test:
actorCalled('Alice').attemptsTo(
Ensure.that(
Attribute.of(confirmation).called('checked'),
equals('true')
),
);
要开始使用 Serenity/JS 和量角器:
完全披露,我是Serenity/JS的作者