Run firefox in background from C# - c#

I run Firefox (default browser) from C# with the code:
System.Diagnostics.Process.Start(browser.Document.Url.ToString());
I want Firefox to run in the background, because every time is open a new tab, the Windows is focusing on the Firefox, and is annoying.
How can I control Firefox tabs, close them after a time ?

You can use a ProcessStartInfo to tell it to run hidden or minimized or whatever. Not sure how to programmatically manipulate FireFox but I'm sure there's an API.
var psi = new System.Diagnostics.ProcessStartInfo();
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
psi.FileName = browser.Document.Url.ToString();
var proc = System.Diagnostics.Process.Start(psi);
//after a while...
proc.Kill();

Technically, you are not starting Firefox, you are executing a url.
I'm not sure exactly what Windows does, but in effect, that url is opened in the system's default browser, be it IE, FF or some other thing that might not even support tabs, so finding and killing Firefox is not really a solution if the url is opened in Opera.
Moreover, the Process.Start method returns null if no process is actually started by the call, so if Firefox is already running and just displays an additional tab, you will get a null as the result of the call.
So, I'm pretty sure this is impossible to do in a broad sence (any browser), and, unless Firefox has some sort of API for client-side management, not possible for that scenario either.
BTW, on my system (IE is the default browser), the WindowStyle property is not working as expected, as IE pops up to the front.

Rather than trimming the tabs, why not just kill the entire Firefox process and restart it periodically?

You won't be able to do this. First of all, I'm pretty sure running Firefox in the background won't stop it gaining focus when a new tab is opened. Second, it is difficult to control firefox programmatically. The only way to do what you want is to use a plugin like MozRepl. You could also try using selenium or your own JavaScript to control the browser behaviour. I needed to be able to open and close tabs in a shell script without using selenium or MozRepl, check out my question From a shell script open a new tab in a specific instance of Firefox

Related

Keep selenium out of focus for user

I am using selenium in C#. I am curious if there is a way I can make it so that as a user you can still do what it is you are doing without being interrupted by selenium. For example, if I am typing something and selenium opens a new tab, my mouse focuses on the tab it opened and doesn't allow me to type unless I click on where I am typing again. Would this be something to do in code or in windows settings?
Run browser in headless mode , in this case the browser runs without GUI so there won't be any interruption
All browsers support headless flag now , add headless argument to capabilities while creating the browser instance
Previously headless browsers like phantomjs used to use webkit rendering engine but now chrome has inbuild headless support and uses same rendering enginee blink
so there is no effect of quality
You can run in headless mode.
Basically in headless mode as name sounds, there's no windows. You do not even need browser in your system.
Code:
var chromeOptions = new ChromeOptions();
chromeOptions.AddArgument("--headless");
chromeOptions.addArguments("window-size=1920,1080");

Selenium ChromeDriver - Run in background but not headless

I am looking for a way to run selenium tests with a chrome driver, in the background. With the background I mean as in, not the foreground focussed window. I can actually do this, but as soon as actions like opening a new tab or switching between windows (so basically switching window handles) happen in the chrome driver, the browser window gets pushed to the foreground.
So my question is, how can I prevent this from happening without running the test headless?
Any suggestions are appreciated, open for discussion.
EDIT
As a somewhat temporary solution I came up with the following.
Using the Windows 10 Virtual Desktops feature, I run the test and thus the chrome browser window in a seperate virual desktop.
I then switch back to my main virtual desktop to continue with other tasks.
This prevents the chrome browser window from being forced to the foreground.
Note that this still makes a flashing chrome icon appear in the taskbar when any of the actions described above appear.
Still looking for a more solid solution, so any suggestions are still appreaciated.
To hopefully open new perspectives and discussion points, and ultimately a solution, I will provide some more detailed info of what my code is doing.
I have 5 chrome webdrivers, and each of these webdrivers contains 6 tabs (WindowHandles).
The idea is that a certain process has to be repeated continuously on each tab. So we loop over each webdriver, and within that webdriver over each tab and set this tab as the webdrivers current WindowHandle. This makes the chrome window visibly switch to the assigned tab.
After that switch has taken place, so basic selenium automation is performed on the content of the tab, after wich we repeat the whole process.
The actual issue seems to take place when a chrome webdriver switches to a new tab (WindowHandle), at this moment the chrome window containing the tab is pushed to the foreground and steals focus. Note that this does not always takes place, often it can switch tabs without any issues. So it is unclear wether there is another factor which would cause the window to steal focus.
EDIT 2
After doing the following:
I overloaded the selenium method which is used to switch between tabs (WindowHandles), and called SetWindoPos each time. Unfortunately this did not solve this issue either. I will try to look deeper into what might be causing this and will report back. – S. Van den Wyngaert
I went out for a few hours while running the tests, and came back to see that surprisingly I was still on my main Virtual Desktop (win10 feature). This means that the issue didn't occur during the time I was gone. I started working again, opened a chrome window and noticed that shortly after I did this, focus was stolen by one of the chrome driver's windows again.
What I conclude from this is that the issue only occurs when another chrome window (not opened by a chrome driver from code) is opened.
I will keep investigating and will report back with updates.
After investigating this behavior for a few more hours I noticed that when another chrome window is open, as long as this has focus, the issue doesn't take place. So to quickly summarize this:
The issue doesn't take place when:
No other chrome windows (not selenium driven) are opened or minimised
Another chrome window (not selenium driven) is opened and has focus
Another application running fullscreen mode has focus
The issue does take place when:
Another chrome window (not selenium driven) is opened and has no focus
Note that when I talk about another chrome window I specificly mean a chrome window that is not driven by selenium, so a regular chrome window opened by the user.
Easiest way would be to run a local selenium grid. Start your node(s) as a windows service. This way the test will run in the background, without being headless.
Another good option to scale your solution, and if your machine has the capacity to run docker, is to use
zalenium
It's a docker based, auto scaling, selenium-grid solution that works pretty quick out of the box.
You can watch your tests live via the management pages, watch a recording after the fact, pause/debug with live interaction via VNC. Also something to be said for not having the worry about changing browser versions.
Last time i used it, it had the odd bug and throws an end of stream error every now and then - but that was a good year ago.

Open Chrome from command line and wait till it's closed

I'm using following code to iterate over a list of browsers executable paths and start each of them:
foreach (var browser in browsers)
{
var proc = new Process();
proc.StartInfo.FileName = browser.ExecutablePath;
proc.StartInfo.Arguments = "http://google.com";
proc.Start();
proc.WaitForExit();
Console.WriteLine(proc.ExitCode.ToString());
proc.Close();
}
What is should do is: it should open browser window with google.com loaded and stop the application until the window is closed. And it works fine for both IE and Firefox, but fails with Chrome.
For Chrome proc is in Exit state just after launching the browser, when the window is still active and visible.
I tried using some of chromium command line switches, including --new-window and --single-process but with no success.
Question is, how can I force Google Chrome to run in the process it is started in, so it would be possible to wait until window is closed?
Update
Just to clarify the question:
I know why it does not work - it's because Chrome uses multiple processes for different things, like different tabs, plug-ins, etc.
I tried to find the correct process looking on process tree, but found nothing.
I can't just take the latest process created by chrome, because it may be the process created for a pluging the page requires, not the page itself.
If you want to open/close entire Chrome window:
Chrome by default is constantly running in background because of its default settings. Change this option to unchecked:
Settings > Show advanced > System > 'Continue running background apps when Google Chrome is closed'
So you have to make sure Chrome is closed before you run it again by your code. That works for me.
If you want to open/close related tabs only:
Chrome have one 'mother process' and some child processes.
The problem is that if you run chrome using your code you are trying to create new instance of 'mother process' but the existing one won't let you do it. She'll instantly kill your new process and create her own child instead. That's how it works...
So, all you need is figure out how to run another 'chrome mother process' and prevent the previous hug from killing her ;P
I figure out this solution:
Run new chrome process with this parameter --user-data-dir="%temp%/random_name". This means that you are opening chrome with new user profile.
Advantages:
It works
Chrome is opening in new window
Chrome is closing when all related tabs are closed
Disadvantages:
Default settings (no bookmarks, etc) but you can copy them from default user profile directory
So, maybe you should look for sth in this direction...
Another command line parameter that (sort of) works is --chrome-frame. It appears Chrome uses WinInet API when in this mode, because the IE history is available. I do like more the idea about using --user-data-dir with a unique temp folder, as proposed by #DamianDrygiel.
You could find all the child processes of the Chrome process you run and then wait for them to finish.
There is a StackOverflow question that has some useful code: Find all child processes of my own .NET process / find out if a given process is a child of my own?. Also you might find this useful: Monitor child processes of a process.

