首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么单击处理程序不运行在Leadfoot中?

为什么单击处理程序不运行在Leadfoot中?
EN

Stack Overflow用户
提问于 2015-10-20 14:05:31
回答 2查看 513关注 0票数 0

我试图使用实习生框架编写功能测试,该框架使用铅足库实现WebDriver API,就像我使用Selenium安装程序在远程浏览器上测试webapp一样。该应用程序已经启动并运行。我使用的功能测试如下:

代码语言:javascript
复制
define(function (require) {
var tdd = require('intern!tdd');
var assert = require('intern/chai!assert');
var url = '...';
var server = '...';

tdd.suite("Init suite",function(){
    tdd.before(function () {
      // executes before suite starts
    });

    tdd.after(function () {
      // executes after suite ends
    });

    tdd.beforeEach(function () {
      // executes before each test
    });

    tdd.afterEach(function () {
      // executes after each test
    });
    tdd.test('Checking servers', function () {
        var that = this.remote;
        return that
            .setFindTimeout(15000)
            .get(url)
            .findById('linkservers')
                .click()
                .then(function(){
                    console.log("Click resolved");
                })
            .end()
            .findDisplayedByClassName('server-name-span-text')
                .getVisibleText()
                .then(function(texts){
                    var t=0;
                    var tlen = 0;
                    if (Array.isArray(texts))
                    {
                        tlen = texts.length
                        for (t=0;t<tlen;t++)
                            console.log("server["+t+"]: "+texts[t]);
                        assert.strictEqual(texts[0],server,"server is: "+texts[0]);
                    } else {
                        assert.strictEqual(texts,server,"server is: "+texts[0]);
                    }
                })
            .end();
    });
});

});

为了开始我的测试,我使用了实习生运行程序:./node_modules/.bin/intern-runner config=tests/intern.cfg -reporters=Runner

我问题的本质是findDisplayedByClassName('server-name-span-text')找不到类名,尽管我使用的是等待元素显示的findDisplayed调用。元素没有显示,因为出于某种原因,click()调用没有正确地触发事件(猜测)。我的意思是webapp代码中的单击处理程序没有执行,因此没有创建类名为server-name-span-text的元素。我最终得到的是由于超时而导致的findDisplayedByClassName失败。

当我在本地运行这个程序时,我实际上可以观察并确认没有发生单击事件。因此,我的not应用程序中的预期更改不会发生。

实习生的日志如下:

代码语言:javascript
复制
Listening on 0.0.0.0:9000
Tunnel started
‣ Created session firefox on LINUX (2d94ea44-dea8-411a-8ee5-a3d7b749cc7b)
Click resolved
× firefox on LINUX - Init suite - Checking servers (15.588s)
NoSuchElement: An element could not be located on the page using the given search parameters.
  at <node_modules/intern/node_modules/leadfoot/lib/findDisplayed.js:37:21>
  at <node_modules/intern/node_modules/dojo/Promise.ts:393:15>
  at run  <node_modules/intern/node_modules/dojo/Promise.ts:237:7>
  at <node_modules/intern/node_modules/dojo/nextTick.ts:44:3>
  at doNTCallback0  <node.js:417:9>
  at process._tickCallback  <node.js:346:13>
  at Command.findDisplayed  <node_modules/intern/node_modules/leadfoot/Command.js:23:10>
  at Command.prototype.(anonymous function) [as findDisplayedByClassName]  <node_modules/intern/node_modules/leadfoot/lib/strategies.js:28:16>
  at Test.test  <tests/functional/loadgui.js:36:6>
  at <node_modules/intern/lib/Test.js:211:24>
  at <node_modules/intern/node_modules/dojo/Promise.ts:393:15>
  at runCallbacks  <node_modules/intern/node_modules/dojo/Promise.ts:11:11>
  at <node_modules/intern/node_modules/dojo/Promise.ts:317:4>
  at run  <node_modules/intern/node_modules/dojo/Promise.ts:237:7>
  at <node_modules/intern/node_modules/dojo/nextTick.ts:44:3>
  at doNTCallback0  <node.js:417:9>
No unit test coverage for firefox on LINUX
firefox on LINUX: 1/1 tests failed


TOTAL: tested 1 platforms, 1/1 tests failed

selenium节点的日志没有显示问题,至少在信息级别上是这样的:

代码语言:javascript
复制
15:33:59.735 INFO [13] org.openqa.selenium.remote.server.DriverServlet - Executing: [find element: By.id: linkservers])
15:33:59.742 INFO [13] org.openqa.selenium.remote.server.DriverServlet - Done: [find element: By.id: linkservers]
15:33:59.750 INFO [13] org.openqa.selenium.remote.server.DriverServlet - Executing: [click: 9 [[FirefoxDriver: firefox on LINUX (84846fb0-1467-45a9-bbfe-a6333ddef515)] -> id: linkservers]])
15:33:59.811 INFO [13] org.openqa.selenium.remote.server.DriverServlet - Done: [click: 9 [[FirefoxDriver: firefox on LINUX (84846fb0-1467-45a9-bbfe-a6333ddef515)] -> id: linkservers]]
15:33:59.824 INFO [13] org.openqa.selenium.remote.server.DriverServlet - Executing: [find elements: By.className: server-name-span-text])
15:34:14.844 INFO [13] org.openqa.selenium.remote.server.DriverServlet - Done: [find elements: By.className: server-name-span-text]
15:34:14.957 INFO [192] org.openqa.selenium.remote.server.DriverServlet - Executing: [execute script: return (function getCoverageData(coverageVariable) {
                var coverageData = (function () { return this; })()[coverageVariable];
                return coverageData && JSON.stringify(coverageData);
        }).apply(this, arguments);, [__internCoverage]])
