Skip to content

Commit 3a99cb3

Browse files
committed
Adding experimental IWebDriver extension methods to .NET support classes
This commit adds extension methods to IWebDriver, which can be used to reduce the amount of type casting that must be done to access functionality not provided by the base IWebDriver interface. The following methods were added: * TakeScreenshot() - does not require a cast to ITakesScreenshot, and has support for working directly with instances of RemoteWebDriver. * ExecuteJavaScript<T>() - does not require a cast to IJavaScriptExecutor, and will automatically cast the result to the type specified by the generic type parameter (T). These extension methods should be considered experimental. To use them requires a reference to WebDriver.Support.dll, and adding a using clause for OpenQA.Selenium.Support.Extensions.
1 parent 3c58c82 commit 3a99cb3

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
// <copyright file="WebDriverExtensions.cs" company="WebDriver Committers">
2+
// Copyright 2013 Software Freedom Conservancy
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
// </copyright>
16+
17+
using System;
18+
using System.Collections.Generic;
19+
using System.Linq;
20+
using System.Reflection;
21+
using System.Text;
22+
using OpenQA.Selenium.Remote;
23+
24+
namespace OpenQA.Selenium.Support.Extensions
25+
{
26+
/// <summary>
27+
/// Provides extension methods for convenience in using WebDriver.
28+
/// </summary>
29+
public static class WebDriverExtensions
30+
{
31+
/// <summary>
32+
/// Gets a <see cref="Screenshot"/> object representing the image of the page on the screen.
33+
/// </summary>
34+
/// <param name="driver">The driver instance to extend.</param>
35+
/// <returns>A <see cref="Screenshot"/> object containing the image.</returns>
36+
/// <exception cref="WebDriverException">Thrown if this <see cref="IWebDriver"/> instance
37+
/// does not implement <see cref="ITakesScreenshot"/>, or the capabilities of the driver
38+
/// indicate that it cannot take screenshots.</exception>
39+
public static Screenshot TakeScreenshot(this IWebDriver driver)
40+
{
41+
ITakesScreenshot screenshotDriver = driver as ITakesScreenshot;
42+
if (screenshotDriver == null)
43+
{
44+
IHasCapabilities capabilitiesDriver = driver as IHasCapabilities;
45+
if (capabilitiesDriver == null)
46+
{
47+
throw new WebDriverException("Driver does not implement ITakesScreenshot or IHasCapabilities");
48+
}
49+
50+
if (!capabilitiesDriver.Capabilities.HasCapability(CapabilityType.TakesScreenshot) || !(bool)capabilitiesDriver.Capabilities.GetCapability(CapabilityType.TakesScreenshot))
51+
{
52+
throw new WebDriverException("Driver capabilities do not support taking screenshots");
53+
}
54+
55+
MethodInfo executeMethod = driver.GetType().GetMethod("Execute", BindingFlags.Instance | BindingFlags.NonPublic);
56+
Response screenshotResponse = executeMethod.Invoke(driver, new object[] { DriverCommand.Screenshot, null }) as Response;
57+
if (screenshotResponse == null)
58+
{
59+
throw new WebDriverException("Unexpected failure getting screenshot; response was not in the proper format.");
60+
}
61+
62+
string screenshotResult = screenshotResponse.Value.ToString();
63+
return new Screenshot(screenshotResult);
64+
}
65+
66+
return screenshotDriver.GetScreenshot();
67+
}
68+
69+
/// <summary>
70+
/// Executes JavaScript in the context of the currently selected frame or window
71+
/// </summary>
72+
/// <typeparam name="T">Expected return type of the JavaScript execution.</typeparam>
73+
/// <param name="driver">The driver instance to extend.</param>
74+
/// <param name="script">The JavaScript code to execute.</param>
75+
/// <param name="args">The arguments to the script.</param>
76+
/// <returns>The value returned by the script.</returns>
77+
/// <exception cref="WebDriverException">Thrown if this <see cref="IWebDriver"/> instance
78+
/// does not implement <see cref="IJavaScriptExecutor"/>, or if the actual return type
79+
/// of the JavaScript execution does not match the expected type.</exception>
80+
public static T ExecuteJavaScript<T>(this IWebDriver driver, string script, params object[] args)
81+
{
82+
IJavaScriptExecutor executor = driver as IJavaScriptExecutor;
83+
if (executor == null)
84+
{
85+
throw new WebDriverException("Driver does not implement IJavaScriptExecutor");
86+
}
87+
88+
object result = executor.ExecuteScript(script, args);
89+
if (!result.GetType().IsAssignableFrom(typeof(T)))
90+
{
91+
throw new WebDriverException("Script returned a value, but the result could not be cast to the desired type");
92+
}
93+
94+
return (T)result;
95+
}
96+
}
97+
}

dotnet/src/support/WebDriver.Support.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
<Compile Include="Events\WebDriverNavigationEventArgs.cs" />
7676
<Compile Include="Events\WebDriverScriptEventArgs.cs" />
7777
<Compile Include="Events\WebElementEventArgs.cs" />
78+
<Compile Include="Extensions\WebDriverExtensions.cs" />
7879
<Compile Include="GlobalSuppressions.cs" />
7980
<Compile Include="PageObjects\ByChained.cs" />
8081
<Compile Include="PageObjects\ByFactory.cs" />

0 commit comments

Comments
 (0)