Selenium IDE Rollups With Arguments

As I prepare another release of Store Locator Plus with some new features I’ve decided it is time to up my QA-fu with Selenium.   I’ve been using Selenium IDE for a while now and find that , despite being free, it is one of the best user experience testing tools out there.    I’ve paid for a few testing tools over the years and I always come back to Selenium IDE.     The paid tools are do not offer a lot more and are just as complex to learn to get advanced testing techniques in place.

Simple Rollups

Speaking of advanced techniques, here is some new skills I picked up regarding Selenium ID rollups.   If you are not aware of what a rollup is, in the simplest form it is an easy way to group together oft-repeated commands in Selenium into a single entry.  This makes your test files easier to read and limits errors by ensuring consistency across your tests.   For example, of of my earlier rollups does a simple “syntax error” check which is very useful when running tests of my WordPress plugins or the SaaS version of the application when I have debug mode enabled.  It does little more than scan the body of the web page for known strings that typically mean the app crashed.

Here is what that rollup looks like:

manager.addRollupRule({
    name: 'check_for_syntax_errors',
    description: 'Check for PHP syntax errors, notices, warnings.',
    commandMatchers: [],
    getExpandedCommands: function(args) {
        var commands = [];

        commands.push({ command: 'setSpeed'         , target: '0'           , value: ''                                 });
        commands.push({ command: 'assertNotText'    , target: '//body'      , value: '*Notice: Undefined*'              });
        commands.push({ command: 'assertNotText'    , target: '//body'      , value: '**Notice: Trying to get*'         });
        commands.push({ command: 'assertNotText'    , target: '//body'      , value: '*Notice: Use of*'                 });
        commands.push({ command: 'assertNotText'    , target: '//body'      , value: '*Fatal error:*'                   });
        commands.push({ command: 'assertNotText'    , target: '//body'      , value: '*Strict Standards:*'              });
        commands.push({ command: 'assertNotText'    , target: '//body'      , value: '*Warning: call_user_func_array*'  });
        commands.push({ command: 'assertNotText'    , target: '//body'      , value: '*failed to open stream*'          });
        commands.push({ command: 'assertNotText'    , target: '//body'      , value: 'headers already sent'             });
        commands.push({ command: 'setSpeed'         , target: '200'         , value: ''                         });

        return commands;
    }
});

 

Rollups With Arguments

Today I added a new level to my rollups: parameter passing.

This allows you to create a single rollup that serves multiple purposes.  For example, before today I had 4 different rollups.  One to open each of 4 different tabs in my application.   I’d call rollup open_general_tab or open_experience_tab depending on what I was about to test next.

Now I have a smaller more efficient rollup thanks to the use of arguments.   I now call rollup open_tab tab=slp_general or rollup open_tab tab=slp_experience and the back end runs a single small set of code.  That means less memory being consumed in the browser and less chance of errors as the codebase is reduced by nearly a factor of 4 in this case.

Here is my open tab rollup:

manager.addRollupRule({
    name: 'open_tab',
    description: 'Open the settings tab and check for errors.',
    args: [ { name: 'tab' , description: 'tab name' } ],
    commandMatchers: [],
    getExpandedCommands: function(args) {
        var commands = [];

        commands.push({ command: 'setSpeed'             , target: '200'                                     , value: ''                         });
        commands.push({ command: 'open'                 , target: '/wp-admin/admin.php?page=' + args.tab    , value: ''                         });
        commands.push({ command: 'waitForElementPresent', target: 'id=footer-thankyou'                      , value: ''                         });
        commands.push({ command: 'rollup'               , target: 'check_for_syntax_errors'                 , value: ''                         });
        commands.push({ command: 'setSpeed'             , target: '0'                                       , value: ''                         });

        return commands;
    }
});

 

And here is how it looks in the IDE:

Selenium IDE Rollup With Args 2017-04-18_16-05-38
Selenium IDE Rollup With Args 2017-04-18_16-05-38

If you are not familiar with extending Selenium, you will want to review their documentation on creating rollups.    It is a basic JavaScript file that you include in Selenium IDE by setting the file name as a core extension.   I also strongly recommend getting a flow control extension to Selenium IDE as well.  I’ve “rolled my own” based on the ide-flow-control modules of others called “Go With The Flow” the includes basic if, gotoIf, etc. calls.

 

6 thoughts on “Selenium IDE Rollups With Arguments

  1. Hello Lance,

    I’ve started to use rollups after reading this entry and it simplifies my tests a lot so thank you very much. However, I’m having a problem when trying to use gotoIf and label in the rollups? Basically, the label command is ignored. Have you experienced this as well? I hardly have found just another person reporting a similar problem but no answers or explanations

    1. You cannot use custom some of the custom commands in the rollups. It has to do with how the JavaScript is loaded for the custom commands (those are JavaScript as well) and the scope of the variables commands like labels / goto have set.

      However, since rollups are JavaScript anonymous functions you can use any JavaScript trickery you’d like to build the rollup. You can simulate your own gotoIf commands using standard JavaScript if commands. Any stored values are in the storedVars array.

      This is not a direct example of gotoIf but you can see how I’ve build some JavaScript logic into my rollup here:

      var all_set = ( ! args.read_again );

      if ( all_set ) {
      for (var i = 0; i < num_plugins; ++i) {
      if (typeof storedVars[plugins[i] + '_active' ] === 'undefined') {
      all_set = false;
      break;
      }
      }
      }

      var commands = [];

      if ( ! all_set ) {
      commands.push({command: 'setSpeed', target: '200', value: 'tab=slp_experience'});
      commands.push({command: 'open', target: '/wp-admin/plugins.php', value: ''});
      } else {
      LOG.info( '— Active Plugins already set.' );
      }

      HTH,
      Lance

  2. Ok. Now I understand it! The example is also valid for my purposes.
    Many many thanks. I think I need to invest more time learning how Selenium works internally…

    Fernando

  3. Hi Lance,

    I have been using rollups for some time – I am not a javascript expert however. I have been struggling to create a variable within a roll up using selenium commands, and then use it within a javascript function in the rollup. Your use seems to be similar to my needs. eg: use selenium ide to run a rollup that in turn uses ‘storeElementPresent’ to identify the presence of an element, storing as ‘ElementExists’ but then runs a javascript if statement to run another selenium ide function based on ‘ElementExists’ being true. However I keep getting ‘undefined’ when I test with JS alert statements within the rollup.

    Does this make sense? Do you have any ideas? Thanks in advance.

    1. Yes- you are doing it wrong. 🙂

      If the variable is undefined you have a typo or your execution order of statements is not what you think it is. Try using some log commands to debug your execution.

    2. Hi Scott,

      I do exactly what you are describing. Do you access the variable ‘ElementExists’ using the storedVars array?

      Fernando

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.