Skip to content

Commit

Permalink
feat(gatsby-script): Script component (#35403)
Browse files Browse the repository at this point in the history
Co-authored-by: tyhopp <[email protected]>
Co-authored-by: Michal Piechowiak <[email protected]>
Co-authored-by: Jude Agboola <[email protected]>
  • Loading branch information
4 people authored May 19, 2022
1 parent 09a6dd9 commit a88703f
Show file tree
Hide file tree
Showing 79 changed files with 2,985 additions and 65 deletions.
3 changes: 3 additions & 0 deletions e2e-tests/development-runtime/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,6 @@ cypress/videos
__history__.json

src/gatsby-types.d.ts
/test-results/
/playwright-report/
/playwright/.cache/
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import { inlineScript } from "../../../gatsby-script-scripts"
import { resourceRecord, markRecord } from "../../../gatsby-script-records"

const page = {
target: `/gatsby-script-inline-scripts/`,
navigation: `/gatsby-script-navigation/`,
}

const typesOfInlineScripts = [
{
descriptor: `dangerouslySetInnerHTML`,
inlineScriptType: inlineScript.dangerouslySet,
},
{
descriptor: `template literals`,
inlineScriptType: inlineScript.templateLiteral,
},
]

/**
* Normally we would duplicate the tests so they're flatter and easier to debug,
* but since the test count grew and the cases are exactly the same we'll iterate.
*/

for (const { descriptor, inlineScriptType } of typesOfInlineScripts) {
describe(`inline scripts set via ${descriptor}`, () => {
describe(`using the post-hydrate strategy`, () => {
it(`should execute successfully`, () => {
cy.visit(page.target)

cy.getRecord(
`post-hydrate-${inlineScriptType}`,
`success`,
true
).should(`equal`, `true`)
})

it(`should load after the framework bundle has loaded`, () => {
cy.visit(page.target)

// Assert framework is loaded before inline script is executed
cy.getRecord(
`post-hydrate-${inlineScriptType}`,
markRecord.executeStart
).then(dangerouslySetExecuteStart => {
cy.getRecord(`framework`, resourceRecord.responseEnd).should(
`be.lessThan`,
dangerouslySetExecuteStart
)
})
})
})

describe(`using the idle strategy`, () => {
it(`should execute successfully`, () => {
cy.visit(page.target)

cy.getRecord(`idle-${inlineScriptType}`, `success`, true).should(
`equal`,
`true`
)
})

it(`should load after other strategies`, () => {
cy.visit(page.target)

cy.getRecord(`idle-${inlineScriptType}`, markRecord.executeStart).then(
dangerouslySetExecuteStart => {
cy.getRecord(
`post-hydrate-${inlineScriptType}`,
markRecord.executeStart
).should(`be.lessThan`, dangerouslySetExecuteStart)
}
)
})
})

describe(`when navigation occurs`, () => {
it(`should load only once on initial page load`, () => {
cy.visit(page.target)

cy.get(`table[id=script-mark-records] tbody`)
.children()
.should(`have.length`, 4)
cy.getRecord(
`post-hydrate-${inlineScriptType}`,
`strategy`,
true
).should(`equal`, `post-hydrate`)
cy.getRecord(`idle-${inlineScriptType}`, `strategy`, true).should(
`equal`,
`idle`
)
})

it(`should load only once after the page is refreshed`, () => {
cy.visit(page.target).waitForRouteChange()
cy.reload().url().should(`contain`, page.target)

cy.get(`table[id=script-mark-records] tbody`)
.children()
.should(`have.length`, 4)
cy.getRecord(
`post-hydrate-${inlineScriptType}`,
`strategy`,
true
).should(`equal`, `post-hydrate`)
cy.getRecord(`idle-${inlineScriptType}`, `strategy`, true).should(
`equal`,
`idle`
)
})

it(`should load only once after anchor link navigation`, () => {
cy.visit(page.target)
cy.get(`a[id=anchor-link-back-to-index]`).click()
cy.url().should(`contain`, page.navigation)
cy.get(`a[href="${page.target}"][id=anchor-link]`).click()

cy.get(`table[id=script-mark-records] tbody`)
.children()
.should(`have.length`, 4)
cy.getRecord(
`post-hydrate-${inlineScriptType}`,
`strategy`,
true
).should(`equal`, `post-hydrate`)
cy.getRecord(`idle-${inlineScriptType}`, `strategy`, true).should(
`equal`,
`idle`
)
})

it(`should load only once if the page is revisited via browser back/forward buttons after anchor link navigation`, () => {
cy.visit(page.navigation).waitForRouteChange()
cy.get(`a[href="${page.target}"][id=anchor-link]`).click()
cy.get(`table[id=script-mark-records] tbody`) // Make sure history has time to change
cy.go(`back`)
cy.go(`forward`)

cy.get(`table[id=script-mark-records] tbody`)
.children()
.should(`have.length`, 4)
cy.getRecord(
`post-hydrate-${inlineScriptType}`,
`strategy`,
true
).should(`equal`, `post-hydrate`)
cy.getRecord(`idle-${inlineScriptType}`, `strategy`, true).should(
`equal`,
`idle`
)
})

it(`should load only once after Gatsby link navigation`, () => {
cy.visit(page.target)
cy.get(`a[id=gatsby-link-back-to-index]`).click()
cy.get(`a[href="${page.target}"][id=gatsby-link]`).click()

cy.get(`table[id=script-mark-records] tbody`)
.children()
.should(`have.length`, 4)
cy.getRecord(
`post-hydrate-${inlineScriptType}`,
`strategy`,
true
).should(`equal`, `post-hydrate`)
cy.getRecord(`idle-${inlineScriptType}`, `strategy`, true).should(
`equal`,
`idle`
)
})

it(`should load only once if the page is revisited via browser back/forward buttons after Gatsby link navigation`, () => {
cy.visit(page.navigation)
cy.get(`a[href="${page.target}"][id=gatsby-link]`).click()
cy.go(`back`)
cy.go(`forward`)

cy.get(`table[id=script-mark-records] tbody`)
.children()
.should(`have.length`, 4)
cy.getRecord(
`post-hydrate-${inlineScriptType}`,
`strategy`,
true
).should(`equal`, `post-hydrate`)
cy.getRecord(`idle-${inlineScriptType}`, `strategy`, true).should(
`equal`,
`idle`
)
})
})
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
import { script } from "../../../gatsby-script-scripts"
import { resourceRecord } from "../../../gatsby-script-records"

const page = {
target: `/gatsby-script-scripts-with-sources/`,
navigation: `/gatsby-script-navigation/`,
}

describe(`scripts with sources`, () => {
describe(`using the post-hydrate strategy`, () => {
it(`should load successfully`, () => {
cy.visit(page.target)
cy.getRecord(script.three, `success`, true).should(`equal`, `true`)
})

it(`should load after the framework bundle has loaded`, () => {
cy.visit(page.target)

// Assert framework is loaded before three starts loading
cy.getRecord(script.three, resourceRecord.fetchStart).then(
threeFetchStart => {
cy.getRecord(`framework`, resourceRecord.responseEnd).should(
`be.lessThan`,
threeFetchStart
)
}
)
})

it(`should call an on load callback once the script has loaded`, () => {
cy.visit(page.target)
cy.getRecord(script.three, resourceRecord.responseEnd).then(() => {
cy.get(`[data-on-load-result=post-hydrate]`)
})
})

it(`should call an on error callback if an error occurred`, () => {
cy.visit(page.target)
cy.get(`[data-on-error-result=post-hydrate]`)
})
})

describe(`using the idle strategy`, () => {
it(`should load successfully`, () => {
cy.visit(page.target)
cy.getRecord(script.marked, `success`, true).should(`equal`, `true`)
})

it(`should load after other strategies`, () => {
cy.visit(page.target)

cy.getRecord(script.marked, resourceRecord.fetchStart).then(
markedFetchStart => {
cy.getRecord(script.three, resourceRecord.fetchStart).should(
`be.lessThan`,
markedFetchStart
)
}
)
})

it(`should call an on load callback once the script has loaded`, () => {
cy.visit(page.target)
cy.getRecord(script.marked, resourceRecord.responseEnd).then(() => {
cy.get(`[data-on-load-result=idle]`)
})
})

it(`should call an on error callback if an error occurred`, () => {
cy.visit(page.target)
cy.get(`[data-on-error-result=idle]`)
})
})

describe(`when navigation occurs`, () => {
it(`should load only once on initial page load`, () => {
cy.visit(page.target)

cy.get(`table[id=script-resource-records] tbody`)
.children()
.should(`have.length`, 5)
cy.getRecord(script.three, `strategy`, true).should(
`equal`,
`post-hydrate`
)
cy.getRecord(script.marked, `strategy`, true).should(`equal`, `idle`)
})

it(`should load only once after the page is refreshed`, () => {
cy.visit(page.target)
cy.reload()

cy.get(`table[id=script-resource-records] tbody`)
.children()
.should(`have.length`, 5)
cy.getRecord(script.three, `strategy`, true).should(
`equal`,
`post-hydrate`
)
cy.getRecord(script.marked, `strategy`, true).should(`equal`, `idle`)
})

it(`should load only once after anchor link navigation`, () => {
cy.visit(page.target)
cy.get(`a[id=anchor-link-back-to-index]`).click()
cy.url().should(`contain`, page.navigation)
cy.get(`a[href="${page.target}"][id=anchor-link]`).click()

cy.get(`table[id=script-resource-records] tbody`)
.children()
.should(`have.length`, 5)
cy.getRecord(script.three, `strategy`, true).should(
`equal`,
`post-hydrate`
)
cy.getRecord(script.marked, `strategy`, true).should(`equal`, `idle`)
})

it(`should load only once if the page is revisited via browser back/forward buttons after anchor link navigation`, () => {
cy.visit(page.navigation)
cy.get(`a[href="${page.target}"][id=anchor-link]`).click()
cy.go(`back`)
cy.go(`forward`)

cy.get(`table[id=script-resource-records] tbody`)
.children()
.should(`have.length`, 5)
cy.getRecord(script.three, `strategy`, true).should(
`equal`,
`post-hydrate`
)
cy.getRecord(script.marked, `strategy`, true).should(`equal`, `idle`)
})

it(`should load only once after Gatsby link navigation`, () => {
cy.visit(page.target)
cy.get(`a[id=gatsby-link-back-to-index]`).click()
cy.get(`a[href="${page.target}"][id=gatsby-link]`).click()

cy.get(`table[id=script-resource-records] tbody`)
.children()
.should(`have.length`, 5)
cy.getRecord(script.three, `strategy`, true).should(
`equal`,
`post-hydrate`
)
cy.getRecord(script.marked, `strategy`, true).should(`equal`, `idle`)
})

it(`should load only once if the page is revisited via browser back/forward buttons after Gatsby link navigation`, () => {
cy.visit(page.navigation)
cy.get(`a[href="${page.target}"][id=gatsby-link]`).click()
cy.go(`back`)
cy.go(`forward`)

cy.get(`table[id=script-resource-records] tbody`)
.children()
.should(`have.length`, 5)
cy.getRecord(script.three, `strategy`, true).should(
`equal`,
`post-hydrate`
)
cy.getRecord(script.marked, `strategy`, true).should(`equal`, `idle`)
})
})
})
Loading

0 comments on commit a88703f

Please sign in to comment.