V
V
valentine112015-12-24 20:28:18
JavaScript
valentine11, 2015-12-24 20:28:18

Node.js - Imported function doesn't see variables in current scope, solution?

Good afternoon. I'm a tester, learning automation.
I am new to js and nodejs.
There is a file with test blocks. I'm trying to move constantly repetitive actions outside the source file in order to reduce the amount of code. But something goes wrong.
Taken actions:

exports.loadRegistrationForm = function() {
    driver.get('http:...');
    driver.getTitle().then(function(title){
      if("..."===title){
        driver.findElement(webdriver.By.xpath('html/body/div/header/div/div/div[2]/div[2]/a[1]'))
            .click();
      };
    });
  driver.wait(function(){
    return driver.isElementPresent(webdriver.By.name('fos_user_registration_form[email]'));
  }, 3000, 'Failed to load Registration form');    	
};

// заполнение формы регистрации и проверка соответствия
exports.fillingRegistrationForm = function(inputEmail, inputPassword, errElement, errMessage){ 
  driver.findElement(webdriver.By.name('fos_user_registration_form[email]'))
      .sendKeys(inputEmail); //вводим уже зарегистрированный email
  driver.findElement(webdriver.By.name('fos_user_registration_form[plainPassword]'))
      .sendKeys(inputPassword); //вводим валидный пароль
  driver.findElement(webdriver.By.id('btn-submit')).click();//сабмит

  driver.wait(function(){
    return driver.isElementPresent(webdriver.By.xpath(errElement));
  }, 3000, 'Элемент не найден'); //ожидание загрузки текста ошибки

  var flow = webdriver.promise.controlFlow();
  function getErrObject(){
    errObject = driver.findElement(webdriver.By.xpath(errElement))
            .getText()
  } //берем объект элемента с текстом ошибки
  flow.execute(getErrObject).then(function(){
    if(errObject.value_ === errMessage){
      assert.equal(errObject.value_, errMessage);
      console.log('OK')
    };
  });
};

An attempt to rewrite the original file with function loading:
var assert = require("assert")
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().
      withCapabilities(webdriver.Capabilities.chrome()).
      build();
var loadRegistrationForm = require('./reusable_function').loadRegistrationForm;
var fillingRegistrationForm = require('./reusable_function').fillingRegistrationForm;

describe('Проверка поля Email формы регистрации.', function(){
  it('Ввод уже зарегистрированного Email', function(done){
      var inputEmail = '[email protected]';
    var inputPassword = '12345678Aa';
    var errElement = "//*[@class='form-errors server-error']";
    var errMessage = 'Email уже используется';
        loadRegistrationForm();	//загружаем форму регистрации
    fillingRegistrationForm(inputEmail, inputPassword, errElement, errMessage);
    return done();
  });
});

When running the test, the following is displayed in the console:
C:\Program Files\nodejs\test\reusable_function.js:9
    driver.get('http://...');
    ^

ReferenceError: driver is not defined
    at Object.exports.loadRegistrationForm (C:\Program Files\nodejs\test\reusabl
e_function.js:9:5)
    at Object.<anonymous> (C:\Program Files\nodejs\test\test2_mocha.js:7:32)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Module.require (module.js:366:17)
    at require (module.js:385:17)
    at C:\Users\Valentine11\AppData\Roaming\npm\node_modules\mocha\lib\mocha.js:
216:27
    at Array.forEach (native)
    at Mocha.loadFiles (C:\Users\Valentine11\AppData\Roaming\npm\node_modules\mo
cha\lib\mocha.js:213:14)
    at Mocha.run (C:\Users\Valentine11\AppData\Roaming\npm\node_modules\mocha\li
b\mocha.js:453:10)
    at Object.<anonymous> (C:\Users\Valentine11\AppData\Roaming\npm\node_modules
\mocha\bin\_mocha:393:18)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Function.Module.runMain (module.js:467:10)
    at startup (node.js:136:18)
    at node.js:963:3

Those. does not find driver variable.
Question: why? Maybe I'm loading the functions in the wrong way?
Solution from post: Node.js. Uploading a file to the current environment does not work.
If you remove ; in lines 6 and 7, then mocha itself gives the same error:
Проверка поля Email формы регистрации.
    1) Ввод уже зарегистрированного Email


  0 passing (41ms)
  1 failing

  1) Проверка поля Email формы регистрации. Ввод уже зарегистрированного Email:
     ReferenceError: driver is not defined
      at exports.loadRegistrationForm (C:\Program Files\nodejs\test\reusable_fun
ction.js:9:5)
      at Context.<anonymous> (C:\Program Files\nodejs\test\test2_mocha.js:15:9)
      at callFnAsync (C:\Users\Valentine11\AppData\Roaming\npm\node_modules\moch
a\lib\runnable.js:306:8)
      at Test.Runnable.run (C:\Users\Valentine11\AppData\Roaming\npm\node_module
s\mocha\lib\runnable.js:261:7)
      at Runner.runTest (C:\Users\Valentine11\AppData\Roaming\npm\node_modules\m
ocha\lib\runner.js:421:10)
      at C:\Users\Valentine11\AppData\Roaming\npm\node_modules\mocha\lib\runner.
