c# - 从 LightBDD 装饰器中,如何从 DependencyResolver 中检索场景的当前 ChromeDriver?
问题描述
我正在使用LightBDD运行 Selenium 测试,并且我试图在场景失败时自动截取屏幕截图。我编写了一个类级别的 LightBDD 装饰器来执行此操作,但我从 检索 ChromeDriver 的一个新实例,ResourcePool
而不是检索当前的 ChromeDriver。
如何检索场景的当前ChromeDriver 而不是新实例?
更多细节
我正在按照提供的示例注册 ChromeDriver ,即:
private void ConfigureContainer(ContainerConfigurator config)
{
config.RegisterInstance(
new ResourcePool<ChromeDriver>(CreateDriver),
new RegistrationOptions());
}
private ChromeDriver CreateDriver()
{
var driver = new ChromeDriver();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(0);
return driver;
}
我的装饰器:
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class TakeScreenshotOnErrorAttribute : Attribute, IScenarioDecoratorAttribute
{
public async Task ExecuteAsync(IScenario scenario, Func<Task> scenarioInvocation)
{
try {
await scenarioInvocation();
}
catch (Exception ex) {
await TakeScreenshot(scenario);
}
}
public int Order { get; set; }
private static async Task TakeScreenshot(IScenario scenario)
{
try {
var driverHandle = scenario.DependencyResolver.Resolve(typeof(ResourceHandle<ChromeDriver>));
var driver = await ((ResourceHandle<ChromeDriver>) driverHandle).ObtainAsync();
var screenshot = driver.GetScreenshot();
screenshot.SaveAsFile(@"c:\temp\error.png");
}
catch {
/* Ignore */
}
}
}
版本:带有 NUnit3 的 LightBDD 3.0.1
解决方案
LightBDD DI 容器的默认行为是在每次Resolve()
调用方法时提供所请求依赖项的新实例。
为了使其按预期工作,必须使用更高级的 DI(如LightBDD.Autofac包),并且ResourceHandle<ChromeDriver>
必须使用作用域生命周期进行注册:
public class ConfiguredLightBddScopeAttribute : LightBddScopeAttribute
{
protected override void OnConfigure(LightBddConfiguration configuration)
{
configuration.DependencyContainerConfiguration()
.UseAutofac(ConfigureContainer());
}
private ContainerBuilder ConfigureContainer()
{
var builder = new ContainerBuilder();
builder.RegisterInstance(new ResourcePool<ChromeDriver>(CreateDriver));
builder.RegisterType<ResourceHandle<ChromeDriver>>().InstancePerLifetimeScope();
// ^-- this makes the difference
return builder;
}
private ChromeDriver CreateDriver()
{
var driver = new ChromeDriver();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(0);
return driver;
}
}
这意味着虽然每个场景都将获得自己的句柄副本,但场景代码和装饰器代码将获得相同的实例。
我在 LightBDD 问题页面的回复中提供了工作示例:https ://github.com/LightBDD/LightBDD/issues/186
推荐阅读
- 3d - 在文本 STEP 文件 ISO-10303-21 中旋转和移动模型
- django - Django Rest Framework API,调用 get_queryset 两次
- bluetooth-lowenergy - DeviceWatcher.Added 方法创建编译问题
- azure - Windows VM 系统分配的托管标识以访问 Typescript 中的 Azure Key Vault?
- javascript - Web API:net::ERR_EMPTY_RESPONSE 与西门子 PLC 设备通信成功后
- angular - Selenium - 在 shadow dom 中测试 iframe
- amazon-web-services - aws ec2 describe-instances 标签值反向搜索意外行为
- wpf - 不依赖于 MainWindow 的 DialogService
- sql-server - SQL Server 合并复制 - 快照重新应用时订阅者数据丢失以解决错误
- java - 如何在jpa中加入具有多个主键或特定主键的列