Skip to content

Commit

Permalink
feat(gatsby-plugin-gatsby-cloud): add prototype of preview indicator (#…
Browse files Browse the repository at this point in the history
…30839)

Co-authored-by: Ward Peeters <ward@coding-tech.com>
  • Loading branch information
DanielSLew and wardpeet committed Apr 23, 2021
1 parent 9a4d1ae commit 841c0d2
Show file tree
Hide file tree
Showing 6 changed files with 1,657 additions and 34 deletions.
7 changes: 6 additions & 1 deletion packages/gatsby-plugin-gatsby-cloud/package.json
Expand Up @@ -16,8 +16,13 @@
"devDependencies": {
"@babel/cli": "^7.12.1",
"@babel/core": "^7.12.3",
"@testing-library/dom": "^7.30.3",
"@testing-library/jest-dom": "^5.11.10",
"@testing-library/react": "^11.2.6",
"@testing-library/user-event": "^13.1.3",
"babel-preset-gatsby-package": "^1.4.0-next.0",
"cross-env": "^7.0.3"
"cross-env": "^7.0.3",
"jest": "^26.6.3"
},
"homepage": "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-gatsby-cloud#readme",
"keywords": [
Expand Down
174 changes: 174 additions & 0 deletions packages/gatsby-plugin-gatsby-cloud/src/__tests__/gatsby-browser.js
@@ -0,0 +1,174 @@
import React from "react"
import "@testing-library/jest-dom"
import userEvent from "@testing-library/user-event"
import { render, screen } from "@testing-library/react"

import { wrapPageElement } from "../gatsby-browser"
import Indicator from "../indicator"

describe(`Preview status indicator`, () => {
const waitForPoll = ms =>
new Promise(resolve => setTimeout(resolve, ms || 50))

describe(`wrapPageElement`, () => {
const testMessage = `Test Page`

beforeEach(() => {
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => {
return {
currentBuild: { id: `123`, buildStatus: `SUCCESS` },
latestBuild: { id: `1234`, buildStatus: `SUCCESS` },
}
},
})
)
})

it(`renders the initial page and indicator if indicator enabled`, async () => {
process.env.GATSBY_PREVIEW_INDICATOR_ENABLED = `true`

render(
wrapPageElement({
element: <div>{testMessage}</div>,
})
)

await waitForPoll()

expect(screen.getByText(testMessage)).toBeInTheDocument()
expect(
screen.queryByTestId(`preview-status-indicator`)
).toBeInTheDocument()
})

it(`renders page without the indicator if indicator not enabled`, () => {
process.env.GATSBY_PREVIEW_INDICATOR_ENABLED = `false`

render(
wrapPageElement({
element: <div>{testMessage}</div>,
})
)

expect(screen.getByText(testMessage)).toBeInTheDocument()
expect(
screen.queryByTestId(`preview-status-indicator`)
).not.toBeInTheDocument()
})

it(`renders initial page without indicator if Indicator errors`, async () => {
render(
wrapPageElement({
element: <div>{testMessage}</div>,
})
)

global.fetch = jest.fn(() =>
Promise.resolve({ json: () => new Error(`failed`) })
)

await waitForPoll()

expect(screen.getByText(testMessage)).toBeInTheDocument()
expect(
screen.queryByTestId(`preview-status-indicator`)
).not.toBeInTheDocument()
})
})

describe(`Indicator component`, () => {
beforeEach(() => {
render(<Indicator />)
})

describe(`Success state`, () => {
beforeEach(async () => {
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => {
return {
currentBuild: { id: `123`, buildStatus: `SUCCESS` },
latestBuild: { id: `1234`, buildStatus: `SUCCESS` },
}
},
})
)

await waitForPoll()
})

it(`renders when more recent successful build available`, async () => {
expect(screen.getByText(`New preview available`)).toBeInTheDocument()
})

it(`navigates to new build when indicator is clicked`, async () => {
delete window.location
window.location = new URL(`https://preview-testsite.gtsb.io`)
window.location.replace = jest.fn(
() => (window.location = new URL(`https://build-123.gtsb.io`))
)

const previewIndicator = screen.getByText(`New preview available`)
userEvent.click(previewIndicator)
await waitForPoll(300)

expect(String(window.location)).toBe(`https://build-123.gtsb.io/`)
})
})

it(`renders FAILED state when most recent build failed`, async () => {
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => {
return {
currentBuild: { id: `123`, buildStatus: `ERROR` },
latestBuild: { id: `1234`, buildStatus: `SUCCESS` },
}
},
})
)

await waitForPoll()

expect(
screen.getByText(`Latest preview build failed`)
).toBeInTheDocument()
})

it(`renders BUILDING state when most recent build is currently building`, async () => {
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => {
return {
currentBuild: { id: `123`, buildStatus: `BUILDING` },
latestBuild: { id: `1234`, buildStatus: `SUCCESS` },
}
},
})
)

await waitForPoll()

expect(screen.getByText(`New preview building`)).toBeInTheDocument()
})

it(`renders NO state when on most successful build`, async () => {
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => {
return {
currentBuild: { id: `123`, buildStatus: `SUCCESS` },
latestBuild: { id: `123`, buildStatus: `SUCCESS` },
}
},
})
)

expect(
screen.queryByTestId(`preview-status-indicator`)
).not.toBeInTheDocument()
})
})
})
2 changes: 2 additions & 0 deletions packages/gatsby-plugin-gatsby-cloud/src/constants.js
Expand Up @@ -41,3 +41,5 @@ export const LINK_REGEX = /^(Link: <\/)(.+)(>;.+)/
export const COMMON_BUNDLES = [`commons`, `app`]

export const PAGE_DATA_DIR = `page-data/`

export const POLLING_INTERVAL = 5000
10 changes: 10 additions & 0 deletions packages/gatsby-plugin-gatsby-cloud/src/gatsby-browser.js
@@ -0,0 +1,10 @@
import React from "react"
import Indicator from "./indicator"

export const wrapPageElement = ({ element }) => {
if (process.env.GATSBY_PREVIEW_INDICATOR_ENABLED === `true`) {
return <Indicator>{element}</Indicator>
} else {
return <>{element}</>
}
}

0 comments on commit 841c0d2

Please sign in to comment.