using Beam.Downloaders; using Beam.Models; using Microsoft.Playwright; namespace Beam.Playwright { public class PlaywrightUnitDownloader : UnitDownloaderBinary { public PlaywrightAsyncManipulator PuppetManipulator { get; } public PlaywrightUnitDownloader(HttpClient client, PlaywrightAsyncManipulator puppetManipulator, AsyncTransformer asyncHtmlTransformer, AsyncDownloadFailurePredicate[] asyncDownloadFailurePredicates) : base(client, asyncHtmlTransformer, asyncDownloadFailurePredicates) { PuppetManipulator = puppetManipulator; } protected override async Task<(bool, T?)> TryDownloadWithNoRetries(string link, CancellationToken ct) { var page = await PlaywrightContext.Browser.Value.NewPageAsync(); try { await page.GotoAsync(link); await PuppetManipulator(page); var download = await page.WaitForDownloadAsync(); using var stream = await download.CreateReadStreamAsync(); byte[] content = new byte[stream.Length]; await stream.ReadExactlyAsync(content, ct); ByteDocument doc = new ByteDocument(download.SuggestedFilename, content); if (FailurePredicates is not null && await IsFailure(doc)) return (false, default); var transformed = await Transformer(doc); return (true, transformed); } catch (Exception) { return (false, default); } finally { if (!page.IsClosed) await page.CloseAsync(); } } } }