Forum Discussion

hkim5's avatar
hkim5
Staff
4 years ago

TestComplete and Device Cloud Add On

Hi All,

 

Today, I wanted to discuss the Device Cloud add on and its practical usage just a bit further, most of what I'm talking about is pretty well covered in the documentation here: https://support.smartbear.com/testexecute/docs/running/cross-platform-tests/run/command-line.html

In short, once we have a stable set of test cases that we'd like to run in parallel across multiple OS and browser configurations, this should be your go-to move!

This will make use of a newly released application called "TestExecuteLite.exe", which supports the launching multiple instances of the application - hence the "parallels" as the documentation above refers to. 

Things to note: 

  • TestExecuteLite (henceforth to be called TElite, can launch multiple instances, and is currently supported in the Jenkins plugin/pipeline, Azure DevOps pipeline, and the CMD line)
  • We need to use the "new name mapping" of the Xpath and CSS selectors
  • We should try to make our entire pjs only contains web-app based projects/tests (no LL procedures, desktop based tests/ testedapps, etc.)

To start, we need to create a function that will consume our custom command line parameters. The docs above have the same function, but here is mine (which is annotated just a little bit more)

 

config = ""

def processCommandLineArguments():
  #ParamCount returns an integer of # of parameters used in cmd line args
  for i in range(0, BuiltIn.ParamCount() + 1): 
    #added 1 to the range above for list indexing to print out the info about the last cmd arg
    Log.Message(BuiltIn.ParamStr(i)) #print each of the cmd args, looks like for some reason tc cant print the custom arg entry at the very end
    processCommandLineArgument(BuiltIn.ParamStr(i)) #ParamStr returns a str of each of the cmd line entries ie. /config=Safari

def processCommandLineArgument(arg):
  items = arg.split("=") #using python str split method to create a new list variable with newly split strs as each of the index items
  
  if (len(items) != 2):
    #if the cmd arg didnt use an '=' to divide up (hence not a custom arg) return blank 
    #(since len(items) woudl be 1 if they didnt use '=' in the cmd line args)
    return 

  #get rid of break characters, replace backslash with nothing for items[0] entries (looking for the custom arg)
  item = aqString.ToLower(aqString.Replace(aqString.Trim(items[0]), "/", "")) 
  
  if (item == "config"): #if we find the custom arg that we are looking for (which is "config")
    Log.Message(items[1]) #this should read as the caps name that we want to run
    global config # Set the config variable for this unit using the "global" keyword
    config = items[1] #access the index 1 entry of items (this should be the config name i.e Safari)

 

Now that we can receive the command line parameters dictating which config to use, we need to create another function which will tell TestComplete/TestExecuteLite what those configs are in the JSON format that the Run Remote Browser expects as a part of the parameters. We do it with the code below (once again documented, but I changed it slightly to make it a bit more readable)

 

config_dict = {} #empty dict
#implmenting a switch case style dictionary for the get capabilities function instead 
#(dict support for JSON notation makes it easier to manipulate later)
def getCapabilities(argument):
    #list out some capabilities that we want to use
    config_dict = {
        "Safari": {"platform":"Mac OSX 10.15","browserName": "Safari","version": "13","screenResolution": "1366x768","record_video":"true"},
        "Edge": {"platform":"Windows 10","browserName":"MicrosoftEdge","version":"79","screenResolution":"1366x768","record_video": "true"},  
        "Chrome": {"platform":"Windows 10","browserName":"Chrome","version":"80x64","screenResolution":"1366x768","record_video": "true"},
        }
    #get the caps in dictionary format- json-ish standard, otherwise, output "invalid config"
    capabilities = config_dict.get(argument, "Invalid Config") 
    #assign current testcase name to the caps-dict['name']  
    capabilities['name'] = str(aqTestCase.CurrentTestCase.Name) + " " + argument + " Test" 
    return capabilities #ouput the cmd line config in caps format - to be consumed in our actual test

 

Now that we have these helper functions, we want to create one more function so that we can generalize our tests to receive the command line arguments from either the cmd line or from our CICD frameworks, such that it kicks off our tests in the correct configurations in our remote browser.

 

def startUp_withConfigs(URL):
  # Get capabilities
  processCommandLineArguments()
  aCap = getCapabilities(config) #get the corresponding capabilities from the getCapabilities() function
  if (aCap != None):
    server = "http://hub.crossbrowsertesting.com:80/wd/hub" #defining our CBT server no need to ever change this
    Browsers.RemoteItem[server, aCap].Run(URL) #launching remote browser

 

Now, if you disable/comment out the first line of your web app functional tests which make references to hard coded local/remote browsers, this startUp_withConfigs(URL) function will take the command line arguments, parse it, and supply the correct capabilities and start up the remote browser session to the specified URL (of course we don't need to make this URL mandatory). 

If you've build some modular test cases, you can go ahead and start changing/disabling/commenting and replacing the other "blocks" of code to use similarly refactored, generalized code like: 

 

def NavigateCurrentBrowser(URL):
  Browsers.CurrentBrowser.Navigate(URL)
  
def MaximizeCurrentBrowser():
  Aliases.browser.BrowserWindow(0).Maximize()

 

to make sure that we continue to use the active remote browser session, stay on the designated web page, and to make sure that our remote browsers are maximized (sometimes elements will face an object not found error if this isn't true, at least on non-mobile browsers).

Now your test scripts may look something like this:

where the previous lines of code expecting a local browser, or a hard coded remote browser config has been commented out

or for your keyword tests, something like the following screenshot attached

such that when run through a CICD framework or the CMD line, we achieve as many parallels as we described within the configs section alongside the tests we selected (won't go into deployment configurations for CICD and cmd line since that is also well documented, and without code, so no further annotations needed from me):

I'd love to hear if anyone in the community has some more practical usage of the TELite application, or any questions or concerns surrounding the example shown above. Being able to make certain of your web app's functionality across multiple configs of major browsers can certainly help with the traditional browser coverage in testing, but now we are able to do it in parallel using a combination of 3-4 functions. What are some other ways that the community has been using in order to increase your testing velocity when it comes to web app testing?

2 Replies

  • Golf01's avatar
    Golf01
    New Contributor

    We have to using "TestExecuteLite.exe" for testing now. But command or Jenkins pipline all failed.

    I have try the steps as your document, but we cannot setup the scripts.

    We are testing website for automation.

     

    When we are using command of TestExecute is worked, but using TELite will be failed.

    The Command as screenshot.