How to open two separate (default) browser windows instead of new tabs

I'm trying to use C# to open two separate browser windows side by side. I've tried using Process.Start(url) but that causes Chrome to open new tabs instead of new windows. This seems to work on IE, however I'd like to have code that can work with different types of browsers, namely: IE, Chrome, Firefox, and Safari. How do I detect the default browser and then open two separate windows side-by-side? Additionally, I want to be able to position the two windows next to each other, is that possible?
If you want to open new window in chrome instead of new tab, this code worked for me
Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = "chrome";
process.StartInfo.Arguments = <yoururl> + " --new-window";
process.Start();
This is more about the way that the browser is configured than how the process is called from C#. In both cases, the system simply calls the default program assigned to handle the URL. There may or may not be arguments to that command, but typically it will simply invoke chrome.exe <url> and from there, the chrome.exe process decides how to handle the parameter.
The only method I am aware of would be to examine the registry (under HKEY_CLASSES_ROOT\http\shell\open\command) and parse the string value. Once you know the specific browser, you may be able to control the presentation using command-line arguments. Of course, this is specific to Windows and may be a pain to manage.
If the browser does not support setting a geometry from the command line, you will need to use FindWindow and SetWindowPos (using P/Invoke) to manipulate the window locations.
I am not sure about your application, but would embedding a WebBrowser Control meet your needs? Then you would have total control of the presentation.

.net console app with hyperlinks?

is it possible ? any samples/patterns or ideas on how to go about it ?
Update -
this essentially becomes a text browser which displays various tables of information based on various commands on the prompt like typing the url in a browser
now instead of typing various commands like
prompt>command arg1 arg2
if only you could say "click" on the text in a certain "column"/"row" which would execute the command say
prompt>commandX arg1
it'd be somewhat faster/easier
Now, before someone mentions doing a typical browser/asp.net mvc/whatever app, i already have that running but have encountered some limitations esp. with accesing network files. etc. Now that's taken care of using a service-broker service which reads the file etc. but having added numerous extensions to it, it'd be somewhat easier if you could just run the app as a console prompt with a mvc pattern and add extensions to it etc. etc.
if only the text is clickable, it'd make it more friendly for use !!
Assuming no mouse, I would just launch the URL as a new process based on some keyboard trigger.
// this will launch the default browser
ProcessStartInfo psi = new ProcessStartInfo("https://stackoverflow.com");
Process p = new Process(psi);
p.Start();
VB syntax:
// this will launch the default browser
Dim psi = New ProcessStartInfo("https://stackoverflow.com")
Dim p As Process = Process.Start(psi)
The window's shell doesn't support clickable hyperlinks, so no, this isn't possible.
What are you trying to do that warrants the need for hyperlinks in the command shell? Perhaps this application would be better built as a WinForms/WPF or ASP.NET application.
I don't know what a "hyperlink" is for you, but in the context of a Console Application, you can have numbers or letters that you are expecting the user to press
(imagine a simple menu with 3 options)
Press one option
1 - Open ServerFault
2 - Open StackOverflow
3 - Open SuperUser
and in the readline you have a switch that start the IExplorer process for example and opens the webpage.
Is that what you call regarding "hyperlinks in a console application"?
For an idea of what it can look like, get your hands on a copy of links. It's a text-mode web browser that works just fine in several operating systems.
you can access the mouse from the console, if you wish to have clickable elements in your console application. you'll have to build the logic yourself of course for the clickable areas.
http://cboard.cprogramming.com/windows-programming/38680-win32-console-app-mouse-input.html

Categories