Browse Source

add gossip-grid + refactor pick-and-click

pull/617/head
Clement Denis 4 years ago
parent
commit
f775a6024d
  1. 98
      dom/gossip-grid_test.js
  2. 153
      dom/pick-and-click_test.js
  3. 33
      dom/test.js
  4. 7
      subjects/gossip-grid/README.md

98
dom/gossip-grid_test.js

@ -14,28 +14,110 @@ tests.push(async ({ page, eq }) => {
tests.push(async ({ page, eq }) => { tests.push(async ({ page, eq }) => {
// test that you can add a gossip // 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 }) => { 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 }) => { 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 }) => { 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)
})

153
dom/pick-and-click_test.js

@ -2,55 +2,10 @@ export const tests = []
const between = (expected, min, max) => expected >= min && expected <= max const between = (expected, min, max) => expected >= min && expected <= max
const random = (min, max) => { export const setup = async ({ page, rgbToHsl }) => {
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 }) => {
return { return {
bodyBgRgb: async () => bodyBgRgb: async () =>
(await page.$eval('body', (body) => body.style.background)) rgbToHsl(await page.$eval('body', body => body.style.background)),
.replace(/[^0-9,]+/g, '')
.split(',')
.map((e) => Number(e)),
} }
} }
@ -64,7 +19,7 @@ tests.push(async ({ page, eq }) => {
const x = move const x = move
const y = move * 2 const y = move * 2
await page.mouse.move(x, y) 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') const validColor = bodyBg.includes('rgb')
if (!validColor) continue if (!validColor) continue
bgs.push(bodyBg) bgs.push(bodyBg)
@ -73,105 +28,77 @@ tests.push(async ({ page, eq }) => {
eq(differentBgs, 20) 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)], [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 // check that the hsl value displayed matches the current background color
const moves = coords() for (const move of generateCoords(random)) {
let step = 0 await page.mouse.move(...move)
while (step < moves.length) { const a = await bodyBgRgb()
await page.mouse.move(...moves[step]) const b = (await page.$eval('.hsl', numVal)).split(',')
const bgValue = rgbToHsl(...(await bodyBgRgb())) if (a.every((v, i) => near(v, Number(b[i])))) continue
const hslValue = await page.$eval('.hsl', (hsl) => throw Error(`hsl(${a.map(Math.round)}) to far from hsl(${b})`)
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++
} }
}) })
tests.push(async ({ page, eq, bodyBgRgb }) => { tests.push(async ({ page, eq, bodyBgRgb, random }) => {
// check that the hue value displayed matches the current background color // check that the hue value displayed matches the current background color
const moves = coords() for (const move of generateCoords(random)) {
let step = 0 await page.mouse.move(...move)
while (step < moves.length) { const [h] = await bodyBgRgb()
await page.mouse.move(...moves[step]) const hue = await page.$eval('.hue', numVal)
const bgValue = rgbToHsl(...(await bodyBgRgb()))
const hueValue = await page.$eval('.hue', (hue) => if (!near(h, Number(hue))) {
hue.textContent.replace(/[^0-9,]+/g, ''), console.log({h,hue, c:near(h, Number(hue)) })
) throw Error(`hue ${Math.round(h)} to far from ${hue}`)
}
const matching = between(hueValue, bgValue[0] - 2, bgValue[0] + 2)
? bgValue[0]
: Number(hueValue)
eq(matching, bgValue[0])
step++
} }
}) })
tests.push(async ({ page, eq, bodyBgRgb }) => { tests.push(async ({ page, eq, bodyBgRgb, random }) => {
// check that the luminosity value displayed matches the current background color // check that the luminosity value displayed matches the current background color
const moves = coords() for (const move of generateCoords(random)) {
let step = 0 await page.mouse.move(...move)
while (step < moves.length) { const [,,l] = await bodyBgRgb()
await page.mouse.move(...moves[step]) const lum = await page.$eval('.luminosity', numVal)
const bgValue = rgbToHsl(...(await bodyBgRgb()))
const luminosityValue = await page.$eval('.luminosity', (luminosity) =>
luminosity.textContent.replace(/[^0-9,]+/g, ''),
)
const matching = between(luminosityValue, bgValue[2] - 2, bgValue[2] + 2) if (!near(l, Number(lum))) {
? bgValue[2] throw Error(`luminosity ${Math.round(l)} to far from ${lum}`)
: Number(luminosityValue) }
eq(matching, bgValue[2])
step++
} }
}) })
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 // check that the hsl value is copied in the clipboard on click
const moves = coords() for (const move of generateCoords(random)) {
let step = 0 await page.mouse.click(...move)
while (step < moves.length) {
await page.mouse.click(...moves[step])
const clipboard = await page.evaluate(() => navigator.clipboard.readText()) 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) 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 // check that each svg axis is following the mouse
const moves = coords() const [[mouseX, mouseY]] = generateCoords(random)
let step = 0
while (step < 1) {
const [mouseX, mouseY] = moves[step]
await page.mouse.move(mouseX, mouseY) await page.mouse.move(mouseX, mouseY)
const axisX = await page.$eval('#axisX', (line) => [ const axisX = await page.$eval('#axisX', line => [
line.getAttribute('x1'), line.getAttribute('x1'),
line.getAttribute('x2'), line.getAttribute('x2'),
]) ])
const axisY = await page.$eval('#axisY', (line) => [ const axisY = await page.$eval('#axisY', line => [
line.getAttribute('y1'), line.getAttribute('y1'),
line.getAttribute('y2'), line.getAttribute('y2'),
]) ])
const checkAxisCoords = (coords) => Number([...new Set(coords)].join()) const checkAxisCoords = coords => Number([...new Set(coords)].join())
eq(checkAxisCoords(axisX), mouseX) eq(checkAxisCoords(axisX), mouseX)
eq(checkAxisCoords(axisY), mouseY) eq(checkAxisCoords(axisY), mouseY)
step++
}
}) })

33
dom/test.js

@ -29,6 +29,28 @@ const mediaTypes = {
json: 'application/json', 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 const server = http
.createServer(({ url, method }, response) => { .createServer(({ url, method }, response) => {
console.log(method + ' ' + url) console.log(method + ' ' + url)
@ -57,7 +79,14 @@ const server = http
const [page] = await browser.pages() const [page] = await browser.pages()
await page.goto(`http://localhost:${PORT}/${exercise}/index.html`) 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 browser
.defaultBrowserContext() .defaultBrowserContext()
@ -65,7 +94,7 @@ const server = http
for (const [n, test] of tests.entries()) { for (const [n, test] of tests.entries()) {
try { try {
await test({ page, eq: deepStrictEqual, ...context }) await test({ ...baseContext, ...context })
} catch (err) { } catch (err) {
console.log(`test #${n} failed:`) console.log(`test #${n} failed:`)
console.log(test.toString()) console.log(test.toString())

7
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 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 ### Notions

Loading…
Cancel
Save