Skip to content

typeIn not taking caret position into account prior to inputting characters. #1535

Open
@ErvinSabic

Description

@ErvinSabic

I am creating a number input that formats as the user types for https://github.com/CrowdStrike/ember-headless-form.

The component on my own branch - https://github.com/ErvinSabic/ember-headless-form/blob/main/packages/ember-headless-form/src/-private/components/control/local-number.gts

I wrote the following test:

  test("multiple decimals are handled", async function(assert) {
    const options = {
      style: "currency",
      currency: "USD"
    };

    await render(
      <template>
        <HeadlessForm as |form|>
          <form.Field @name="localNum" as |field|>
            <field.LocalNumber
              @locale="en-US"
              @formatOptions={{options}}
              @value="0.00"
            />
          </form.Field>
        </HeadlessForm>
      </template>
    );

    let input = this.element.querySelector("input") as HTMLInputElement;

    // For example, typing "123.45.67" should result in a properly formatted value.
    await typeIn("input", "12345");
    // $123.45|
    console.log(input.value);
    console.log(input.selectionStart);
    await typeIn("input", ".");
    // Should skip the caret to the decimal like so:
    // $123.|45
    console.log(input.value);
    console.log(input.selectionStart);
    await typeIn("input", "67");
    // The numbers should start pushing left. It should look like this:
    // $12,367.|45
    console.log(input.value);
    console.log(input.selectionStart);

    // Adjust the expected value to what your implementation should yield.
    assert.strictEqual(input.value, "$12,367.45", "Extra decimals are collapsed to a single decimal");
  });

Which in my console after testing outputted the following:

test-app:test: not ok 53 Chrome 133.0 - [487 ms] - Integration Component HeadlessForm > Local Number: multiple decimals are handled
test-app:test:     ---
test-app:test:         actual: >
test-app:test:             $12,345.67
test-app:test:         expected: >
test-app:test:             $12,367.45
test-app:test:         stack: >
test-app:test:                 at Object.<anonymous> (http://localhost:4203/assets/tests.js:1833:14)
test-app:test:         message: >
test-app:test:             Extra decimals are collapsed to a single decimal
test-app:test:         negative: >
test-app:test:             false
test-app:test:         browser log: |
test-app:test:             {"type":"log","text":"$123.45"}
test-app:test:             {"type":"log","text":"7"}
test-app:test:             {"type":"log","text":"$123.45"}
test-app:test:             {"type":"log","text":"5"}
test-app:test:             {"type":"log","text":"$12,345.67"}
test-app:test:             {"type":"log","text":"10"}
test-app:test:     ...

Based on the output it appears to me that typeIn skips to the end of the input when it begins typing unless it is overriden by some repositioning logic. (Like the extra decimal I input that would cause a shift to the current decimal position) however it goes right back to the end of the input if it's a normal input that has no repositioning logic (like the numbers, "67"). This causes unexpected test results if the location for the caret changes based on the logic of the component you are testing. Caret position should be preserved between inputs like it would be for a user typing into the form.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions