Automating installers in .dmg files on macOS

Last edited on

To automate an installer contained in a .dmg file the .dmg file must first be mounted, which can be achieved by using macOS’s open command line tool.

Here is an example that demonstrates mounting a .dmg file and starting the contained installer:

import os.path
import subprocess

# Adjust the following to your setup/needs:

# In or relative to test suite folder:
#dmg_file_path = squishinfo.testCase + "/.."
# In or relative to current user's downloads folder:
dmg_file_path = os.path.expanduser("~/Downloads")

dmg_file_name = "squish-6.3.1-mac.dmg"
installer_file_path = "/Volumes/froglogic Squish"
installer_file_name = "Install Squish"

def openDmg():
    test.startSection("Open/mount .dmg file")
    args = ["open", os.path.join(dmg_file_path, dmg_file_name)]
    test.log("Executing: %s" % args)

    try:
        output = subprocess.check_output(args)
    except subprocess.CalledProcessError:
        test.fatal("Opening/mounting failed:")
        test.fatal("File: %s" % os.path.join(dmg_file_path, dmg_file_name))
        test.fatal("Output: %s" % output)
        return False
    finally:
        test.endSection()
    return True

def registerInstallerAsAUT():
    test.startSection("Register installer as AUT")
    args = [os.path.join(os.getenv("SQUISH_PREFIX"), "bin", "squishserver"), "--config", "addAUT", installer_file_name, installer_file_path]
    test.log("Executing: %s" % args)

    try:
        output = subprocess.check_output(args)
    except subprocess.CalledProcessError:
        test.fatal("Registering installer as AUT failed:")
        test.fatal("Output: %s" % output)
        return False
    finally:
        test.endSection()
    return True

def closeDmg():
    test.startSection("Close/unmount .dmg file")
    args = ["umount", installer_file_path]
    test.log("Executing: %s" % args)

    try:
        output = subprocess.check_output(args)
    except subprocess.CalledProcessError:
        test.fatal("Closing/unmounting failed:")
        test.fatal("File: %s" % os.path.join(dmg_file_path, dmg_file_name))
        test.fatal("Output: %s" % output)
        return False
    finally:
        test.endSection()
    return True

def main():
    if not openDmg():
        return
    if not registerInstallerAsAUT():
        return

    # Start running the installer as the AUT from here
    test.startSection("Start installer as AUT")
    try:
        startApplication('"%s"' % installer_file_name)
    finally:
        test.endSection()

    # Set breakpoint on the next line, execute to it, start
    # recording a snippet (Run > Record Snippet):
    snooze(1)

    closeDmg()
test.py

What about .pkg based installers?

.pkg files are not executable, and they are handled by a system application called Installer.app. Hooking this application via Squish is not currently possible, so Squish can not be used to automate the installation of apps that are packaged in this way.