Search code examples
javascriptexceljs

Exceljs Error Creating Files If Not Existing


I am trying to create the file and then creating sheets on it. If the file exists already the fs.access will work otherwise the runTests() will crash the program with errors.

Errors:

node:internal/fs/utils:320
    throw err;
    ^

Error: ENOENT: no such file or directory, open 'C:\Users\arund\Desktop\Code\Python\Selenium\Porton\bookApp\portonBookAppTests.xlsx'       
    at Object.openSync (node:fs:495:3)
    at Object.readFileSync (node:fs:396:35)
    at read_binary (C:\Users\arund\Desktop\Code\Python\Selenium\Porton\bookApp\node_modules\xlsx\xlsx.js:2730:44)
    at readSync (C:\Users\arund\Desktop\Code\Python\Selenium\Porton\bookApp\node_modules\xlsx\xlsx.js:21018:69)
    at Object.readFileSync (C:\Users\arund\Desktop\Code\Python\Selenium\Porton\bookApp\node_modules\xlsx\xlsx.js:21046:9)
    at appendToExcel (C:\Users\arund\Desktop\Code\Python\Selenium\Porton\bookApp\index.js:52:21)
    at runTests (C:\Users\arund\Desktop\Code\Python\Selenium\Porton\bookApp\index.js:111:5)
    at C:\Users\arund\Desktop\Code\Python\Selenium\Porton\bookApp\index.js:99:13
    at FSReqCallback.oncomplete (node:fs:187:23) {
  errno: -4058,
  syscall: 'open',
  code: 'ENOENT',
  path: 'C:\\Users\\arund\\Desktop\\Code\\Python\\Selenium\\Porton\\bookApp\\portonBookAppTests.xlsx'
}

Code:

const {Builder, By, Key, util}=require("selenium-webdriver");
require("chromedriver");
const Excel = require('exceljs')
driver = null;
var fs = require('fs');
var XLSX = require('xlsx');

filename = process.cwd()+"\\portonBookAppTests.xlsx";
bookAppSheets=["Rostered Patient","Non-Rostered Patient","Email","Error Handling"];
bookAppTestingProcedures=[
                            ["Start up page shows “Announcement”, message about app, and visual map location",
                               "Entering their HIN should automatically select their past provider",
                               "Fill out appointment detail and contact info",
                               "Available time slots from today to the next month.",
                               "Available number of slots for each day.",
                               "View all available time slots or select closest time slot for that day",
                               "Check box consenting clinic to use their information for the appointment, cancellation policy",
                               "Pop up confirming their appointment with details of appointment"],
                            ["Start up page shows “Announcement”, message about app, and visual map location",
                               "When submitting HIN, shows the options to “Continue as Walk-in” or “Register an account”",
                               "If registering then fill in their personal information",
                               "Choose a provider, appointment mode, and type of service.",
                               "If choosing “Walk-in”, choose a provider, appointment mode, and type of service",
                               "Available time slots from today to the next month.",
                               "Available number of slots for each day.",
                               "View all available time slots or select closest time slot for that day",
                               "Check box consenting clinic to use their information for the appointment, cancellation policy",
                               "Pop up confirming their appointment with details of appointment"],
                            
                              ["Booking an appointment sends confirmation email",
                               "Email outlines time, date, location and mode of appointment",
                               "Displays logo of clinic, cancellation policy, announcement, Porton logo correctly",
                               "Link to modify their appointment, add appointment to calendar",
                               "Link brings them to a new page",
                               "Reschedule: Modify appointment detail with HIN number and provider pre-filled",
                               "See available time slots of the month",
                               "See available time slots of the day",
                               "Confirmation pop up message after rescheduling",
                               "New rescheduled confirmation email"
                               ],
                              ["App disconnected from server, displays appropriate message",
                               "If HIN less than 10 digits, displays HIN error message",
                               "If HIN other than numbers, display invalid HIN message",
                               "Register with invalid HIN, red text outline and error message",
                               "If phone # less than 10 digits, display phone# error message"]];
                               
function appendToExcel(){
    const bookAppColumns=["ID","Testing Procedure:","Pass/Fail","Issue#","Date","Severity","Comment"];
    let currentDate = new Date().toLocaleDateString();
    
    const wb = XLSX.readFile(filename);

    const sheets = wb.SheetNames;
    //console.log(sheets);
    
    //console.log(formated);
    for (let y=0;y<bookAppTestingProcedures.length;y++){
        data=[];
        for (let x=0;x<bookAppTestingProcedures[y].length;x++)
        {
            //console.log(x+1,bookAppTestingProcedures[y][x])    
            data.push([(x+1),bookAppTestingProcedures[y][x],"","",currentDate,"",""]);
        }
        //console.log(data,bookAppSheets[y]);

        //Append to sheet with 2d data
        var ws = XLSX.utils.sheet_add_json(wb.Sheets[sheets[y]],data,  {
            header: bookAppColumns,
            skipHeader: false,
            origin: -1,  // append to bottom of worksheet starting on first column
          });
        //console.log(ws);
    }
    XLSX.writeFile(wb,filename);
}

function main(){
    
    if(driver==null)
    {
        setUp();
    }
    console.log(filename);

    fs.access(filename, (err)=> {
        if (err) {
            createWorkBook();
            runTests();
        }
        else{
            console.log("File exists"); 
            runTests();    
        }
        
     });

}

function runTests(){
    appendToExcel() 
    checkInput();
}

function setUp(){
    driver = new Builder().forBrowser("chrome").build()
}

function checkInput(){
     //await driver.get("http://google.com");
}

function createWorkBook(){

    const workbook = new Excel.Workbook();
    
    for (sheet of bookAppSheets) {
        if (!workbook.worksheets.includes(sheet))
        {
            console.log("Created sheet: "+sheet);
            workbook.addWorksheet(sheet);
        } 
    }
    //console.log((workbook.worksheets));

    workbook.xlsx.writeFile(filename).then(() => {
        console.log("saved");
    })
    .catch((err) => {
        console.log("err", err);
    });
    
}

main();

Solution

  • Wait until the new is created then run the test.

    Easiest way - using async/await.

    Make createWorkBook to return a promise:

    function createWorkBook(){
    
        // ...
    
        return workbook.xlsx.writeFile(filename); // return a promise
    }
    

    In function wait until creating file finished:

    // ...
    fs.access(filename, async (err) => { // async
      if (err) {
        try {
          await createWorkBook(); // wait
          runTests(); // just runTests when file created successfully
        } catch (error) {
          console.log(error);
        }
      }
      else {
        console.log("File exists");
        runTests();
      }
    });
    //...