Skip to content

Commit

Permalink
Adding support for CDP version 87 in .NET
Browse files Browse the repository at this point in the history
  • Loading branch information
jimevans committed Nov 10, 2020
1 parent be6f8ee commit de8579b
Show file tree
Hide file tree
Showing 13 changed files with 711 additions and 2 deletions.
4 changes: 4 additions & 0 deletions dotnet/src/webdriver/BUILD.bazel
Expand Up @@ -51,6 +51,7 @@ generated_assembly_info(
"//dotnet/src/webdriver/cdp:generate-v84",
"//dotnet/src/webdriver/cdp:generate-v85",
"//dotnet/src/webdriver/cdp:generate-v86",
"//dotnet/src/webdriver/cdp:generate-v87",
],
out = "WebDriver",
resources = [
Expand Down Expand Up @@ -99,6 +100,7 @@ generated_assembly_info(
"//dotnet/src/webdriver/cdp:generate-v84",
"//dotnet/src/webdriver/cdp:generate-v85",
"//dotnet/src/webdriver/cdp:generate-v86",
"//dotnet/src/webdriver/cdp:generate-v87",
],
out = "WebDriver",
resources = [
Expand Down Expand Up @@ -138,6 +140,7 @@ generated_assembly_info(
"//dotnet/src/webdriver/cdp:generate-v84",
"//dotnet/src/webdriver/cdp:generate-v85",
"//dotnet/src/webdriver/cdp:generate-v86",
"//dotnet/src/webdriver/cdp:generate-v87",
],
out = "strongnamed/WebDriver",
keyfile = "//dotnet:WebDriver.snk",
Expand Down Expand Up @@ -187,6 +190,7 @@ generated_assembly_info(
"//dotnet/src/webdriver/cdp:generate-v84",
"//dotnet/src/webdriver/cdp:generate-v85",
"//dotnet/src/webdriver/cdp:generate-v86",
"//dotnet/src/webdriver/cdp:generate-v87",
],
out = "strongnamed/WebDriver",
keyfile = "//dotnet:WebDriver.snk",
Expand Down
3 changes: 2 additions & 1 deletion dotnet/src/webdriver/DevTools/DevToolsDomains.cs
Expand Up @@ -34,9 +34,10 @@ public abstract class DevToolsDomains
// This is the list of known supported DevTools version implementation.
// Note carefully that it is sorted in reverse order, most recent
// version first, as that is more likely to match. When new versions
// are implemented for support,
// are implemented for support, new types must be added to this list.
private static readonly List<Type> SupportedDevToolsVersions = new List<Type>()
{
typeof(V87.V87Domains),
typeof(V86.V86Domains),
typeof(V85.V85Domains),
typeof(V84.V84Domains)
Expand Down
66 changes: 66 additions & 0 deletions dotnet/src/webdriver/DevTools/v87/V87Domains.cs
@@ -0,0 +1,66 @@
// <copyright file="V86Domains.cs" company="WebDriver Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Text;

namespace OpenQA.Selenium.DevTools.V87
{
/// <summary>
/// Class containing the domain implementation for version 86 of the DevTools Protocol.
/// </summary>
public class V87Domains : DevToolsDomains
{
private DevToolsSessionDomains domains;

public V87Domains(DevToolsSession session)
{
this.domains = new DevToolsSessionDomains(session);
}

/// <summary>
/// Gets the DevTools Protocol version for which this class is valid.
/// </summary>
public static int DevToolsVersion => 87;

/// <summary>
/// Gets the version-specific domains for the DevTools session. This value must be cast to a version specific type to be at all useful.
/// </summary>
public override DevTools.DevToolsSessionDomains VersionSpecificDomains => this.domains;

/// <summary>
/// Gets the object used for manipulating network information in the browser.
/// </summary>
public override DevTools.Network Network => new V87Network(domains.Network, domains.Fetch);

/// <summary>
/// Gets the object used for manipulating the browser's JavaScript execution.
/// </summary>
public override JavaScript JavaScript => new V87JavaScript(domains.Runtime, domains.Page);

/// <summary>
/// Gets the object used for manipulating DevTools Protocol targets.
/// </summary>
public override DevTools.Target Target => new V87Target(domains.Target);

/// <summary>
/// Gets the object used for manipulating the browser's logs.
/// </summary>
public override DevTools.Log Log => new V87Log(domains.Log);
}
}
172 changes: 172 additions & 0 deletions dotnet/src/webdriver/DevTools/v87/V87JavaScript.cs
@@ -0,0 +1,172 @@
// <copyright file="V86JavaScript.cs" company="WebDriver Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using OpenQA.Selenium.DevTools.V87.Page;
using OpenQA.Selenium.DevTools.V87.Runtime;

namespace OpenQA.Selenium.DevTools.V87
{
/// <summary>
/// Class containing the JavaScript implementation for version 85 of the DevTools Protocol.
/// </summary>
public class V87JavaScript : JavaScript
{
private RuntimeAdapter runtime;
private PageAdapter page;

/// <summary>
/// Initializes a new instance of the <see cref="V86JavaScript"/> class.
/// </summary>
/// <param name="runtime">The DevTools Protocol adapter for the Runtime domain.</param>
/// <param name="page">The DevTools Protocol adapter for the Page domain.</param>
public V87JavaScript(RuntimeAdapter runtime, PageAdapter page)
{
this.runtime = runtime;
this.page = page;
this.runtime.BindingCalled += OnRuntimeBindingCalled;
this.runtime.ConsoleAPICalled += OnRuntimeConsoleApiCalled;
this.runtime.ExceptionThrown += OnRuntimeExceptionThrown;
}

/// <summary>
/// Asynchronously enables the Runtime domain in the DevTools Protocol.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public override async Task EnableRuntime()
{
await runtime.Enable();
}

/// <summary>
/// Asynchronously disables the Runtime domain in the DevTools Protocol.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public override async Task DisableRuntime()
{
await runtime.Disable();
}

/// <summary>
/// Asynchronously enables the Page domain in the DevTools Protocol.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public override async Task EnablePage()
{
await page.Enable();
}

/// <summary>
/// Asynchronously disables the Page domain in the DevTools Protocol.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public override async Task DisablePage()
{
await page.Disable();
}

/// <summary>
/// Adds a binding to a specific JavaScript name.
/// </summary>
/// <param name="name">The name to which to bind to.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
public override async Task AddBinding(string name)
{
await runtime.AddBinding(new AddBindingCommandSettings() { Name = name });
}

/// <summary>
/// Removes a binding from a specific JavaScript name.
/// </summary>
/// <param name="name">The name to which to remove the bind from.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
public override async Task RemoveBinding(string name)
{
await runtime.RemoveBinding(new RemoveBindingCommandSettings() { Name = name });
}

/// <summary>
/// Adds a JavaScript snippet to evaluate when a new document is opened.
/// </summary>
/// <param name="script">The script to add to be evaluated when a new document is opened.</param>
/// <returns>A task that represents the asynchronous operation. The task result contains the internal ID of the script.</returns>
public override async Task<string> AddScriptToEvaluateOnNewDocument(string script)
{
var result = await page.AddScriptToEvaluateOnNewDocument(new AddScriptToEvaluateOnNewDocumentCommandSettings() { Source = script });
return result.Identifier;
}

/// <summary>
/// Removes a JavaScript snippet from evaluate when a new document is opened.
/// </summary>
/// <param name="scriptId">The ID of the script to be removed.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
public override async Task RemoveScriptToEvaluateOnNewDocument(string scriptId)
{
await page.RemoveScriptToEvaluateOnNewDocument(new RemoveScriptToEvaluateOnNewDocumentCommandSettings() { Identifier = scriptId });
}

private void OnRuntimeBindingCalled(object sender, Runtime.BindingCalledEventArgs e)
{
BindingCalledEventArgs wrapped = new BindingCalledEventArgs()
{
ExecutionContextId = e.ExecutionContextId,
Name = e.Name,
Payload = e.Payload
};

this.OnBindingCalled(wrapped);
}

private void OnRuntimeExceptionThrown(object sender, Runtime.ExceptionThrownEventArgs e)
{
// TODO: Collect stack trace elements
var wrapped = new ExceptionThrownEventArgs()
{
Timestamp = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(e.Timestamp),
Message = e.ExceptionDetails.Text
};

this.OnExceptionThrown(wrapped);
}

private void OnRuntimeConsoleApiCalled(object sender, ConsoleAPICalledEventArgs e)
{
List<ConsoleApiArgument> args = new List<ConsoleApiArgument>();
foreach (var arg in e.Args)
{
string argValue = null;
if (arg.Value != null)
{
argValue = arg.Value.ToString();
}
args.Add(new ConsoleApiArgument() { Type = arg.Type.ToString(), Value = argValue });
}

var wrapped = new ConsoleApiCalledEventArgs()
{
Timestamp = new DateTime(1979, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(e.Timestamp),
Type = e.Type,
Arguments = args.AsReadOnly()
};

this.OnConsoleApiCalled(wrapped);
}
}
}
80 changes: 80 additions & 0 deletions dotnet/src/webdriver/DevTools/v87/V87Log.cs
@@ -0,0 +1,80 @@
// <copyright file="V85Log.cs" company="WebDriver Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using OpenQA.Selenium.DevTools.V87.Log;

namespace OpenQA.Selenium.DevTools.V87
{
/// <summary>
/// Class containing the browser's log as referenced by version 86 of the DevTools Protocol.
/// </summary>
public class V87Log : DevTools.Log
{
private LogAdapter adapter;

/// <summary>
/// Initializes a new instance of the <see cref="V86Log"/> class.
/// </summary>
/// <param name="adapter">The adapter for the Log domain.</param>
public V87Log(LogAdapter adapter)
{
this.adapter = adapter;
this.adapter.EntryAdded += OnAdapterEntryAdded;
}

/// <summary>
/// Asynchronously enables manipulation of the browser's log.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public override async Task Enable()
{
await adapter.Enable();
}

/// <summary>
/// Asynchronously disables manipulation of the browser's log.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public override async Task Disable()
{
await adapter.Disable();
}

/// <summary>
/// Asynchronously clears the browser's log.
/// </summary>
/// <returns>A task that represents the asynchronous operation.</returns>
public override async Task Clear()
{
await adapter.Clear();
}

private void OnAdapterEntryAdded(object sender, Log.EntryAddedEventArgs e)
{
EntryAddedEventArgs propagated = new EntryAddedEventArgs();
propagated.Entry = new LogEntry();
propagated.Entry.Kind = e.Entry.Source.ToString();
propagated.Entry.Message = e.Entry.Text;
this.OnEntryAdded(propagated);
}
}
}

0 comments on commit de8579b

Please sign in to comment.