Friday, 17 June 2011

Example - Select Random Wordpress Entry - Part2

Aim:
How to generate a dynamic element locator when element's ids are dynamically changing. In this example, we will demonstrate how to randomly select a post entry.

What you will learn?
  1. xpaths
  2. random variables
  3. variables
  4. screenshot command
  5. Usage of the GOTO javascript extension

Difficulty Level:
High



Tips
  1. ensure the blog page has many entries 
  2. the xpath is already generated in this example, see if you can establish the xpath yourself
Pre-requisites:

  • Firefox browser with Selenium IDE installed
  • Access to wordpress.com 
Key Steps
  1. copy and paste the example below into Selenium IDE and also install the Javascript extension
  2. open up browser and goto the wordpress test site
  3. randomly select a blog entry
  4. take a screenshot of the resul
Conclusions
  1. View the screenshot after execution
  2. Run the script again and view the screenshot
  3. notice that the screenshots are different which means that the random selection script worked
  4. maybe run the script many times in case you find that the two screenshots are the same


Related Entries

  1. none
HTML:
<?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?>
<!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;>
<html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;>
<head profile=&quot;http://selenium-ide.openqa.org/profiles/test-case&quot;>
<meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; />
<link rel=&quot;selenium.base&quot; href=&quot;http://localhost&quot; />
<title>selectRandomBlogEntry</title>
</head>
<body>
<table cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; border=&quot;1&quot;>
<thead>
<tr><td rowspan=&quot;1&quot; colspan=&quot;3&quot;>selectRandomBlogEntry</td></tr>
</thead><tbody>
<tr>
 <td>open</td>
 <td>/wordpress/</td>
 <td></td>
</tr>
<tr>
 <td>storeXpathCount</td>
 <td>//h2</td>
 <td>countId</td>
</tr>
<tr>
 <td>echo</td>
 <td>javascript{&quot;xpath count &quot; + storedVars['countId'];}</td>
 <td></td>
</tr>
<tr>
 <td>label</td>
 <td>againGenrateRandom</td>
 <td></td>
</tr>
<tr>
 <td>store</td>
 <td>javascript{ var mycountId = storedVars['countId'];Math.ceil( Math.random()*(100)); }</td>
 <td>RandomBlogEntryId</td>
</tr>
<tr>
 <td>gotoIf</td>
 <td>${RandomBlogEntryId}&lt;10</td>
 <td>againGenrateRandom</td>
</tr>
<tr>
 <td>echo</td>
 <td>javascript{&quot;randomBlogEntryId=&quot; + storedVars['RandomBlogEntryId'];}</td>
 <td></td>
</tr>
<tr>
 <td>storeEval</td>
 <td>&quot;/html/body/div[@id='wrapper']/div[@id='main']/div[@id='container']/div[@id='content']/div[@id='post-${RandomBlogEntryId}']/h2/a&quot;</td>
 <td>myxpath</td>
</tr>
<tr>
 <td>storeHtmlSource</td>
 <td>sourceValue</td>
 <td></td>
</tr>
<tr>
 <td>store</td>
 <td>${sourceValue}</td>
 <td>aa</td>
</tr>
<tr>
 <td>echo</td>
 <td>javascript{storedVars['sourceValue'];}</td>
 <td></td>
</tr>
<tr>
 <td>storeEval</td>
 <td>storedVars['sourceValue'].length</td>
 <td>q</td>
</tr>
<tr>
 <td>echo</td>
 <td>javascript{&quot;Source code Length =&quot; + storedVars['q'];}</td>
 <td></td>
</tr>
<tr>
 <td>storeEval</td>
 <td>storedVars['sourceValue'].search(&quot;post-&quot;+storedVars['RandomBlogEntryId'])</td>
 <td>value</td>
</tr>
<tr>
 <td>echo</td>
 <td>javascript{&quot;match if greater than -1:: &quot; + storedVars['value'];}</td>
 <td></td>
</tr>
<tr>
 <td>echo</td>
 <td>${value}</td>
 <td></td>
</tr>
<tr>
 <td>gotoIf</td>
 <td>${value}==-1</td>
 <td>label1</td>
</tr>
<tr>
 <td>echo</td>
 <td>javascript{&quot;myxpath=&quot; + storedVars['myxpath'];}</td>
 <td></td>
