How to remove whitespace from a string in Cypress
Asked Answered
H

4

7

I'm trying to remove a whitespace from a numerical value representing money.

For example, I want 1 000 kr to be 1000. This is the same case for when the currency is 10 000

I'm using this function to remove the kr but when I try to add another .replace it does not work:

Cypress.Commands.add('currency', (selector) => {
      cy.get(selector)
        .children()
        .eq(1)
        .invoke('text') // get text
        .then((text) => +text.replace('kr', '').trim());
    });

How would I add another .replace to remove the extra spacing from the numerical value? enter image description here

Helot answered 31/3, 2021 at 19:22 Comment(1)
What about using regex?Pious
W
6

This should work:

function formatString(text) {
    return text.replace('kr', '').replace('\u00A0','').trim();
}

Cypress.Commands.add('currency', (selector) => {
      cy.get(selector)
        .children()
        .eq(1)
        .invoke('text') // get text
        .then(formatString)
    });

But you can also use Cypress to achieve this using a regex string (the first example in this Cypress FAQ is like yours):

Cypress.Commands.add('currency', (selector) => {
      cy.get(selector)
        .should('have.text', '\d+[\u00A0]*')
    });

You can test out the regex here: https://regex101.com/r/YC4szy/1. It will match strings with a number, followed by a blank space, and any subsequent characters. You can get fancy with the regex to test what you want.

My last suggestion, if matching regex patterns doesn't help, is that you can wrap your cypress command in a function that takes text content as an argument, which you pass into the should('have.text', ...) line.

Wilser answered 31/3, 2021 at 22:4 Comment(3)
Your regex is a bit suspect, only matching the 4 digits not the nbsp.Billion
You can see here regex101.com/r/YC4szy/1 that the nbsp is detected in Javascript environments.If you need the encoding for another language, you can play around with it in that link (by changing Flavor on the left) and substituting in the correct nbsp encoded character: fileformat.info/info/unicode/char/00a0/index.htm (see Encodings section).Wilser
The other language needed for your example to work is HTML. Unfortunately, that's not an option on regex101.com.Billion
S
1

  is a non breaking space which isn't the same as a "regular" breaking space:

const read = sel => document.querySelector(sel).textContent;

console.log(read('div') === '1 000 kr'); // false!
<div>1&nbsp;000 kr</div>

These two whitespace characters actually have different ascii code:

const read = sel => document.querySelector(sel).textContent;
const strencode = str => [...str].map(c => c.charCodeAt(0)).join('\t');

console.log(strencode('1 000 kr'));
console.log(strencode(read('div')));
<div>1&nbsp;000 kr</div>

See how the second characters differ?

You can normalise the strings with String#normalize:

const read = sel => document.querySelector(sel).textContent;

console.log(read('div').normalize('NFKC') === '1 000 kr')
<div>1&nbsp;000 kr</div>

So here's one possible answer to your question:

  1. Normalize your string
  2. Remove all spaces (ascii 32) characters with / /g
  3. Remove 'kr' at the end

const read = sel => document.querySelector(sel).textContent;
const clean = str => str.normalize('NFKC').replace(/ /g, '').replace(/kr$/, '');

console.log(clean(read('#div1')));
console.log(clean(read('#div2')));
<div id="div1">1&nbsp;000 kr</div>
<div id="div2">10&nbsp;000</div>
Smelser answered 31/3, 2021 at 22:24 Comment(0)
C
1

Please see How is a non-breaking space represented in a JavaScript string?

When doing .text(), all HTML entities are decoded to their character values.

Instead of comparing using the entity, compare using the actual raw character

if (x == '\xa0') { // Non-breakable space is char 0xa0 (160 dec)

This would be the expression you are looking for

+text.replace('kr', '')  
  .replace('\xa0', '')
  .trim()

Tested with

<div>1&nbsp;100 kr</div>
Colonel answered 31/3, 2021 at 22:34 Comment(0)
B
1

To illustrate the idea from @evolutionxbox, you can use a regex on element.innerText to replace non-breaking spaces.

Cypress.Commands.add('currency', (selector) => {
  cy.get(selector)   
    .children()
    .eq(1) 
    .then($el => +$el[0].innerText.replace(/\s/g, '').replace('kr', '') )
})
Billion answered 1/4, 2021 at 12:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.