断言元素是重点

时间:2015-02-23 17:12:48

标签: javascript angularjs testing protractor end-to-end

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

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

7 个答案:

答案 0 :(得分:9)

在我的回答中,我将假设activeElempageElem都是量角器元素查找器,并且指向同一个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());