Introduction
As you probably know, I am developing a series of posts called Pragmatic Automation with WebDriver. They consist of tons of practical information how to start writing automation tests with WebDriver. Also, they contain a lot of more advanced topics such as automation strategies, benchmarks and researches. In the next couple of publications, I am going to share with you some Advanced WebDriver usages in tests. Without further ado, here are today's advanced WebDriver Automation tips and trips.
1. Taking a Screenshot
You can use the following method to take a full-screen screenshot of the browser.
public void TakeFullScreenshot(IWebDriver driver, String filename)
{
Screenshot screenshot = ((ITakesScreenshot)driver).GetScreenshot();
screenshot.SaveAsFile(filename, ImageFormat.Png);
}
Sometimes, you may need to take a screenshot of a single element.
public void TakeScreenshotOfElement(IWebDriver driver, By by, string fileName)
{
var screenshotDriver = driver as ITakesScreenshot;
Screenshot screenshot = screenshotDriver.GetScreenshot();
var bmpScreen = new Bitmap(new MemoryStream(screenshot.AsByteArray));
IWebElement element = driver.FindElement(by);
var cropArea = new Rectangle(element.Location, element.Size);
var bitmap = bmpScreen.Clone(cropArea, bmpScreen.PixelFormat);
bitmap.Save(fileName);
}
First, we make a full-screen screenshot, then we locate the specified element by its location and size attributes. After that, the found rectangle chunk is saved as a bitmap.
Here is how you use both methods in tests.
[TestMethod]
public void WebDriverAdvancedUsage_TakingFullScrenenScreenshot()
{
this.driver.Navigate().GoToUrl(@"http://automatetheplanet.com");
this.WaitUntilLoaded();
string tempFilePath = Path.GetTempFileName().Replace(".tmp", ".png");
this.TakeFullScreenshot(this.driver, tempFilePath);
}
[TestMethod]
public void WebDriverAdvancedUsage_TakingElementScreenshot()
{
this.driver.Navigate().GoToUrl(@"http://automatetheplanet.com");
this.WaitUntilLoaded();
string tempFilePath = Path.GetTempFileName().Replace(".tmp", ".png");
this.TakeScreenshotOfElement(this.driver,
By.XPath("//*[@id='tve_editor']/div[2]/div[2]/div/div"), tempFilePath);
}
We get a temp file name through the special Path .NET class. By default, temp files are generated with ".tmp" extension because of that we replace it with ".png".
2. Get HTML Source of WebElement
You can use the GetAttribute
method of the IWebElement
interface to get the inner HTML of a specific element.
[TestMethod]
public void GetHtmlSourceOfWebElement()
{
this.driver.Navigate().GoToUrl(@"http://automatetheplanet.com");
this.WaitUntilLoaded();
var element = this.driver.FindElement(By.XPath("//*[@id='tve_editor']/div[2]/div[3]/div/div"));
string sourceHtml = element.GetAttribute("innerHTML");
Debug.WriteLine(sourceHtml);
}
3. Execute JavaScript
You can use the interface IJavaScriptExecutor
to execute JavaScript through WebDriver
.
[TestMethod]
public void ExecuteJavaScript()
{
this.driver.Navigate().GoToUrl(@"http://automatetheplanet.com");
this.WaitUntilLoaded();
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
string title = (string)js.ExecuteScript("return document.title");
Debug.WriteLine(title);
}
This test is going to take the current window's title via JavaScript and print it to the Debug Output Window.
4. Set Page Load Timeout
There are at least three methods that you can use for the job.
First, you can set the default driver's page load timeout through the WebDriver
's options class.
this.driver.Manage().Timeouts().SetPageLoadTimeout(new TimeSpan(0, 0, 10));
You can wait until the page is completely loaded via JavaScript.
private void WaitUntilLoaded()
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
wait.Until((x) =>
{
return ((IJavaScriptExecutor)this.driver)
.ExecuteScript("return document.readyState").Equals("complete");
});
}
Your third option is to wait for a specific element(s) to be visible on the page.
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
wait.Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(
By.XPath("//*[@id='tve_editor']/div[2]/div[2]/div/div")));
5. Execute Tests in a Headless Browser
PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG. In order to be able to use the PhantomJSDriver in your code, you first need to download its binaries.
[TestMethod]
public void ExecuteInHeadlessBrowser()
{
this.driver = new PhantomJSDriver(@"D:\Projects\PatternsInAutomation.Tests\WebDriver.Series.Tests\Drivers");
this.driver.Navigate().GoToUrl(@"http://automatetheplanet.com");
this.WaitUntilLoaded();
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
string title = (string)js.ExecuteScript("return document.title");
Debug.WriteLine(title);
}
This test is executed under 3 seconds through the PhantomJSDriver. Almost three times faster than with the FirefoxDriver.
6. Check If an Element Is Visible
You can use the Displayed
property of the IWebElement
interface.
[TestMethod]
public void ExecuteInHeadlessBrowser()
{
this.driver = new PhantomJSDriver
(@"D:\Projects\PatternsInAutomation.Tests\WebDriver.Series.Tests\Drivers");
this.driver.Navigate().GoToUrl(@"http://automatetheplanet.com");
this.WaitUntilLoaded();
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
string title = (string)js.ExecuteScript("return document.title");
Debug.WriteLine(title);
}
7. Use Specific Profile
By default, WebDriver always assigns a new 'clean' profile if you use the FirefoxDriver's default constructor. However, sometimes you may want to fine-tune the profile, e.g., add extensions, turn off the JavaScript, etc.
FirefoxProfileManager profileManager = new FirefoxProfileManager();
FirefoxProfile profile = profileManager.GetProfile("YourProfileName");
this.driver = new FirefoxDriver(profile);
You can do some similar configurations for the ChromeDriver.
ChromeOptions options = new ChromeOptions();
DesiredCapabilities dc = DesiredCapabilities.Chrome();
dc.SetCapability(ChromeOptions.Capability, options);
IWebDriver driver = new RemoteWebDriver(dc);
8. Turn Off JavaScript
You can use the code from point 7 to set up a new Firefox profile. Then you need to set the 'javascript.enabled
' attribute to false
.
FirefoxProfileManager profileManager = new FirefoxProfileManager();
FirefoxProfile profile = profileManager.GetProfile("HARDDISKUSER");
profile.SetPreference("javascript.enabled", false);
this.driver = new FirefoxDriver(profile);
9. Manage Cookies
Before you can work with the cookies of a site, you need to navigate to some of its pages.
Add a New Cookie
Cookie cookie = new Cookie("key", "value");
this.driver.Manage().Cookies.AddCookie(cookie);
Get All Cookies
var cookies = this.driver.Manage().Cookies.AllCookies;
foreach (var currentCookie in cookies)
{
Debug.WriteLine(currentCookie.Value);
}
Delete a Cookie by Name
this.driver.Manage().Cookies.DeleteCookieNamed("CookieName");
Delete All Cookies
this.driver.Manage().Cookies.DeleteAllCookies();
Get a Cookie by Name
var myCookie = this.driver.Manage().Cookies.GetCookieNamed("CookieName");
Debug.WriteLine(myCookie.Value);
10. Maximize Window
Use the Maximize
method of the IWindow
interface.
[TestMethod]
public void MaximizeWindow()
{
this.driver.Navigate().GoToUrl(@"http://automatetheplanet.com");
this.driver.Manage().Window.Maximize();
}
So Far in the 'Pragmatic Automation with WebDriver' Series