断言一个元素是有重点的

Asserting an element is focused

本文关键字:元素 一个 断言      更新时间:2024-04-14

根据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());

但is失败了,出现了一个我甚至无法理解的错误——有一个巨大的回溯(在控制台中滚动大约需要10分钟),但里面没有用户友好的错误。

我还尝试过使用getWebElement():

expect(page.element.getWebElement()).toEqual(browser.driver.switchTo().activeElement());

但这导致了以下错误:

错误:预期使用WebElement参数调用,预期为Promise。做你的意思是用.getText()?

使用最新的量角器开发版本。

在我的回答中,我假设activeElempageElem都是量角器元素查找器,并且指向同一个web元素。

首先回答您关于为什么的问题

expect(activeElem).toEqual(pageElem);

进入一个无限循环,这是因为量角器在断言之前修补了jasmine的expect来解析promise,所以像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'))是错误的,因为它不是同一个参考。)

因此,为了回答这个线程的真正问题:如何查看两个elementFinder是否具有相同的底层web元素:

expect(activeElem.getId()).toEqual(pageElem.getId());

奇怪的是,它只期望一个promise,却无法处理webdriver元素。。。我和你一样经历了巨大的堆叠赛跑。

不管怎样,你会接受这种解决方案吗:发送一个"愚蠢"的承诺,并附上一条好的评论,来证明你为什么要这么做。我承认,这更多的是一种变通方法,而不是一种语义解决方案。

expect(page.element.getInnerHtml())
  .toEqual(browser.driver.switchTo().activeElement().getInnerHtml());

它对我有效;)

编辑:奖励答案

你不能用WebElement调用expect的原因来自于Webdriver控制流原理(我相信你已经知道了)和jasminwd中的这一行,这是Protractor开发和使用的jasmine到Webdriver的适配器;)

对于未来的读者,我创建了一个自定义匹配器来断言元素是否是活动的/聚焦的:

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();

使用CSS选择器和:focus 怎么样

expect(element.all(by.css('#myid:focus')).count()).toBe(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

您需要想出一种方法来告诉Protractor/webdriver如何在页面上找到您的元素。Protractor使用JavaScript来查找元素,因此可以使用任何可用于检查DOM的工具。Protractor和webdriver将这些API包装成各种by风格:

http://angular.github.io/protractor/#/api?view=ProtractorBy

除了基本的风格之外,Protractor还添加了感知Angular的风格(因此您可以通过Angular绑定等进行搜索)。

如果您的元素没有任何明显的特征,那么可能值得添加一些内容,使其更易于测试。或者,(尽管这通常不受欢迎,因为它太脆弱了),您可以使用xpath。看见https://github.com/angular/protractor/blob/master/docs/locators.md

您可以简单地检查元素的文本(或任何其他内容):

var currentElement = browser.switchTo().activeElement();
expect(currentElement.getText()).toEqual(page.element.getText());