Skip to content

Commit

Permalink
Add tests for download
Browse files Browse the repository at this point in the history
  • Loading branch information
BenSurgisonGDS committed Jun 8, 2022
1 parent 8daa0dd commit 733c6d6
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 3 deletions.
18 changes: 18 additions & 0 deletions cypress/integration/2-create-pages/download.cypress.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { download } from '../utils'

describe('download page', () => {
beforeEach(() => {
cy.visit('/docs/tutorials-and-examples')
})

it('loaded ok', () => {
cy.get('a[data-link="download"]')
.should('contains.text', 'Download the Prototype Kit (zip file)')
.click()

cy.get('details a span')
.first()
.should('contains.text', 'Source code')
.then(download({ timeout: 60000 }))
})
})
30 changes: 30 additions & 0 deletions cypress/integration/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,37 @@ const waitForApplication = async () => {
.should('contains.text', 'Prototype your service using GOV.UK Prototype Kit')
}

const getFilename = ({ currentTarget }) => currentTarget.location.pathname
.split('/')
.pop()
.replace('v', 'govuk-prototype-kit-') + '.zip'

/* Based on the workaround examples here: https://github.com/cypress-io/cypress/issues/14857 */
const download = ({ timeout }) => (element) => {
cy.window().document().then(doc => {
doc.addEventListener('click', async (event) => {
const downloadsFolder = Cypress.config('downloadsFolder')
const filename = getFilename(event)
await sleep(1000)
cy.task('downloaded', { filename, downloadsFolder })
await sleep(1000)
cy.task('installApp', { timeout })
doc.location.reload()
})

/* Make sure the file exists */
cy.intercept('/', (req) => {
req.reply((res) => {
expect(res.statusCode).to.equal(200)
})
})

element.click()
})
}

module.exports = {
download,
sleep,
waitForApplication
}
79 changes: 76 additions & 3 deletions cypress/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,60 @@
// const spawn = require('child_process').spawn
const fs = require('fs')
const path = require('path')

const waitOn = require('wait-on')
const extract = require('extract-zip')
const { exec } = require('child_process')

const { sleep } = require('../integration/utils')
const { waitUntilFileExists } = require('../../lib/utils')

const createFolderForFile = (filepath) => {
const dir = filepath.substring(0, filepath.lastIndexOf('/'))
const separator = (filepath.indexOf('/') > -1) ? '/' : '\\'
const dir = filepath.substring(0, filepath.lastIndexOf(separator))
if (dir && !fs.existsSync(dir)) {
fs.mkdirSync(dir, {
recursive: true
})
}
}

const validateExtractedVersion = extractFolder => {
// Retrieve the name and version from the package.json from the extracted zip file
const data = fs.readFileSync(path.join(extractFolder, 'package.json'))
const { name, version } = JSON.parse(data)
// Retrieve the directory name of the extracted files
const separator = (extractFolder.indexOf('/') > -1) ? '/' : '\\'
const dirname = extractFolder.substring(extractFolder.lastIndexOf(separator) + 1)
// Make sure they match
if (`${name}-${version}` !== dirname) {
throw new Error(`Extracted folder ${extractFolder} contains wrong version in package.json >> ${name}-${version}`)
}
}

const waitForDownload = async (filename, previousModified = -1) => {
return new Promise((resolve) => {
const exists = fs.existsSync(filename)
const currentModified = exists ? fs.statSync(filename).mtime.getTime() : previousModified - 1
if (previousModified !== currentModified) {
setTimeout(() => waitForDownload(filename, currentModified).then(resolve), 100)
} else {
resolve()
}
})
}

const performInstall = async ({ folder }) => {
exec(`cd ${folder} && npm install`, (err, stdout, stderr) => {
if (err) {
throw new Error(err.message)
} else {
// the *entire* stdout and stderr (buffered)
console.log(`stdout: ${stdout}`)
console.log(`stderr: ${stderr}`)
}
})
}

/**
* @type {Cypress.PluginConfig}
*/
Expand All @@ -42,7 +82,22 @@ module.exports = (on, config) => {
const waitUntilAppRestarts = async (timeout) => await waitOn({ delay: 2000, resources: [config.baseUrl], timeout })

on('task', {
copyFile: async ({ source, target, timeout = 2000 }) => {
downloaded: async ({ filename, downloadsFolder }) => {
try {
const fullFilename = path.join(downloadsFolder, filename)
await waitForDownload(fullFilename)
await extract(fullFilename, { dir: downloadsFolder })
const extractFolder = fullFilename.substring(0, fullFilename.lastIndexOf('.zip'))
validateExtractedVersion(extractFolder)
return Promise.resolve(null)
} catch (err) {
return Promise.reject(err)
}
}
})

on('task', {
copyFile: async ({ source, target }) => {
try {
createFolderForFile(target)
fs.copyFileSync(source, target)
Expand All @@ -56,6 +111,24 @@ module.exports = (on, config) => {
}
})

on('task', {
installApp: async ({ timeout }) => {
try {
const downloadsFolder = path.join('cypress', 'downloads')
const files = fs.readdirSync(downloadsFolder)
if (files.length) {
const folder = path.join(downloadsFolder, files[0])
await performInstall({ folder })
const filename = path.join(folder, 'node_modules', 'govuk-frontend', 'package.json')
await waitUntilFileExists(filename, timeout)
}
return Promise.resolve(null)
} catch (err) {
return Promise.reject(err)
}
}
})

on('task', {
createFile: async ({ filename, data, replace = false }) => {
try {
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"optionalDependencies": {
"cypress": "^9.6.0",
"eslint-plugin-cypress": "^2.12.1",
"extract-zip": "^2.0.1",
"glob": "^7.1.4",
"jest": "^27.3.1",
"standard": "^14.3.3",
Expand Down

0 comments on commit 733c6d6

Please sign in to comment.