Skip to content

[BUG] Azure Function Setup Issue: System.Text.Json version issue #2696

@weightmans-seanbrogan

Description

@weightmans-seanbrogan

System info

  • Playwright Version: v1.37.1
  • Operating System: All
  • Browser: Chromium
  • Azure Function Runtime: v4
  • Language: C# .Net Core 7

Description

I'm trying to get playwright browsers installed locally within an azure function underneath the .playwright/packages/.local_browsers directory so that an azure function can be self contained within a cloud hosted azure function. The below provided code is a separate example i have created from the main project that replicates the issue i am having. I have tried multiple approaches to do this using environment variables but none have seemed to work except for one.

The only time I have managed to get it to work is when:

  • Azure function runtime set to .net 6
  • playwright version reverted to 1.28 which seems to use System.Text.Json 6.0.5 (screenshot of the error to do with this dll is shown below).

Source code

using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Microsoft.Playwright;

namespace Azure.Playwright.Function
{
    public class Function1
    {
        [FunctionName("Function1")]
        public async Task RunAsync([TimerTrigger("0 */1 * * * *")] TimerInfo myTimer, ILogger log)
        {
            var browserPath = Path.Combine(Directory.GetCurrentDirectory(), ".playwright", "package", ".local_browsers");

            Environment.SetEnvironmentVariable("HOME_EXPANDED", browserPath);
            Environment.SetEnvironmentVariable("PLAYWRIGHT_BROWSERS_PATH", Environment.GetEnvironmentVariable("HOME_EXPANDED"));

            try
            {
                await Task.Run(() =>
                {
                    Microsoft.Playwright.Program.Main(new string[] { "install", "chromium" });
                }).ContinueWith(async (t) =>
                {
                    using var playwright = await Microsoft.Playwright.Playwright.CreateAsync();
                    await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions()
                    {
                        Headless = false
                    });

                    var page = await browser.NewPageAsync();
                    await page.GotoAsync("https://playwright.dev/dotnet");
                });
            }
            catch (Exception ex)
            {
                log.LogError(ex, "Error");
            }
        }
    }
}

Config file

// local.settings.json
{
  "IsEncrypted": false,
  "Values": {
    "AzureBlobStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet"
  }
}

.csproj file

 // csproj
        ....
	<Target Name="FixPlaywrightCopyAfterBuild" AfterTargets="Build">
		<ItemGroup>
			<_BuildCopyItems Include="$(OutDir).playwright\**" />
		</ItemGroup>
		<Message Text="[Fix] Copying files to the nested bin folder of the azure function... $(OutDir)bin" Importance="high" />
		<Copy SourceFiles="@(_BuildCopyItems)" DestinationFiles="@(_BuildCopyItems->'$(OutDir)bin\.playwright\%(RecursiveDir)%(Filename)%(Extension)')" />
	</Target>

	<Target Name="FixPlaywrightCopyAfterPublish" AfterTargets="Publish">
		<ItemGroup>
			<_BuildCopyItems Include="$(PublishDir).playwright\**" />
		</ItemGroup>
		<Message Text="[Fix] Copying files to the nested bin folder of the azure function for publishing... $(PublishDir)bin" Importance="high" />
		<Copy SourceFiles="@(_BuildCopyItems)" DestinationFiles="@(_BuildCopyItems->'$(PublishDir)bin\.playwright\%(RecursiveDir)%(Filename)%(Extension)')" />
	</Target>

Steps

  • Create basic azure function
  • Add storage blob via emulator -> Connected services -> Storage Azurite Emulator (local)
  • Install playwright via nuget
  • Modify function as per source code example above
  • Ensure local.settings.json contains configuration stated above
  • Run application

Expected
The expected behavior is that the function will execute every 1 minute to open up the requested web page in a chromium instance.

Actual
The actual result is a "System.IO.FileNotFoundException: 'Could not load file or assembly 'System.Text.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" error when calling Playwright.CreateAsync.
image

Are there any official examples of how to use playwright within an azure function as I can't seem to find much information on this.

Help with this would be greatly appreciated :)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions