如何创建一个全局可访问的变量?

时间:2014-07-31 19:29:58

标签: javascript nightwatch.js

如何在nightwatch.js中创建一个全局可访问的变量?我使用变量来存储自定义网址(取决于我们的在线产品中加载了哪个商店),但我需要它可以通过多个javascript函数访问。看起来它的值在每个函数结束后重置,尽管它是在文件头部的函数之外声明的。

6 个答案:

答案 0 :(得分:15)

已经有一段时间了,因为你问过你的问题并支持你之前可能没有(原生)可用的内容。现在是。

在开发人员指南中,提供了两种方法,用于创建可从任何给定测试访问的全局变量,具体取决于您的需要。请参阅here以获得良好的阅读效果。

方法1: 对于真正的全局全局变量,即适用于所有测试和所有环境。在" globals_path"定义一个对象,或者传递一个文件。你的nightwatch.json文件的一部分,即

select case when not exists (
    select * from (
        select 'ALPHA' foo
        union select 'BETA' foo
        union select 'GAMMA' foo) a
    left join (select distinct foo from bar) b
    on a.foo = b.foo
    where b.foo is null)
    then 1
    else 0
end;

然而,您需要导出变量,因此在Node上刷新是一个好主意。这是一个基本的globals.js文件示例:

bar

此对象/文件将用于所有测试,无论环境如何,除非您指定不同的文件/对象,如下面的方法2所示。

要从测试套件中访问变量,请使用传递给每个函数(测试)的强制浏览器/客户端变量,即:

"globals_path": "./lib/globals.js",

方法2: 对于基于环境的全局变量,它根据您指定的环境而变化。在"全局"定义一个对象,或传递一个文件。 nightwatch.json文件的一部分,嵌套在您所需的环境下。即。

var userNames = {
  basicAuth: 'chicken',
  clientEmail: 'SaddenedSnail@domain.com',
  adminEmail: 'admin@domain.com',
};

module.exports = {
  userNames: userNames
}

请注意,在撰写本文时,守夜人似乎存在一个错误,因此使用方法2传递文件不起作用(至少在我的环境中)。有关所述错误的更多信息可以在here找到。

答案 1 :(得分:4)

为了扩展Tricote的答案,Nightwatch内置了对此的支持。请参阅documentation

您可以在nightwatch.json文件中将"globals": {"myvar": "whatever"}文件指定为globals.js,也可以在nightwatch.json中使用"globals": "path/to/globals.js"引用的globals.js文件中指定。{p>在后一种情况下,module.exports = { myvar: 'whatever' }; 可能有:

module.exports = {
  "test": function(browser) {
    console.log(browser.globals.myvar); // "whatever"
  }
};

在任何一种情况下,您都可以像Tricote提到的那样访问测试中的变量:

{{1}}

答案 2 :(得分:1)

我可能会为此投票,但我成功用于存储和检索对象和数据的另一个选项是将文件写入现有文件的键值对。

这允许我在测试运行结束时查看随机创建的任何数据。我在第一个测试脚本中使用我将用于创建测试的各种帐户的所有数据创建此文件。通过这种方式,如果我看到很多失败,我可以查看该文件并查看使用了哪些数据,然后说,以该用户身份登录并手动转到该位置。

在自定义命令中,我有一个导出以下函数的文件:

saveToFile : function(path, filename, data) {
    this.yfs = fs;
    buffer = new Buffer(data);

    console.log("Note: About to update the configuration with test data" )

    fs.open(path, 'w', function(err, fd) {
        if (err) {
            throw 'error opening file: ' + err;
        }

        fs.write(fd, buffer, 0, buffer.length, null, function(err) {
            if (err) throw 'error writing file: ' + err;
             return fs.close(fd, function() {
                console.log('File write: ' +  path + ' has been updated.' );
            })
        });
    })
},

在此文件中,'data'是键值对,如“username”:“Randy8989@mailinator.com”。因此,如果需要,我可以在以后的脚本中使用该数据。

这是真的,我将立即探索GrayedFox的答案。

答案 3 :(得分:0)

不确定这是最好的方法,但我的方法如下:您可以在browser.globals中定义变量并在不同的测试中访问它

例如:

 module.exports = {
  before: function(browser) {
    console.log("Setting up...");

    // initialize global variable state
    browser.globals.state = {};
  },

  "first test": function(browser) {
    var settings = browser.globals,
        state = browser.globals.state;

    state.my_shared_var = "something";

    browser.
      // ...
      // use a shared variable
      .setValue('input#id', state.my_shared_var)
      // ...

      // ...
      // save something from the page in a variable 
      .getText("#result", function(result) {
        state.my_shared_result = result.value;
      })
      // ...
  },

  "second test": function(browser) {
    var settings = browser.globals,
        state = browser.globals.state;

    browser.
      // ...
      // use the variables
      .url("http://example.com/" + state.my_shared_result + "/show")
      .assert.containsText('body', state.my_shared_var)
      // ...
  }
}

答案 4 :(得分:0)

globals.json 的替代方法,如果您需要通过复杂的过程读取数据,只需在同一测试文件中创建一个函数即可。

在以下示例中,我需要来自csv的简单值和数据。
因此,我创建了 getData()函数,并且可以直接从内部调用:

let csvToJson = require('convert-csv-to-json');

function getData(){
  let users = csvToJson.getJsonFromCsv("/../users.csv");
  return {
    "users:": users,
    "wordToSearch":"JRichardsz"
  }
}

module.exports = {
    
    "login": function(browser) {

      //data is loading here
      var data = getData();

      browser
           .url('https://www.google.com')
           .waitForElementVisible('input[name="q"]', 4000)
           .setValue('input[name="q"]', data.wordToSearch)
           .keys(browser.Keys.ENTER)
           .waitForElementVisible('#result-stats', 4000)
           .end();
    }
};

答案 5 :(得分:-3)

通常这是一种不好的做法,但您可以将其指定为window类的字段。

window.someGlobalVar = 'http://example.org/'

可以全局访问窗口对象