Submit and vote on feature ideas.

Welcome to the new Parasoft forums! We hope you will enjoy the site and try out some of the new features, like sharing an idea you may have for one of our products or following a category.

Using Selenium with Firefox Snap (Ubuntu)

benken_parasoft
benken_parasoft Posts: 1,124 ✭✭✭

Ubuntu now provides Firefox as a Snap package. The WebDriver for Firefox (geckodriver) is not compatible out-of-box. From the release notes:

Using geckodriver to launch Firefox inside a sandbox -- for example a Firefox distribution using Snap or Flatpak -- can fail with a "Profile not found" error if the sandbox restricts Firefox's ability to access the system temporary directory. geckodriver uses the temporary directory to store Firefox profiles created during the run.

They provide a work around:

This issue can now be worked around by using the --profile-root command line option or setting the TMPDIR environment variable to a location that both Firefox and geckodriver have read/write access

How do you pass --profile-root to geckodriver from Selenium? It isn't trivial but here's one way to do it:

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.firefox.GeckoDriverService;

public final class DriverUtil {

    private DriverUtil() {
    }

    public static FirefoxDriver getFirefoxDriver() {
        FirefoxOptions options = new FirefoxOptions();
        String osName = System.getProperty("os.name");
        String profileRoot = osName.contains("Linux") && new File("/snap/firefox").exists()
                ? createProfileRootInUserHome()
                : null;
        return profileRoot != null
                ? new FirefoxDriver(createGeckoDriverService(profileRoot), options)
                : new FirefoxDriver(options);
    }

    private static String createProfileRootInUserHome() {
        String userHome = System.getProperty("user.home");
        File profileRoot = new File(userHome, "snap/firefox/common/.firefox-profile-root");
        if (!profileRoot.exists()) {
            if (!profileRoot.mkdirs()) {
                return null;
            }
        }
        return profileRoot.getAbsolutePath();
    }

    private static GeckoDriverService createGeckoDriverService(String tempProfileDir) {
        return new GeckoDriverService.Builder() {
            @Override
            protected List<String> createArgs() {
                List<String> args = new ArrayList<>(super.createArgs());
                args.add(String.format("--profile-root=%s", tempProfileDir));
                return args;
            }
        }.build();
    }
}

The above example uses "~/snap/firefox/common/.firefox-profile-root" as the profile root but you can choose some other directory under "~/snap/firefox/common/" as desired.