I never considered myself as a web frontend developer, cause I usually prefer doing more system stuff, but time over time I do it, and occasionally I have to target old browsers, and so I have to test using these browsers. While there are services like SauceLabs and BrowserStack that offer you cloud-backed web browser testing, often testing and debugging using these services are slow. They are fine as quality gate used in CI, but using them continuously slows down development. Running tests and debugging in browser locally is much faster.

So let’s start with Firefox, because it’s the easiest case. All Firefox releases are published in an archive. But just installing every single version that you need to support isn’t going to work for you on Linux, at least this wasn’t the case for me. Because all these versions of browsers use the same paths for storing user profile data. You obviously can try to separate them by using different environment variables for profiles and other settings. Also, you probably would have to disable the remote interface via -no-remote CLI option, which disables the listening socket that accepts commands. This is used as a way to speed up browser launching, since the browser stays loaded even when you close all pages, and when you click to open something it receives a remote command. But since we are going to run multiple versions they would bind to the same socket which would cause a conflict. There are also a number of other issues as well.

So, is there is any better way ? Yeah, let’s use lightweight containers for this. I often use bwrap aka bubblewrap for this kind of issues. Here’s an example that I use as a launcher for Firefox 38:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/bin/sh
/usr/bin/bwrap \
    --ro-bind /bin /bin \
    --ro-bind /lib /lib \
    --ro-bind /lib64 /lib64 \
    --ro-bind /usr/bin /usr/bin \
    --ro-bind /usr/lib /usr/lib \
    --ro-bind /usr/lib64 /usr/lib64 \
    --ro-bind /usr/libexec /usr/libexec \
    --ro-bind /usr/share /usr/share \
    --ro-bind /etc /etc \
    --tmpfs /home \
    --tmpfs /run \
    --tmpfs /opt \
    --tmpfs /tmp \
    --bind /var/tmp /var/tmp \
    --dev-bind /dev /dev \
    --proc /proc \
    --bind /sys /sys \
    --tmpfs $HOME \
    --ro-bind $HOME/.Xauthority $HOME/.Xauthority \
    --bind $HOME/.nv/ $HOME/.nv/ \
    --ro-bind $HOME/.nvidia-settings-rc  $HOME/.nvidia-settings-rc \
    --ro-bind /tmp/.X11-unix/ /tmp/.X11-unix/ \
    --bind $HOME/.config/pulse/ $HOME/.config/pulse/ \
    --bind /run/user/ /run/user/ \
    --bind $HOME/.local/oldbrowsers/ $HOME/oldbrowsers/ \
    --unshare-all --share-net \
    --chdir $HOME/ \
      "$HOME/oldbrowsers/firefox-38/firefox-bin"

This should be pretty self-explanatory, but I’ll comment on few details. $HOME is mounted as tmpfs, so when the bwrap process dies, it will be unmounted, and all data that were stored in this folder will disappear. Which is exactly what I wanted for testing. Furthermore, as you can see, this isn’t a fully isolated container. It shares all system folders with your system, mostly in a read-only mode, so it takes just a minimal amount of disk space.

With the Chrome browser, things get a little bit harder because there is no official release archive for it. But you should know that Chrome is based on Chromium, which is open-source and has public CI with results of every build. But usually you can easily find a super new experimental builds, not an old outdated build. Luckily someone made a tool that could simplify that. Basically it helps you find the correct git commit for a particular release of interest and build artifacts. In addition, someone generated a list of artifacts for a large amount of different versions. And there is another website with a simpler UI, where you can get links to official build artifacts, but it has fewer releases. And with Chromium you can use the same trick with bwrap (in some cases you might require using --no-sandbox options).

Now what about testing in IE 11 and Microsoft Edge ? It’s been surprising for me to discover that Microsoft actually has testing VMs on their website that is intended exactly for this purpose absolutely for free. These VMs will expire after 90 days, but you can make a snapshot, and use them as long as you want. Moreover, these VMs could be used also for application testing as well, for example, you could compile an app on Linux via MinGW and test the generated executable in these VMs.

Now we are left with only one major browser left, Safari. So what about it ? Unfortunately, I don’t know any way to run it under Linux, so your only available options is use a physical device (Apple device) or use some remote service like macincloud. Well, strictly speaking, you can still run it in VM under Linux (but shh, I didn’t told you that).

Update: As of 2025, Microsoft changed the link for testing VM and now even disabled it. They also released a Linux version of the Microsoft Edge browser.

There were changes in Chromium build links as well. Now builds are hosted here.