Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error on change event in form on custom element #137

Open
domingo2000 opened this issue Dec 4, 2024 · 1 comment
Open

Error on change event in form on custom element #137

domingo2000 opened this issue Dec 4, 2024 · 1 comment

Comments

@domingo2000
Copy link

domingo2000 commented Dec 4, 2024

When using the pollyfill for JSDom tests i am getting an error when sending dispatch events to the parent form of custom control created using WebComponent with ElementInternals.

I suspect the error is in src/utils.ts on method #formChangeCallback and #formInputCallback that have the following implementation.

/**
 * The global form input callback. Updates the form's validity
 * attributes on input.
 * @param {Event} - The form input event
 * @return {void}
 */
export const formInputCallback = (event: Event) => {
  setFormValidity(findParentForm(event.target));
};

/**
 * The global form change callback. Updates the form's validity
 * attributes on change.
 * @param {Event} - The form change event
 * @return {void}
 */
 export const formChangeCallback = (event: Event) => {
  setFormValidity(findParentForm(event.target));
};

The event hiven to those methods are the form events, so when it calls findParentForm(event.target) the target is null and the error cascades passing the null value to the setFormValidity method.

I added how to replicate and the error trace for eassier debugging.

I need the pollyfill to work on tests because JSDom currently does not support ElementInternals, so i cannot test my components propperly when building custom controls that propagate the events to the form.

Error

❯ pnpm vitest error.test.js
The CJS build of Vite's Node API is deprecated. See https://vite.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.

 DEV  v2.1.8 /home/domingo/buk/replicate-error-polyfill

stdout | error.test.js > element internals polyfill error on custom element form input events
HTMLFormElement {
  [Symbol(SameObject caches)]: [Object: null prototype] { elements: HTMLFormControlsCollection {} }
}

stderr | error.test.js > element internals polyfill error on custom element form input events
Error: Uncaught [TypeError: Cannot read properties of null (reading 'elements')]
    at reportException (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:66:24)
    at innerInvokeEventListeners (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:353:9)
    at invokeEventListeners (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3)
    at HTMLFormElementImpl._dispatch (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9)
    at HTMLFormElementImpl.dispatchEvent (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17)
    at HTMLFormElement.dispatchEvent (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34)
    at /home/domingo/buk/replicate-error-polyfill/error.test.js:35:10
    at file:///home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js:146:14
    at file:///home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js:533:11
    at runWithTimeout (file:///home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js:39:7) TypeError: Cannot read properties of null (reading 'elements')
    at setFormValidity (file:///home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/element-internals-polyfill/dist/index.js:259:55)
    at HTMLFormElement.formChangeCallback (file:///home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/element-internals-polyfill/dist/index.js:274:9)
    at HTMLFormElement.callTheUserObjectsOperation (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30)
    at innerInvokeEventListeners (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:350:25)
    at invokeEventListeners (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3)
    at HTMLFormElementImpl._dispatch (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9)
    at HTMLFormElementImpl.dispatchEvent (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17)
    at HTMLFormElement.dispatchEvent (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34)
    at /home/domingo/buk/replicate-error-polyfill/error.test.js:35:10
    at file:///home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js:146:14 {
  stackStr: "TypeError: Cannot read properties of null (reading 'elements')\n" +
    '    at setFormValidity (file:///home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/element-internals-polyfill/dist/index.js:259:55)\n' +
    '    at HTMLFormElement.formChangeCallback (file:///home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/element-internals-polyfill/dist/index.js:274:9)\n' +
    '    at HTMLFormElement.callTheUserObjectsOperation (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30)\n' +
    '    at innerInvokeEventListeners (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:350:25)\n' +
    '    at invokeEventListeners (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3)\n' +
    '    at HTMLFormElementImpl._dispatch (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9)\n' +
    '    at HTMLFormElementImpl.dispatchEvent (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17)\n' +
    '    at HTMLFormElement.dispatchEvent (/home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34)\n' +
    '    at /home/domingo/buk/replicate-error-polyfill/error.test.js:35:10\n' +
    '    at file:///home/domingo/buk/replicate-error-polyfill/node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js:146:14',
  nameStr: 'TypeError',
  expected: 'undefined',
  actual: 'undefined'
}

 ✓ error.test.js (1)
   ✓ element internals polyfill error on custom element form input events

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Uncaught Exception ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
TypeError: Cannot read properties of null (reading 'elements')
 ❯ setFormValidity node_modules/.pnpm/[email protected]/node_modules/element-internals-polyfill/dist/index.js:259:55
    257|     };
    258|     const setFormValidity = (form) => {
    259|         const nativeControlValidity = Array.from(form.elements)
       |                                                       ^
    260|             .filter((element) => !element.tagName.includes('-') && element.validity)
    261|             .map((element) => element.validity.valid);
 ❯ HTMLFormElement.formChangeCallback node_modules/.pnpm/[email protected]/node_modules/element-internals-polyfill/dist/index.js:274:9
 ❯ HTMLFormElement.callTheUserObjectsOperation node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30
 ❯ innerInvokeEventListeners node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:350:25
 ❯ invokeEventListeners node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3
 ❯ HTMLFormElementImpl._dispatch node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9
 ❯ HTMLFormElementImpl.dispatchEvent node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17
 ❯ HTMLFormElement.dispatchEvent node_modules/.pnpm/[email protected]/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34
 ❯ error.test.js:35:10
 ❯ node_modules/.pnpm/@[email protected]/node_modules/@vitest/runner/dist/index.js:146:14

This error originated in "error.test.js" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
The latest test that might've caused the error is "element internals polyfill error on custom element form input events". It might mean one of the following:
- The error was thrown, while Vitest was running this test.
- If the error occurred after the test had been completed, this was the last documented test before it was thrown.
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 Test Files  1 passed (1)
      Tests  1 passed (1)
     Errors  1 error
   Start at  17:58:34
   Duration  521ms (transform 19ms, setup 11ms, collect 8ms, tests 27ms, environment 305ms, prepare 51ms)

 FAIL  Tests failed. Watching for file changes...

How to replicate

setup.js on vitest loads the pollifyll before.

import "element-internals-polyfill"
/**
 * @vitest-environment jsdom
 */
import { test } from "vitest";

class DummyElement extends HTMLElement {
    static formAssociated = true;

    constructor() {
      super();
      this.attachShadow({ mode: "open" });
      this.internals_ = this.attachInternals();
      this.value_ = this.getAttribute("value");
    }

    connectedCallback() {
      this.innerHTML = "<div>dummy element</div>";
    }
  }

customElements.define("dummy-element", DummyElement);


test("element internals polyfill error on custom element form input events", () => {
    document.body.innerHTML = `
    <form>
        <dummy-element value="lorem"></dummy-element>
    </form>
    `;
    const element = document.querySelector("dummy-element");
    const form = document.querySelector("form");
    console.log(element.internals_.form);

    // Bug occurs dispatching change event to form element
    form.dispatchEvent(new Event("change"));
});
@calebdwilliams
Copy link
Owner

calebdwilliams commented Dec 4, 2024

Happy to field a PR for this but I might not have time to do it myself for a couple weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants