playwright icon indicating copy to clipboard operation
playwright copied to clipboard

[Feature] Change whitespace returned using .inputValue() from nbsp to regular spaces.

Open kLjubomir opened this issue 1 year ago • 3 comments

Relates to issue: https://github.com/microsoft/playwright/issues/23037

When using .inputValue() on an input text field which contains a whitespace, the whitespace is treated as charCode 160 or a nbsp. This causes issues with the string returned from .inputValue(), as using it in an expect statement or even just a regular equality operator from a programming language will cause inequality issues, for example "4038 1501 1441 384" fetched from inputValue() will throw false when compared to ""4038 1501 1441 384" written as a string.

It would seem the implementation of .inputValue() actions is actually fetching innerText, which in the majority of use cases will cause more issues then benefits.

This can affect cases like checking if the app parses credit card text and transforms the input into the whitespace separated input and similar forms of frontend transformation, where in the tests the retreived inputValue() could be evaluated for business logic.

Usually if tasked with validating the HTML values of characters it would make more sense to go with innerText, the inputValue would make more sense if it returned a regular whitespace with charCode 32

kLjubomir avatar May 18 '23 08:05 kLjubomir

if we make .inputValue() to inputValue().toString() will this work?

syedddanishalinaqvi avatar May 18 '23 16:05 syedddanishalinaqvi

The .toString() method in JavaScript converts a value to a string, but it does not change the actual content of the string. In this case, calling .toString() on the return value of .inputValue() will not replace the non-breaking space character with a regular space character.

We can normalize the string before comparing. When comparing strings fetched from .inputValue() and hardcoded strings, consider normalizing these strings to account for non-breaking spaces. Here is a code snippet using JavaScript. Let me know if we can use it like this.

let inputValue = someElement.inputValue(); // returns "4038 1501 1441 384"
let hardcodedValue = "4038 1501 1441 384";

// normalize both strings to replace non-breaking spaces with regular spaces
inputValue = inputValue.replace(/\u00A0/g, " ");
hardcodedValue = hardcodedValue.replace(/\u00A0/g, " ");

// now you should be able to compare them without issue
console.log(inputValue === hardcodedValue); // true

ArunVatsyayan avatar May 18 '23 17:05 ArunVatsyayan

I have found the replace regex solution before opening this Feature request. The request is made because logically there are many more use cases for fetching an elements input with normalized whitespace than there would be cases where html specific elements are the subject to assertions. In those rare cases where I was tasked to assert unicode or character codes of an application, I saw it fit to use the jQuery's element.innerText implementation. If nothing else then it would make sense to have a Playwright function that fetches innerText as in HTML characters as a separate function, or have parameters in inputValue({type: html}) that would specify the treatment of characters that were returned from a string.

Since the documentation of inputValue does not in any way suggest that the returned string is treated as an html element it was not as easy discovering what is causing the issue, Half a day of debugging and asserting returned values both with Playwright functions and just regular JavaScript comparisons and then making a loop from the text to print it's charCode finally revealed the implementation I would have never thought was used.

kLjubomir avatar May 19 '23 08:05 kLjubomir

Let me close this in favor of #23037, and we can continue the discussion there.

dgozman avatar May 22 '23 16:05 dgozman