Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Assets/LogoWithClosedPackage.ico
Binary file not shown.
300 changes: 300 additions & 0 deletions Assets/LogoWithClosedPackage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 27 additions & 1 deletion PackageInstaller.Core/ModelViews/GettingStartedModelView.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Reactive;
using System.Reactive.Linq;
using System.Reactive.Threading.Tasks;
using ReactiveUI;
using Sextant;
using Shared.Misc;
Expand Down Expand Up @@ -32,6 +33,11 @@ IApplicationLifeCycle lifeCycle
LaunchExplorerCommand = ReactiveCommand.CreateFromTask(LaunchExplorerAsync);
LaunchWithFileCommand = ReactiveCommand.CreateFromTask<string?>(LaunchWithFileAsync);
ExitCommand = ReactiveCommand.Create(() => _lifeCycle.Exit(0));
OpenDefaultAppsSettingsPageCommand = ReactiveCommand.CreateFromTask(
_launcher.LaunchDefaultAppsSettingsPageAsync
);

_userShouldCheckFileHandlerRegistrations = false;
}

private async Task LaunchWithFileAsync(string? filePath)
Expand Down Expand Up @@ -75,6 +81,17 @@ private async Task PickFilesAsync()
public ReactiveCommand<Unit, Unit> LaunchExplorerCommand { get; }
public ReactiveCommand<string?, Unit> LaunchWithFileCommand { get; }
public ReactiveCommand<Unit, Unit> ExitCommand { get; }
public ReactiveCommand<Unit, Unit> OpenDefaultAppsSettingsPageCommand { get; }

bool _userShouldCheckFileHandlerRegistrations;
public bool UserShouldCheckFileHandlerRegistrations
{
get { return _userShouldCheckFileHandlerRegistrations; }
private set
{
this.RaiseAndSetIfChanged(ref _userShouldCheckFileHandlerRegistrations, value);
}
}

public string Id { get; } = nameof(GettingStartedModelView);

Expand All @@ -92,6 +109,15 @@ public IObservable<Unit> WhenNavigatedFrom(INavigationParameter parameter)

public IObservable<Unit> WhenNavigatingTo(INavigationParameter parameter)
{
return Observable.Return(Unit.Default);
return ProcessAsync().ToObservable(RxApp.MainThreadScheduler);
}

public async Task ProcessAsync()
{
await Task.Delay(10).ConfigureAwait(true);

UserShouldCheckFileHandlerRegistrations = !await _launcher
.VerifyThatAllFileTypeAssociationsAreRegisteredAsync()
.ConfigureAwait(true);
}
}
4 changes: 3 additions & 1 deletion PackageInstaller.Core/ModelViews/PreparationViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ public async Task ProcessAsync(string[] arguments)

private void NavigateToGettingStarted()
{
_viewStackService.PushPage<GettingStartedModelView>().Subscribe();
_viewStackService
.PushPage<GettingStartedModelView>(new Sextant.NavigationParameter())
.Subscribe();
}

private FileSystemPath ParseArguments(string[] arguments)
Expand Down
14 changes: 13 additions & 1 deletion PackageInstaller/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
using Microsoft.UI.Xaml;
using System;
using System.IO;
using System.Linq;
using System.Reactive;
using System.Threading;
using Windows.ApplicationModel;
using Windows.Storage;
using Community.Sextant.WinUI;
using Community.Sextant.WinUI.Adapters;
using NativeInterop.Win32.Xaml;
Expand All @@ -23,24 +26,33 @@ public sealed partial class MainWindow : DesktopWindow
private readonly ThemeManager _themeManager;
private string args = string.Empty;
private readonly IApplicationLifeCycle _lifeCycle;
private IPath _path;

public MainWindow(
IParameterViewStackService viewStackService,
INavigationService navigationService,
ThemeManager themeManager,
IApplicationLifeCycle lifeCycle
IApplicationLifeCycle lifeCycle,
IPath path
)
{
_viewStackService = viewStackService;
_navigationService = navigationService;
_themeManager = themeManager;
_lifeCycle = lifeCycle;
_path = path;

this.InitializeComponent();

Title = "Winstrumenta PackageManager";
ExtendsContentIntoTitleBar = true;
SetTitleBar(DummyTitleBar); // do not set the title bar to use a 100% custom one.

var iconPath = Path.Combine(Package.Current.InstalledPath, "PackageInstaller.ico");
if (File.Exists(iconPath))
{
_nativeWindow.LoadIcon(iconPath);
}
}

