Esempio n. 1
0
    def main(self, argv=None):
        global tmp_dir

        logger.debug('Command arguments: %s' % self.args)

        cleanup.init()
        Iris.fix_terminal_encoding()
        tmp_dir = self.__create_tempdir()

        # Create workdir (usually ~/.iris, used for caching etc.)
        # Assumes that no previous code will write to it.
        if not os.path.exists(self.args.workdir):
            logger.debug('Creating working directory %s' % self.args.workdir)
            os.makedirs(self.args.workdir)

        if self.args.firefox == 'local':
            # Use default Firefox installation
            logger.info('Running with default installed Firefox build')
            if Settings.getOS() == Platform.MAC:
                self.fx_app = self.get_test_candidate('/Applications/Firefox.app/Contents')
            elif Settings.getOS() == Platform.WINDOWS:
                if os.path.exists('C:\\Program Files (x86)\\Mozilla Firefox'):
                    self.fx_app = self.get_test_candidate('C:\\Program Files (x86)\\Mozilla Firefox')
                else:
                    self.fx_app = self.get_test_candidate('C:\\Program Files\\Mozilla Firefox')
            else:
                self.fx_app = self.get_test_candidate('/usr/lib/firefox')
        else:
            self.fx_app = self.get_test_candidate(self.args.firefox)

        self.fx_path = self.fx_app.exe
        self.version = self.fx_app.version
        self.build_id = self.fx_app.build_id

        return 0
Esempio n. 2
0
    def init_tesseract_path(self):

        which_tesseract = \
            subprocess.Popen('which tesseract', stdout=subprocess.PIPE, shell=True).communicate()[0].rstrip()

        path_not_found = False
        current_os = Settings.get_os()

        if current_os == Platform.WINDOWS:
            win_default_tesseract_path = 'C:\\Program Files (x86)\\Tesseract-OCR'

            if '/c/' in str(which_tesseract):
                win_which_tesseract_path = which_tesseract.replace('/c/', 'C:\\').replace('/', '\\') + '.exe'
            else:
                win_which_tesseract_path = which_tesseract.replace('\\', '\\\\')

            if self.check_tesseract_path(win_default_tesseract_path):
                pytesseract.pytesseract.tesseract_cmd = win_default_tesseract_path + '\\tesseract'
            elif self.check_tesseract_path(win_which_tesseract_path):
                pytesseract.pytesseract.tesseract_cmd = win_which_tesseract_path
            else:
                path_not_found = True

        elif current_os == Platform.LINUX or current_os == Platform.MAC:
            if self.check_tesseract_path(which_tesseract):
                pytesseract.pytesseract.tesseract_cmd = which_tesseract
            else:
                path_not_found = True
        else:
            path_not_found = True

        if path_not_found:
            logger.critical('Unable to find Tesseract.')
            logger.critical('Please consult wiki for complete setup instructions.')
            self.finish(1)
Esempio n. 3
0
    def init_tesseract_path(self):

        win_tesseract_path = 'C:\\Program Files (x86)\\Tesseract-OCR'
        osx_linux_tesseract_path_1 = '/usr/local/bin/tesseract'
        osx_linux_tesseract_path_2 = '/usr/bin/tesseract'

        path_not_found = False
        current_os = Settings.getOS()

        if current_os == Platform.WINDOWS:
            if self.check_tesseract_path(win_tesseract_path):
                pytesseract.pytesseract.tesseract_cmd = win_tesseract_path + '\\tesseract'
            else:
                path_not_found = True
        elif current_os == Platform.LINUX or current_os == Platform.MAC:
            if self.check_tesseract_path(osx_linux_tesseract_path_1):
                pytesseract.pytesseract.tesseract_cmd = osx_linux_tesseract_path_1
            elif self.check_tesseract_path(osx_linux_tesseract_path_2):
                pytesseract.pytesseract.tesseract_cmd = osx_linux_tesseract_path_2
            else:
                path_not_found = True
        else:
            path_not_found = True

        if path_not_found:
            logger.critical('Unable to find Tesseract.')
            logger.critical('Please consult wiki for complete setup instructions.')
            self.finish(1)
