Catching Network Traffic With Selenium C# - c#

I al looking to capture network traffic and log responses/headers however I cannot seem to find any resources for achieving this in c#. Most if not all of the guides have been for JS or Python. I read that this functionality was not added into the c# version as of 2019 but no new news has been posted. Does anyone know how to get network logs from a ChromeDriver?

Wrong, in selenium 4 you can do that but it is still in beta

Through much effort and googling around I have created something in C# that seems to do what you want. My answer is an adaption of some C# and Java implementations found on the internet which I could not get to work on individually, but did provide some needed insight.
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.DevTools;
using Network = OpenQA.Selenium.DevTools.V108.Network;
using DevToolsSessionDomains = OpenQA.Selenium.DevTools.V108.DevToolsSessionDomains;
internal class Program
{
private static async Task Main(string[] args)
{
string url = "https://stackoverflow.com/questions/68582545/catching-network-traffic-with-selenium-c-sharp";
Uri uri = new Uri(url);
var driver = new ChromeDriver();
var devTools = (IDevTools)driver;
IDevToolsSession session = devTools.GetDevToolsSession();
var domains = session.GetVersionSpecificDomains<DevToolsSessionDomains>();
domains.Network.ResponseReceived += ResponseReceivedHandler;
Task task = domains.Network.Enable(new Network.EnableCommandSettings());
task.Wait();
driver.Navigate().GoToUrl(uri);
var name = Console.ReadLine();
Console.WriteLine("finished");
driver.Dispose();
void ResponseReceivedHandler(object sender,Network.ResponseReceivedEventArgs e)
{
Console.WriteLine("New Work Response received");
Console.WriteLine($"Response Status: {e.Response.Status}");
Console.WriteLine($"Status Text: {e.Response.StatusText}");
Console.WriteLine($"Response MimeType: {e.Response.MimeType}");
Console.WriteLine($"Response Url: {e.Response.Url}");
}
}
}
I hope this answer answers your question or at least helps someone in a similar situation.

You can use this approach in any selenium version and not wait for the Selenium 4 release.
https://www.automatetheplanet.com/webdriver-capture-modify-http-traffic/

If you want to do use a simular version like that one from Jeppe Holt, for Selenium 4+ without being version and browser specific try that one: (Works on Chrome and Edge with Selenium 4.8)
public void SetupNetworkLogging(IWebDriver driver)
{
NetworkManager manager = new NetworkManager(driver);
manager.NetworkResponseReceived += ResponseHandler;
manager.StartMonitoring();
}
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;
network.EnableNetwork();
network.EnableNetworkCaching();

Related

Change PhantomJS proxy settings while running

I'm using Selenium and PhantomJs in a C#/Winforms application.
I have to set the proxy for PhantomJS before running it with this code:
var driverService = PhantomJSDriverService.CreateDefaultService("phantomjsdriver");
Proxy proxy = new Proxy();
proxy.HttpProxy = string.Format("xx.xx.xx.xx:port");
driverService.ProxyType = "http";
driverService.Proxy = proxy.HttpProxy;
driverService.AddArgument(string.Format("--proxy-auth={0}:{1}", "username", "password"));
using (var driver = new PhantomJSDriver(driverService))
{
//......
}
Now I have a list of proxies! And I need to change the proxy after each request, So what I do now is just quitting the driver then run it again with a new proxy.
It's not a very efficient way so I was wondering if there was any method to change the proxy without quitting the driver!
Thanks in advance!
EDIT
So there is a function in PhantomJS that enable us to change the proxy at any time.
Any idea how to use it under Selenium?
I found the solution, After finding that PhantomJS has a setProxy function, It was just a matter of how to use it:
String script = "return phantom.setProxy(\"{0}\", {1}, \"http\", \"{2}\", \"{3}\")";
string func = string.Format(script, ppp.IP, ppp.Port, ppp.Username, ppp.Password);
Object obj = driver.ExecutePhantomJS(func);
Hope this code helps someone else!

Coap.Net - Starting

