javascriptcypressspecial-characterscypress-custom-commands

cy.wrap().its()... doesn't work when the value in .its() contains a period


I am looking to extract a URL parameter from the current URL I'm testing with Cypress. I was able to basically get the answer from this SO post, however, my extracted values are not available to me when I use Cypress's .its() command.
The parameters in the url all have periods in them, and I believe this is the cause for my error. Here is my custom Cypress Command I'm building:

Cypress.Commands.add('getParmsCommand', function(value) {
cy.url().as('url')

cy.then( () => {
  cy.log(this.url)
  const kvPairArray = this.url.toString().split('?')[1].toString().split('&')
  const paramObj = {}
  kvPairArray.forEach(param => {
    cy.log(param)
    //default 'value' to 0 if it doesn't exist
    const [ key, value="0" ] = param.split('=')
    paramObj[key] = value
  })
  //forcefully adding a debug element to the key value store for testing
  paramObj['beverage'] = 'soda'

cy.wrap(paramObj)
  .its('timeline.ws')                                   //doesn't work
  // .its(`${Cypress.$.escapeSelector('timeline.ws')}`) doesn't work
  // .its('timeline\.ws')                               doesn't work
  // .its('"timeline.ws"')                              doesn't work
  // .its('beverage')                                   this DOES work!
  .then(parmVal => {
    cy.log(parmVal)
})

Here is the relevant part of the URL that I'm trying to extract from:

timeline.ws=3600000&timeline.to&timeline.fm&timeline.ar=false

You can see from the error that Cypress is only looking for the id timeline, NOT timeline.ws; it completely ignores everything after the period, and thus, never finds my parameter.
Cypress error message

I saw there was a similar error with Cypress's .get() function back in 2018.


Solution

  • .its() is just a shorthand for property extraction. Since it fails with the period, you could instead use bracket notation in a .then().

    cy.wrap(paramObj)
      .then(paramObj => paramObj['timeline.ws'])
    

    or just

    cy.wrap(paramObj['timeline.ws'])
    

    Playing around with the URL constructor

    const urlString = 'http://example.com?timeline.ws=3600000&timeline.to&timeline.fm&timeline.ar=false'
    const url = new URL(urlString)
    
    cy.wrap(url.searchParams.get('timeline.ws'))
      .should('eq', '3600000')
    
    cy.wrap(url.searchParams.get('timeline.to'))
      .should('be.empty')
    
    cy.wrap(url.searchParams.get('timeline.ar'))
      .should('eq', 'false')