Forum Discussion

Novari-QA's avatar
Novari-QA
Frequent Contributor
7 years ago

Keyword tests are unable to identify functions

Keyword tests are unable to to see function.names.  See the code below.

The script is called LoginPage.js

var page = {
  form: {
    username: Aliases.browser.pageLogin.form.textboxUsername,
    password: Aliases.browser.pageLogin.form.textboxPassword,
    submitButton: Aliases.browser.pageLogin.form.buttonSubmit
  }
}

function abc()
{
  Login.Positive("Admin", "123456");
}


var Login = 
{
  Positive: function(pUsername, pPassword)
  {
    page.form.username.SetText(pUsername);
    page.form.password.SetText(pPassword);
    page.form.submitButton.ClickButton();
  },
  Negitive: function(pUsername, pPassword)
  {
    page.form.username.SetText(pUsername);
    page.form.password.SetText(pPassword);
    page.form.submitButton.ClickButton();
  }
}

function Login() {}

Login.Positive = function(pUsername, pPassword)
{
  page.form.username.SetText(pUsername);
  page.form.password.SetText(pPassword);
  page.form.submitButton.ClickButton();
}

Login.Negitive = function(pUsername, pPassword)
{
  page.form.username.SetText(pUsername);
  page.form.password.SetText(pPassword);
  page.form.submitButton.ClickButton();
}


I have two different examples, both with the same outcome. When I try to call Login.Positive in my keyword test or my projects main run, it cannot find the function name. All it can find is Login and ABC.

Help please, I would like to order my scripts this way.

The script is called the page. while the functions are grouped by a common object. For example, the action of login in is a common object with multiple ways to login and multiple ways to test logging in. Hence the object Login. With functions that perform actions around that common object.

If there are better ways to organize my scripts, please let me know.

 

  • Exactly... also, prevents the "copy paste" code problem from your original OP...  it's really generally bad practice to have the same code showing up almost EXACTLY the same way in multiple places... better to have the code modularized in one spot that is "smart" enough code to do what it needs to no matter where it is called.  Again, keep in mind, you're creating building blocks for your testers...  if you give them too many blocks that look almost exactly the same, you'll end up with more mistakes as the testers can get easily confused... 

  • tristaanogre's avatar
    tristaanogre
    Esteemed Contributor

    Correct, keyword tests "Run Script Routine" is exactly that... it recognizes and only runs what it parses out as routines/functions that are parented on the script file itself.  Login.Postive and Login.Negitive are methods on the Login object... something not exposed as a script routine.

     

    If you want to execute the code in that way, you can use "Code Snippet" to execute. However, if you want to just execute the Positive and Negative, define them as separate functions within the LoginPage.js like so. 

     

    var page = {
      form: {
        username: Aliases.browser.pageLogin.form.textboxUsername,
        password: Aliases.browser.pageLogin.form.textboxPassword,
        submitButton: Aliases.browser.pageLogin.form.buttonSubmit
      }
    }
    
    function Positive(pUsername, pPassword)
    {
      page.form.username.SetText(pUsername);
      page.form.password.SetText(pPassword);
      page.form.submitButton.ClickButton();
    }
    
    function Negitive(pUsername, pPassword)
    {
      page.form.username.SetText(pUsername);
      page.form.password.SetText(pPassword);
      page.form.submitButton.ClickButton();
    }

    However, that feels redundant... all you REALLY want is a function that does a username/password entry for Login... it's the data that actually determines postive vs. negative and what you do with it.  So, to simplify even further:

     

    var page = {
      form: {
        username: Aliases.browser.pageLogin.form.textboxUsername,
        password: Aliases.browser.pageLogin.form.textboxPassword,
        submitButton: Aliases.browser.pageLogin.form.buttonSubmit
      }
    }
    
    function Login(pUsername, pPassword, isPositive = true)
    {
      page.form.username.SetText(pUsername);
      page.form.password.SetText(pPassword);
      page.form.submitButton.ClickButton();
    if (isPositive) {
    //Perform positive validation
    }
    else {
    //Perform negative validation
    } }

     

    This way you call a script routine to execute a test on logging in.  You determine, by a boolean parameter, whether the test will check for a positive workflow or a negative workflow.  It's all just logging in.

    • Novari-QA's avatar
      Novari-QA
      Frequent Contributor

      certainly my example can be simplified as stated above, however the pages get more complex. I am trying to build a bunch of predefined objects which a "non" coder can utilitize in keyword tests. 

      I could just make a ton of scripts rather a ton of function. So instead of stating LoginPage.js, I can have a folder called LoginPage with a script called Login.

      Hmm. 

      • tristaanogre's avatar
        tristaanogre
        Esteemed Contributor

        However works for you works... but the limitation is that "Run Script Routine" does just that... runs a script routine... it doesn't run a method of an object unless that object is exposed in some way... Scripts != objects... they are files... units of code... they may CONTAIN objects but they are not seen as objects by TestComplete.