I'm currently trying to start with CoAP in C#. The library I'm using is CoAP.Net (→ https://github.com/smeshlink/CoAP.NET).
Unfortunately, I didn't even succeed with the example published in the "Quick Start"-Section on GitHub.
My Server Code:
class Program
{
static void Main(string[] args)
{
CoapServer server = new CoapServer();
server.Add(new HelloWorldRessouce());
server.Start();
}
}
and a ressource-class in the Server solution:
class HelloWorldRessouce : CoAP.Server.Resources.Resource
{
public HelloWorldRessouce() : base("hello-world")
{
Attributes.Title = "GET a friendly greeting!";
}
protected override void DoGet (CoapExchange exchange)
{
exchange.Respond("Hello World fron CoAP.NET!");
}
}
On the client-side I've got the following:
static void Main(string[] args)
{
CoapClient client = new CoapClient();
Request request = new Request(Method.GET);
//request.URI = new Uri("coap://[::1]/hello-world");
request.URI = new Uri("coap://192.168.178.48:5683/hello-world");
request.Send();
// wait for response
Response response = request.WaitForResponse();
}
Here is the Console-Output from the Server:
DEBUG - Starting CoAP server
DEBUG - BlockwiseLayer uses MaxMessageSize: 1024 and
DefaultBlockSize:512
DBEUG - Starting endpoint bound to [::ffff:0:0]:5683
Press any key...
Here is the Console-Output from the Client:
Console-Output - Client
I'm pretty sure, the problems are on the Client-side...
It would be awesome, if there's someone to help me get this example running. Or maybe, someone can give me a few Noob-Examples. The example-files don't really help me with this problem...
Thanks everybody...
Cheers, Mirco
Okay, it seems as if there was the dumbest user at work...^^
Server-side:
static void Main(string[] args)
{
CoapServer server = new CoapServer();
server.Add(new HelloWorldRessouce());
server.Start();
}
after "server.Start();" the program is finished and the server turns off.
By adding a "Console.ReadKey();" afterwards, everything is fine.
If someone has any noob-examples espacially about the configuration, they are still appreciated.
Thanks everybody ;)

Selenium screenshot parameter is not valid

Here is my selemium test:
[Test]
public void RunStepsTest()
{
using (var driver = new InternetExplorerDriver())
{
driver.Navigate().GoToUrl(Url);
ExecuteStep(driver, "start");
ExecuteStep(driver, "step1");
ExecuteStep(driver, "step2");
ExecuteStep(driver, "finish");
}
}
private void ExecuteStep(InternetExplorerDriver driver, string stepName)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(x => ExpectedConditions.ElementIsVisible(By.Id(stepName)));
var scrrenshot = driver.GetScreenshot();
scrrenshot.SaveAsFile(Path.Combine(ScreenshotDirectory, stepName + ".jpg"), ScreenshotImageFormat.Jpeg);
var link = driver.FindElement(By.Id(stepName));
link.SendKeys(Keys.Enter);
}
Most of time this test fails on line
scrrenshot.SaveAsFile(Path.Combine(ScreenshotDirectory, stepName + ".jpg"), ScreenshotImageFormat.Jpeg);
with message "Paramter is not valid". What do I do wrong?
In Internet Explorer driver, it's intended to throw this error .
From Github bug tracking :
Because of the limitations of how the IE driver is forced to work in
order to take full-DOM screenshots, screenshots are only supported for
browser windows viewing HTML documents. This is entirely as intended
by the driver (regardless of the behavior of Chrome or Firefox). The
driver is forced by the constraints of the IE browser itself.
Accordingly, I'm closing this as "working as intended".
If you are allowed to use other driver, you can try Firefox or Chrome Driver to have screenshot.
Try this code like this:
Screenshot ss = ((ITakesScreenshot)driver).GetScreenshot();
ss.SaveAsFile("e:\\pande", System.Drawing.Imaging.ImageFormat.Jpeg);

NoSuchElementException using PhantomJS 1.9.2 in Visual Studio/C#

