Jsdom: Erro: Não implementado: HTMLFormElement.prototype.submit

Criado em 10 ago. 2017  ·  21Comentários  ·  Fonte: jsdom/jsdom

Erro

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()

})

Comentários muito úteis

Encontrei isso ao escrever testes usando Jest.
Minha solução alternativa:

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

Adicionado isso antes de montar meu componente no caso de teste.
Pelo menos mantém meu console limpo.

Todos 21 comentários

Sim, de fato, o envio do formulário não foi implementado. Isso está funcionando conforme o esperado.

@runbb você encontrou outra solução para isso? Eu estou tentando fazer a mesma coisa.

@domenic , você tem alguma ideia de como realizar essa funcionalidade? Talvez outra biblioteca?

@stefanbuck no :(

@domenic há uma razão para isso não ser implementado? Você estaria aberto a uma solicitação pull para implementar isso?

Consulte https://github.com/jsdom/jsdom#unimplemented -parts-of-the-web-platform. Trata-se de navegação e, portanto, de um grande empreendimento. Você pode tentar, mas entenda que você precisa implementar basicamente todos os https://html.spec.whatwg.org/multipage/browsing-the-web.html.

@domenic , seria bom desativar essa mensagem de erro.

Você pode fazer isso; veja o readme em jsdomErrors.

Ainda é possível implementar o tratamento das entradas quando o formulário é enviado?
event.target[name] não estão definidos.

Minha solução agora é form.dispatchEvent(new Event('submit'));

Encontrei isso ao escrever testes usando Jest.
Minha solução alternativa:

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

Adicionado isso antes de montar meu componente no caso de teste.
Pelo menos mantém meu console limpo.

Consegui silenciar os erros fazendo:

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

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

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

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

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

Encontrei isso ao escrever testes usando Jest.
Minha solução alternativa:

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

Adicionado isso antes de montar meu componente no caso de teste.
Pelo menos mantém meu console limpo.

Oi! Eu gosto da sua solução alternativa, mas não tenho certeza de onde fazer isso, você acha que poderia ajudar, talvez? Eu tenho o seguinte código: (veja eu adicionei sua "correção" como a primeira instrução em 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();

}

mas ainda está levantando o mesmo Error: Not implemented: HTMLFormElement.prototype.submit

Solução possível:

// 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;
})

Se você não se importa com submit você também pode desativar o envio do formulário com

<form onsubmit="return false;">

Não há mais mensagem de erro

Solução possível:

// 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;
})

Esta solução quebra o rastreamento de pilha de erros reais e será mais difícil encontrá-los.

Antes
image

Depois de
image

Se você usar um console virtual e ouvir "jsdomError" s, deverá obter um objeto de exceção com rastreamento de pilha.

@domenic , você poderia nos mostrar como usar um console virtual a partir do próprio arquivo de teste?

Vamos sugerir que o arquivo de teste seja o próximo

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()
})

PS: há uma piada como executor de testes

Desculpe, você precisará pedir a Jest para obter suporte sobre como usar o Jest. O jsdom só é capaz de fornecer suporte para o próprio jsdom, não para qualquer pacote que use o jsdom como dependência.

Tive um componente usando um formulário, mas não usando enviar no formulário e ainda estava vendo este erro. Resolvi isso adicionando type = "button" aos meus outros botões no formulário.

Esta página foi útil?
0 / 5 - 0 avaliações