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

fix(gatsby-remark-images): regenerate markdown when used image changes #34433

Merged
merged 16 commits into from
Jan 18, 2022
Merged
8 changes: 8 additions & 0 deletions e2e-tests/development-runtime/content/md-image.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: Hello World
date: 2018-12-14
---

This is a truly meaningful blog post

![Image](../src/images/image.png)
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,68 @@ const TEST_ID = `sub-title`
const message = `This is a sub-title`

describe(`hot reloading non-js file`, () => {
beforeEach(() => {
cy.exec(
`npm run update -- --file content/2018-12-14-hello-world.md --replacements "${message}:%${TEMPLATE}%" --exact`
)
cy.wait(1000)
describe(`markdown`, () => {
beforeEach(() => {
cy.exec(
`npm run update -- --file content/2018-12-14-hello-world.md --replacements "${message}:%${TEMPLATE}%" --exact`
)
cy.wait(1000)

cy.visit(`/2018-12-14-hello-world/`).waitForRouteChange()

cy.wait(1000)
})

it(`displays placeholder content on launch`, () => {
cy.getTestElement(TEST_ID).invoke(`text`).should(`contain`, TEMPLATE)
})

it(`hot reloads with new content`, () => {
cy.getTestElement(TEST_ID).invoke(`text`).should(`contain`, TEMPLATE)

cy.exec(
`npm run update -- --file content/2018-12-14-hello-world.md --replacements "${TEMPLATE}:${message}"`
)

// wait for socket.io to update
cy.wait(5000)

cy.getTestElement(TEST_ID).invoke(`text`).should(`eq`, message)
})
})

cy.visit(`/2018-12-14-hello-world/`).waitForRouteChange()
describe(`image`, () => {
beforeEach(() => {
cy.visit(`/md-image/`).waitForRouteChange()
cy.wait(1000)

cy.wait(1000)
})
cy.exec(
`npm run update -- --file src/images/image.png --copy "src/images/original.png"`
)
cy.wait(2000)
})

it(`displays placeholder content on launch`, () => {
cy.getTestElement(TEST_ID).invoke(`text`).should(`contain`, TEMPLATE)
})
const runImageSnapshot = (snapshotName) => {
cy.get(`.gatsby-resp-image-wrapper`)
.find("img")
.each(($el, i) => {
cy.wrap($el).matchImageSnapshot(`${snapshotName}-${i}`)
})
}

it(`hot reloads with new content`, () => {
cy.getTestElement(TEST_ID).invoke(`text`).should(`contain`, TEMPLATE)
it(`displays original content on launch`, () => {
runImageSnapshot(`non-js-file--image-original`)
})

cy.exec(
`npm run update -- --file content/2018-12-14-hello-world.md --replacements "${TEMPLATE}:${message}"`
)
it(`hot reloads with new content`, () => {
cy.exec(
`npm run update -- --file src/images/image.png --copy "src/images/new.png"`
)

// wati for socket.io to update
cy.wait(5000)
// wait for socket.io to update
cy.wait(5000)

cy.getTestElement(TEST_ID).invoke(`text`).should(`eq`, message)
runImageSnapshot(`non-js-file--image-new`)
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ describe(`collection-routing`, () => {
})

it(`can navigate to a collection route and see its content rendered`, () => {
// this test depends on the alphabetical sorting of markdown files
cy.findByTestId(`collection-routing-blog-0`)
cy.should(`have.attr`, `data-testslug`, `/2018-12-14-hello-world/`)
.should(`have.attr`, `data-testslug`, `/2018-12-14-hello-world/`)
.click()
cy.waitForRouteChange()
.assertRoute(`/collection-routing/2018-12-14-hello-world/`)
Expand All @@ -25,8 +26,9 @@ describe(`collection-routing`, () => {
})

it(`can navigate to a collection route that uses unions and see its content rendered`, () => {
// this test depends on the alphabetical sorting of image files
cy.findByTestId(`collection-routing-image-0`)
cy.should(`have.attr`, `data-testimagename`, `gatsby-astronaut`)
.should(`have.attr`, `data-testimagename`, `gatsby-astronaut`)
.click()
cy.waitForRouteChange()
.assertRoute(`/collection-routing/gatsby-astronaut/`)
Expand Down
10 changes: 10 additions & 0 deletions e2e-tests/development-runtime/cypress/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// the project's config changing)
const blockResources = require(`./block-resources`)
const gatsbyConfig = require(`./gatsby-config`)
const { addMatchImageSnapshotPlugin } = require("cypress-image-snapshot/plugin")

module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
Expand All @@ -20,4 +21,13 @@ module.exports = (on, config) => {
...blockResources,
...gatsbyConfig,
})

addMatchImageSnapshotPlugin(on, config)
on("before:browser:launch", (browser = {}, launchOptions) => {
if (browser.family === "chromium" || browser.family === "chrome") {
// Make retina screens run at 1x density so they match the versions in CI
launchOptions.args.push("--force-device-scale-factor=1")
}
return launchOptions
})
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions e2e-tests/development-runtime/cypress/support/commands.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import "@testing-library/cypress/add-commands"
import { addMatchImageSnapshotCommand } from "cypress-image-snapshot/command"
import "gatsby-cypress"

Cypress.Commands.add(`lifecycleCallCount`, action =>
cy
Expand Down Expand Up @@ -113,3 +115,12 @@ Cypress.Commands.add(`getFastRefreshOverlay`, () => (
Cypress.Commands.add(`assertNoFastRefreshOverlay`, () => (
cy.get('gatsby-fast-refresh').should('not.exist')
))

addMatchImageSnapshotCommand({
customDiffDir: `/__diff_output__`,
customDiffConfig: {
threshold: 0.1,
},
failureThreshold: 0.08,
failureThresholdType: `percent`,
})
5 changes: 4 additions & 1 deletion e2e-tests/development-runtime/gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ module.exports = {
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [`gatsby-remark-subcache`],
plugins: [
`gatsby-remark-subcache`,
`gatsby-remark-images`
],
},
},
`gatsby-plugin-sharp`,
Expand Down
6 changes: 4 additions & 2 deletions e2e-tests/development-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"author": "Dustin Schau <[email protected]>",
"dependencies": {
"babel-plugin-search-and-replace": "^1.1.0",
"gatsby": "^3.0.0-next.6",
"gatsby": "^4.6.0-next.4",
"gatsby-image": "^3.0.0-next.0",
"gatsby-plugin-image": "^1.0.0-next.5",
"gatsby-plugin-less": "^5.1.0-next.2",
Expand All @@ -15,10 +15,11 @@
"gatsby-plugin-sass": "^4.1.0-next.2",
"gatsby-plugin-sharp": "^3.0.0-next.5",
"gatsby-plugin-stylus": "^3.1.0-next.2",
"gatsby-remark-images": "^6.6.0-next.2",
"gatsby-seo": "^0.1.0",
"gatsby-source-filesystem": "^3.0.0-next.2",
"gatsby-transformer-json": "^3.0.0-next.0",
"gatsby-transformer-remark": "^3.0.0-next.0",
"gatsby-transformer-remark": "^5.6.0-next.2",
"gatsby-transformer-sharp": "^3.0.0-next.1",
"node-fetch": "^2.6.1",
"prop-types": "^15.6.2",
Expand Down Expand Up @@ -56,6 +57,7 @@
"@testing-library/cypress": "^7.0.0",
"cross-env": "^5.2.0",
"cypress": "6.1.0",
"cypress-image-snapshot": "^4.0.1",
"fs-extra": "^7.0.1",
"gatsby-core-utils": "^2.12.0",
"gatsby-cypress": "^0.1.7",
Expand Down
9 changes: 8 additions & 1 deletion e2e-tests/development-runtime/scripts/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const args = yargs
default: [],
type: `array`,
})
.option(`copy`, {
default: undefined,
type: `string`,
})
.option(`exact`, {
default: false,
type: `boolean`,
Expand Down Expand Up @@ -50,7 +54,7 @@ const args = yargs
async function update() {
const history = await getHistory()

const { file: fileArg, replacements, restore } = args
const { file: fileArg, replacements, restore, copy } = args
const filePath = path.resolve(fileArg)
if (restore) {
const original = history.get(filePath)
Expand Down Expand Up @@ -85,6 +89,9 @@ async function update() {
if (exists) {
await fs.remove(filePath)
}
} else if(args.copy) {
const copyFileContent = await fs.readFile(args.copy)
await fs.writeFile(filePath, copyFileContent)
} else {
const contents = replacements.reduce((replaced, pair) => {
const [key, value] = pair.split(`:`)
Expand Down
3 changes: 3 additions & 0 deletions e2e-tests/development-runtime/snapshots.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
"__version": "6.1.0"
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added e2e-tests/development-runtime/src/images/new.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Layout from "../../components/layout"
export default function Index(props) {
return (
<Layout>
{props.data.markdown.nodes.map((node, index) => {
{props.data.markdown.nodes.sort((a, b) => a.fields.slug.localeCompare(b.fields.slug)).map((node, index) => {
return (
<Link
key={node.gatsbyPath}
Expand All @@ -17,7 +17,7 @@ export default function Index(props) {
</Link>
)
})}
{props.data.images.nodes.map((node, index) => {
{props.data.images.nodes.sort((a, b) => a.parent.name.localeCompare(b.parent.name)).map((node, index) => {
return (
<Link
key={node.gatsbyPath}
Expand Down Expand Up @@ -49,7 +49,7 @@ export const query = graphql`
}
}

images: allImageSharp(limit: 1, skip: 1) {
images: allImageSharp {
nodes {
parent {
... on File {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,37 @@ exports[`it transforms images in markdown 1`] = `
</span>"
`;

exports[`it transforms images in markdown and uses getRemarkFileDependency when given 1`] = `
"<span
class=\\"gatsby-resp-image-wrapper\\"
style=\\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 300px; \\"
>
<a
class=\\"gatsby-resp-image-link\\"
href=\\"not-a-real-dir/not-a-real-dir/images/my-image.jpeg\\"
style=\\"display: block\\"
target=\\"_blank\\"
rel=\\"noopener\\"
>
<span
class=\\"gatsby-resp-image-background-image\\"
style=\\"padding-bottom: 133.33333333333331%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw'); background-size: cover; display: block;\\"
></span>
<img
class=\\"gatsby-resp-image-image\\"
alt=\\"image\\"
title=\\"image\\"
src=\\"not-a-real-dir/not-a-real-dir/images/my-image.jpeg\\"
srcset=\\"not-a-real-dir/not-a-real-dir/images/my-image.jpeg, not-a-real-dir/not-a-real-dir/images/my-image.jpeg\\"
sizes=\\"(max-width: 650px) 100vw, 650px\\"
style=\\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\\"
loading=\\"lazy\\"
decoding=\\"async\\"
/>
</a>
</span>"
`;

exports[`it transforms images in markdown with query strings 1`] = `
"<span
class=\\"gatsby-resp-image-wrapper\\"
Expand Down
46 changes: 40 additions & 6 deletions packages/gatsby-remark-images/src/__tests__/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,27 @@ const createNode = content => {
return markdownNode
}

const createPluginOptions = (content, imagePaths = `/`) => {
const createPluginOptions = (
content,
imagePaths = `/`,
passGetRemarkFileDependency = false
) => {
const dirName = `not-a-real-dir`
const mockGetImageNode = imagePath => {
return {
absolutePath: queryString.parseUrl(`${dirName}/${imagePath}`).url,
}
}

let getRemarkFileDependency
if (passGetRemarkFileDependency) {
getRemarkFileDependency = jest.fn(fileQuery =>
mockGetImageNode(fileQuery.absolutePath.eq)
)
}

return {
files: [].concat(imagePaths).map(imagePath => {
return {
absolutePath: queryString.parseUrl(`${dirName}/${imagePath}`).url,
}
}),
files: [].concat(imagePaths).map(mockGetImageNode),
markdownNode: createNode(content),
markdownAST: remark.parse(content),
getNode: () => {
Expand All @@ -82,6 +95,7 @@ const createPluginOptions = (content, imagePaths = `/`) => {
parseString: remark.parse.bind(remark),
generateHTML: node => hastToHTML(toHAST(node)),
},
getRemarkFileDependency,
}
}

Expand Down Expand Up @@ -119,6 +133,26 @@ test(`it leaves files with unsupported file extensions alone`, async () => {
expect(result).toEqual([])
})

test(`it transforms images in markdown and uses getRemarkFileDependency when given`, async () => {
const imagePath = `images/my-image.jpeg`
const content = `

![image](./${imagePath})
`.trim()

const pluginOptions = createPluginOptions(content, imagePath, true)
const nodes = await plugin(pluginOptions)

expect(nodes.length).toBe(1)

const node = nodes.pop()
expect(node.type).toBe(`html`)
expect(node.value).toMatchSnapshot()
expect(node.value).not.toMatch(`<html>`)

expect(pluginOptions.getRemarkFileDependency.mock.calls.length).toBe(1)
})

test(`it transforms images in markdown`, async () => {
const imagePath = `images/my-image.jpeg`
const content = `
Expand Down
Loading