如何使用Nightwatch滚动到元素?

17

我正在使用Nightwatch对我的应用进行端到端测试。其中一个测试失败了,因为它无法滚动到正在测试的元素。我怀疑是需要滚动还是有其他方法可以解决?这是我正在测试的元素:

 return this.waitForElementVisible('#myElement', 4000) //wait for it to be visible
       .assert.visible('#myElement')
       .click('#myElement')

该元素位于页面顶部,但测试运行器已向下滚动了一些页面,并且在截图中不可见。如有需要,我如何将页面滚动到该元素?或者:我如何测试此元素?

7个回答

13

Nightwatch中有一个本地方法可以将元素滚动到视图中。总的来说,应该始终从nightwatch/selenium中滚动元素以获得更好的效果。但是如果您想自己手动实现,可以使用getLocationInView()

return this.getLocationInView('#myElement')
   .assert.visible('#myElement')
   .click('#myElement')

Nightwatch也支持直接通过Webdriver协议使用moveTo()来实现此操作,而不需要任何抽象。在这种情况下,它看起来更像是:

const self = this;
return this.api.element('#myElement', (res) => {
  self.api.moveTo(res.value.ELEMENT, 0, 0, () => {
    self.assert.visible('#myElement');
    self.click('#myElement');
  })
});

但在您的情况下有助于改变配置中Selenium元素滚动行为,例如:

firefox: {
  desiredCapabilities: {
    browserName: 'firefox',
    javascriptEnabled: true,
    acceptSslCerts: true,
    elementScrollBehavior: 1
  }
}

默认值为0 -> 元素滚动到页面顶部

elementScrollBavior为1 -> 元素滚动到页面底部


1
提及一下,本地方法是http://nightwatchjs.org/api/moveTo.html会很有帮助。 - Mike Davlantes
@MikeDavlantes 感谢您的建议。我尝试扩展我的描述,希望我还记得如何在 nightwatch 中正确使用它 :'D - TheBay0r

8
你可以使用 moveToElement() 函数。
只需像这样简单地使用它。
browser.
.moveToElement(#myElement, 10, 10)
.waitForElementVisible(#myElement, 500)

如果元素在屏幕下方,它会“滚动”屏幕以将该元素移动到可视区域吗? - Snekse
moveToElement在Firefox中不起作用。这是一个已知的问题。 - John Kretschmann

7

请记住:

.execute()会将一段JavaScript代码注入到当前选中框架的上下文中执行。执行的脚本被认为是同步的,评估结果将返回给客户端。

以及

Window.scrollTo()可以滚动文档到特定的坐标。

你的测试代码将如下所示:

module.exports = {
    'your-test': function (browser) {
        browser
            .url("http://example.com")
            .waitForElementPresent('body', 2000, "Be sure that the page is loaded")
            .execute('scrollTo(x, y)')
            .yourFirstAssertionHere()
            .yourSecondAssertionHere()
            ...
            .yourLastAssertionHere()
            .end()
    }
};
  • 如果您知道具有id myElement 的元素位于页面顶部,则可以将xy更改为0(只是为了确保滚动到页面顶部)。

  • 如果您需要获取xy的确切值,可以使用:getLocationInView(),如下所示:

    module.exports = { 'your-test': function (browser) { browser .url("http://example.com") .waitForElementPresent('body', 2000, "确保页面已加载") .getLocationInView("#myElement", function(result) { // x值将为:result.value.x // y值将为:result.value.y }); } }

    .getLocationInView():确定元素在视图中滚动后在屏幕上的位置... 返回页面中该元素的X和Y坐标。

希望这能对您有所帮助。


3
您可以使用以下JavaScript代码:execute document.querySelector({{ACTUAL_SELECTOR}}).scrollIntoView();来实现此功能。

scrollIntoView() 在所有主要浏览器中都兼容。https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollIntoView#浏览器兼容性 - lasec0203

1

另外,我使用了一个作为页面对象命令的示例(be_expand),其中我的选择器已经在元素中使用了xpath(@be_click):

    be_expand() {
        this.api.execute(function(xpath) {
            function getElementByXpath(path) {
                return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
            }
            var res = getElementByXpath(xpath);
            res.scrollIntoView(true);
        }, [this.elements.be_click.selector]);
        this.assert.visible('@be_click');
        this.click('@be_click');
        return this;
    }

0
browser.execute('scrollTo(0,3000)');

0
browser.execute('window.scrollTo(0, 1080)')

这个代码对我来说可以滚动到页面底部。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接