Jsdom: 였λ₯˜: κ΅¬ν˜„λ˜μ§€ μ•ŠμŒ: HTMLFormElement.prototype.submit

에 λ§Œλ“  2017λ…„ 08μ›” 10일  Β·  21μ½”λ©˜νŠΈ  Β·  좜처: jsdom/jsdom

였λ₯˜

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

})

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

Jestλ₯Ό μ‚¬μš©ν•˜μ—¬ ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•  λ•Œ 이 λ¬Έμ œμ— λΆ€λ”ͺμ³€μŠ΅λ‹ˆλ‹€.
λ‚΄ ν•΄κ²° 방법:

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

ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ— ꡬ성 μš”μ†Œλ₯Ό λ§ˆμš΄νŠΈν•˜κΈ° 전에 이것을 μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€.
적어도 λ‚΄ μ½˜μ†”μ„ κΉ¨λ—ν•˜κ²Œ μœ μ§€ν•©λ‹ˆλ‹€.

λͺ¨λ“  21 λŒ“κΈ€

예, μ‹€μ œλ‘œ 양식 μ œμΆœμ€ κ΅¬ν˜„λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ˜ˆμƒλŒ€λ‘œ μž‘λ™ν•©λ‹ˆλ‹€.

@runbb 이에 λŒ€ν•œ λ‹€λ₯Έ 해결책을 μ°Ύμ•˜μŠ΅λ‹ˆκΉŒ? 같은 일을 ν•˜λ €κ³  ν•©λ‹ˆλ‹€.

@domenic 이 κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ” 방법에 λŒ€ν•œ 아이디어가 μžˆμŠ΅λ‹ˆκΉŒ? μ•„λ§ˆλ„ λ‹€λ₯Έ λ„μ„œκ΄€?

