70 - garden-astro - Test image links

Livestream

I find that after changing Github fetch method from Degit to Octokit. The images stop rendering.

I verify that the path is correct, but it seems that all the image files are corrupted.

Upon debugging, I find the root of the problem I parse the file content before writing to file system.

for await (const item of readTar(passThroughStream, fileFilter)) {
  const source = item.content.toString()
  const path = pathWithoutTopmostDir(item.entry.path)
  const destinationPath = `./tmp/second-brain/${path}`

  await fs.promises.writeFile(destinationPath, source) // Source is string
}

The fix is simple, just use the file content directly, it is a Buffer that is also supported by writeFile function.

for await (const item of readTar(passThroughStream, fileFilter)) {
  const path = pathWithoutTopmostDir(item.entry.path)
  const destinationPath = `./tmp/second-brain/${path}`

  await fs.promises.writeFile(destinationPath, item.content) // Buffer
}

The images are now render-able again.

Testing

To prevent broken images in the future, I add the Playwright test to test all the images on the website to the existing link tester.

async function isImageLoaded(src: string) {
  return new Promise((resolve) => {
    const img = new Image()
    img.onload = () => resolve(true)
    img.onerror = () => resolve(false)
    img.src = src
  })
}

const locator = page.locator("img")
const images = await locator.evaluateAll((imgs: HTMLImageElement[]) =>
  imgs
    .map((img) => img.src)
    .filter((src) => src.startsWith("http://localhost:3000"))
)

for (const imageSrc of images) {
  const isLoaded = await page.evaluate(isImageLoaded, imageSrc)
  
  if (!isLoaded) {
    console.error("Broken image", imageSrc, "on page", link)
    brokenImages.push({ image: imageSrc, page: link })
  }
}

expect(brokenImages.length).toEqual(0)

When the test found any broken images, it will fail the test.