diff --git a/puppeteer/mouse-trap.js b/puppeteer/mouse-trap.js index 4a872d814..c888a3d83 100644 --- a/puppeteer/mouse-trap.js +++ b/puppeteer/mouse-trap.js @@ -20,14 +20,15 @@ export const createCircle = () => { } const create = ({ clientX, clientY }) => { - const elem = document.createElement('div') - elem.className = 'elem' - body.append(elem) - elem.style.top = `${clientY - radius}px` - elem.style.left = `${clientX - radius}px` + const circle = document.createElement('div') + circle.className = 'circle' + body.append(circle) + circle.style.top = `${clientY - radius}px` + circle.style.left = `${clientX - radius}px` + circle.style.background = 'white' const hasEntered = insideX(clientX) && insideY(clientY) if (hasEntered) { - elem.style.background = 'var(--purple)' + circle.style.background = 'var(--purple)' } isInside = false } @@ -38,29 +39,29 @@ export const moveCircle = () => { } const move = (e) => { - const elems = [...document.getElementsByClassName('elem')] - const elem = elems[elems.length - 1] - if (!elem) return - position(e, elem) + const circles = [...document.getElementsByClassName('circle')] + const circle = circles[circles.length - 1] + if (!circle) return + position(e, circle) } -const position = ({ clientX, clientY }, elem) => { +const position = ({ clientX, clientY }, circle) => { const hasEntered = insideX(clientX) && insideY(clientY) if (hasEntered) { isInside = true - elem.style.background = 'var(--purple)' + circle.style.background = 'var(--purple)' } if (isInside) { if (insideY(clientY)) { - elem.style.top = `${clientY - radius}px` + circle.style.top = `${clientY - radius}px` } if (insideX(clientX)) { - elem.style.left = `${clientX - radius}px` + circle.style.left = `${clientX - radius}px` } } else { - elem.style.top = `${clientY - radius}px` - elem.style.left = `${clientX - radius}px` + circle.style.top = `${clientY - radius}px` + circle.style.left = `${clientX - radius}px` } } diff --git a/puppeteer/mouse-trap_test.js b/puppeteer/mouse-trap_test.js new file mode 100644 index 000000000..a32c7a303 --- /dev/null +++ b/puppeteer/mouse-trap_test.js @@ -0,0 +1,123 @@ +export const tests = [] + +export const setup = async ({ page }) => { + return { + getCirclesPos: async () => + await page.$$eval('.circle', (nodes) => { + const circleRadius = 25 + const formatPos = (pos) => Number(pos.replace('px', '')) + circleRadius + return nodes.map((node) => [ + formatPos(node.style.left), + formatPos(node.style.top), + ]) + }), + } +} + +tests.push(async ({ page, viewport, eq, getCirclesPos }) => { + // check that a circle is created on click at the mouse position + const { width, height } = await page.evaluate(() => ({ + width: document.documentElement.clientWidth, + height: document.documentElement.clientHeight, + })) + + const clicks = [...Array(10).keys()].map((e) => [ + random(width), + random(height), + ]) + + for (const [i, click] of clicks.entries()) { + const [posX, posY] = click + await page.mouse.click(posX, posY) + const currentCircle = (await getCirclesPos())[i] + eq(currentCircle, click) + } +}) + +tests.push(async ({ page, eq, getCirclesPos }) => { + // check that the last created circle moves along the mouse + let move = 0 + while (move < 100) { + move += 1 + const x = move + const y = move * 2 + await page.mouse.move(x, y) + const circles = await getCirclesPos() + const currentCirclePos = circles[circles.length - 1] + eq(currentCirclePos, [x, y]) + } +}) + +tests.push(async ({ page, eq, getCirclesPos }) => { + // check that a circle is trapped and purple when inside the box + const box = await page.$eval('.box', (box) => ({ + top: box.getBoundingClientRect().top, + right: box.getBoundingClientRect().right, + left: box.getBoundingClientRect().left, + bottom: box.getBoundingClientRect().bottom, + })) + + await page.mouse.click(200, 200) + + let move = 200 + let hasEntered = false + + while (move < 500) { + const x = move + 50 + const y = move + await page.mouse.move(x, y) + + const circles = await getCirclesPos() + const currentCircle = circles[circles.length - 1] + + const circleRadius = 25 + + const bg = await page.$$eval( + '.circle', + (nodes) => nodes[nodes.length - 1].style.background, + ) + + const insideX = x > box.left + circleRadius && x < box.right - circleRadius + const insideY = y > box.top + circleRadius && y < box.bottom - circleRadius + const isInside = insideX && insideY + + // check that the background is set to the right color + if (isInside) { + hasEntered = true + eq(bg, 'var(--purple)') + } else { + eq(bg, hasEntered ? 'var(--purple)' : 'white') + } + + // check that the mouse is trapped inside the box + if (hasEntered) { + if (insideY) { + eq(currentCircle[1], y) + } else { + const maxY = + currentCircle[1] === box.top + circleRadius + 1 || + currentCircle[1] === box.bottom - circleRadius - 1 + eq(maxY, true) + } + if (insideX) { + eq(currentCircle[0], x) + } else { + const maxX = + currentCircle[0] === box.left + circleRadius + 1 || + currentCircle[0] === box.right - circleRadius - 1 + eq(maxX, true) + } + } + move++ + } +}) + +const random = (min, max) => { + if (!max) { + max = min + min = 0 + } + min = Math.ceil(min) + max = Math.floor(max) + return Math.floor(Math.random() * (max - min + 1)) + min +} diff --git a/subjects/mouse-trap/README.md b/subjects/mouse-trap/README.md index f6b32493e..5b613d08b 100644 --- a/subjects/mouse-trap/README.md +++ b/subjects/mouse-trap/README.md @@ -4,7 +4,7 @@ Develop a trap to capture the elements when the mouse is getting too close to the center of the page! -- Create a function `createCircle`: make it fire on every click on the page, and create a white circle at the position of the mouse on the screen +- Create a function `createCircle`: make it fire on every click on the page, and create a `div` at the position of the mouse on the screen, setting its `background` to `white` and its class to `circle` - Create a function `moveCircle`: make it fire when the mouse moves, and get the last circle created and makes it move along with the mouse diff --git a/subjects/mouse-trap/index.html b/subjects/mouse-trap/index.html index c59f1185a..90ca014c1 100644 --- a/subjects/mouse-trap/index.html +++ b/subjects/mouse-trap/index.html @@ -33,11 +33,10 @@ body { font-size: 12px; } -.elem { +.circle { width: 50px; height: 50px; border-radius: 50%; - background: var(--clear); position: absolute; opacity: 0.75; }