Aspose.HTML fails to load/find fonts *only in Nunit test*

We are failing locally running tests when attempting to convert HTML files to PDF using Converter.ConvertHTML() to create PDF files.

We have a wrapper class around the Aspose.Html Library (in C#, below) that works as expected in our application. However, when running it from a test function, it fails with System.InvalidOperationException : No font was found. To resolve this problem, you can set up your custom set of fonts, following this documentation article: https://docs.aspose.com/html/net/how-to-set-font-folder/.

Our test script is below as well. Is there a workaround or mock mechanism we can use to ensure the fonts are usable within a test script?

Creating a new HTMLDocument(filepath) works fine. However, when handing that document to Converter.ConvertHTML(htmlDoc, saveOptions, outputPath), the exception mentioned is thrown for any document using the Aspose.HTML library (we’ve tested with .md files as well).

The behavior does not happen in our main application, just within these tests (Nunit).

[Test]
public void ShouldConvertHtmlToPdf()
{
    var testDocument = Path.Combine(_baseFolderTestPath, "sample.html");
    var outputPdf = Path.Combine(_testOutputFolder, Path.GetTempFileName());

    try
    {
        if (!File.Exists(testDocument))
        {
            Assert.Inconclusive($"At least one file not found");
        }

        Console.WriteLine($"Converting: {testDocument}");

        var wrapper = new AsposeHtmlWrapper();
        var htmlDoc = wrapper.LoadDocument(testDocument);
        wrapper.SaveToPdf(htmlDoc, outputPdf);

        // We have also tested directly from the library and have the same issue:
        // var configuration = new Aspose.Html.Configuration();
        // var useragent = configuration.GetService<Aspose.Html.Services.IUserAgentService>();
        // useragent
        //        .FontsSettings
        //        .SetFontsLookupFolder(
        //                Environment.GetFolderPath(Environment.SpecialFolder.Fonts)
        //                , true);
        // var htmlDoc = new HTMLDocument(testDocument);
        // Converter.ConvertHTML(htmlDoc, new PdfSaveOptions(), outputPdf); // -> Throws font exception

        outputPdf.ShouldNotBeNull();
        File.Exists(outputPdf).ShouldBeTrue($"Output PDF should exist: {outputPdf}");

        // Verify it's a valid PDF
        using (var doc = new Aspose.Pdf.Document(outputPdf))
        {
            doc.Pages.Count.ShouldBeGreaterThan(0);
        }

        Console.WriteLine($"Successfully created: {outputPdf}");
    }

    finally
    {
        if (File.Exists(outputPdf))
        {
            try { File.Delete(outputPdf); } catch { }
        }
        
    }
}
using System;
using Aspose.Html;
using Aspose.Html.Converters;
using PdfSaveOptions = Aspose.Html.Saving.PdfSaveOptions;

namespace AsposeWrappers;

public class AsposeHtmlWrapper : IAsposeHtmlWrapper
{
    public HTMLDocument LoadDocument(string filePath)
    {
        var configuration = new Aspose.Html.Configuration();
        var useragent = configuration.GetService<Aspose.Html.Services.IUserAgentService>();
        useragent.FontsSettings.SetFontsLookupFolder(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), true);
        return new HTMLDocument(filePath, configuration);
    }

    public HTMLDocument LoadMarkdownDocument(string filepath)
    {
        var configuration = new Aspose.Html.Configuration();
        var useragent = configuration.GetService<Aspose.Html.Services.IUserAgentService>();
        useragent.FontsSettings.SetFontsLookupFolder(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), true);
        return Converter.ConvertMarkdown(filepath, configuration);
    }

    public void SaveToPdf(HTMLDocument html, string filePath, PdfSaveOptions saveOptions = null)
    {
        if (html == null) throw new ArgumentNullException(nameof(html));
        if (filePath == null) throw new ArgumentNullException(nameof(filePath));

        if (saveOptions != null)
        {
             // "Font not found" exception occurs here
            Converter.ConvertHTML(html, saveOptions, filePath);
        }
        else
        {
             // "Font not found" exception occurs here
            Converter.ConvertHTML(html, new PdfSaveOptions(), filePath);
        }
    }
}

