3

I have a ChromiumWebBrowser control in my MainWindow.xaml:

<cefSharp:ChromiumWebBrowser x:Name="chromiumBrowser" Address="https://www.github.com/"/>

and I'm trying to drive it by attaching a Selenium ChromeDriver to it:

    ChromeOptions options = new ChromeOptions();
    options.BinaryLocation = AppDomain.CurrentDomain.FriendlyName;
    options.AddArguments("disable-extensions");
    options.AddArguments("disable-plugins");

    ChromeDriver chromeDriver = new ChromeDriver(options);
    chromeDriver.Url = "http://www.reddit.com";

Is this a correct approach? It seems to nearly work as the embedded control flashes once when the driver attempts to connect to it but then I get the following error from the ChromeDriver console:

[1006/220430.356:ERROR:cache_util_win.cc(21)] Unable to move the cache: Access is denied. (0x5) [1006/220430.357:ERROR:cache_util.cc(139)] Unable to move cache folder GPUCache to old_GPUCache_000

EDIT

Apparently attaching a driver using options.BinaryLocation will unfortunately always launch a new instance of the executable. From the comments below, I gathered that the correct way would be to attach the driver through a debug port. So I create my browser control through code:

CefSettings settings = new CefSettings();
settings.RemoteDebuggingPort = 9222;
settings.UserDataPath = "C:/Temp";
Cef.Initialize(settings);
browserControl = new ChromiumWebBrowser("chrome://version");

But when I try to attach to it:

    ChromeOptions options = new ChromeOptions();
    options.AddArguments("--remote-debugging-port=9222");

    ChromeDriver driver = new ChromeDriver(options);
    driver.Url = "http://www.reddit.com";

The error is now: System.InvalidOperationException: 'session not created from disconnected: unable to connect to renderer (Session info: chrome=85.0.4183.121) (SessionNotCreated)'

This could be due to mismatching chrome versions as CefSharp only supports up to v84 at the moment. I'm using a v84 chromedriver so I don't know where this 85 warning comes from.

Jelly Ama
  • 6,701
  • 3
  • 20
  • 23
  • Does this post help?: https://stackoverflow.com/questions/57890068/automation-for-chrome-legacy-window-chromium-using-winium – pcalkins Oct 06 '20 at 20:15
  • Thanks for the link but using Winium for this problem seems like quite a contorted approach. I really hope Selenium can be bound to an embedded browser control in a straightforward way. – Jelly Ama Oct 06 '20 at 20:22
  • Never done this before but it doesn't seem like you'd need Winium... you just need to launch the embedded browser with remote-debugging-port on. Then when you launch your chromedriver instance it will be using the same localhost. (If I understood that post correctly...): https://blog.chromium.org/2011/05/remote-debugging-with-chrome-developer.html – pcalkins Oct 06 '20 at 20:28
  • See https://stackoverflow.com/a/8353313/4583726 Selenium doesn't support attaching to an already running instance. If that's what you require then I'd look at puppeteer Sharp. – amaitland Oct 06 '20 at 20:39
  • this is a little different in that it's embedded. You can attach to a running instance if you store the sessionID and use it... though you end up with an orphaned browser instance. In this case, it sounds like they can launch the browser with a certain flag that would allow all localhost sessions to be used. (Though that part is a little unclear...) – pcalkins Oct 06 '20 at 21:23
  • I'm aware it's embedded using CefSharp. I'm not sure exactly what you mean by a certain flag though. To enable remote debugging then http://cefsharp.github.io/api/84.4.x/html/P_CefSharp_CefSettingsBase_RemoteDebuggingPort.htm is required. The generic CEF instructions are https://bitbucket.org/chromiumembedded/cef/wiki/UsingChromeDriver.md – amaitland Oct 06 '20 at 21:41

1 Answers1

5

After sustaining some massive hair loss, I found out that this works:

CefSettings settings = new CefSettings();
settings.RemoteDebuggingPort = 9222;
settings.UserDataPath = "C:/Temp";
Cef.Initialize(settings);
browserControl = new ChromiumWebBrowser("chrome://version");

And this is how to gloriously attach to the embedded ChromiumWebBrowser:

ChromeOptions options = new ChromeOptions();
options.DebuggerAddress = "localhost:9222";

ChromeDriverService service = ChromeDriverService.CreateDefaultService();
service.HideCommandPromptWindow = true;

ChromeDriver driver = new ChromeDriver(service, options);

The trick was to use ChromeOptions.DebuggerAddress instead of ChromeOptions.AddArguments("--remote-debugging-port=XXXX")

Jelly Ama
  • 6,701
  • 3
  • 20
  • 23