Skip to content

Commit a8a800e

Browse files
committed
Add IntegrationTests project
1 parent c1e7b84 commit a8a800e

25 files changed

Lines changed: 1331 additions & 1 deletion
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
namespace ElectronNET.IntegrationTests
2+
{
3+
using System.Reflection;
4+
using ElectronNET.API;
5+
using ElectronNET.API.Entities;
6+
7+
// Shared fixture that starts Electron runtime once
8+
public class ElectronFixture : IAsyncLifetime
9+
{
10+
public BrowserWindow MainWindow { get; private set; } = null!;
11+
12+
public async Task InitializeAsync()
13+
{
14+
AppDomain.CurrentDomain.SetData("ElectronTestAssembly", Assembly.GetExecutingAssembly());
15+
var runtimeController = ElectronNetRuntime.RuntimeController;
16+
await runtimeController.Start();
17+
await runtimeController.WaitReadyTask;
18+
19+
// create hidden window for tests (avoid showing UI)
20+
this.MainWindow = await Electron.WindowManager.CreateWindowAsync(new BrowserWindowOptions
21+
{
22+
Show = false,
23+
Width = 800,
24+
Height = 600,
25+
});
26+
27+
// Clear potential cache side-effects
28+
await this.MainWindow.WebContents.Session.ClearCacheAsync();
29+
}
30+
31+
public async Task DisposeAsync()
32+
{
33+
var runtimeController = ElectronNetRuntime.RuntimeController;
34+
await runtimeController.Stop();
35+
await runtimeController.WaitStoppedTask;
36+
}
37+
}
38+
39+
[CollectionDefinition("ElectronCollection")]
40+
public class ElectronCollection : ICollectionFixture<ElectronFixture>
41+
{
42+
}
43+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<!-- When this is enabled, the project will be switched from nuget packages to consuming the ElectronNet orchestration directly -->
5+
<ElectronNetDevMode>true</ElectronNetDevMode>
6+
</PropertyGroup>
7+
8+
<Import Project="..\ElectronNET\build\ElectronNET.props" Condition="$(ElectronNetDevMode)" />
9+
10+
<PropertyGroup>
11+
<TargetFramework>net8.0</TargetFramework>
12+
<ImplicitUsings>enable</ImplicitUsings>
13+
<Nullable>enable</Nullable>
14+
<IsPackable>false</IsPackable>
15+
</PropertyGroup>
16+
17+
<ItemGroup>
18+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
19+
<PackageReference Include="xunit" Version="2.9.2" />
20+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
21+
<PrivateAssets>all</PrivateAssets>
22+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
23+
</PackageReference>
24+
<PackageReference Include="FluentAssertions" Version="6.12.0" />
25+
</ItemGroup>
26+
27+
<ItemGroup>
28+
<ProjectReference Include="..\ElectronNET.API\ElectronNET.API.csproj" />
29+
<ProjectReference Include="..\ElectronNET\ElectronNET.csproj" />
30+
</ItemGroup>
31+
32+
<ItemGroup>
33+
<Folder Include="NewFolder\" />
34+
</ItemGroup>
35+
36+
<PropertyGroup>
37+
<!-- Disable test parallelization at runner level to avoid multiple Electron instances -->
38+
<ParallelizeTestCollections>false</ParallelizeTestCollections>
39+
</PropertyGroup>
40+
41+
<Import Project="..\ElectronNET\build\ElectronNET.targets" Condition="$(ElectronNetDevMode)" />
42+
43+
</Project>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
global using Xunit;
2+
global using FluentAssertions;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"$schema": "https://raw.githubusercontent.com/electron-userland/electron-builder/refs/heads/master/packages/app-builder-lib/scheme.json",
3+
"compression": "maximum",
4+
"linux": {
5+
"target": [
6+
"tar.xz"
7+
],
8+
"executableArgs": [ "--no-sandbox" ],
9+
"artifactName": "${name}-${arch}-${version}.${ext}"
10+
},
11+
"win": {
12+
"target": [
13+
{
14+
"target": "portable",
15+
"arch": "x64"
16+
}
17+
]
18+
}
19+
}
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
namespace ElectronNET.IntegrationTests.Tests
2+
{
3+
using System.Runtime.InteropServices;
4+
using ElectronNET.API;
5+
using ElectronNET.API.Entities;
6+
using System;
7+
using System.IO;
8+
using System.Threading.Tasks;
9+
10+
[Collection("ElectronCollection")]
11+
public class AppTests
12+
{
13+
// ReSharper disable once NotAccessedField.Local
14+
private readonly ElectronFixture fx;
15+
public AppTests(ElectronFixture fx)
16+
{
17+
this.fx = fx;
18+
}
19+
20+
[Fact]
21+
public async Task Can_get_app_path()
22+
{
23+
var path = await Electron.App.GetAppPathAsync();
24+
path.Should().NotBeNullOrWhiteSpace();
25+
Directory.Exists(path).Should().BeTrue();
26+
}
27+
28+
[Fact]
29+
public async Task Can_get_version_and_locale()
30+
{
31+
var version = await Electron.App.GetVersionAsync();
32+
version.Should().NotBeNullOrWhiteSpace();
33+
var locale = await Electron.App.GetLocaleAsync();
34+
locale.Should().NotBeNullOrWhiteSpace();
35+
}
36+
37+
[Fact]
38+
public async Task Can_get_special_paths()
39+
{
40+
var userData = await Electron.App.GetPathAsync(PathName.UserData);
41+
userData.Should().NotBeNullOrWhiteSpace();
42+
Directory.Exists(Path.GetDirectoryName(userData) ?? userData).Should().BeTrue();
43+
44+
var temp = await Electron.App.GetPathAsync(PathName.Temp);
45+
temp.Should().NotBeNullOrWhiteSpace();
46+
Directory.Exists(temp).Should().BeTrue();
47+
}
48+
49+
50+
[Fact]
51+
public async Task Badge_count_roundtrip_where_supported()
52+
{
53+
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
54+
{
55+
var ok = await Electron.App.SetBadgeCountAsync(3);
56+
ok.Should().BeTrue();
57+
var count = await Electron.App.GetBadgeCountAsync();
58+
count.Should().Be(3);
59+
// reset
60+
await Electron.App.SetBadgeCountAsync(0);
61+
}
62+
else
63+
{
64+
// On Windows it's usually unsupported; ensure badge query works and returns a non-negative value
65+
await Electron.App.SetBadgeCountAsync(0); // ignore return value
66+
var count = await Electron.App.GetBadgeCountAsync();
67+
count.Should().BeGreaterOrEqualTo(0);
68+
}
69+
}
70+
71+
[Fact]
72+
public async Task Can_get_app_metrics()
73+
{
74+
var metrics = await Electron.App.GetAppMetricsAsync();
75+
metrics.Should().NotBeNull();
76+
metrics.Length.Should().BeGreaterThan(0);
77+
}
78+
79+
[Fact]
80+
public async Task Can_get_gpu_feature_status()
81+
{
82+
var status = await Electron.App.GetGpuFeatureStatusAsync();
83+
status.Should().NotBeNull();
84+
}
85+
86+
[Fact]
87+
public async Task Can_get_login_item_settings()
88+
{
89+
var settings = await Electron.App.GetLoginItemSettingsAsync();
90+
settings.Should().NotBeNull();
91+
}
92+
93+
[Fact]
94+
public void Can_set_app_logs_path()
95+
{
96+
var tempDir = Path.Combine(Path.GetTempPath(), "ElectronLogsTest" + Guid.NewGuid().ToString("N"));
97+
Directory.CreateDirectory(tempDir);
98+
Electron.App.SetAppLogsPath(tempDir);
99+
}
100+
101+
[Fact]
102+
public async Task CommandLine_append_and_query_switch()
103+
{
104+
var switchName = "integration-switch";
105+
Electron.App.CommandLine.AppendSwitch(switchName, "value123");
106+
(await Electron.App.CommandLine.HasSwitchAsync(switchName)).Should().BeTrue();
107+
(await Electron.App.CommandLine.GetSwitchValueAsync(switchName)).Should().Be("value123");
108+
}
109+
110+
[Fact]
111+
public async Task Accessibility_support_toggle()
112+
{
113+
Electron.App.SetAccessibilitySupportEnabled(true);
114+
var enabled = await Electron.App.IsAccessibilitySupportEnabledAsync();
115+
enabled.Should().BeTrue(); // API responded
116+
Electron.App.SetAccessibilitySupportEnabled(false);
117+
}
118+
119+
[Fact]
120+
public async Task UserAgentFallback_roundtrip()
121+
{
122+
var original = await Electron.App.UserAgentFallbackAsync;
123+
Electron.App.UserAgentFallback = "ElectronIntegrationTest/1.0";
124+
var updated = await Electron.App.UserAgentFallbackAsync;
125+
updated.Should().Be("ElectronIntegrationTest/1.0");
126+
Electron.App.UserAgentFallback = original; // restore
127+
}
128+
129+
[Fact]
130+
public async Task BadgeCount_set_and_reset_where_supported()
131+
{
132+
await Electron.App.SetBadgeCountAsync(2);
133+
var count = await Electron.App.GetBadgeCountAsync();
134+
// Some platforms may always return0; just ensure call didn't throw and is non-negative
135+
count.Should().BeGreaterOrEqualTo(0);
136+
await Electron.App.SetBadgeCountAsync(0);
137+
}
138+
139+
[Fact]
140+
public async Task App_metrics_have_cpu_info()
141+
{
142+
var metrics = await Electron.App.GetAppMetricsAsync();
143+
metrics[0].Cpu.Should().NotBeNull();
144+
}
145+
146+
[Fact]
147+
public async Task App_badge_count_roundtrip()
148+
{
149+
// Set then get (non-mac platforms treat as no-op but should return0 or set value)
150+
var success = await Electron.App.SetBadgeCountAsync(3);
151+
success.Should().BeTrue();
152+
var count = await Electron.App.GetBadgeCountAsync();
153+
// Allow fallback to0 on platforms without badge support
154+
(count ==3 || count ==0).Should().BeTrue();
155+
}
156+
157+
[Fact]
158+
public async Task App_gpu_feature_status_has_some_fields()
159+
{
160+
var status = await Electron.App.GetGpuFeatureStatusAsync();
161+
status.Should().NotBeNull();
162+
status.Webgl.Should().NotBeNull();
163+
status.VideoDecode.Should().NotBeNull();
164+
}
165+
}
166+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
namespace ElectronNET.IntegrationTests.Tests
2+
{
3+
using ElectronNET.API;
4+
using ElectronNET.API.Entities;
5+
6+
[Collection("ElectronCollection")]
7+
public class BrowserViewTests
8+
{
9+
private readonly ElectronFixture fx;
10+
public BrowserViewTests(ElectronFixture fx)
11+
{
12+
this.fx = fx;
13+
}
14+
15+
[Fact]
16+
public async Task Create_browser_view_and_adjust_bounds()
17+
{
18+
var view = await Electron.WindowManager.CreateBrowserViewAsync(new BrowserViewConstructorOptions());
19+
this.fx.MainWindow.SetBrowserView(view);
20+
view.Bounds = new Rectangle { X = 0, Y = 0, Width = 300, Height = 200 };
21+
// Access bounds again (synchronous property fetch)
22+
var current = view.Bounds;
23+
current.Width.Should().Be(300);
24+
current.Height.Should().Be(200);
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)