js:528:12
      at next (C:\Users\Valentine11\AppData\Roaming\npm\node_modules\mocha\lib\r
unner.js:341:14)
      at C:\Users\Valentine11\AppData\Roaming\npm\node_modules\mocha\lib\runner.
js:351:7
      at next (C:\Users\Valentine11\AppData\Roaming\npm\node_modules\mocha\lib\r
unner.js:283:14)
      at Immediate._onImmediate (C:\Users\Valentine11\AppData\Roaming\npm\node_m
odules\mocha\lib\runner.js:319:5)

I am not writing the original code yet, because I think that in principle it is not needed here, and I don’t want to turn the question into a sheet ... but if necessary, I’ll add it. Thanks in advance for your replies.
---
UPD. Removed the error with the driver for the time being, specifying the driver in the file with the removed functions. I don't like this solution but so be it for now.
Now the code looks like this:
var assert = require("assert")
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().
      withCapabilities(webdriver.Capabilities.chrome()).
      build();
var flow = webdriver.promise.controlFlow();
      

loadRegistrationForm = require('./reusable_function').loadRegistrationForm
fillingRegistrationForm = require('./reusable_function').fillingRegistrationForm


describe('Проверка поля Email формы регистрации.', function(){
  it('Ввод уже зарегистрированного Email', function(done){
      var inputEmail = '[email protected]';
    var inputPassword = '12345678Aa';
    var errElement = "//*[@class='form-errors server-error']";
    var errMessage = 'Email уже используется';
        loadRegistrationForm();
    fillingRegistrationForm(inputEmail, inputPassword, errElement, errMessage);
    flow.execute(function(){
        return done();	
    });
  });
});

The code works, the test is executed. BUT! the script opens two browser windows, because when importing, the driver is initialized, it strains. If you remove the driver initialization, driver is not defined again appears in the test file. Those. in fact, the problem in the title remains.
It is also not clear why the code works only if it is imported as a Function Declaration:
loadRegistrationForm = require('./reusable_function').loadRegistrationForm
fillingRegistrationForm = require('./reusable_function').fillingRegistrationForm?
All examples use import via var.
Why the code is inoperable if you put module.export in the imported functions, and not just export, is also unclear.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
N
Nicholas, 2015-12-24
@healqq

PS I did not immediately understand what exactly the error was. My suggestion is to do it like this:

function testsHelper(driver) {
  var _driver = driver;
  function loadRegistrationForm() {
    _driver.get('http:...');
      _driver.getTitle().then(function(title){
        if("..."===title){
          _driver.findElement(web_driver.By.xpath('html/body/div/header/div/div/div[2]/div[2]/a[1]'))
              .click();
        };
      });
    _driver.wait(function(){
      return _driver.isElementPresent(web_driver.By.name('fos_user_registration_form[email]'));
    }, 3000, 'Failed to load Registration form'); 
  }
  
  // заполнение формы регистрации и проверка соответствия
  function fillingRegistrationForm(inputEmail, inputPassword, errElement, errMessage) { 
    _driver.findElement(web_driver.By.name('fos_user_registration_form[email]'))
        .sendKeys(inputEmail); //вводим уже зарегистрированный email
    _driver.findElement(web_driver.By.name('fos_user_registration_form[plainPassword]'))
        .sendKeys(inputPassword); //вводим валидный пароль
    _driver.findElement(web_driver.By.id('btn-submit')).click();//сабмит

    _driver.wait(function(){
      return _driver.isElementPresent(web_driver.By.xpath(errElement));
    }, 3000, 'Элемент не найден'); //ожидание загрузки текста ошибки

    var flow = web_driver.promise.controlFlow();
    function getErrObject(){
      errObject = _driver.findElement(web_driver.By.xpath(errElement))
              .getText()
    } //берем объект элемента с текстом ошибки
    flow.execute(getErrObject).then(function(){
      if(errObject.value_ === errMessage){
        assert.equal(errObject.value_, errMessage);
        console.log('OK')
      };
    });
  }
  return {
    fillingRegistrationForm: fillingRegistrationForm,
    loadRegistrationForm: loadRegistrationForm
  }
}
module.exports = testsHelper;

var Helper = require(testsHelper.js);

// инициализируем driver
var driver = ...
var helper = new Helper(driver);

A
Alexander Litvinenko, 2015-12-24
@edli007

Pass the necessary variables to the function, but what the hell are you doing, take out the repeating blocks where these variables exist.

A
Alexander Leonovich, 2015-12-24
@atlantech

Initialize Variable

var driver = new webdriver.Builder().
      withCapabilities(webdriver.Capabilities.chrome()).
      build();

at the beginning of the file where you moved the loadRegistrationForm. Then the variable driverbecomes global with respect to loadRegistrationForm. Should work

T
timfcsm, 2015-12-24
@timfcsm

move the driver to a separate module and import it where necessary

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question