Skip to content

Instantly share code, notes, and snippets.

@minhphong306
Created November 28, 2025 01:11
Show Gist options
  • Select an option

  • Save minhphong306/7808b59ad25580f3be8c0df23fd8d979 to your computer and use it in GitHub Desktop.

Select an option

Save minhphong306/7808b59ad25580f3be8c0df23fd8d979 to your computer and use it in GitHub Desktop.
code.ts
const { chromium } = require('playwright');
const fs = require('fs');
const path = require('path');
async function downloadAndCheckFile() {
const downloadPath = path.join(__dirname, 'downloads');
// Create downloads directory if it doesn't exist
if (!fs.existsSync(downloadPath)) {
fs.mkdirSync(downloadPath, { recursive: true });
}
const browser = await chromium.launch({ headless: false });
const context = await browser.newContext({
acceptDownloads: true
});
const page = await context.newPage();
// Navigate to a page with a download link
await page.goto('https://example.com/download-page');
// Start waiting for download before clicking
const downloadPromise = page.waitForEvent('download');
// Click the download button/link
await page.click('a.download-link'); // Adjust selector as needed
const download = await downloadPromise;
// Get file info from the download object
const suggestedFilename = download.suggestedFilename();
console.log('Suggested filename:', suggestedFilename);
// Save the file to disk
const filePath = path.join(downloadPath, suggestedFilename);
await download.saveAs(filePath);
// Check if download was successful
const failure = await download.failure();
if (failure) {
console.error('Download failed:', failure);
await browser.close();
return;
}
// Get file stats
const stats = fs.statSync(filePath);
// File information
const fileInfo = {
fileName: suggestedFilename,
filePath: filePath,
fileSize: stats.size,
fileSizeFormatted: formatFileSize(stats.size),
fileExtension: path.extname(suggestedFilename).toLowerCase(),
mimeType: getMimeType(suggestedFilename),
createdAt: stats.birthtime,
modifiedAt: stats.mtime
};
console.log('\n--- File Information ---');
console.log('File Name:', fileInfo.fileName);
console.log('File Path:', fileInfo.filePath);
console.log('File Size:', fileInfo.fileSizeFormatted, `(${fileInfo.fileSize} bytes)`);
console.log('File Extension:', fileInfo.fileExtension);
console.log('MIME Type:', fileInfo.mimeType);
// Validate file
validateFile(fileInfo);
await browser.close();
return fileInfo;
}
// Format file size to human readable
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
// Get MIME type from extension
function getMimeType(filename) {
const ext = path.extname(filename).toLowerCase();
const mimeTypes = {
'.pdf': 'application/pdf',
'.doc': 'application/msword',
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'.xls': 'application/vnd.ms-excel',
'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.gif': 'image/gif',
'.zip': 'application/zip',
'.txt': 'text/plain',
'.csv': 'text/csv',
'.json': 'application/json',
'.xml': 'application/xml',
'.mp4': 'video/mp4',
'.mp3': 'audio/mpeg'
};
return mimeTypes[ext] || 'application/octet-stream';
}
// Validate file against expected criteria
function validateFile(fileInfo, options = {}) {
const {
expectedExtensions = null, // e.g., ['.pdf', '.docx']
maxSizeBytes = null, // e.g., 10 * 1024 * 1024 (10MB)
minSizeBytes = null, // e.g., 1024 (1KB)
expectedFilename = null // exact filename or regex
} = options;
const errors = [];
// Check extension
if (expectedExtensions && !expectedExtensions.includes(fileInfo.fileExtension)) {
errors.push(`Invalid file type: ${fileInfo.fileExtension}. Expected: ${expectedExtensions.join(', ')}`);
}
// Check max size
if (maxSizeBytes && fileInfo.fileSize > maxSizeBytes) {
errors.push(`File too large: ${fileInfo.fileSizeFormatted}. Max: ${formatFileSize(maxSizeBytes)}`);
}
// Check min size
if (minSizeBytes && fileInfo.fileSize < minSizeBytes) {
errors.push(`File too small: ${fileInfo.fileSizeFormatted}. Min: ${formatFileSize(minSizeBytes)}`);
}
// Check filename
if (expectedFilename) {
if (expectedFilename instanceof RegExp) {
if (!expectedFilename.test(fileInfo.fileName)) {
errors.push(`Filename doesn't match pattern: ${expectedFilename}`);
}
} else if (fileInfo.fileName !== expectedFilename) {
errors.push(`Unexpected filename: ${fileInfo.fileName}. Expected: ${expectedFilename}`);
}
}
if (errors.length > 0) {
console.log('\n--- Validation Errors ---');
errors.forEach(err => console.error('❌', err));
return false;
}
console.log('\n✅ File validation passed!');
return true;
}
// Run the download
downloadAndCheckFile().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment