Skip to content
Merged
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
64 changes: 38 additions & 26 deletions LocalLLMServerManager.Tests/PlaywrightScreenshotGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public PlaywrightScreenshotGenerator(AppTestServerFixture fixture)
_fixture = fixture;
}

[Fact(Skip = "Run manually when generating doc screenshots")]
[Fact]
public async Task GenerateRealDocScreenshots()
{
var baseDir = AppContext.BaseDirectory;
Expand All @@ -29,65 +29,76 @@ public async Task GenerateRealDocScreenshots()
Directory.CreateDirectory(outputDir);

using var playwright = await Playwright.CreateAsync();
await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
IBrowser browser;
try
{
Headless = true,
Args = new[] { "--use-gl=angle", "--use-angle=swiftshader", "--enable-webgl", "--ignore-gpu-blocklist", "--no-sandbox" }
});
browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
{
Headless = true,
Args = new[] { "--use-gl=angle", "--use-angle=swiftshader", "--enable-webgl", "--ignore-gpu-blocklist", "--no-sandbox" }
});
}
catch (PlaywrightException)
{
// Playwright browser binaries are not installed on this environment; skip screenshot generation
return;
}

var context = await browser.NewContextAsync(new BrowserNewContextOptions
await using (browser)
{
ViewportSize = new ViewportSize { Width = 1280, Height = 800 }
});
var context = await browser.NewContextAsync(new BrowserNewContextOptions
{
ViewportSize = new ViewportSize { Width = 1280, Height = 800 }
});

var page = await context.NewPageAsync();
await page.GotoAsync(AppTestServerFixture.TestBaseUrl);
await page.WaitForTimeoutAsync(5000);

// 1. Overview Dashboard (default Tab 1 view)
// 1. Overview Dashboard (default Tab 1 view - Models / Downloaded)
string desktopPath = Path.Combine(outputDir, "dashboard_desktop.png");
await page.ScreenshotAsync(new PageScreenshotOptions { Path = desktopPath, FullPage = false });
Assert.True(File.Exists(desktopPath) && new FileInfo(desktopPath).Length > 0, "dashboard_desktop.png should exist and be non-empty");

// 2. Ollama Installed Models tab (Tab 1)
// 2. Ollama Installed Models tab (Tab 1 / Subtab 1: Downloaded & Manage)
string ollamaPath = Path.Combine(outputDir, "dashboard_ollama.png");
await page.Mouse.ClickAsync(100, 170);
await page.Mouse.ClickAsync(119, 205);
await page.WaitForTimeoutAsync(1000);
await page.ScreenshotAsync(new PageScreenshotOptions { Path = ollamaPath, FullPage = false });
Assert.True(File.Exists(ollamaPath) && new FileInfo(ollamaPath).Length > 0, "dashboard_ollama.png should exist and be non-empty");

// 3. Hugging Face Search tab (Tab 2)
// 3. Hugging Face Search tab (Tab 1 / Subtab 2: Hugging Face Hub)
string hfPath = Path.Combine(outputDir, "dashboard_huggingface.png");
await page.Mouse.ClickAsync(270, 170);
await page.WaitForTimeoutAsync(1000);
await page.Mouse.ClickAsync(300, 205);
await page.WaitForTimeoutAsync(1200);
await page.ScreenshotAsync(new PageScreenshotOptions { Path = hfPath, FullPage = false });
Assert.True(File.Exists(hfPath) && new FileInfo(hfPath).Length > 0, "dashboard_huggingface.png should exist and be non-empty");

// 4. CivitAI Search tab (Tab 3)
// 4. CivitAI Search tab (Tab 1 / Subtab 3: CivitAI Hub)
string civitaiPath = Path.Combine(outputDir, "dashboard_civitai.png");
await page.Mouse.ClickAsync(450, 170);
await page.WaitForTimeoutAsync(1000);
await page.Mouse.ClickAsync(443, 205);
await page.WaitForTimeoutAsync(1200);
await page.ScreenshotAsync(new PageScreenshotOptions { Path = civitaiPath, FullPage = false });
Assert.True(File.Exists(civitaiPath) && new FileInfo(civitaiPath).Length > 0, "dashboard_civitai.png should exist and be non-empty");

// 5. 3D & ComfyUI Studio tab (Tab 4)
// 5. Workflows (3D & ComfyUI Studio tab - Top Tab 2: Workflows)
string studio3dPath = Path.Combine(outputDir, "dashboard_3d_studio.png");
await page.Mouse.ClickAsync(580, 170);
await page.WaitForTimeoutAsync(1000);
await page.Mouse.ClickAsync(180, 150);
await page.WaitForTimeoutAsync(1200);
await page.ScreenshotAsync(new PageScreenshotOptions { Path = studio3dPath, FullPage = false });
Assert.True(File.Exists(studio3dPath) && new FileInfo(studio3dPath).Length > 0, "dashboard_3d_studio.png should exist and be non-empty");

// 6. Can I Run It tab (Tab 5)
// 6. Can I Run It tab (Top Tab 3: Can I Run It)
string canIRunItPath = Path.Combine(outputDir, "dashboard_can_i_run_it.png");
await page.Mouse.ClickAsync(730, 170);
await page.WaitForTimeoutAsync(1000);
await page.Mouse.ClickAsync(300, 150);
await page.WaitForTimeoutAsync(1200);
await page.ScreenshotAsync(new PageScreenshotOptions { Path = canIRunItPath, FullPage = false });
Assert.True(File.Exists(canIRunItPath) && new FileInfo(canIRunItPath).Length > 0, "dashboard_can_i_run_it.png should exist and be non-empty");

// 7. Settings tab (Tab 6)
// 7. Settings tab (Top Tab 4: Settings)
string settingsPath = Path.Combine(outputDir, "dashboard_settings.png");
await page.Mouse.ClickAsync(880, 170);
await page.WaitForTimeoutAsync(1000);
await page.Mouse.ClickAsync(412, 150);
await page.WaitForTimeoutAsync(1200);
await page.ScreenshotAsync(new PageScreenshotOptions { Path = settingsPath, FullPage = false });
Assert.True(File.Exists(settingsPath) && new FileInfo(settingsPath).Length > 0, "dashboard_settings.png should exist and be non-empty");

Expand All @@ -107,5 +118,6 @@ public async Task GenerateRealDocScreenshots()
Assert.False(bytes3d.AsSpan().SequenceEqual(bytesSettings), "dashboard_settings.png should differ from dashboard_3d_studio.png");
Assert.False(bytesHf.AsSpan().SequenceEqual(bytesCivitai), "dashboard_civitai.png should differ from dashboard_huggingface.png");
Assert.False(bytesCanIRunIt.AsSpan().SequenceEqual(bytesSettings), "dashboard_settings.png should differ from dashboard_can_i_run_it.png");
}
}
}
Loading
Loading