Search code examples
c#seleniumgoogle-chrome-devtools

Handling network errors after a test in selenium


The issue

I have seached a lot for a solution in C#, but none of them are working for me. I can't use them because there are objects missing that I can't import or the objects are deprecated. (DesiredCapabilities for example)

What I want to do

All I want to do is after executing a test, to check in the tear down if something went wrong during the test. When something went wrong the test should fail with message. (Assert.Fail) The problem here is that I can't get the logs I want to see.

I will show what I have tried.

Version 1:

ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.SetLoggingPreference("performance", LogLevel.All);
var logs = driver.Manage().Logs.GetLog("performance");

This works for me, but the issue here is that I can't see what's really wrong. The message output just shows me that some error has happend, but not what error.

This is accepted solution like you can see here:

How to set up performance logging in SeleniumWebdriver with Chrome

Unable to get Chrome Performance logs in Selenium C#

Version 2:

The same like in version 1 with a little change

var logs = driver.Manage().Logs.GetLog(LogType.Browser);

The issue here is that I only get one log, but I want to get all logs from the execution.

Version 3:

This seems to me the most up to date solution, but again I have issues with accessing the objects.

C# Selenium 4: Setup request interception

Version 4:

I haven't tied this because that's not directly selenium, but maybe this could help.

How do I see the raw HTTP request that the HttpWebRequest class sends?

Update: It doesn't work like this.

Edit - Version 5:

There also some official examples with Chrome DevTools but not many of them are in C#

Something like this should work, but I need to use this in my test not in a console application.

This is my current state:

IDevTools devTools = driver as IDevTools;
DevToolsSession session = devTools.CreateDevToolsSession();
session.Network.ResponseReceived += ResponseReceivedHandler;
session.Network.Enable(new EnableCommandSettings());

driver.Navigate().GoToUrl("https://google.com");

With this method:

public static void ResponseReceivedHandler(object sender, ResponseReceivedEventArgs e)
{
   Debug.WriteLine($"Url: { e.Response.Url } Status: { e.Response.Status } Type: { e.Response.MimeType } ");
}

Update 2:

I can get most of the time a e.Response.StatusText message and allways an status code, what I want to see is the msg object in the network tab. (You can see it when you click on an item and then open the preview tab)


I hope you can help me out, it should work for chrome other browsers would be good but speciaclly for chrome it would help.


Solution

  • Disclamer: Long answer for Selenium 4+ scroll down :)

    I solved it for myself some month ago, can tell now what the real problem was, but here you can find a working example how to do it in Selenium 4.0 :)

    Here is some working code for alpha and beta, from this answer.

    Before chrome version specifications: (Until 4.0.0 alpha 5)

    IDevTools devTools = driver as IDevTools;
    DevToolsSession session = devTools.CreateDevToolsSession();
    session.Network.ResponseReceived += ResponseReceivedHandler;
    session.Network.Enable(new EnableCommandSettings());
    driver.Navigate().GoToUrl(url);
    
    public void ResponseReceivedHandler(object sender, ResponseReceivedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"Status: { e.Response.Status } : {e.Response.StatusText} | File: { e.Response.MimeType } | Url: { e.Response.Url }");
    }
    

    After chrome version specifications: (> 4.0.0 alpha 5)

    using DevToolsSessionDomains = OpenQA.Selenium.DevTools.V96.DevToolsSessionDomains;
    var driver = new ChromeDriver();
    var devTools = (IDevTools)driver;
    IDevToolsSession session = devTools.GetDevToolsSession();
    var domains = session.GetVersionSpecificDomains<DevToolsSessionDomains>();
    domains.Network.ResponseReceived += ResponseReceivedHandler;
    await domains.Network.Enable(new OpenQA.Selenium.DevTools.V96.Network.EnableCommandSettings());
    driver.Navigate().GoToUrl(url);
    
    void ResponseReceivedHandler(object sender, ResponseReceivedEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine($"Status: { e.Response.Status } : {e.Response.StatusText} | File: { e.Response.MimeType } | Url: { e.Response.Url }");
    }
    

    For Selenium 4+ versions

    I can recommend you to use a version and browser unspecific approach: (Works in Chrome and Edge with Selenium 4.8)

    public void SetupNetworkLogging(IWebDriver driver)
    {
        NetworkManager manager = new NetworkManager(driver);
        manager.NetworkResponseReceived += ResponseHandler;
    
        Task monitoring = manager.StartMonitoring();
        monitoring.Wait();
    }
    
    private void ResponseHandler(object sender, NetworkResponseReceivedEventArgs e)
    {
        Console.WriteLine($"Http status: {e.ResponseStatusCode} : {e.ResponseBody} | Url: {e.ResponseUrl} ");
    }
    

    You can also experiment with a devtools session:

    IDevTools devTools = driver as IDevTools;
    var session = devTools.GetDevToolsSession();
    var network = session.Domains.Network;
    
    Task enableNetwork = network.EnableNetwork();
    Task networkCaching = network.EnableNetworkCaching();
    enableNetwork.Wait();
    networkCaching.Wait();
    

    I hope this was helpful for you - The official documentation can be found here. :)