0

I have a function defined below. This function downloads files one by one and moves it to the directory named templates. In the end, it should return the length of the directory. The issue is, it returns the undefined value. I believe that I am messing up something. Can someone please help?

this.no_of_templates = function () {
    var num;
    this.download_files.each( async function (elem) {
        wait.waitForElementVisibility(elem);
        js.highlighterElement(elem);
        elem.click();
        browser.driver.wait(function(){
            var filesArray = glob.sync(dirPath + '**/*.+(xlsx|docx|pptx)');
            if(typeof filesArray !== 'undefined' && filesArray.length > 0){
                return filesArray;
            }
        }, 60000).then(function(filesArray){
            var filename = filesArray[0];
            fileSystem.moveFile(filename, process.cwd()+'/templates/');
            if(fileSystem.getAllDirFiles(process.cwd()+'/templates/').length >= 6){
                num = fileSystem.getAllDirFiles(process.cwd()+'/templates/').length;
                return false;
            }

        });
    });

    return num;
}

getAllDirFiles() is defined as

this.getAllDirFiles = function (dirPath, arrayOfFiles) {
    var files = fs.readdirSync(dirPath);

    arrayOfFiles = arrayOfFiles || [];

    files.forEach(function (file) {
        if (fs.statSync(dirPath + "/" + file).isDirectory()) {
            arrayOfFiles = getAllDirFiles(dirPath + "/" + file, arrayOfFiles);
        } else {
            arrayOfFiles.push(file);
        }
    })
    return arrayOfFiles;
}

Function returns undefined value.

it('test if templates are downloadable', () => {
var templates = bt.no_of_templates();
expect(templates).toBe(6);

});

  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Randy Casburn Jan 24 '21 at 06:27

3 Answers3

0

Because you are using async function in each, it won't wait for they finished.

try this:


this.no_of_templates = async function () {
    var num;
    var holdon = this.download_files.map( async function (elem) {
        wait.waitForElementVisibility(elem);
        js.highlighterElement(elem);
        elem.click();
        return browser.driver.wait(function(){
            var filesArray = glob.sync(dirPath + '**/*.+(xlsx|docx|pptx)');
            if(typeof filesArray !== 'undefined' && filesArray.length > 0){
                return filesArray;
            }
        }, 60000).then(function(filesArray){
            var filename = filesArray[0];
            fileSystem.moveFile(filename, process.cwd()+'/templates/');
            if(fileSystem.getAllDirFiles(process.cwd()+'/templates/').length >= 6){
                num = fileSystem.getAllDirFiles(process.cwd()+'/templates/').length;
                return false;
            }

        });
    });
    await Promise.all(holdon)
    return num;
}

test:

bt.no_of_templates().then(num => {
  expect(num).toBe(6);
});

just need to change to match your framework, it seems not pure javascript.


And i found some problem in code. why are you count files in every download job?

王仁宏
  • 396
  • 1
  • 9
  • It throws the error (node:12451) UnhandledPromiseRejectionWarning: TypeError: [object Object] is not iterable – vivek kurhe Jan 24 '21 at 08:17
  • because if I don't count it gives the expected result as - Expected 1 to be 6. - Expected 2 to be 6. - Expected 3 to be 6. - Expected 3 to be 6. - Expected 5 to be 6. – vivek kurhe Jan 24 '21 at 08:27
0

It throws the error

(node:12451) UnhandledPromiseRejectionWarning: TypeError: [object Object] is not iterable
at Function.all (<anonymous>)
at BusinessTemplatesPage.no_of_templates (/home/vivek/simplifiedcredit-qa-automation/src/page-objects/business_templates.page.js:125:23)
at UserContext.it (/home/vivek/simplifiedcredit-qa-automation/src/specs/business_templates.spec.js:41:26)
at /home/vivek/simplifiedcredit-qa-automation/node_modules/jasminewd2/index.js:112:25
at new ManagedPromise (/home/vivek/simplifiedcredit-qa-automation/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:1077:7)
at ControlFlow.promise (/home/vivek/simplifiedcredit-qa-automation/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:2505:12)
at schedulerExecute (/home/vivek/simplifiedcredit-qa-automation/node_modules/jasminewd2/index.js:95:18)
at TaskQueue.execute_ (/home/vivek/simplifiedcredit-qa-automation/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:3084:14)
at TaskQueue.executeNext_ (/home/vivek/simplifiedcredit-qa-automation/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:3067:27)
at asyncRun (/home/vivek/simplifiedcredit-qa-automation/node_modules/protractor/node_modules/selenium-webdriver/lib/promise.js:2974:25)

(node:12451) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2) (node:12451) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

because if I don't count it gives the expected result as

- Expected 1 to be 6.
- Expected 2 to be 6.
- Expected 3 to be 6.
- Expected 3 to be 6.
- Expected 5 to be 6.

And I have to use the same function to test templates of different categories. Currently there are 4 categories and each one has different number of templates.

  • i dont know what type of `this.download_files` is. using `map` to collect their promise and wait them finish. – 王仁宏 Jan 24 '21 at 10:08
0

this.download_files is an ElementArrayFinder.

this.download_files = element.all(by.xpath('//button//img[@src="url_here"]'));