javascript - javascript递归调用的问题

标签 javascript node.js jasmine protractor

描述:我想从网页读取特定标签,其值更改为“已开始”、“进行中”、“成功”、“错误”之一。一旦标签值更改为“成功”或“错误”,将不会再发生任何进一步的更改。

问题:当我在 Protractor 中使用javascript读取标签值时,标签的文本值不会返回到调用函数;相反,它返回“未定义”。下面是我的代码,请看一下,让我看看问题出在哪里。

CheckColor_Test.js

var commonFunctions = require('../pages/CommonFunctions.js');
describe("Run Test", function () {
    it("should stop once the status reached Success or Error", function () {
        var processStatus = commonFunctions.refreshTillProcessFinish();
        expect(processStatus).toContain('Success','Error');
    });
});

CommonFunctions.js

Var CommonFunctions = function(){
var label = element(by.id('Status'));
var refreshStatusBtn = element(by.css('[ng-click="getJob()"]'));
    this.getStatusValue = function () {
        return label.then(function (headers) {
            return headers.getText();
        });
    };
    this.refreshTillRefreshFinish = function () {
        var refreshStatusMonitor = function (currentStatus) {
            return currentStatus.then(function (Status) {
                if (Status == 'Success' || Status.includes("Error")) {
                    console.log(Status);
                    return Status;
                } else {
                    refreshStatusBtn.click();
                    console.log(Status);
                    browser.sleep(2000);
                    refreshStatusMonitor (currentStatus);
                }
            });
        };
        return refreshStatusMonitor (this.getStatusValue);
    };
}
module.exports = new CommonFunctions();

在 Protractor 中执行: 我已经在 Webstorm 中配置了 Protractor ,因此我曾经使用它来运行。

预期结果: 测试应该成功并通过

实际结果: 测试失败并出现以下错误。

"C:\Program Files (x86)\JetBrains\WebStorm 2016.1.1\bin\runnerw.exe" "C:\Program Files\nodejs\node.exe" node_modules\protractor\built\cli.js D:\Somesh_HDD\WebstormProjects\ProjectUBET\conf.js
[22:19:59] I/direct - Using ChromeDriver directly...
[22:19:59] I/launcher - Running 1 instances of WebDriver
Spec started
Started
InProgress
Success

  Run Test
    ? should stop once the status reached Success or Error
      - Expected undefined to contain 'Success', 'Error'.

**************************************************
*                    Failures                    *
**************************************************

1) Run Test should stop once the status reached Success or Error
  - Expected undefined to contain 'Success', 'Error'.

Executed 1 of 1 spec (1 FAILED) in 33 secs.
[22:20:36] I/launcher - 0 instance(s) of WebDriver still running
[22:20:36] I/launcher - chrome #01 failed 1 test(s)
[22:20:36] I/launcher - overall: 1 failed spec(s)
[22:20:36] E/launcher - Process exited with error code 1

Process finished with exit code 1

最佳答案

返回值如下:

return currentStatus.then(...);

不是此语句返回的值:

return Status;

事实上,后者返回到 refreshStatusMonitor 的递归调用之一,该调用在任何地方都没有捕获。

因为这是涉及 Promise 的异步代码,所以 currentStatus 的返回值也应该是一个 Promise,它将通过 refreshStatusMonitorrefreshTillRefreshFinish 冒泡 code> 到您的测试,然后还需要进行调整,以便在期望任何事情之前等待 promise 得到履行。

我还建议不要使用 browser.sleep(...) 因为它会完全阻止您的 JavaScript 环境。您可以使用 setTimeout(...) 来代替。

这里是一些基于这些想法的未经测试的代码:

this.refreshTillRefreshFinish = function () {
    // create a promise
    var deferred = protractor.promise.defer();
    var refreshStatusMonitor = function (currentStatus) {
        currentStatus.then(function refresh(Status) {
            if (Status == 'Success' || Status.includes("Error")) {
                // Signal the completion via the promise. 
                // This triggers the `then` callback in your revised test
                deferred.fulfill(Status); 
            } else {
                refreshStatusBtn.click();
                console.log(Status);
                // Use setTimeout so JavaScript is not blocked here:
                setTimeout(function () {
                    refreshStatusMonitor(currentStatus);
                }, 2000);
            }
        });
    };
    refreshStatusMonitor(this.getStatusValue);
    // Don't wait for the result to happen while blocking everything, 
    // instead return a custom-made promise immediately 
    return deferred.promise;
};

你的测试还应该考虑到你正在处理一个 promise :

it("should stop once the status reached Success or Error", function () {
    var processStatus = commonFunctions.refreshTillProcessFinish().then(function () {
        expect(processStatus).toContain('Success','Error');
        done();
    });
}, 20000); // set timeout to 20 seconds

请注意,Jasmine 的默认超时时间为 2 秒,因此您需要在最后提供额外的参数。

注意:这种异步测试不太适合运行批量的单元测试。

关于javascript - javascript递归调用的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37546381/

相关文章:

jquery - Jasmine 文字验证: How to normalize text?

javascript - AngularJS 和 Jasmine : mocking services

node.js - 在本地主机上运行时,Firebase 出现 CORS 错误

file - 对 node.js 文件系统感到困惑

node.js - 无法信任 Node.js 中来自 IIS Express 的自签名 SSL 证书

javascript - 在更改桌面屏幕分辨率时更改 css

javascript - coffeescript 和 jquery 为背景图片生成完整的 url?

javascript - 如何在nodejs服务器上使用tensorflow js?

javascript - 前端开发工作流程

javascript - 使用 Javascript 创建 SVG 图形?