2021-12-18 Automatically starting Firefox with a clean profile

I am currently working on a side project, which is a very specific web application. One of the requirements is that several users should be able to be logged in simultaneously and interact with each other in real time. For the “real time” part, I use websockets (with the Socket.IO library, which is quite nice to work with). Today, however, I wanted to say something about a different thing: testing. Not automated testing (I will probably blog about it later, too), but good old manual testing. The trouble is, how do I log in as two (or more) users at the same time? I can’t use separate browser tabs, since they share cookies and logging in or out in one of them logs me in or out in all of them. It turns out that if you open several “private browsing” windows in Firefox, they all share cookies and similar data, too – that wasn’t obvious for me, but this is how it works. I could use separate browsers (say, Firefox and Chromium), but that is far from comfortable – and obviously scales very poorly.

Of course, Firefox profiles are exactly what is needed here. They have one drawback: it takes a lot of clicking to create a new profile. (Also, you have to name it, keep track of your profiles, delete the ones you don’t need anymore…)

So, let’s script it. Before I start, please note that this is not an “official” solution, I came up with it by some trial and error, and it might not work 100% correctly, stop working at any point in time etc.

The key ingredients of my solution are the --profile option, which starts Firefox with the given profile, and the fact that profiles are basically just directories where Firefox keeps profile-related data (or so it seems at least). So, here is my script which runs Firefox (developer edition, to be precise) with a pristine profile, and deletes that profile on exit:

#!/bin/sh
PROFILE=$(mktemp -d)
firefox-developer-edition --profile "$PROFILE"
rm -rf "$PROFILE"

Note that this wouldn’t work if the profile directory were not created first (hence mkdir) and that removing that directory with rm -rf seems enough to tell Firefox that the profile doesn’t exist anymore.

Now it would be way cooler if I could also install add-ons via command line. (In fact, this was my initial plan, to install React Dev Tools, too.) Unfortunately, it seems that installing an add-on fully automatically is either impossible or hard enough I didn’t manage to find out how to do it. Happily, it can be done almost automatically. You just need to download the xpi file with the extension manually and give it as a command-line parameter to Firefox:

#!/bin/sh
REACT_DEV_TOOLS=/path/react_developer_tools-4.21.0-fx.xpi
PROFILE=$(mktemp -d)
firefox-developer-edition --profile "$PROFILE" "$REACT_DEV_TOOLS"
rm -rf "$PROFILE"

With this script, you’ll need two more clicks: one to accept the add-on, and another to confirm that you are aware that it was added. Sigh. Also, there will be a new, empty tab corresponding to the "$REACT_DEV_TOOLS" parameter. Yes, you guessed it: you can add more add-ons this way, but for every one of them you’ll need to click two buttons in a dedicated tab (which you’ll have to activate manually). Also, every time Firefox with a fresh profile is started, you’ll be shown the Firefox privacy note in another separate tab. This is insane…

Don’t get me wrong, it’s kind of cool that you can install extensions (almost) automatically from command-line. (And from what I’ve read on the internet, you can actually do this fully automatically, even without those two clicks, using something called Firefox ESR. I’ll probably study that one day, too. Also, there is web-ext, which is a command-line tool designed to help with developing extensions, and apparently it can run Firefox with some add-on installed.) OTOH, it’s a bit annoying that you can’t just drive Firefox fully from command-line, including things like closing tabs (apparently, you can open a new tab by just saying firefox <url>), listing tabs etc. Some time ago, I played a bit with Puppeteer, which probably allows for all these things (and perhaps more), but I suspect it’s not possible to start Chromium with Puppeteer and then switch it to a normal manual operation. Anyway, at least for now I’ll have to live with my slightly half-baked solution – still, it’s much better than nothing.

CategoryEnglish, CategoryBlog