JSDOMμ νμ¬ HTML5 μμ μ ν¨μ± κ²μ¬, νΉν checkValidity APIλ₯Ό μ²λ¦¬νμ§ μμ΅λλ€.
μ΄κ²μ HTML5 μμμ μ¬μ©νλ μ΅μ μμ© νλ‘κ·Έλ¨μ μ ννκ² ν μ€νΈνλ λ° νμν©λλ€.
http://www.thecssninja.com/javascript/h5f λ₯Ό μμμ μΌλ‘ μ¬μ©νμ¬ μ΄ μ§μμ μΆκ°ν μ μλμ§ κΆκΈν©λλ€. H5Fλ HTML5 μμ μ§μμ μ§μνμ§ μλ λΈλΌμ°μ μ μΆκ°νκΈ° μν λΈλΌμ°μ shimμ λλ€. μ μ³λκ³ , λκ΅°κ°κ° λμκ² κ°μ₯ μ’μ λ°©λ²μ μλ €μ€ μ μλ€λ©΄ μ΄ λμμ μ§μ μΆκ°ν μ μμ΄ κΈ°μ©λλ€.
λλ μ΄κ²μ΄ νλ₯νκ³ μ€μν κ²μ΄λΌλ λ° λμν©λλ€. κ·Έλ¬λ κ·Έκ²μ κ½€ μΌμ΄ λ κ²μ λλ€.
μ¬κΈ°μ νμν κ°μ₯ ν° κ²μ κ²¬κ³ ν ν μ€νΈ λͺ¨μμ λλ€. Contributing.md κ°μ΄λλΌμΈμ 보면 μ΄λμ μ°Ύμ μ μλμ§, μλλ©΄ μ°Ύμ μ μλμ§, μ΄λ€ λ©μΌλ§ 리μ€νΈμ λ¬Όμ΄λ΄μΌ νλμ§μ λν λͺ κ°μ§ μ§μΉ¨μ΄ μμ΅λλ€. νν€μΉ μ μλ€λ©΄ νΉν H5Fλ₯Ό μμμ μΌλ‘ μ¬μ©νμ¬ μ§μ ν κ²μ²λΌ μ΄λ₯Ό ꡬνν κΈ°νκ° μλ€κ³ μκ°ν©λλ€.
μ€μ ꡬνμμ μ μΌνκ² λ€λ₯Έ μ€μν λΆλΆμ DOM λ 벨 3 μ΄μμ ꡬννκΈ° μν μ μ ν "level4" λλ "html5" ν΄λκ° μλ€λ κ²μ λλ€. κ·Έλ¬λ κ·Έκ²μ μ μ λμ νμνκΈ° λλ¬Έμ μλν΄ λ³΄κ² μ΅λλ€. 빨리 μμνκΈ° μν΄.
:+1: νλ₯ν κΈ°λ₯μ΄ λ κ²μ λλ€.
μ§κΈμ jsdom μ€μ ν ν΄λ¦¬νλ‘ https://github.com/hyperform/hyperform μ μΆκ°νκ³ μμ΅λλ€. κ·Έκ²μ μ μλν©λλ€.
μΌ! μ λ Hyperformμ μ μμ λλ€. κ·Έλ¦¬κ³ μ΄μ΄ μ’μΌλ©΄ μ΄λ―Έ JSDomμ μ¬μ© νμ¬ ν μ€νΈ νκ²½μ μ€μ νμ΅λλ€ .
JSDom κ΄λ¦¬μμκ² ν₯λ―Έλ‘μΈ μ μλ λΆλΆ: μ μ ν μΉ νλ«νΌ ν μ€νΈλ₯Ό λ€λ£¨κΈ° μν΄ JSDom λ΄λΆμμλ Hyperformμ μ¬μ©νμ΅λλ€.
$ git diff test/web-platform-tests/create-jsdom.js
diff --git a/test/web-platform-tests/create-jsdom.js b/test/web-platform-tests/create-jsdom.js
index 7009df7..9edcb16 100644
--- a/test/web-platform-tests/create-jsdom.js
+++ b/test/web-platform-tests/create-jsdom.js
@@ -1,5 +1,6 @@
"use strict";
const jsdom = require("../..");
+const hyperform = require("hyperform");
const nodeResolverPromise = require("../util").nodeResolverPromise;
const globalPool = { maxSockets: 6 };
@@ -35,6 +36,9 @@ module.exports = (urlPrefix, testPath) => {
return created
.then(window => {
+ global.window = window;
+ global.document = window.document;
+ hyperform(window);
return new Promise((resolve, reject) => {
const errors = [];
test/web-platform-tests/index.js
μμ "html/semantics/forms/constraints/*.html"
ν
μ€νΈμ μ£Όμμ μ κ±°ν©λλ€.
λΆννλ λλ λ ΉμμΌλ‘ λ³νλ λͺ κ°μ§ ν μ€νΈ μΌμ΄μ€ λ§ κ°μ§κ³ μμ΅λλ€. κ·Έλ¬λ (μ΄λ€ μμΌλ‘λ ) Hyperformμ κΈ°λ₯μ JSDomμ μΆκ°νλ λ° κ΄μ¬μ΄ μλ€λ©΄
) ν΄λΉ ν
μ€νΈλ₯Ό ν΅κ³Όνκ³
b) μμ μμ€ API λ₯Ό μ μΈνλ λ²μ λλ ꡬμ±μ Hyperformμ μ 곡
FWIW, λλ μ΄κ²μ κ½€ κ΄μ¬μ΄ μμ΅λλ€. μ λ JSON μ€ν€λ§λ₯Ό κΈ°λ°μΌλ‘ μμμ λ λλ§νλ Vue κ΅¬μ± μμμμ μμ μ€μ΄λ©° Validity APIμ μμ‘΄νμ¬ μ μΆ μ μ ν¨μ± κ²μ¬ μνλ₯Ό μ°μΆν©λλ€. λ΄ λ¨μ ν μ€νΈλ Jest(νλμμ JSDOM μ¬μ©)λ‘ μ€νλμμΌλ©° νμ¬λ‘μλ μ΄ λΆλΆμ ν μ€νΈν μ μμ΅λλ€.
@Boldewyn μ κ²½μ°μ κ΄λ ¨νμ¬ μ μ μ¬νμ΄ μμΌλ©΄ κΈ°κΊΌμ΄ μλ½νκ² μ΅λλ€. μμνλ λ° λͺ κ°μ§ μ§μΉ¨μ΄ μ 곡λλ κ²½μ° μ΄λ₯Ό ꡬννλ λ° λμμ μ€ μλ μμ΅λλ€. :)
νΈμ§ : μλμμ @EricHenry μ μ루μ
μ μ¬μ©νλλ° μλνμ΅λλ€. HTMLInputElement
, HTMLSelectElement
λ° HTMLTextAreaElement
μλ checkValidity
λ₯Ό μ€μ ν΄μΌ νμ΅λλ€ HTMLFormElement
). 건배!
Jest λ° Enzymeμ μ¬μ©νμ¬ React κ΅¬μ± μμλ₯Ό ν μ€νΈν λ μ΄ λ¬Έμ κ° μλ μ¬λμ μν΄ μμμ @fernandopasik λ° @Boldewyn μ΄ μΈκΈν νμ΄νΌνΌ ν¨ν€μ§λ₯Ό μ¬μ©νμ¬ JSDOM μ ν΄λ¦¬νν μ μμμ΅λλ€.
ν μ€νΈ νμΌμμ νμ΄νΌνΌμ μ€μΉν ν λ€μμ μνν μ μμ΅λλ€.
import * as hyperform from 'hyperform';
var global = global;
const defineValidity = {
get() {
return hyperform.ValidityState(this);
},
configurable: true
};
global.HTMLFormElement.prototype.checkValidity = function() {
return hyperform.checkValidity(this);
};
Object.defineProperty(global.HTMLFormElement.prototype, 'validity', defineValidity);
Object.defineProperty(global.HTMLInputElement.prototype, 'validity', defineValidity);
Object.defineProperty(global.HTMLSelectElement.prototype, 'validity', defineValidity);
Object.defineProperty(global.HTMLTextAreaElement.prototype, 'validity', defineValidity);
μμ ν΄μΌ νλ λ€λ₯Έ HTMLElement λλ ν΄λ¦¬νμ νμν λ€λ₯Έ μμ±μ λν΄ λμΌν λ°©λ²μ λ°λ₯Ό μ μμ΅λλ€.
PR #2142λ ν΄λ¦¬ν μμ΄ μ 체 μ μ½ μ‘°κ±΄ APIλ₯Ό ꡬνν©λλ€.
Jest λ¬Έμλ JSDOMμμ ꡬνλμ§ μμ λͺ¨μ λ°©λ²μ μ μν©λλ€. ν μ€νΈλ‘ μΈν΄ νκ²½μ μ€μΌμν€λ κ²λ³΄λ€ μ΄κ²μ΄ λ κΉ¨λν μ루μ μ΄λΌκ³ μκ°ν©λλ€.
μ κ²½μ°μλ μμμ μ ν¨μ±μ κ²μ¬ν λ€μ μμμ classList
μμ νΉμ ν΄λμ€κ° μλμ§ κ²μ¬ν΄μΌ νμ΅λλ€. μ΄ ν΄λμ€κ° μμΌλ©΄ μμμ μ ν¨μ±μ λν΄ μλ €μ€λλ€.
λ΄ μ루μ
μ μμμ μμ±μ μ‘°λ‘±νλ κ²μ΄μμ΅λλ€. μλ₯Ό λ€μ΄ classList
DOMTokenList
μ κΈ°λ³Έ ꡬνμ μ‘°λ‘±νμ΅λλ€.
beforeAll(() => {
window.DOMTokenList = jest.fn().mockImplementation(() => {
return {
list: [],
remove: jest.fn().mockImplementation(function (item) {
const idx = this.list.indexOf(item);
if (idx > -1) {
this.list.splice(idx, 1)
}
}),
add: jest.fn().mockImplementation(function (item) {
this.list.push(item);
}),
contains: jest.fn().mockImplementation(function (item) {
return this.list.indexOf(item) > -1;
})
};
});
})
κ·Έλ° λ€μ μ΄λ²€νΈ νΈλ€λ¬μ μμ±μ μ λ¬νλ λ° μ¬μ©νμ΅λλ€. event.currentTarget.form
λ₯Ό μ¬μ©νμ¬ μ μΆ λ²νΌμμ λ°μ κ΅¬μ± μμμ μμμ μ‘μΈμ€ν μ μμ΅λλ€.
let mockClassList = new DOMTokenList();
submitBtn.simulate('click', {
currentTarget: {
form: {
checkValidity: () => false,
classList: mockClassList
}
},
preventDefault: jest.fn(),
stopPropagation: jest.fn()
})
μ΄λ₯Ό ν΅ν΄ μμμ μ ν¨μ±μ false λ° trueλ‘ μ€μ νκ³ λ§€λ² was-validated
ν΄λμ€κ° μλμ§ mockClassList
λ₯Ό κ²μ¬ν μ μμ΅λλ€.
submitBtn.simulate('click', {
currentTarget: {
form: {
checkValidity: () => false,
classList: mockClassList
}
},
preventDefault: jest.fn(),
stopPropagation: jest.fn()
});
expect(mockClassList.contains('was-validated')).toBeTruthy();
submitBtn.simulate('click', {
currentTarget: {
form: {
checkValidity: () => true,
classList: mockClassList
}
},
preventDefault: jest.fn(),
stopPropagation: jest.fn()
});
expect(mockClassList.contains('was-validated')).toBeFalsy();
μ°Έκ³ : μ λ μ΄λ₯Ό μν΄ Enzymeμ μμ λ λλ§μ μ¬μ©νκ³ μμ΅λλ€. λ§μ΄νΈκ° μ΄ μ루μ μμ μλνμ§ μλ κ² κ°μ΅λλ€. κ·Έλ¬λ JSDOMμμ ꡬνλμ§ μμ λͺ¨μ λ©μλμ λν λ€λ₯Έ μ μμ ν μ€νΈλ νμΌ λ¬Έμμ λ©μλκ° μ§μ μ€νλ λ λ§μ΄νΈ λ λλ§κ³Ό ν¨κ» μλν μ μλ€κ³ μκ°νλ κ²½ν₯μ΄ μμ΅λλ€.
j [email protected] μμ μ¬μ©ν μ μλ input.validity
μ λ¬Έμ κ° μμ΅λλ€.
// EditableInput.js:
this.inputElement = React.createRef();
...
const input = this.inputElement.current;
console.error('input.validity: ', input.validity);
// EditableInput.test.js run outcome:
console.error src/components/Form/Input/EditableInput.js:47
input.validity: undefined
// yarn.lock:
jsdom@^11.5.1:
version "11.12.0"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8"
integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==
μ ν¨μ± μΈν°νμ΄μ€κ° μλ PRμ΄ λ³ν©λ λ 릴리μ€λμμΌλ―λ‘ μμ νμ΄μΌ νλ λ²μ μ΄ 11.8.0μμ μ μ μμ΅λλ€. λ΄κ° λκ°λ₯Ό λμΉκ³ μμ΅λκΉ?
κ°μ₯ μ μ©ν λκΈ
:+1: νλ₯ν κΈ°λ₯μ΄ λ κ²μ λλ€.