-
-
Notifications
You must be signed in to change notification settings - Fork 8.4k
.pr_agent_auto_best_practices
Pattern 1: Add null checks for parameters and properties before using them to prevent NullReferenceExceptions. Validate input parameters at the beginning of methods and handle null values appropriately with clear error messages.
Example code before:
public void ProcessData(string input) {
var result = input.ToUpper();
// Use result...
}
Example code after:
public void ProcessData(string input) {
ArgumentNullException.ThrowIfNull(input, nameof(input));
var result = input.ToUpper();
// Use result...
}
Relevant past accepted suggestions:
Suggestion 1:
Prevent removing default context
Add validation to prevent removing the "default" user context. The docstring mentions that an exception will be raised if the user context ID is "default", but there's no actual validation in the code to prevent this operation.
py/selenium/webdriver/common/bidi/browser.py [168-180]
def remove_user_context(self, user_context_id: str) -> None:
"""Removes a user context.
Parameters:
-----------
user_context_id: The ID of the user context to remove.
Raises:
------
Exception: If the user context ID is "default" or does not exist.
"""
+ if user_context_id == "default":
+ raise Exception("Cannot remove the default user context")
+
params = {"userContext": user_context_id}
self.conn.execute(command_builder("browser.removeUserContext", params))
Suggestion 2:
Check dictionary key exists
The code doesn't check if the successId exists in the _pendingCommands dictionary before accessing it. This could lead to a KeyNotFoundException if a success message is received for a command ID that is not in the dictionary.
dotnet/src/webdriver/BiDi/Communication/Broker.cs [136-142]
try
{
var data = await _transport.ReceiveAsync(cancellationToken).ConfigureAwait(false);
Utf8JsonReader utfJsonReader = new(new ReadOnlySpan<byte>(data));
utfJsonReader.Read();
var messageType = utfJsonReader.GetDiscriminator("type");
switch (messageType)
{
case "success":
var successId = int.Parse(utfJsonReader.GetDiscriminator("id"));
- var successCommand = _pendingCommands[successId];
- var messageSuccess = JsonSerializer.Deserialize(ref utfJsonReader, successCommand.Item1.ResultType, _jsonSerializerContext);
+ if (_pendingCommands.TryGetValue(successId, out var successCommand))
+ {
+ var messageSuccess = JsonSerializer.Deserialize(ref utfJsonReader, successCommand.Item1.ResultType, _jsonSerializerContext);
- successCommand.Item2.SetResult(messageSuccess);
+ successCommand.Item2.SetResult(messageSuccess);
- _pendingCommands.TryRemove(successId, out _);
+ _pendingCommands.TryRemove(successId, out _);
+ }
break;
Suggestion 3:
Handle potential null string
The RemoteValue.String() method is called with a potentially null string value from GetString(), but the method doesn't appear to handle null values properly. This could lead to a NullReferenceException.
dotnet/src/webdriver/BiDi/Communication/Json/Converters/Polymorphic/RemoteValueConverter.cs [36]
-return RemoteValue.String(jsonDocument.RootElement.GetString());
+return RemoteValue.String(jsonDocument.RootElement.GetString() ?? string.Empty);
Suggestion 4:
Add null check for handler
Add null check for the returned HttpClientHandler from CreateHttpClientHandler() before using it to avoid potential NullReferenceException
dotnet/src/webdriver/Remote/HttpCommandExecutor.cs [248-252]
protected virtual HttpClient CreateHttpClient()
{
var httpClientHandler = CreateHttpClientHandler();
+ if (httpClientHandler == null)
+ {
+ throw new InvalidOperationException("CreateHttpClientHandler() returned null");
+ }
HttpMessageHandler handler = httpClientHandler;
Suggestion 5:
Add null validation check for required class field to prevent potential NullReferenceException
The CreateHttpClientHandler() method uses this.remoteServerUri without validating that it's not null. Since this is a required field for the class functionality, add a null check at the start of the method to fail fast with a clear error message.
dotnet/src/webdriver/Remote/HttpCommandExecutor.cs [229-233]
protected virtual HttpClientHandler CreateHttpClientHandler()
{
+ ArgumentNullException.ThrowIfNull(this.remoteServerUri, nameof(remoteServerUri));
HttpClientHandler httpClientHandler = new HttpClientHandler();
string userInfo = this.remoteServerUri.UserInfo;
if (!string.IsNullOrEmpty(userInfo) && userInfo.Contains(":"))
Suggestion 6:
Add parameter validation
Add null checks for the subscription ID and event handler parameters to prevent potential NullReferenceException when unsubscribing.
dotnet/src/webdriver/BiDi/Communication/Broker.cs [274-281]
public async Task UnsubscribeAsync(Modules.Session.Subscription subscription, EventHandler eventHandler)
{
+ ArgumentNullException.ThrowIfNull(subscription);
+ ArgumentNullException.ThrowIfNull(eventHandler);
+
var eventHandlers = _eventHandlers[eventHandler.EventName];
eventHandlers.Remove(eventHandler);
await _bidi.SessionModule.UnsubscribeAsync([subscription]).ConfigureAwait(false);
}
Suggestion 7:
Add null check for response value
Add null check for response.Value in GetContext() method before attempting ToString() conversion to avoid potential NullReferenceException.
dotnet/src/webdriver/Firefox/FirefoxDriver.cs [263-266]
Response commandResponse = this.Execute(GetContextCommand, null);
-if (commandResponse.Value is not string response
+if (commandResponse.Value is null
+ || commandResponse.Value is not string response
|| !Enum.TryParse(response, ignoreCase: true, out FirefoxCommandContext output))
Suggestion 8:
Prevent null reference exception
Add null check for binaryPaths.BrowserPath before validating file existence to prevent NullReferenceException. The browser path might be null in some cases.
dotnet/src/webdriver/DriverFinder.cs [119-122]
-if (!File.Exists(binaryPaths.BrowserPath))
+if (!string.IsNullOrEmpty(binaryPaths.BrowserPath) && !File.Exists(binaryPaths.BrowserPath))
{
throw new NoSuchDriverException($"The browser path is not a valid file: {binaryPaths.BrowserPath}");
}
Suggestion 9:
Handle null browser path safely
Add null check for path before accessing it in GetBrowserPath() to prevent potential NullReferenceException when accessing BrowserPath property.
dotnet/src/webdriver/DriverFinder.cs [56-59]
public string GetBrowserPath()
{
- return BinaryPaths().BrowserPath;
+ var paths = BinaryPaths();
+ return paths.BrowserPath ?? string.Empty;
}
Suggestion 10:
Handle null response values
Add null check for commandResponse.Value before calling ToString() since the response value could be null, which would cause a NullReferenceException
dotnet/src/webdriver/WebElement.cs [100-102]
Response commandResponse = this.Execute(DriverCommand.GetElementText, parameters);
-return commandResponse.Value.ToString();
+return commandResponse.Value?.ToString() ?? string.Empty;
Suggestion 11:
Add null check for path
Add null check for Path.GetDirectoryName() result since it can return null for invalid paths. The current forced null-forgiving operator (!) could lead to NullReferenceException.
dotnet/src/webdriver/Firefox/FirefoxDriverService.cs [203]
-driverPath = Path.GetDirectoryName(driverPath)!;
+var dirPath = Path.GetDirectoryName(driverPath);
+if (dirPath == null) throw new ArgumentException("Invalid driver path provided", nameof(driverPath));
+driverPath = dirPath;
Suggestion 12:
Add null parameter validation
Add null check for webDriver parameter to prevent NullReferenceException when calling the extension method with null
dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs [29-31]
public static async Task<BiDi> AsBiDiAsync(this IWebDriver webDriver)
{
+ ArgumentNullException.ThrowIfNull(webDriver);
var webSocketUrl = ((IHasCapabilities)webDriver).Capabilities.GetCapability("webSocketUrl");
Suggestion 13:
Add proper validation for nullable values before using them to prevent potential runtime errors
The code uses null-forgiving operator (!) on webSocketUrl.ToString() which could lead to runtime errors if webSocketUrl is null. Instead, validate the value before using it and provide a clear error message.
dotnet/src/webdriver/BiDi/WebDriver.Extensions.cs [33-35]
-if (webSocketUrl is null) throw new BiDiException("The driver is not compatible with bidirectional protocol or \"webSocketUrl\" not enabled in driver options.");
-var bidi = await BiDi.ConnectAsync(webSocketUrl.ToString()!).ConfigureAwait(false);
+if (webSocketUrl is null)
+ throw new BiDiException("The driver is not compatible with bidirectional protocol or \"webSocketUrl\" not enabled in driver options.");
+var webSocketUrlStr = webSocketUrl.ToString();
+if (string.IsNullOrEmpty(webSocketUrlStr))
+ throw new BiDiException("Invalid empty webSocketUrl value");
+
+var bidi = await BiDi.ConnectAsync(webSocketUrlStr).ConfigureAwait(false);
+
Suggestion 14:
Add parameter validation to prevent null reference exceptions
Add null check for value parameter in FromJson method to prevent potential NullReferenceException when deserializing JSON.
dotnet/src/webdriver/Response.cs [74-76]
public static Response FromJson(string value)
{
+ if (string.IsNullOrEmpty(value))
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
Dictionary<string, object> rawResponse = JsonSerializer.Deserialize<Dictionary<string, object>>(value, s_jsonSerializerOptions)
Suggestion 15:
Add null check for required parameter to prevent runtime errors
Add null check for target parameter in ConvertElement() since it's marked as nullable but the method assumes it's non-null.
dotnet/src/webdriver/Interactions/PointerInputDevice.cs [584-588]
private Dictionary<string, object> ConvertElement()
{
+ if (this.target == null)
+ {
+ throw new ArgumentNullException(nameof(target));
+ }
if (this.target is IWebDriverObjectReference element)
{
return element.ToDictionary();
}
Suggestion 16:
Add parameter validation to prevent null reference exceptions
Add null check for key parameter in SetPreferenceValue method to prevent potential issues with null keys.
dotnet/src/webdriver/Firefox/Preferences.cs [166-168]
private void SetPreferenceValue(string key, JsonNode? value)
{
+ if (key == null)
+ throw new ArgumentNullException(nameof(key));
if (!this.IsSettablePreference(key))
Pattern 2: Use try-finally blocks to ensure proper resource cleanup, especially for driver instances and other disposable resources, even when exceptions occur during test execution.
Example code before:
public void TestMethod() {
var driver = new WebDriver();
driver.Navigate().GoToUrl("https://example.com");
driver.FindElement(By.Id("element")).Click();
driver.Quit();
}
Example code after:
public void TestMethod() {
var driver = new WebDriver();
try {
driver.Navigate().GoToUrl("https://example.com");
driver.FindElement(By.Id("element")).Click();
} finally {
driver.Quit();
}
}
Relevant past accepted suggestions:
Suggestion 1:
Ensure proper resource cleanup
Ensure the driver is properly closed even if the test fails by using a try-finally block. Currently, if the test fails before reaching driver.quit(), the driver won't be properly cleaned up.
py/test/selenium/webdriver/remote/remote_connection_tests.py [38-53]
def test_remote_webdriver_with_http_timeout(firefox_options, webserver):
"""This test starts a remote webdriver with an http client timeout
set less than the implicit wait timeout, and verifies the http timeout
is triggered first when waiting for an element.
"""
http_timeout = 6
wait_timeout = 8
server_addr = f"http://{webserver.host}:{webserver.port}"
client_config = ClientConfig(remote_server_addr=server_addr, timeout=http_timeout)
assert client_config.timeout == http_timeout
driver = webdriver.Remote(options=firefox_options, client_config=client_config)
- driver.get(f"{server_addr}/simpleTest.html")
- driver.implicitly_wait(wait_timeout)
- with pytest.raises(ReadTimeoutError):
- driver.find_element(By.ID, "no_element_to_be_found")
- driver.quit()
+ try:
+ driver.get(f"{server_addr}/simpleTest.html")
+ driver.implicitly_wait(wait_timeout)
+ with pytest.raises(ReadTimeoutError):
+ driver.find_element(By.ID, "no_element_to_be_found")
+ finally:
+ driver.quit()
Suggestion 2:
Missing driver cleanup
The test is missing cleanup for driver2. If driver2 is successfully created, it should be quit in the finally block to properly release resources.
py/test/selenium/webdriver/chrome/chrome_service_tests.py [53-54]
finally:
driver1.quit()
+ if driver2:
+ driver2.quit()
Suggestion 3:
Handle undefined variable safely
The test is missing a reference to driver1 before quitting it in the finally block. Since driver1 is defined inside the try block, it might not exist if an exception occurs before its creation, causing a NameError.
py/test/selenium/webdriver/chrome/chrome_service_tests.py [54]
-driver1.quit()
+if 'driver1' in locals() and driver1:
+ driver1.quit()
Suggestion 4:
Properly dispose of HTTP client resources to prevent memory leaks
Dispose of the HttpClient instance in the Dispose method to prevent resource leaks. The current implementation might leave the HttpClient hanging.
dotnet/src/webdriver/Remote/HttpCommandExecutor.cs [52]
private HttpClient? client;
+public void Dispose()
+{
+ if (!isDisposed)
+ {
+ client?.Dispose();
+ client = null;
+ isDisposed = true;
+ }
+}
+
Pattern 3: Check dictionary key existence before accessing values to prevent KeyNotFoundException. Use TryGetValue or ContainsKey methods to safely access dictionary entries.
Example code before:
var value = dictionary[key];
ProcessValue(value);
Example code after:
if (dictionary.TryGetValue(key, out var value)) {
ProcessValue(value);
}
Relevant past accepted suggestions:
Suggestion 1:
Check dictionary key exists
The code doesn't check if the successId exists in the _pendingCommands dictionary before accessing it. This could lead to a KeyNotFoundException if a success message is received for a command ID that is not in the dictionary.
dotnet/src/webdriver/BiDi/Communication/Broker.cs [136-142]
try
{
var data = await _transport.ReceiveAsync(cancellationToken).ConfigureAwait(false);
Utf8JsonReader utfJsonReader = new(new ReadOnlySpan<byte>(data));
utfJsonReader.Read();
var messageType = utfJsonReader.GetDiscriminator("type");
switch (messageType)
{
case "success":
var successId = int.Parse(utfJsonReader.GetDiscriminator("id"));
- var successCommand = _pendingCommands[successId];
- var messageSuccess = JsonSerializer.Deserialize(ref utfJsonReader, successCommand.Item1.ResultType, _jsonSerializerContext);
+ if (_pendingCommands.TryGetValue(successId, out var successCommand))
+ {
+ var messageSuccess = JsonSerializer.Deserialize(ref utfJsonReader, successCommand.Item1.ResultType, _jsonSerializerContext);
- successCommand.Item2.SetResult(messageSuccess);
+ successCommand.Item2.SetResult(messageSuccess);
- _pendingCommands.TryRemove(successId, out _);
+ _pendingCommands.TryRemove(successId, out _);
+ }
break;
Suggestion 2:
Check event handlers exist
The code doesn't check if the method exists in the _eventHandlers dictionary or if there are any handlers for that method before accessing it. This could lead to a KeyNotFoundException or InvalidOperationException (when calling First() on an empty collection) if an event is received for a method that has no registered handlers.
dotnet/src/webdriver/BiDi/Communication/Broker.cs [145-159]
case "event":
utfJsonReader.Read();
utfJsonReader.Read();
var method = utfJsonReader.GetString();
utfJsonReader.Read();
- // TODO: Just get type info from existing subscribers, should be better
- var type = _eventHandlers[method].First().EventArgsType;
+ if (_eventHandlers.TryGetValue(method, out var handlers) && handlers.Count > 0)
+ {
+ // TODO: Just get type info from existing subscribers, should be better
+ var type = handlers.First().EventArgsType;
- var eventArgs = (EventArgs)JsonSerializer.Deserialize(ref utfJsonReader, type, _jsonSerializerContext);
+ var eventArgs = (EventArgs)JsonSerializer.Deserialize(ref utfJsonReader, type, _jsonSerializerContext);
- var messageEvent = new MessageEvent(method, eventArgs);
- _pendingEvents.Add(messageEvent);
+ var messageEvent = new MessageEvent(method, eventArgs);
+ _pendingEvents.Add(messageEvent);
+ }
break;
Suggestion 3:
Validate JSON property existence
Add null check for the 'clientWindows' property existence in JSON to prevent potential JsonException
-var clientWindows = doc.RootElement.GetProperty("clientWindows").Deserialize<IReadOnlyList<ClientWindowInfo>>(options);
+if (!doc.RootElement.TryGetProperty("clientWindows", out JsonElement clientWindowsElement))
+ throw new JsonException("Missing required 'clientWindows' property");
+var clientWindows = clientWindowsElement.Deserialize<IReadOnlyList<ClientWindowInfo>>(options);
Pattern 4: Fix inconsistent error messages and validation logic. Ensure error messages are clear, accurate, and provide specific information about the error condition and expected values.
Example code before:
if (value < 0) {
throw new ArgumentException("Invalid value");
}
Example code after:
if (value < 0) {
throw new ArgumentException($"Value must be non-negative. Received: {value}");
}
Relevant past accepted suggestions:
Suggestion 1:
Improve error message clarity
The error message should be more specific about the expected types. Currently it mentions "PartitionDescriptor" which is a parent class, but the check is specifically for BrowsingContextPartitionDescriptor or StorageKeyPartitionDescriptor.
javascript/node/selenium-webdriver/bidi/storage.js [56-61]
if (
partition !== undefined &&
!(partition instanceof BrowsingContextPartitionDescriptor || partition instanceof StorageKeyPartitionDescriptor)
) {
- throw new Error(`Params must be an instance of PartitionDescriptor. Received:'${partition}'`)
+ throw new Error(`Params must be an instance of BrowsingContextPartitionDescriptor or StorageKeyPartitionDescriptor. Received:'${partition}'`)
}
Suggestion 2:
Fix inconsistent docstring formatting
The indentation in the docstring is inconsistent. The "Example:" section has one less dash than the "Parameters:" section, which could cause issues with Sphinx documentation generation.
py/selenium/webdriver/remote/webdriver.py [814-824]
def set_page_load_timeout(self, time_to_wait: float) -> None:
"""Sets the amount of time to wait for a page load to complete before
throwing an error.
Parameters:
-----------
time_to_wait : float
- The amount of time to wait (in seconds)
Example:
- -------
+ --------
>>> driver.set_page_load_timeout(30)
"""
Suggestion 3:
Prevent potential null reference
The Title property should check if commandResponse is null before using the null-coalescing operator on its Value property to avoid potential NullReferenceException.
dotnet/src/webdriver/WebDriver.cs [123]
-object returnedTitle = commandResponse?.Value ?? string.Empty;
+object returnedTitle = commandResponse == null ? string.Empty : commandResponse.Value ?? string.Empty;
Suggestion 4:
Enhance error messages with actual values for better debugging experience
Include the actual value in the exception message to help with debugging when an invalid cookie name is provided.
dotnet/src/webdriver/CookieJar.cs [82]
-throw new ArgumentException("Cookie name cannot be empty", nameof(name));
+throw new ArgumentException($"Cookie name cannot be empty. Provided value: '{name}'", nameof(name));
Suggestion 5:
Provide accurate error messages that reflect the actual system locale instead of assuming Arabic
The error message incorrectly assumes the system language is Arabic when it's any non-English locale. Update the message to be more accurate and include the actual locale in the error message.
java/src/org/openqa/selenium/chrome/ChromeDriverService.java [289]
-throw new NumberFormatException("Couldn't format the port numbers because the System Language is arabic: \"" + String.format("--port=%d", getPort()) +
+throw new NumberFormatException("Couldn't format the port numbers due to non-English system locale '" + Locale.getDefault(Locale.Category.FORMAT) + "': \"" + String.format("--port=%d", getPort()) +
Pattern 5: Initialize collections and properties with safe default values instead of null to prevent NullReferenceExceptions. Use empty collections or appropriate default values for properties.
Example code before:
public class RequestHandler {
public List<string> Headers { get; set; } = null!;
public void AddHeader(string name, string value) {
Headers.Add($"{name}: {value}");
}
}
Example code after:
public class RequestHandler {
public List<string> Headers { get; set; } = new List<string>();
public void AddHeader(string name, string value) {
Headers.Add($"{name}: {value}");
}
}
Relevant past accepted suggestions:
Suggestion 1:
Initialize collection to prevent nulls
Initialize the Headers dictionary in the parameterless constructor to prevent NullReferenceException when adding headers.
dotnet/src/webdriver/HttpRequestData.cs [34-39]
public HttpRequestData()
{
this.Method = null!;
this.Url = null!;
- this.Headers = null!;
+ this.Headers = new Dictionary<string, string>();
}
Suggestion 2:
Use meaningful defaults over nulls
Avoid using null-forgiving operator (!) for required properties. Instead, initialize with meaningful default values.
dotnet/src/webdriver/HttpRequestData.cs [34-39]
public HttpRequestData()
{
- this.Method = null!;
- this.Url = null!;
- this.Headers = null!;
+ this.Method = "GET";
+ this.Url = string.Empty;
+ this.Headers = new Dictionary<string, string>();
}
Suggestion 3:
Avoid null reference runtime exceptions
Initialize RequestMatcher in the constructor instead of using null! to avoid potential null reference exceptions at runtime.
dotnet/src/webdriver/NetworkRequestHandler.cs [35]
-public Func<HttpRequestData, bool> RequestMatcher { get; set; } = null!;
+public Func<HttpRequestData, bool> RequestMatcher { get; set; } = _ => false;
Suggestion 4:
Provide safe default function implementations
Initialize ResponseMatcher and ResponseTransformer in the constructor with safe default implementations instead of using null! to avoid potential null reference exceptions.
dotnet/src/webdriver/NetworkResponseHandler.cs [35-42]
-public Func<HttpResponseData, bool> ResponseMatcher { get; set; } = null!;
-public Func<HttpResponseData, HttpResponseData> ResponseTransformer { get; set; } = null!;
+public Func<HttpResponseData, bool> ResponseMatcher { get; set; } = _ => false;
+public Func<HttpResponseData, HttpResponseData> ResponseTransformer { get; set; } = response => response;
Suggestion 5:
Add safe default function implementation
Initialize UriMatcher with a safe default implementation instead of using null! to avoid potential null reference exceptions.
dotnet/src/webdriver/NetworkAuthenticationHandler.cs [35]
-public Func<Uri, bool> UriMatcher { get; set; } = null!;
+public Func<Uri, bool> UriMatcher { get; set; } = _ => false;
Suggestion 6:
Add null safety checks and proper dictionary access to prevent potential runtime exceptions
The IsEnabled method could throw a NullReferenceException if _loggers is null or if the logger's issuer type is not found in the dictionary. Add null checks and fallback logic.
dotnet/src/webdriver/Internal/Logging/LogContext.cs [104]
-return Handlers != null && level >= _level && level >= _loggers?[logger.Issuer].Level;
+return Handlers != null && level >= _level && (_loggers?.TryGetValue(logger.Issuer, out var loggerEntry) != true || level >= loggerEntry.Level);
Suggestion 7:
Add null checks during dictionary initialization to prevent potential null reference exceptions
The logger initialization in constructor could fail if any of the source loggers has a null Issuer. Add validation to handle this case.
dotnet/src/webdriver/Internal/Logging/LogContext.cs [51]
-_loggers = new ConcurrentDictionary<Type, ILogger>(loggers.Select(l => new KeyValuePair<Type, ILogger>(l.Key, new Logger(l.Value.Issuer, level))));
+_loggers = new ConcurrentDictionary<Type, ILogger>(loggers.Where(l => l.Value?.Issuer != null).Select(l => new KeyValuePair<Type, ILogger>(l.Key, new Logger(l.Value.Issuer, level))));
[Auto-generated best practices - 2025-04-30]
This wiki is not where you want to be! Visit the Wiki Home for more useful links
Getting Involved
Triaging Issues
Releasing Selenium
Ruby Development
Python Bindings
Ruby Bindings
WebDriverJs
This content is being evaluated for where it belongs
Architectural Overview
Automation Atoms
HtmlUnitDriver
Lift Style API
LoadableComponent
Logging
PageFactory
RemoteWebDriver
Xpath In WebDriver
Moved to Official Documentation
Bot Style Tests
Buck
Continuous Integration
Crazy Fun Build
Design Patterns
Desired Capabilities
Developer Tips
Domain Driven Design
Firefox Driver
Firefox Driver Internals
Focus Stealing On Linux
Frequently Asked Questions
Google Summer Of Code
Grid Platforms
History
Internet Explorer Driver
InternetExplorerDriver Internals
Next Steps
PageObjects
RemoteWebDriverServer
Roadmap
Scaling WebDriver
SeIDE Release Notes
Selenium Emulation
Selenium Grid 4
Selenium Help
Shipping Selenium 3
The Team
TLC Meetings
Untrusted SSL Certificates
WebDriver For Mobile Browsers
Writing New Drivers