Created
November 28, 2025 01:11
-
-
Save minhphong306/7808b59ad25580f3be8c0df23fd8d979 to your computer and use it in GitHub Desktop.
code.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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