public void SetLaunchArgs(string arguments)
Expand Down
2 changes: 2 additions & 0 deletions PackageInstaller/PackageInstaller.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
<None Remove="Images\Wide310x150Logo.scale-200.png" />
<None Remove="Images\Wide310x150Logo.scale-400.png" />
<None Remove="Package.appxmanifest" />
<None Remove="PackageInstaller.ico" />
<None Remove="Pages\GettingStarted.xaml" />
<None Remove="Pages\NotificationHub.xaml" />
</ItemGroup>
Expand Down Expand Up @@ -145,6 +146,7 @@
<Content Include="Images\Wide310x150Logo.scale-150.png" />
<Content Include="Images\Wide310x150Logo.scale-200.png" />
<Content Include="Images\Wide310x150Logo.scale-400.png" />
<Content Include="PackageInstaller.ico" />
</ItemGroup>

<ItemGroup>
Expand Down
Binary file added PackageInstaller/PackageInstaller.ico
Binary file not shown.
28 changes: 23 additions & 5 deletions PackageInstaller/Pages/GettingStarted.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<controls:RowDefinition Height="Auto" />
<controls:RowDefinition Height="*" />
<controls:RowDefinition Height="Auto" />
<controls:RowDefinition Height="Auto" />
</controls:Grid.RowDefinitions>
<controls:TextBlock
controls:Grid.Row="0"
Expand Down Expand Up @@ -57,7 +58,7 @@
<controls:TextBlock
FontSize="20"
TextWrapping="WrapWholeWords"
Padding="25"
Padding="20"
TextAlignment="Center"
AllowDrop="True"
AutomationProperties.AutomationId="PickSection"
Expand Down Expand Up @@ -89,20 +90,37 @@
<controls:TextBlock
FontSize="20"
TextWrapping="WrapWholeWords"
Padding="25"
Padding="20"
TextAlignment="Center"
AutomationProperties.AutomationId="ExplorerSection"
>
Double click in Windows Explorer to install
Double click package files in Windows Explorer to install
</controls:TextBlock>
</controls:StackPanel>
</controls:Border>
<RelativePanel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Padding="10,0,10,10">
<InfoBar
x:Name="DefaultAppsSettingsPageInfo"
Severity="Informational"
IsClosable="False"
IsOpen="True"
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="10"
Height="60"
>
<InfoBar.Message>Remember to change the default file type associations.</InfoBar.Message>
<InfoBar.ActionButton>
<Button x:Name="OpenDefaultAppsSettingsPage" Content="Open Settings" />
</InfoBar.ActionButton>
</InfoBar>
<RelativePanel Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Padding="10,0,10,10">
<Button
x:Name="ExitButton"
RelativePanel.AlignVerticalCenterWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
Content="Exit"
Content="Close"
AutomationProperties.AutomationId="Close"
/>
</RelativePanel>
</controls:Grid>
Expand Down
15 changes: 15 additions & 0 deletions PackageInstaller/Pages/GettingStarted.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,21 @@ public GettingStarted()

this.BindCommand(ViewModel, (vm) => vm.ExitCommand, (v) => v.ExitButton)
.DisposeWith(disposable);

this.BindCommand(
ViewModel,
(vm) => vm.OpenDefaultAppsSettingsPageCommand,
(v) => v.OpenDefaultAppsSettingsPage
)
.DisposeWith(disposable);

this.OneWayBind(
ViewModel,
(vm) => vm.UserShouldCheckFileHandlerRegistrations,
(v) => v.DefaultAppsSettingsPageInfo.Visibility,
(visible) => visible ? Visibility.Visible : Visibility.Collapsed
)
.DisposeWith(disposable);
}
);
}
Expand Down
10 changes: 10 additions & 0 deletions Shared.Services.Implementations.Winui/Launcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,14 @@ public Task LaunchFolderAsync(string folderPath)
{
return Windows.System.Launcher.LaunchFolderPathAsync(folderPath).AsTask();
}

public Task LaunchDefaultAppsSettingsPageAsync()
{
return Windows.System.Launcher.LaunchUriAsync(new Uri("ms-settings:defaultapps")).AsTask();
}

public async Task<bool> VerifyThatAllFileTypeAssociationsAreRegisteredAsync()
{
return false; // not possible to actually check
}
}
2 changes: 2 additions & 0 deletions Shared.Services/ILauncher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ public interface ILauncher
public Task LaunchAsync(Uri uri);

