Does anybody know how to enable Flash plugin in Chrome 69.
I use chromedriver 2.41 with java selenium bindings.
I've tried with
prefs.put("profile.default_content_setting_values.plugins", 1);
prefs.put("profile.content_settings.plugin_whitelist.adobe-flash-player", 1);
prefs.put("profile.content_settings.exceptions.plugins.*,*.per_resource.adobe-flash-player", 1);
but with no luck.
I've also tried to compare chrome profile preferences with disallowed/allowed flash for particular site and then tried with:
Map<String, Object> site = new HashMap<>();
Map<String, Object> values = new HashMap<>();
Map<String, Object> setting = new HashMap<>();
setting.put("flashPreviouslyChanged", true);
values.put("last_modified", "13180613213099316");
values.put("setting", setting);
site.put("http://my.site,*", values);
prefs.put("profile.content_settings.exceptions.flash_data", site);
but it won't work as well.
I've also tried to run with profile specified via
options.addArguments("user-data-dir=" + profileDir);
but since this white list setting becomes 'ephemeral' in Chrome 69 it also won't work.
Is there any method to run my automation in Chrome with flash support?
Thanks everyone for answers.
I finally have found the solution. In order to enable flash progrmatically since Chrome 69 we have to do 2 things:
Disable Ephemeral Flash Permissions (to enable list of allowed for
Flash sites) and
Add all sites to that list.
See the following code on Java:
ChromeOptions options = new ChromeOptions();
// disable ephemeral flash permissions flag
options.addArguments("--disable-features=EnableEphemeralFlashPermission");
Map<String, Object> prefs = new HashMap<>();
// Enable flash for all sites for Chrome 69
prefs.put("profile.content_settings.exceptions.plugins.*,*.setting", 1);
options.setExperimentalOption("prefs", prefs);
nestedDriver = new ChromeDriver(options);
Given the flag --disable-features=EnableEphemeralFlashPermission has been removed in Chrome 71 which severely cripples Flash test automation I would like to share our solution.
public class FlashPolicyHelper {
private final ChromeDriver driver;
public FlashPolicyHelper(ChromeDriver driver) {
this.driver = driver;
}
public FlashPolicyHelper addSite(String site) {
this.driver.get("chrome://settings/content/siteDetails?site=" + site);
WebElement root1 = driver.findElement(By.tagName("settings-ui"));
WebElement shadowRoot1 = expandRootElement(root1);
WebElement root2 = shadowRoot1.findElement(getByIdentifier("id=container"));
WebElement main = root2.findElement(getByIdentifier("id=main"));
WebElement shadowRoot3 = expandRootElement(main);
WebElement shadowRoot4 = shadowRoot3.findElement(getByIdentifier("class=showing-subpage"));
WebElement shadowRoot5 = expandRootElement(shadowRoot4);
WebElement shadowRoot6 = shadowRoot5.findElement(getByIdentifier("id=advancedPage"));
WebElement shadowRoot7 = shadowRoot6.findElement(By.tagName("settings-privacy-page"));
WebElement shadowRoot8 = expandRootElement(shadowRoot7);
WebElement shadowRoot9 = shadowRoot8.findElement(getByIdentifier("id=pages"));
WebElement shadowRoot10 = shadowRoot9.findElement(By.tagName("settings-subpage"));
WebElement shadowRoot11 = shadowRoot10.findElement(By.tagName("site-details"));
WebElement shadowRoot12 = expandRootElement(shadowRoot11);
WebElement shadowRoot13 = shadowRoot12.findElement(By.id("plugins"));
WebElement shadowRoot14 = expandRootElement(shadowRoot13);
new Select(shadowRoot14.findElement(By.id("permission"))).selectByValue("allow");
return this;
}
private By getByIdentifier(String identifier) {
String[] identifiers = identifier.split("=");
return identifiers[0].equals("id") ? By.id(identifiers[1]) :
By.className(identifiers[1]);
}
private WebElement expandRootElement(WebElement element) {
return (WebElement) driver.executeScript("return arguments[0].shadowRoot",element);
}
}
The helper should be called after instantiating the ChromeDriver.
driver = new ChromeDriver(options);
new FlashPolicyHelper(driver).addSite("https://your.site").addSite("https://another.site");
Follow these steps:
Input this URL in Chrome: chrome://flags/
On search inputbox, digit: ephemeral flash
Choose "disabled" option.
This will not ask to run Flash Player for further sessions in Chrome 69.
Python3 version for Chrome 74. Converted from the Java version of #JohnoCrawford above.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
def add_flash_site(driver, web_url):
def expand_root_element(element):
return driver.execute_script("return arguments[0].shadowRoot", element)
driver.get("chrome://settings/content/siteDetails?site=" + web_url)
root1 = driver.find_element(By.TAG_NAME, "settings-ui")
shadow_root1 = expand_root_element(root1)
root2 = shadow_root1.find_element(By.ID, "container")
root3 = root2.find_element(By.ID, "main")
shadow_root3 = expand_root_element(root3)
root4 = shadow_root3.find_element(By.CLASS_NAME, "showing-subpage")
shadow_root4 = expand_root_element(root4)
root5 = shadow_root4.find_element(By.ID, "advancedPage")
root6 = root5.find_element(By.TAG_NAME, "settings-privacy-page")
shadow_root6 = expand_root_element(root6)
root7 = shadow_root6.find_element(By.ID, "pages")
root8 = root7.find_element(By.TAG_NAME, "settings-subpage")
root9 = root8.find_element(By.TAG_NAME, "site-details")
shadow_root9 = expand_root_element(root9)
root10 = shadow_root9.find_element(By.ID, "plugins")
shadow_root10 = expand_root_element(root10)
root11 = shadow_root10.find_element(By.ID, "permission")
Select(root11).select_by_value("allow")
Chrome 69 recently released does not allow sites (URLs) to be permanently added (enabled) via chrome://settings/content/flash as was the case for previous versions of Flash Player. However, a URL can be temporarily enabled for the current sesison by clicking on the lock icon to the left of the location bar, then choose Site Settings, and then enable Flash Player.
This policy forces users of Flash Player to re-configure their permission settings every session, which makes it less convenient to use Flash Player. That is apparently by design.
Fortunately, the Microsoft Edge browser does not have this policy. Like Chrome, Edge runs Flash Player. However, unlike Chrome, it persists the permission settings and does not inconvenience the user.
thanks for #JohnoCrawford, i wrote a python code by referring to his java code.
from urllib import quote_plus as url_quoteplus
from urlparse import urlsplit
from selenium.webdriver.common.by import By as WebBy
from selenium.webdriver.support.ui import Select as WebSelect
def allow_flash(driver, url):
def _base_url(url):
if url.find("://")==-1:
url = "http://{}".format(url)
urls = urlsplit(url)
return "{}://{}".format(urls.scheme, urls.netloc)
def _shadow_root(driver, element):
return driver.execute_script("return arguments[0].shadowRoot", element)
base_url = _base_url(url)
driver.get("chrome://settings/content/siteDetails?site={}".format(url_quoteplus(base_url)))
root1 = driver.find_element(WebBy.TAG_NAME, "settings-ui")
shadow_root1 = _shadow_root(driver, root1)
root2 = shadow_root1.find_element(WebBy.ID, "container")
root3 = root2.find_element(WebBy.ID, "main")
shadow_root3 = _shadow_root(driver, root3)
root4 = shadow_root3.find_element(WebBy.CLASS_NAME, "showing-subpage")
shadow_root4 = _shadow_root(driver, root4)
root5 = shadow_root4.find_element(WebBy.ID, "advancedPage")
root6 = root5.find_element(WebBy.TAG_NAME, "settings-privacy-page")
shadow_root6 = _shadow_root(driver, root6)
root7 = shadow_root6.find_element(WebBy.ID, "pages")
root8 = root7.find_element(WebBy.TAG_NAME, "settings-subpage")
root9 = root8.find_element(WebBy.TAG_NAME, "site-details")
shadow_root9 = _shadow_root(driver, root9)
root10 = shadow_root9.find_element(WebBy.ID, "plugins") # Flash
shadow_root10 = _shadow_root(driver, root10)
root11 = shadow_root10.find_element(WebBy.ID, "permission")
WebSelect(root11).select_by_value("allow")
Since I saw many methods here is not work for Chrome 71, I would like to share the solution in C# that I am using:
ChromeOptions chromeOptions = new ChromeOptions();
List<string> allowFlashUrls = new List<string>() {
"*.testing1.com",
"*.testing2.com",
};
chromeOptions.AddUserProfilePreference("profile.managed_plugins_allowed_for_urls", config.ChromeConfig.AllowFlashUrls);
ChromeDriver chromeDriver = new ChromeDriver(chromeOptions);
// Then run your test using chromeDriver
By setting profile.managed_plugins_allowed_for_urls will force Chrome the allow run Flash in the domain declare in allowFlashUrls list. Not tested but it should allow Flash to all site by adding http://* and https:// to allow Flash list.
I handled this by going into the settings for the website before I ran my test and doing selenium actions such as below:
public void SetFlashForURL (string yourWebsiteURL) {
driver.Navigate().GoToUrl(string.Format("chrome://settings/content/siteDetails?site={0}", yourWebsiteURL));
Thread.Sleep(1000);
Actions actions = new Actions(driver);
if (yourWebsiteURL.Contains("https"))
{
actions.SendKeys(OpenQA.Selenium.Keys.Tab);
actions.SendKeys(OpenQA.Selenium.Keys.Tab);
actions.SendKeys(OpenQA.Selenium.Keys.Tab);
actions.SendKeys(OpenQA.Selenium.Keys.Tab);
}
actions.SendKeys(OpenQA.Selenium.Keys.Tab);
actions.SendKeys(OpenQA.Selenium.Keys.Tab);
actions.SendKeys(OpenQA.Selenium.Keys.Tab);
actions.SendKeys(OpenQA.Selenium.Keys.Down);
actions.Build().Perform();
}
My solution for C#
var chromeOptions = new ChromeOptions();
chromeOptions.AddArgument("--disable-features=EnableEphemeralFlashPermission");
chromeOptions.AddUserProfilePreference(
"profile.content_settings.exceptions.plugins.*,*.per_resource.adobe-flash-player", 1);
var capability = (DesiredCapabilities)chromeOptions.ToCapabilities();
Using #RodolphoSilva answer with links:
1 - Input link: chrome://flags/#enable-ephemeral-flash-permission
2 - Change to "Disabled"
3 - Click "RELAUNCH NOW" button
4 - Input link: chrome://settings/content/flash?search=flash
5 - Now you can add or block sites to use flash
#RodolphoSilva - Many thanks for your great answer!
In case anyone else needs it, here's how to do the same thing in a Protractor config:
capabilities: {
browserName: 'chrome',
chromeOptions: {
args: ['--disable-features=EnableEphemeralFlashPermission'],
prefs: {
"profile.content_settings.exceptions.plugins.*,*.per_resource.adobe-flash-player": 1,
}
},
}
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-features=EnableEphemeralFlashPermission");
Map<String, Object> prefs = new HashMap<>();
prefs.put("profile.content_settings.exceptions.plugins.*,*.per_resource.adobe-flash-player",1);
options.setExperimentalOption("prefs", prefs);
WebDriver driver = new ChromeDriver(options);
driver.get("some url");
Enable flash in chromedriver using robotframework
Credits: #BaiJiFeiLong
Save following code as flash_helper.py
from robot.libraries.BuiltIn import BuiltIn
from selenium.webdriver.common.by import By as WebBy
from selenium.webdriver.support.ui import Select as WebSelect
def allow_flash(url):
seleniumlib = BuiltIn().get_library_instance('SeleniumLibrary')
driver = seleniumlib.driver
def _shadow_root(driver, element):
return driver.execute_script("return arguments[0].shadowRoot", element)
driver.get("chrome://settings/content/siteDetails?site={}".format(url))
root1 = driver.find_element(WebBy.TAG_NAME, "settings-ui")
shadow_root1 = _shadow_root(driver, root1)
root2 = shadow_root1.find_element(WebBy.ID, "container")
root3 = root2.find_element(WebBy.ID, "main")
shadow_root3 = _shadow_root(driver, root3)
root4 = shadow_root3.find_element(WebBy.CLASS_NAME, "showing-subpage")
shadow_root4 = _shadow_root(driver, root4)
root5 = shadow_root4.find_element(WebBy.ID, "advancedPage")
root6 = root5.find_element(WebBy.TAG_NAME, "settings-privacy-page")
shadow_root6 = _shadow_root(driver, root6)
root7 = shadow_root6.find_element(WebBy.ID, "pages")
root8 = root7.find_element(WebBy.TAG_NAME, "settings-subpage")
root9 = root8.find_element(WebBy.TAG_NAME, "site-details")
shadow_root9 = _shadow_root(driver, root9)
root10 = shadow_root9.find_element(WebBy.ID, "plugins") # Flash
shadow_root10 = _shadow_root(driver, root10)
root11 = shadow_root10.find_element(WebBy.ID, "permission")
WebSelect(root11).select_by_value("allow")
Use above method as keyword in robotframework
save following code as test.robot
*** Settings ***
Library SeleniumLibrary
Library flash_helper.py
*** Test Case ***
Allow Flash In Chrome
Open Browser https://www.google.com chrome
# go to chrome settings and enable flash
${CURRENT_URL} Get Location
Allow Flash ${CURRENT_URL}
# revert to previous page
Go To ${CURRENT_URL}
# now Flash is enabled in chrome!!
Since EnableEphemeralFlashPermission can no longer be disabled in Chrome 71+ versions, here's a slightly modified version of #JohnoCrawford code that works for Chrome 81:
def add_flash_site(driver, web_url):
def expand_root_element(element):
return driver.execute_script("return arguments[0].shadowRoot", element)
driver.get("chrome://settings/content/siteDetails?site=" + web_url)
root1 = driver.find_element(By.TAG_NAME, "settings-ui")
shadow_root1 = expand_root_element(root1)
root2 = shadow_root1.find_element(By.ID, "container")
root3 = root2.find_element(By.ID, "main")
shadow_root3 = expand_root_element(root3)
root4 = shadow_root3.find_element(By.CLASS_NAME, "showing-subpage")
shadow_root4 = expand_root_element(root4)
root5 = shadow_root4.find_element(By.TAG_NAME, "settings-privacy-page")
shadow_root5 = expand_root_element(root5)
root6 = shadow_root5.find_element(By.ID, "pages")
root7 = root6.find_element(By.TAG_NAME, "settings-subpage")
root8 = root7.find_element(By.TAG_NAME, "site-details")
shadow_root8 = expand_root_element(root8)
root9 = shadow_root8.find_element(By.ID, "plugins")
shadow_root9 = expand_root_element(root9)
root10 = shadow_root9.find_element(By.ID, "permission")
Select(root10).select_by_value("allow")
I have the same answer as user BaiJiFeiLong
but i found that I had to change the line:
root5 = shadow_root4.find_element(By.ID, "advancedPage")
to:
root5 = shadow_root4.find_element(By.ID, "basicPage")
Because the original line was returning NoSuchElement error.
This is the code I am using to start Firefox via Selenium Webdriver (Java):
private FirefoxDriver getfox(String pr) {
String geckoPath = "/opt/driver";
String browserPath = "/opt/browser";
String h = pr.split(":")[0];
String p = pr.split(":")[1];
System.setProperty("webdriver.firefox.marionette", geckoPath);
FirefoxProfile fp;
fp = new FirefoxProfile();
System.out.println("setting proxy " + h + ", port " + p);
fp.setPreference("network.proxy.http", h);
fp.setPreference("network.proxy.http_port", p);
FirefoxOptions fo = new FirefoxOptions();
fo.setProfile(fp);
fo.setBinary(browserPath);
FirefoxDriver driver = new FirefoxDriver(fo);
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
driver.manage().timeouts().pageLoadTimeout(30,TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(30,TimeUnit.SECONDS);
return driver;
}
However, when I enter about:config in the started browser and check the settings then only the proxy host has been changed. The http_port is set to 0. When I check my IP by navigating, e.g.,
Webdriver driver = getfox("host.proxy.server:port");
String address = "https://www.find-ip.net";
//String address = "http://www.find-ip.net";
System.out.println("navigating to " + address);
driver.get(address);
System.out.println("searching elements");
String selector = ("div.ipcontent.pure-u-13-24");
List<WebElement> elems = driver.findElements(By.cssSelector(selector));
for (WebElement w : elems) {
System.out.println(w.getText());
}
to http(s)://www.find-ip.net then I see my real IP address. The values I am passing are correct. I have no problem setting that proxy in HtmlUnit driver.
The versions involved are:
Selenium 3.6.0
Firefox 45.9.0
geckodriver 19.0
Is there anything I need to change?
With geckodriver v0.19.0 is recommended to use Firefox 55.0 (and greater).
Update your browser and re-try.
I would like to get the PID of the browser launched by selenium. Is there any way to get it done?
Using the Python API, it's pretty simple:
from selenium import webdriver
browser = webdriver.Firefox()
print browser.binary.process.pid
# browser.binary.process is a Popen object...
If you're using Chrome, it's a little more complex, you go via a chromedriver process:
c = webdriver.Chrome()
c.service.process # is a Popen instance for the chromedriver process
import psutil
p = psutil.Process(c.service.process.pid)
print p.get_children(recursive=True)
hwjp's solution isn't working anymore for me, but the solution from ABM is working for other browsers too in case anyone is wondering, so for firefox as of now:
from selenium import webdriver
driver = webdriver.Firefox()
print(driver.service.process.pid)
can't comment because of reputation, so I'm submitting this as separate answer...
If you're using PhantomJS then you can get the PID from the process Popen object:
from selenium import webdriver
browser = webdriver.PhantomJS()
print browser.service.process.pid
In Java, if you use ChromeDriver, you can find the port that the driver will use
port = chromeDriverService.getUrl().getPort();
and then, using the port, you can find the chromedriver process id by running the command
netstat -anp | grep LISTEN | grep [port] (on linux)
or
netstat -aon | findstr LISTENING | findstr [port] (on windows)
You can go further, to find out the chrome process id, by using the chromedriver process id (parent id of the chrome process)
ps -efj | grep google-chrome | grep [chromedriverprocessid] (on linux)
or
wmic process get processid,parentprocessid,executablepath | find \"chrome.exe\" |find \"chromeDriverProcessID\"
the code looks like this:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import org.apache.commons.lang.SystemUtils;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
public class WebdriverProcessID
{
public static void main(String[] args) throws IOException, InterruptedException
{
ChromeDriver driver = null;
ChromeOptions options = new ChromeOptions();
List<String> listArguments = new ArrayList<String>();
DesiredCapabilities cap = DesiredCapabilities.chrome();
cap.setCapability(ChromeOptions.CAPABILITY, options);
LoggingPreferences logPrefs = new LoggingPreferences();
logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
cap.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
ChromeDriverService chromeDriverService = ChromeDriverService.createDefaultService();
int port = chromeDriverService.getUrl().getPort();
driver = new ChromeDriver(chromeDriverService, cap);
System.out.println("starting chromedriver on port " + port);
int chromeDriverProcessID = GetChromeDriverProcessID(port);
System.out.println("detected chromedriver process id " + chromeDriverProcessID);
System.out.println("detected chrome process id " + GetChromeProcesID(chromeDriverProcessID));
driver.navigate().to("https://www.test.com/");
try
{
Thread.sleep(100000);
}
catch (InterruptedException e)
{
}
try
{
driver.close();
}
catch (WebDriverException ex)
{
ex.printStackTrace();
}
try
{
driver.quit();
}
catch (WebDriverException ex)
{
ex.printStackTrace();
}
}
private static int GetChromeDriverProcessID(int aPort) throws IOException, InterruptedException
{
String[] commandArray = new String[3];
if (SystemUtils.IS_OS_LINUX)
{
commandArray[0] = "/bin/sh";
commandArray[1] = "-c";
commandArray[2] = "netstat -anp | grep LISTEN | grep " + aPort;
}
else if (SystemUtils.IS_OS_WINDOWS)
{
commandArray[0] = "cmd";
commandArray[1] = "/c";
commandArray[2] = "netstat -aon | findstr LISTENING | findstr " + aPort;
}
else
{
System.out.println("platform not supported");
System.exit(-1);
}
System.out.println("running command " + commandArray[2]);
Process p = Runtime.getRuntime().exec(commandArray);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
String result = sb.toString().trim();
System.out.println("parse command response line:");
System.out.println(result);
return SystemUtils.IS_OS_LINUX ? ParseChromeDriverLinux(result) : ParseChromeDriverWindows(result);
}
private static int GetChromeProcesID(int chromeDriverProcessID) throws IOException, InterruptedException
{
String[] commandArray = new String[3];
if (SystemUtils.IS_OS_LINUX)
{
commandArray[0] = "/bin/sh";
commandArray[1] = "-c";
commandArray[2] = "ps -efj | grep google-chrome | grep " + chromeDriverProcessID;
}
else if (SystemUtils.IS_OS_WINDOWS)
{
commandArray[0] = "cmd";
commandArray[1] = "/c";
commandArray[2] = "wmic process get processid,parentprocessid,executablepath | find \"chrome.exe\" |find \"" + chromeDriverProcessID + "\"";
}
else
{
System.out.println("platform not supported");
System.exit(-1);
}
System.out.println("running command " + commandArray[2]);
Process p = Runtime.getRuntime().exec(commandArray);
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null)
{
if (SystemUtils.IS_OS_LINUX && line.contains("/bin/sh"))
{
continue;
}
sb.append(line + "\n");
}
String result = sb.toString().trim();
System.out.println("parse command response line:");
System.out.println(result);
return SystemUtils.IS_OS_LINUX ? ParseChromeLinux(result) : ParseChromeWindows(result);
}
private static int ParseChromeLinux(String result)
{
String[] pieces = result.split("\\s+");
// root 20780 20772 20759 15980 9 11:04 pts/1 00:00:00 /opt/google/chrome/google-chrome.........
// the second one is the chrome process id
return Integer.parseInt(pieces[1]);
}
private static int ParseChromeWindows(String result)
{
String[] pieces = result.split("\\s+");
// C:\Program Files (x86)\Google\Chrome\Application\chrome.exe 14304 19960
return Integer.parseInt(pieces[pieces.length - 1]);
}
private static int ParseChromeDriverLinux(String netstatResult)
{
String[] pieces = netstatResult.split("\\s+");
String last = pieces[pieces.length - 1];
// tcp 0 0 127.0.0.1:2391 0.0.0.0:* LISTEN 3333/chromedriver
return Integer.parseInt(last.substring(0, last.indexOf('/')));
}
private static int ParseChromeDriverWindows(String netstatResult)
{
String[] pieces = netstatResult.split("\\s+");
// TCP 127.0.0.1:26599 0.0.0.0:0 LISTENING 22828
return Integer.parseInt(pieces[pieces.length - 1]);
}
}
the output will be, on linux:
starting chromedriver on port 17132
running command netstat -anp | grep LISTEN | grep 17132
parse command response line:
tcp 0 0 127.0.0.1:17132 0.0.0.0:* LISTEN 22197/chromedriver
detected chromedriver process id 22197
running command ps -efj | grep google-chrome | grep 22197
parse command response line:
root 22204 22197 22183 15980 26 11:17 pts/1 00:00:00 /opt/google/chrome/google-chrome ...
detected chrome process id 22204
and on windows:
starting chromedriver on port 34231
running command netstat -aon | findstr LISTENING | findstr 34231
parse command response line:
TCP 127.0.0.1:34231 0.0.0.0:0 LISTENING 10692
detected chromedriver process id 10692
running command wmic process get "processid,parentprocessid,executablepath" | findstr "chrome.exe" | findstr "10692"
parse command response line:
C:\Program Files (x86)\Google\Chrome\Application\chrome.exe 10692 12264
detected chrome process id 12264
You can retrieve the PID of Browser Process launched by Selenium using python client in different ways as follows:
Firefox
Accessing the capabilities object which returns a dictionary using the following solution:
Code Block:
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
options = Options()
options.binary_location = r'C:\Program Files\Firefox Nightly\firefox.exe'
driver = webdriver.Firefox(firefox_options=options, executable_path=r'C:\WebDrivers\geckodriver.exe')
my_dict = driver.capabilities
print("PID of the browser process is: " + str(my_dict['moz:processID']))
Console Output:
PID of the browser process is: 14240
Browser Snapshot:
Chrome
Iterating through the processes using psutil.process_iter() where process.cmdline() contains --test-type=webdriver as follows:
Code Block:
from selenium import webdriver
from contextlib import suppress
import psutil
driver = webdriver.Chrome(executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
driver.get('https://www.google.com/')
for process in psutil.process_iter():
if process.name() == 'chrome.exe' and '--test-type=webdriver' in process.cmdline():
with suppress(psutil.NoSuchProcess):
print(process.pid)
Console Output:
1164
1724
4380
5748
Browser Snapshot:
This is an example you can use for C# and Selenium. There would be the same implementation for other languages (like Java) but I am only working in C#.
Chrome allows you to supply your own user-defined command-line arguments. So you can add an argument named "scriptpid-" with the PID (Windows Process ID) of your currently running program. ChromeDriver passes your argument to Chrome in the command-line. Then using Windows WMI calls retrieve this PID from the command-line of the running Chrome ...
public static IntPtr CurrentBrowserHwnd = IntPtr.Zero;
public static int CurrentBrowserPID = -1;
ChromeOptions options = new ChromeOptions();
options.AddArgument("scriptpid-" + System.Diagnostics.Process.GetCurrentProcess().Id);
IWebDriver driver = new ChromeDriver(options);
// Get the PID and HWND details for a chrome browser
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("chrome");
for (int p = 0; p < processes.Length; p++)
{
ManagementObjectSearcher commandLineSearcher = new ManagementObjectSearcher("SELECT CommandLine FROM Win32_Process WHERE ProcessId = " + processes[p].Id);
String commandLine = "";
foreach (ManagementObject commandLineObject in commandLineSearcher.Get())
{
commandLine += (String)commandLineObject["CommandLine"];
}
String script_pid_str = (new Regex("--scriptpid-(.+?) ")).Match(commandLine).Groups[1].Value;
if (!script_pid_str.Equals("") && Convert.ToInt32(script_pid_str).Equals(System.Diagnostics.Process.GetCurrentProcess().Id))
{
CurrentBrowserPID = processes[p].Id;
CurrentBrowserHwnd = processes[p].MainWindowHandle;
break;
}
}
CurrentBrowserHwnd should contain the HWND of your Chrome window.
CurrentBrowserPID should contain the Process ID of your Chrome window.
If you are using java and selenium, you can simply first find the PID of the JVM and then through its child processes, you can get the PID of chromedriver and then similarly PID of chrome. Here is an example to find the PID of chromedriver.
final String jvmName = ManagementFactory.getRuntimeMXBean().getName();
final int index = jvmName.indexOf('#');
if(index > 1) {
try {
String processId = Long.toString(Long.parseLong(jvmName.substring(0, index)));
Scanner scan = new Scanner(Runtime.getRuntime().exec("wmic process where (ParentProcessId="+ processId +") get Caption,ProcessId").getInputStream());
scan.useDelimiter("\\A");
String childProcessIds = scan.hasNext() ? scan.next() : "";
List<String> chromeDrivers = new ArrayList<String>();
String[] splited = childProcessIds.split("\\s+");
for(int i =0 ; i<splited.length; i = i+2){
if("chromedriver.exe".equalsIgnoreCase(splited[i])){
chromeDrivers.add(splited[i+1]);
}
}
/*
*
*Do whatever you want to do with the chromedriver's PID here
*
* */
scan.close();
} catch (Exception e) {
}
}
I solved it this way:
I am on a Linux OS using Python to detect Firefox memory usage:
import psutil
# Get pid of geckodriver
webdriver_pid = driver.service.process.pid
# Get the process of geckodriver
process = psutil.Process(webdriver_pid)
# Get memory of geckodriver + firefox
# Since memory is in bytes divide by 1024*1024 to obtain result in MB
total_memory = sum([x.memory_info().rss/1048576 for x in process.children() + [process]])
for the guys comming here to find a solution, here it is, hope it will help you out.
protected Integer getFirefoxPid(FirefoxBinary binary){
try {
final Field fieldCmdProcess = FirefoxBinary.class.getDeclaredField("process");
fieldCmdProcess.setAccessible(true);
final Object ObjCmdProcess = fieldCmdProcess.get(binary);
final Field fieldInnerProcess = ObjCmdProcess.getClass().getDeclaredField("process");
fieldInnerProcess.setAccessible(true);
final Object objInnerProcess = fieldInnerProcess.get(ObjCmdProcess);
final Field fieldWatchDog = objInnerProcess.getClass().getDeclaredField("executeWatchdog");
fieldWatchDog.setAccessible(true);
final Object objWatchDog = fieldWatchDog.get(objInnerProcess);
final Field fieldReelProcess = objWatchDog.getClass().getDeclaredField("process");
fieldReelProcess.setAccessible(true);
final Process process = (Process) fieldReelProcess.get(objWatchDog);
final Integer pid;
if (Platform.getCurrent().is(WINDOWS)) {
final Field f = process.getClass().getDeclaredField("handle");
f.setAccessible(true);
long hndl = f.getLong(process);
final Kernel32 kernel = Kernel32.INSTANCE;
final WinNT.HANDLE handle = new WinNT.HANDLE();
handle.setPointer(Pointer.createConstant(hndl));
pid = kernel.GetProcessId(handle);
} else {
final Field f = process.getClass().getDeclaredField("pid");
f.setAccessible(true);
pid = (Integer) f.get(process);
}
logger.info("firefox process id : " + pid + " on plateform : " + Platform.getCurrent());
return pid;
} catch (Exception e) {
e.printStackTrace();
logger.error("Cannot get firefox process id, exception is : {}", e);
}
return null;
}
#Sean Griffin's answer is great.
One thing - better to filter the list of chrome processes by the ones that started in the last 5 (or so ) minutes, like this:
System.Diagnostics.Process[] processesInLast5Min = processes.Where(p => DateTime.Now.Subtract(p.StartTime) <= TimeSpan.FromMinutes(5) ).ToArray();