Jsdom: Error: Not implemented: HTMLFormElement.prototype.submit

Created on 10 Aug 2017  ·  21Comments  ·  Source: jsdom/jsdom

Error

HTMLInputElement {} HTMLInputElement {}
Error: Not implemented: HTMLFormElement.prototype.submit
    at module.exports (/home/xlmnxp/Documents/Nodejs/DownFrom99/node_modules/jsdom/lib/jsdom/browser/not-implemented.js:9:17)
    at HTMLFormElementImpl.submit (/home/xlmnxp/Documents/Nodejs/DownFrom99/node_modules/jsdom/lib/jsdom/living/nodes/HTMLFormElement-impl.js:68:5)
    at HTMLFormElement.submit (/home/xlmnxp/Documents/Nodejs/DownFrom99/node_modules/jsdom/lib/jsdom/living/generated/HTMLFormElement.js:18:21)
    at /home/xlmnxp/Documents/Nodejs/DownFrom99/app.js:12:10
    at process._tickCallback (internal/process/next_tick.js:109:7) undefined
import { JSDOM } from "jsdom";

JSDOM.fromURL("http://localhost/").then((dom:JSDOM) => {
    let document = dom.window.document;
    let window = dom.window;

    let form = <HTMLFormElement> document.querySelector("form");
    let urlField = <HTMLInputElement> document.querySelector("input[name='formvalue']");
    let submitButton = <HTMLInputElement> document.querySelector("input[type='submit']");

    console.log(submitButton,urlField)

    urlField.value = "https://www.youtube.com/watch?v=RWjDLfx8Lww";

    form.submit()

})

Most helpful comment

Ran into this when writing tests using Jest.
My workaround:

window.HTMLFormElement.prototype.submit = () => {}

Added this before I mount my component in the test case.
At least it keeps my console clean.

All 21 comments

Yes, indeed, form submission is not implemented. This is working as expected.

@runbb did you find another solution for this? I am trying to do the same thing.

@domenic do you have any ideas on how to accomplish this functionality? Perhaps another library?

@stefanbuck no :(

@domenic is there a reason why this is unimplemented? Would you be open to a pull request to implement this?

See https://github.com/jsdom/jsdom#unimplemented-parts-of-the-web-platform. This is about navigation, and thus a huge undertaking. You're welcome to try, but please understand you'd need to be implementing basically all of https://html.spec.whatwg.org/multipage/browsing-the-web.html.

@domenic it would be nice to disable this error message.

You can do so; see the readme on jsdomErrors.

Is it still possible to implement the handling of the inputs when the form is submitted?
event.target[name] are not defined.

My workaround for now is form.dispatchEvent(new Event('submit'));

Ran into this when writing tests using Jest.
My workaround:

window.HTMLFormElement.prototype.submit = () => {}

Added this before I mount my component in the test case.
At least it keeps my console clean.

I managed to silence the errors by doing:

describe('submit', () => {
  let emit;

  beforeAll(() => {
    ({ emit } = window._virtualConsole);
  });

  beforeEach(() => {
    window._virtualConsole.emit = jest.fn();
  });

  afterAll(() => {
    window._virtualConsole.emit = emit;
  });

  it('should handle submit ', () => {
    ...
  });
});

Ran into this when writing tests using Jest.
My workaround:

window.HTMLFormElement.prototype.submit = () => {}

Added this before I mount my component in the test case.
At least it keeps my console clean.

Hi! I like your workaround but I am not sure where to do that, you thing you could help maybe? I have the following code: (see I added your "fix" as the first statement in main())

const jsdom = require("jsdom");
const { JSDOM } = jsdom;

JSDOM.fromFile("index.html", null).then(dom => {
    main(dom.window);
});

function main(window){

  window.HTMLFormElement.prototype.submit = () => {}

  var oldAlert = window.alert;
  window.alert = function() {
    console.log("Alert fired with arguments: " + arguments);
    oldAlert.apply(window, arguments);
  };

  window.document.getElementsByTagName("button")[0].click();

}

but it is still raising the same Error: Not implemented: HTMLFormElement.prototype.submit

Possible solution:

// Following code mocks window.console.error
// to ignore the "Not implemented: HTMLFormElement.prototype.submit".
//
// Problem: We use "form.onsubmit" event listener in some tests,
// but HTMLFormElement.prototype.submit is not implemented in JSDOM,
// although the tests are passing and handler fires.
//
// More:
// https://github.com/jsdom/jsdom/issues/1937
// https://github.com/facebook/jest/issues/5223#issuecomment-489422244

let origErrorConsole;

beforeEach(() => {
  origErrorConsole = window.console.error;

  window.console.error = (...args) => {
    const firstArg = args.length > 0 && args[0];

    const shouldBeIgnored =
      firstArg &&
      typeof firstArg === 'string' &&
      firstArg.includes('Not implemented: HTMLFormElement.prototype.submit');

    if (!shouldBeIgnored) {
      origErrorConsole(...args);
    }
  }
})

afterEach(() => {
  window.console.error = origErrorConsole;
})

If you don't care about the submit you can also disable submitting the form with

<form onsubmit="return false;">

No more error message

Possible solution:

// Following code mocks window.console.error
// to ignore the "Not implemented: HTMLFormElement.prototype.submit".
//
// Problem: We use "form.onsubmit" event listener in some tests,
// but HTMLFormElement.prototype.submit is not implemented in JSDOM,
// although the tests are passing and handler fires.
//
// More:
// https://github.com/jsdom/jsdom/issues/1937
// https://github.com/facebook/jest/issues/5223#issuecomment-489422244

let origErrorConsole;

beforeEach(() => {
  origErrorConsole = window.console.error;

  window.console.error = (...args) => {
    const firstArg = args.length > 0 && args[0];

    const shouldBeIgnored =
      firstArg &&
      typeof firstArg === 'string' &&
      firstArg.includes('Not implemented: HTMLFormElement.prototype.submit');

    if (!shouldBeIgnored) {
      origErrorConsole(...args);
    }
  }
})

afterEach(() => {
  window.console.error = origErrorConsole;
})

This solution breaks stacktrace of real error and it'll be harder to find them.

Before
image

After
image

If you use a virtual console and listen for "jsdomError"s you should get an exception object with a stack trace.

@domenic, could you please show us how to use a virtual console from the test file itself?

Let's suggest that the test file is next

import React from 'react'

import {render} from '@testing-library/react'

import ComponentWithSubmit from './ComponentWithSubmit'

test('Component with form', () => {
  const {getByText} = render(<ComponentWithSubmit />)
  expect(getByText('I am inside form')).toBeInTheDocument()
})

P.S: there is jest as a test runner

Sorry, you'll need to ask Jest for support on how to use Jest. The jsdom is only able to provide support for jsdom itself, not for any package that uses jsdom as a dependency.

I had a component using a form but not using submit on the form and was still seeing this error. I solved it by adding type="button" to my other buttons within the form.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Progyan1997 picture Progyan1997  ·  3Comments

potapovDim picture potapovDim  ·  4Comments

josephrexme picture josephrexme  ·  4Comments

eszthoff picture eszthoff  ·  3Comments

kentmw picture kentmw  ·  3Comments