Skip to main content
Version: 10.2.4

Automate operations with files

Automate file download​

The example shows how to automate the Save File As system dialog. A file is saved by the Desktop driver.

tip

Your file is saved into the RPA Agent machine's temporary folder. To upload it on S3, use the S3 plugins.

You need to configure an S3 bucket first. To simulate the use of the S3 bucket, refer to Upload files to S3 Minio Storage.

The preconditions are as follows:

  • Local disk D.
  • temp.bucket as the S3 bucket name or any other name. In the latter case, make the corresponding changes in the script.

Switch to Save As in IE 11 and use desktop driver​

See the code below as an example:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://web-harvest.sourceforge.net/schema/1.0/config" scriptlang="groovy">

<robotics-flow>

<robot name="c3po" driver="internet explorer" close-on-completion="false">
<script><![CDATA[
pageLoadTimeout(3 * 1000)
try {
open('https://rpa-tutorial.s3.amazonaws.com/trainings/ie-download.html')
$(byPartialLinkText('Portable Zip')).click()
// If click was not performed, try this workaround:
// $(byPartialLinkText('Portable Zip')).sendKeys('').pressEnter()
} catch (org.openqa.selenium.TimeoutException ignored) {}
]]></script>
</robot>

<robot name="bsod" driver="desktop" close-on-completion="true">
<capability name="SEARCH_ALL_WINDOWS" value="true"></capability>
<script><![CDATA[

// Switch to 'Save' dialog by Alt+N
switchTo().window('[CLASS:IEFrame]')
sendKeys(Keys.chord(Keys.LEFT_ALT, 'n'))

// By TAB > ARROW_DOWN > ARROW_DOWN > ENTER pull up 'Save As' and click context menu item
pressTab()
sendKeys(Keys.ARROW_DOWN)
sendKeys(Keys.ARROW_DOWN)
pressEnter()

// Switching to 'Save As' window
switchTo().window('[CLASS:#32770]')

// Entering full path of file to be saved
def tempPath = 'D:\\_temp\\'
uniqueId = "${UUID.randomUUID()}.json"
def savePath = tempPath + uniqueId
$('[CLASS:Edit;INSTANCE:1]').sendKeys(savePath).pressEnter()

// saving file content to a byte array
file_content = downloadFileFromAgent(savePath)
]]></script>
</robot>

<robot name="c3po" driver="internet explorer" close-on-completion="true"/>

</robotics-flow>

<!-- creating a file on S3 storage -->
<var-def name="file_s3_location">
<s3 bucket="temp.bucket">
<s3-put path="_r2d2/${uniqueId}" content-type="application/json" content-disposition="inline" acl="PublicRead">
<script return='file_content' />
</s3-put>
</s3>
</var-def>

<export include-original-data="true">
<single-column name="file_s3_location" value="${file_s3_location}"/>
</export>
</config>

Download file in Chrome​

The implementation does not guarantee correct parallel execution of the script on a single node.

See the code below as an example:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://web-harvest.sourceforge.net/schema/1.0/config" scriptlang="groovy">

<script><![CDATA[
// Set your Chrome default download directory here
downloadDir = 'C:/Users/Your Username/Downloads/'

getLastModifiedFileName = {RemoteWebDriver aDriver, String dirPath ->
return (String) aDriver.executeScript(
" File dir = new File(\"" + dirPath.replace('\\', '/') + "\");\n" +
" File[] files = dir.listFiles();\n" +
" if (files == null || files.length == 0) {\n" +
" return null;\n" +
" }\n" +
"\n" +
" File lastModifiedFile = files[0];\n" +
" for (int i = 1; i < files.length; i++) {\n" +
" if (lastModifiedFile.lastModified() < files[i].lastModified()) {\n" +
" lastModifiedFile = files[i];\n" +
" }\n" +
" }\n" +
"return lastModifiedFile.getAbsolutePath();"
, "GROOVY");
}

getFileContent = {RemoteWebDriver aDriver, String absoluteFilePath ->
Object res = aDriver.executeScript(
"def bytes = new File('" + absoluteFilePath.replace('\\', '/') + "').bytes; \n"
+ "return Base64.getEncoder().encodeToString(bytes);", "GROOVY");

byte[] content = Base64.getDecoder().decode(res.toString());
return content;
}

getDownloadedFile = {RemoteWebDriver desktopDriver, String downloadDir, String latestFilePath ->
String downloadFilePath = getLastModifiedFileName(desktopDriver, downloadDir);

// Wait until new file appears.
int maxCounter = 1000;
boolean downloadStarted = downloadFilePath != null && !downloadFilePath.equals(latestFilePath);
while (!downloadStarted && maxCounter > 0) {
Thread.sleep(10);
downloadFilePath = getLastModifiedFileName(desktopDriver, downloadDir);
downloadStarted = downloadFilePath != null && !downloadFilePath.equals(latestFilePath);
maxCounter--;
}

// Lets wait until latest file is not tmp or crdownload.
if (downloadStarted) {
maxCounter = 300;
downloadFilePath = getLastModifiedFileName(desktopDriver, downloadDir);
String fileExtension = org.apache.commons.io.FilenameUtils.getExtension(downloadFilePath);
boolean isDownloading = "crdownload".equals(fileExtension) || "tmp".equals(fileExtension);

while (isDownloading && maxCounter > 0) {
Thread.sleep(100);
downloadFilePath = getLastModifiedFileName(desktopDriver, downloadDir);
fileExtension = org.apache.commons.io.FilenameUtils.getExtension(downloadFilePath);
isDownloading = "crdownload".equals(fileExtension) || "tmp".equals(fileExtension);

maxCounter--;
}
if (!isDownloading) {
return getFileContent(desktopDriver, downloadFilePath);
}
}

throw new Exception("Some issues during file download");
}
]]></script>

