const { Builder, Browser, By, until } = require('selenium-webdriver'); const { Options } = require('selenium-webdriver/chrome'); const path = require('path'); const fs = require('fs'); // Taken from: ; feel free to make a better implementation, if you want to! async function checkFileExist(path, timeout = 2000) { let totalTime = 0; let checkTime = timeout / 10; return await new Promise((resolve, reject) => { const timer = setInterval(function() { totalTime += checkTime; let fileExists = fs.existsSync(path); if (fileExists || totalTime >= timeout) { clearInterval(timer); resolve(fileExists); } }, checkTime); }); } (async function exportElixFormsModule() { // Override with environment variables, if they exist const username = process.env.ELIXFORMS_USERNAME || null; const password = process.env.ELIXFORMS_PASSWORD || null; const moduleName = process.env.ELIXFORMS_MODULE_TAG || null; // Validate that all required environment variables are set if (!username || !password || !moduleName) { console.error('Please set ELIXFORMS_USERNAME, ELIXFORMS_PASSWORD, and ELIXFORMS_MODULE_TAG using one of:\n- an .env file in the project root\n- specify an .env file with `npx env-cmd --file <.env_path> -- `\n- pass them as environment variables'); process.exit(1); } const downloadDir = path.resolve(__dirname, 'downloads'); // Configure Chrome options let options = new Options(); options.setUserPreferences({ 'download.default_directory': downloadDir, // Set download folder 'download.prompt_for_download': false, // No prompt 'download.directory_upgrade': true, 'safebrowsing.enabled': true // Avoid blocking }); options.addArguments("--headless"); let driver = await new Builder() .forBrowser(Browser.CHROME) .setChromeOptions(options) .build(); const originalWindow = await driver.getWindowHandle(); // Implicit timeouts await driver.manage().setTimeouts({ implicit: 3000 }); console.log(`Starting export for module: ${moduleName}`); // Cleanup download directory before starting if (!fs.existsSync(downloadDir)) { console.log(`Creating download directory: ${downloadDir}`); fs.mkdirSync(downloadDir); } else { console.log(`Cleaning up download directory: ${downloadDir}`); fs.readdirSync(downloadDir).forEach(file => { fs.unlinkSync(path.join(downloadDir, file)); }); } console.log(`Navigating to login page...`); await driver.get('https://console-unipr.elixforms.it/backoffice/'); console.log(`Logging in with username: ${username}`); await driver .findElement(By.id('username')) .sendKeys(username); // 'Automation_User' await driver .findElement(By.id('password')) .sendKeys(password); // 'n_HH9shL#VPeiiT^%;:t5/,jY' await driver .findElement(By.name('INSERT_BTN00000')) .click(); console.log(`Waiting for "Benvenuto" (quit if not found, likely login failed)`); await driver .wait(until.elementLocated(By.id('title_0')), 10000) .catch(() => { console.error('Login failed or "Benvenuto" not found'); driver.quit(); process.exit(1); }); console.log(`Navigating to module export page...`); await driver .navigate() .to('https://console-unipr.elixforms.it/rwe2/admin_console.jsp'); let moduleSearchTextbox = await driver.findElement(By.id('TITLE__TAG__CATTAG')); await moduleSearchTextbox.clear(); await moduleSearchTextbox.sendKeys(moduleName); await moduleSearchTextbox.sendKeys('\n'); console.log(`Waiting for search results...`); // Needed to wait for the search results to load before clicking the export button await driver.sleep(2000); console.log(`Clicking export button for module: ${moduleName}`); await driver .findElement(By.xpath('//div[contains(@class, "item")][1]')) .findElement(By.xpath('.//input[starts-with(@name, "INSERT_BTN_USER_")]')) .click() console.log(`Clicking "Esporta il modulo" link...`); await driver .findElement(By.linkText('Esporta il modulo')) .click(); console.log(`Waiting for the new tab to finish loading content...`); await driver.wait(async () => (await driver.getAllWindowHandles()).length === 2, 5000); const windows = await driver.getAllWindowHandles(); windows.forEach(async handle => { if (handle !== originalWindow) { await driver.switchTo().window(handle); } }); let moduleProtocol = await driver.findElement(By.id('moduleProtocol')); if (!await moduleProtocol.isSelected()) { await moduleProtocol.click(); } let moduleId = await driver.findElement(By.id('moduleId')).getAttribute('value'); let moduleFilename ="elxforms_" + moduleId + ".elx"; await driver .findElement(By.id('download')) .click(); let downloadLink = await driver.wait(until.elementLocated(By.linkText('Scarica il modulo'))); let href = await downloadLink.getAttribute('href'); console.log(`Found download link: ${href}; clicking to download the module as ${moduleFilename}...`); await downloadLink.click(); console.log(`Waiting for the file to be downloaded to ${downloadDir}...`); let downloadedFilePath = path.join(downloadDir, moduleFilename); await checkFileExist(downloadedFilePath, 5000); console.log(`File downloaded!`); await driver.quit(); return downloadedFilePath; })();