How to use _logFailedCommand method in fMBT

Best Python code snippet using fMBT_python

fmbtandroid.py

Source:fmbtandroid.py Github

copy

Full Screen

...138 '-sharpen 5 -level 90%%,100%%,3.0 -filter Mitchell -sharpen 5'139 ]140def _adapterLog(msg):141 fmbt.adapterlog("fmbtandroid: %s" % (msg,))142def _logFailedCommand(source, command, exitstatus, stdout, stderr):143 _adapterLog('in %s command "%s" failed:\n output: %s\n error: %s\n status: %s' %144 (source, command, stdout, stderr, exitstatus))145if platform.system() == "Windows":146 _g_closeFds = False147 _g_adbExecutable = "adb.exe"148else:149 _g_closeFds = True150 _g_adbExecutable = "adb"151def _run(command, expectedExitStatus = None, timeout=None):152 if type(command) == str:153 if timeout != None:154 command = "timeout %s %s" % (timeout, command)155 shell=True156 else:157 if timeout != None:158 command = ["timeout", str(timeout)] + command159 shell=False160 try:161 p = subprocess.Popen(command, shell=shell,162 stdout=subprocess.PIPE,163 stderr=subprocess.PIPE,164 close_fds=_g_closeFds)165 if expectedExitStatus != None or timeout != None:166 out, err = p.communicate()167 else:168 out, err = ('', None)169 except Exception, e:170 class fakeProcess(object): pass171 p = fakeProcess172 p.returncode = 127173 out, err = ('', e)174 exitStatus = p.returncode175 if expectedExitStatus != None:176 if ((type(expectedExitStatus) in [list, tuple] and177 not exitStatus in expectedExitStatus) or178 (type(expectedExitStatus) == int and179 not exitStatus == expectedExitStatus)):180 msg = 'Unexpected exit status %s from command "%s".\n Output: %s\n Error: %s' % (181 exitStatus, command, out, err)182 _adapterLog(msg)183 if "error: device not found" in err:184 raise AndroidDeviceNotFound(msg)185 else:186 raise FMBTAndroidRunError(msg)187 return (exitStatus, out, err)188class Device(fmbtgti.GUITestInterface):189 """190 The Device class provides191 - keywords as its methods192 - device properties from device's INI file193 - view() returns the most recently refreshed View, that contains194 items parsed from window dump.195 - screenshot() returns the most recently refreshed Screenshot,196 bitmaps can be searched from this.197 """198 _PARSE_VIEW_RETRY_LIMIT = 10199 def __init__(self, deviceName=None, iniFile=None, connect=True, **kwargs):200 """201 Connect to given device, or the first not-connected Android202 device in the "adb devices" list, if nothing is defined.203 Parameters:204 deviceName (string, optional):205 If deviceName is a device serial number (an item in206 the left most column in "adb devices"), connect to207 that device. Device information is read from208 $FMBTANDROIDHOME/etc/SERIALNUMBER.ini, if it exists.209 If deviceName is a nick name, device information is210 looked for from $FMBTANDROIDHOME/etc/deviceName.ini,211 and the connection is established to the device with212 the serial number given in the ini file.213 The default is None. The first disconnected device214 in the "adb devices" list is connected to. Device215 information is read from216 $FMBTANDROIDHOME/etc/SERIALNUMBER.ini, if it exists.217 iniFile (file object, optional):218 A file object that contains device information219 ini. Connect to the device with a serial number220 given in this file. The default is None.221 rotateScreenshot (integer, optional)222 rotate new screenshots by rotateScreenshot degrees.223 Example: rotateScreenshot=-90. The default is 0 (no224 rotation).225 To create an ini file for a device, use dumpIni. Example:226 file("/tmp/test.ini", "w").write(fmbtandroid.Device().dumpIni())227 """228 fmbtgti.GUITestInterface.__init__(self, **kwargs)229 self._fmbtAndroidHomeDir = os.getenv("FMBTANDROIDHOME", os.getcwd())230 self._platformVersion = None231 self._lastView = None232 self._conf = Ini()233 self._loadDeviceAndTestINIs(self._fmbtAndroidHomeDir, deviceName, iniFile)234 if deviceName == None:235 deviceName = self._conf.value("general", "serial", "")236 if connect == False and deviceName == "":237 deviceName = "nodevice"238 self.setConnection(None)239 elif deviceName == "":240 # Connect to an unspecified device.241 # Go through devices in "adb devices".242 listDevicesCommand = [_g_adbExecutable, "devices"]243 status, output, err = _run(listDevicesCommand, expectedExitStatus = [0, 127])244 if status == 127:245 raise FMBTAndroidError('adb not found in PATH. Check your Android SDK installation.')246 outputLines = [l.strip() for l in output.splitlines()]247 try: deviceLines = outputLines[outputLines.index("List of devices attached")+1:]248 except: deviceLines = []249 deviceLines = [l for l in deviceLines if l.strip() != ""]250 if deviceLines == []:251 raise AndroidDeviceNotFound('No devices found with "%s"' % (listDevicesCommand,))252 potentialDevices = [line.split()[0] for line in deviceLines]253 for deviceName in potentialDevices:254 try:255 self.serialNumber = deviceName256 self._conf.set("general", "serial", self.serialNumber)257 self.setConnection(_AndroidDeviceConnection(self.serialNumber))258 break259 except AndroidConnectionError, e:260 continue261 else:262 raise AndroidConnectionError("Could not connect to device(s): %s." % (263 ", ".join(potentialDevices)))264 # Found a device (deviceName).265 self._loadDeviceAndTestINIs(self._fmbtAndroidHomeDir, deviceName, iniFile)266 else:267 # Device name given, find out the serial number to connect to.268 # It may be given in device or test run INI files.269 self.serialNumber = self._conf.value("general", "serial", deviceName)270 if connect:271 self.setConnection(_AndroidDeviceConnection(self.serialNumber))272 _deviceIniFilename = self._fmbtAndroidHomeDir + os.sep + "etc" + os.sep + deviceName + ".ini"273 self.loadConfig(_deviceIniFilename, override=True, level="device")274 # Fetch properties from device configuration275 self.nickName = self._conf.value("general", "name", deviceName)276 self.phoneNumber = self._conf.value("general", "phonenumber")277 # Loading platform-specific configuration requires a278 # connection to the device for checking the platform version.279 _platformIniFilename = self._fmbtAndroidHomeDir + os.sep + "etc" + os.sep + "android" + self.platformVersion() + ".ini"280 # would we need a form-factor ini, too?281 self.loadConfig(_platformIniFilename, override=False, level="platform")282 self.loadConfig(StringIO.StringIO(DEVICE_INI_DEFAULTS), override=False, level="global default")283 self.wlanAP = self._conf.value("environment", "wlanAP")284 self.wlanPass = self._conf.value("environment", "wlanPass")285 self.btName = self._conf.value("environment", "BTName")286 self.btAccessory = self._conf.value("environment", "BTAccessory")287 self.serverIP = self._conf.value("environment", "ServerIP")288 self.androidUser = self._conf.value("environment", "AndroidUser")289 self.voiceMailNumber = self._conf.value("environment", "VoiceMailNumber")290 if self._conn: hw = self._conn.recvVariable("build.device")291 else: hw = "nohardware"292 self.hardware = self._conf.value("general", "hardware", hw)293 self.setBitmapPath(self._conf.value("paths", "bitmapPath", ".:" + self._fmbtAndroidHomeDir + os.sep + "bitmaps" + os.sep + self.hardware + "-" + self.platformVersion()), self._fmbtAndroidHomeDir)294 self.setScreenshotDir(self._conf.value("paths", "screenshotDir", self._fmbtAndroidHomeDir + os.sep + "screenshots"))295 def callContact(self, contact):296 """297 Call to given contact.298 Return True if successful, otherwise False.299 """300 callCommand = 'service call phone 1 s16 "%s"' % (contact,)301 status, out, err = self.shellSOE(callCommand)302 if status != 0:303 _logFailedCommand("callContact", callCommand, status, out, err)304 return False305 else:306 return True307 def callNumber(self, number):308 """309 Call to given phone number.310 Return True if successful, otherwise False.311 """312 callCommand = "am start -a android.intent.action.CALL -d 'tel:%s'" % (number,)313 status, out, err = self.shellSOE(callCommand)314 if status != 0:315 _logFailedCommand("callNumber", callCommand, status, out, err)316 return False317 else:318 return True319 def close(self):320 fmbtgti.GUITestInterface.close(self)321 if hasattr(self, "_conn"):322 del self._conn323 if hasattr(self, "_lastView"):324 del self._lastView325 import gc326 gc.collect()327 def dumpIni(self):328 """329 Returns contents of current device configuration as a string (in330 INI format).331 """332 return self._conf.dump()333 def ini(self):334 """335 Returns an Ini object containing effective device336 configuration.337 """338 return self._conf339 def loadConfig(self, filenameOrObj, override=True, level=""):340 try:341 if type(filenameOrObj) == str:342 filename = filenameOrObj343 fileObj = file(filenameOrObj)344 else:345 fileObj = filenameOrObj346 filename = getattr(fileObj, "name", "<string>")347 if hasattr(fileObj, "seek"):348 fileObj.seek(0)349 self._conf.addFile(fileObj, override=override)350 except Exception, e:351 _adapterLog('Loading %s configuration from "%s" failed: %s' % (level, filename, e))352 return353 _adapterLog('Loaded %s configuration from "%s"' % (level, filename))354 def platformVersion(self):355 """356 Returns the platform version of the device.357 """358 if self._platformVersion == None:359 if self._conn:360 self._platformVersion = self._conn.recvVariable("build.version.release")361 else:362 self._platformVersion = "nosoftware"363 return self._platformVersion364 def pressAppSwitch(self, **pressKeyKwArgs):365 """366 Press the app switch button.367 Optional parameters are the same as for pressKey.368 """369 return self.pressKey("KEYCODE_APP_SWITCH", **pressKeyKwArgs)370 def pressBack(self, **pressKeyKwArgs):371 """372 Press the back button.373 Optional parameters are the same as for pressKey.374 """375 return self.pressKey("KEYCODE_BACK", **pressKeyKwArgs)376 def pressHome(self, **pressKeyKwArgs):377 """378 Press the home button.379 Optional parameters are the same as for pressKey.380 """381 return self.pressKey("KEYCODE_HOME", **pressKeyKwArgs)382 def pressKey(self, keyName, long=False, hold=0.0):383 """384 Press a key on the device.385 Parameters:386 keyName (string):387 the name of the key, like KEYCODE_HOME. If KEYCODE_388 prefix is not given, it is added. Refer to Android389 KeyEvent documentation.390 long (boolean, optional):391 if True, press the key for long time.392 hold (float, optional):393 time in seconds to hold the key down.394 """395 if not keyName.upper().startswith("KEYCODE_"):396 keyName = "KEYCODE_" + keyName397 keyName = keyName.upper()398 return fmbtgti.GUITestInterface.pressKey(self, keyName, long, hold)399 def pressMenu(self, **pressKeyKwArgs):400 """401 Press the menu button.402 Optional parameters are the same as for pressKey.403 """404 return self.pressKey("KEYCODE_MENU", **pressKeyKwArgs)405 def pressPower(self, **pressKeyKwArgs):406 """407 Press the power button.408 Optional parameters are the same as for pressKey.409 """410 return self.pressKey("KEYCODE_POWER", **pressKeyKwArgs)411 def pressSearch(self, **pressKeyKwArgs):412 """413 Press the search button.414 Optional parameters are the same as for pressKey.415 """416 return self.pressKey("KEYCODE_SEARCH", **pressKeyKwArgs)417 def pressVolumeUp(self, **pressKeyKwArgs):418 """419 Press the volume up button.420 Optional parameters are the same as for pressKey.421 """422 return self.pressKey("KEYCODE_VOLUME_UP", **pressKeyKwArgs)423 def pressVolumeDown(self, **pressKeyKwArgs):424 """425 Press the volume down button.426 Optional parameters are the same as for pressKey.427 """428 return self.pressKey("KEYCODE_VOLUME_DOWN", **pressKeyKwArgs)429 def reboot(self, reconnect=True, firstBoot=False, timeout=120):430 """431 Reboot the device.432 Parameters433 reconnect (boolean, optional)434 If True, do not return until the device has been435 connected after boot. Otherwise return once reboot436 command has been sent. The default is True.437 firstBoot (boolean, optional)438 If True, the device boots like it would have been439 flashed. Requires that "adb root" works. The default440 is False.441 timeout (integer, optional)442 Timeout in seconds for reconnecting after reboot.443 The default is 120 s.444 Returns True on success, otherwise False.445 """446 return self._conn.reboot(reconnect, firstBoot, timeout)447 def reconnect(self):448 """449 Close connections to the device and reconnect.450 """451 self.setConnection(None)452 import gc453 gc.collect()454 try:455 self.setConnection(_AndroidDeviceConnection(self.serialNumber))456 return True457 except Exception, e:458 _adapterLog("reconnect failed: %s" % (e,))459 return False460 def refreshView(self, forcedView=None):461 """462 (Re)reads view items on display and updates the latest View463 object.464 Parameters:465 forcedView (View or filename, optional):466 use given View object or view file instead of reading467 items from the device.468 Returns created View object.469 """470 def formatErrors(errors):471 return "refreshView parse errors:\n %s" % (472 "\n ".join(["line %s: %s error: %s" % e for e in errors]),)473 if self._conn:474 displayToScreen = self._conn._displayToScreen475 else:476 displayToScreen = None477 if forcedView != None:478 if isinstance(forcedView, View):479 self._lastView = forcedView480 elif type(forcedView) == str:481 self._lastView = View(self.screenshotDir(), self.serialNumber, file(forcedView).read(), displayToScreen)482 _adapterLog(formatErrors(self._lastView.errors()))483 else:484 raise ValueError("forcedView must be a View object or a filename")485 return self._lastView486 retryCount = 0487 while True:488 dump = self._conn.recvViewData()489 if dump != None:490 view = View(self.screenshotDir(), self.serialNumber, dump, displayToScreen)491 else:492 _adapterLog("refreshView window dump reading failed")493 view = None494 # fail quickly if there is no answer495 retryCount += self._PARSE_VIEW_RETRY_LIMIT / 2496 if dump == None or len(view.errors()) > 0:497 if view:498 _adapterLog(formatErrors(view.errors()))499 if retryCount < self._PARSE_VIEW_RETRY_LIMIT:500 retryCount += 1501 time.sleep(0.2) # sleep before retry502 else:503 raise AndroidConnectionError("Cannot read window dump")504 else:505 # successfully parsed or parsed with errors but no more retries506 self._lastView = view507 return view508 def useDisplaySize(self, (width, height) = (None, None)):509 """510 Transform coordinates of synthesized events from screenshot511 resolution to given resolution. By default events are512 synthesized directly to screenshot coordinates.513 Parameters:514 (width, height) (pair of integers, optional):515 width and height of display in pixels. If not516 given, values from Android system properties517 "display.width" and "display.height" will be used.518 Returns None.519 """520 if width == None:521 width = int(self.systemProperty("display.width"))522 if height == None:523 height = int(self.systemProperty("display.height"))524 screenWidth, screenHeight = self.screenSize()525 self._conn.setScreenToDisplayCoords(526 lambda x, y: (x * width / screenWidth,527 y * height / screenHeight))528 self._conn.setDisplayToScreenCoords(529 lambda x, y: (x * screenWidth / width,530 y * screenHeight / height))531 def shell(self, shellCommand):532 """533 Execute shellCommand in adb shell.534 shellCommand is a string (arguments separated by whitespace).535 Returns output of "adb shell" command.536 If you wish to receive exitstatus or standard output and error537 separated from shellCommand, refer to shellSOE().538 """539 return self._conn._runAdb(["shell", shellCommand])[1]540 def shellSOE(self, shellCommand):541 """542 Execute shellCommand in adb shell.543 shellCommand is a string (arguments separated by whitespace).544 Returns tuple (exitStatus, standardOutput, standardError).545 Requires tar and uuencode to be available on the device.546 """547 return self._conn.shellSOE(shellCommand)548 def smsNumber(self, number, message):549 """550 Send message using SMS to given number.551 Parameters:552 number (string)553 phone number to which the SMS will be sent554 message (string)555 the message to be sent.556 Returns True on success, otherwise False.557 """558 smsCommand = ('am start -a android.intent.action.SENDTO ' +559 '-d sms:%s --es sms_body "%s"' +560 ' --ez exit_on_sent true') % (number, message)561 status, out, err = self.shellSOE(smsCommand)562 if status != 0:563 _logFailedCommand("sms", smsCommand, status, out, err)564 return False565 _adapterLog("SMS command returned %s" % (out + err,))566 time.sleep(2)567 self.pressKey("KEYCODE_DPAD_RIGHT")568 time.sleep(1)569 self.pressKey("KEYCODE_ENTER")570 return True571 def supportsView(self):572 """573 Check if connected device supports reading view data.574 View data is needed by refreshView(), view(), verifyText() and575 waitText(). It is produced by Android window dump.576 Returns True if view data can be read, otherwise False.577 """...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run fMBT automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful