How to use findItemsByContentDesc method in fMBT

Best Python code snippet using fMBT_python

fmbtandroid.py

Source:fmbtandroid.py Github

copy

Full Screen

...1215 d.refreshView(uiautomatorDump=True)1216 d.tapContentDesc("Apps")1217 """1218 assert self._lastView != None, "View required."1219 items = self._lastView.findItemsByContentDesc(contentDesc)1220 if len(items) == 0: return False1221 return self.tapItem(items[0], **tapKwArgs)1222 def topApp(self):1223 """1224 Returns the name of the top application.1225 """1226 if not self._conn:1227 return None1228 else:1229 return self._conn.recvTopAppWindow()[0]1230 def topWindow(self):1231 """1232 Returns the name of the top window.1233 """1234 # the top window may be None during transitions, therefore1235 # retry a couple of times if necessary.1236 if not self._conn:1237 return None1238 timeout = 0.51239 pollDelay = 0.21240 start = time.time()1241 tw = self.existingConnection().recvTopAppWindow()[1]1242 while tw == None and (time.time() - start < timeout):1243 time.sleep(pollDelay)1244 tw = self.existingConnection().recvTopAppWindow()[1]1245 return tw1246 def topWindowStack(self):1247 """1248 Returns window names in the stack of the top fullscreen application.1249 The topmost window is the last one in the list.1250 """1251 return self.existingConnection().recvTopWindowStack()1252 def uiautomatorDump(self):1253 """1254 Returns whether or not uiautomator is used for refreshView()1255 """1256 return self._uiautomatorDump1257 def uninstall(self, apkname, keepData=False):1258 """1259 Uninstall a package from the device.1260 Parameters:1261 package (string):1262 the package to be uninstalled.1263 keepData (boolean, optional):1264 keep app data and cache.1265 Corresponds to adb uninstall "-k".1266 The default is False.1267 Returns True on success, otherwise False.1268 Example:1269 d.uninstall("com.android.python27")1270 """1271 if self._conn:1272 return self._conn.uninstall(apkname, keepData)1273 else:1274 return False1275 def userRotation(self):1276 """1277 Returns rotation set with setUserRotation.1278 """1279 return self.existingConnection().recvUserRotation()1280 def verifyText(self, text, partial=False):1281 """1282 Verify that the last view has at least one item with given1283 text.1284 Parameters:1285 text (string):1286 text to be searched for in items.1287 partial (boolean, optional):1288 if True, match items if item text contains given1289 text, otherwise match only if item text is equal to1290 the given text. The default is False (exact match).1291 """1292 assert self._lastView != None, "View required."1293 return self._lastView.findItemsByText(text, partial=partial, count=1, onScreen=True) != []1294 def view(self):1295 """1296 Returns the last view (the most recently refreshed view).1297 """1298 return self._lastView1299 def waitAnyText(self, listOfTexts, partial=False, uiautomatorDump=False, **waitKwArgs):1300 """1301 Wait until any of texts is on the screen.1302 Parameters:1303 listOfTexts (list of string):1304 texts to be waited for.1305 partial (boolean, optional):1306 refer to verifyText. The default is False.1307 uiautomatorDump (boolean, optional):1308 use uiautomator to read view dump from the device.1309 If not given, uiautomatorDump() default will be used.1310 waitTime, pollDelay, beforeRefresh, afterRefresh (optional):1311 refer to wait documentation.1312 Returns list of texts that appear in the first refreshed view1313 that contains at least one of the texts. If none of the texts1314 appear within the time limit, returns empty list.1315 If any of texts is not found from the latest refreshed1316 view, waitAnyText will update the view in pollDelay interval until1317 waitTime is exceeded.1318 """1319 if listOfTexts == []: return []1320 if not self._lastView: self.refreshView(uiautomatorDump=uiautomatorDump)1321 waitArgs, rest = fmbtgti._takeWaitArgs(waitKwArgs)1322 foundTexts = []1323 def observe():1324 for text in listOfTexts:1325 if self.verifyText(text, partial=partial):1326 foundTexts.append(text)1327 return foundTexts != []1328 self.wait(1329 lambda: self.refreshView(uiautomatorDump=uiautomatorDump),1330 observe, **waitArgs)1331 return foundTexts1332 def waitText(self, text, *waitAnyTextArgs, **waitAnyTextKwArgs):1333 """1334 Wait until text appears in any view item.1335 Parameters:1336 text (string):1337 text to be waited for.1338 partial (boolean, optional):1339 refer to verifyText. The default is False.1340 uiautomatorDump (boolean, optional):1341 use uiautomator to read view dump from the device.1342 If not given, uiautomatorDump() default will be used.1343 waitTime, pollDelay, beforeRefresh, afterRefresh (optional):1344 refer to wait documentation.1345 Returns True if text appeared within given time limit,1346 otherwise False.1347 Updates the last view if the text is not found in the latest view1348 and waitTime > 0.1349 """1350 return self.waitAnyText(1351 [text], *waitAnyTextArgs, **waitAnyTextKwArgs) != []1352 def wake(self):1353 """1354 Force the device to wake up.1355 """1356 return self.existingConnection().sendWake()1357 def _loadDeviceAndTestINIs(self, homeDir, deviceName, iniFile):1358 if deviceName != None:1359 _deviceIniFilename = homeDir + os.sep + "etc" + os.sep + deviceName + ".ini"1360 self.loadConfig(_deviceIniFilename, override=True, level="device")1361 if iniFile:1362 self.loadConfig(iniFile, override=True, level="test")1363class Ini:1364 """1365 Container for device configuration loaded from INI files.1366 INI file syntax:1367 [section1]1368 key1 = value11369 ; commented = out1370 # commented = out1371 """1372 def __init__(self, iniFile=None):1373 """1374 Initialise the container, optionally with an initial configuration.1375 Parameters:1376 iniFile (file object, optional):1377 load the initial configuration from iniFile.1378 The default is None: start with empty configuration.1379 """1380 # _conf is a dictionary:1381 # (section, key) -> value1382 self._conf = {}1383 if iniFile:1384 self.addFile(iniFile)1385 def addFile(self, iniFile, override=True):1386 """1387 Add values from a file to the current configuration.1388 Parameters:1389 iniFile (file object):1390 load values from this file object.1391 override (boolean, optional):1392 If True, loaded values override existing values.1393 Otherwise, only currently undefined values are1394 loaded. The default is True.1395 """1396 for line in iniFile:1397 line = line.strip()1398 if line.startswith('[') and line.endswith(']'):1399 section = line[1:-1].strip()1400 elif line.startswith(";") or line.startswith("#"):1401 continue1402 elif '=' in line:1403 key, value = line.split('=', 1)1404 if override or (section, key.strip()) not in self._conf:1405 self._conf[(section, key.strip())] = value.strip()1406 def sections(self):1407 """1408 Returns list of sections in the current configuration.1409 """1410 return list(set([k[0] for k in self._conf.keys()]))1411 def keys(self, section):1412 """1413 Returns list of keys in a section in the current configuration.1414 Parameters:1415 section (string):1416 the name of the section.1417 """1418 return [k[1] for k in self._conf.keys() if k[0] == section]1419 def dump(self):1420 """1421 Returns the current configuration as a single string in the1422 INI format.1423 """1424 lines = []1425 for section in sorted(self.sections()):1426 lines.append("[%s]" % (section,))1427 for key in sorted(self.keys(section)):1428 lines.append("%-16s = %s" % (key, self._conf[(section, key)]))1429 lines.append("")1430 return "\n".join(lines)1431 def set(self, section, key, value):1432 """1433 Set new value for a key in a section.1434 Parameters:1435 section, key (strings):1436 the section, the key.1437 value (string):1438 the new value. If not string already, it will be1439 converted to string, and it will be loaded as a1440 string when loaded from file object.1441 """1442 self._conf[(section, key)] = str(value)1443 def value(self, section, key, default=""):1444 """1445 Returns the value (string) associated with a key in a section.1446 Parameters:1447 section, key (strings):1448 the section and the key.1449 default (string, optional):1450 the default value to be used and stored if there is1451 no value associated to the key in the section. The1452 default is the empty string.1453 Reading a value of an undefined key in an undefined section1454 adds the key and the section to the configuration with the1455 returned (the default) value. This makes all returned values1456 visible in dump().1457 """1458 if not (section, key) in self._conf:1459 self._conf[(section, key)] = default1460 return self._conf[(section, key)]1461# For backward compatibility, someone might be using old _DeviceConf1462_DeviceConf = Ini1463class ViewItem(fmbtgti.GUIItem):1464 """1465 ViewItem holds the information of a single GUI element.1466 """1467 _boundsRegEx = re.compile(r'\[([0-9]+),([0-9]+)\]\[([0-9]+),([0-9]+)\]')1468 def __init__(self, className, code, indent, properties, parent, rawProps, dumpFilename, displayToScreen):1469 self._p = properties1470 self._parent = parent1471 self._className = className1472 self._code = code1473 self._indent = indent1474 self._children = []1475 self._parentsVisible = True1476 if "resource-id" in self._p:1477 self._id = self._p["resource-id"].split(":", 1)[-1]1478 else:1479 self._id = self.property("mID")1480 self._rawProps = ""1481 if not "bounds" in self._p:1482 if not "scrolling:mScrollX" in self._p:1483 self._p["scrolling:mScrollX"] = 01484 self._p["scrolling:mScrollY"] = 01485 self._visible = self._p.get("getVisibility()", "") == "VISIBLE"1486 if "text:mText" in self._p:1487 self._text = self._p["text:mText"]1488 else:1489 self._text = None1490 else:1491 self._visible = True1492 self._text = self._p["text"]1493 fmbtgti.GUIItem.__init__(self, className, self._calculateBbox(displayToScreen), dumpFilename)1494 def addChild(self, child):1495 child._parentsVisible = self.visibleBranch()1496 self._children.append(child)1497 def _calculateBbox(self, displayToScreen):1498 if "bounds" in self._p:1499 try:1500 left, top, right, bottom = [1501 int(v) for v in1502 ViewItem._boundsRegEx.findall(self._p["bounds"])[0]]1503 except IndexError:1504 raise ValueError('invalid bounds "%s"' % (self._p["bounds"],))1505 width = right - left1506 height = bottom - top1507 elif "layout:getLocationOnScreen_x()" in self._p:1508 left = int(self._p["layout:getLocationOnScreen_x()"])1509 top = int(self._p["layout:getLocationOnScreen_y()"])1510 height = int(self._p["layout:getHeight()"])1511 width = int(self._p["layout:getWidth()"])1512 elif "layout:mLeft" in self._p:1513 left = int(self._p["layout:mLeft"])1514 top = int(self._p["layout:mTop"])1515 parent = self._parent1516 while parent:1517 pp = parent._p1518 left += int(pp["layout:mLeft"]) - int(pp["scrolling:mScrollX"])1519 top += int(pp["layout:mTop"]) - int(pp["scrolling:mScrollY"])1520 parent = parent._parent1521 height = int(self._p["layout:getHeight()"])1522 width = int(self._p["layout:getWidth()"])1523 else:1524 raise ValueError("bounding box not found, layout fields missing")1525 screenLeft, screenTop = displayToScreen(left, top)1526 screenRight, screenBottom = displayToScreen(left + width, top + height)1527 return (screenLeft, screenTop, screenRight, screenBottom)1528 def children(self): return self._children1529 def className(self): return self._className1530 def code(self): return self._code1531 def indent(self): return self._indent1532 def id(self): return self._id1533 def parent(self): return self._parent1534 def properties(self): return self._p1535 def property(self, propertyName):1536 return self._p.get(propertyName, None)1537 def visibleBranch(self):1538 """Returns True if this item and all items containing this are visible1539 up to the root node"""1540 return self._parentsVisible and self.visible()1541 def text(self):1542 return self._text1543 def content_desc(self):1544 if "content-desc" in self._p:1545 return self._p["content-desc"]1546 elif "accessibility:getContentDescription()" in self._p:1547 return self._p["accessibility:getContentDescription()"]1548 else:1549 return None1550 def visible(self):1551 return self._visible1552 def dump(self):1553 p = self._p1554 return ("ViewItem(\n\tchildren = %d\n\tclassName = '%s'\n\tcode = '%s'\n\t" +1555 "indent = %d\n\tproperties = {\n\t\t%s\n\t})") % (1556 len(self._children), self._className, self._code, self._indent,1557 '\n\t\t'.join(['"%s": %s' % (key, p[key]) for key in sorted(p.keys())]))1558 def dumpProperties(self):1559 rv = []1560 if self._p:1561 for key in [k for k in sorted(self._p.keys()) if not "layout:" in k and not "padding:" in k and not "drawing:" in k]: # sorted(self._p.keys()): # [k for k in sorted(self._p.keys()) if not ":" in k]:1562 rv.append("%s=%s" % (key, self._p[key]))1563 return "\n".join(rv)1564 def __str__(self):1565 if self.text():1566 text = ", text=%s" % (repr(self.text()),)1567 else:1568 text = ""1569 if "content-desc" in self._p and self._p["content-desc"]:1570 text += ", content_desc=%s" % (repr(self.content_desc(),))1571 return ("ViewItem(className=%s, id=%s, bbox=%s%s)" % (1572 repr(self._className), repr(self.id()), self.bbox(), text))1573class View(object):1574 """1575 View provides interface to screen dumps from Android. It parses1576 the dump to a hierarchy of ViewItems. find* methods enable searching1577 for ViewItems based on their properties.1578 """1579 def __init__(self, screenshotDir, serialNumber, dump, displayToScreen=None,1580 itemOnScreen=None, intCoords=None):1581 self.screenshotDir = screenshotDir1582 self.serialNumber = serialNumber1583 self._viewItems = []1584 self._errors = []1585 self._lineRegEx = re.compile("(?P<indent>\s*)(?P<class>[\w.$]+)@(?P<id>[0-9A-Fa-f]{4,8} )(?P<properties>.*)")1586 self._olderAndroidLineRegEx = re.compile("(?P<indent>\s*)(?P<class>[\w.$]+)@(?P<id>\w)(?P<properties>.*)")1587 self._propRegEx = re.compile("(?P<prop>(?P<name>[^=]+)=(?P<len>\d+),)(?P<data>[^\s]* ?)")1588 self._dump = dump1589 self._rawDumpFilename = self.screenshotDir + os.sep + fmbtgti._filenameTimestamp() + "-" + self.serialNumber + ".view"1590 file(self._rawDumpFilename, "w").write(self._dump)1591 if displayToScreen == None:1592 displayToScreen = lambda x, y: (x, y)1593 if itemOnScreen == None:1594 itemOnScreen = lambda item: True1595 self._itemOnScreen = itemOnScreen1596 if intCoords == None:1597 intCoords = lambda x, y: (int(x), int(y))1598 self._intCoords = intCoords1599 try:1600 if dump.startswith("<?xm"):1601 self._parseUIAutomatorDump(dump, self._rawDumpFilename, displayToScreen)1602 else:1603 self._parseDump(dump, self._rawDumpFilename, displayToScreen)1604 except Exception, e:1605 self._errors.append((-1, "", "Parser error"))1606 def viewItems(self): return self._viewItems1607 def errors(self): return self._errors1608 def dumpRaw(self): return self._dump1609 def dumpItems(self, itemList = None):1610 if itemList == None: itemList = self._viewItems1611 l = []1612 for i in itemList:1613 l.append(self._dumpItem(i))1614 return '\n'.join(l)1615 def dumpTree(self, rootItem = None):1616 l = []1617 if rootItem != None:1618 l.extend(self._dumpSubTree(rootItem, 0))1619 else:1620 for i in self._viewItems:1621 if i._indent == 0:1622 l.extend(self._dumpSubTree(i, 0))1623 return '\n'.join(l)1624 def _dumpSubTree(self, viewItem, indent):1625 l = []1626 i = viewItem1627 l.append(" "*indent + self._dumpItem(viewItem))1628 for i in viewItem.children():1629 l.extend(self._dumpSubTree(i, indent + 4))1630 return l1631 def _dumpItem(self, viewItem):1632 i = viewItem1633 if i.text() != None: t = '"%s"' % (i.text(),)1634 else: t = None1635 return "id=%s cls=%s text=%s bbox=%s vis=%s" % (1636 i.id(), i.className(), t, i.bbox(), i.visibleBranch())1637 def filename(self):1638 return self._rawDumpFilename1639 def findItems(self, comparator, count=-1, searchRootItem=None, searchItems=None, onScreen=False):1640 """1641 Returns list of ViewItems to which comparator returns True.1642 Parameters:1643 comparator (function that takes one parameter (ViewItem))1644 returns True for all accepted items.1645 count (integer, optional):1646 maximum number of items to be returned.1647 The default is -1 (unlimited).1648 searchRootItem (ViewItem, optional):1649 search only among items that are children of1650 searchRootItem. The default is None (search from all).1651 searchItems (list of ViewItems, optional):1652 search only among given items. The default is None,1653 (search from all).1654 onScreen (boolean, optional):1655 search only among items that are on screen. The1656 default is False.1657 """1658 foundItems = []1659 if count == 0: return foundItems1660 if searchRootItem != None:1661 # find from searchRootItem and its children1662 if comparator(searchRootItem) and (1663 not onScreen or1664 searchRootItem.visibleBranch() and self._itemOnScreen(searchRootItem)):1665 foundItems.append(searchRootItem)1666 for c in searchRootItem.children():1667 foundItems.extend(self.findItems(comparator, count=count-len(foundItems), searchRootItem=c, onScreen=onScreen))1668 else:1669 if searchItems != None:1670 # find from listed items only1671 searchDomain = searchItems1672 else:1673 # find from all items1674 searchDomain = self._viewItems1675 for i in searchDomain:1676 if comparator(i) and (1677 not onScreen or1678 i.visibleBranch() and self._itemOnScreen(i)):1679 foundItems.append(i)1680 if count > 0 and len(foundItems) >= count:1681 break1682 return foundItems1683 def findItemsByText(self, text, partial=False, count=-1, searchRootItem=None, searchItems=None, onScreen=False):1684 """1685 Returns list of ViewItems with given text.1686 """1687 if partial:1688 c = lambda item: item.text().find(text) != -1 if item.text() != None else False1689 else:1690 c = lambda item: item.text() == text1691 return self.findItems(c, count=count, searchRootItem=searchRootItem, searchItems=searchItems, onScreen=onScreen)1692 def findItemsById(self, id, count=-1, searchRootItem=None, searchItems=None, onScreen=False):1693 """1694 Returns list of ViewItems with given id.1695 """1696 c = lambda item: item.id() == id1697 return self.findItems(c, count=count, searchRootItem=searchRootItem, searchItems=searchItems, onScreen=onScreen)1698 def findItemsByClass(self, className, partial=True, count=-1, searchRootItem=None, searchItems=None, onScreen=False):1699 """1700 Returns list of ViewItems with given class.1701 """1702 if partial: c = lambda item: item.className().find(className) != -11703 else: c = lambda item: item.className() == className1704 return self.findItems(c, count=count, searchRootItem=searchRootItem, searchItems=searchItems, onScreen=onScreen)1705 def findItemsByIdAndClass(self, id, className, partial=True, count=-1, searchRootItem=None, searchItems=None, onScreen=False):1706 """1707 Returns list of ViewItems with given id and class.1708 """1709 idOk = self.findItemsById(id, count=-1, searchRootItem=searchRootItem, onScreen=onScreen)1710 return self.findItemsByClass(className, partial=partial, count=count, searchItems=idOk, onScreen=onScreen)1711 def findItemsByContentDesc(self, content_desc, partial=False, count=-1, searchRootItem=None, searchItems=None, onScreen=False):1712 """1713 Returns list of ViewItems with given content-desc.1714 Works on uiautomatorDumps only.1715 """1716 if partial:1717 c = lambda item: item.content_desc().find(content_desc) != -11718 else:1719 c = lambda item: item.content_desc() == content_desc1720 return self.findItems(c, count=count, searchRootItem=searchRootItem, searchItems=searchItems, onScreen=onScreen)1721 def findItemsByRawProps(self, s, count=-1, searchRootItem=None, searchItems=None, onScreen=False):1722 """1723 Returns list of ViewItems with given string in properties.1724 """1725 c = lambda item: item._rawProps.find(s) != -1...

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