Get QML element in Squish by id or objectName using findObject () or waitForObject () without an object map

How to get a QML element by id or objectName with findObject()or waitForObject()without an object map? Is it possible?

Consider:

Item {
    id: page
    objectName: "pageObject"

    Text {
        id: foobar
        objectName: "lorem"
        text: "ipsum"
    }
}

I would like to access foobar text in a test script like:

obj = findObject("foobar")
if obj.text == "ipsum":
    test.passes("all good")
else:
    test.fail("uh oh")

I also tried:

obj = findObject("lorem")
obj = findObject("{name='lorem'}")
obj = findObject("{name='lorem' type='Text'}")
obj = findObject("{objectName='lorem'}")
obj = findObject("{objectName='lorem' type='Text'}")
+4
source share
3 answers

I ended up solving the problem only by having the root level object in the object map. All other objects are repeated in code using the following functions.

import sys
import time

# Definitions
ROOT_SYMBOLIC_OBJECT = ":_KMainView"

# Object finding functions
def findSymbolic(symbolicName):
    # Note: give Squish symbolic name like ":Foobar"
    try:
        obj = findObject(symbolicName)
    except LookupError:
        sys.exc_clear()
        test.log("FAIL: Root object not found: " + symbolicName)
        sys.exit()

    return obj

def findRoot():
    return findSymbolic(ROOT_SYMBOLIC_OBJECT)

def findFlat(fromElement, findId, occurence, stopOnFail, verbose):
    start = time.time()
    result = None
    found = 0

    if fromElement and hasattr(fromElement, 'children'):
        children = object.children(fromElement)
        for child in children:
            if hasattr(child, 'id') and child.id == findId:
                found += 1
                if found == occurence:
                    result = child
                    break

    if result == None and stopOnFail:
        test.log("FAIL: findFlat: " + findId + " not found")
        sys.exit()

    if verbose:
        printElapsed("findFlat", findId, start)

    return result

def findRecursive(fromElement, findId, occurence):
    return findRecursiveWithOptions(fromElement, findId, occurence, True, False, True)

def findRecursiveWithOptions(fromElement, findId, occurence, stopOnFail, verbose, skipUnnamed):
    start = time.time()
    found = 0
    depth = -1

    obj, found, depth = objIter(fromElement, findId, occurence, verbose, skipUnnamed, found, depth)

    if found == occurence:
        printElapsed("findRecursive ok", findId, start)
        return obj

    printElapsed("findRecursive not found", findId, start)
    if stopOnFail:
        test.log("FAIL: findRecursive:" + findId + " not found.")
        sys.exit()

    return None 

def objIter(fromElement, findId, occurence, verbose, skipUnnamed, found, depth):
    depth += 1

    if verbose:
        printObjIter(fromElement, depth)

    children = object.children(fromElement)
    for child in children:
        if hasattr(child, 'id'):
            if child.id == findId:
                found += 1
                if found == occurence:
                    return child, found, depth
        elif skipUnnamed:
            continue

        obj, found, depth = objIter(child, findId, occurence, verbose, skipUnnamed, found, depth)
        depth = depth - 1
        if found == occurence: 
            return obj, found, depth

    return None, found, depth

def findRecursiveList(fromElement, findId):
    return findRecursiveListWithOptions(fromElement, findId, True, False, True)

def findRecursiveListWithOptions(fromElement, findId, stopOnFail, verbose, skipUnnamed):
    start = time.time()
    objList = []
    depth = -1

    objList, depth = objListIter(fromElement, findId, verbose, skipUnnamed, objList, depth)

    printElapsed("findRecursiveList", findId, start)
    return objList 

def objListIter(fromElement, findId, verbose, skipUnnamed, objList, depth):
    depth += 1

    if verbose:
        printObjIter(fromElement, depth)

    children = object.children(fromElement)
    for child in children:
        if hasattr(child, 'id'):
            if child.id == findId:
                objList.append(child)
        elif skipUnnamed:
            continue

        objList, depth = objListIter(child, findId, verbose, skipUnnamed, objList, depth)
        depth = depth - 1

    return objList, depth

# Utilities
def printElapsed(functionName, objectId, start):
    elapsed = time.time() - start
    test.log(functionName + " - " + objectId + " in " + str(elapsed) + "s.")

def printObjIter(element, depth):
    dashes = "-" * depth

    if hasattr(element, 'id'):
        test.log(dashes + " " + str(element.id))
    else:
        test.log(dashes + " [unnamed]")

Sample test script for a QML question:

startApplication("exampleapp") # Launch application binary 'exampleapp'
snooze(10) # Let it start

root = findRoot()
page = findFlat(root, "page", 1, True, False)
foobar = findFlat(page, "foobar", 1, True, False)

# Also just: foobar = findRecursive(root, "foobar", 1)

if foobar.text == "ipsum":
    test.passes("text is ok")
else:
    test.fail("Incorrect foobar text: " + foobar.text)
0
source

: findObject ( "{container = ': _ QQuickView' id = 'foobar' type = 'Text' visible = 'true'}" )

[Navigate] β†’ [Open Symbolic Name], " "

0

You can replace the symbolic name ": _KMainView" stored in ROOT_SYMBOLIC_OBJECT with its real name, since the symbolic name is simply the owner of the place for the real names:

Article - How Squish Scans Real Names from Symbolic Names

0
source

Source: https://habr.com/ru/post/1529384/


All Articles