@stefanbuck μ•„λ‹ˆμš” :(

@domenic 이것이 κ΅¬ν˜„λ˜μ§€ μ•Šμ€ μ΄μœ κ°€ μžˆμŠ΅λ‹ˆκΉŒ? 이것을 κ΅¬ν˜„ν•˜κΈ° μœ„ν•œ ν’€ λ¦¬ν€˜μŠ€νŠΈλ₯Ό μˆ˜λ½ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?

https://github.com/jsdom/jsdom#unimplemented -parts-of-the-web-platform을 μ°Έμ‘° https://html.spec.whatwg.org/multipage/browsing-the-web.html을 κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€λŠ” 점을 이해해 μ£Όμ‹­μ‹œμ˜€

@domenic 이 였λ₯˜ λ©”μ‹œμ§€λ₯Ό λΉ„ν™œμ„±ν™”ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

κ·Έλ ‡κ²Œ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. jsdomErrors에 λŒ€ν•œ μΆ”κ°€ 정보λ₯Ό μ°Έμ‘°ν•˜μ‹­μ‹œμ˜€.

양식이 제좜될 λ•Œ μž…λ ₯ 처리λ₯Ό κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆκΉŒ?
event.target[name] 이(κ°€) μ •μ˜λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

ν˜„μž¬ ν•΄κ²° 방법은 form.dispatchEvent(new Event('submit'));

Jestλ₯Ό μ‚¬μš©ν•˜μ—¬ ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•  λ•Œ 이 λ¬Έμ œμ— λΆ€λ”ͺμ³€μŠ΅λ‹ˆλ‹€.
λ‚΄ ν•΄κ²° 방법:

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

ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ— ꡬ성 μš”μ†Œλ₯Ό λ§ˆμš΄νŠΈν•˜κΈ° 전에 이것을 μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€.
적어도 λ‚΄ μ½˜μ†”μ„ κΉ¨λ—ν•˜κ²Œ μœ μ§€ν•©λ‹ˆλ‹€.

λ‹€μŒμ„ μˆ˜ν–‰ν•˜μ—¬ 였λ₯˜λ₯Ό 숨길 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

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

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

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

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

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

여기에 쒋은 ν•΄κ²° 방법이 μžˆμŠ΅λ‹ˆλ‹€. https://kula.blog/posts/test_on_submit_in_react_testing_library/

Jestλ₯Ό μ‚¬μš©ν•˜μ—¬ ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•  λ•Œ 이 λ¬Έμ œμ— λΆ€λ”ͺμ³€μŠ΅λ‹ˆλ‹€.
λ‚΄ ν•΄κ²° 방법:

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

ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ— ꡬ성 μš”μ†Œλ₯Ό λ§ˆμš΄νŠΈν•˜κΈ° 전에 이것을 μΆ”κ°€ν–ˆμŠ΅λ‹ˆλ‹€.
적어도 λ‚΄ μ½˜μ†”μ„ κΉ¨λ—ν•˜κ²Œ μœ μ§€ν•©λ‹ˆλ‹€.

μ•ˆλ…•ν•˜μ„Έμš”! ν•΄κ²° 방법이 λ§ˆμŒμ— λ“€μ§€λ§Œ μ–΄λ””μ„œ ν•΄μ•Ό 할지 잘 λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€. λ„μ™€μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ? λ‹€μŒ μ½”λ“œκ°€ μžˆμŠ΅λ‹ˆλ‹€. (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();

}

ν•˜μ§€λ§Œ μ—¬μ „νžˆ 같은 Error: Not implemented: HTMLFormElement.prototype.submit λͺ¨μœΌκ³  μžˆμŠ΅λ‹ˆλ‹€.

κ°€λŠ₯ν•œ ν•΄κ²°μ±…:

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

submit 에 λŒ€ν•΄ μ‹ κ²½ 쓰지 μ•ŠλŠ”λ‹€λ©΄ λ‹€μŒμ„ μ‚¬μš©ν•˜μ—¬ 양식 μ œμΆœμ„ λΉ„ν™œμ„±ν™”ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

<form onsubmit="return false;">

더 이상 였λ₯˜ λ©”μ‹œμ§€ μ—†μŒ

κ°€λŠ₯ν•œ ν•΄κ²°μ±…:

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

이 μ†”λ£¨μ…˜μ€ μ‹€μ œ 였λ₯˜μ˜ μŠ€νƒ 좔적을 κΉ¨κ³  μ°ΎκΈ°κ°€ 더 μ–΄λ €μšΈ κ²ƒμž…λ‹ˆλ‹€.

전에
image

후에
image

가상 μ½˜μ†” 을 μ‚¬μš©ν•˜κ³  "jsdomError" λ₯Ό μˆ˜μ‹ ν•˜λŠ” 경우 μŠ€νƒ 좔적이 μžˆλŠ” μ˜ˆμ™Έ 개체λ₯Ό 가져와야 ν•©λ‹ˆλ‹€.

@domenic , ν…ŒμŠ€νŠΈ 파일 μžμ²΄μ—μ„œ 가상 μ½˜μ†”μ„ μ‚¬μš©ν•˜λŠ” 방법을 μ•Œλ €μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ?

ν…ŒμŠ€νŠΈ 파일이 λ‹€μŒμž„μ„ μ œμ•ˆν•©μ‹œλ‹€.

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

μΆ”μ‹ : ν…ŒμŠ€νŠΈ λŸ¬λ„ˆλ‘œμ„œ 농담이 μžˆμŠ΅λ‹ˆλ‹€.

μ£„μ†‘ν•©λ‹ˆλ‹€. Jest μ‚¬μš© 방법에 λŒ€ν•œ 지원을 Jest에 μš”μ²­ν•΄μ•Ό ν•©λ‹ˆλ‹€. jsdom은 jsdom을 μ’…μ†μ„±μœΌλ‘œ μ‚¬μš©ν•˜λŠ” νŒ¨ν‚€μ§€κ°€ μ•„λ‹Œ jsdom μžμ²΄μ— λŒ€ν•œ μ§€μ›λ§Œ μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

양식을 μ‚¬μš©ν•˜λŠ” ꡬ성 μš”μ†Œκ°€ μžˆμ§€λ§Œ μ–‘μ‹μ—μ„œ μ œμΆœμ„ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ° μ—¬μ „νžˆ 이 였λ₯˜κ°€ ν‘œμ‹œλ©λ‹ˆλ‹€. 양식 λ‚΄μ˜ λ‹€λ₯Έ λ²„νŠΌμ— type="button"을 μΆ”κ°€ν•˜μ—¬ 문제λ₯Ό ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