Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BoDi.ObjectContainerException: Interface cannot be resolved: Microsoft.Playwright.IBrowser #58

Closed
konarx opened this issue Feb 28, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@konarx
Copy link

konarx commented Feb 28, 2024

Reqnroll Version

1.0.1

Which test runner are you using?

NUnit

Test Runner Version Number

4.5.0

.NET Implementation

.NET 6.0

Test Execution Method

ReSharper Test Runner

Content of reqnroll.json configuration file

{
  "$schema": "https://schemas.reqnroll.net/reqnroll-config-latest.json",
  "bindingAssemblies": [
    {
      "assembly": "My.External.NuGet"
    }
  ]
}

Issue Description

I am using Rider with the latest build of the Rider.Reqnroll plugin.
I have two .cs files for Hooks, TestRunLevelHooks:

[Binding]
public sealed class TestRunLevelHooks
{
    private static IPlaywright _playwright;
    private static IBrowser _browser;
    private static IObjectContainer _objectContainer;

    [BeforeTestRun]
    public static async Task BeforeTestRun(IObjectContainer objectContainer)
    {
        _objectContainer = objectContainer;

        var env = Environment.GetEnvironmentVariable("ENV")?.ToLower() ?? "";

        var testConfig = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("test_settings.json", false, true)
            .AddJsonFile($"test_settings.{env}.json", true, true)
            .AddEnvironmentVariables()
            .Build();

        TestConfiguration.BrowserOptions = testConfig.GetSection("BrowserOptions")
            .Get<BrowserTypeLaunchOptions>();
        
        _playwright = await Playwright.CreateAsync();

        _browser = await _playwright.Chromium.LaunchAsync(TestConfiguration.BrowserOptions);

        _objectContainer.RegisterInstanceAs(_playwright);
        _objectContainer.RegisterInstanceAs(_browser);
    }

    [AfterTestRun]
    public static async Task AfterTestRun()
    {
        await _browser.CloseAsync();
        _playwright.Dispose();
    }
}

and ScenarioLevelHooks:

[Binding]
public sealed class ScenarioLevelHooks
{
    private readonly IBrowser _browser;
    private readonly IObjectContainer _objectContainer;
    private readonly ScenarioContext _scenarioContext;
    private IBrowserContext _browserContext;
    private IPage _page;

    public ScenarioLevelHooks(IObjectContainer objectContainer, IBrowser browser, ScenarioContext scenarioContext)
    {
        _browser = browser;
        _scenarioContext = scenarioContext;
        _objectContainer = objectContainer;
    }

    [BeforeScenario(Order = 0)]
    public async Task BeforeScenario()
    {
        _browserContext =
            await _browser.NewContextAsync(TestConfiguration.BrowserContextOptions);

        _page = await _browserContext.NewPageAsync();

        _page.SetDefaultTimeout(30000);
        _page.SetDefaultNavigationTimeout(30000);

        _objectContainer.RegisterInstanceAs(_browserContext);
        _objectContainer.RegisterInstanceAs(_page);
    }

    [BeforeScenario(Order = 1)]
    public async Task StartTracing()
    {
        await _browserContext.Tracing.StartAsync(new TracingStartOptions
        {
            Screenshots = true,
            Snapshots = true,
            Sources = true
        });
    }

    [AfterScenario]
    public async Task AfterScenario()
    {
        await _page.CloseAsync();
        await _browserContext.CloseAsync();
    }
}

I execute a test using Test Explorer in Rider and getting the following error:

BoDi.ObjectContainerException : Interface cannot be resolved: Microsoft.Playwright.IBrowser (resolution path: MyProject.UITests.Hooks.ScenarioLevelHooks)
TearDown : BoDi.ObjectContainerException : Interface cannot be resolved: Microsoft.Playwright.IBrowser (resolution path: MyProject.UITests.Hooks.ScenarioLevelHooks)
at BoDi.ObjectContainer.TypeRegistration.<>c__DisplayClass3_0.b__1()
at BoDi.ObjectContainer.RegistrationWithStrategy.ExecuteWithLock(Object lockObject, Func1 getter, Func1 factory, ResolutionList resolutionPath)
at BoDi.ObjectContainer.TypeRegistration.ResolvePerContext(ObjectContainer container, RegistrationKey keyToResolve, ResolutionList resolutionPath)
at BoDi.ObjectContainer.RegistrationWithStrategy.Resolve(ObjectContainer container, RegistrationKey keyToResolve, ResolutionList resolutionPath)
at BoDi.ObjectContainer.ResolveObject(RegistrationKey keyToResolve, ResolutionList resolutionPath)
at BoDi.ObjectContainer.Resolve(Type typeToResolve, ResolutionList resolutionPath, String name)
at BoDi.ObjectContainer.<>c__DisplayClass71_0.b__0(ParameterInfo p)
at System.Linq.Enumerable.SelectArrayIterator2.ToArray() at BoDi.ObjectContainer.ResolveArguments(IEnumerable1 parameters, RegistrationKey keyToResolve, ResolutionList resolutionPath)
at BoDi.ObjectContainer.CreateObject(Type type, ResolutionList resolutionPath, RegistrationKey keyToResolve)
at BoDi.ObjectContainer.TypeRegistration.<>c__DisplayClass3_0.b__1()
at BoDi.ObjectContainer.RegistrationWithStrategy.ExecuteWithLock(Object lockObject, Func1 getter, Func1 factory, ResolutionList resolutionPath)
at BoDi.ObjectContainer.TypeRegistration.ResolvePerContext(ObjectContainer container, RegistrationKey keyToResolve, ResolutionList resolutionPath)
at BoDi.ObjectContainer.RegistrationWithStrategy.Resolve(ObjectContainer container, RegistrationKey keyToResolve, ResolutionList resolutionPath)
at BoDi.ObjectContainer.ResolveObject(RegistrationKey keyToResolve, ResolutionList resolutionPath)
at BoDi.ObjectContainer.Resolve(Type typeToResolve, ResolutionList resolutionPath, String name)
at BoDi.ObjectContainer.Resolve(Type typeToResolve, String name)
at Reqnroll.Infrastructure.TestObjectResolver.ResolveBindingInstance(Type bindingType, IObjectContainer container)
at lambda_method25(Closure , IContextManager )

The issue started after migrate to Reqnroll using the namespace changes method. It was not reproduced when using SpecFlow and I have kept the same dependency injection methods.

Here is the .csproj (if it matters):

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <LangVersion>10</LangVersion>
  </PropertyGroup>

  <ItemGroup>
    <Using Include="Reqnroll"/>
    <Using Include="Microsoft.Playwright"/>
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="My.External.NuGet" Version="1.1.0-rc1"/>
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0"/>
    <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.1"/>
    <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0"/>
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0"/>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0"/>
    <PackageReference Include="Microsoft.Playwright" Version="1.41.2"/>
    <PackageReference Include="ReportPortal.Extensions.SourceBack" Version="2.1.0"/>
    <PackageReference Include="ReportPortal.Reqnroll" Version="1.0.0"/>
    <PackageReference Include="Reqnroll.NUnit" Version="1.0.1"/>
    <PackageReference Include="RestSharp" Version="110.2.0"/>
    <PackageReference Include="nunit" Version="4.1.0"/>
    <PackageReference Include="NUnit3TestAdapter" Version="4.5.0"/>
    <PackageReference Include="FluentAssertions" Version="6.12.0"/>
  </ItemGroup>

  <ItemGroup>
    <None Update="test_settings*.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="ReportPortal.config.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>

  <ItemGroup>
    <Content Include="Features\*.feature"/>
  </ItemGroup>

</Project>

Steps to Reproduce

When debugging, I managed to see that the [BeforeTestRun] executed successfully, registering all objects to the _objectContainer. The error occurs in the ScenarioLevelHooks.

Link to Repro Project

No response

@konarx konarx added the bug Something isn't working label Feb 28, 2024
@konarx konarx changed the title BoDi.ObjectContainerException : Interface cannot be resolved: Microsoft.Playwright.IBrowser BoDi.ObjectContainerException: Interface cannot be resolved: Microsoft.Playwright.IBrowser Feb 28, 2024
@gasparnagy
Copy link
Contributor

@konarx Which version of SpecFlow did you use before migrating?

@gasparnagy
Copy link
Contributor

gasparnagy commented Feb 28, 2024

I was able to reproduce the issue. I think this was an issue already in SpecFlow v4 beta, but I am waiting for your confirmation on that.

The problem is that the IObjectContainer you get in the [BeforeTestRun] hook should be the "global container", but for some reason the "test thread container" is injected instead. For some other reason (I'm not sure if this is OK), the scenario and the related [BeforeScenario] hook is running in another test thread so it does not "see" the registrations you made on the container.

This has to be fixed.

Workaround: The workaround is to get the "base container" of the "test thread container" in the [BeforeTestRun] hook. So you need to change the line in the BeforeTestRun method from:

_objectContainer = objectContainer;

to

_objectContainer = ((ObjectContainer)objectContainer).BaseContainer;

(this workaround needs to be reverted once the issue is fixed)

@konarx
Copy link
Author

konarx commented Feb 28, 2024

Thank you @gasparnagy, the suggested workaround does the trick indeed. I can proceed with the migration now.

@gasparnagy
Copy link
Contributor

It is fixed now by #59 and will be included in the next release. In the meantime please use the workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants