Home > Software design >  cy.type() can only accept a string or number. You passed in: undefined
cy.type() can only accept a string or number. You passed in: undefined

Time:05-27

I am trying to fill out an HTML form using a CSV file. For them I first convert the CSV file to JSON and then try to fill the form using the JSON file. However, the only thing I get is the error: cy.type() can only accept a string or number. You passed in: undefined

I have checked the answers that have been given for this same problem but I can't find one that helps me. What am I doing wrong?

Here I leave the code with which I first pass the file from CSV to JSON, then it is logged in the console and finally I pass it through the form:

<!-- language: js -->
import {parse} from "papaparse"
    describe('Convert CSV file in JSON file', function(){
        let allData        
        before(()=>{
            cy.readFile('C:/data/cypress/downloads/generatedBy_react-csv.csv')
                .then(str =>{
                    cy.writeFile('C:/data/cypress/fixtures/testDataFromCSV.json', parse(str, {header:true}))
                })
            cy.fixture('testDataFromCSV.json')
                .as('dataJson')
                .then(dataJson => {
                    allData = dataJson
                })
        })
it('Log the data from the CSV to the JSON file', function(){       
    allData.data.forEach(data =>{
        cy.log(data.firstName)
        cy.log(data.lastName)
        cy.log(data.email)
        cy.log(data.age)
        cy.log(data.address)
        cy.log(data.vehicle)
        cy.log(data.phoneNo)
    })
})

it('Use JSON Data in hte HTML form', function(){       
    allData.data.forEach(data =>{
        cy.visit('http://localhost/2iTesting/form.html')
        cy.fixture("testDataFromCSV.json")
            .then((dataJson)=>{
                allData = JSON.stringify(dataJson)
                cy.get('[cy-data="firstname"]')
                    .type(data.firstName)
                cy.get('[cy-data="lastname"]')
                    .type(data.lastName)
                cy.get('[cy-data="email"]')
                    .type(data.email);
                cy.get('[cy-data="address"]')
                    .type(data.address);
                cy.get('[cy-data="vehicle"]')
                    .type(data.vehicle);
                cy.get('[cy-data="submit"]')
                    .click()
                cy.wait(1500)
            })
    })
})

})

CodePudding user response:

The issue is the scope of your then block. Inside the then block for this fixture. cy.fixture('testDataFromCSV.json').as('dataJson').then(dataJson => { allData = dataJson})

allData = dataJson

But outside the then block alldata = let alldata or just undefined. To get access to the assigned variable you need to use cy.wrap().

cy.fixture('testDataFromCSV.json').as('dataJson')
.then( (dataJson) => {
  cy.wrap(dataJson).as(allData)
 }

To then access your wrapped object you simply do the following.

it('Log the data from the CSV to the JSON file', () =>{
cy.get('@allData')
.then( (allData) => {
  Object.Values(allData.data).forEach( (value) =>{ //this might be wrong as I'm unsure the data structure of your object
    cy.log(value)
  }
}
it('Use JSON Data in the HTML form', () =>{
cy.get('@allData')
  .then( (dataJson) =>{
    allData = JSON.stringify(dataJson)
    cy.get('[cy-data="firstname"]')
    .type(allData.data.firstName) //and so on from here
  }

One last thing to note, you have a cy.wait(1500) at the end of your second it block. I would suggest looking into cy.intercept().as('api') to catch whatever API response you are getting by clicking submit. Then its just a mater of cy.wait('api') which is a best practice.

CodePudding user response:

Just remove the stringify step.

I think you intend to parse, but there's no need because Cypress already does it for you. Any file with .json extension is passed into the test as an object.

cy.fixture("testDataFromCSV.json")
  .then((dataJson) => {

    // allData = JSON.stringify(dataJson)  // no need to do this, just use dataJson

    cy.get('[cy-data="firstname"]')
      .type(dataJson.firstName)    // NOTE you have data.firstName
    ...                            // which looks like a cut-and-paste error
                                   // from the test above

Writing the data portion of the parse result

The papaparse library gives you a wrapper object that contains the data, an errors array and meta data.

Ideally you want to check errors before writing the JSON, but at minimum you will need to write the .data property of the parse result.

cy.readFile('./cypress/downloads/generatedBy_react-csv.csv').then(str =>{
  const result = parse(str, {header:true})
  if (result.errors.length) {
    // handle errors
  }
  cy.writeFile('./cypress/fixtures/testDataFromCSV.json', result.data)
})
  • Related