utils/WasmTestRunner/Program.cs (172 lines of code) (raw):

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Xml.Linq; using Mono.Options; using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Chromium; using OpenQA.Selenium.Edge; namespace WasmTestRunner { public class Program { private const string DefaultUrl = "http://localhost:5000/"; private const string ResultsFileName = "TestResults.xml"; private static string chromeDriverPath; public static string ChromeDriverPath { get => chromeDriverPath; set { chromeDriverPath = value; var fname = Path.GetFileNameWithoutExtension(chromeDriverPath); if (fname.Equals("msedgedriver", StringComparison.OrdinalIgnoreCase)) UseEdge = true; } } public static string OutputPath { get; set; } = Directory.GetCurrentDirectory(); public static int Timeout { get; set; } = 30; public static bool UseHeadless { get; set; } = true; public static bool UseEdge { get; set; } public static bool ShowHelp { get; set; } public static bool Verbose { get; set; } public static string Url { get; set; } = DefaultUrl; public static int Main(string[] args) { var p = new OptionSet { { "d|driver=", "the path to the ChromeDriver executable. Default is use the local version.", v => ChromeDriverPath = v }, { "o|output=", "the path to the test results file. Default is the current directory.", v => OutputPath = v }, { "t|timeout=", "the number of seconds to wait before timing out. Default is 30.", (int v) => Timeout = v }, { "no-headless", "do not use a headless browser.", v => UseHeadless = false }, { "v|verbose", "show verbose error messages.", v => Verbose= true }, { "h|help", "show this message and exit.", v => ShowHelp = true }, }; List<string> extra; try { extra = p.Parse(args); if (extra.Count > 1) throw new OptionException("To many extras provided.", "extras"); Url = extra.FirstOrDefault() ?? DefaultUrl; if (string.IsNullOrEmpty(OutputPath)) OutputPath = Directory.GetCurrentDirectory(); OutputPath = Path.Combine(OutputPath, ResultsFileName); var dir = Path.GetDirectoryName(OutputPath); if (!string.IsNullOrEmpty(dir)) Directory.CreateDirectory(dir); } catch (OptionException ex) { Console.Error.Write("wasm-test: "); Console.Error.WriteLine(ex.Message); Console.Error.WriteLine("Try `wasm-test --help' for more information."); if (Verbose) Console.Error.WriteLine(ex); return 1; } if (ShowHelp) { Console.WriteLine("Usage: wasm-test [OPTIONS]+ URL"); Console.WriteLine("Run WASM tests in the browser."); Console.WriteLine(); Console.WriteLine("Options:"); p.WriteOptionDescriptions(Console.Out); return 0; } try { RunTests(); var xdoc = XDocument.Load(OutputPath); var failed = xdoc.Root.Element("assembly").Attribute("failed").Value; if (failed != "0") throw new Exception($"There were test failures: {failed}"); } catch (Exception ex) { Console.Error.WriteLine($"There was an error running the tests: {ex.Message}"); if (Verbose) Console.Error.WriteLine(ex); return 1; } return 0; } private static ChromiumOptions CreateOptions() { if (UseEdge) { return new EdgeOptions(); } else { return new ChromeOptions(); } } private static (ChromiumDriverService Service, ChromiumDriver Driver) CreateDriver(ChromiumOptions options) { if (UseEdge) { var service = string.IsNullOrEmpty(ChromeDriverPath) ? EdgeDriverService.CreateDefaultService() : EdgeDriverService.CreateDefaultService(ChromeDriverPath); var driver = new EdgeDriver(service, (EdgeOptions)options); return (service, driver); } else { var service = string.IsNullOrEmpty(ChromeDriverPath) ? ChromeDriverService.CreateDefaultService() : ChromeDriverService.CreateDefaultService(ChromeDriverPath); var driver = new ChromeDriver(service, (ChromeOptions)options); return (service, driver); } } private static void RunTests() { var options = CreateOptions(); if (UseHeadless) { options.AddArgument("no-sandbox"); options.AddArgument("headless"); } options.AddArgument("window-size=1024x768"); var (service, driver) = CreateDriver(options); using var _ = service; using var __ = driver; driver.Url = Url; var index = 0; var currentTimeout = Timeout; do { var pre = driver.FindElements(By.TagName("PRE")).Skip(index).ToArray(); if (pre.Length > 0) { index += pre.Length; currentTimeout = Timeout; // reset the timeout foreach (var e in pre) Console.WriteLine(e.Text); } var resultsElement = driver.FindElements(By.Id("results")); if (resultsElement.Count == 0) { if (driver.FindElements(By.ClassName("neterror")).Count > 0) { var errorCode = driver.FindElements(By.ClassName("error-code")).FirstOrDefault()?.Text; throw new Exception($"There was an error loading the page: {errorCode}"); } Thread.Sleep(500); continue; } var text = resultsElement[0].Text; var bytes = Convert.FromBase64String(text); File.WriteAllBytes(OutputPath, bytes); break; } while (--currentTimeout > 0); if (currentTimeout <= 0) throw new TimeoutException(); } } }