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:
Source code of test shown above, with the error occurring on the selected line (with clickButton.Click() )
To debug this issue, lets open up a C# Repl on the beginning of the test (using FluentSharp’s script_Me Extension Method)
Running this UnitTest
... will open up the browser and the REPL gui
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:
... and adding a couple references and using statements:
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:
2) get a strongly typed reference to the ChromeDriver object and invoke Navigate and Refresh
3) Get XPath using private field value
4) get element reference (in this case the ‘OWASP Top 10’ folder from the OWASP library)
5) Click on element and the same error we had when executing the UnitTest normally (first screenshot).
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:
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:
Then I call the JavaScript method to close all tree nodes:
... and the JavaScript method to open/expand that folder:
Back into C# code, here are a couple Extension Methods that will allow us to do this programmatically:
… which can be used like this:
So now we can invoke (from C#) the JavaScript code that closes all folders:
… and the script that opens the folder:
Next we create a generic lambda method to open the node, and loop it 5 times (for fun):
,
And now, the code from the original UnitTest (i.e the Click event) doesn’t fail anymore:
… and we can add the rest of the UnitTest (just to make sure it all works)
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)
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:
And the test now passes :)
To fix the other UnitTests that were also failing (on this class), I transformed the Lambda method into a normal C# function:
... which was used in this unit test:
… and this one
And finally, with these fixes, all unit tests now executed ok :)
Related posts:
- Coding Firefox in C# in real-time using Selenium's Firefox driver
- PoC - Selenium - Gui with 3 Hijacked Browser Windows.h2
- Using TeamCity and NUnit to Start WebServer, Run Selenium Tests and Stop WebServer
- OpenQA.Selenium.DriverServiceNotFoundException on Chrome
- Using Selenium to Login using Multiple Browsers
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
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