import {firefox, Page, BrowserContext, Download} from 'playwright'; async function lucida(album: URL, timeout: number, context: BrowserContext): Promise { const page: Page = await context.newPage(); await page.goto('/'); // Fill in the album URL await page.fill('input[id="download"]', album.href); // Wait for the XHR request to complete await Promise.all([ page.waitForResponse(res => res.url().includes('/api/load') && res.status() == 200), page.click('input[id="go"]'), page.waitForLoadState('domcontentloaded') ]); // Check 'Hide my download from recently downloaded' checkbox await page.check('input[id="hide-from-ticker"]'); // Parse info const albumName: string = (await page.locator('h1[class="svelte-6pt9ji"]').last().innerText()).trim(); const trackCount: string = (await page.locator('h3[class="svelte-6pt9ji"]').first().innerText()).trim(); // Start download await page.getByText('download full album').click(); console.log(`Downloading ${albumName} (${trackCount}) from ${album.href}...`); page.on('download', download => download.path().then(console.log)); const downloadPromise: Promise = page.waitForEvent('download', { timeout: timeout }); const download: Download = await downloadPromise; // Save the download to the Downloads folder // TODO Set path (configurable) await download.saveAs('/home/tdpeuter/Downloads/' + download.suggestedFilename()); await page.close(); } (async () => { // Launch a new Firefox browser instance // TODO Allow to pass headless option as argument const browser = await firefox.launch({ headless: true }); // Set headless: true to run without UI const context = await browser.newContext({ acceptDownloads: true, // Enable download handling baseURL: 'https://lucida.to' }); const album: URL = new URL('https://www.qobuz.com/us-en/album/you-me-disclosure-eliza-doolittle/q5q4tg0cupgwa'); // const album: URL = new URL('https://www.qobuz.com/us-en/album/led-zeppelin-iv-hd-remastered-edition-led-zeppelin/0603497898503'); const timeout: number = 240000; await lucida(album, timeout, context); // Close the browser await browser.close(); })();