Skip to content

Commit 8e8d88c

Browse files
authored
Merge pull request #931 from softworkz/submit_update_tests
Integration Tests Everywhere!
2 parents 90c3eb2 + 61476e3 commit 8e8d88c

21 files changed

+470
-133
lines changed
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [ develop, main ]
6+
pull_request:
7+
branches: [ develop, main ]
8+
9+
concurrency:
10+
group: integration-tests-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
tests:
15+
name: Integration Tests (${{ matrix.os }})
16+
runs-on: ${{ matrix.os }}
17+
strategy:
18+
fail-fast: false
19+
matrix:
20+
include:
21+
- os: ubuntu-24.04
22+
rid: linux-x64
23+
- os: windows-2022
24+
rid: win-x64
25+
- os: macos-14
26+
rid: osx-arm64
27+
28+
env:
29+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
30+
DOTNET_NOLOGO: 1
31+
CI: true
32+
ELECTRON_ENABLE_LOGGING: 1
33+
34+
steps:
35+
- name: Checkout
36+
uses: actions/checkout@v4
37+
38+
- name: Setup .NET
39+
uses: actions/setup-dotnet@v4
40+
with:
41+
dotnet-version: '10.0.x'
42+
43+
- name: Setup Node.js
44+
uses: actions/setup-node@v4
45+
with:
46+
node-version: '22'
47+
48+
- name: Restore
49+
run: dotnet restore -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj
50+
51+
- name: Build
52+
run: dotnet build --no-restore -c Release -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj
53+
54+
- name: Install Linux GUI dependencies
55+
if: runner.os == 'Linux'
56+
run: |
57+
set -e
58+
sudo apt-get update
59+
# Core Electron dependencies
60+
sudo apt-get install -y xvfb \
61+
libgtk-3-0 libnss3 libgdk-pixbuf-2.0-0 libdrm2 libgbm1 libxss1 libxtst6 libatk-bridge2.0-0 libatk1.0-0 libatspi2.0-0 libx11-xcb1 libasound2t64
62+
63+
- name: Run tests (Linux)
64+
if: runner.os == 'Linux'
65+
continue-on-error: true
66+
run: |
67+
mkdir -p test-results/Ubuntu
68+
xvfb-run -a dotnet test src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj \
69+
-c Release --no-build -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} \
70+
--logger "trx;LogFileName=Ubuntu.trx" \
71+
--logger "console;verbosity=detailed" \
72+
--results-directory test-results
73+
74+
- name: Run tests (Windows)
75+
if: runner.os == 'Windows'
76+
continue-on-error: true
77+
run: |
78+
New-Item -ItemType Directory -Force -Path test-results/Windows | Out-Null
79+
dotnet test src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj -c Release --no-build -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} --logger "trx;LogFileName=Windows.trx" --logger "console;verbosity=detailed" --results-directory test-results
80+
81+
- name: Run tests (macOS)
82+
if: runner.os == 'macOS'
83+
continue-on-error: true
84+
run: |
85+
mkdir -p test-results/macOS
86+
dotnet test src/ElectronNET.IntegrationTests/ElectronNET.IntegrationTests.csproj -c Release --no-build -r ${{ matrix.rid }} -p:RuntimeIdentifier=${{ matrix.rid }} --logger "trx;LogFileName=macOS.trx" --logger "console;verbosity=detailed" --results-directory test-results
87+
88+
- name: Upload raw test results
89+
if: always()
90+
uses: actions/upload-artifact@v4
91+
with:
92+
name: test-results-${{ matrix.os }}
93+
path: test-results/*.trx
94+
retention-days: 7
95+
96+
summary:
97+
name: Test Results
98+
runs-on: ubuntu-24.04
99+
if: always()
100+
needs: [tests]
101+
102+
permissions:
103+
actions: read
104+
contents: read
105+
checks: write
106+
pull-requests: write
107+
108+
steps:
109+
- name: Download all test results
110+
uses: actions/download-artifact@v4
111+
with:
112+
path: test-results
113+
114+
- name: Setup .NET (for CTRF conversion)
115+
uses: actions/setup-dotnet@v4
116+
with:
117+
dotnet-version: '10.0.x'
118+
119+
- name: Install CTRF TRX→CTRF converter (dotnet tool)
120+
run: |
121+
dotnet new tool-manifest
122+
dotnet tool install DotnetCtrfJsonReporter --local
123+
124+
- name: Convert TRX → CTRF and clean names (keep suites; set filePath=OS)
125+
shell: bash
126+
run: |
127+
set -euo pipefail
128+
mkdir -p ctrf
129+
shopt -s globstar nullglob
130+
conv=0
131+
for trx in test-results/**/*.trx; do
132+
fname="$(basename "$trx")"
133+
os="${fname%.trx}"
134+
outdir="ctrf/${os}"
135+
mkdir -p "$outdir"
136+
out="${outdir}/ctrf-report.json"
137+
138+
dotnet tool run DotnetCtrfJsonReporter -p "$trx" -d "$outdir" -f "ctrf-report.json"
139+
140+
jq --arg os "$os" '.results.tests |= map(.filePath = $os)' "$out" > "${out}.tmp" && mv "${out}.tmp" "$out"
141+
142+
echo "Converted & normalized $trx -> $out"
143+
conv=$((conv+1))
144+
done
145+
echo "Processed $conv TRX file(s)"
146+
147+
148+
- name: Publish Test Report
149+
if: always()
150+
uses: ctrf-io/github-test-reporter@v1
151+
with:
152+
report-path: 'ctrf/**/*.json'
153+
154+
summary: true
155+
pull-request: false
156+
status-check: false
157+
status-check-name: 'Integration Tests'
158+
use-suite-name: true
159+
update-comment: true
160+
always-group-by: true
161+
overwrite-comment: true
162+
exit-on-fail: true
163+
group-by: 'suite'
164+
upload-artifact: true
165+
fetch-previous-results: true
166+
167+
summary-report: false
168+
summary-delta-report: true
169+
github-report: true
170+
test-report: false
171+
test-list-report: false
172+
failed-report: true
173+
failed-folded-report: false
174+
skipped-report: true
175+
suite-folded-report: true
176+
suite-list-report: false
177+
file-report: true
178+
previous-results-report: true
179+
insights-report: true
180+
flaky-report: true
181+
flaky-rate-report: true
182+
fail-rate-report: false
183+
slowest-report: false
184+
185+
report-order: 'summary-delta-report,failed-report,skipped-report,suite-folded-report,file-report,previous-results-report,github-report'
186+
env:
187+
GITHUB_TOKEN: ${{ github.token }}
188+
189+
190+
- name: Create PR Comment
191+
if: always()
192+
uses: ctrf-io/github-test-reporter@v1
193+
with:
194+
report-path: 'ctrf/**/*.json'
195+
196+
summary: true
197+
pull-request: true
198+
use-suite-name: true
199+
update-comment: true
200+
always-group-by: true
201+
overwrite-comment: true
202+
upload-artifact: false
203+
204+
pull-request-report: true
205+
env:
206+
GITHUB_TOKEN: ${{ github.token }}
207+
208+
- name: Summary
209+
run: echo "All matrix test jobs completed."

