PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchShort answer: Selenium must take and save the image; Azure DevOps (formerly VSTS) only displays it after your test framework registers the file or your pipeline publishes it. With Visual Studio Test (TRX), call TestContext.AddResultFile(path), then run PublishTestResults@2 with testRunner: VSTest. If you produce JUnit or xUnit results, publish the files as build artifacts or upload them through the Azure DevOps attachment REST API instead.
What changed from VSTS to Azure DevOps?
Microsoft retired the VSTS name. The current service is Azure DevOps, but the workflow is the same: capture a browser image in Selenium, preserve it on the build agent, associate it with the test result (or publish it separately), and inspect it in the run.
Azure DevOps does not take a browser screenshot automatically when a test fails. As Microsoft’s UI-testing guidance puts it, “Most UI testing frameworks provide the ability to capture screenshots.” Your test code still has to invoke that capability and make the resulting file available before the agent workspace is cleaned up.
Microsoft’s guidance covers result attachments for VSTest/TRX and NUnit 3.0. JUnit and xUnit result files do not formally carry attachments through the Publish Test Results route, so use an artifact or the attachment API for those formats.
#1 Best Overall
Choose where the screenshot should appear
| Route | Where you find the image | Use it when |
|---|---|---|
| Test-result attachment | Attachments on the individual automated test result | You emit TRX or a supported NUnit result and want evidence beside the failed test. |
| Build artifact | Build summary, Artifacts page | Your result format is JUnit or xUnit, or you want a folder of all screenshots. |
| Attachment REST API | An attachment associated with a test run/result | You need result-level placement but your runner does not provide a supported attachment mechanism. |
Capture a screenshot in Selenium
Visual Studio Test with C#
The following MSTest-style example captures only when the test fails, writes to a predictable directory, and registers the existing file with the result. The directory is created on the agent, and the file name includes the test name and a UTC timestamp to avoid collisions.
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;
using System.IO;
[TestClass]
public class CheckoutTests
{
public TestContext TestContext { get; set; }
private IWebDriver driver;
[TestInitialize]
public void Start()
{
driver = new ChromeDriver();
}
[TestMethod]
public void CheckoutShowsConfirmation()
{
try
{
driver.Navigate().GoToUrl("https://example.test/checkout");
// test steps and assertions go here
Assert.IsTrue(driver.Title.Contains("Checkout"));
}
catch
{
var root = Environment.GetEnvironmentVariable("BUILD_ARTIFACTSTAGINGDIRECTORY")
?? Path.Combine(Directory.GetCurrentDirectory(), "screenshots");
Directory.CreateDirectory(root);
var safeName = "CheckoutShowsConfirmation-" + DateTime.UtcNow.ToString("yyyyMMdd-HHmmssfff") + ".png";
var path = Path.Combine(root, safeName);
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile(path);
TestContext.AddResultFile(path);
throw;
}
}
[TestCleanup]
public void Stop()
{
driver?.Quit();
driver?.Dispose();
}
}
TestContext must be a property on the test class. AddResultFile records the path for the Visual Studio Test result; it does not create a missing file, so write and verify the image first. If you prefer a screenshot on every test, move the capture into teardown and register it there, but failure-only capture usually keeps result storage manageable.
NUnit 3.7 and later
Microsoft’s UI-testing guidance identifies TestContext.AddTestAttachment() for NUnit 3.7 or later. Capture with Selenium’s ITakesScreenshot, save the path, then call the NUnit attachment method before the test process exits. Confirm the NUnit adapter and framework versions on your agent; an older adapter can produce a result that does not contain the attachment.
try
{
driver.Navigate().GoToUrl("https://example.test/login");
Assert.That(driver.Title, Does.Contain("Sign in"));
}
catch
{
var path = Path.Combine(TestContext.CurrentContext.WorkDirectory,
"login-" + DateTime.UtcNow.ToString("yyyyMMdd-HHmmssfff") + ".png");
((ITakesScreenshot)driver).GetScreenshot().SaveAsFile(path);
TestContext.AddTestAttachment(path, "Selenium failure screenshot");
throw;
}
Publish TRX results in an Azure Pipelines YAML build
Make the test runner emit TRX files, then configure the task for VSTest. The task’s default pattern is aimed at JUnit XML, so specify a TRX glob that matches your actual output.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
- task: VSTest@2
inputs:
testSelector: 'testAssemblies'
testAssemblyVer2: '**\*test*.dll'
searchFolder: '$(System.DefaultWorkingDirectory)'
resultsFolder: '$(Agent.TempDirectory)\TestResults'
- task: PublishTestResults@2
inputs:
testRunner: VSTest
testResultsFiles: '**/*.trx'
searchFolder: '$(Agent.TempDirectory)\TestResults'
mergeTestResults: true
failTaskOnFailedTests: true
The exact test assembly pattern, results folder, and task version depend on your repository. Inspect the agent log and confirm that the glob finds the generated .trx file. A successful test run with a zero-file glob can leave you with no published attachments.
Publish screenshots when the result format cannot carry them
Build artifacts for JUnit or xUnit
Microsoft states that Publish Test Results cannot publish attachments from JUnit or xUnit result schemas because those formats do not formally define them. Keep writing screenshots to a dedicated directory and publish that directory:
Rank #3
- task: CopyFiles@2
inputs:
SourceFolder: '$(Build.ArtifactStagingDirectory)'
Contents: '**/*.png'
TargetFolder: '$(Build.ArtifactStagingDirectory)/selenium-screenshots'
flattenFolders: false
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)/selenium-screenshots'
ArtifactName: 'selenium-screenshots'
publishLocation: 'Container'
Use a source folder that matches where your test actually writes files. The images will be under the build summary’s Artifacts page, not inside an individual test result.
Attachment REST API
If result-level placement is essential, call Azure DevOps’ Create Test Iteration Result Attachment API with the organization, project, run, result (or iteration) identifiers, API version, and an authorization scope accepted by your organization. The endpoint and request contract are documented in Microsoft’s Create Test Iteration Result Attachment REST API. Treat identifiers as run-time values; do not hard-code a run number in a reusable pipeline.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesFind the screenshot in Azure DevOps
- Open the Azure DevOps project and the pipeline run that published the tests.
- Open the Tests tab (or the test run in Test Plans).
- Select the failed automated test result.
- Open its Attachments area and select the image. Supported image files can be previewed in the Test Run Hub.
Run-level attachments and result-specific attachments are separate views. If you published an artifact instead, open the build summary and choose Artifacts. Automated test-result retention follows the associated build’s retention by default, so changing build retention changes how long the evidence remains available.
Agent, browser, and file-system requirements
- On Microsoft-hosted Windows images, Microsoft recommends using the preinstalled Selenium WebDrivers that match the installed browser versions. Hosted images change, so check the current image software list when a previously stable test starts failing.
- Drivers are not preinstalled on Microsoft-hosted Linux, Ubuntu, and macOS agents according to Microsoft’s Selenium pipeline guidance. Install and pin compatible browser and driver versions yourself.
- Self-hosted UI tests may require an interactive session and autologon. A service account running without a desktop can produce blank or unusable captures even when the test process starts.
- Write to a directory that survives until the publish task runs. Do not rely on a temporary path that a cleanup step deletes.
- Use unique names for parallel tests. Include the test name, shard or job name, and timestamp; otherwise workers can overwrite one another.
Troubleshooting checklist
The test fails but no image is listed
- Confirm the screenshot file exists on the agent before cleanup.
- Confirm the capture code executes on every failure path, including assertion and setup failures.
- For TRX, verify
TestContext.AddResultFile(path)receives the same absolute path that was written. - For NUnit, check that the framework/adapter supports
AddTestAttachment. - Confirm
PublishTestResults@2usestestRunner: VSTestfor TRX and that its glob matches the emitted file.
The publish task reports zero results
Inspect the task log for the expanded search folder and glob. A common mistake is leaving the JUnit default pattern while the runner emitted .trx files, or publishing before the test task has finished writing results.
The image is blank or the browser is not visible
Check driver/browser compatibility and whether the agent has an interactive desktop. Add an explicit wait for the page state your test needs before capturing. On hosted agents, compare the current browser and driver versions with the versions used by the failing run.
Parallel jobs overwrite screenshots
Include a job identifier and a high-resolution UTC timestamp in each file name, and give each job its own output directory. Publish after all captures are complete.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server for developers. It is useful when you need a clean page image outside the Selenium test itself: before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status in X-Page-Verdict and X-Billed headers.
Use the API documentation at https://screenshotneo.com/docs/ for options such as full-page or element capture, device and retina settings, waits, custom headers and cookies, PDF output, blocking rules, signed links, asynchronous jobs, and bulk capture.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
require('fs').writeFileSync('shot.webp', Buffer.from(await res.arrayBuffer()));
ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. One thousand screenshots per month are free with no card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.
Official references
- Microsoft Learn: Configure for UI testing
- Microsoft Learn: Perform UI tests with Selenium
- Microsoft Learn: PublishTestResults@2
- Microsoft Learn: Manage test runs in Azure DevOps Test Plans
Frequently Asked Questions
Can Selenium screenshots be attached automatically just by saving a PNG?
No. Saving the file is only the capture step. Register it with the framework’s result API or publish it as an artifact/API attachment before the agent workspace is removed.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Which Azure DevOps result formats support built-in attachments?
Microsoft documents attachment support through the test-result publishing route for VSTest/TRX and NUnit 3.0. JUnit and xUnit require an artifact or attachment-API route.
Why can I see a build artifact but not an attachment on the failed test?
Artifacts and result attachments are different locations. An artifact appears on the build summary; a result attachment appears only when the runner and result format carry it to that specific test.
The Bottom Line
Capture with Selenium, register the existing file with TRX/NUnit when supported, and publish artifacts or use the REST API for other result formats. Verify the output path, result glob, and agent browser setup before diagnosing Azure DevOps.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Free tools Windows power users keep installed
One-click scans. No signup required.

