Friday, 7 June 2013

Controlling Selenium and Chrome WebDriver from a C# REPL GUI (while fixing UnitTest)

When I was Running TeamMentor WebAutomation UnitTests locally (using Selenium and ChromeDriver), there were a number of TeamMentor's UnitTests that failed, and could not be fixed with simple changes or re-execution

This post shows how I used the O2 Platform's FluentSharp REPL script_Me capabilities to debug the problem and find a solution.

In the TeamMentor's UserTests here is one that was failing:

image

Source code of test shown above, with the error occurring on the selected line (with clickButton.Click() )

image

To debug this issue, lets open up a C# Repl on the beginning of the test (using FluentSharp’s script_Me Extension Method)

image

Running this UnitTest

image

... will open up the browser and the REPL gui

image

Note: the error shown above is a known bug in the O2 Platform REPL generator, and it is due to the fact that the unitTest variable (passed as a parameter to the REPL GUI) is a collection. This is a minor bug in, which can be dealt with by making the parameter a generic value:

image

... and adding a couple references and using statements:

image

With this set-up we can now control the Chome WebDriver from this REPL Scripts.

Some examples:

1) Get a reference to the teamMentor object and call the homePage method:

image

2) get a strongly typed reference to the ChromeDriver object and invoke Navigate and Refresh

image

3) Get XPath using private field value

image

4) get element reference (in this case the ‘OWASP Top 10’ folder from the OWASP library)

image

5) Click on element and the same error we had when executing the UnitTest normally (first screenshot).

image

Basically the problem is that if that folder is currently not visible, the Click event cannot be invoked.

And just to confirm, if we manually expand that folder, we will get no errors:

image

To fix this we need to open up that folder programmatically.

In these cases I always like to look at jQuery and see if I can use it to address the issue.

So in another Chome window, I opened up the developer tools and used the same GUID as used in the UnitTest to find the folder:

image

Then I call the JavaScript method to close all tree nodes:

image

... and the JavaScript method to open/expand that folder:

image

Back into C# code, here are a couple Extension Methods that will allow us to do this programmatically:

image

… which can be used like this:

image

So now we can invoke (from C#) the JavaScript code that closes all folders:

image

… and the script that opens the folder:

image

Next we create a generic lambda method to open the node, and loop it 5 times (for fun):

image ,

And now, the code from the original UnitTest (i.e the Click event) doesn’t fail anymore:

image

… and we can add the rest of the UnitTest (just to make sure it all works)

image

Note that I had to comment out the .Click event since it was closing down the OWASP Top 10 folder (which meant that nodes.first().Text would return an empty value)

image

Now that we have a fix, the final step is to close the REPL window and update the UnitTest with the new jQuery based commands

So back in the UnitTest file (the one that was failing before), I removed the clickButton code and added the code created in the REPL C# environment:

image

And the test now passes :)

image

To fix the other UnitTests that were also failing (on this class), I transformed the Lambda method into a normal C# function:

image

... which was used in this unit test:

image

… and this one

image

And finally, with these fixes, all unit tests now executed ok :)

image


Related posts:




Scripts used in this post:

a) calling teamMentor.HomePage()
var testBase = (TMTestBase<ChromeDriver>)unitTest;

testBase.teamMentor.homePage();

return unitTest;

//using OpenQA.Selenium
//using OpenQA.Selenium.Chrome
//using TeamMentor.UnitTests.Automation
//O2Ref:TeamMentor.UnitTests.Automation.DLL
//O2Ref:WebDriver.dll
//O2Ref:Microsoft.CSharp.dll 

//O2Tag_SetInvocationParametersToDynamic

b) strongly-typed reference to ChromeDriver object
var testBase = (TMTestBase<ChromeDriver>)unitTest;

//testBase.teamMentor.homePage();

var driver = (ChromeDriver)testBase.driver;
driver.Navigate().Refresh();

return unitTest;

//using OpenQA.Selenium
//using OpenQA.Selenium.Chrome
//using TeamMentor.UnitTests.Automation
//O2Ref:TeamMentor.UnitTests.Automation.DLL
//O2Ref:WebDriver.dll
//O2Ref:Microsoft.CSharp.dll 

//O2Tag_SetInvocationParametersToDynamic


) Get JsTree using XPath
var testBase = (TMTestBase<ChromeDriver>)unitTest;

var driver = (ChromeDriver)testBase.driver;

//testBase.teamMentor.homePage();
//driver.Navigate().Refresh();

var privateField = testBase.field<string>("OWASP_JSTRE_XPATH_EXPRESSION");
var jsTree = driver.FindElementex(By.XPath(privateField));
return jsTree;