src/ElectronNET.API/ElectronNetRuntime.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ static ElectronNetRuntime()
2424
StartupManager.Initialize();
2525
}
2626

27+
public static string ElectronExtraArguments { get; set; }
28+
2729
public static int? ElectronSocketPort { get; internal set; }
2830

2931
public static int? AspNetWebPort { get; internal set; }

src/ElectronNET.API/Runtime/Controllers/RuntimeControllerDotNetFirst.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ protected override Task StartCore()
4040
{
4141
var isUnPacked = ElectronNetRuntime.StartupMethod.IsUnpackaged();
4242
var electronBinaryName = ElectronNetRuntime.ElectronExecutable;
43-
var args = Environment.CommandLine;
43+
var args = string.Format("{0} {1}", ElectronNetRuntime.ElectronExtraArguments, Environment.CommandLine).Trim();
4444
this.port = ElectronNetRuntime.ElectronSocketPort;
4545

4646
if (!this.port.HasValue)
@@ -49,10 +49,15 @@ protected override Task StartCore()
4949
ElectronNetRuntime.ElectronSocketPort = this.port;
5050
}
5151

52+
Console.Error.WriteLine("[StartCore]: isUnPacked: {0}", isUnPacked);
53+
Console.Error.WriteLine("[StartCore]: electronBinaryName: {0}", electronBinaryName);
54+
Console.Error.WriteLine("[StartCore]: args: {0}", args);
55+
5256
this.electronProcess = new ElectronProcessActive(isUnPacked, electronBinaryName, args, this.port.Value);
5357
this.electronProcess.Ready += this.ElectronProcess_Ready;
5458
this.electronProcess.Stopped += this.ElectronProcess_Stopped;
5559

60+
Console.Error.WriteLine("[StartCore]: Before Start");
5661
return this.electronProcess.Start();
5762
}
5863

@@ -82,11 +87,11 @@ private void ElectronProcess_Stopped(object sender, EventArgs e)
8287

