Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: provide custom FILE_CDN url generator from adapter #38735

Merged
merged 11 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ jobs:

e2e_tests_adapters:
<<: *e2e-executor
docker:
- image: cypress/browsers:node-18.16.1-chrome-114.0.5735.133-1-ff-114.0.2-edge-114.0.1823.51-1
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newer node than e2e default needed for latest netlify-cli. As gatsby itself has node 18.0.0 min, we should not bump it in other tests so default stayed as is

steps:
- run: echo 'export CYPRESS_RECORD_KEY="${CY_CLOUD_ADAPTERS}"' >> "$BASH_ENV"
- e2e-test:
Expand Down
268 changes: 143 additions & 125 deletions e2e-tests/adapters/cypress/e2e/remote-file.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,16 @@ const configs = [
{
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,
},
]
Expand All @@ -57,89 +54,70 @@ for (const config of configs) {
cy.wait(600)
})

async function testImages(images, expectations) {
for (let i = 0; i < images.length; i++) {
const expectation = expectations[i]
describe(`Image CDN`, () => {
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 res = await fetch(url, {
method: "HEAD",
})
expect(res.ok).to.be.true

const expectedNaturalWidth =
expectation.naturalWidth ?? expectation.width
const expectedNaturalHeight =
expectation.naturalHeight ?? expectation.height
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
)
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`, () => {
if (config.fileCDN) {
cy.get('[data-testid="public"]').then(async $urls => {
it(`should render correct dimensions`, () => {
cy.get('[data-testid="image-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, {
// urls is array of href attribute, not absolute urls, so it already is stripped of origin
for (const urlWithoutOrigin of urls) {
// using Netlify Image CDN
expect(urlWithoutOrigin).to.match(/^\/.netlify\/images/)
const res = await fetch(urlWithoutOrigin, {
method: "HEAD",
})
expect(res.ok).to.be.true
}
})
}

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,
},
])
})

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 @@ -154,72 +132,112 @@ for (const config of configs) {
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(".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,
},
])
}
)
})

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`, () => {
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]")
cy.get(".full [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
})
})
})

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

// urls is array of href attribute, not absolute urls, so it already is stripped of origin
for (const urlWithoutOrigin of urls) {
// using Netlify Image CDN
expect(urlWithoutOrigin).to.match(
new RegExp(`^${PATH_PREFIX}/_gatsby/file`)
)
const res = await fetch(urlWithoutOrigin, {
method: "HEAD",
})
expect(res.ok).to.be.true
}
})
})
}
)
Expand Down