Esempio n. 4
0
 def check_keyboard_state(self):
     is_lock_on = False
     if Settings.get_os() != Platform.MAC:
         if Key.is_lock_on(Key.CAPS_LOCK):
             logger.error('Cannot run Iris because Key.CAPS_LOCK is on. Please turn it off to continue.')
             is_lock_on = True
         if Key.is_lock_on(Key.NUM_LOCK):
             logger.error('Cannot run Iris because Key.NUM_LOCK is on. Please turn it off to continue.')
             is_lock_on = True
         if Key.is_lock_on(Key.SCROLL_LOCK):
             logger.error('Cannot run Iris because Key.SCROLL_LOCK is on. Please turn it off to continue.')
             is_lock_on = True
     else:
         try:
             cmd = subprocess.Popen('xset q', shell=True, stdout=subprocess.PIPE)
         except subprocess.CalledProcessError as e:
             logger.error('Command failed: %s' % repr(e.cmd))
             raise Exception('Unable to run command')
         else:
             keys = ['Caps', 'Num', 'Scroll']
             locked = None
             for line in cmd.stdout:
                 for key in keys:
                     if key in line:
                         value = ' '.join(line.split())
                         if key in value[0:len(value) / 3]:
                             button = value[0:len(value) / 3]
                             if "off" in button:
                                 is_lock_on = False
                             else:
                                 is_lock_on = True
                                 locked = key
                                 break
                         elif key in value[len(value) / 3:len(value) / 3 + len(value) / 3]:
                             button = value[len(value) / 3:len(value) / 3 + len(value) / 3]
                             if "off" in button:
                                 is_lock_on = False
                             else:
                                 is_lock_on = True
                                 locked = key
                                 break
                         else:
                             button = value[len(value) / 3 * 2:len(value)]
                             if "off" in button:
                                 is_lock_on = False
                             else:
                                 is_lock_on = True
                                 locked = key
                                 break
                 if is_lock_on:
                     logger.error('Cannot run Iris because Key.%s_LOCK is toggled.' % locked.upper())
                     logger.error('Please turn it off to continue.')
                     break
             IrisCore.shutdown_process('Xquartz')
     if is_lock_on:
         self.finish(code=1)
Esempio n. 5
0
 def at_exit():
     if hasattr(Iris, 'process_list'):
         logger.debug('There are %s queued process(es) to terminate.' % len(Iris.process_list))
         for process in Iris.process_list:
             logger.debug('Terminating process.')
             process.terminate()
             process.join()
     if Settings.is_mac():
         # Extra call to shutdown the program we use to check keyboard lock,
         # in case Iris was terminated abruptly.
         IrisCore.shutdown_process('Xquartz')
Esempio n. 6
0
 def initialize_platform(self):
     self.args = parse_args()
     self.module_dir = IrisCore.get_module_dir()
     self.platform = get_platform()
     self.os = Settings.get_os()
     self.create_working_directory()
     self.create_run_directory()
     initialize_logger(LOG_FILENAME, self.args.level)
     IrisCore.create_profile_cache()
     Iris.process_list = []
     self.local_web_root = os.path.join(self.module_dir, 'iris', 'local_web')
     self.base_local_web_url = 'http://127.0.0.1:%s' % self.args.port
     self.create_test_json()
     self.create_arg_json()
     self.test_list = []
     self.test_packages = []
Esempio n. 7
0
 def __init__(self):
     self.args = parse_args()
     initialize_logger(LOG_FILENAME, self.args.level)
     self.process_list = []
     self.check_keyboard_state()
     self.init_tesseract_path()
     self.check_7zip()
     self.module_dir = get_module_dir()
     self.platform = get_platform()
     self.os = Settings.getOS()
     self.local_web_root = os.path.join(self.module_dir, 'iris', 'local_web')
     self.base_local_web_url = 'http://127.0.0.1:%s' % self.args.port
     self.start_local_web_server(self.local_web_root, self.args.port)
     self.main()
     self.create_run_directory()
     run(self)