I've read all prior posts and tried all suggestions. I've verified the page is loading via taking a screenshot. It's there. I have a 30 second implicit wait in place, which PhantomJS waits for. I have a fully qualified URL. And i've tested the same simple code snippet below with ChromeDriver and it works by flipping to that driver. Any ideas?
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
var d = new PhantomJSDriver();
//var d = new ChromeDriver();
try
{
var s = "abc";
d.Manage().Window.Maximize();
d.Manage().Timeouts().ImplicitlyWait(System.TimeSpan.FromSeconds(10));
d.Navigate().GoToUrl("http://www.google.com");
var e = d.FindElement(By.Name("q"));
e.SendKeys(s);
e.Submit();
Assert.AreEqual<String>(s + " - Google Search", d.Title);
}
catch(Exception e)
{
((ITakesScreenshot)d).GetScreenshot().SaveAsFile("c:\\exception.png", System.Drawing.Imaging.ImageFormat.Png);
Console.WriteLine(d.PageSource);
throw e;
}
finally
{
d.Quit();
}
}
Google may response with different HTML code depending on user agent and/or viewport size. Set a viewport of a desktop browser (like 1280x1024) to get a desktop version, whereas default PhantomJS viewport of 400x300 gets a lighter mobile version.
On how to change viewport size, see https://stackoverflow.com/a/23840494/2715393

WebSockets in firefox

For implementing my websocket server in C# I'm using Alchemy framework. I'm stuck with this issue. In the method OnReceive when I try to deserialize json object, I get a FormatException:
"Incorrect format of the input string." (maybe it's different in english, but I'm getting a localized exception message and that's my translation :P). What is odd about this is that when I print out the context.DataFrame I get: 111872281.1341000479.1335108793.1335108793.1335108793.1; __ad which is a substring of the cookies sent by the browser: __gutp=entrystamp%3D1288455757%7Csid%3D65a51a83cbf86945d0fd994e15eb94f9%7Cstamp%3D1288456520%7Contime%3D155; __utma=111872281.1341000479.1335108793.1335108793.1335108793.1; __adtaily_ui=cupIiq90q9.
JS code:
// I'm really not doing anything more than this
var ws = new WebSocket("ws://localhost:8080");
C# code:
static void Main(string[] args) {
int port = 8080;
WebSocketServer wsServer = new WebSocketServer(port, IPAddress.Any) {
OnReceive = OnReceive,
OnSend = OnSend,
OnConnect = OnConnect,
OnConnected = OnConnected,
OnDisconnect = OnDisconnect,
TimeOut = new TimeSpan(0, 5, 0)
};
wsServer.Start();
Console.WriteLine("Server started listening on port: " + port + "...");
string command = string.Empty;
while (command != "exit") {
command = Console.ReadLine();
}
Console.WriteLine("Server stopped listening on port: " + port + "...");
wsServer.Stop();
Console.WriteLine("Server exits...");
}
public static void OnReceive(UserContext context) {
string json = "";
dynamic obj;
try {
json = context.DataFrame.ToString();
Console.WriteLine(json);
obj = JsonConvert.DeserializeObject(json);
} catch (Exception e) {
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
return;
}
}
On the C# side I'm using Newtonsoft.Json, though it's not a problem with this library...
EDIT:
One more thing - I browsed through the code in here: https://github.com/Olivine-Labs/Alchemy-Websockets-Example and found nothing - I mean, I'm doing everything the same way authors did in this tutorial...
EDIT:
I was testing the above code in Firefox v 17.0.1, and it didn't work, so I tested it under google chrome, and it works. So let me rephrase the question - what changes can be made in js, so that firefox would not send aforementioned string?
I ran into the same issue - simply replacing
var ws = new WebSocket("ws://localhost:8080");
with
var ws = new WebSocket("ws://127.0.0.1:8080");
fixed the issue for me.
In C# console app I connect the client to the server using :
var aClient = new WebSocketClient(#"ws://127.0.0.1:81/beef");
Your code above is connecting using
var ws = new WebSocket("ws://localhost:8080");
There could be one of two issues -
First is to see if WebSocketClient works instead.
To make sure your url is of the format ws://ur:port/context. This threw me off for a while.

Categories

Resources