As an update:

We’ve tested font availability alongside the tests within Nunit, and that doesn’t seem to be an issue. The first test here passes, while the second test fails:


        // Passes
        [Test]
        public void CanAccessSystemFonts()
        {
            string fontDir = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
            string arialPath = Path.Combine(fontDir, "arial.ttf");

            Assert.That(File.Exists(arialPath), "System font file must be accessible.");
        }

        // Fails
        [Test]
        public void ShouldConvertHtmlToPdf()
        {
            var testDocument = Path.Combine(_baseFolderTestPath, "sample.html");
            var outputPdf = Path.Combine(_testOutputFolder, Path.GetTempFileName());

            try
            {
                if (!File.Exists(testDocument))
                {
                    Assert.Inconclusive($"At least one file not found");
                }

                Console.WriteLine($"Converting: {testDocument}");

                //var wrapper = new AsposeHtmlWrapper();
                //var htmlDoc = wrapper.LoadDocument(testDocument);
                //wrapper.SaveToPdf(htmlDoc, outputPdf);

                var configuration = new Aspose.Html.Configuration();
                var useragent = configuration.GetService<Aspose.Html.Services.IUserAgentService>();
                useragent
                    .FontsSettings
                    .SetFontsLookupFolder(
                        Environment.GetFolderPath(Environment.SpecialFolder.Fonts)
                        , true);
                var htmlDoc = new HTMLDocument(testDocument, configuration);
                Converter.ConvertHTML(htmlDoc, new PdfSaveOptions(), outputPdf); // Fails here

                outputPdf.ShouldNotBeNull();
                File.Exists(outputPdf).ShouldBeTrue($"Output PDF should exist: {outputPdf}");

                // Verify it's a valid PDF
                using (var doc = new Aspose.Pdf.Document(outputPdf))
                {
                    doc.Pages.Count.ShouldBeGreaterThan(0);
                }

                Console.WriteLine($"Successfully created: {outputPdf}");
            }

            finally
            {
                if (File.Exists(outputPdf))
                {
                    try { File.Delete(outputPdf); } catch { }
                }
                
            }
        }

Thank you for the additional details.

We reviewed the thread, but we do not yet have the referenced sample.html file needed to reproduce the problem on our side.

Could you please attach the sample.html file (and any related resources if the HTML depends on them) to this forum thread? Once we have the sample, we will test it and update you with our findings.

Yes, sorry for the delay.

Here is an example of the test that is failing:

image.png (320.7 KB)

This is the simplesample.html file used in the example:

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Non-empty HTML file</title>
</head>
<body>
<h1>There's something here at least!</h1>
<p>I guess that's more than nothing.</p>
</body>
</html>

We were unable to reproduce this issue from the nunit tests. Could you try using another folder in your working directories and copy the system fonts there?

// Create a fonts folder in the working directory
string fontsFolder = Path.Combine(Environment.CurrentDirectory, "Fonts");
if (!Directory.Exists(fontsFolder))
{
    Directory.CreateDirectory(fontsFolder);
}

// Copy all system fonts to the created folder
string systemFontsPath = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
try
{
    foreach (string fontFile in Directory.GetFiles(systemFontsPath, "*.*", SearchOption.TopDirectoryOnly)
        .Where(f => f.EndsWith(".ttf", StringComparison.OrdinalIgnoreCase) || 
                    f.EndsWith(".otf", StringComparison.OrdinalIgnoreCase)))
    {
        string fileName = Path.GetFileName(fontFile);
        string destPath = Path.Combine(fontsFolder, fileName);
        if (!File.Exists(destPath))
        {
            File.Copy(fontFile, destPath, false);
        }
    }
}
catch (Exception ex)
{
    Console.WriteLine($"Error copying fonts: {ex.Message}");
}

// Use the created fonts folder
var configuration = new Aspose.Html.Configuration();
var useragent = configuration.GetService<Aspose.Html.Services.IUserAgentService>();
useragent.FontsSettings.SetFontsLookupFolder(fontsFolder, true);
return new HTMLDocument(filePath, configuration);