Esempio n. 8
0
    def get_test_candidate(self):
        """Download and extract a build candidate.

        Build may either refer to a Firefox release identifier, package, or build directory.
        :param:
            build: str with firefox build
        :return:
            Installation path for the Firefox App
        """

        location = ''
        candidate_app = ''

        if self.args.firefox == 'local':
            if Settings.is_mac():
                location = '/Applications/Firefox.app/Contents/'
                candidate_app = os.path.join(location, 'MacOS', 'firefox')
            elif Settings.is_windows():
                location = 'C:\\Program Files (x86)\\Mozilla Firefox'
                if not os.path.exists(location):
                    location = 'C:\\Program Files\\Mozilla Firefox'
                    candidate_app = os.path.join(location, 'firefox.exe')
            elif Settings.is_linux():
                location = '/usr/lib/firefox'
                candidate_app = os.path.join(location, 'firefox')
            else:
                logger.critical('Platform not supported')
                self.finish(code=5)

            if not os.path.isdir(location):
                logger.critical(
                    'Firefox not found. Please download if from https://www.mozilla.org/en-US/firefox/new/'
                )
                self.finish(code=5)

            return candidate_app

        else:
            try:
                locale = 'ja-JP-mac' if self.args.locale == 'ja' and Settings.is_mac(
                ) else self.args.locale
                type, scraper_details = get_scraper_details(
                    self.args.firefox, Settings.CHANNELS,
                    os.path.join(IrisCore.get_working_dir(), 'cache'), locale)
                scraper = FactoryScraper(type, **scraper_details)

                firefox_dmg = scraper.download()
                install_folder = install(src=firefox_dmg,
                                         dest=IrisCore.get_current_run_dir())

                binary = get_binary(install_folder, 'Firefox')

                channel = get_firefox_channel(binary)
                latest_type, latest_scraper_details = get_latest_scraper_details(
                    channel)
                latest_path = FactoryScraper(latest_type,
                                             **latest_scraper_details).filename

                self.latest_version = get_version_from_path(latest_path)
                logger.info('Latest available version for %s channel is: %s' %
                            (channel, self.latest_version))

                return binary
            except errors.NotFoundError:
                logger.critical(
                    'Specified build (%s) has not been found. Closing Iris ...'
                    % self.args.firefox)
                self.finish(5)
Esempio n. 9
0
    def control_center(self):
        # If user provides custom command-line arguments, we will skip the control center.
        if len(sys.argv) > 1 and not self.args.control:
            return True
        else:
            # Copy web assets to working directory.
            dir_util.copy_tree(
                os.path.join(self.module_dir, 'iris', 'cc_files'),
                self.args.workdir)
            # Copy profile for Firefox.
            profile_path = os.path.join(self.args.workdir, 'cc_profile')
            if os.path.exists(profile_path):
                shutil.rmtree(profile_path)
            Profile._get_staged_profile(Profile.LIKE_NEW, profile_path)

            # Open local installation of Firefox.
            paths = []
            is_installed = False
            fx_path = ''
            if Settings.get_os() == Platform.MAC:
                paths.append(
                    '/Applications/Firefox.app/Contents/MacOS/firefox')
                paths.append(
                    '/Applications/Firefox Developer Edition.app/Contents/MacOS/firefox'
                )
                paths.append(
                    '/Applications/Firefox Nightly.app/Contents/MacOS/firefox')
            elif Settings.get_os() == Platform.WINDOWS:
                paths.append(
                    'C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe')
                paths.append(
                    'C:\\Program Files (x86)\\Firefox Developer Edition\\firefox.exe'
                )
                paths.append('C:\\Program Files (x86)\\Nightly\\firefox.exe')
                paths.append('C:\\Program Files\\Mozilla Firefox\\firefox.exe')
                paths.append(
                    'C:\\Program Files\\Firefox Developer Edition\\firefox.exe'
                )
                paths.append('C:\\Program Files\\Nightly\\firefox.exe')
            else:
                paths.append('/usr/bin/firefox')
                paths.append('/usr/lib/firefox/firefox')

            for path in paths:
                if os.path.exists(path):
                    fx_path = path
                    is_installed = True
                    break
            if not is_installed:
                logger.error(
                    'Can\'t find local Firefox installation, aborting Iris run.'
                )
                self.finish(1)

            fx_runner = launch_firefox(fx_path,
                                       profile=profile_path,
                                       url=self.base_local_web_url)
            fx_runner.start()
            server = LocalWebServer(self.args.workdir, self.args.port)

            # Iris waits for the user to make a choice in the control center. Once they
            # make a decision, Firefox will quit.
            quit_firefox()

            # Check the result of the user's decision. If they have chosen to run tests,
            # we will continue. Otherwise, abort the current run.
            if server.result == 'cancel':
                # We will quit Iris gracefully and clean up.
                logger.info('Canceling Iris run.')
                return False
            else:
                # We will parse this returned value and turn it into runtime data.
                logger.debug('Received data from control center: %s' %
                             server.result)

                # Update app args with new values
                self.args.locale = server.result['locale']
                self.args.firefox = server.result['firefox']
                self.args.override = server.result['override']
                self.args.port = int(server.result['port'])
                self.args.email = server.result['email']
                self.args.highlight = server.result['highlight']
                self.args.mouse = float(server.result['mouse'])
                self.args.report = server.result['report']
                self.args.save = server.result['save']

                # For other parts of Iris that get their arguments from parse_args,
                # we have to update the values there as well.
                get_global_args().locale = self.args.locale
                get_global_args().firefox = self.args.firefox
                get_global_args().override = self.args.override
                get_global_args().port = self.args.port
                get_global_args().email = self.args.email
                get_global_args().highlight = server.result['highlight']
                get_global_args().mouse = self.args.mouse
                get_global_args().report = self.args.report
                get_global_args().save = self.args.save

                # Update this URL, used by test cases.
                self.base_local_web_url = 'http://127.0.0.1:%s' % self.args.port

                # Parse tests.
                tests = sorted(server.result['tests'])
                if len(tests):
                    for package in tests:
                        self.test_packages.append(package)
                        for test in server.result['tests'][package]:
                            self.test_list.append(test['name'])
                else:
                    logger.info('No tests selected, canceling Iris run.')
                    return False
                return True
