Skip to content

Commit

Permalink
Merge pull request #31 from grokys/fixes/dont-close-attached-apps
Browse files Browse the repository at this point in the history
On session close, don't close apps that weren't started by the WebDriver
  • Loading branch information
aristotelos authored May 2, 2024
2 parents 88b51ae + 18193c2 commit dac4fab
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
37 changes: 37 additions & 0 deletions src/FlaUI.WebDriver.UITests/SessionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,10 @@ public void NewSession_AppTopLevelWindow_IsSupported()
var title = driver.Title;

Assert.That(title, Is.EqualTo("FlaUI WPF Test App"));

driver.Quit();

Assert.That(testAppProcess.Process.HasExited, Is.False);
}

[Test]
Expand Down Expand Up @@ -166,6 +170,10 @@ public void NewSession_AppTopLevelWindowTitleMatch_IsSupported(string match)
var title = driver.Title;

Assert.That(title, Is.EqualTo("FlaUI WPF Test App"));

driver.Quit();

Assert.That(testAppProcess.Process.HasExited, Is.False);
}

[Test, Ignore("Sometimes multiple processes are left open")]
Expand Down Expand Up @@ -315,6 +323,35 @@ public void NewCommandTimeout_NotExpired_DoesNotEndSession()
Assert.That(() => driver.Title, Throws.Nothing);
}

[Test, Explicit(("Sometimes multiple processes are left open"))]
public void NewCommandTimeout_SessionWithAppTopLevelWindowTitleMatch_ClosesSessionButDoesNotCloseApp()
{
using var testAppProcess = new TestAppProcess();
var driverOptions = FlaUIDriverOptions.AppTopLevelWindowTitleMatch("FlaUI WPF Test App");
driverOptions.AddAdditionalOption("appium:newCommandTimeout", 1);
using var driver = new RemoteWebDriver(WebDriverFixture.WebDriverUrl, driverOptions);

System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1) + WebDriverFixture.SessionCleanupInterval * 2);

Assert.That(testAppProcess.Process.HasExited, Is.False);
Assert.That(() => driver.Title, Throws.TypeOf<WebDriverException>().With.Message.Matches("No active session with ID '.*'"));
}

[Test]
public void NewCommandTimeout_SessionWithAppTopLevelWindow_ClosesSessionButDoesNotCloseApp()
{
using var testAppProcess = new TestAppProcess();
var windowHandle = string.Format("0x{0:x}", testAppProcess.Process.MainWindowHandle);
var driverOptions = FlaUIDriverOptions.AppTopLevelWindow(windowHandle);
driverOptions.AddAdditionalOption("appium:newCommandTimeout", 1);
using var driver = new RemoteWebDriver(WebDriverFixture.WebDriverUrl, driverOptions);

System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1) + WebDriverFixture.SessionCleanupInterval * 2);

Assert.That(testAppProcess.Process.HasExited, Is.False);
Assert.That(() => driver.Title, Throws.TypeOf<WebDriverException>().With.Message.Matches("No active session with ID '.*'"));
}

[TestCase("123")]
[TestCase(false)]
[TestCase("not a number")]
Expand Down
5 changes: 4 additions & 1 deletion src/FlaUI.WebDriver/Controllers/SessionController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public async Task<ActionResult> CreateNewSession([FromBody] CreateSessionRequest
.Select(capabillities => matchedCapabilities!);

Core.Application? app;
var isAppOwnedBySession = false;
var capabilities = matchingCapabilities.FirstOrDefault();
if (capabilities == null)
{
Expand Down Expand Up @@ -69,6 +70,8 @@ public async Task<ActionResult> CreateNewSession([FromBody] CreateSessionRequest
throw WebDriverResponseException.InvalidArgument($"Starting app '{appPath}' with arguments '{appArguments}' threw an exception: {e.Message}");
}
}

isAppOwnedBySession = true;
}
else if (TryGetStringCapability(capabilities, "appium:appTopLevelWindow", out var appTopLevelWindowString))
{
Expand All @@ -84,7 +87,7 @@ public async Task<ActionResult> CreateNewSession([FromBody] CreateSessionRequest
{
throw WebDriverResponseException.InvalidArgument("One of appium:app, appium:appTopLevelWindow or appium:appTopLevelWindowTitleMatch must be passed as a capability");
}
var session = new Session(app);
var session = new Session(app, isAppOwnedBySession);
if(TryGetNumberCapability(capabilities, "appium:newCommandTimeout", out var newCommandTimeout))
{
session.NewCommandTimeout = TimeSpan.FromSeconds(newCommandTimeout);
Expand Down
6 changes: 4 additions & 2 deletions src/FlaUI.WebDriver/Session.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ namespace FlaUI.WebDriver
{
public class Session : IDisposable
{
public Session(Application? app)
public Session(Application? app, bool isAppOwnedBySession)
{
App = app;
SessionId = Guid.NewGuid().ToString();
Automation = new UIA3Automation();
InputState = new InputState();
TimeoutsConfiguration = new TimeoutsConfiguration();
IsAppOwnedBySession = isAppOwnedBySession;

if (app != null)
{
Expand All @@ -30,6 +31,7 @@ public Session(Application? app)
public TimeSpan ImplicitWaitTimeout => TimeSpan.FromMilliseconds(TimeoutsConfiguration.ImplicitWaitTimeoutMs);
public TimeSpan PageLoadTimeout => TimeSpan.FromMilliseconds(TimeoutsConfiguration.PageLoadTimeoutMs);
public TimeSpan? ScriptTimeout => TimeoutsConfiguration.ScriptTimeoutMs.HasValue ? TimeSpan.FromMilliseconds(TimeoutsConfiguration.ScriptTimeoutMs.Value) : null;
public bool IsAppOwnedBySession { get; }

public TimeoutsConfiguration TimeoutsConfiguration { get; set; }

Expand Down Expand Up @@ -124,7 +126,7 @@ public void RemoveKnownWindow(Window window)

public void Dispose()
{
if (App != null && !App.HasExited)
if (IsAppOwnedBySession && App != null && !App.HasExited)
{
App.Close();
}
Expand Down

0 comments on commit dac4fab

Please sign in to comment.