<robotics-flow>
<robot name="desktopDriver" driver="desktop" close-on-completion="false">
<script><![CDATA[

aDriver = driver()
latestFilePath = getLastModifiedFileName(aDriver, downloadDir)

]]></script>
</robot>

<robot name="robotDriver" driver="chrome" close-on-completion="true"
start-in-private="true">
<script><![CDATA[

open('http://wf-sharebox.s3.amazonaws.com/some-cool-video.zip')
documentContent = getDownloadedFile(aDriver, downloadDir, latestFilePath)

]]></script>
</robot>

<script><![CDATA[
try {
aDriver.quit()
} catch(Exception ignore) {}
]]></script>
</robotics-flow>

<!-- Upload to S3 or perform any other actions. -->

<!-- Export your values -->
<export include-original-data="true">
<single-column name="content" value="${documentContent}"></single-column>
</export>

</config>

Automate file upload​

See the code below as an example:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://web-harvest.sourceforge.net/schema/1.0/config" scriptlang="groovy">

<robotics-flow>
<robot name="bb8" driver="desktop" close-on-completion="true">
<script> <![CDATA[

// Copy the file to the RPA machine.
def s3Path = 'https://rpa-tutorial.s3.amazonaws.com/trainings/pdf-sample.pdf'
filePath = downloadFileOnAgent(s3Path)

]]></script>
</robot>

<robot name="webRobot" driver="internet explorer" close-on-completion="false" start-in-private="true">
<script><![CDATA[

def loginPage = 'http://mail.google.com'
def username = 'tuk.tuk.rpa@gmail.com'
def password = 'work4WorkFusion!1'
def mailSubject = 'Attach PDF'
def mailBody = 'This is an RPA message with attached PDF file.'

timeouts(20 * 1000)

// Login into the mail system
open(loginPage)
$('#identifierId').val(username).pressEnter()
$(byXpath("//*[@name='password']")).val(password)
$('#passwordNext').click()

// Populate new message fields
$(byText('COMPOSE')).click();
$(By.name('to')).val(username).pressTab()
$(by('placeholder', 'Subject')).val(mailSubject).pressTab()
$('.editable').val(mailBody).pressEnter()

// Start attaching file.
$(byXpath("//div[@class='a1 aaA aMZ']")).click()

]]></script>
</robot>

<robot name="r2d2" driver="desktop" close-on-completion="true">
<capability name="SEARCH_ALL_WINDOWS" value="true" />
<script><![CDATA[

// Attach file using "upload file" dialog.
switchTo().window('[CLASS:#32770]')
$('[CLASS:Edit;INSTANCE:1]').sendKeys(filePath)
$('[CLASS:Button;INSTANCE:1]').click()

]]></script>
</robot>

<robot name="webRobot" driver="internet explorer" close-on-completion="true">
<script><![CDATA[

$(byText('Send')).click()
$(withText('Your message has been sent')).shouldBe(VISIBLE)
sleep(3000)

]]></script>
</robot>
</robotics-flow>

<export include-original-data="false">
<single-column name="rpa_local_file_path" value="${filePath}"/>
</export>

</config>

The same example that uses the Universal Driver is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns="http://web-harvest.sourceforge.net/schema/1.0/config" scriptlang="groovy">

<robotics-flow>
<robot name="bb8" driver="universal" close-on-completion="true">
<capability name="SEARCH_ALL_WINDOWS" value="true" />
<script> <![CDATA[

// Copy the file to the RPA machine.
def s3Path = 'https://rpa-tutorial.s3.amazonaws.com/trainings/pdf-sample.pdf'
filePath = downloadFileOnAgent(s3Path)

def loginPage = 'http://mail.google.com'
def username = 'tuk.tuk.rpa@gmail.com'
def password = 'work4WorkFusion!1'
def mailSubject = 'Attach PDF'
def mailBody = 'This is an RPA message with attached PDF file.'

timeouts(20 * 1000)

// Login into the mail system
openIE(loginPage)
$('#identifierId').val(username).pressEnter()
$(byXpath("//*[@name='password']")).val(password)
$('#passwordNext').click()

// Populate new message fields
$(byText('COMPOSE')).click();
$(By.name('to')).val(username).pressTab()
$(by('placeholder', 'Subject')).val(mailSubject).pressTab()
$('.editable').val(mailBody).pressEnter()

// Start attaching file.
$(byXpath("//div[@class='a1 aaA aMZ']")).click()


// Attach file using "upload file" dialog.
switchTo().window('[CLASS:#32770]')
$('[CLASS:Edit;INSTANCE:1]').sendKeys(filePath)
$('[CLASS:Button;INSTANCE:1]').click()

switchTo().window('[CLASS:IEFrame]')
$(byText('Send')).click()
$(withText('Your message has been sent')).shouldBe(VISIBLE)
sleep(3000)

]]></script>
</robot>
</robotics-flow>

<export include-original-data="false">
<single-column name="rpa_local_file_path" value="${filePath}"/>
</export>

</config>