I'm working on an ASP.NET Core Web API that uses PuppeteerSharp to create PDF files from HTML.
It has a Program class:
public partial class Program
{
public static void Main(string[] callParams)
{
new CenterHub().StartWork(callParams);
}
}
that uses a CenterHub class dealing with setting everything up:
public class CenterHub
{
public void StartWork(string[] callParams)
{
WebApplicationBuilder? appBuilder = WebApplication.CreateBuilder(callParams);
appBuilder.Services.AddControllersWithViews();
appBuilder.Services.AddSingleton(new HtmlToPdfService());
WebApplication? runningApp = appBuilder.Build();
runningApp.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
runningApp.Run();
}
}
Among other things, StartWork() registers a HtmlToPdfService object:
public class HtmlToPdfService
{
private readonly string[] _puppeteerArgs = new[] {
"--no-sandbox",
"--disable-dev-shm-usage",
"--disable-gpu",
"--disable-setuid-sandbox",
"--disable-extensions",
"--disable-software-rasterizer",
"--font-render-hinting=none"
};
private IBrowser _navigateur { get; }
private PdfOptions _optionsPdf { get; }
public HtmlToPdfService()
{
BrowserFetcher browserUser = new();
browserUser.DownloadAsync().GetAwaiter().GetResult();
_browser = Puppeteer.LaunchAsync(new LaunchOptions
{
Headless = true,
ExecutablePath = "/usr/bin/chromium-browser",
Args = _puppeteerArgs
})
.GetAwaiter()
.GetResult();
_pdfOptionSet = new PdfOptions
{
Format = PaperFormat.A4,
PreferCSSPageSize = true,
PrintBackground = true,
};
}
}
All this works fine.
Now, I want to use automated integration tests on the API.
I'm using NUnit. The test class looks like this:
[TestFixture]
internal class TestSpecificDocument1
{
[Test]
public async Task TestsRequestForDocument1()
{
AppTest appObjectForTest = new();
Environment.CurrentDirectory = "/app";
HttpClient clientHttp = appObjectForTest.WithWebHostBuilder(bu => bu.UseEnvironment("Development")).CreateClient();
// Tests will follow once I get the above code to work
}
}
It uses the following class to prepare the app for testing:
public class AppTest : WebApplicationFactory<Program>
{
}
(I will provide the appsettings.json file if and when someone asks for it, but until then I feel this question is already long enough.)
However, when running the Puppeteer.LaunchAsync() method from the HtmlToPdfService constructor, I get the following message:
An error occurred trying to start process '/usr/bin/chromium-browser' with working directory 'C:\path_to_my_test_project\bin\Debug\net8.0'.
I've tried variations, such as:
HttpClient clientHttp = appObjectForTest.WithWebHostBuilder(bu => bu.UseStartup<Program>()
.UseContentRoot("/app"))
.CreateDefaultClient();
but I still get the same error except the path where Chromium is supposed to be is now C:\app.
EDIT: I forgot to mention that the solution uses Docker Desktop and has a docker-compose project, which accounts for being able to use /usr/bin/chromium-browser on a Windows computer.
How can I make this work? The documentation makes it look very simple, but it doesn't feature running Chromium, nor should it.
/usr/bin/chromium-browsersounds like *nix butC:\path_to_my_test_project\bin\Debug\net8.0is going to be Windows. What OS are you using?ExecutablePathas the default?ExecutablePath, I seem to remember it comes from the PuppeteerSharp documentation. I'll look into it./usr/bin/chromium-browserjust plain old won't work on Windows. If you need different paths for different systems/environments you could do worse than sticking the path in config which could be overwritten by an environment variable.