Skip to content

Commit 841c0d2

Browse files
DanielSLewwardpeet
andauthored
feat(gatsby-plugin-gatsby-cloud): add prototype of preview indicator (#30839)
Co-authored-by: Ward Peeters <[email protected]>
1 parent 9a4d1ae commit 841c0d2

File tree

6 files changed

+1657
-34
lines changed

6 files changed

+1657
-34
lines changed

packages/gatsby-plugin-gatsby-cloud/package.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,13 @@
1616
"devDependencies": {
1717
"@babel/cli": "^7.12.1",
1818
"@babel/core": "^7.12.3",
19+
"@testing-library/dom": "^7.30.3",
20+
"@testing-library/jest-dom": "^5.11.10",
21+
"@testing-library/react": "^11.2.6",
22+
"@testing-library/user-event": "^13.1.3",
1923
"babel-preset-gatsby-package": "^1.4.0-next.0",
20-
"cross-env": "^7.0.3"
24+
"cross-env": "^7.0.3",
25+
"jest": "^26.6.3"
2126
},
2227
"homepage": "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-gatsby-cloud#readme",
2328
"keywords": [
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
import React from "react"
2+
import "@testing-library/jest-dom"
3+
import userEvent from "@testing-library/user-event"
4+
import { render, screen } from "@testing-library/react"
5+
6+
import { wrapPageElement } from "../gatsby-browser"
7+
import Indicator from "../indicator"
8+
9+
describe(`Preview status indicator`, () => {
10+
const waitForPoll = ms =>
11+
new Promise(resolve => setTimeout(resolve, ms || 50))
12+
13+
describe(`wrapPageElement`, () => {
14+
const testMessage = `Test Page`
15+
16+
beforeEach(() => {
17+
global.fetch = jest.fn(() =>
18+
Promise.resolve({
19+
json: () => {
20+
return {
21+
currentBuild: { id: `123`, buildStatus: `SUCCESS` },
22+
latestBuild: { id: `1234`, buildStatus: `SUCCESS` },
23+
}
24+
},
25+
})
26+
)
27+
})
28+
29+
it(`renders the initial page and indicator if indicator enabled`, async () => {
30+
process.env.GATSBY_PREVIEW_INDICATOR_ENABLED = `true`
31+
32+
render(
33+
wrapPageElement({
34+
element: <div>{testMessage}</div>,
35+
})
36+
)
37+
38+
await waitForPoll()
39+
40+
expect(screen.getByText(testMessage)).toBeInTheDocument()
41+
expect(
42+
screen.queryByTestId(`preview-status-indicator`)
43+
).toBeInTheDocument()
44+
})
45+
46+
it(`renders page without the indicator if indicator not enabled`, () => {
47+
process.env.GATSBY_PREVIEW_INDICATOR_ENABLED = `false`
48+
49+
render(
50+
wrapPageElement({
51+
element: <div>{testMessage}</div>,
52+
})
53+
)
54+
55+
expect(screen.getByText(testMessage)).toBeInTheDocument()
56+
expect(
57+
screen.queryByTestId(`preview-status-indicator`)
58+
).not.toBeInTheDocument()
59+
})
60+
61+
it(`renders initial page without indicator if Indicator errors`, async () => {
62+
render(
63+
wrapPageElement({
64+
element: <div>{testMessage}</div>,
65+
})
66+
)
67+
68+
global.fetch = jest.fn(() =>
69+
Promise.resolve({ json: () => new Error(`failed`) })
70+
)
71+
72+
await waitForPoll()
73+
74+
expect(screen.getByText(testMessage)).toBeInTheDocument()
75+
expect(
76+
screen.queryByTestId(`preview-status-indicator`)
77+
).not.toBeInTheDocument()
78+
})
79+
})
80+
81+
describe(`Indicator component`, () => {
82+
beforeEach(() => {
83+
render(<Indicator />)
84+
})
85+
86+
describe(`Success state`, () => {
87+
beforeEach(async () => {
88+
global.fetch = jest.fn(() =>
89+
Promise.resolve({
90+
json: () => {
91+
return {
92+
currentBuild: { id: `123`, buildStatus: `SUCCESS` },
93+
latestBuild: { id: `1234`, buildStatus: `SUCCESS` },
94+
}
95+
},
96+
})
97+
)
98+
99+
await waitForPoll()
100+
})
101+
102+
it(`renders when more recent successful build available`, async () => {
103+
expect(screen.getByText(`New preview available`)).toBeInTheDocument()
104+
})
105+
106+
it(`navigates to new build when indicator is clicked`, async () => {
107+
delete window.location
108+
window.location = new URL(`https://preview-testsite.gtsb.io`)
109+
window.location.replace = jest.fn(
110+
() => (window.location = new URL(`https://build-123.gtsb.io`))
111+
)
112+
113+
const previewIndicator = screen.getByText(`New preview available`)
114+
userEvent.click(previewIndicator)
115+
await waitForPoll(300)
116+
117+
expect(String(window.location)).toBe(`https://build-123.gtsb.io/`)
118+
})
119+
})
120+
121+
it(`renders FAILED state when most recent build failed`, async () => {
122+
global.fetch = jest.fn(() =>
123+
Promise.resolve({
124+
json: () => {
125+
return {
126+
currentBuild: { id: `123`, buildStatus: `ERROR` },
127+
latestBuild: { id: `1234`, buildStatus: `SUCCESS` },
128+
}
129+
},
130+
})
131+
)
132+
133+
await waitForPoll()
134+
135+
expect(
136+
screen.getByText(`Latest preview build failed`)
137+
).toBeInTheDocument()
138+
})
139+
140+
it(`renders BUILDING state when most recent build is currently building`, async () => {
141+
global.fetch = jest.fn(() =>
142+
Promise.resolve({
143+
json: () => {
144+
return {
145+
currentBuild: { id: `123`, buildStatus: `BUILDING` },
146+
latestBuild: { id: `1234`, buildStatus: `SUCCESS` },
147+
}
148+
},
149+
})
150+
)
151+
152+
await waitForPoll()
153+
154+
expect(screen.getByText(`New preview building`)).toBeInTheDocument()
155+
})
156+
157+
it(`renders NO state when on most successful build`, async () => {
158+
global.fetch = jest.fn(() =>
159+
Promise.resolve({
160+
json: () => {
161+
return {
162+
currentBuild: { id: `123`, buildStatus: `SUCCESS` },
163+
latestBuild: { id: `123`, buildStatus: `SUCCESS` },
164+
}
165+
},
166+
})
167+
)
168+
169+
expect(
170+
screen.queryByTestId(`preview-status-indicator`)
171+
).not.toBeInTheDocument()
172+
})
173+
})
174+
})

packages/gatsby-plugin-gatsby-cloud/src/constants.js

+2
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,5 @@ export const LINK_REGEX = /^(Link: <\/)(.+)(>;.+)/
4141
export const COMMON_BUNDLES = [`commons`, `app`]
4242

4343
export const PAGE_DATA_DIR = `page-data/`
44+
45+
export const POLLING_INTERVAL = 5000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from "react"
2+
import Indicator from "./indicator"
3+
4+
export const wrapPageElement = ({ element }) => {
5+
if (process.env.GATSBY_PREVIEW_INDICATOR_ENABLED === `true`) {
6+
return <Indicator>{element}</Indicator>
7+
} else {
8+
return <>{element}</>
9+
}
10+
}

0 commit comments

Comments
 (0)