Skip to content

Instantly share code, notes, and snippets.

@tw3
Last active January 28, 2022 17:56
Show Gist options
  • Save tw3/ef2858f3fe4d224e02eb9ff5dbca2aba to your computer and use it in GitHub Desktop.
Save tw3/ef2858f3fe4d224e02eb9ff5dbca2aba to your computer and use it in GitHub Desktop.
Helps read and compare files downloaded during a protractor e2e test
// <project_root>/e2e/protractorDownloads/protractor-download-helper.ts
import { browser } from 'protractor';
const fs = require('fs');
const path = require('path');
export class ProtractorDownloadHelper {
private readonly maxReadWaitTime = 10000; // 10 seconds
constructor() {
}
removeFile(fileName: string): void {
this.removeFileAtPath(this.getFilePath(fileName));
}
async getFileContents(fileName: string): Promise<string> {
const filePath: string = this.getFilePath(fileName);
try {
await browser.driver.wait(() => {
// Wait until the file exists, download may take some time
return fs.existsSync(filePath);
}, this.maxReadWaitTime);
} catch (err) {
throw new Error(`File ${filePath} does not exist`);
}
return fs.readFileSync(filePath, { encoding: 'utf8' });
}
private removeFileAtPath(filePath: string): void {
if (fs.existsSync(filePath)) {
fs.unlinkSync(filePath);
}
}
private getFilePath(fileName: string): string {
return path.join(__dirname, fileName);
}
}
/*
Sample use:
// <project_root>/e2e/your-test.e2e-spec.ts
import { ProtractorDownloadHelper } from './protractorDownloads/protractor-download-helper';
describe('Your test', () => {
it('should download proper file', async () => {
const downloadedFileName = 'download.json';
const expectedDownloadFileName = 'expected_download.json';
// Remove the existing download file, if any (so browser doesn't rename the file)
const downloadHelper: ProtractorDownloadHelper = new ProtractorDownloadHelper();
downloadHelper.removeFile(downloadedFileName);
// Click the download button
$('.download-link').click();
// Verify file contents
try {
const actualFileContents: string = await this.getFileContents(downloadedFileName);
const expectedFileContents: string = await this.getFileContents(expectedDownloadFileName);
expect(actualFileContents).toBe(expectedFileContents, 'Downloaded file differs from expected download file');
} catch (err) {
fail(`ERROR: Exception thrown: ${err.message}`);
}
// Remove file
downloadHelper.removeFile(downloadedFileName);
});
});
*/
/*
Sample config:
// <project_root>/protractor.conf.js
const path = require('path');
const downloadsPath = path.resolve(__dirname, './e2e/protractorDownloads');
exports.config = {
capabilities: {
browserName: 'chrome',
chromeOptions: {
args: [
'--no-sandbox',
'--test-type=browser'
],
prefs: {
download: {
prompt_for_download: false,
default_directory: downloadsPath
}
}
}
},
};
*/
@mandras73
Copy link

I get "Object is possible 'Undefined'" on this.getFileContents(downloadedFileName);

@tw3
Copy link
Author

tw3 commented Jan 27, 2022

@mandras73 Do you see this when the code compiles? Or when the code runs?

It it happens at compile time, maybe you have to add some null/undefined checks, e.g.

async getFileContents(fileName: string): Promise<string> {
    if (!browser || !browser.driver || !browser.driver.wait) {
      return null;
    }
    const filePath: string = this.getFilePath(fileName);
    try {
      await browser.driver.wait(() => {
        // Wait until the file exists, download may take some time
        return fs.existsSync(filePath);
      }, this.maxReadWaitTime);
    } catch (err) {
      throw new Error(`File ${filePath} does not exist`);
    }

    return fs.readFileSync(filePath, { encoding: 'utf8' });
  }

There seems to be more info on StackOverflow.

If it happens at runtime, can you determine which line is the culprit? Can you set a breakpoint or add some console.log() statements to see where it fails?

Please let me know if you find a fix and I will update this gist.

@mandras73
Copy link

hey!
im using webstorm, and when pasted the code into my ts file (using protractor and typescipt) it show immediately that "this" is undefined
(so it happens before runtime, just in the IDE)

@tw3
Copy link
Author

tw3 commented Jan 28, 2022

Can you please paste a screenshot here? All of the this references in the gist seem fine to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment