Lidarr/src/NzbDrone.Automation.Test/BrowserStackAutomationTest.cs

201 lines
7.2 KiB
C#

using System;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using FluentAssertions;
using Mono.Unix.Native;
using NLog;
using NUnit.Framework;
using NzbDrone.Automation.Test.PageModel;
using NzbDrone.Common.EnvironmentInfo;
using NzbDrone.Common.Extensions;
using NzbDrone.Common.Processes;
using NzbDrone.Test.Common;
using OpenQA.Selenium.Remote;
namespace NzbDrone.Automation.Test
{
[TestFixture("", "Windows", "10", "Chrome", "63", 9901)]
[TestFixture("", "Windows", "10", "Firefox", "67", 9902)]
[TestFixture("", "Windows", "10", "Edge", "18", 9903)]
[TestFixture("", "OS X", "Mojave", "Safari", "12.1", 9904)]
// [TestFixture("iPhone X", "", "11", "iPhone", "", 9905)]
// [TestFixture("Samsung Galaxy S9 Plus", "", "9.0", "android", "", 9906)]
[Parallelizable(ParallelScope.Fixtures)]
public class BrowserStackAutomationTest : MainPagesTest
{
protected string browser;
protected string browserVersion;
protected string os;
protected string osVersion;
protected string device;
private readonly Logger _logger;
private ProcessProvider _processProvider;
private Process _browserStackLocalProcess;
public BrowserStackAutomationTest(string device, string os, string osVersion, string browser, string browserVersion, int port)
{
this.device = device;
this.browser = browser;
this.browserVersion = browserVersion;
this.os = os;
this.osVersion = osVersion;
_logger = LogManager.GetCurrentClassLogger();
_processProvider = new ProcessProvider(_logger);
_runner = new NzbDroneRunner(_logger, port);
}
[OneTimeSetUp]
public override void SmokeTestSetup()
{
string username = Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME");
string accessKey = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY");
if (username.IsNullOrWhiteSpace() || accessKey.IsNullOrWhiteSpace())
{
Assert.Ignore("BrowserStack Tests Disabled, No Credentials");
}
_runner.Start();
string browserstackLocal = "true";
string browserstackLocalIdentifier = string.Format("Lidarr_{0}_{1}", DateTime.UtcNow.Ticks, new Random().Next());
string buildName = BuildInfo.Version.ToString();
string serverOs = OsInfo.Os.ToString();
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.SetCapability("device", device);
capabilities.SetCapability("os", os);
capabilities.SetCapability("os_version", osVersion);
capabilities.SetCapability("browser", browser);
capabilities.SetCapability("browser_version", browserVersion);
capabilities.SetCapability("browserstack.local", browserstackLocal);
capabilities.SetCapability("browserstack.localIdentifier", browserstackLocalIdentifier);
capabilities.SetCapability("browserstack.debug", "true");
capabilities.SetCapability("browserstack.console", "verbose");
capabilities.SetCapability("name", string.Format("Functional Tests: {0} - {1}", serverOs, browser));
capabilities.SetCapability("project", "Lidarr");
capabilities.SetCapability("build", buildName);
var bsLocalArgs = $"--key {accessKey} --local-identifier {browserstackLocalIdentifier} --verbose";
_browserStackLocalProcess = StartBrowserStackLocal(_runner.AppData, bsLocalArgs);
driver = new RemoteWebDriver(new Uri("https://" + username + ":" + accessKey + "@hub.browserstack.com/wd/hub"), capabilities);
driver.Url = $"http://{LocalIPAddress()}:{_runner.Port}";
var page = GetPageBase(driver, device);
page.WaitForNoSpinner();
driver.ExecuteScript("window.Lidarr.NameViews = true;");
GetPageErrors().Should().BeEmpty();
}
private IPAddress LocalIPAddress()
{
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
return host.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
}
private PageBase GetPageBase(RemoteWebDriver driver, string device)
{
if (device.IsNullOrWhiteSpace())
{
return new PageBase(driver);
}
else
{
return new PageBaseMobile(driver);
}
}
[SetUp]
public override void Setup()
{
page = GetPageBase(driver, device);
}
[OneTimeTearDown]
public override void SmokeTestTearDown()
{
driver?.Quit();
if (_browserStackLocalProcess != null && !_browserStackLocalProcess.HasExited)
{
_browserStackLocalProcess.Kill();
}
_runner?.Kill();
}
private Process StartBrowserStackLocal(string tempDir, string args = null)
{
string url;
string name;
if (OsInfo.IsWindows)
{
url = "https://www.browserstack.com/browserstack-local/BrowserStackLocal-win32.zip";
name = "BrowserStackLocal.exe";
}
else if (OsInfo.IsOsx)
{
url = "https://www.browserstack.com/browserstack-local/BrowserStackLocal-darwin-x64.zip";
name = "BrowserStackLocal";
}
else
{
url = "https://www.browserstack.com/browserstack-local/BrowserStackLocal-linux-x64.zip";
name = "BrowserStackLocal";
}
var dest = Path.Combine(tempDir, "browserstack.zip");
TestContext.Progress.WriteLine("Fetching browserstack local");
using (var client = new WebClient())
{
client.DownloadFile(url, dest);
}
ZipFile.ExtractToDirectory(dest, tempDir);
var browserStack = Path.Combine(tempDir, name);
if (OsInfo.IsNotWindows)
{
Syscall.chmod(browserStack, FilePermissions.DEFFILEMODE | FilePermissions.S_IRWXU | FilePermissions.S_IXGRP | FilePermissions.S_IXOTH);
}
TestContext.Progress.WriteLine("Starting browserstack local");
var processStarted = new ManualResetEventSlim();
var process = _processProvider.Start(browserStack, args, onOutputDataReceived: (string data) => {
TestContext.Progress.WriteLine(data);
if (data.Contains("You can now access your local server"))
{
processStarted.Set();
}
});
if (!processStarted.Wait(10000))
{
Assert.Fail("Failed to start browserstack within 10 sec");
}
TestContext.Progress.WriteLine($"Successfully started browserstacklocal pid {process.Id}");
return process;
}
}
}