The function is coming back with a value of undefined

I need some assistance with a function I have below. This function is meant to download files one by one and move them to a directory called templates. At the end, it should return the length of the directory. However, it seems to be returning an undefined value. I suspect that I am missing something here. Can anyone provide some guidance?

this.countTemplates = 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;
}

The method getAllDirFiles() is defined as follows:

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;
}

The function currently returns an undefined value.

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

});

Answer №1

When utilizing async functions within each loop, it will not wait for them to finish.

Consider implementing the following solution:


this.calculateNumberOfTemplates = async function () {
    var numOfFiles;
    var tasks = this.download_files.map( async function (element) {
        wait.waitForElementVisibility(element);
        js.highlighterElement(element);
        element.click();
        return browser.driver.wait(async 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){
                numOfFiles = fileSystem.getAllDirFiles(process.cwd()+'/templates/').length;
                return false;
            }

        });
    });
    await Promise.all(tasks)
    return numOfFiles;
}

Test the function with:

this.calculateNumberOfTemplates().then(count => {
  expect(count).toBe(6);
});

You may need to adjust according to your framework as it appears to be non-standard JavaScript.


I also noticed an issue in the code - why are you counting files in every download task?

Answer №2

An error is thrown due to a TypeError where an object is not iterable in the code snippet below:

(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)

This error occurs when not counting, resulting in an unexpected outcome as shown below:

- 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.

The same function needs to be used to test templates of various categories, with each category containing a different number of templates.

Answer №3

this.download_files represents a collection of elements.

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating an overlay button within various containing divs requires setting the position of the button

Tips for overlaying a button on each HTML element with the class WSEDIT. My approach involves using a JavaScript loop to identify elements with the CSS class WSEDIT, dynamically create a button within them, and prepend this button to each element. Below ...

Guide on altering the background color of a table row depending on the data in its cells with the help of AngularJS

I am looking to dynamically change the background color of a row based on specific cell data. If the first four characters in a table cell match a certain value, I want the entire row to change its color to red. Currently, my code changes the row color ba ...

Locating and identifying visible elements on a web application with Selenium

I am struggling to locate visible elements on a web application page using Selenium. Specifically, I need to identify a clickable row and then click on it. The challenge lies in the fact that these elements are dynamically generated and do not appear in ...

Switch between using the useState hook by toggling it with the MUI Switch

Looking to implement a custom Dark Mode feature for a specific element on my create-react-app website using MUI. I have successfully implemented the Switch to change the state on toggle, but I am having trouble figuring out how to toggle it back and fort ...

Getting Started with Parsing JSON Objects in ReactJS

In my ReactJS project, I am trying to parse through a JSON list using the following model: public class ModelEmployee { public List<Employeelist> Employees { get; set; } public int count { get; set; } public int Pagenumber { get; set; } ...

Mastering data binding with Vue Js is a process that requires dedication and time

I'm a Vue JS beginner and I've created a component that repeats a grid-like section. However, I've noticed that adding a dropdown in the grid is causing a significant increase in load time. As the number of records grows, the load time will ...

Tips for circumventing the ajax data size restriction in asp.net mvc3

Currently, I am implementing an auto suggest function using AJAX in the following manner: $("#empName2").autocomplete({ search: function (event, ui) { var key = CheckBrowser(event); if (key == 13) return tr ...

Issue with dynamic code detected by Sys.Application.add_init

I am facing a challenge with an older application that I recently took over ownership of. My efforts to successfully run it have been partially fruitful, as I am encountering some strange behavior that seems to be related to Internet Explorer 11. Interesti ...

Html content overlapping div rather than being stacked vertically

My goal is to arrange a group of divs inside another div in a vertical stack. However, I am facing an issue where the text from the last div is overlapping with the second div instead of following a proper vertical alignment where the text in the third div ...

updating information automatically on page every X seconds for Angular component

I am trying to implement a way to automatically refresh the data of an Angular component every 30 seconds. Currently, I have used a simple setInterval function like this: this.interval = setInterval(() => { this.refresh(); // api call ...

The function 'toBlob' on 'HTMLCanvasElement' cannot be executed in react-image-crop because tainted canvases are not allowed to be exported

Currently, I am utilizing the react-image-crop npm package for image cropping purposes. Everything works perfectly when I pass a local image as props to the module. However, an issue arises when I try to pass a URL of an image fetched from the backend - th ...

The unexpected identifier 'express' was encountered in the import call, which requires either one or two arguments

I'm in the process of constructing an express server using typescript and Bun. Recently, I completed my register route: import express from "express"; const router = express.Router(); router.get('/registerUser',(_req:express.Reque ...

A cutting-edge JQuery UI slider brought to life using HTML5's data-* attributes and CSS class styling

I've been attempting to create multiple sliders using a shared CSS class and HTML5 data attributes, but unfortunately, I haven't had much success so far. Although I am able to retrieve some values, there are certain ones that simply aren't w ...

Guide to verifying current data using the jQuery validation library combined with CodeIgniter 4 in the presence of automatic CSRF protection

I am currently working on validating a form using the jQuery validation plugin and CodeIgniter 4. I have enabled CSRF protection that auto generates for each request. Initially, I can successfully validate the form on the first request. However, on subsequ ...

Having difficulty accessing the API response accurately

The response from my API is as follows: {"__v":0,"short":"8xdn4a5k","_id":"5404db5ac27408f20440babd","branches":[{"version":1,"code":""}],"ext":"js","language":"javascript"} When I use this code, it works perfectly: console.log(response.short); However ...

Display each new array element on a separate line

let team = [['Sara', 'John', 'Kate']] let newTeam = team.map(function(r) { return r; }) outputs [ [ 'Sara', 'John', 'Kate' ] ] Is there a way to modify it so that each value is r ...

Transformer Class: An object containing properties that are instances of another class

class ClassA { x: number; y: number; sum(): number { return this.x + this.y; } } class ClassB { @Type(() => ClassA) z: {[key: string]: ClassA}; } const b = transformObject(ClassB, obj); const z = b.z[key]; const s = z.s ...

What are some effective ways to analyze jQuery and JavaScript using web development tools?

I'm struggling to use web development tools to inspect the JavaScript on websites. It's challenging to identify which parts of a site are utilizing JS, unlike CSS or HTML where it's more visibly defined. Even when I attempt to delete some J ...

The Grid within the Container is presented vertically rather than horizontally

I followed the coding style exactly as shown in a recent tutorial on YouTube, where the cards were displayed in a row. However, when I implemented it, they are appearing strangely in a column. Why is this happening? The default should be inline. Even afte ...

Is there a way to declare the different types of var id along with its properties in Typescript?

I recently received a task to convert a JavaScript file to a TypeScript file. One issue I am currently facing is whether or not I should define types for the 'id' with this expression, e.g., id={id}. So far, I have tried: Even though I defined ...