8388
private void HandleStopped()
8489
{
85-
if (this.socketBridge.State != LifetimeState.Stopped)
90+
if (this.socketBridge != null && this.socketBridge.State != LifetimeState.Stopped)
8691
{
8792
this.socketBridge.Stop();
8893
}
89-
else if (this.electronProcess.State != LifetimeState.Stopped)
94+
else if (this.electronProcess != null && this.electronProcess.State != LifetimeState.Stopped)
9095
{
9196
this.electronProcess.Stop();
9297
}

src/ElectronNET.API/Runtime/Services/ElectronProcess/ElectronProcessActive.cs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System;
66
using System.ComponentModel;
77
using System.IO;
8+
using System.Runtime.InteropServices;
89
using System.Threading.Tasks;
910

1011
/// <summary>
@@ -42,6 +43,11 @@ protected override Task StartCore()
4243
var electrondir = Path.Combine(dir.FullName, ".electron");
4344
startCmd = Path.Combine(electrondir, "node_modules", "electron", "dist", "electron");
4445

46+
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
47+
{
48+
startCmd = Path.Combine(electrondir, "node_modules", "electron", "dist", "Electron.app", "Contents", "MacOS", "Electron");
49+
}
50+
4551
args = $"main.js -unpackeddotnet --trace-warnings -electronforcedport={this.socketPort:D} " + this.extraArguments;
4652
workingDir = electrondir;
4753
}
@@ -68,22 +74,40 @@ protected override Task StopCore()
6874

6975
private async Task StartInternal(string startCmd, string args, string directoriy)
7076
{
71-
await Task.Delay(10).ConfigureAwait(false);
77+
try
78+
{
79+
await Task.Delay(10).ConfigureAwait(false);
7280

73-
this.process = new ProcessRunner("ElectronRunner");
74-
this.process.ProcessExited += this.Process_Exited;
75-
this.process.Run(startCmd, args, directoriy);
81+
Console.Error.WriteLine("[StartInternal]: startCmd: {0}", startCmd);
82+
Console.Error.WriteLine("[StartInternal]: args: {0}", args);
7683

77-
await Task.Delay(500).ConfigureAwait(false);
84+
this.process = new ProcessRunner("ElectronRunner");
85+
this.process.ProcessExited += this.Process_Exited;
86+
this.process.Run(startCmd, args, directoriy);
7887

79-
if (!this.process.IsRunning)
80-
{
81-
Task.Run(() => this.TransitionState(LifetimeState.Stopped));
88+
await Task.Delay(500).ConfigureAwait(false);
8289

83-
throw new Exception("Failed to launch the Electron process.");
84-
}
90+
Console.Error.WriteLine("[StartInternal]: after run:");
91+
92+
if (!this.process.IsRunning)
93+
{
94+
Console.Error.WriteLine("[StartInternal]: Process is not running: " + this.process.StandardError);
95+
Console.Error.WriteLine("[StartInternal]: Process is not running: " + this.process.StandardOutput);
8596

86-
this.TransitionState(LifetimeState.Ready);
97+
Task.Run(() => this.TransitionState(LifetimeState.Stopped));
98+
99+
throw new Exception("Failed to launch the Electron process.");
100+
}
101+
102+
this.TransitionState(LifetimeState.Ready);
103+
}
104+
catch (Exception ex)
105+
{
106+
Console.Error.WriteLine("[StartInternal]: Exception: " + this.process?.StandardError);
107+
Console.Error.WriteLine("[StartInternal]: Exception: " + this.process?.StandardOutput);
108+
Console.Error.WriteLine("[StartInternal]: Exception: " + ex);
109+
throw;
110+
}
87111
}
88112

89113
private void Process_Exited(object sender, EventArgs e)

src/ElectronNET.API/Runtime/StartupManager.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,19 @@ private BuildInfo GatherBuildInfo()
132132

133133
if (electronAssembly == null)
134134
{
135+
Console.WriteLine("GatherBuildInfo: Early exit");
135136
return buildInfo;
136137
}
137138

138139
if (electronAssembly.GetName().Name == "testhost" || electronAssembly.GetName().Name == "ReSharperTestRunner")
139140
{
141+
Console.WriteLine("GatherBuildInfo: Detected testhost");
140142
electronAssembly = AppDomain.CurrentDomain.GetData("ElectronTestAssembly") as Assembly ?? electronAssembly;
141143
}
144+
else
145+
{
146+
Console.WriteLine("GatherBuildInfo: No testhost detected: " + electronAssembly.GetName().Name);
147+
}
142148

143149
var attributes = electronAssembly.GetCustomAttributes<AssemblyMetadataAttribute>().ToList();
144150

0 commit comments

Comments
 (0)