</tr>
<tr>
 <td>clickAtAndWait</td>
 <td>xpath=${myxpath}</td>
 <td></td>
</tr>
<tr>
 <td>captureEntirePageScreenshot</td>
 <td>C:SelectRandomBlogEntry.jpg</td>
 <td></td>
</tr>
<tr>
 <td>goto</td>
 <td>end</td>
 <td></td>
</tr>
<tr>
 <td>label</td>
 <td>label1</td>
 <td></td>
</tr>
<tr>
 <td>getEval</td>
 <td>alert(&quot;Post is not available...Click 'OK'&nbsp;&nbsp;for LogOut&quot;);</td>
 <td></td>
</tr>
<tr>
 <td>label</td>
 <td>end</td>
 <td></td>
</tr>
</tbody></table>
</body>
</html>

Javascript Extension File 
var gotoLabels= {};
var whileLabels = {};

// overload the original Selenium reset function
Selenium.prototype.reset = function() {
    // reset the labels
    this.initialiseLabels();
    // proceed with original reset code
    this.defaultTimeout = Selenium.DEFAULT_TIMEOUT;
    this.browserbot.selectWindow("null");
    this.browserbot.resetPopups();
}

Selenium.prototype.initialiseLabels = function()
{
    gotoLabels = {};
    whileLabels = { ends: {}, whiles: {} };
    var command_rows = [];
    var numCommands = testCase.commands.length;
    for (var i = 0; i < numCommands; ++i) {
        var x = testCase.commands[i];
        command_rows.push(x);
    }
    var cycles = [];
    for( var i = 0; i < command_rows.length; i++ ) {
        if (command_rows[i].type == 'command')
        switch( command_rows[i].command.toLowerCase() ) {
            case "label":
                gotoLabels[ command_rows[i].target ] = i;
                break;
            case "while":
            case "endwhile":
                cycles.push( [command_rows[i].command.toLowerCase(), i] )
                break;
        }
    }  
    var i = 0;
    while( cycles.length ) {
        if( i >= cycles.length ) {
            throw new Error( "non-matching while/endWhile found" );
        }
        switch( cycles[i][0] ) {
            case "while":
                if( ( i+1 < cycles.length ) && ( "endwhile" == cycles[i+1][0] ) ) {
                    // pair found
                    whileLabels.ends[ cycles[i+1][1] ] = cycles[i][1];
                    whileLabels.whiles[ cycles[i][1] ] = cycles[i+1][1];
                    cycles.splice( i, 2 );
                    i = 0;
                } else ++i;
                break;
            case "endwhile":
                ++i;
                break;
        }
    }
}

Selenium.prototype.continueFromRow = function( row_num )
{
    if(row_num == undefined || row_num == null || row_num < 0) {
        throw new Error( "Invalid row_num specified." );
    }
    testCase.debugContext.debugIndex = row_num;
}

// do nothing. simple label
Selenium.prototype.doLabel = function(){};

Selenium.prototype.doGotolabel = function( label )
{
    if( undefined == gotoLabels[label] ) {
        throw new Error( "Specified label '" + label + "' is not found." );
    }
    this.continueFromRow( gotoLabels[ label ] );
};

Selenium.prototype.doGoto = Selenium.prototype.doGotolabel;

Selenium.prototype.doGotoIf = function( condition, label )
{
    if( eval(condition) ) this.doGotolabel( label );
}

Selenium.prototype.doWhile = function( condition )
{
    if( !eval(condition) ) {
        var last_row = testCase.debugContext.debugIndex;
        var end_while_row = whileLabels.whiles[ last_row ];
        if( undefined == end_while_row ) throw new Error( "Corresponding 'endWhile' is not found." );
        this.continueFromRow( end_while_row );
    }
}

Selenium.prototype.doEndWhile = function()
{
    var last_row = testCase.debugContext.debugIndex;
    var while_row = whileLabels.ends[ last_row ] - 1;
    if( undefined == while_row ) throw new Error( "Corresponding 'While' is not found." );
    this.continueFromRow( while_row );
} 

Helpful Video

2 comments:

  1. I have put only solutions here, it's under todo, so please review first.

    ReplyDelete
  2. I also haven't made any changes in existing one.

    ReplyDelete

Thank you for your comment
- Time2test Team