Skip to content

Commit

Permalink
Merge pull request #266 from Lombiq/issue/WALMA-133
Browse files Browse the repository at this point in the history
WALMA-133: Adding fake video capture file configuration to chrome
  • Loading branch information
Psichorex authored Mar 24, 2023
2 parents 5bbed7c + 450f453 commit c22651e
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 2 deletions.
9 changes: 7 additions & 2 deletions Lombiq.Tests.UI/Constants/DirectoryPaths.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Linq;

namespace Lombiq.Tests.UI.Constants;

Expand All @@ -10,8 +9,14 @@ public static class DirectoryPaths
public const string Temp = nameof(Temp);
public const string Screenshots = nameof(Screenshots);

public static string GetTempDirectoryPath(params string[] subDirectoryNames) =>
Path.Combine(
Path.Combine(Environment.CurrentDirectory, Temp),
Path.Combine(subDirectoryNames));

public static string GetTempSubDirectoryPath(string contextId, params string[] subDirectoryNames) =>
Path.Combine(new[] { Environment.CurrentDirectory, Temp, contextId }.Concat(subDirectoryNames).ToArray());
GetTempDirectoryPath(
Path.Combine(contextId, Path.Combine(subDirectoryNames)));

public static string GetScreenshotsDirectoryPath(string contextId) =>
GetTempSubDirectoryPath(contextId, Screenshots);
Expand Down
71 changes: 71 additions & 0 deletions Lombiq.Tests.UI/Docs/FakeVideoCaptureSource.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Fake video capture source

## Preparing video file

You can use video files as a fake video capture source in Chrome browser of format `y4m` or `mjpeg`.

If you have a video file in e.g., `mp4` format, use your preferred video tool to convert it to one of the formats mentioned above. If you don't have a preferred tool, simply use `ffmpeg`.

_Suggestion: use `mjpeg`, it will result in a smaller file size._

```bash
# Convert mp4 to y4m.
ffmpeg -y -i test.mp4 -pix_fmt yuv420p test.y4m

# Convert with resize to 480p.
ffmpeg -y -i test.mp4 -filter:v scale=480:-1 -pix_fmt yuv420p test.y4m

# Convert mp4 to mjpeg.
ffmpeg -y -i test.mp4 test.mjpeg

# Convert with resize to 480p.
ffmpeg -y -i test.mp4 -filter:v scale=480:-1 test.mjpeg

```

### Configuring test

Add the prepared video file to your `csproj` project as an `EmbeddedResource`, and then configure the test method as shown below.

```csharp
using Lombiq.Tests.UI.Attributes;
using Lombiq.Tests.UI.Constants;
using Lombiq.Tests.UI.Extensions;
using Lombiq.Tests.UI.Models;
using Lombiq.Tests.UI.Services;
using OpenQA.Selenium;
using Shouldly;
using System.Linq;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace Lombiq.Tests.UI.Samples.Tests;

public class BasicTests : UITestBase
{
public BasicTests(ITestOutputHelper testOutputHelper)
: base(testOutputHelper)
{
}

[Theory, Chrome]
public Task TestMethod(Browser browser) =>
ExecuteTestAfterSetupAsync(
async context =>
{
// ...
},
browser,
configuration =>
// Here we set the fake video source configuration.
configuration.BrowserConfiguration.FakeVideoSource = new FakeBrowserVideoSource
{
StreamProvider = () =>
// Load video file content from resources.
typeof(BasicTests).Assembly.GetManifestResourceStream(typeof(BasicTests), "BasicTest.mjpeg"),
// Set the video format.
Format = FakeBrowserVideoSourceFileFormat.MJpeg,
});
}
```
30 changes: 30 additions & 0 deletions Lombiq.Tests.UI/Extensions/FakeBrowserVideoSourceExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using Lombiq.Tests.UI.Constants;
using Lombiq.Tests.UI.Models;
using System;
using System.IO;

namespace Lombiq.Tests.UI.Extensions;

public static class FakeBrowserVideoSourceExtensions
{
public static string SaveVideoToTempFolder(this FakeBrowserVideoSource source)
{
using var fakeCameraSource = source.StreamProvider();
var fakeCameraSourcePath = Path.ChangeExtension(
DirectoryPaths.GetTempDirectoryPath(Guid.NewGuid().ToString()),
GetExtension(source.Format));
using var fakeCameraSourceFile = new FileStream(fakeCameraSourcePath, FileMode.CreateNew, FileAccess.Write);

fakeCameraSource.CopyTo(fakeCameraSourceFile);

return fakeCameraSourcePath;
}

private static string GetExtension(FakeBrowserVideoSourceFileFormat format) =>
format switch
{
FakeBrowserVideoSourceFileFormat.MJpeg => "mjpeg",
FakeBrowserVideoSourceFileFormat.Y4m => "y4m",
_ => throw new ArgumentOutOfRangeException(nameof(format)),
};
}
19 changes: 19 additions & 0 deletions Lombiq.Tests.UI/Models/FakeBrowserVideoSource.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.IO;

namespace Lombiq.Tests.UI.Models;

public class FakeBrowserVideoSource
{
/// <summary>
/// Gets or sets a callback that will be used to obtain the video content <see cref="Stream"/> and will be saved and used
/// as a fake video capture file for the Chrome browser. The consumer will dispose of the returned <see cref="Stream"/>
/// after the callback is called.
/// </summary>
public Func<Stream> StreamProvider { get; set; }

/// <summary>
/// Gets or sets the video format of the provided stream.
/// </summary>
public FakeBrowserVideoSourceFileFormat Format { get; set; } = FakeBrowserVideoSourceFileFormat.MJpeg;
}
7 changes: 7 additions & 0 deletions Lombiq.Tests.UI/Models/FakeBrowserVideoSourceFileFormat.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Lombiq.Tests.UI.Models;

public enum FakeBrowserVideoSourceFileFormat
{
MJpeg,
Y4m,
}
6 changes: 6 additions & 0 deletions Lombiq.Tests.UI/Services/BrowserConfiguration.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Lombiq.Tests.UI.Constants;
using Lombiq.Tests.UI.Models;
using SixLabors.ImageSharp;
using System;
using System.Globalization;
Expand Down Expand Up @@ -37,4 +38,9 @@ public class BrowserConfiguration
/// cref="CommonDisplayResolutions.Standard"/> when the setup is loaded.
/// </summary>
public Size DefaultBrowserSize { get; set; } = CommonDisplayResolutions.Standard;

/// <summary>
/// Gets or sets the fake camera video source information. See: <see cref="FakeBrowserVideoSource"/>.
/// </summary>
public FakeBrowserVideoSource FakeVideoSource { get; set; }
}
10 changes: 10 additions & 0 deletions Lombiq.Tests.UI/Services/WebDriverFactory.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Lombiq.Tests.UI.Extensions;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;
Expand Down Expand Up @@ -136,6 +137,15 @@ private static TDriverOptions SetCommonChromiumOptions<TDriverOptions>(
// Disabling smooth scrolling to avoid large waiting time when taking full-page screenshots.
options.AddArgument("disable-smooth-scrolling");

if (configuration.FakeVideoSource is not null)
{
var fakeCameraSourceFilePath = configuration.FakeVideoSource.SaveVideoToTempFolder();

options.AddArgument("use-fake-device-for-media-stream");
options.AddArgument("use-fake-ui-for-media-stream");
options.AddArgument($"use-file-for-fake-video-capture={fakeCameraSourceFilePath}");
}

if (configuration.Headless) options.AddArgument("headless");

return options;
Expand Down
1 change: 1 addition & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Highlights:
- Ready to use GitHub Actions workflows for CI builds and support for test grouping and error annotations in [Lombiq GitHub Actions](https://github.com/features/actions). This feature is automatically enabled if a GitHub environment is detected.
- Support for [TeamCity test metadata reporting](https://www.jetbrains.com/help/teamcity/reporting-test-metadata.html) so you can see the important details and metrics of a test at a glance in a TeamCity CI/CD server.
- Visual verification testing: You can make the test fail if the look of the app changes. Demo video [here](https://www.youtube.com/watch?v=a-1zKjxTKkk).
- Using video files as a fake video capture source in Chrome browser. Docs [here](Lombiq.Tests.UI/Docs/FakeVideoCaptureSource.md).

See a demo video of the project [here](https://www.youtube.com/watch?v=mEUg6-pad-E). Also, see our [Testing Toolbox](https://github.com/Lombiq/Testing-Toolbox) for similar features for lower-level tests.

Expand Down

0 comments on commit c22651e

Please sign in to comment.