I have a console application that uses NUnitLite and runs a single selenium test in a headless browser. If I play the application from visual studio, it runs perfectly. What I want is to compile the application into an .exe and run it from a task scheduler. The problem is that when I compile it, the .exe just flashes the command prompt and does nothing. I'm not sure what I'm missing.
I've also tried running with NUnitConsole by installing "NUnit.Console-3.15.0.msi" and by running the following command
nunit3-console "C:\Deployments\PSA_AutoImport_Runner\AutoImport_Runner.dll"
NUnitConsole returns the following error:
Unhandled Exception: NUnit.Engine.NUnitEngineException: Remote test agent exited with non-zero exit code 1 at NUnit.Engine.Services.TestAgency.OnAgentExit(Process process, Guid agentId) at NUnit.Engine.Services.TestAgency.<>c__DisplayClass13_0.b__0(Object sender, EventArgs e) at System.Diagnostics.Process.OnExited() at System.Diagnostics.Process.RaiseOnExited() at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading._ThreadPoolWaitOrTimerCallback.PerformWaitOrTimerCallback(Object state, Boolean timedOut)
Errors, Failures and Warnings
- Error : NUnit.Engine.NUnitEngineException : Unable to acquire remote process agent --NUnitEngineException Unable to acquire remote process agent at NUnit.Engine.Runners.ProcessRunner.CreateAgentAndRunnerIfNeeded()
at NUnit.Engine.Runners.ProcessRunner.RunTests(ITestEventListener listener, TestFilter filter)
Any help/direction towards the NUnitLite way or the NUnitConsole way would be much appreciated. If you need more info, just let me know.
NugetPackages:
Program Code:
using NUnit.Common;
using NUnitLite;
using System.Reflection;
return new AutoRun(typeof(Program).GetTypeInfo().Assembly)
.Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
Test Code:
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using ***.Application.Services;
using ***.AutoImport_Runner;
using ***.Api.Service.Models;
namespace NUnitSeleniumTest
{
public class Tests
{
private TestServer _server;
[OneTimeSetUp]
public void SetUp()
{
// Arrange
IWebHostBuilder builder = new WebHostBuilder()
.UseConfiguration(new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build()
).UseStartup<Startup>();
_server = new TestServer(builder);
}
[OneTimeTearDown]
public void TearDown()
{
_server = null;
}
[Test]
public async Task Test1()
{
var filePath = @"C:\***Downloads";
//Browser needs to be headless
var chromeOptions = new ChromeOptions();
chromeOptions.AddArguments("headless");
//Download the file
using (var webDriver = new ChromeDriver(chromeOptions))
{
var enableDownloadCommandParameters = new Dictionary<string, object>
{
{ "behavior", "allow" },
{ "downloadPath", filePath }
};
var result = ((ChromeDriver)webDriver).ExecuteCdpCommand("Page.setDownloadBehavior", enableDownloadCommandParameters);
webDriver.Navigate().GoToUrl("*********************");
//Don't understand why this is needed but it breaks without it.
webDriver.Manage().Timeouts().ImplicitWait = System.TimeSpan.FromSeconds(60);
//Also need this wait. Without it and the above wait, the code breaks.
WebDriverWait wait = new WebDriverWait(webDriver, new TimeSpan(0, 0, 60));
var element = wait.Until(condition =>
{
try
{
//Subfunction DDL
webDriver.FindElement(By.Id("SubFunctionCombobox")).Click();
webDriver.FindElement(By.Id("SubFunctionCombobox_283")).Click();
webDriver.FindElement(By.Id("SubFunctionCombobox_284")).Click();
webDriver.FindElement(By.Id("SubFunctionCombobox_286")).Click();
webDriver.FindElement(By.Id("SubFunctionCombobox_305")).Click();
webDriver.FindElement(By.Id("SubFunctionCombobox_306")).Click();
webDriver.FindElement(By.Id("_htmCanvasShield")).Click();
//StartDate EndDate
var dtNow = DateTime.Now.Date;
var dtEnd = dtNow.AddMonths(4).Date;
string dtNowStr = dtNow.ToString("MM/dd/yyyy");
string dtEndStr = dtEnd.ToString("MM/dd/yyyy");
((IJavaScriptExecutor)webDriver).ExecuteScript($"$('#StartDateCalendar').val('{dtNowStr}').change();");
((IJavaScriptExecutor)webDriver).ExecuteScript($"$('#EndDateCalendar').val('{dtEndStr}').change();");
return true;
}
catch (StaleElementReferenceException)
{
return false;
}
catch (NoSuchElementException)
{
return false;
}
});
//Export
webDriver.FindElement(By.Id("RunButton")).Click();
//Wait on the file to download Currently 500 seconds
for (var i = 0; i < 500; i++)
{
var fCount = Directory.GetFiles(filePath, "*", SearchOption.TopDirectoryOnly).Length;
if (fCount > 0)
{
Thread.Sleep(10000); //Waiting here is necessary. Don't remember why.
//Get the file and remove the .crdownload from the path
var fileUrl = Directory.GetFiles(filePath, "*", SearchOption.TopDirectoryOnly).First();
if (fileUrl != null)
{
if (fileUrl.EndsWith(".crdownload")) fileUrl = fileUrl.Replace(".crdownload", "");
using (var stream = File.OpenRead(fileUrl))
{
var file = new FormFile(stream, 0, stream.Length, null, Path.GetFileName(stream.Name))
{
Headers = new HeaderDictionary(),
ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
};
//Post the file to ImportExportService
await PostAttachment(file);
}
//Delete the file from the folder
File.Delete(fileUrl);
}
break;
}
Thread.Sleep(1000);
}
}
}
private async Task PostAttachment(FormFile uploadFile)
{
string fileName = Path.GetFileName(uploadFile?.FileName?.Trim());
FileStreamModel inputFileStreamModel = new()
{
DataStream = uploadFile?.OpenReadStream(),
Length = uploadFile?.OpenReadStream()?.Length,
ContentType = uploadFile?.ContentType,
LastModified = DateTime.Now
};
inputFileStreamModel.SetFileNameAndType(fileName);
var _importExportService = _server.Services.GetService<IImportExportService>();
await _importExportService.ImportPSASpreadsheet(inputFileStreamModel, 9, null, null, true);
}
}
}
Startup Code:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using ***.Application.Services;
using ***.Dal;
using ***.Dal.Repos;
using ***.Api.Result;
namespace ***.AutoImport_Runner
{
public class Startup
{
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
_env = env;
}
public IConfiguration Configuration { get; }
private readonly IWebHostEnvironment _env;
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IResultDto, ResultDto>();
services.AddDbContext<***Context>((serviceProvider, options) =>
{
options.UseSqlServer("************", sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.EnableRetryOnFailure(
maxRetryCount: 2,
maxRetryDelay: TimeSpan.FromSeconds(10),
errorNumbersToAdd: null);
});
});
services.AddTransient<IResultDto, ResultDto>();
services.AddTransient<IImportExportService, ImportExportService>();
services.AddTransient<IImportExportRepo, ImportExportRepo>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment _)
{
}
}
}
ANSWER:
So, I ended up uninstalling the NUnit Console app that was installed by the .msi. I downloaded the NUnit.Console-3.15.0.zip and everything worked as it should.
