Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public async Task CanCallFunctionWithArgumentNumberZero()
[Test]
public async Task CanCallFunctionWithArgumentNumberNegativeZero()
{
var arg = new NumberLocalValue(double.NegativeZero);
var arg = new NumberLocalValue(-0.0d);

var result = await context.Script.CallFunctionAsync($$"""
(arg) => {
Expand Down
8 changes: 5 additions & 3 deletions dotnet/test/common/BiDi/Script/CallFunctionParameterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// </copyright>

using NUnit.Framework;
using System.Runtime.CompilerServices;
using System.Reflection;
using System.Threading.Tasks;

namespace OpenQA.Selenium.BiDi.Script;
Expand Down Expand Up @@ -229,7 +229,9 @@ private string GetElementId(By selector)
var element = (WebElement)driver.FindElement(selector);
return ReflectElementId(element);

[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "get_Id")]
static extern string ReflectElementId(WebElement element);
static string ReflectElementId(WebElement element)
{
return (string)typeof(WebElement).GetProperty("Id", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(element, null);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
// </copyright>

using NUnit.Framework;
using OpenQA.Selenium.Extensions;
using System.Threading.Tasks;

namespace OpenQA.Selenium.BiDi.Script;
Expand Down Expand Up @@ -135,7 +136,7 @@ public async Task CanCallFunctionAndReturnNumberNegativeZero()

var actualNumberValue = ((NumberRemoteValue)response.AsSuccessResult()).Value;
Assert.That(actualNumberValue, Is.Zero);
Assert.That(double.IsNegative(actualNumberValue), Is.True);
Assert.That(DoubleUtility.IsNegative(actualNumberValue), Is.True);
}

[Test]
Expand Down
4 changes: 2 additions & 2 deletions dotnet/test/common/BiDi/Script/LocalValueConversionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ static void AssertValue(LocalValue value)
[Test]
public void CanConvertDateTimeOffsetToLocalValue()
{
var date = new DateTimeOffset(2025, 4, 13, 5, 40, 20, 123, 456, TimeSpan.FromHours(+3));
var date = new DateTimeOffset(2025, 4, 13, 5, 40, 20, 123, TimeSpan.FromHours(+3));

AssertValue(date);

Expand All @@ -172,7 +172,7 @@ public void CanConvertDateTimeOffsetToLocalValue()
static void AssertValue(LocalValue value)
{
Assert.That(value, Is.TypeOf<DateLocalValue>());
Assert.That((value as DateLocalValue).Value, Is.EqualTo("2025-04-13T05:40:20.1234560+03:00"));
Assert.That((value as DateLocalValue).Value, Is.EqualTo("2025-04-13T05:40:20.1230000+03:00"));
}
}

Expand Down
3 changes: 2 additions & 1 deletion dotnet/test/common/Environment/TestWebServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
// </copyright>

using Bazel;
using OpenQA.Selenium.Utilities;
using System;
using System.Diagnostics;
using System.IO;
Expand Down Expand Up @@ -46,7 +47,7 @@ public async Task StartAsync()

var standaloneAppserverProbingPath = @"_main/java/test/org/openqa/selenium/environment/appserver";

if (OperatingSystem.IsWindows())
if (PlatformUtilities.IsWindows())
{
standaloneAppserverProbingPath += ".exe";
}
Expand Down
5 changes: 3 additions & 2 deletions dotnet/test/common/Environment/UrlBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,10 @@ public string CreateInlinePage(InlinePage page)

// The response string from the Java remote server has trailing null
// characters. This is due to the fix for issue 288.
if (responseString.Contains('\0'))
int terminator = responseString.IndexOf('\0');
if (terminator >= 0)
{
responseString = responseString[..responseString.IndexOf('\0')];
responseString = responseString.Substring(0, terminator);
}

if (responseString.Contains("localhost"))
Expand Down
31 changes: 31 additions & 0 deletions dotnet/test/common/Utilities/ArrayExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// <copyright file="ArrayExtensions.cs" company="Selenium 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.
// </copyright>

using System.Collections.Generic;
using System.Linq;

namespace System;

internal static class ArrayExtensions
{
public static IEnumerable<T> Reverse<T>(this T[] array)
{
return Enumerable.Reverse(array);
}
}
34 changes: 34 additions & 0 deletions dotnet/test/common/Utilities/DoubleUtility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// <copyright file="DoubleUtility.cs" company="Selenium 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.
// </copyright>

using System;

namespace OpenQA.Selenium.Extensions;

internal static class DoubleUtility
{
public static bool IsNegative(double d)
{
var isNegative = BitConverter.DoubleToInt64Bits(d) < 0;
#if NET8_0_OR_GREATER
System.Diagnostics.Debug.Assert(isNegative == double.IsNegative(d));
#endif
return isNegative;
}
}
32 changes: 32 additions & 0 deletions dotnet/test/common/Utilities/PlatformUtilities.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// <copyright file="PlatformUtilities.cs" company="Selenium 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.
// </copyright>

namespace OpenQA.Selenium.Utilities;

internal static class PlatformUtilities
{
public static bool IsWindows()
{
#if NET8_0_OR_GREATER
return System.OperatingSystem.IsWindows();
#else
return System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows);
#endif
}
}
37 changes: 37 additions & 0 deletions dotnet/test/common/Utilities/ProcessExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// <copyright file="ProcessExtensions.cs" company="Selenium 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.
// </copyright>

using System.Diagnostics;

namespace System;

internal static class ProcessExtensions
{
public static void Kill(this Process process, bool entireProcessTree)
{
if (!entireProcessTree)
{
process.Kill();
return;
}

// TODO kill all child processes
process.Kill();
}
}
40 changes: 40 additions & 0 deletions dotnet/test/common/Utilities/TaskExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// <copyright file="TaskExtensions.cs" company="Selenium 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.
// </copyright>

#if !NET8_0_OR_GREATER

using System.Threading.Tasks;

namespace System;

internal static class TaskExtensions
{
public static async Task<T> WaitAsync<T>(this Task<T> task, TimeSpan timeout)
{
var timeoutTask = Task.Delay(timeout);
var completedTask = await Task.WhenAny(task, timeoutTask);
if (completedTask == timeoutTask)
{
throw new TimeoutException();
}
return await task;
}
}

#endif
Loading