recurly / recurly-js

Simple subscription billing in the browser
https://js.recurly.com/
MIT License
645 stars 138 forks source link

Unable to edit last digit on LGTV #677

Closed jlilly closed 3 years ago

jlilly commented 3 years ago

On LG smart TVs (2016 and newer), users cannot edit the last digit of a card number grouping.

Demo app and device specific setup steps here: https://github.com/jlilly/recurly-lgtv

Steps to Reproduce:

  1. Type '4111 1111 1111 1111' into the card number field
  2. Delete last character
  3. Try to type any other number into the card number field

Results:

User is unable to edit the last digit

Expected Results:

User should be able to edit the last digit of the card number

This seems to happen on last digit of a grouping, EG: 411x, 4111 111x, 4111 1111 111x and 4111 1111 1111 111x. Suspect other card types would be affected as well with a similar pattern.

Work around:

There are two ugly workarounds:

  1. The user can delete another digit, They then can enter digits into the card number field again. However, if the user deletes enough digits, they can hit the same issue again -- see above
  2. The user can focus onto another part of the form and then come back to the card number field. Blurring and refocusing allows the last digit to be added

LG uses a virtual keyboard that differs from a traditional keyboard in a few ways. It is detailed here

Devices tested on: 2019 LG TV Model: 49SM8600PUA OS Version: 05.00.15 SDK Version: 4.9.0 User Agent: Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.34 Safari/537.36 WebAppManager

2018 LG TV Modal: 43UK6300PUE OS Version: 05.30.10 SDK Version: 4.3.0 User Agent: Mozilla/5.0 (Web0S; Linux/SmartTV) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.34 Safari/537.36 WebAppManager

LG TV dev setup

chrissrogers commented 3 years ago

Hi! I've had the chance to test this scenario out using LG's webos emulator for the 6.x series, and thus far have been able to delete chars and re-type new ones onto the end of strings like 4111 1111 1111 111x and the sub-segments therein.

I'll try further on the 4.x series, but suspect this may be a bug on the 4.x (and potentially on 5.x) series.. which makes the potential for a workaround less likely, but still certainly possible. I understand that steep upgrade paths (buying a new TV, by my read) make it less likely that folks are on the latest version.

chrissrogers commented 3 years ago

Further, I would like to thank you for the extremely detailed report here. It's incredibly helpful and appreciated!

jlilly commented 3 years ago

Hey Chris! Thanks for getting to this bug. If you curious to know the mappings between model years and OS / SDK version you can see that here: https://webostv.developer.lge.com/discover/specifications/web-engine/

If you need any help testing on the device, please feel free to reach out.

chrissrogers commented 3 years ago

It appears the root scenario here is due to WebOS 4.x series not firing the keydown event when using the on-screen numeric keypad, but will do so for the backspace button on the on-screen keypad. The formatting library relies on the keydown event to make formatting decisions following backspaces, in order to remove things like whitespace in the input field, and there is an element of statefulness that carries over to the next keydown event in order to determine where to position the cursor and what whitespace to introduce. Thus, two backspace presses (firing the two underlying keydown events) will complete the cycle, but one backspace followed by a numeric button press (firing only one underlying keydown event) will not complete the cycle. But yes unfortunately, keydown events are not dispatched as they would in every other device environment.

Thus far I don't have a resolution that doesn't result in brittleness to the formatting system.

One potential workaround I can suggest is to detect WebOS 4.x and use multiple Elements (separate number, month, year, and cvv) with formatting disabled for the CardNumberElement in that case.

jlilly commented 3 years ago

Chris,

Thanks for the workaround.

Where is the card number formatting code? I would like to try to see if listening on input events would fix the issue on WebOS devices. It is desirable to keep the card number formatted for obvious reasons, I wonder if we can expose a feature flag to use an alternative formatting solution if something along the lines of the input listener works. Or allow the consumer of the library the ability to specify when to run the formatter -- EG on blur. The upside would be that non-standard devices, cough TVs cough, could then have the ability to work around platform oddities.

chrissrogers commented 3 years ago

The trouble with the input event is that it fires after the value in the input has changed, where the formatting routines do need a prior interruption in order to avoid latent reformatting.

I think your suggestion of allowing some more customization sentinels is a good call, though. We of course have to be careful with formatting systems because of the data being formatting, but flags for certain routine behaviors would work fine as a feature request here.

As for the routines themselves. Those exist in an internal library which manages the internal frame behaviors of Elements. It's certainly possible to introspect those from within a browser debugger or the TV emulator remote debugger, so that you can get an idea of how it's behaving. A breakpoint onto the change or keydown events there will take you down the path of formatting decision-making. We use a derivation of the cleave library for card number formats, and can accept upstream updates from their main fork.