//using OpenQA.Selenium
//using OpenQA.Selenium.Chrome
//using TeamMentor.UnitTests.Automation
//O2Ref:TeamMentor.UnitTests.Automation.DLL
//O2Ref:WebDriver.dll
//O2Ref:Microsoft.CSharp.dll 

//O2Tag_SetInvocationParametersToDynamic


) get element and click on link
var testBase = (TMTestBase<ChromeDriver>)unitTest;

var driver = (ChromeDriver)testBase.driver;

//testBase.teamMentor.homePage();
//driver.Navigate().Refresh();

var privateField = testBase.field<string>("OWASP_JSTRE_XPATH_EXPRESSION");
var jsTree = driver.FindElementex(By.XPath(privateField));

var clickButton = driver.FindElement(By.XPath(".//*[@id='30b034e7-f3a2-4a81-acbc-e357129711ff']/ins"));

clickButton.Click();

return clickButton;


//using OpenQA.Selenium
//using OpenQA.Selenium.Chrome
//using TeamMentor.UnitTests.Automation
//O2Ref:TeamMentor.UnitTests.Automation.DLL
//O2Ref:WebDriver.dll
//O2Ref:Microsoft.CSharp.dll 

//O2Tag_SetInvocationParametersToDynamic


) Hello from C#
var testBase = (TMTestBase<ChromeDriver>)unitTest;
var driver = (ChromeDriver)testBase.driver;
//testBase.teamMentor.homePage();
//driver.Navigate().Refresh();
var privateField = testBase.field<string>("OWASP_JSTRE_XPATH_EXPRESSION");
var jsTree = driver.FindElementex(By.XPath(privateField));
var clickButton = driver.FindElement(By.XPath(".//*[@id='30b034e7-f3a2-4a81-acbc-e357129711ff']/ins"));

driver.executeJavaScript("alert('hello from C#' )");

clickButton.Click();
return clickButton;


//using OpenQA.Selenium
//using OpenQA.Selenium.Chrome
//using TeamMentor.UnitTests.Automation
//O2Ref:TeamMentor.UnitTests.Automation.DLL
//O2Ref:WebDriver.dll
//O2Ref:Microsoft.CSharp.dll 
//O2Tag_SetInvocationParametersToDynamic


) loop 5 times
var testBase = (TMTestBase<ChromeDriver>)unitTest;
var driver = (ChromeDriver)testBase.driver;
//testBase.teamMentor.homePage();
//driver.Navigate().Refresh();
var privateField = testBase.field<string>("OWASP_JSTRE_XPATH_EXPRESSION");
var jsTree = driver.FindElementex(By.XPath(privateField));
var clickButton = driver.FindElement(By.XPath(".//*[@id='30b034e7-f3a2-4a81-acbc-e357129711ff']/ins"));

Action<string> closeAll_and_OpenNode = 
    (nodeId)=>{
                    driver.executeJavaScript("TM.Gui.LibraryTree.jsTree.close_all();");                    
                    200.wait();
                    driver.executeJavaScript("TM.Gui.LibraryTree.openNode('#{0}')".format(nodeId));
              };
5.loop(()=> closeAll_and_OpenNode("30b034e7-f3a2-4a81-acbc-e357129711ff"));

return  "done";

//clickButton.Click();
return clickButton;


//using OpenQA.Selenium
//using OpenQA.Selenium.Chrome
//using TeamMentor.UnitTests.Automation
//O2Ref:TeamMentor.UnitTests.Automation.DLL
//O2Ref:WebDriver.dll
//O2Ref:Microsoft.CSharp.dll 
//O2Tag_SetInvocationParametersToDynamic


) final REPL code that contained the original UnitTest’s Asserts
var testBase = (TMTestBase<ChromeDriver>)unitTest;
var driver = (ChromeDriver)testBase.driver;

testBase.teamMentor.homePage();
//driver.Navigate().Refresh();

var privateField = testBase.field<string>("OWASP_JSTRE_XPATH_EXPRESSION");

var clickButton = driver.FindElement(By.XPath(".//*[@id='30b034e7-f3a2-4a81-acbc-e357129711ff']/ins"));

Action<string> closeAll_and_OpenNode = 
    (nodeId)=>{
                    driver.executeJavaScript("TM.Gui.LibraryTree.jsTree.close_all();");                    
                    200.wait();
                    driver.executeJavaScript("TM.Gui.LibraryTree.openNode('#{0}')".format(nodeId));
              };
closeAll_and_OpenNode("30b034e7-f3a2-4a81-acbc-e357129711ff");
clickButton.Click();

var jsTree = driver.FindElementex(By.XPath(privateField));
var nodes = jsTree.FindElements(By.TagName("li"));

