Skip to content

Commit 8b5ba75

Browse files
[js] download files from remote server (#13102)
* error if downloads are not enabled * unzip and download file to provided directory * getDownloadableFiles returns the names directly * fix unzipping files into target location (#13388) --------- Co-authored-by: harsha509 <[email protected]> Co-authored-by: Sri Harsha <[email protected]>
1 parent c2c41b8 commit 8b5ba75

File tree

5 files changed

+74
-3
lines changed

5 files changed

+74
-3
lines changed

javascript/node/selenium-webdriver/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const webdriver = require('./lib/webdriver')
4141
const select = require('./lib/select')
4242
const LogInspector = require('./bidi/logInspector')
4343
const BrowsingContext = require('./bidi/browsingContext')
44-
const BrowsingConextInspector = require('./bidi/browsingContextInspector')
44+
const BrowsingContextInspector = require('./bidi/browsingContextInspector')
4545
const ScriptManager = require('./bidi/scriptManager')
4646
const NetworkInspector = require('./bidi/networkInspector')
4747

@@ -720,7 +720,7 @@ class Builder {
720720
/**
721721
* In the 3.x releases, the various browser option classes
722722
* (e.g. firefox.Options) had to be manually set as an option using the
723-
* Capabilties class:
723+
* Capabilities class:
724724
*
725725
* let ffo = new firefox.Options();
726726
* // Configure firefox options...
@@ -802,6 +802,6 @@ exports.until = until
802802
exports.Select = select.Select
803803
exports.LogInspector = LogInspector
804804
exports.BrowsingContext = BrowsingContext
805-
exports.BrowsingConextInspector = BrowsingConextInspector
805+
exports.BrowsingContextInspector = BrowsingContextInspector
806806
exports.ScriptManager = ScriptManager
807807
exports.NetworkInspector = NetworkInspector

javascript/node/selenium-webdriver/lib/capabilities.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ const Capability = {
209209
* Used to upload a file when strict file interactability is on
210210
*/
211211
STRICT_FILE_INTERACTABILITY: 'strictFileInteractability',
212+
213+
214+
ENABLE_DOWNLOADS: "se:downloadsEnabled",
212215
}
213216

214217
/**
@@ -519,6 +522,10 @@ class Capabilities {
519522
strictFileInteractability
520523
)
521524
}
525+
526+
enableDownloads() {
527+
return this.set(Capability.ENABLE_DOWNLOADS, true)
528+
}
522529
}
523530

524531
/**

javascript/node/selenium-webdriver/lib/command.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ const Name = {
181181

182182
ACTIONS: 'actions',
183183
CLEAR_ACTIONS: 'clearActions',
184+
185+
GET_DOWNLOADABLE_FILES: "getDownloadableFiles",
186+
DOWNLOAD_FILE: "downloadFile",
187+
DELETE_DOWNLOADABLE_FILES: "deleteDownloadableFiles",
184188
}
185189

186190
/**

javascript/node/selenium-webdriver/lib/http.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ const W3C_COMMAND_MAP = new Map([
400400
cmd.Name.SET_USER_VERIFIED,
401401
post('/session/:sessionId/webauthn/authenticator/:authenticatorId/uv'),
402402
],
403+
404+
[cmd.Name.GET_DOWNLOADABLE_FILES, get('/session/:sessionId/se/files')],
405+
[cmd.Name.DOWNLOAD_FILE, post(`/session/:sessionId/se/files`)],
406+
[cmd.Name.DELETE_DOWNLOADABLE_FILES, del(`/session/:sessionId/se/files`)]
403407
])
404408

405409
/**

javascript/node/selenium-webdriver/lib/webdriver.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const webElement = require('./webelement')
4242
const { isObject } = require('./util')
4343
const BIDI = require('../bidi')
4444
const { PinnedScript } = require('./pinnedScript')
45+
const JSZip = require('jszip');
4546

4647
// Capability names that are defined in the W3C spec.
4748
const W3C_CAPABILITY_NAMES = new Set([
@@ -1726,6 +1727,61 @@ class WebDriver {
17261727
.setParameter('isUserVerified', verified)
17271728
)
17281729
}
1730+
1731+
async getDownloadableFiles() {
1732+
const caps = await this.getCapabilities()
1733+
if (!caps['map_'].get('se:downloadsEnabled')) {
1734+
throw new error.WebDriverError('Downloads must be enabled in options')
1735+
}
1736+
1737+
return (await this.execute(new command.Command(command.Name.GET_DOWNLOADABLE_FILES))).names
1738+
}
1739+
1740+
async downloadFile(fileName, targetDirectory) {
1741+
const caps = await this.getCapabilities();
1742+
if (!caps['map_'].get('se:downloadsEnabled')) {
1743+
throw new Error('Downloads must be enabled in options');
1744+
}
1745+
1746+
const response = await this.execute(
1747+
new command.Command(command.Name.DOWNLOAD_FILE).setParameter('name', fileName)
1748+
);
1749+
1750+
const base64Content = response.contents;
1751+
1752+
if (!targetDirectory.endsWith('/')) {
1753+
targetDirectory += '/';
1754+
}
1755+
1756+
fs.mkdirSync(targetDirectory, { recursive: true });
1757+
const zipFilePath = path.join(targetDirectory, `${fileName}.zip`);
1758+
fs.writeFileSync(zipFilePath, Buffer.from(base64Content, 'base64'));
1759+
1760+
const zipData = fs.readFileSync(zipFilePath);
1761+
await JSZip.loadAsync(zipData)
1762+
.then(zip => {
1763+
// Iterate through each file in the zip archive
1764+
Object.keys(zip.files).forEach(async (fileName) => {
1765+
const fileData = await zip.files[fileName].async('nodebuffer');
1766+
fs.writeFileSync(`${targetDirectory}/${fileName}`, fileData);
1767+
console.log(`File extracted: ${fileName}`);
1768+
});
1769+
})
1770+
.catch(error => {
1771+
console.error("Error unzipping file:", error);
1772+
});
1773+
}
1774+
1775+
async deleteDownloadableFiles() {
1776+
const caps = await this.getCapabilities()
1777+
if (!caps['map_'].get('se:downloadsEnabled')) {
1778+
throw new error.WebDriverError('Downloads must be enabled in options')
1779+
}
1780+
1781+
return await this.execute(
1782+
new command.Command(command.Name.DELETE_DOWNLOADABLE_FILES)
1783+
)
1784+
}
17291785
}
17301786

17311787
/**

0 commit comments

Comments
 (0)