Skip to content

Commit

Permalink
feat: move custom image cdn url generator implementation to adapter (#…
Browse files Browse the repository at this point in the history
…38715)

* feat: move custom image cdn url generator implementation to adapter

* provide public types for custom image cdn url generator function signature and individual arguments
  • Loading branch information
pieh authored Nov 30, 2023
1 parent 0975496 commit d31412a
Show file tree
Hide file tree
Showing 20 changed files with 673 additions and 369 deletions.
331 changes: 181 additions & 150 deletions e2e-tests/adapters/cypress/e2e/remote-file.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,107 +11,116 @@ Cypress.on("uncaught:exception", err => {

const PATH_PREFIX = Cypress.env(`PATH_PREFIX`) || ``

describe(
`remote-file`,
// there are multiple scenarios we want to test and ensure that custom image cdn url is used:
// - child build process (SSG, Page Query)
// - main build process (SSG, Page Context)
// - query engine (SSR, Page Query)
const configs = [
{
retries: {
runMode: 4,
},
title: `remote-file (SSG, Page Query)`,
pagePath: `/routes/remote-file/`,
fileCDN: true,
placeholders: true,
},
{
title: `remote-file (SSG, Page Context)`,
pagePath: `/routes/remote-file-data-from-context/`,
fileCDN: true,
placeholders: true,
},
{
title: `remote-file (SSR, Page Query)`,
pagePath: `/routes/ssr/remote-file/`,
fileCDN: false,
placeholders: false,
},
() => {
beforeEach(() => {
cy.visit(`/routes/remote-file/`).waitForRouteChange()

// trigger intersection observer
cy.scrollTo("top")
cy.wait(200)
cy.scrollTo("bottom", {
duration: 600,
]

for (const config of configs) {
describe(
config.title,
{
retries: {
runMode: 4,
},
},
() => {
beforeEach(() => {
cy.visit(config.pagePath).waitForRouteChange()

// trigger intersection observer
cy.scrollTo("top")
cy.wait(200)
cy.scrollTo("bottom", {
duration: 600,
})
cy.wait(600)
})
cy.wait(600)
})

async function testImages(images, expectations) {
for (let i = 0; i < images.length; i++) {
const expectation = expectations[i]
async function testImages(images, expectations) {
for (let i = 0; i < images.length; i++) {
const expectation = expectations[i]

const url = images[i].currentSrc
const url = images[i].currentSrc

const { href, origin } = new URL(url)
const urlWithoutOrigin = href.replace(origin, ``)
const { href, origin } = new URL(url)
const urlWithoutOrigin = href.replace(origin, ``)

// using Netlify Image CDN
expect(urlWithoutOrigin).to.match(/^\/.netlify\/images/)
// using Netlify Image CDN
expect(urlWithoutOrigin).to.match(/^\/.netlify\/images/)

const res = await fetch(url, {
method: "HEAD",
})
expect(res.ok).to.be.true

const expectedNaturalWidth =
expectation.naturalWidth ?? expectation.width
const expectedNaturalHeight =
expectation.naturalHeight ?? expectation.height

if (expectation.width) {
expect(
Math.ceil(images[i].getBoundingClientRect().width)
).to.be.equal(expectation.width)
}
if (expectation.height) {
expect(
Math.ceil(images[i].getBoundingClientRect().height)
).to.be.equal(expectation.height)
}
if (expectedNaturalWidth) {
expect(Math.ceil(images[i].naturalWidth)).to.be.equal(
expectedNaturalWidth
)
}
if (expectedNaturalHeight) {
expect(Math.ceil(images[i].naturalHeight)).to.be.equal(
expectedNaturalHeight
)
}
}
}

it(`should render correct dimensions`, () => {
cy.get('[data-testid="public"]').then(async $urls => {
const urls = Array.from(
$urls.map((_, $url) => $url.getAttribute("href"))
)

for (const url of urls) {
// using OSS implementation for publicURL for now
expect(url).to.match(new RegExp(`^${PATH_PREFIX}/_gatsby/file`))
const res = await fetch(url, {
method: "HEAD",
})
expect(res.ok).to.be.true

const expectedNaturalWidth =
expectation.naturalWidth ?? expectation.width
const expectedNaturalHeight =
expectation.naturalHeight ?? expectation.height

if (expectation.width) {
expect(
Math.ceil(images[i].getBoundingClientRect().width)
).to.be.equal(expectation.width)
}
if (expectation.height) {
expect(
Math.ceil(images[i].getBoundingClientRect().height)
).to.be.equal(expectation.height)
}
if (expectedNaturalWidth) {
expect(Math.ceil(images[i].naturalWidth)).to.be.equal(
expectedNaturalWidth
)
}
if (expectedNaturalHeight) {
expect(Math.ceil(images[i].naturalHeight)).to.be.equal(
expectedNaturalHeight
)
}
}
})
}

cy.get(".resize").then({ timeout: 60000 }, async $imgs => {
await testImages(Array.from($imgs), [
{
width: 100,
height: 133,
},
{
width: 100,
height: 160,
},
{
width: 100,
height: 67,
},
])
})
it(`should render correct dimensions`, () => {
if (config.fileCDN) {
cy.get('[data-testid="public"]').then(async $urls => {
const urls = Array.from(
$urls.map((_, $url) => $url.getAttribute("href"))
)

for (const url of urls) {
// using OSS implementation for publicURL for now
expect(url).to.match(new RegExp(`^${PATH_PREFIX}/_gatsby/file`))
const res = await fetch(url, {
method: "HEAD",
})
expect(res.ok).to.be.true
}
})
}

cy.get(".fixed img:not([aria-hidden=true])").then(
{ timeout: 60000 },
async $imgs => {
cy.get(".resize").then({ timeout: 60000 }, async $imgs => {
await testImages(Array.from($imgs), [
{
width: 100,
Expand All @@ -126,70 +135,92 @@ describe(
height: 67,
},
])
}
)
})

cy.get(".constrained img:not([aria-hidden=true])").then(
{ timeout: 60000 },
async $imgs => {
await testImages(Array.from($imgs), [
{
width: 300,
height: 400,
},
{
width: 300,
height: 481,
},
{
width: 300,
height: 200,
},
])
}
)
cy.get(".fixed img:not([aria-hidden=true])").then(
{ timeout: 60000 },
async $imgs => {
await testImages(Array.from($imgs), [
{
width: 100,
height: 133,
},
{
width: 100,
height: 160,
},
{
width: 100,
height: 67,
},
])
}
)

cy.get(".full img:not([aria-hidden=true])").then(
{ timeout: 60000 },
async $imgs => {
await testImages(Array.from($imgs), [
{
naturalHeight: 1333,
},
{
naturalHeight: 1603,
},
{
naturalHeight: 666,
},
])
cy.get(".constrained img:not([aria-hidden=true])").then(
{ timeout: 60000 },
async $imgs => {
await testImages(Array.from($imgs), [
{
width: 300,
height: 400,
},
{
width: 300,
height: 481,
},
{
width: 300,
height: 200,
},
])
}
)

cy.get(".full img:not([aria-hidden=true])").then(
{ timeout: 60000 },
async $imgs => {
await testImages(Array.from($imgs), [
{
naturalHeight: 1333,
},
{
naturalHeight: 1603,
},
{
naturalHeight: 666,
},
])
}
)
})

it(`should render a placeholder`, () => {
if (config.placeholders) {
cy.get(".fixed [data-placeholder-image]")
.first()
.should("have.css", "background-color", "rgb(232, 184, 8)")
cy.get(".constrained [data-placeholder-image]")
.first()
.should($el => {
expect($el.prop("tagName")).to.be.equal("IMG")
expect($el.prop("src")).to.contain("data:image/jpg;base64")
})
cy.get(".constrained_traced [data-placeholder-image]")
.first()
.should($el => {
// traced falls back to DOMINANT_COLOR
expect($el.prop("tagName")).to.be.equal("DIV")
expect($el).to.be.empty
})
}
)
})

it(`should render a placeholder`, () => {
cy.get(".fixed [data-placeholder-image]")
.first()
.should("have.css", "background-color", "rgb(232, 184, 8)")
cy.get(".constrained [data-placeholder-image]")
.first()
.should($el => {
expect($el.prop("tagName")).to.be.equal("IMG")
expect($el.prop("src")).to.contain("data:image/jpg;base64")
})
cy.get(".constrained_traced [data-placeholder-image]")
.first()
.should($el => {
// traced falls back to DOMINANT_COLOR
expect($el.prop("tagName")).to.be.equal("DIV")
expect($el).to.be.empty
})
cy.get(".full [data-placeholder-image]")
.first()
.should($el => {
expect($el.prop("tagName")).to.be.equal("DIV")
expect($el).to.be.empty
})
})
}
)
cy.get(".full [data-placeholder-image]")
.first()
.should($el => {
expect($el.prop("tagName")).to.be.equal("DIV")
expect($el).to.be.empty
})
})
}
)
}
Loading

0 comments on commit d31412a

Please sign in to comment.