feat(library): lay the ALL THUMBS wall out in justified rows per day, and stop clipping the frames at the pane's edges
This commit is contained in:
@@ -243,12 +243,73 @@ await context.addInitScript(
|
||||
const page = await context.newPage();
|
||||
const errors = [];
|
||||
page.on('pageerror', (e) => errors.push(String(e.message).slice(0, 200)));
|
||||
|
||||
// The day a frame of this roll was shot on, on the reader's own clock — the same
|
||||
// cut the wall files it under.
|
||||
const dayKeyOf = (name) => {
|
||||
const d = new Date(dayOfName(name));
|
||||
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
// What the wall is drawing, read off the boxes: every row it has drawn, the frames
|
||||
// in them, and the pane and body they are drawn in. The whole check is read off
|
||||
// this, so a row standing at a top the layout did not give it is a row this sees.
|
||||
const audit = () =>
|
||||
page.evaluate(() => {
|
||||
const el = document.querySelector('.adm-grid');
|
||||
if (!el) return null;
|
||||
const box = el.getBoundingClientRect();
|
||||
const body = el.querySelector('.adm-wall-body');
|
||||
const rows = [...el.querySelectorAll('.adm-row')].map((row) => {
|
||||
const rb = row.getBoundingClientRect();
|
||||
const month = row.querySelector('.adm-month-head');
|
||||
return {
|
||||
band: row.classList.contains('adm-band'),
|
||||
day: row.getAttribute('data-day') ?? '',
|
||||
label: row.querySelector('.adm-day-head')?.textContent?.trim() ?? '',
|
||||
month: month ? (month.getAttribute('data-key') ?? '').replace('lib-month-', '') : '',
|
||||
top: Math.round(rb.top - box.top),
|
||||
bottom: Math.round(rb.bottom - box.top),
|
||||
tiles: [...row.querySelectorAll('.lib-tile')].map((t) => {
|
||||
const tb = t.getBoundingClientRect();
|
||||
const img = t.querySelector('img');
|
||||
return {
|
||||
name: (t.getAttribute('data-key') ?? '').split('/').pop(),
|
||||
// Kept as the browser laid them out: a row that is justified to the wall
|
||||
// is a sum of widths, and rounding each of them is a sum off by up to
|
||||
// half a frame a piece.
|
||||
w: Number(tb.width.toFixed(2)),
|
||||
h: Number(tb.height.toFixed(2)),
|
||||
ar: img && img.naturalWidth > 0 ? Number((img.naturalWidth / img.naturalHeight).toFixed(3)) : null,
|
||||
};
|
||||
}),
|
||||
};
|
||||
});
|
||||
const run = document.querySelector('.adm-row:not(.adm-band)');
|
||||
return {
|
||||
scrollTop: Math.round(el.scrollTop),
|
||||
clientH: Math.round(el.clientHeight),
|
||||
clientW: Math.round(el.clientWidth),
|
||||
scrollH: el.scrollHeight,
|
||||
bodyH: body ? Math.round(body.getBoundingClientRect().height) : null,
|
||||
gap: run ? Number.parseFloat(getComputedStyle(run).columnGap) || 0 : 0,
|
||||
rows,
|
||||
};
|
||||
});
|
||||
|
||||
// A stop on the shelf: a fraction of the room under it, or its own end at -1.
|
||||
const scrollTo = (f) =>
|
||||
page.evaluate((at) => {
|
||||
const el = document.querySelector('.adm-grid');
|
||||
el.scrollTop = at < 0 ? el.scrollHeight : Math.round((el.scrollHeight - el.clientHeight) * at);
|
||||
el.dispatchEvent(new Event('scroll'));
|
||||
}, f);
|
||||
|
||||
const read = () =>
|
||||
page.evaluate(() => {
|
||||
const el = document.querySelector('.adm-grid');
|
||||
return {
|
||||
cards: el ? el.querySelectorAll('.adm-card').length : 0,
|
||||
wall: el ? el.scrollHeight > el.clientHeight : false,
|
||||
tiles: el ? el.querySelectorAll('.lib-tile').length : 0,
|
||||
// The white screen itself: no rail, no words, nothing drawn.
|
||||
blank: document.body.innerText.trim().length < 40 && !document.querySelector('nav.rail'),
|
||||
};
|
||||
@@ -267,88 +328,103 @@ await page
|
||||
const counted = await page.$eval('[data-key="lib-count"]', (e) => e.textContent?.trim() ?? '');
|
||||
step('the roll is read whole', counted.includes(String(FRAMES)), counted);
|
||||
|
||||
// The day the header of a card stands under, read off the sections themselves:
|
||||
// every header must name the day of every card filed under it. A day whose first
|
||||
// rows are above the window still gets its header where the eye lands (see
|
||||
// `dayRuns`), so the rule is "a header names its own cards" and not "one header
|
||||
// per day in the shelf".
|
||||
const dayAudit = () =>
|
||||
page.evaluate(() => {
|
||||
const key = (ts) => {
|
||||
const d = new Date(ts);
|
||||
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
||||
};
|
||||
const out = { sections: 0, cards: 0, labelled: 0, bad: [] };
|
||||
for (const section of document.querySelectorAll('.adm-day')) {
|
||||
out.sections++;
|
||||
const own = (section.getAttribute('data-key') ?? '').replace('lib-day-', '');
|
||||
const head = section.querySelector('.adm-day-head')?.textContent?.trim() ?? '';
|
||||
if (head) out.labelled++;
|
||||
const names = [...section.querySelectorAll('[data-key^="lib-photo-"]')].map(
|
||||
(el) => (el.getAttribute('data-key') ?? '').split('/').pop()
|
||||
);
|
||||
const days = new Set(names.map((name) => key(window.__dayOf(name))));
|
||||
if (!names.length || days.size !== 1 || !days.has(own)) out.bad.push({ own, head, days: [...days], names: names.slice(0, 2) });
|
||||
}
|
||||
out.cards = document.querySelectorAll('.adm-card').length;
|
||||
return out;
|
||||
});
|
||||
|
||||
await page.click('[data-key="lib-view-grid"]');
|
||||
await page.waitForSelector('.adm-grid', { timeout: 15_000 });
|
||||
await page.waitForFunction(() => document.querySelectorAll('.adm-card').length > 0, null, { timeout: 30_000 });
|
||||
await page.waitForTimeout(2000);
|
||||
const wall = await read();
|
||||
step('the wall draws a screenful of the shelf', wall.cards > 0 && wall.cards < FRAMES, `${wall.cards} of ${FRAMES} cards drawn`);
|
||||
step('and stands in for the rows it is not drawing', wall.wall, 'the shelf scrolls');
|
||||
await page.waitForSelector('.adm-row', { timeout: 15_000 });
|
||||
await page.waitForFunction(() => document.querySelectorAll('.lib-tile').length > 0, null, { timeout: 30_000 });
|
||||
await page.waitForTimeout(2500);
|
||||
|
||||
const days1 = await dayAudit();
|
||||
// The first screenful is one day of a mixed roll often as not — a day big enough
|
||||
// to fill it is a day at all — so what is read here is that a band stands over
|
||||
// the cards and names its day, and the cut into several days is read below, on a
|
||||
// wall scrolled off the fold.
|
||||
step('the wall draws its days over the cards', days1.sections >= 1 && days1.labelled === days1.sections, `${days1.sections} headers over ${days1.cards} cards`);
|
||||
step('every header names the day of the cards under it', days1.bad.length === 0, JSON.stringify(days1.bad.slice(0, 2)));
|
||||
|
||||
// The same wall, scrolled to where no day starts at the fold: the headers have to
|
||||
// move with it, which is the whole risk of cutting a virtualised wall into days.
|
||||
// Read down the shelf rather than at one stop: a stop of any one fraction lands
|
||||
// inside a day big enough to fill the screen as often as it lands on a fold, so
|
||||
// what is read is that no band ever files a card under another day's header, and
|
||||
// that the shelf's own cuts move through the window as it travels.
|
||||
const stops = [0.15, 0.35, 0.55, 0.75, 0.95];
|
||||
const seenDays = new Set();
|
||||
let scrolledBad = [];
|
||||
for (const at of stops) {
|
||||
await page.evaluate((f) => {
|
||||
const el = document.querySelector('.adm-grid');
|
||||
el.scrollTop = Math.round((el.scrollHeight - el.clientHeight) * f);
|
||||
el.dispatchEvent(new Event('scroll'));
|
||||
}, at);
|
||||
await page.waitForTimeout(900);
|
||||
const audit = await dayAudit();
|
||||
for (const section of await page.$$eval('.adm-day', (els) => els.map((e) => e.getAttribute('data-key')))) seenDays.add(section);
|
||||
scrolledBad = scrolledBad.concat(audit.bad);
|
||||
}
|
||||
const opened = await audit();
|
||||
const openedTiles = opened.rows.reduce((n, r) => n + r.tiles.length, 0);
|
||||
step('the wall draws a screenful of the shelf', openedTiles > 0 && openedTiles < FRAMES, `${openedTiles} of ${FRAMES} frames drawn`);
|
||||
step('and stands in for the rows it is not drawing', opened.scrollH > opened.clientH, `a shelf of ${opened.scrollH}px in a pane of ${opened.clientH}px`);
|
||||
// The shelf's own height, which is the layout's and not the DOM's: a body standing
|
||||
// shorter than the layout puts the frames under the fold out of reach, and one
|
||||
// standing taller leaves the reader at the end of the scroll with a screen of
|
||||
// nothing under the last frame drawn.
|
||||
step(
|
||||
'a scrolled wall still files every card under its own day',
|
||||
scrolledBad.length === 0 && seenDays.size > 1,
|
||||
`${seenDays.size} days through the window, ${JSON.stringify(scrolledBad.slice(0, 2))}`
|
||||
'the body of the wall stands the shelf the layout counted',
|
||||
opened.bodyH !== null && Math.abs(opened.scrollH - opened.bodyH) <= 1,
|
||||
`body ${opened.bodyH}px, scroll ${opened.scrollH}px`
|
||||
);
|
||||
|
||||
// The two frames the pane is drawn for, and the ones a shelf that moves under the
|
||||
// reader hides: the row over the top edge of the pane and the row under its bottom
|
||||
// edge are rows the wall has to have drawn, at every stop of the roll, its two
|
||||
// ends included. Read down the shelf and not at one stop, since a stop of any one
|
||||
// fraction lands inside a day often as it lands on a fold.
|
||||
const stops = [0, 0.15, 0.35, 0.55, 0.75, 0.95, -1];
|
||||
// Read down the drawn rows, from the top edge of the pane to its bottom one, and
|
||||
// the holes between them: two rows of the wall stand a gap apart, and a gap is
|
||||
// not a hole — anything wider than the gap is a row the window left out.
|
||||
const holes = [];
|
||||
const SLIT = 4;
|
||||
const unjustified = [];
|
||||
const dayBad = [];
|
||||
const seenDays = new Set();
|
||||
for (const at of stops) {
|
||||
await scrollTo(at);
|
||||
await page.waitForTimeout(900);
|
||||
const a = await audit();
|
||||
let cursor = 0;
|
||||
for (const r of [...a.rows].sort((x, y) => x.top - y.top)) {
|
||||
if (r.bottom <= 0) continue;
|
||||
if (r.top > cursor + SLIT) holes.push({ at, slit: [cursor, r.top] });
|
||||
if (r.bottom > cursor) cursor = r.bottom;
|
||||
}
|
||||
if (cursor < a.clientH - 1) holes.push({ at, open: [cursor, a.clientH] });
|
||||
// A row of frames is justified to the wall: the frames of a day packed into a row
|
||||
// until it is at least as wide as the wall, and the row then stretched to exactly
|
||||
// that width, so every frame keeps its own proportions and meets its neighbours.
|
||||
// Every row of a day but the last is that width; the last one is as wide as the
|
||||
// day's frames come out, which is what tells one day from the next.
|
||||
const run = a.rows.filter((r) => !r.band);
|
||||
for (let i = 0; i < run.length; i++) {
|
||||
const row = run[i];
|
||||
if (!row.tiles.length) continue;
|
||||
const sum = row.tiles.reduce((n, t) => n + t.w, 0) + a.gap * (row.tiles.length - 1);
|
||||
const last = i + 1 >= run.length || run[i + 1].day !== row.day;
|
||||
if (Math.abs(sum - a.clientW) > 1 && !(last && sum < a.clientW)) {
|
||||
unjustified.push({ day: row.day, sum, wall: a.clientW, last });
|
||||
}
|
||||
for (const t of row.tiles) {
|
||||
if (t.ar !== null && Math.abs(t.w / t.h - t.ar) > 0.02) {
|
||||
unjustified.push({ day: row.day, name: t.name, ar: t.ar, drawn: Number((t.w / t.h).toFixed(3)) });
|
||||
}
|
||||
}
|
||||
}
|
||||
// And the bands: a band names the day it stands over, and the frames under it are
|
||||
// the frames of that day.
|
||||
let head = null;
|
||||
for (const row of a.rows) {
|
||||
if (row.band) {
|
||||
head = row.day;
|
||||
if (head) seenDays.add(head);
|
||||
continue;
|
||||
}
|
||||
// The first row drawn may begin under a band the window left above the fold.
|
||||
if (!head) continue;
|
||||
if (row.day !== head) dayBad.push({ head, row: row.day });
|
||||
for (const t of row.tiles) {
|
||||
if (t.name && head !== dayKeyOf(t.name)) dayBad.push({ head, name: t.name, own: dayKeyOf(t.name) });
|
||||
}
|
||||
}
|
||||
}
|
||||
step('the frames fill the pane from its top edge to its bottom one', holes.length === 0, JSON.stringify(holes.slice(0, 2)));
|
||||
step('a row of frames is justified to the wall, and a day ends in a row of its own', unjustified.length === 0, JSON.stringify(unjustified.slice(0, 2)));
|
||||
step(
|
||||
'every row of frames stands under the band that names its day',
|
||||
dayBad.length === 0 && seenDays.size > 1,
|
||||
`${seenDays.size} days through the window, ${JSON.stringify(dayBad.slice(0, 2))}`
|
||||
);
|
||||
|
||||
// Back to the head of the roll, where the month's own band is drawn.
|
||||
await page.evaluate(() => {
|
||||
const el = document.querySelector('.adm-grid');
|
||||
el.scrollTop = 0;
|
||||
el.dispatchEvent(new Event('scroll'));
|
||||
});
|
||||
await scrollTo(0);
|
||||
await page.waitForTimeout(1200);
|
||||
|
||||
// The two bands, at the heights the wall counts its shelf in. The month's and the
|
||||
// day's band are both fixed numbers in the style sheet and the shelf's whole
|
||||
// length — and with it every spacer standing in for the rows not drawn — is
|
||||
// counted from them, so a band that grew with its own text is a shelf whose end
|
||||
// moves.
|
||||
// The two bands, at the heights the wall lays its shelf out in: both are fixed
|
||||
// numbers in the style sheet, and the shelf's whole height — and with it every
|
||||
// frame's own top — is counted from them, so a band that grew with its own text is
|
||||
// a shelf whose end moves.
|
||||
const bands = await page.evaluate(() => {
|
||||
const h = (sel) => {
|
||||
const el = document.querySelector(sel);
|
||||
@@ -356,34 +432,27 @@ const bands = await page.evaluate(() => {
|
||||
};
|
||||
return { month: h('.adm-month-head'), day: h('.adm-day-head') };
|
||||
});
|
||||
step('the month and the day bands stand at the heights the wall counts them at', bands.month === 54 && bands.day === 28, JSON.stringify(bands));
|
||||
step('the month and the day bands stand at the heights the wall lays them in', bands.month === 44 && bands.day === 30, JSON.stringify(bands));
|
||||
|
||||
// The month's own band, over the first day of the month it names and over no
|
||||
// other: the wall is read by the month it was shot and only then by the day, and
|
||||
// a band left standing over a day of the month above it is a month named twice.
|
||||
const monthAudit = () =>
|
||||
page.evaluate(() => {
|
||||
const out = { sections: 0, heads: 0, bad: [] };
|
||||
const sections = [...document.querySelectorAll('.adm-day')];
|
||||
out.sections = sections.length;
|
||||
let prev = null;
|
||||
for (const section of sections) {
|
||||
const month = section.getAttribute('data-month') ?? '';
|
||||
const head = section.querySelector('.adm-month-head');
|
||||
const named = head ? (head.getAttribute('data-key') ?? '').replace('lib-month-', '') : '';
|
||||
if (head) out.heads++;
|
||||
// The window's own first day is not read: it is a day the wall began in the
|
||||
// middle of, and the band above it was drawn above the fold or not at all.
|
||||
if (prev !== null) {
|
||||
if ((month !== prev) !== Boolean(head)) out.bad.push({ month, prev, head: Boolean(head) });
|
||||
else if (head && named !== month) out.bad.push({ month, named });
|
||||
}
|
||||
prev = month;
|
||||
}
|
||||
return out;
|
||||
});
|
||||
const months1 = await monthAudit();
|
||||
step('the wall names a month over the first day of it, and only there', months1.heads >= 1 && months1.bad.length === 0, `${months1.heads} month bands over ${months1.sections} days, ${JSON.stringify(months1.bad.slice(0, 2))}`);
|
||||
// other: the wall is read by the month it was shot and only then by the day, and a
|
||||
// band left standing over a day of the month above it is a month named twice.
|
||||
const head = await audit();
|
||||
const monthBad = [];
|
||||
let prev = null;
|
||||
let monthBands = 0;
|
||||
for (const row of head.rows) {
|
||||
if (!row.band) continue;
|
||||
const month = row.day.slice(0, 7);
|
||||
if (row.month) monthBands++;
|
||||
// The window's own first day is not read: it is a day the wall began in the
|
||||
// middle of, and the band above it was drawn above the fold or not at all.
|
||||
if (prev !== null && ((month !== prev) !== Boolean(row.month) || (row.month && row.month !== month))) {
|
||||
monthBad.push({ day: row.day, named: row.month, month });
|
||||
}
|
||||
prev = month;
|
||||
}
|
||||
step('the wall names a month over the first day of it, and only there', monthBands >= 1 && monthBad.length === 0, `${monthBands} month bands, ${JSON.stringify(monthBad.slice(0, 2))}`);
|
||||
|
||||
// The ruler down the right edge: a tick a month of the roll and a named tick a
|
||||
// year of it, on the shelf's own months and not on a calendar — a month nothing
|
||||
@@ -410,11 +479,11 @@ await page.click(`[data-key="${press.tick}"]`);
|
||||
await page.waitForTimeout(1500);
|
||||
const landed = await page.evaluate((key) => {
|
||||
const grid = document.querySelector('.adm-grid');
|
||||
const head = document.querySelector(`[data-key="lib-month-${key}"]`);
|
||||
const band = document.querySelector(`[data-key="lib-month-${key}"]`);
|
||||
const on = document.querySelector('.lib-ruler-tick.on');
|
||||
return {
|
||||
drawn: Boolean(head),
|
||||
offset: head && grid ? Math.round(head.getBoundingClientRect().top - grid.getBoundingClientRect().top) : null,
|
||||
drawn: Boolean(band),
|
||||
offset: band && grid ? Math.round(band.getBoundingClientRect().top - grid.getBoundingClientRect().top) : null,
|
||||
value: document.querySelector('[data-key="lib-ruler-value"]')?.textContent?.trim() ?? '',
|
||||
on: on ? on.getAttribute('data-at') : '',
|
||||
};
|
||||
@@ -426,18 +495,18 @@ step(
|
||||
`on=${landed.on} of ${press.at}, " ${landed.value}"`
|
||||
);
|
||||
|
||||
// A notch of the wheel, over the ruler: one month, whichever way the roll is
|
||||
// read, and never off the end of it.
|
||||
// A notch of the wheel, over the ruler: one month, whichever way the roll is read,
|
||||
// and never off the end of it.
|
||||
const notch = () =>
|
||||
page.evaluate(() => {
|
||||
const ticksAll = [...document.querySelectorAll('.lib-ruler-tick')];
|
||||
const months = ticksAll.filter((t) => t.getAttribute('data-kind') === 'month');
|
||||
const months = [...document.querySelectorAll('.lib-ruler-tick')].filter((t) => t.getAttribute('data-kind') === 'month');
|
||||
const on = months.find((t) => t.classList.contains('on'));
|
||||
const needle = document.querySelector('[data-key="lib-ruler-needle"]');
|
||||
return {
|
||||
on: months.findIndex((t) => t.classList.contains('on')),
|
||||
count: months.length,
|
||||
needle: needle ? parseFloat(needle.style.top) || 0 : 0,
|
||||
tick: months.find((t) => t.classList.contains('on')) ? parseFloat(months.find((t) => t.classList.contains('on')).style.top) || 0 : 0,
|
||||
needle: needle ? Number.parseFloat(needle.style.top) || 0 : 0,
|
||||
tick: on ? Number.parseFloat(on.style.top) || 0 : 0,
|
||||
};
|
||||
});
|
||||
const beforeNotch = await notch();
|
||||
@@ -452,16 +521,16 @@ step('and the needle stands in the month the eye is in', Math.abs(afterNotch.nee
|
||||
|
||||
// The shelf walked to its own end, a screen at a time — a jump straight to the
|
||||
// bottom is a different question, and the one this check exists for: the wall
|
||||
// stands in for the frames it is not drawing, and a spacer standing in for more
|
||||
// rows than those frames take leaves the reader at the end of the scroll with a
|
||||
// screen of nothing under the last card drawn and the rest of the roll never
|
||||
// drawn at all. What the walk is read for is that it *gets* there, standing on
|
||||
// the last frame, and that every frame of the roll was drawn on the way.
|
||||
// draws the rows around the eye and stands in for the rest with its own height, so
|
||||
// a body standing shorter than the layout leaves the reader at the end of the
|
||||
// scroll on a screen of nothing and the rest of the roll never drawn at all. What
|
||||
// the walk is read for is that it *gets* there, standing on the last frame, and
|
||||
// that every frame of the roll was drawn on the way.
|
||||
const walked = await page.evaluate(async () => {
|
||||
const el = document.querySelector('.adm-grid');
|
||||
const seen = new Set();
|
||||
const collect = () => {
|
||||
for (const card of el.querySelectorAll('.adm-card')) seen.add(card.getAttribute('data-key'));
|
||||
for (const tile of el.querySelectorAll('.lib-tile')) seen.add(tile.getAttribute('data-key'));
|
||||
};
|
||||
const breathe = () => new Promise((r) => setTimeout(r, 150));
|
||||
el.scrollTop = 0;
|
||||
@@ -474,21 +543,21 @@ const walked = await page.evaluate(async () => {
|
||||
await breathe();
|
||||
}
|
||||
collect();
|
||||
const cards = [...el.querySelectorAll('.adm-card')];
|
||||
const last = cards[cards.length - 1];
|
||||
const box = el.getBoundingClientRect();
|
||||
const body = el.querySelector('.adm-wall-body');
|
||||
const tiles = [...el.querySelectorAll('.lib-tile')];
|
||||
const last = tiles[tiles.length - 1];
|
||||
return {
|
||||
top: Math.round(el.scrollTop),
|
||||
reached: el.scrollTop + el.clientHeight >= el.scrollHeight - 2,
|
||||
room: Math.round(el.scrollHeight - el.clientHeight),
|
||||
// What is left under the last card drawn: the spacer that has nothing left
|
||||
// to stand in for. A few pixels is the grid's own gap.
|
||||
gap: last ? Math.round(el.scrollHeight - (last.getBoundingClientRect().bottom - box.top + el.scrollTop)) : null,
|
||||
// What is left under the last frame drawn: the body that has nothing left to
|
||||
// stand in for.
|
||||
gap: last && body ? Math.round(body.getBoundingClientRect().bottom - last.getBoundingClientRect().bottom) : null,
|
||||
seen: [...seen],
|
||||
};
|
||||
});
|
||||
step('the shelf is walked to its own end', walked.reached, `stopped at ${walked.top} of ${walked.room}`);
|
||||
step('and stands on nothing there', walked.gap !== null && walked.gap <= 16, `${walked.gap}px of nothing under the last card`);
|
||||
step('and stands on nothing there', walked.gap !== null && walked.gap <= 2, `${walked.gap}px of nothing under the last frame`);
|
||||
const missed = names.filter((name) => !walked.seen.includes(`lib-photo-${FOLDER}/${name}`));
|
||||
step('every frame of the roll is drawn on the way', missed.length === 0, `${walked.seen.length} of ${names.length} drawn, first missed ${missed[0] ?? 'none'}`);
|
||||
|
||||
@@ -506,10 +575,10 @@ const after = await read();
|
||||
const looped = errors.filter((e) => e.includes('185') || e.includes('update depth'));
|
||||
step(
|
||||
'a wall fed its own window does not take the screen down',
|
||||
!after.blank && after.cards > 0 && looped.length === 0,
|
||||
`blank=${after.blank}, cards=${after.cards}, errors=${looped.length ? looped[0] : 'none'}`
|
||||
!after.blank && after.tiles > 0 && looped.length === 0,
|
||||
`blank=${after.blank}, tiles=${after.tiles}, errors=${looped.length ? looped[0] : 'none'}`
|
||||
);
|
||||
step('the wall is still the wall', after.cards > 0, `${after.cards} cards after the feed`);
|
||||
step('the wall is still the wall', after.tiles > 0, `${after.tiles} frames after the feed`);
|
||||
|
||||
await page.screenshot({ path: process.env.SHOT ?? '/tmp/wall-check.png' }).catch(() => {});
|
||||
if (errors.length) console.log('page errors:', errors.slice(0, 6).join(' // '));
|
||||
|
||||
Reference in New Issue
Block a user