Esempio n. 10
0
    def get_test_candidate(self, build):
        """Download and extract a build candidate.

        Build may either refer to a Firefox release identifier, package, or build directory.
        :param:
            build: str with firefox build
        :return:
            FirefoxApp object for test candidate
        """
        if os.path.isdir(build):
            candidate_app = fa.FirefoxApp(build, Settings.getOS(), False)
            return candidate_app
        else:
            platform = fd.FirefoxDownloader.detect_platform()
            if platform is None:
                logger.error('Unsupported platform: "%s"' % sys.platform)
                sys.exit(5)

            # `build` may refer to a build reference as defined in FirefoxDownloader,
            # a local Firefox package as produced by `mach build`, or a local build tree.
            if build in fd.FirefoxDownloader.build_urls:
                # Download test candidate by Firefox release ID
                logger.info('Downloading Firefox "%s" build for platform "%s"' % (build, platform))
                fdl = fd.FirefoxDownloader(self.args.workdir, cache_timeout=1 * 60 * 60)
                build_archive_file = fdl.download(build, self.args.locale, platform)
                if build_archive_file is None:
                    self.finish(code=-1)
                # Extract candidate archive
                candidate_app = fe.extract(build_archive_file, Settings.getOS(), self.args.workdir,
                                           cache_timeout=1 * 60 * 60)
                candidate_app.package_origin = fdl.get_download_url(build, platform)
            elif os.path.isfile(build):
                # Extract firefox build from archive
                logger.info('Using file "%s" as Firefox package' % build)
                candidate_app = fe.extract(build, Settings.getOS(), self.args.workdir, cache_timeout=1 * 60 * 60)
                candidate_app.package_origin = build
                logger.debug('Build candidate executable is "%s"' % candidate_app.exe)
            elif os.path.isfile(os.path.join(build, 'mach')):
                logger.info('Using Firefox build tree at `%s`' % build)
                dist_globs = sorted(glob.glob(os.path.join(build, 'obj-*', 'dist')))
                if len(dist_globs) == 0:
                    logger.critical('"%s" looks like a Firefox build directory, but can\'t find a build in it' % build)
                    self.finish(code=5)
                logger.debug('Potential globs for dist directory: %s' % dist_globs)
                dist_dir = dist_globs[-1]
                logger.info('Using "%s" as build distribution directory' % dist_dir)
                if 'apple-darwin' in dist_dir.split('/')[-2]:
                    # There is a special case for OS X dist directories:
                    # FirefoxApp expects OS X .dmg packages to contain the .app folder inside
                    # another directory. However, that directory isn't there in build trees,
                    # thus we need to point to the parent for constructing the app.
                    logger.info('Looks like this is an OS X build tree')
                    candidate_app = fa.FirefoxApp(os.path.abspath(os.path.dirname(dist_dir)), Settings.getOS(), True)
                    candidate_app.package_origin = os.path.abspath(build)
                else:
                    candidate_app = fa.FirefoxApp(os.path.abspath(dist_dir), Settings.getOS(), True)
                    candidate_app.package_origin = os.path.abspath(build)
            else:
                logger.critical('"%s" specifies neither a Firefox release, package file, or build directory' % build)
                logger.critical('Valid Firefox release identifiers are: %s' % ', '.join(fd.FirefoxDownloader.list()[0]))
                self.finish(5)

            logger.debug('Build candidate executable is "%s"' % candidate_app.exe)
            if candidate_app.platform != platform:
                logger.warning('Platform mismatch detected')
                logger.critical('Running a Firefox binary for "%s" on a "%s" platform will probably fail' %
                                (candidate_app.platform, platform))
            return candidate_app