Assert.IsTrue(nodes.Count == 10, "There should be 10 Items int this library");

Assert.IsTrue(nodes.Any(x => x.Text.ToString().Trim() == "A01: Injection"));
Assert.IsTrue(nodes.Any(x => x.Text.ToString().Trim() == "A02: Cross-Site Scripting (XSS)"));
Assert.IsTrue(nodes.Any(x => x.Text.ToString().Trim() == "A03: Broken Authentication and Session Management"));
Assert.IsTrue(nodes.Any(x => x.Text.ToString().Trim() == "A04: Insecure Direct Object References"));
Assert.IsTrue(nodes.Any(x => x.Text.ToString().Trim() == "A05: Cross-Site Request Forgery (CSRF)"));
Assert.IsTrue(nodes.Any(x => x.Text.ToString().Trim() == "A06: Security Misconfiguration"));
Assert.IsTrue(nodes.Any(x => x.Text.ToString().Trim() == "A07: Insecure Cryptographic Storage"));
Assert.IsTrue(nodes.Any(x => x.Text.ToString().Trim() == "A08: Failure to Restrict URL Access"));
Assert.IsTrue(nodes.Any(x => x.Text.ToString().Trim() == "A09: Insufficient Transport Layer Protection"));
Assert.IsTrue(nodes.Any(x => x.Text.ToString().Trim() == "A10: Unvalidated Redirects and Forwards"));

return "All Asserts where true";

//using NUnit.Framework
//O2Ref:NUnit.Framework.dll

//using OpenQA.Selenium
//using OpenQA.Selenium.Chrome
//using TeamMentor.UnitTests.Automation
//O2Ref:TeamMentor.UnitTests.Automation.DLL
//O2Ref:WebDriver.dll
//O2Ref:Microsoft.CSharp.dll 
//O2Tag_SetInvocationParametersToDynamic

10 comments:

janakikrishnan said...

Good blog where i am able to gather a lot of worthy information.
Selenium Training in Bangalore
Selenium Training Institutes in Bangalore
Selenium Classes in Bangalore
Selenium Training in Coimbatore
Selenium Course in Coimbatore
Selenium Classes in Coimbatore

Aruna Ram said...

Nice content! It was very useful for my development. Thank you for your great post and I like more one post from your blog...


Spark Training in Chennai
Spark Training Fees in Chennai
Pega Training in Chennai
Primavera Training in Chennai
Unix Training in Chennai
Linux Training in Chennai
Social Media Marketing Courses in Chennai
Power BI Training in Chennai
Tableau Training in Chennai

punitha said...

Nice blog!! I hope you will share more info like this. I will use this for my studies and research.
PHP Training Institute in Chennai
Best PHP training in chennai
Ethical Hacking Course in Chennai
PHP Training in Chennai
Web Designing Course in Chennai
PHP Training in Chennai
PHP Course in Chennai

Raju said...

Your article contents are easy to read and understand the topic which i searched before.We expect your valuable blog posting in the future.
Selenium Training in Adyar
Selenium Training in OMR
Software Testing Training in Tambaram
Software Testing Training in Anna nagar
Software Testing Training in OMR
Selenium Training in Porur
Selenium Training in Chennai
Selenium Course in Chennai

Sadhana Rathore said...

Excellent post, it will be definitely helpful for many people. Keep posting more like this.
Automation Anywhere Training in Chennai
Automation courses in Chennai
Automation Training in Chennai
Blue Prism Training in Chennai
Blue Prism Training in Anna Nagar
RPA course in Chennai
RPA Training Institute in Chennai
RPA Training in Chennai

velraj said...


Thank you very much for shared this. I got lot of ideas after reading this. Share more as similar to this.
core java training in chennai
core java Training in Tnagar
c c++ course fees in chennai
c c++ courses in chennai
C Language Training
javascript training in chennai
Appium Training in Chennai
JMeter Training in Chennai

Kerrthika K said...

It's great post and more effective ...informative blog!
Hadoop Admin Training in Chennai
Hadoop administration in Chennai
Big Data Analytics Courses in Chennai
Blockchain course
Informatica MDM Training in Chennai
Informatica Training in Chennai

Alex Avid said...

very good informative content
python Training near Bellandur|selenium testing courses in Bellandur
python classes in Marathahalli|selenium testing Training near Marathahalli

praveen jos said...

effective content
python courses in Bellandur|python courses in Marathahalli
selenium testing courses in Marathahalli|selenium testing courses in Bellandur

Madhi Priya said...

ecxellent work
python Training in Bellandur|python courses in Marathahalli
selenium testing courses in Marathahalli|selenium testing Training in Bellandur