Ask a Question

Using .ClickItem() to set dropdown takes too long, but .value doesn't fire onChange in the browser.

SOLVED
aceataldot
New Contributor

Using .ClickItem() to set dropdown takes too long, but .value doesn't fire onChange in the browser.

Hello, I've been beating my head against the wall on this one for some time now.  I'm trying to use TestComplete to create an set of automated tests that will run nightly to see if anyone "broke the build" for our very large web application.
 
The biggest issue at the moment regards the setting of values for ComboBoxes a.k.a. dropdowns.  The preferred way to set the value of one of these is using the ClickItem() method.  However, some of our dropdowns contain over 1,000 items and it can take 30 seconds or more to set the value.
 
Here is the function to set the value that I created  (the wait loop is to try and handle slow JSON calls.):
def SetJsonDropdownClick(fieldHandle, newName, newValue, waitForJson):
    if (waitForJson):
        stopTime = GetTickCount() + 20000;
        while (GetTickCount() < stopTime):
            if fieldHandle.wItemCount >= 2:
                fieldHandle.ClickItem(newName)
                       
                if fieldHandle.value == newValue:
                    break
       
            aqUtils.Delay(100)
    else:       
        fieldHandle.ClickItem(newName)
 
However, I found that assigning the value property can set the value property with sub-second response time.
def SetJsonDropdownUd(fieldHandle, newValue, waitForJson, triggerJson):
    i = 0
    if (waitForJson):
        stopTime = GetTickCount() + 20000;
        while (GetTickCount() < stopTime):
            if fieldHandle.wItemCount >= 2:
                fieldHandle.value = newValue
               
                if fieldHandle.value == newValue:
                    break
            i += 1
            Log.Message("Pass: " + str(i) + " Count: " + str(fieldHandle.wItemCount) + " Values [" + fieldHandle.value + "]/[" + newValue + "]")
            Log.Message(fieldHandle.innerHTML)
            aqUtils.Delay(100)
            Aliases.browser.Refresh()
    else:       
        fieldHandle.value = newValue
 
While this cuts the setting time to a consistent sub-second response, it does not raise the OnChange event that triggers JSON calls to fill other dropdowns on the page.  I have confirmed by looking at similar issues on this site that this is normal behavior for setting a value that way.  I even added the following to the end to get OnChange to fire.
    if (triggerJson):
        fieldHandle.Keys("[Up][Down]")  
 
While this reliably fires OnChange, it actually does it twice.  And sometimes, the first one takes longer than the second (desired) one and the wrong data fills the next dropdown(s) and causes the test script to fail.
The following may be marginally faster:
def SetJsonDropdownItemList(fieldHandle, newName, newValue, waitForJson):
    if (waitForJson):
        stopTime = GetTickCount() + 20000;
        while (GetTickCount() < stopTime):
            i = -1
            if fieldHandle.wItemCount >= 2:
                itemListWork = fieldHandle.wItemList.split(';')
                       
                for i in range(len(itemListWork)):
                    if (itemListWork[i] == newName):
                        fieldHandle.ClickItem(i)
                        break
       
            if (i >= 0 & i < len(itemListWork)):
                break
            else:   
                aqUtils.Delay(100)
    else:       
        itemListWork = fieldHandle.wItemList.split(';')
                       
        for i in range(len(itemListWork)):
            if (itemListWork[i] == newName):
                fieldHandle.ClickItem(i)
                break
 
It still takes time due to the manual search.  Since nearly all our dropdowns are sorted alphanumerically, I can implement a binary search.  But, still, this and the text based ClickItem take 50% longer than setting the value.
 
I also spent a good amount of time looking at https://community.smartbear.com/t5/TestComplete-Desktop-Testing/ClickItem-Very-Slow-For-DropDown-Com... While we have the same symptom, our dropdown list items are children of the dropdown itself.  And, the slow selection happens whether the dropdown is filled at page creation or set up later with a JSON call.
 
So, I either need a way to speed up ClickItem() or to trigger the fields OnChange event when setting the value.  And, I know that the RaiseEvent function does not handle HTML objects.
 
We are using Python as the scripting language and the TC version is 14.30.
 
Contractor for ALDOT in Montgomery, AL
5 REPLIES 5
tristaanogre
Esteemed Contributor

I would go with what you're doing with setting the value directly.  But then, you should be able to see on your object in the object browser of TestComplete the OnChange event method that you SHOULD be able to call directly.  At least, that's how I've done it in the past.  YMMV.


Robert Martin
[Hall of Fame]
Please consider giving a Kudo if I write good stuff
----

Why automate?  I do automated testing because there's only so much a human being can do and remain healthy.  Sleep is a requirement.  So, while people sleep, automation that I create does what I've described above in order to make sure that nothing gets past the final defense of the testing group.
I love good food, good books, good friends, and good fun.

Mysterious Gremlin Master
Vegas Thrill Rider
Extensions available

Sounds good.

 

However, I apparently don't have the right syntax when I'm calling it.

I've tried both the full path: (APP_URL is replaced the actual URL in the script.)     Sys.Browser("chrome").Page(APP_URL).Panel(1).Panel("BodyContainer").Panel("page_content").Panel("rightColumn").Panel("scrollable_area").Form(0).Panel(0).Panel(0).Select("RegionId").OnChange()

Or, the alias

fieldHandle.OnChange()

Aliases.browser.page16438.form.selectBureauRegion.OnChange()

 

But, when I call it, I get the error message:

TypeError: 'NoneType' object is not callable

 

So, do I need be specific to the Javascript by using iether region.change or updateOffices() or something else?

 

   region.change(function () {
        area.val("");
        updateOffices();
    });

Contractor for ALDOT in Montgomery, AL

Have you tried to write your own JavaSciprt function to select values from the drop-down list?

Link:


https://support.smartbear.com/testcomplete/docs/app-testing/web/general/common-tasks/javascript.html...

 

It's a kind of a workaround.

 

1) Run your own script, in which you will set the drop-down values
2) obtain the values
3) pass it to the TestComplete scripts

Based on your response, I did try something along those lines.  Since my scripts were correclty setting the drop down values, I left that alone.  What I tried to do was call the function that the OnChange() event calls.

I tried this: 

# Enter required fields & Save
Aliases.browser.page16438.form.selectBureauRegion.value = bureauRegionId;
curPage = Sys.Browser("*").Page("*")
curPage.contentDocument.Script.updateOffices()

 

It attempts to call the function direclty, but what I get is this:

2019-12-17_16-25-58.png

 

I also tried it via eval as below:

# Enter required fields & Save
Aliases.browser.page16438.form.selectBureauRegion.value = bureauRegionId;
curPage = Sys.Browser("*").Page("*")
evalStr = "rootPath=\"" + ProjectSuite.Variables.ServerUrl + "/\"; updateOffices()"
# curPage.contentDocument.Script.eval(evalStr)

 

When I run this, the call to updateOffices() is apparently skipped.  I did enough debugging to determine that this is correct.  Occasionally, it will blow up instead.

 

In both cases, it does not appear to find the JavaScript function.  Now, updateOffices() is defined is a .js file that the page loads as part of its operation.

 

Do I need to do something more for it to find the function?

Contractor for ALDOT in Montgomery, AL

From SmartBear support we got an answer that seems to be good enough.

 

In short, we switched from Chrome to Firefox for the browser for these test scripts.  Using Click Item in Firefox is nearly as fast as the setting the .Value directly and the JSON is automatically triggered.

Contractor for ALDOT in Montgomery, AL
cancel
Showing results for 
Search instead for 
Did you mean: