Skip to content

Commit

Permalink
Add Selenium downloadFile command
Browse files Browse the repository at this point in the history
  • Loading branch information
ccharnkij committed May 2, 2024
1 parent 8096b20 commit 06f273f
Show file tree
Hide file tree
Showing 6 changed files with 366 additions and 0 deletions.
126 changes: 126 additions & 0 deletions package-lock.json

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

43 changes: 43 additions & 0 deletions packages/wdio-protocols/src/protocols/selenium.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,49 @@ export default {
},
},
},
'/session/:sessionId/se/files': {
GET: {
command: 'getDownloadableFiles',
description:
'List files from remote machine available for download.',
ref: 'https://www.seleniumhq.org/',
parameters: [],
returns: {
type: 'Object',
name: 'names',
description:
'Object containing a list of downloadable files on remote machine.',
},
},
POST: {
command: 'download',
description:
'Download a file from remote machine on which the browser is running.',
ref: 'https://www.seleniumhq.org/',
parameters: [
{
name: 'name',
type: 'string',
description:
'Name of the file to be downloaded',
required: true,
},
],
returns: {
type: 'Object',
name: 'data',
description:
'Object containing downloaded file name and its content',
},
},
DELETE: {
command: 'deleteDownloadableFiles',
description:
'Remove all downloadable files from remote machine on which the browser is running.',
ref: 'https://www.seleniumhq.org/',
parameters: [],
},
},
'/grid/api/hub/': {
GET: {
isHubCommand: true,
Expand Down
1 change: 1 addition & 0 deletions packages/webdriverio/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"grapheme-splitter": "^1.0.2",
"import-meta-resolve": "^4.0.0",
"is-plain-obj": "^4.1.0",
"jszip": "^3.10.1",
"lodash.clonedeep": "^4.5.0",
"lodash.zip": "^4.2.0",
"minimatch": "^9.0.0",
Expand Down
1 change: 1 addition & 0 deletions packages/webdriverio/src/commands/browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './browser/custom$$.js'
export * from './browser/custom$.js'
export * from './browser/debug.js'
export * from './browser/deleteCookies.js'
export * from './browser/downloadFile.js'
export * from './browser/emulate.js'
export * from './browser/execute.js'
export * from './browser/executeAsync.js'
Expand Down
87 changes: 87 additions & 0 deletions packages/webdriverio/src/commands/browser/downloadFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import fs from 'node:fs'
import path from 'node:path'
import JSZip from 'jszip'
/**
*
* Download a file from the remote computer running Selenium node to local file system
* by using the [`downloadFile`](https://webdriver.io/docs/api/selenium#downloadFile) command.
*
* _Note:_ that this command is only supported if you use a
* [Selenium Grid](https://www.selenium.dev/documentation/en/grid/) with Chrome, Edge or Firefox.
*
* <example>
:downloadFile.js
it('should download a file', async () => {
// capabilities: [
// {
// browserName: 'chrome',
// se:downloadsEnabled': true
// }]
await browser.url('https://www.selenium.dev/selenium/web/downloads/download.html')
await $('#file-1').click()
await browser.waitUntil(async function () {
return (await browser.getDownloadableFiles()).names.includes('file_1.txt')
}, {timeout: 5000})
const files = await browser.getDownloadableFiles()
await browser.downloadFile(files.names[0], process.cwd())
await browser.deleteDownloadableFiles()
})
* </example>
*
* @alias browser.downloadFile
* @param {string} fileName remote path to file
* @param {string} targetDirectory target location on local computer
* @type utility
* @uses protocol/download
*
*/
export async function downloadFile(
this: WebdriverIO.Browser,
fileName: string,
targetDirectory: string
) {
/**
* parameter check
*/
if (typeof fileName !== 'string' || typeof targetDirectory !== 'string') {
throw new Error('number or type of arguments don\'t agree with downloadFile command')
}

/**
* check if command is available
*/
if (typeof this.download !== 'function') {
throw new Error(`The downloadFile command is not available in ${(this.capabilities as WebdriverIO.Capabilities).browserName}`)
}

const response = await this.download(fileName)
const base64Content = response.contents

if (!targetDirectory.endsWith('/')) {
targetDirectory += '/'
}

fs.mkdirSync(targetDirectory, { recursive: true })
const zipFilePath = path.join(targetDirectory, `${fileName}.zip`)
fs.writeFileSync(zipFilePath, Buffer.from(base64Content, 'base64'))

const zipData = fs.readFileSync(zipFilePath)
await JSZip.loadAsync(zipData)
.then((zip) => {
// Iterate through each file in the zip archive
Object.keys(zip.files).forEach(async (fileName) => {
const fileData = await zip.files[fileName].async('nodebuffer')
fs.writeFileSync(`${targetDirectory}/${fileName}`, fileData)
console.log(`File extracted: ${fileName}`)
})
})
.catch((error) => {
console.error('Error unzipping file:', error)
})
}

0 comments on commit 06f273f

Please sign in to comment.