15:34:14.970 INFO [192] org.openqa.selenium.remote.server.DriverServlet - Done: [execute script: return (function getCoverageData(coverageVariable) {
                var coverageData = (function () { return this; })()[coverageVariable];
                return coverageData && JSON.stringify(coverageData);
        }).apply(this, arguments);, [__internCoverage]]
15:34:14.980 INFO [192] org.openqa.selenium.remote.server.DriverServlet - Executing: [delete session: 2d94ea44-dea8-411a-8ee5-a3d7b749cc7b])
15:34:15.047 INFO [192] org.openqa.selenium.remote.server.DriverServlet - Done: [delete session: 2d94ea44-dea8-411a-8ee5-a3d7b749cc7b]

我该如何解决这个问题?

注:实习版为“3.0.6”,铅脚为“1.6.4”。我尝试使用Selenium运行相同的功能测试,并且成功地运行了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-21 12:06:49

因为click()事件是由浏览器在附加处理程序之前触发的。问题是在get()调用和click()调用之间:

代码语言:javascript
复制
...
.get(url)
    .findById('linkservers')
        .click()
...

所发生的情况是浏览器在附加处理程序之前触发了单击事件。处理程序在被测试的应用程序中实现。这意味着在触发单击事件时,没有处理程序,因此没有创建server-name-span-text元素,从而导致了findDisplayedByClassName操作的超时。注意,我也尝试了findByClassName操作,在这个原因中,我得到了异常findByClassName快速的解决办法,虽然非常麻烦,是在sleep()调用之后添加一个get()

解决方案1:

代码语言:javascript
复制
define(function (require) {
var tdd = require('intern!tdd');
var assert = require('intern/chai!assert');
var url = '...';
var server = '...';

tdd.suite("Init suite",function(){
tdd.before(function () {
  // executes before suite starts
});

tdd.after(function () {
  // executes after suite ends
});

tdd.beforeEach(function () {
  // executes before each test
});

tdd.afterEach(function () {
  // executes after each test
});
tdd.test('Checking servers', function () {
    var that = this.remote;
    return that
        .setFindTimeout(15000)
        .get(url)
        .sleep(1000) //#Fix-1
        .findById('linkservers')
            .click()
            .then(function(){
                console.log("Click resolved");
            })
        .end()
        .findDisplayedByClassName('server-name-span-text')
            .getVisibleText()
            .then(function(texts){
                var t=0;
                var tlen = 0;
                if (Array.isArray(texts))
                {
                    tlen = texts.length
                    for (t=0;t<tlen;t++)
                        console.log("server["+t+"]: "+texts[t]);
                    assert.strictEqual(texts[0],server,"server is: "+texts[0]);
                } else {
                    assert.strictEqual(texts,server,"server is: "+texts[0]);
                }
            })
        .end();
});
});

更新:正如前面所解释的,显式等待是解决此类问题的一个棘手的解决方案。下一个解决方案是基于在应用程序端执行异步脚本executeAsync()调用。此脚本返回一个必须由应用程序解决的承诺,以便结束异步调用的等待。当然,应用程序必须与此合作,这是一个实现的延迟对象,因此它可以确定应用程序加载的时间点。否则,这种方法就行不通了。优雅的方式如下所示。

解决方案2:

代码语言:javascript
复制
define(function (require) {
var tdd = require('intern!tdd');
var assert = require('intern/chai!assert');
var url = '...';
var server = '...';

tdd.suite("Init suite",function(){
tdd.before(function () {
  // executes before suite starts
});

tdd.after(function () {
  // executes after suite ends
});

tdd.beforeEach(function () {
  // executes before each test
});

tdd.afterEach(function () {
  // executes after each test
});
tdd.test('Checking servers', function () {
    var that = this.remote;
    return that
        .setFindTimeout(15000)
        .get(url)
        .executeAsync(function(done){
            //application side.
            application.loaded
                 .then(function(){
                      //at this moment the application has loaded
                      //so we resolve our intern side promise
                      done();
                  })
         })
        .findById('linkservers')
            .click()
            .then(function(){
                console.log("Click resolved");
            })
        .end()
        .findDisplayedByClassName('server-name-span-text')
            .getVisibleText()
            .then(function(texts){
                var t=0;
                var tlen = 0;
                if (Array.isArray(texts))
                {
                    tlen = texts.length
                    for (t=0;t<tlen;t++)
                        console.log("server["+t+"]: "+texts[t]);
                    assert.strictEqual(texts[0],server,"server is: "+texts[0]);
                } else {
                    assert.strictEqual(texts,server,"server is: "+texts[0]);
                }
            })
        .end();
});
});

如果您愿意,还可以向回调返回一些参数,然后在应用程序端解析该参数。有关这方面的更多信息,您可以查看文档

票数 0
EN

Stack Overflow用户

发布于 2015-10-20 15:20:12

解决这个问题的几个建议:

在使用findDisplayedByClassName之前,请确保可以使用findByClassName找到元素

如果它找不到元素,那么确保.findById('linkservers')正常工作。要检查,您可以尝试在之前和之后添加.sleep(),以查看它是否实际工作,并通过'server-name-span-text'类为您提供一个元素。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33238905

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档