根据How do I assert an element is focused?线程,您可以通过切换到activeElement()
来检查元素是否已被聚焦,并断言这与您期望获得焦点的元素相同:
expect(page.element.getAttribute('id')).toEqual(browser.driver.switchTo().activeElement().getAttribute('id'));
在我的情况下,当前关注的元素没有id
属性。
我应该怎么做而不是检查id
?
奖金问题:另外,正如我从试图解决它看到的那样,看起来我不能指望/断言一个元素(或web元素)作为一个完整的对象。为什么呢?
我试过了:
expect(page.element).toEqual(browser.driver.switchTo().activeElement());
但是失败的是我甚至无法理解的错误 - 有一个巨大的追溯(在控制台中滚动约10分钟),但内部没有用户友好的错误。
我还试图使用getWebElement()
:
expect(page.element.getWebElement()).toEqual(browser.driver.switchTo().activeElement());
但是这导致了以下错误:
错误:期望使用WebElement参数调用,期望是Promise。难道 你的意思是使用.getText()?
使用最新的量角器开发版本。
答案 0 :(得分:9)
在我的回答中,我将假设activeElem
和pageElem
都是量角器元素查找器,并且指向同一个web元素。
首先回答你关于原因的问题
expect(activeElem).toEqual(pageElem);
进入一个无限循环,这是因为量角器修补了jasmine的expect
以在断言之前解决了这个承诺,所以像expect(activeElem.getText()).toEqual('text');
之类的东西可以在不必执行的情况下工作
activeElem.getText().then(function(text) {
expect(text).toEqual('text');
})
你可以说,为什么不一次解决这个承诺呢?但后来有嵌套的承诺。
所以现在你可能会认为这是一个问题,但实际上并不是因为你永远不会在一个真实的用例中比较两个elementFinder。 Jasmine的toEqual执行引用检查,而不是深度比较,因此expect(activeElem).toEqual(pageElem)
与简单的引用比较(activeElem === pageElem).toToTruthy()
相同,并且实际上没有必要这样做。 (注意element(by.css('html')) === element(by.css('html'))
为false,因为它不是相同的引用。)
所以,回答这个线程的真正问题:如何看看两个elementFinder是否具有相同的底层元素:
expect(activeElem.getId()).toEqual(pageElem.getId());
答案 1 :(得分:3)
奇怪的是它只期待一个承诺并且无法处理一个webdriver元素......我和你有着相同的巨大堆栈跟踪。
无论如何,你会接受这种解决方案:发送一个"哑巴"承诺一个很好的评论来证明为什么你必须这样做。它比我承认的语义解决方案更像是一种解决方法。
expect(page.element.getInnerHtml())
.toEqual(browser.driver.switchTo().activeElement().getInnerHtml());
它为我工作;)
编辑:奖励回答
您无法使用WebElement调用expect的原因来自Webdriver Control Flow Principle(我确定您已经知道)和this line in jasminewd,jasemine to Webdriver的适配器已开发并由Protractor使用;)
答案 2 :(得分:1)
对于未来的读者,我创建了一个custom matcher来断言元素是否处于活动/聚焦状态:
beforeEach(function() {
jasmine.addMatchers({
toBeActive: function() {
return {
compare: function(elm) {
return {
pass: elm.getId().then(function (activeElementID) {
return browser.driver.switchTo().activeElement().getId().then(function (currentElementID) {
return jasmine.matchersUtil.equals(currentElementID, activeElementID);
});
})
};
}
};
}
});
});
用法:
expect(element(by.css("#myid")).toBeActive();
答案 3 :(得分:1)
如何使用CSS选择器和:focus
expect(element.all(by.css('#myid:focus')).count()).toBe(1);
答案 4 :(得分:1)
我用量角器解决了它:
ElementFinder.prototype.equals
const activeElement = await browser.driver.switchTo().activeElement();
const potentialyFocusedElement = await component.$('your-locator');
const isFocused = await potentialyFocusedElement.equals(activeElement);
我不确定equals
究竟是如何工作的,如果它做了深度比较,或者它以某种方式比较实例。但它确实有效。
请注意,您无法拨打activeElement.equals(...)
,因为它不是ElementFinder,而是WebElement
。
答案 5 :(得分:0)
您需要想出一种方法来告诉Protractor / webdriver如何在页面上找到您的元素。量角器使用JavaScript来查找元素,因此可以使用任何可用于检查DOM的工具。量角器和webdriver以各种by
风格包装这些API:
http://angular.github.io/protractor/#/api?view=ProtractorBy
除了基本风格之外,Protractor还添加了Angular-aware风格(因此您可以通过Angular绑定等进行搜索)。
如果您的元素没有任何区别特征,那么可能值得添加一些内容以使其更容易测试。或者,(虽然这常常令人不悦,因为它太脆弱了),你可以使用xpath。见https://github.com/angular/protractor/blob/master/docs/locators.md
答案 6 :(得分:0)
您可以简单地检查元素的文本(或其他任何内容):
var currentElement = browser.switchTo().activeElement();
expect(currentElement.getText()).toEqual(page.element.getText());