๐ฆ testing-library/react๋ก๋ ๋ง์ค์ ํ ์คํธ๋ฅผ ํ ์ ์๋ค.
testing-library/React๋ก๋ ๋ง์ค์(truncate) ์ฒดํฌ๋ฅผ ํ ์ ์์๋ ์ด์ โ Cypress๋ฅผ ์ฐ์
testing-library/react์์๋ scrollWidth์ clientWidth๋ ์ธ์ ๋ 0 ๐
๊ทผ๋์ ๋ฆฌ์กํธ๋ก ํ์ฌ์์ ๊ณต์ฉ์ผ๋ก ์ฐ๋ ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๋ฉด์ ๋ง์ค์(โฆ)์ด ์ ๋๋์ง ํ ์คํธ์ฝ๋๋ฅผ ์ฐ๊ณ ์ถ์๋ฐ, ๋ง์์ฒ๋ผ ์ ์๋์ด์.
function isTextTruncated(element) {
return element.scrollWidth > element.clientWidth;
}
์์ ๊ฐ์ด scrollWidth๊ฐ clientWidth๋ณด๋ค ๊ธธ์ด์ก๋ค๋ฉด ๋ง์ค์ ์ฒ๋ฆฌ๊ฐ ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์ด๊ฑธ๋ก ํ ์คํธํ๋ฉด ๋๊ฒ ๋ค! ์ถ์์ด์. ๊ทธ๋ฐ๋ฐ scrollWidth์ clientWidth๊ฐ 0์ returnํด์ ๊ฐ์ ๋น๊ตํ ์๊ฐ ์๋๋ผ๊ณ ์. ํ..๐คญ
์ฝ๋๋ ์๋ชป์ด ์์ง, ๋ด๊ฐ ์๋ชปํ ๊ฑฐ์ง๋ผ๋ ์๊ฐ์ผ๋ก ๊ตฌ๊ธ๋ง์ ํ๋ค๊ฐ testing-library/react-testing-library Github ์ด์ ํ์ด์ง์์ ์ ๋ ๋น์ทํ ์ง๋ฌธ์ ํ ์ฌ๋์ ์ฐพ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ฑฐ๊ธฐ์ ๊ต์ฅํ๊ณ ๊ต์ฅํ ๋ถ์ธ ์ผํธ์จ๊ฐ ์น์ ํ๊ฒ ๋ต๋ณ์ ํด์ฃผ์ จ๋๋ฐโฆ
testing-library๋ ๊ธฐ๋ณธ์ ์ JSDOM์ ์ด์ฉํ๋ค๊ณ ํฉ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด JSDOM์ layout์ ๋ํ ์ง์์ ํ์ง ์๊ธฐ ๋๋ฌธ์, scrollWidth, clientWidth๊ฐ์ด ์ธก์ ๋๋ ๊ฐ์ ํญ์ 0์ ๋ฆฌํดํ๋ค๊ณ ํ๋ค์!
JSDOM Githubํ์ด์ง๋ก ์ด๋ํด์ ์ฌ์ค์ธ์ง ํ์ธํด๋ด ์๋ค.
JSDOM์ Layout์ ์ง์ํ์ง ์์์.
Note that jsdom still does not do any layout or rendering, so this is really just about pretending to be visual, not about implementing the parts of the platform a real, visual web browser would implement.
(์์ญ) jsdom์ ์ฌ์ ํ ๋ ์ด์์์ด๋ ๋ ๋๋ง ์์ ์ ํ์ง ์๋ค๋ ์ ์ ์ฃผ์ํด์ผํฉ๋๋ค. ์๊ฐ์ ์ผ๋ก (๋ ๋๋ง ๋ฑ์ ์์ ์)ํ๋ ์ฒํ๊ณ ์์ง๋ง, ์ง์ง ๋ธ๋ผ์ฐ์ ์ ์ผ๋ถ์ฒ๋ผ ๋์ํ์ง ์์ต๋๋ค.
Readmeํ์ผ์ ์ฝ๋ค๋ณด๋ ์ด๋ฐ ๋ง์ด ์์ต๋๋ค. ์ผํธ์จ์ ๋ง์ฒ๋ผ jsdom์ ์ง์์ ํ์ง ์๋๋ค๋ค์. does not do any layout or rendering
๋ถ๋ถ์ ๋ค๋ฅธ ๋ฌธ์ ๋งํฌ๊ฐ ์ฐ๊ฒฐ๋์ด ์๊ธธ๋ ํ๊ณ ๋ค์ด๊ฐ๋ณด์์ต๋๋ค.
์ด ๋ฌธ์์์๋ ์ฐ๋ฆฌ๊ฐ ์ฐ๋ ํฌ๋กฌ ๋ธ๋ผ์ฐ์ ๊ฐ์ ์น ํ๋ซํผ์์๋ ๊ธฐ๋ฅ์ด ์์ง๋ง, jsdom์์๋ ๊ตฌํ๋์ง ์์ ๊ฒ๋ค์ ๋ํด ์ฐ์ฌ์์์ต๋๋ค.
์นํ๋ซํผ์๋ ๊ธฐ๋ฅ์ด ์์ง๋ง, JSDOM์๋ ์๋ ๊ฒ๋ค
๐๐ปโโ๏ธ ์ ๋๋ฆ๋๋ก ๋ฒ์ญํ๋ฉด์ ์ ์ ์ธ์ด๋ก ์ฎ๊ฒจ์ ์ ๊ฒ์ด๋ค๋ณด๋ ์ ํํ๊ฒ ํ์ธํ๊ณ ์ถ์ ๊ผผ๊ผผ์์ด ๋ถ๋ค์ ์ง์ ๋ฌธ์๋ฅผ ์ฝ๋ ๊ฒ์ ์ถ์ฒ๋๋ฆฝ๋๋ค ๐
JSDOM ๊ฐ ์ด์ฌํ ๋ ธ๋ ฅํ๊ณ ์์ง๋ง ์ต์ ๋ธ๋ผ์ฐ์ API๋ฅผ ๋ค ๋ฐ์ํ ์ํ๋ ์๋๋๋ค. ์นํ๋ซํผ์๋ ์์ง๋ง JSDOM์ ์๋ ๊ฐ์ฅ ๊ตต์งํ 2๊ฐ์ ๊ธฐ๋ฅ์ Navigation๊ณผ Layout์ ๋๋ค.
- Navigation: ๋งํฌ๋ฅผ ํด๋ฆญํ๊ฑฐ๋
location.href
์ ๊ฐ์ ํ ๋นํ ๋ ์ ์ญ๊ฐ์ฒด๋ ๊ด๋ จ๋ ๋ค๋ฅธ ๊ฐ์ฒด๋ค์ ๋ณ๊ฒฝํ ์ ์๋ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. - Layout: element๋ค์ด CSS์ ๊ฒฐ๊ณผ๋ก ์๊ฐ์ ์ผ๋ก ๋ฐฐ์น๋์ด ์๋ ์์น๋ฅผ ๊ณ์ฐํ ์ ์๋
getBoundingClientRects()
๋๋offsetTop
๊ฐ์ ์์ฑ์ JSDOM์์ ์ง์ํ์ง ์์ต๋๋ค.
ํ์ฌ ์ํ์ JSDOM์ ์ ๊ธฐ๋ฅ๋ค๊ณผ ๊ด๋ จ๋์ด์๋ ๊ฐ์(์ฝ๊ฒ ๋งํด ๊ฐ์ง) ๋์์ ํ๊ณ ์์ต๋๋ค. Naviagion ๊ฐ์ ๊ฒฝ์ฐ์๋ ๊ฐ์์ ์ฝ์์ not implemented(๊ตฌํ๋์ง ์์)
๋๋ jsdomError
๊ฐ์ ์๋ฌ๋ฅผ ๋ฑ๊ณ , Laytout ๊ด๋ จ ์์ฑ์ผ ๊ฒฝ์ฐ์๋ 0์ returnํ๊ณ ์์ต๋๋ค. ๊ทธ๋์ scrollWidth, clientWidth๋ ํญ์ 0์ returnํ ์ ๋ฐ์ ์์ต๋๋ค.
์ด๋ค ๊ฒฝ์ฐ์๋ ์ฝ๋๋ก ์ด๋ฐ ํ๊ณ๋ฅผ ๊ทน๋ณตํ ์๋ ์์ต๋๋ค. ํฌ๋กค๋ง ์ค์ ์ด๋ํ๋ ํ์ด์ง๋ง๋ค JSDOM instance๋ฅผ ์๋ก ์์ฑํ๋ค๋ ์ง, Object.defineProperty()
๋ฅผ ์ด์ฉํด์ ๋ค์ํ ๋ ์ด์์๊ณผ ๊ด๋ จํ getter์ ๋ฉ์๋๊ฐ ๋ฆฌํดํ๋ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค๋ฉด ์ด๋ฐ ์์ผ๋ก์! viniciusavieira๋์ด ์ ์ํ ๋ด์ฉ์ ๊ฐ์ ธ์์ต๋๋ค.
const originalOffsetHeight =
Object.getOwnPropertyDescriptor(
HTMLElement.prototype,
'offsetHeight'
);Object.defineProperty(
HTMLElement.prototype,
'offsetHeight',
originalOffsetHeight
)
๋๋ ์ผํธ์จ ๊ฐ์ ๊ฒฝ์ฐ์๋ ์๋์ ๊ฐ์ ๋ฐฉ๋ฒ์ ์์ ์ ์ฌ์ฉํ ์ ์ด ์๋ค๊ณ ํ๋ค์. Cypress๋ฅผ ์ฐ๊ฑฐ๋ ์ค์ ๋ธ๋ผ์ฐ์ ๋ฅผ ์ด์ฉํ ๊ฒ ์๋๋ผ๋ฉด ์๋์ ๊ฐ์ ๋ฐฉ๋ฒ์ ์ถ์ฒํ๋ค๊ณ ํฉ๋๋ค. ๋ ๋ง์ ์์ ๋ ์ฌ๊ธฐ์์ ํ์ธํ ์ ์์ต๋๋ค.
import matchMediaPolyfill from 'mq-polyfill'
// ...
beforeAll(() => {
matchMediaPolyfill(window)
window.resizeTo = function resizeTo(width, height) {
Object.assign(this, {
innerWidth: width,
innerHeight: height,
outerWidth: width,
outerHeight: height,
}).dispatchEvent(new this.Event('resize'))
}
})// ...then in my test
window.resizeTo(800, 300)
๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก๋ JSDOM์ด ์ง์ํ์ง ์๊ณ ์๋ ๊ธฐ๋ฅ์ PhantomJS๋ ์ง์ํ๊ณ ์๊ธฐ ๋๋ฌธ์, PhantomJS๋ฅผ ์ด์ฉํด๋ณผ ์๋ ์์ต๋๋ค. PhantomJS์ JSDOM์ ๋น๊ตํ๋ ๊ธ์ ์ฌ๊ธฐ์์ ํ์ธํ์ค ์ ์์ต๋๋ค. ์ฐธ๊ณ ๋ก PhantomJS๋ ์ข ์ค๋๋๊ณ ํฌ๊ทํ ๋ ๋๋ง ์์ง์ ์ฌ์ฉํ๊ณ ์๊ธดํ์ง๋ง ์์ ํ ๋ธ๋ผ์ฐ์ ์ด๊ณ , JSDOM์ ์์ํ JavaScript๋ก ๋ง๋ค์ด์ ธ Node.js ๊ธฐ๋ฐ์์ ๋์๊ฐ๋ ์์ ํ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ ๋ผ์ดํธ๋ฒ์ ์ ๋ธ๋ผ์ฐ์ ์ ๋๋ค.
๊ฒฐ๋ก ์ ์ผ๋ก๋ Layout์ ๋ํ ํ ์คํธ๋ Cypress๋ก ํด์ผํ๋ค
๊ฐ๋จํ ์ ๋ํ ์คํธ๋ ๋ถ๋ช testing-library/react๊ฐ ์ ์ฉํ ๊ฒ ๊ฐ์ต๋๋ค. ๊ทธ๋ฐ๋ฐ Navigation(์ด ํ์ด์ง์์ ์ ํ์ด์ง๋ก ์ด๋ํ๋ค๋ ์ง..?)์ด๋ Layout์ ๊ฒฝ์ฐ์๋ ์๋ฌด๋๋ Cypress๊ฐ์ด E2E ํ ์คํธ๋ฅผ ํ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ๋ ๊ฒ์ด ์ข๊ฒ ๊ตฌ๋! ๋ฅผ ๋ฐฐ์ ์ต๋๋ค.
JSDOM๋ฌธ์์์๋ PhantomJS๊ฐ ์ธ๊ธ๋์ด ์์ง๋ง.. ๋์ค์ E2E ํ ์คํ ์ ๋์ ํด๋ณด๊ธฐ ์ํด์๋ ํ ๋ฒ์ฏค Cypress๋ฅผ ์ด์ฉํด๋ณด๊ณ ์ถ๋ค๋ ์๊ฐ์ ํ์ต๋๋ค.
๊ทธ๋์.. Cypress๋ก ๋ง์ค์ ํ
์คํธ ์ฝ๋๋ฅผ ์ง์ ํด๋ณด๋ ๊ฒ์..
๋ค์ ๋ธ๋ก๊ทธ ๊ธ์์ ์๋ํด๋ณด๋ ค๊ณ ํฉ๋๋ค!
์ด๋ฒ ๋ธ๋ก๊น
์ ์ฌ๊ธฐ์ ๋! ๐ค