diff --git a/dom/gossip-grid_test.js b/dom/gossip-grid_test.js index 2889edd6..e6cbb420 100644 --- a/dom/gossip-grid_test.js +++ b/dom/gossip-grid_test.js @@ -14,28 +14,110 @@ tests.push(async ({ page, eq }) => { tests.push(async ({ page, eq }) => { // test that you can add a gossip - return new Promise(()=>{}) + const rand = Math.random().toString(36).slice(2) + await page.type('textarea', `coucou ${rand}`) + await page.click('.gossip button') + const content = await page.$eval('div.gossip', n => n.textContent) + + eq(content, `coucou ${rand}`) }) +const getStyle = (nodes, key) => nodes.map(n => n.style[key]) tests.push(async ({ page, eq }) => { - // test that you can change the width + // test that you can change the width to the min - return new Promise(()=>{}) -}) + const min = await page.$eval('#width', n => { + n.value = n.min + n.dispatchEvent(new Event('input')) + return Number(n.min) + }) + eq(min, 200) + + const values = await page.$$eval('div.gossip', getStyle, 'width') + + eq(Array(gossips.length + 1).fill(`${min}px`), values) +}) tests.push(async ({ page, eq }) => { - // test that you can change the font-size + // test that you can change the width to the max + + const max = await page.$eval('#width', n => { + n.value = n.max + n.dispatchEvent(new Event('input')) + return Number(n.max) + }) + + eq(max, 800) - return new Promise(()=>{}) + const values = await page.$$eval('div.gossip', getStyle, 'width') + + eq(Array(gossips.length + 1).fill(`${max}px`), values) }) +tests.push(async ({ page, eq }) => { + // test that you can change the font-size to the min + + const min = await page.$eval('#fontSize', n => { + n.value = n.min + n.dispatchEvent(new Event('input')) + return Number(n.min) + }) + + eq(min, 20) + + const values = await page.$$eval('div.gossip', getStyle, 'fontSize') + + eq(Array(gossips.length + 1).fill(`${min}px`), values) +}) tests.push(async ({ page, eq }) => { - // test that you can change the background + // test that you can change the font-size to the max + + const max = await page.$eval('#fontSize', n => { + n.value = n.max + n.dispatchEvent(new Event('input')) + return Number(n.max) + }) + + eq(max, 40) + + const values = await page.$$eval('div.gossip', getStyle, 'fontSize') - return new Promise(()=>{}) + eq(Array(gossips.length + 1).fill(`${max}px`), values) }) +const getBackground = (nodes, key) => nodes.map(n => n.style.background || n.style.backgroundColor) +tests.push(async ({ page, eq, rgbToHsl }) => { + // test that you can change the background to the darkest + const min = await page.$eval('#background', n => { + n.value = n.min + n.dispatchEvent(new Event('input')) + return Number(n.min) + }) + + eq(min, 20) + + const values = await page.$$eval('div.gossip', getBackground) + const lightness = values.map(rgbToHsl).map(([h,s,l]) => l) + eq(Array(gossips.length + 1).fill(min), lightness) +}) + +tests.push(async ({ page, eq, rgbToHsl }) => { + // test that you can change the background to the darkest + + const max = await page.$eval('#background', n => { + n.value = n.max + n.dispatchEvent(new Event('input')) + return Number(n.max) + }) + + eq(max, 75) + + const values = await page.$$eval('div.gossip', getBackground) + const lightness = values.map(rgbToHsl).map(([h,s,l]) => Math.round(l)) + + eq(Array(gossips.length + 1).fill(max), lightness) +}) diff --git a/dom/pick-and-click_test.js b/dom/pick-and-click_test.js index 1f2a1d59..aa454fbb 100644 --- a/dom/pick-and-click_test.js +++ b/dom/pick-and-click_test.js @@ -2,55 +2,10 @@ export const tests = [] const between = (expected, min, max) => expected >= min && expected <= max -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 -} - -const rgbToHsl = (r, g, b) => { - r = r / 255 - g = g / 255 - b = b / 255 - const max = Math.max(r, g, b) - const min = Math.min(r, g, b) - let h - let s - const l = (max + min) / 2 - - if (max === min) { - h = s = 0 // achromatic - } else { - const d = max - min - s = l > 0.5 ? d / (2 - max - min) : d / (max + min) - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0) - break - case g: - h = (b - r) / d + 2 - break - case b: - h = (r - g) / d + 4 - break - } - h /= 6 - } - - return [Math.floor(h * 360), Math.floor(s * 100), Math.floor(l * 100)] -} - -export const setup = async ({ page }) => { +export const setup = async ({ page, rgbToHsl }) => { return { bodyBgRgb: async () => - (await page.$eval('body', (body) => body.style.background)) - .replace(/[^0-9,]+/g, '') - .split(',') - .map((e) => Number(e)), + rgbToHsl(await page.$eval('body', body => body.style.background)), } } @@ -64,7 +19,7 @@ tests.push(async ({ page, eq }) => { const x = move const y = move * 2 await page.mouse.move(x, y) - const bodyBg = await page.$eval('body', (body) => body.style.background) + const bodyBg = await page.$eval('body', body => body.style.background) const validColor = bodyBg.includes('rgb') if (!validColor) continue bgs.push(bodyBg) @@ -73,105 +28,77 @@ tests.push(async ({ page, eq }) => { eq(differentBgs, 20) }) -const coords = () => [ +const near = (a, b) => a < (b+2.5) && a > (b-2.5) +const numVal = n => n.textContent.replace(/[^0-9,]/g, '') +const generateCoords = random => [ [random(125, 500), random(125, 400)], [random(125, 500), random(125, 400)], [random(125, 500), random(125, 400)], ] -tests.push(async ({ page, eq, bodyBgRgb }) => { +tests.push(async ({ page, eq, bodyBgRgb, random }) => { // check that the hsl value displayed matches the current background color - const moves = coords() - let step = 0 - while (step < moves.length) { - await page.mouse.move(...moves[step]) - const bgValue = rgbToHsl(...(await bodyBgRgb())) - const hslValue = await page.$eval('.hsl', (hsl) => - hsl.textContent - .replace(/[^0-9,]+/g, '') - .split(',') - .map((e) => Number(e)), - ) - - const matching = hslValue.map((v, i) => - between(v, bgValue[i] - 2, bgValue[i] + 2) ? bgValue[i] : v, - ) - eq(matching, bgValue) - step++ + for (const move of generateCoords(random)) { + await page.mouse.move(...move) + const a = await bodyBgRgb() + const b = (await page.$eval('.hsl', numVal)).split(',') + if (a.every((v, i) => near(v, Number(b[i])))) continue + throw Error(`hsl(${a.map(Math.round)}) to far from hsl(${b})`) } }) -tests.push(async ({ page, eq, bodyBgRgb }) => { +tests.push(async ({ page, eq, bodyBgRgb, random }) => { // check that the hue value displayed matches the current background color - const moves = coords() - let step = 0 - while (step < moves.length) { - await page.mouse.move(...moves[step]) - const bgValue = rgbToHsl(...(await bodyBgRgb())) - const hueValue = await page.$eval('.hue', (hue) => - hue.textContent.replace(/[^0-9,]+/g, ''), - ) - - const matching = between(hueValue, bgValue[0] - 2, bgValue[0] + 2) - ? bgValue[0] - : Number(hueValue) - eq(matching, bgValue[0]) - step++ + for (const move of generateCoords(random)) { + await page.mouse.move(...move) + const [h] = await bodyBgRgb() + const hue = await page.$eval('.hue', numVal) + + if (!near(h, Number(hue))) { + console.log({h,hue, c:near(h, Number(hue)) }) + throw Error(`hue ${Math.round(h)} to far from ${hue}`) + } } }) -tests.push(async ({ page, eq, bodyBgRgb }) => { +tests.push(async ({ page, eq, bodyBgRgb, random }) => { // check that the luminosity value displayed matches the current background color - const moves = coords() - let step = 0 - while (step < moves.length) { - await page.mouse.move(...moves[step]) - const bgValue = rgbToHsl(...(await bodyBgRgb())) - const luminosityValue = await page.$eval('.luminosity', (luminosity) => - luminosity.textContent.replace(/[^0-9,]+/g, ''), - ) + for (const move of generateCoords(random)) { + await page.mouse.move(...move) + const [,,l] = await bodyBgRgb() + const lum = await page.$eval('.luminosity', numVal) - const matching = between(luminosityValue, bgValue[2] - 2, bgValue[2] + 2) - ? bgValue[2] - : Number(luminosityValue) - eq(matching, bgValue[2]) - step++ + if (!near(l, Number(lum))) { + throw Error(`luminosity ${Math.round(l)} to far from ${lum}`) + } } }) -tests.push(async ({ page, eq, bodyBgRgb }) => { +tests.push(async ({ page, eq, bodyBgRgb, random }) => { // check that the hsl value is copied in the clipboard on click - const moves = coords() - let step = 0 - while (step < moves.length) { - await page.mouse.click(...moves[step]) + for (const move of generateCoords(random)) { + await page.mouse.click(...move) const clipboard = await page.evaluate(() => navigator.clipboard.readText()) - const hslValue = await page.$eval('.hsl', (hsl) => hsl.textContent) + const hslValue = await page.$eval('.hsl', hsl => hsl.textContent) eq(hslValue, clipboard) - step++ } }) -tests.push(async ({ page, eq, bodyBgRgb }) => { +tests.push(async ({ page, eq, bodyBgRgb, random }) => { // check that each svg axis is following the mouse - const moves = coords() - let step = 0 - while (step < 1) { - const [mouseX, mouseY] = moves[step] - await page.mouse.move(mouseX, mouseY) - const axisX = await page.$eval('#axisX', (line) => [ - line.getAttribute('x1'), - line.getAttribute('x2'), - ]) - const axisY = await page.$eval('#axisY', (line) => [ - line.getAttribute('y1'), - line.getAttribute('y2'), - ]) - - const checkAxisCoords = (coords) => Number([...new Set(coords)].join()) - - eq(checkAxisCoords(axisX), mouseX) - eq(checkAxisCoords(axisY), mouseY) - step++ - } + const [[mouseX, mouseY]] = generateCoords(random) + await page.mouse.move(mouseX, mouseY) + const axisX = await page.$eval('#axisX', line => [ + line.getAttribute('x1'), + line.getAttribute('x2'), + ]) + const axisY = await page.$eval('#axisY', line => [ + line.getAttribute('y1'), + line.getAttribute('y2'), + ]) + + const checkAxisCoords = coords => Number([...new Set(coords)].join()) + + eq(checkAxisCoords(axisX), mouseX) + eq(checkAxisCoords(axisY), mouseY) }) diff --git a/dom/test.js b/dom/test.js index 8957816d..e92c6108 100644 --- a/dom/test.js +++ b/dom/test.js @@ -29,6 +29,28 @@ const mediaTypes = { json: 'application/json', } +const random = (min, max = min) => { + max === min && (min = 0) + min = Math.ceil(min) + return Math.floor(Math.random() * (Math.floor(max) - min + 1)) + min +} + +const rgbToHsl = rgbStr => { + const [r, g, b] = rgbStr.slice(4, -1).split(',').map(Number) + const max = Math.max(r, g, b) + const min = Math.min(r, g, b) + const l = (max + min) / ((0xff * 2) / 100) + + if (max === min) return [0, 0, l] + + const d = max - min + const s = (d / (l > 50 ? 0xff * 2 - max - min : max + min)) * 100 + if (max === r) return [((g - b) / d + (g < b && 6)) * 60, s, l] + return max === g + ? [((b - r) / d + 2) * 60, s, l] + : [((r - g) / d + 4) * 60, s, l] +} + const server = http .createServer(({ url, method }, response) => { console.log(method + ' ' + url) @@ -57,7 +79,14 @@ const server = http const [page] = await browser.pages() await page.goto(`http://localhost:${PORT}/${exercise}/index.html`) - const context = await setup({ page }) + const baseContext = { + page, + browser, + eq: deepStrictEqual, + random, + rgbToHsl, + } + const context = await setup(baseContext) browser .defaultBrowserContext() @@ -65,7 +94,7 @@ const server = http for (const [n, test] of tests.entries()) { try { - await test({ page, eq: deepStrictEqual, ...context }) + await test({ ...baseContext, ...context }) } catch (err) { console.log(`test #${n} failed:`) console.log(test.toString()) diff --git a/subjects/gossip-grid/README.md b/subjects/gossip-grid/README.md index 93e30fc2..450664b8 100644 --- a/subjects/gossip-grid/README.md +++ b/subjects/gossip-grid/README.md @@ -9,7 +9,12 @@ They must be `div` with the `gossip` class. The first `gossip` card must be a form with a `textarea` and a submit button that allows to add a new gossip to the list -- customize the width, font size and background of each card with `range` inputs. +Create 3 `type="range"` inputs: +- one with `id="width"` that control the width of cards *(from 200 to 800 pixels)* +- one with `id="fontSize"` that control the font size *(from 20 to 40 pixels)* +- one with `id="background"` that control the background lightness *(from 20% to 75%)* + +> *tips:* use `hsl` for colors ### Notions