public void WithSeleniumReporting_WithConfiguration_ShouldReturnCorrectValue( [Modest] Actor actor, IActor iactor, SeleniumReportingConfiguration configuration, IObserver <string>[] observers, ICanNotify canNotify, ITakeScreenshotStrategy takeScreenshotStrategy, ScreenshotFormat format) { var actual = ActorExtensions.WithSeleniumReporting( actor, configuration, out var actualSeleniumReporter ); TestWithSeleniumReporting(actualSeleniumReporter, actual, actor, iactor, configuration.ScreenshotDirectory, configuration.ScreenshotNameOrFormat, observers, canNotify, takeScreenshotStrategy, format); }
/// <summary> /// Use the given strategy to take screenshots /// </summary> public SeleniumReportingConfiguration WithTakeScreenshotStrategy(ITakeScreenshotStrategy takeScreenshotStrategy) { return(new SeleniumReportingConfiguration(ScreenshotDirectory, ScreenshotNameOrFormat, _canNotify, TextOutputObservers, takeScreenshotStrategy)); }
private static void TestWithSeleniumReporting( ISeleniumReporter actualSeleniumReporter, Actor actual, Actor actor, IActor iactor, string screenshotDirectory, string screenshotName, IObserver <string>[] observers, ICanNotify canNotify, ITakeScreenshotStrategy takeScreenshotStrategy) { // assert var xmlDocumentObserver = new XmlDocumentObserver(); var takeScreenshot = actual.InnerActorBuilder(iactor).Should().BeOfType <TakeScreenshot>().Which; var expectedTakeScreenshot = ActorExtensions.TakeScreenshots( actor, screenshotName, new CompositeObserver <ScreenshotInfo>( new ScreenshotInfoToActionAttachmentObserverAdapter(xmlDocumentObserver), new RenderedScreenshotInfoObserver(new CompositeObserver <string>(observers)), new SaveScreenshotsToFileOnComplete(screenshotDirectory) ), takeScreenshotStrategy ) .InnerActorBuilder(iactor) as TakeScreenshot; takeScreenshot.Should().BeEquivalentTo(expectedTakeScreenshot, o => o.Excluding(a => a.Actor) .Excluding(a => a.NextScreenshotName) .RespectingRuntimeTypes()); var actualScreenshotNames = Enumerable.Range(0, 10).Select(_ => takeScreenshot.NextScreenshotName()); var expectedScreenshotNames = Enumerable.Range(0, 10).Select(_ => expectedTakeScreenshot.NextScreenshotName()); actualScreenshotNames.Should().BeEquivalentTo(expectedScreenshotNames); var reportingActor = takeScreenshot.Actor.Should().BeOfType <ReportingActor>().Which; var expectedReportingActor = actor.WithReporting( new CompositeObserver <ActionNotification>( xmlDocumentObserver, new RenderedReportingObserver( new CompositeObserver <string>(observers), RenderedReportingObserver.DefaultRenderer ) ), canNotify ) .InnerActorBuilder(iactor) as ReportingActor; reportingActor.Should().BeEquivalentTo(expectedReportingActor, o => o.Excluding(a => a.Actor) .Excluding(a => a.MeasureTime.Now) .Excluding((IMemberInfo m) => m.RuntimeType == typeof(DateTimeOffset)) .RespectingRuntimeTypes()); var expectedSeleniumReporter = new SeleniumReporter(xmlDocumentObserver, new SaveScreenshotsToFileOnComplete(screenshotDirectory)); actualSeleniumReporter.Should().BeEquivalentTo(expectedSeleniumReporter, o => o.Excluding((IMemberInfo m) => m.RuntimeType == typeof(DateTimeOffset))); }
/// <summary> /// Add the ability to take screenshot on each action. The screenshots are saved using the given <see cref="ScreenshotInfo"/> observer. /// </summary> /// <param name="actor">The actor</param> /// <param name="screenshotNameOrFormat">A string containing a format for 0 or 1 format item, used to generate the screenshot names. If no format item is provided, the default format is "<paramref name="screenshotNameOrFormat"/>_{0:00}".</param> /// <param name="screenshotInfoObserver">An observer that is notify that screenshots were taken, and can be used to save them on the disk. /// Use <see cref="SaveScreenshotsToFileOnComplete"/> or <see cref="SaveScreenshotsToFileOnNext"/></param> /// <param name="takeScreenshotStrategy">The strategy used to create a screenshot</param> /// <example> /// actor.TakeScreenshots("Screenhshot_{0:000}", new SaveScreenshotsToFileOnComplete(@"C:\tests\screeshots")); /// </example> /// <returns>An new actor taking screenshots</returns> public static Actor TakeScreenshots( this Actor actor, string screenshotNameOrFormat, IObserver <ScreenshotInfo> screenshotInfoObserver, ITakeScreenshotStrategy takeScreenshotStrategy) { if (screenshotInfoObserver == null) { throw new ArgumentNullException(nameof(screenshotInfoObserver)); } if (takeScreenshotStrategy == null) { throw new ArgumentNullException(nameof(takeScreenshotStrategy)); } if (actor == null) { throw new ArgumentNullException(nameof(actor)); } if (screenshotNameOrFormat == null) { throw new ArgumentNullException(nameof(screenshotNameOrFormat)); } var id = 0; string screenshotFormat; if (string.Format(screenshotNameOrFormat, 1) == screenshotNameOrFormat) { screenshotFormat = screenshotNameOrFormat + "_" + "{0:00}"; } else { screenshotFormat = screenshotNameOrFormat; } string nextScreenshotName() { return(string.Format(CultureInfo.InvariantCulture, screenshotFormat, Interlocked.Increment(ref id))); } return(new Actor(actor.Name, actor.Abilities, a => new TakeScreenshot(actor.InnerActorBuilder(a), nextScreenshotName, screenshotInfoObserver, takeScreenshotStrategy))); }
private SeleniumReportingConfiguration(string screenshotDirectory, string screenshotNameOrFormat, ICanNotify canNotify, ImmutableArray <IObserver <string> > textOutputObservers, ITakeScreenshotStrategy takeScreenshotStrategy) { if (string.IsNullOrEmpty(screenshotDirectory)) { throw new ArgumentNullException(nameof(screenshotDirectory)); } if (string.IsNullOrEmpty(screenshotNameOrFormat)) { throw new ArgumentNullException(nameof(screenshotNameOrFormat)); } ScreenshotDirectory = screenshotDirectory; ScreenshotNameOrFormat = screenshotNameOrFormat; _canNotify = canNotify; TextOutputObservers = textOutputObservers; TakeScreenshotStrategy = takeScreenshotStrategy; }
/// <summary> /// Add the ability to take screenshot on each action. The screenshots are saved using the given <see cref="ScreenshotInfo"/> observer. /// </summary> /// <param name="actor">The actor</param> /// <param name="screenshotNameOrFormat">A string containing a format for 0 or 1 format item, used to generate the screenshot names. If no format item is provided, the default format is "<paramref name="screenshotNameOrFormat"/>_{0:00}".</param> /// <param name="screenshotInfoObserver">An observer that is notify that screenshots were taken, and can be used to save them on the disk. /// Use <see cref="SaveScreenshotsToFileOnComplete"/> or <see cref="SaveScreenshotsToFileOnNext"/></param> /// <param name="takeScreenshotStrategy">The strategy used to create a screenshot</param> /// <example> /// actor.TakeScreenshots("Screenhshot_{0:000}", new SaveScreenshotsToFileOnComplete(@"C:\tests\screeshots")); /// </example> /// <returns>An new actor taking screenshots</returns> public static Actor TakeScreenshots( this Actor actor, string screenshotNameOrFormat, IObserver <ScreenshotInfo> screenshotInfoObserver, ITakeScreenshotStrategy takeScreenshotStrategy) { if (screenshotInfoObserver == null) { throw new ArgumentNullException(nameof(screenshotInfoObserver)); } if (takeScreenshotStrategy == null) { throw new ArgumentNullException(nameof(takeScreenshotStrategy)); } if (actor == null) { throw new ArgumentNullException(nameof(actor)); } if (screenshotNameOrFormat == null) { throw new ArgumentNullException(nameof(screenshotNameOrFormat)); } var id = 0; #pragma warning disable S1854 // Unused assignments should be removed. False positive var screenshotFormat = string.Format(screenshotNameOrFormat, 1) == screenshotNameOrFormat #pragma warning restore S1854 // Unused assignments should be removed ? screenshotNameOrFormat + "_" + "{0:00}" : screenshotNameOrFormat; string nextScreenshotName() { return(string.Format(CultureInfo.InvariantCulture, screenshotFormat, Interlocked.Increment(ref id))); } return(new Actor(actor.Name, actor.Abilities, a => new TakeScreenshot(actor.InnerActorBuilder(a), nextScreenshotName, screenshotInfoObserver, takeScreenshotStrategy))); }
/// <summary> /// Creates a new instance of <see cref="TakeScreenshot"/> /// </summary> /// <param name="actor">The decorated actor</param> /// <param name="nextScreenshotName">A function returning the name of the next screenshot. Each name should be different.</param> /// <param name="screenshotsObserver">An observer that can be used to notify that a screenshot was taken</param> /// <param name="takeScreenshotStrategy">The strategy used to take screenshots</param> public TakeScreenshot(IActor actor, Func <string> nextScreenshotName, IObserver <ScreenshotInfo> screenshotsObserver, ITakeScreenshotStrategy takeScreenshotStrategy) { Actor = actor ?? throw new ArgumentNullException(nameof(actor)); NextScreenshotName = nextScreenshotName ?? throw new ArgumentNullException(nameof(nextScreenshotName)); ScreenshotObserver = screenshotsObserver ?? throw new ArgumentNullException(nameof(screenshotsObserver)); TakeScreenshotStrategy = takeScreenshotStrategy ?? throw new ArgumentNullException(nameof(takeScreenshotStrategy)); }