public Task LaunchFolderAsync(string folderPath);
Task LaunchDefaultAppsSettingsPageAsync();
Task<bool> VerifyThatAllFileTypeAssociationsAreRegisteredAsync();
}
16 changes: 6 additions & 10 deletions Winstrumenta.Package.Tests/GettingStartedPageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ public class GettingStartedPageTests : TestSuiteBase
[Test]
public void ShouldShowGettingStartedPageWhenNoArgumentsProvided()
{
GetSession().FindElementByAccessibilityId("Title").Text.Should().Be("Getting started!");
var session = GetSession();
session.FindElementByAccessibilityId("Title").Text.Should().Be("Getting started!");
session.FindElementByAccessibilityId("Close").Click();

WaitFor(() => IsAppRunning().Should().BeFalse("App should have been closed by clicking the close button"));
}

[Test]
Expand All @@ -33,7 +37,7 @@ public void ShouldOpenExplorerWhenClickedOnLink()

private bool HasExplorerAsChildProcess()
{
var process = GetProcess();
var process = GetAppProcess();

if (process == null)
{
Expand All @@ -45,12 +49,4 @@ private bool HasExplorerAsChildProcess()
.Any(childProcess => childProcess.ProcessName == "explorer.exe");
}

private Process? GetProcess()
{
return Process
.GetProcesses()
.FirstOrDefault(
(p) => p.MainWindowHandle.ToString() == GetSession().CurrentWindowHandle
);
}
}
2 changes: 1 addition & 1 deletion Winstrumenta.Package.Tests/TestEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class TestEnvironment
private TestEnvironmentDetails? _environment;
private string _testBaseDirectory;

public const string WAD_URL = "127.0.0.1:4723";
public const string WAD_URL = "http://127.0.0.1:4723";
private const string WAD_FOLDER_NAME = "wad";

public TestEnvironmentDetails? PreparedEnvDetails => _environment;
Expand Down
51 changes: 49 additions & 2 deletions Winstrumenta.Package.Tests/TestSuiteBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using OpenQA.Selenium.Appium;
using System.Diagnostics;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium.Appium.Windows;

namespace Winstrumenta.Package.Tests;
Expand Down Expand Up @@ -41,7 +42,7 @@ private void CreateSession(string[] arguments)
opts.AddAdditionalCapability("deviceName", "WindowsPC");

_session = new WindowsDriver<WindowsElement>(
new Uri($"http://{TestEnvironment.WAD_URL}/wd/hub"),
new Uri($"{TestEnvironment.WAD_URL}/wd/hub"),
opts
);
}
Expand Down Expand Up @@ -101,4 +102,50 @@ public void Sleep(int milliseconds)
{
Thread.Sleep(milliseconds);
}

public void WaitFor(Action check, int timeout = 2_000, int numberOfChecks = 5)
{
int sleepDuration = timeout / numberOfChecks;
Exception? previousException = null;

while (numberOfChecks > 0)
{
numberOfChecks--;

try
{
check();
return;
}
catch (Exception e)
{
previousException = e;

Thread.Sleep(sleepDuration);
}
}

throw new Exception("WaitFor: check failed!", previousException);
}

public bool IsAppRunning()
{
using var proc = GetAppProcess();

return proc is { HasExited: false };
}

public Process? GetAppProcess()
{
return Process
.GetProcesses()
.FirstOrDefault(
(p) => p.MainWindowHandle.ToString() == GetSession().CurrentWindowHandle
);
}

public byte[] GetFixtureFromFile(string filename)
{
return File.ReadAllBytes(Path.Combine(TestContext.CurrentContext.TestDirectory, filename));
}
}
4 changes: 2 additions & 2 deletions Winstrumenta.Package.Tests/Winstrumenta.Package.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
Expand All @@ -10,7 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Appium.WebDriver" Version="4.3.1" />
<PackageReference Include="Appium.WebDriver" Version="4.4.0" />
<PackageReference Include="FluentAssertions" Version="6.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
Expand Down
2 changes: 1 addition & 1 deletion Winstrumenta.msbuildproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Build.NoTargets/3.5.6">
<Project Sdk="Microsoft.Build.NoTargets/3.5.6">
<PropertyGroup>
<TargetFramework>net46</TargetFramework>
</PropertyGroup>
Expand Down