How to get remote debugging URL of specific ChromiumWebBrowser instance in CefSharp? - c#

Goal
I am trying to get remote debugging URL of specific ChromiumWebBrowser object after initializing it with new ChromiumWebBrowser(...)
Application Info
My application creates multiple ChromiumWebBrowser worker instances at runtime, the number of instances varies according to workload. All of them navigates to some URLs and perform tasks(clicks on buttons, fills inputs, collects values) on sites. If the worker finds unexpected result after it's actions(Couldn't find the div element with given id), it sends notification to the user and hands out it's remote debugging URL which is allowing the user to take control of worker and investigate what went wrong during process.
The Problem
I don't know how to obtain remote debugging URL of specific ChromiumWebBrowser object
e.g. it would be nice if the URL variable could instantiated that easy in the following code block but ChromiumWebBrowser class doesn't have such property (RemoteDebuggingUrl).
ChromiumWebBrowser worker1 = new ChromiumWebBrowser(...);
string URL = worker1.RemoteDebuggingUrl;
Efforts
I decided to dig down into the source code of CefSharp to find out how remote debugging server creates links per ChromiumWebBrowser basis, e.g. i assumed maybe it is accessing of ChromiumWebBrowser objects ID like property because the links of browsers in remote debugging main page (accessed via http://localhost:8088) is like following url ;
http://localhost:8088/devtools/inspector.html?ws=localhost:8088/devtools/page/FA54735587998EFD141A2300AE57F70C
The "FA54735587998EFD141A2300AE57F70C" part is the ID of the remote debugging link as seen in http://localhost:8088/json
[
{
"description": "",
"devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:8088/devtools/page/FA54735587998EFD141A2300AE57F70C",
"id": "FA54735587998EFD141A2300AE57F70C",
"title": "Sign In",
"type": "page",
"url": "https://af.sts.mapfre.net/adfs/ls/?SAMLRequest=hZJda8IwFIb%2FSsm9TVvFj9AKtk4Q3BDddrGbEeopBpqkyzl1279fWnFzF3NXgZPzJs9zkhSlrhuxaOlodvDWAlLwoWuDot%2FIWOuMsBIVCiM1oKBS7Bf3G5GEkWicJVvaml1FbickIjhS1rBgvczYa5zP8tE0XxXjPJrdjYer8SiaTIplnAxXwyguWPAMDn1%2FxnzchxBbWBskaciXong2iJNBMn6MExFNxTB5YcHSOygjqU8diRoUnMsqRMJQy6ZyEBogLg8V8ho5CwprELrzbpGX5yZRts75daB0U6tSEQtW1pXQDzBjlawROsytN1Un%2BK4sLuLdZa0Gtwd3UiU87TY%2FkJ7uQlhaHZLjGuraGt5YpB1g0zGwedrNWfSjcPM%2Fsym%2FbkvP7%2FzgvdbLrfXonx24lv9odxV1GFR9qyAnDSqv74U82HvhQJKXJNcC4%2FPzlb9%2F0%2FwL",
"webSocketDebuggerUrl": "ws://localhost:8088/devtools/page/FA54735587998EFD141A2300AE57F70C"
}
]
Finally i couldn't navigate to the implementation of following symbol using Visual Studio 2019
bool CefInitialize(const CefMainArgs& args,
const CefSettings& settings,
CefRefPtr<CefApp> application,
void* windows_sandbox_info);
in purpose of finding how remote debugging server works. I located this symbol in "cef_app.h" header file which is part of the cef-sdk.75.1.14 Nuget Package.
I tried to find the implementation of this symbol because i thought it is the entry point of remote debugging server, because it takes CefSettings parameter which includes RemoteDebuggingPort which was 8088 in my case.

Related

How to allow external process to launch my ASP.NET exe file

UPDATED QUESTION
I just deployed a self-contained solution to test my web app in an offline computer. When I go to the destination folder then double click on the executable I see the terminal window displaying that the ports http://locahost:5000 is open and https://localhost:5001 are open and ready to go. I then open a website and navigate to this url and sure enough I see my website working.
That takes care of part one.
Part 2 is launching my WebServer.exe from another application (called ProcessManager.exe)
This is where I am having issues...
Even though I am seeing the WebServer.exe application launching, I can't see any of the websites when I type: https://localhost:5001/SiteA. It tells me that it couldn't find the location of said url.
I go to my WebServer.exe application to see if its spitting out an error in the logs and I notice that the Content root path is wrong! It's telling me that it is looking for the contents of wwwroot folder in the wrong folder level.
Its saying Content root path:
E:\Projects\MyFirstProject\Deployments
I close everything and then I navigate to where my self-contained asp.net application is located and run WebServer.exe. Sure enough that one is displaying that it is pointing to the correct content root path which is:
E:\Projects\MyFirstProject\Deployments\WebServer
Another thing I notice when I launched my WebServer.exe from my ProcessManager.exe is that the WebServer.exe window also gives me this extra text at the very top:
Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
User profile is available. Using 'C:\Users\me\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
I did some minor research, and it turns out that my web application is not granting my ProcessManager.exe permissions of any kind. Or something to that effect.
This is how I am launchig my WebServer.exe from my ProcessManager project.
private const string WebServerPath = #"E:/Projects/MyFirstProject/Deployments/WebServer/WebServer.exe";
public ExternalProcess WebServerProcess
{
get { return _webServerProcess; }
}
private ExternalProcess _webServerProcess;
// constructor
public ProcessManager()
{
_webServerProcess = new ExternalProcess(WebServerPath);
}
/// <summary>
/// Start the web server
/// Gets called in MainWindowViewModel.cs
/// </summary>
public void StartWebServer()
{
string cmdLine = "";
_webServerProcess.StartProcess(cmdLine);
}
As I mentioned before my ASP.NET application launches without any problems but it does give me that issue that I mentioned above... What am I doing wrong? Can anyone help me understand what the underlying issue is?
many thanks in advance.

Launch web driver chrome browser through web api call

I want to launch the Chrome browser using Web Api call. I'm able to launch it using the below code while running through Visual Studio
URL: http://localhost:64001/api/values
public class ValuesController : ApiController
{
//private TechTalk.SpecFlow.ITestRunner testRunner;
// GET api/values
public IEnumerable<string> Get()
{
IWebDriver driver;
var webDriversPath = HttpContext.Current.Server.MapPath("~/bin/WebDrivers");
driver = new ChromeDriver(webDriversPath);
return new string[] { "value1", "value2" };
}
}
But, the issue is while publish into IIS try to access the URL: http://localhost/MyApp/Api/Values
I'm getting the below exception.
<Error>
<Message>An error has occurred.</Message>
<ExceptionMessage>
The request was aborted: The operation has timed out.
</ExceptionMessage>
<ExceptionType>System.Net.WebException</ExceptionType>
<StackTrace>
at System.Net.HttpWebRequest.GetResponse() at OpenQA.Selenium.Remote.HttpCommandExecutor.CreateResponse(WebRequest request)
</StackTrace>
</Error>
Can you please help me to fix this.
Spent some time working on this for myself and this route worked for me. Some issues arise for running selenium via IIS as the user my have permission issues or problems running GUI sessions without being associated to a GUI itself so it will "run" but become stuck. What worked for me will require you to alter your web API implementation to utilize remote web driver. Shouldn't be a big deal...worse case you might have to change a bunch of driver.FindElementsById to driver.FindElements(By.Id(""));
So what worked for me is
Download selenium stand alone server: http://www.seleniumhq.org/download/
You have the option of running selenium in grid mode but for this purpose, you can just run selenium standalone to handle chrome only. To do so run the following command.
Important note here that tripped me up some, run this from command prompt instead of powershell. Not sure why but powershell didn't cooperate well with the -D command line argument and kept giving me classpath errors.
java -Dwebdriver.chrome.driver=C:/utilities/selenium/chromedriver.exe -jar c:\utilities\selenium\selenium-server-standalone-2.48.2.jar -port 5556 -browser "browserName=chrome, version=ANY, maxInstances=10, platform=WINDOWS"
Alter your web API code to implement RemoteWebDriver, you should have this included in your project already...that is assuming you got your DLL's for selenium from nuget. To do this your web api Action in the Values controller code should look something like this
public IHttpActionResult Get()
{
var opts = new ChromeOptions();
var driver = new RemoteWebDriver(new Uri("http://127.0.0.1:5556/wd/hub"), opts);
driver.Navigate().GoToUrl("http://google.com");
return Ok(new { msg = "All done" });
}
Notice here where 5556 port on the webdriver URL is the same port specified in the command line argument from #3. If you change that port, you'll need to change it here as well. If you don't provide the port argument, I believe the default would be 4444.
Once you've altered your web api code to implement remote web driver you'll need to make sure the selenium stand alone implementation is always running wherever your web API app will exist, from there you should be able to launch
If you are interested in running selenium in grid mode, have a look at this link:
https://community.perfectomobile.com/posts/1101012-selenium-grid-server-configuration-hub-node-setup-for-chrome-firefox-safari-ie
This worked for me and a lot of the issues/answers were more java specific so hopefully this helps .net implementations.

cross browser testing using codedui?

i have issue in cross browser testing using codedui.
Using below code,
Process.Start("firefox", url);
BrowserWindow.CurrentBrowser = "firefox";
Browser = BrowserWindow.Launch(new System.Uri(url));
Keyboard.SendKeys("^{0}");
all code developed in IE . but now i have to execute code in firefox or chrome.I am going to execute the code in forefox.I am using this code here
Browser = BrowserWindow.Launch(new System.Uri(url));
in this line getting error like "An error occurred while connecting to Firefox".how to resolve this issue?I installed selenium components also. if i remove this line I am getting diffrent error like " Unable to find browser"...Please help.
Out of the box Visual Studio doesn't support cross browser CodedUI testing.
You're going to need to install Selenium components to allow for cross browser testing in Visual Studio.
Details on that can be found here:
http://blogs.msdn.com/b/visualstudioalm/archive/2012/10/30/introducing-cross-browser-testing-with-coded-ui-tests.aspx
Selenium components can be found here:
http://visualstudiogallery.msdn.microsoft.com/11cfc881-f8c9-4f96-b303-a2780156628d
Looks like CodedUI doesn't support playback on very many different browsers http://msdn.microsoft.com/en-us/library/dd380742(VS.100).aspx
There are some other tools out there http://watin.org/ is one, but I can't find anything myself that will really solve your problem.
Try
BrowserWindow.CurrentBrowser = "firefox";
BrowserWindow WebApp;
WebApp.CopyFrom(BrowserWindow.LaunchUrl(new System.Uri(url)));
I set up something similar to the following and it works well (I hand code everything, bypassing the UIMap).
public class WebApp : BrowserWindow
{
private string _url;
public WebApp(string url)
{
//define search properties using this keyword so the web application can be treated as a browser
_url = url;
BrowserWindow.CurrentBrowser = "Chrome";
this.CopyFrom(BrowserWindow.Launch(new Uri(url));
}
}
You can overload the constructor, of course, by adding a parameter for the browser to use or whether to start up the browser or not.
By setting up the web application as a BrowserWindow, you can have one open and ready and the playback engine should find it. I find this helps when working on tests (in IE).
Just a reminder, you do need the Selenium plug-in and that plug-in will only work for playback, not recording.
Cheers!
In our environment, we set up the Launch() method by doing the following:
public void LaunchBrowser(string uri)
{
BrowserWindow.CurrentBrowser = "firefox";
BrowserWindow myBrowser = BrowserWindow.Launch(new System.Uri(uri));
}
One thing to note is that if there is a firefox process already running in the background, the WebDriver will not launch a new instance, so be sure that all instances of firefox are shut down before the LaunchBrowser() is called. I've found that there are Java plugins that can keep it running in the background, so try to disable those that you don't need. Another good place to look, if you check your Task Manager and this is the case, is here.

SharePoint Claims-Authentication, Cookies, C#, and Excel-DLL/tld

The basic concept of the project is it accesses SharePoint, verifies a certain file exists, verifies the file is NOT locked by another user, and then, if those two conditions are met, excel opens the file up and does some stuff with it, then saves the file and closes it again.
The issue is at the point where the program accesses SharePoint and runs through the verification steps. Initially, my first crack at this was directly from VBA using SOAP, and, until Microsoft decided to downgrade SharePoint to 2013 from 2010, it worked quite well, meaning now, I'm into using Visual Studio and C# to accomplish the same thing that SOAP was doing in SP2010.
I've attempted implementing the code found here: http://www.vrdmn.com/2013/01/authenticating-net-client-object-model.html, however I can't get it to work. What I did manage to get working was the 2010 authentication model which pops up a browser window, checks for valid cookies, and, if it finds them, reads the cookies, otherwise prompts the user to log into SharePoint and then closes the browser and continues on.
public CookieCollection Show()
{
if (string.IsNullOrEmpty(this.LoginPageUrl)) throw new ApplicationException(Constants.MSG_NOT_CLAIM_SITE);
// navigate to the login page url.
this.webBrowser.Navigate(this.LoginPageUrl);
DisplayLoginForm = new Form();
DisplayLoginForm.SuspendLayout();
// size the login form
int dialogWidth = Constants.DEFAULT_POP_UP_WIDTH;
int dialogHeight = Constants.DEFAULT_POP_UP_HEIGHT;
if (PopUpHeight != 0 && PopUpWidth != 0)
{
dialogWidth = Convert.ToInt32(PopUpWidth);
dialogHeight = Convert.ToInt32(PopUpHeight);
}
DisplayLoginForm.Width = dialogWidth;
DisplayLoginForm.Height = dialogHeight;
DisplayLoginForm.Text = this.fldTargetSiteUrl;
DisplayLoginForm.Controls.Add(this.webBrowser);
DisplayLoginForm.ResumeLayout(false);
//DisplayLoginForm.Show();
Application.Run(DisplayLoginForm);
// see ClaimsWebBrowser_Navigated event
//DisplayLoginForm.Dispose();
return this.fldCookies;
}
The problem comes about with the Application.Run(DisplayLoginForm). If I step through the code line-by-line, everything works fine, and I get the results I need within my VBA code. However, if I run the program with F5 (either by building it in Debug mode or in Release mode), Application.Run(DisplayLoginForm) kills the application (and Excel along with it) once the cookie jar (my term, and most likely not a computer term) has been examined for valid cookies.
You can see in the code, I attempted to use DisplayLoginForm.Show(); rather than Application.Run, however I kept getting null references to the file I'm trying to find, so that approach does not work either.
So here's the question:
How do I go about popping up a web browser (which is obviously set up as a windows form), look for the cookies, prompt the user if needed, close the web browser and remain alive long enough to return the appropriate values (file.exists and file.islockedbyuser.email, both of which are in functions called by the VBA and both of which work just fine) to excel, and then finish up the program without shutting Excel down in the process?
The answer to this question is to set up a new and separate thread on which to operate the browser and login sequence, returning to the main thread (and the thread Excel is running on) the context with the credentials, with which the file can be queried.

WebApplication at "site url" coul not be found

i have made window application, which checks new announcements on sharepoint 2007 site, if any new announcemnt is found it shows it as link in my win application.
application is running fine on my server machine, but when i try to run my window application from normal machine it gives me:
System.IO.FileNotFoundException: The
Web application at
http://Server-Name:Port-Num/lists/announcements/Allitems.aspx could not be found. Verify that you
have typed the URL correctly. If the
URL should be serving existing
content, the system administrator may
need to add a new request URL mapping
to the intended application.
this machine exists on LAN, as i can access site from my browser, but when it comes to win application it gives me the above error on following line:
string rawurl = "http://192.168.1.105:1625/";
SPSite site = new SPSite(rawurl); // this line gives error
It should throw an exception because the Server Object Model you are using like SPSite, SPWeb will not work unless it's on the server either web application or windows application.
If you want to get data from a remote sharepoint server you should use SharePoint Web Services.
This article will help you http://www.infoq.com/articles/swanson-moss-web-services
References:
http://social.msdn.microsoft.com/Forums/en-US/sharepoint2010general/thread/570a4734-d11e-4385-bb97-8625013ebe99/
http://objectmix.com/sharepoint/296959-object-model-new-web-site-creation-remote-sharepoint-server.html
make sure the alternate access mapping is correctly set
so if you can call a page with multiple name (machine name and alias like xxxx73 and portauat) note that may only one works in visual studio so try to fix mapping in central admin or call the page with default main url.
for me noting this small tip, fix my problem in my Sharepoint 2010 UAT environment

Categories