断言一个元素是有焦点的
Asserting an element is focused
根据 How do I assert an element is focused? 线程,您可以通过切换到 activeElement()
来检查元素是否获得焦点,并断言这与您期望获得焦点的元素相同:
expect(page.element.getAttribute('id')).toEqual(browser.driver.switchTo().activeElement().getAttribute('id'));
在我的例子中,当前获得焦点的 元素没有 id
属性 。
除了检查 id
我应该怎么做?
奖金问题:另外,正如您从我尝试解决它所看到的那样,看起来我不能 expect/assert 将元素(或网络元素)作为一个完整的对象。为什么?
我试过:
expect(page.element).toEqual(browser.driver.switchTo().activeElement());
但是失败并出现一个我什至无法理解的错误 - 有一个巨大的回溯(在控制台中滚动大约需要 10 分钟),但内部没有用户友好的错误。
我也尝试过使用 getWebElement()
:
expect(page.element.getWebElement()).toEqual(browser.driver.switchTo().activeElement());
但这导致了以下错误:
Error: expect called with WebElement argument, expected a Promise. Did
you mean to use .getText()?
使用最新的量角器开发版本。
您需要想出一种方法来告诉 Protractor/webdriver 如何在页面上找到您的元素。 Protractor 使用 JavaScript 来查找元素,因此可以使用任何可用于检查 DOM 的工具。 Protractor 和 webdriver 将这些 API 包装在各种 by
风格中:
http://angular.github.io/protractor/#/api?view=ProtractorBy
除了基本风味外,量角器还添加了 Angular 感知风味(因此您可以通过 Angular 绑定等进行搜索)。
如果您的元素没有任何显着特征,那么可能值得添加一些东西以使其更易于测试。或者,(虽然这经常不受欢迎,因为它太脆弱了),您可以使用 xpath。参见 https://github.com/angular/protractor/blob/master/docs/locators.md
奇怪的是它只期待一个 promise 而不能处理 webdriver 元素...我有和你一样的巨大堆栈跟踪。
无论如何,你会接受这种解决方案吗:发送一个 "dumb" 承诺,并附上一个很好的评论来证明你为什么必须这样做。我承认,它更像是一种解决方法,而不是一种语义解决方案。
expect(page.element.getInnerHtml())
.toEqual(browser.driver.switchTo().activeElement().getInnerHtml());
它对我有用 ;)
编辑:奖励答案
您不能使用 WebElement 调用 expect 的原因来自 Webdriver Control Flow Principle (I'm sure you already know about) and this line in jasminewd,由 Protractor 开发和使用的 jasmine 到 Webdriver 的适配器 ;)
您可以简单地检查元素的文本(或其他任何内容):
var currentElement = browser.switchTo().activeElement();
expect(currentElement.getText()).toEqual(page.element.getText());
在我的回答中,我假设 activeElem
和 pageElem
都是量角器元素查找器,并且指向同一个 Web 元素。
先回答你为什么
expect(activeElem).toEqual(pageElem);
进入无限循环,这是因为量角器修补了 jasmine 的 expect
以在断言之前解决承诺,因此 expect(activeElem.getText()).toEqual('text');
之类的事情无需执行
activeElem.getText().then(function(text) {
expect(text).toEqual('text');
})
你可能会说,为什么不只 resolve 一次 promise 呢?但是还有嵌套的承诺。
所以现在您可能认为这是一个问题,但事实并非如此,因为您永远不会在实际用例中比较两个 elementFinder。 Jasmine 的 toEqual 进行引用检查,而不是深度比较,因此 expect(activeElem).toEqual(pageElem)
与简单的引用比较相同:(activeElem === pageElem).toToTruthy()
,这样做真的没有意义。 (注意 element(by.css('html')) === element(by.css('html'))
是错误的,因为它不是同一个引用。)
所以,要回答这个线程的真正问题:如何查看两个 elementFinder 是否具有相同的底层 webelements:
expect(activeElem.getId()).toEqual(pageElem.getId());
对于未来的读者,我创建了一个 custom matcher 来断言元素是否为 active/focused:
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
。
根据 How do I assert an element is focused? 线程,您可以通过切换到 activeElement()
来检查元素是否获得焦点,并断言这与您期望获得焦点的元素相同:
expect(page.element.getAttribute('id')).toEqual(browser.driver.switchTo().activeElement().getAttribute('id'));
在我的例子中,当前获得焦点的 元素没有 id
属性 。
除了检查 id
我应该怎么做?
奖金问题:另外,正如您从我尝试解决它所看到的那样,看起来我不能 expect/assert 将元素(或网络元素)作为一个完整的对象。为什么?
我试过:
expect(page.element).toEqual(browser.driver.switchTo().activeElement());
但是失败并出现一个我什至无法理解的错误 - 有一个巨大的回溯(在控制台中滚动大约需要 10 分钟),但内部没有用户友好的错误。
我也尝试过使用 getWebElement()
:
expect(page.element.getWebElement()).toEqual(browser.driver.switchTo().activeElement());
但这导致了以下错误:
Error: expect called with WebElement argument, expected a Promise. Did you mean to use .getText()?
使用最新的量角器开发版本。
您需要想出一种方法来告诉 Protractor/webdriver 如何在页面上找到您的元素。 Protractor 使用 JavaScript 来查找元素,因此可以使用任何可用于检查 DOM 的工具。 Protractor 和 webdriver 将这些 API 包装在各种 by
风格中:
http://angular.github.io/protractor/#/api?view=ProtractorBy
除了基本风味外,量角器还添加了 Angular 感知风味(因此您可以通过 Angular 绑定等进行搜索)。
如果您的元素没有任何显着特征,那么可能值得添加一些东西以使其更易于测试。或者,(虽然这经常不受欢迎,因为它太脆弱了),您可以使用 xpath。参见 https://github.com/angular/protractor/blob/master/docs/locators.md
奇怪的是它只期待一个 promise 而不能处理 webdriver 元素...我有和你一样的巨大堆栈跟踪。
无论如何,你会接受这种解决方案吗:发送一个 "dumb" 承诺,并附上一个很好的评论来证明你为什么必须这样做。我承认,它更像是一种解决方法,而不是一种语义解决方案。
expect(page.element.getInnerHtml())
.toEqual(browser.driver.switchTo().activeElement().getInnerHtml());
它对我有用 ;)
编辑:奖励答案
您不能使用 WebElement 调用 expect 的原因来自 Webdriver Control Flow Principle (I'm sure you already know about) and this line in jasminewd,由 Protractor 开发和使用的 jasmine 到 Webdriver 的适配器 ;)
您可以简单地检查元素的文本(或其他任何内容):
var currentElement = browser.switchTo().activeElement();
expect(currentElement.getText()).toEqual(page.element.getText());
在我的回答中,我假设 activeElem
和 pageElem
都是量角器元素查找器,并且指向同一个 Web 元素。
先回答你为什么
expect(activeElem).toEqual(pageElem);
进入无限循环,这是因为量角器修补了 jasmine 的 expect
以在断言之前解决承诺,因此 expect(activeElem.getText()).toEqual('text');
之类的事情无需执行
activeElem.getText().then(function(text) {
expect(text).toEqual('text');
})
你可能会说,为什么不只 resolve 一次 promise 呢?但是还有嵌套的承诺。
所以现在您可能认为这是一个问题,但事实并非如此,因为您永远不会在实际用例中比较两个 elementFinder。 Jasmine 的 toEqual 进行引用检查,而不是深度比较,因此 expect(activeElem).toEqual(pageElem)
与简单的引用比较相同:(activeElem === pageElem).toToTruthy()
,这样做真的没有意义。 (注意 element(by.css('html')) === element(by.css('html'))
是错误的,因为它不是同一个引用。)
所以,要回答这个线程的真正问题:如何查看两个 elementFinder 是否具有相同的底层 webelements:
expect(activeElem.getId()).toEqual(pageElem.getId());
对于未来的读者,我创建了一个 custom matcher 来断言元素是否为 active/focused:
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
。