def check_marionette_exists(adb="adb"): dm = DeviceManagerADB(adbPath=adb) if dm.dirExists(INSTALL_DIR): return True else: dm.forward("tcp:2828", "tcp:2828") try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('localhost', 2828)) data = sock.recv(16) sock.close() if 'root' in data: return True except socket.error: return False return False
class TestRun(object): def __init__(self, adb="adb", serial=None): self.test_results = {} self.test_results_file = None self.m = None self.gaia_apps = None self.screenshot_path = None self.logcat_path = None self.app_name = None self.attempt = None self.num_apps = None self.device = None self.serial = serial self.port = None self.run_log = logging.getLogger('marketplace-test') if self.serial: self.dm = DeviceManagerADB(adbPath=adb, deviceSerial=serial) else: self.dm = DeviceManagerADB(adbPath=adb) def reset_marionette(self): try: self.m.delete_session() except Exception: pass self.m = None self.get_marionette() def get_marionette(self): if not self.m: self.m = Marionette(port=self.port) self.m.start_session() self.device = GaiaDevice(self.m) self.device.add_device_manager(self.dm) self.gaia_apps = GaiaApps(self.m) else: tries = 5 while tries > 0: try: self.m.get_url() break except MarionetteException as e: if "Please start a session" in str(e): time.sleep(5) self.m = Marionette(port=self.port) self.m.start_session() self.device = GaiaDevice(self.m) self.device.add_device_manager(self.dm) self.gaia_apps = GaiaApps(self.m) tries -= 1 else: raise e else: self.run_log.error("Can't connect to marionette, rebooting") self.restart_device() return self.m def write_to_file(self, data): with open("%s.tmp" % self.test_results_file, "w") as f: f.write(data) shutil.copyfile("%s.tmp" % self.test_results_file, self.test_results_file) def add_values(self, key, value): if self.serial: self.test_results["%s_%s" % (key, self.serial)] = value else: self.test_results["%s" % key] = value def add_result(self, passed=False, status=None, uninstalled_failure=False): values = {} if status: if not passed: values["status"] = "FAILED: %s" % status else: values["status"] = "PASS" if self.screenshot_path: values["screenshot"] = self.screenshot_path if self.logcat_path: values["logcat"] = self.logcat_path if uninstalled_failure: values["uninstalled_failure"] = uninstalled_failure entry = "%s_%s" % (self.app_name, self.attempt) self.test_results[entry] = values def launch_with_manifest(self, manifest): self.m.switch_to_frame() result = self.m.execute_async_script("GaiaApps.launchWithManifestURL('%s')" % manifest, script_timeout=30000) if result == False: raise Exception("launch timed out") app = GaiaApp(frame=result.get('frame'), src=result.get('src'), name=result.get('name'), origin=result.get('origin')) if app.frame_id is None: raise Exception("failed to launch; there is no app frame") self.m.switch_to_frame(app.frame_id) return app def uninstall_with_manifest(self, manifest): self.m.switch_to_frame() script = """ GaiaApps.locateWithManifestURL('%s', null, function uninstall(app) { navigator.mozApps.mgmt.uninstall(app); marionetteScriptFinished(true); }); """ result = self.m.execute_async_script(script % manifest, script_timeout=60000) if result != True: self.add_result(status="Failed to uninstall app with url '%s'" % manifest) return app def forward_port(self): # get unused port s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('localhost', 0)) addr, port = s.getsockname() s.close() dm_tries = 0 self.run_log.info("using port %s" % port) while dm_tries < 20: if self.dm.forward("tcp:%d" % port, "tcp:2828") == 0: break dm_tries += 1 time.sleep(3) else: return False self.port = port return True def restart_device(self, restart_tries=0): self.run_log.info("rebooting") # TODO restarting b2g doesn't seem to work... reboot then while restart_tries < 3: restart_tries += 1 self.dm.reboot(wait=True) self.run_log.info("forwarding") if not self.forward_port(): self.run_log.error("couldn't forward port in time, rebooting") continue self.m = Marionette(port=self.port) if not self.m.wait_for_port(180): self.run_log.error("couldn't contact marionette in time, rebooting") continue time.sleep(1) self.m.start_session() try: Wait(self.m, timeout=240).until(lambda m: m.find_element("id", "lockscreen-container").is_displayed()) # It retuns a little early time.sleep(2) self.device = GaiaDevice(self.m) self.device.add_device_manager(self.dm) self.device.unlock() self.gaia_apps = GaiaApps(self.m) except (MarionetteException, IOError, socket.error) as e: self.run_log.error("got exception: %s, going to retry" % e) try: self.m.delete_session() except: # at least attempt to clear the session if possible pass continue break else: raise Exception("Couldn't restart the device in time, even after 3 tries") def readystate_wait(self, app): try: Wait(self.get_marionette(), timeout=30).until(lambda m: m.execute_script("return window.document.readyState;") == "complete") except ScriptTimeoutException as e: return False return True def record_icons(self): self.device.touch_home_button() icons = self.m.find_elements("class name", "icon") self.num_apps = len(icons) def check_if_app_installed(self, timeout=180): # TODO: Find a better way to do this than checking homescreen # I hope there is one... self.device.touch_home_button() icons = self.m.find_elements("class name", "icon") start = time.time() end = start + 180 found_icon = None claims_its_loaded = 0 # this is used in case 'loading' isn't applied immediately to the icon while time.time() < end: if not found_icon: icons = self.m.find_elements("class name", "icon") # We can't do set comparison b/c references change if len(icons) > self.num_apps: for icon in icons: if "loading" in icon.get_attribute("innerHTML"): found_icon = icon break else: claims_its_loaded += 1 if claims_its_loaded == 3: return True else: if "loading" not in found_icon.get_attribute("innerHTML"): return True time.sleep(2) return False
class TestRun(object): def __init__(self, adb="adb", serial=None): self.test_results = {} self.test_results_file = None self.m = None self.gaia_apps = None self.screenshot_path = None self.logcat_path = None self.app_name = None self.attempt = None self.num_apps = None self.device = None self.serial = serial self.port = None self.run_log = logging.getLogger('marketplace-test') if self.serial: self.dm = DeviceManagerADB(adbPath=adb, deviceSerial=serial) else: self.dm = DeviceManagerADB(adbPath=adb) def reset_marionette(self): try: self.m.delete_session() except Exception: pass self.m = None self.get_marionette() def get_marionette(self): if not self.m: self.m = Marionette(port=self.port) self.m.start_session() self.device = GaiaDevice(self.m) self.device.add_device_manager(self.dm) self.gaia_apps = GaiaApps(self.m) else: tries = 5 while tries > 0: try: self.m.get_url() break except MarionetteException as e: if "Please start a session" in str(e): time.sleep(5) self.m = Marionette(port=self.port) self.m.start_session() self.device = GaiaDevice(self.m) self.device.add_device_manager(self.dm) self.gaia_apps = GaiaApps(self.m) tries -= 1 else: raise e else: self.run_log.error("Can't connect to marionette, rebooting") self.restart_device() return self.m def write_to_file(self, data): with open("%s.tmp" % self.test_results_file, "w") as f: f.write(data) shutil.copyfile("%s.tmp" % self.test_results_file, self.test_results_file) def add_values(self, key, value): if self.serial: self.test_results["%s_%s" % (key, self.serial)] = value else: self.test_results["%s" % key] = value def add_result(self, passed=False, status=None, uninstalled_failure=False): values = {} if status: if not passed: values["status"] = "FAILED: %s" % status else: values["status"] = "PASS" if self.screenshot_path: values["screenshot"] = self.screenshot_path if self.logcat_path: values["logcat"] = self.logcat_path if uninstalled_failure: values["uninstalled_failure"] = uninstalled_failure entry = "%s_%s" % (self.app_name, self.attempt) self.test_results[entry] = values def launch_with_manifest(self, manifest): self.m.switch_to_frame() result = self.m.execute_async_script( "GaiaApps.launchWithManifestURL('%s')" % manifest, script_timeout=30000) if result == False: raise Exception("launch timed out") app = GaiaApp(frame=result.get('frame'), src=result.get('src'), name=result.get('name'), origin=result.get('origin')) if app.frame_id is None: raise Exception("failed to launch; there is no app frame") self.m.switch_to_frame(app.frame_id) return app def uninstall_with_manifest(self, manifest): self.m.switch_to_frame() script = """ GaiaApps.locateWithManifestURL('%s', null, function uninstall(app) { navigator.mozApps.mgmt.uninstall(app); marionetteScriptFinished(true); }); """ result = self.m.execute_async_script(script % manifest, script_timeout=60000) if result != True: self.add_result(status="Failed to uninstall app with url '%s'" % manifest) return app def forward_port(self): # get unused port s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('localhost', 0)) addr, port = s.getsockname() s.close() dm_tries = 0 self.run_log.info("using port %s" % port) while dm_tries < 20: if self.dm.forward("tcp:%d" % port, "tcp:2828") == 0: break dm_tries += 1 time.sleep(3) else: return False self.port = port return True def restart_device(self, restart_tries=0): self.run_log.info("rebooting") # TODO restarting b2g doesn't seem to work... reboot then while restart_tries < 3: restart_tries += 1 self.dm.reboot(wait=True) self.run_log.info("forwarding") if not self.forward_port(): self.run_log.error("couldn't forward port in time, rebooting") continue self.m = Marionette(port=self.port) if not self.m.wait_for_port(180): self.run_log.error( "couldn't contact marionette in time, rebooting") continue time.sleep(1) self.m.start_session() try: Wait(self.m, timeout=240).until(lambda m: m.find_element( "id", "lockscreen-container").is_displayed()) # It retuns a little early time.sleep(2) self.device = GaiaDevice(self.m) self.device.add_device_manager(self.dm) self.device.unlock() self.gaia_apps = GaiaApps(self.m) except (MarionetteException, IOError, socket.error) as e: self.run_log.error("got exception: %s, going to retry" % e) try: self.m.delete_session() except: # at least attempt to clear the session if possible pass continue break else: raise Exception( "Couldn't restart the device in time, even after 3 tries") def readystate_wait(self, app): try: Wait(self.get_marionette(), timeout=30).until(lambda m: m.execute_script( "return window.document.readyState;") == "complete") except ScriptTimeoutException as e: return False return True def record_icons(self): self.device.touch_home_button() icons = self.m.find_elements("class name", "icon") self.num_apps = len(icons) def check_if_app_installed(self, timeout=180): # TODO: Find a better way to do this than checking homescreen # I hope there is one... self.device.touch_home_button() icons = self.m.find_elements("class name", "icon") start = time.time() end = start + 180 found_icon = None claims_its_loaded = 0 # this is used in case 'loading' isn't applied immediately to the icon while time.time() < end: if not found_icon: icons = self.m.find_elements("class name", "icon") # We can't do set comparison b/c references change if len(icons) > self.num_apps: for icon in icons: if "loading" in icon.get_attribute("innerHTML"): found_icon = icon break else: claims_its_loaded += 1 if claims_its_loaded == 3: return True else: if "loading" not in found_icon.get_attribute("innerHTML"): return True time.sleep(2) return False