Skip to content

Commit 623c4aa

Browse files
[dotnet] Add nullability to Logs API (SeleniumHQ#14875)
1 parent abb8440 commit 623c4aa

File tree

4 files changed

+41
-38
lines changed

4 files changed

+41
-38
lines changed

dotnet/src/webdriver/ILogs.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717
// under the License.
1818
// </copyright>
1919

20+
using System;
2021
using System.Collections.ObjectModel;
2122

23+
#nullable enable
24+
2225
namespace OpenQA.Selenium
2326
{
2427
/// <summary>
@@ -37,6 +40,7 @@ public interface ILogs
3740
/// <param name="logKind">The log for which to retrieve the log entries.
3841
/// Log types can be found in the <see cref="LogType"/> class.</param>
3942
/// <returns>The list of <see cref="LogEntry"/> objects for the specified log.</returns>
43+
/// <exception cref="ArgumentNullException">If <paramref name="logKind"/> is <see langword="null"/>.</exception>
4044
ReadOnlyCollection<LogEntry> GetLog(string logKind);
4145
}
4246
}

dotnet/src/webdriver/LogEntry.cs

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,15 @@
2121
using System.Collections.Generic;
2222
using System.Globalization;
2323

24+
#nullable enable
25+
2426
namespace OpenQA.Selenium
2527
{
2628
/// <summary>
2729
/// Represents an entry in a log from a driver instance.
2830
/// </summary>
2931
public class LogEntry
3032
{
31-
private LogLevel level = LogLevel.All;
32-
private DateTime timestamp = DateTime.MinValue;
33-
private string message = string.Empty;
3433

3534
/// <summary>
3635
/// Initializes a new instance of the <see cref="LogEntry"/> class.
@@ -42,34 +41,27 @@ private LogEntry()
4241
/// <summary>
4342
/// Gets the timestamp value of the log entry.
4443
/// </summary>
45-
public DateTime Timestamp
46-
{
47-
get { return this.timestamp; }
48-
}
44+
public DateTime Timestamp { get; private set; } = DateTime.MinValue;
4945

5046
/// <summary>
5147
/// Gets the logging level of the log entry.
5248
/// </summary>
53-
public LogLevel Level
54-
{
55-
get { return this.level; }
56-
}
49+
public LogLevel Level { get; private set; } = LogLevel.All;
5750

5851
/// <summary>
5952
/// Gets the message of the log entry.
6053
/// </summary>
61-
public string Message
62-
{
63-
get { return this.message; }
64-
}
54+
public string Message { get; private set; } = string.Empty;
55+
56+
private static readonly DateTime UnixEpoch = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
6557

6658
/// <summary>
6759
/// Returns a string that represents the current <see cref="LogEntry"/>.
6860
/// </summary>
6961
/// <returns>A string that represents the current <see cref="LogEntry"/>.</returns>
7062
public override string ToString()
7163
{
72-
return string.Format(CultureInfo.InvariantCulture, "[{0:yyyy-MM-ddTHH:mm:ssZ}] [{1}] {2}", this.timestamp, this.level, this.message);
64+
return string.Format(CultureInfo.InvariantCulture, "[{0:yyyy-MM-ddTHH:mm:ssZ}] [{1}] {2}", this.Timestamp, this.Level, this.Message);
7365
}
7466

7567
/// <summary>
@@ -78,32 +70,31 @@ public override string ToString()
7870
/// <param name="entryDictionary">The <see cref="Dictionary{TKey, TValue}"/> from
7971
/// which to create the <see cref="LogEntry"/>.</param>
8072
/// <returns>A <see cref="LogEntry"/> with the values in the dictionary.</returns>
81-
internal static LogEntry FromDictionary(Dictionary<string, object> entryDictionary)
73+
internal static LogEntry FromDictionary(Dictionary<string, object?> entryDictionary)
8274
{
8375
LogEntry entry = new LogEntry();
84-
if (entryDictionary.ContainsKey("message"))
76+
if (entryDictionary.TryGetValue("message", out object? message))
8577
{
86-
entry.message = entryDictionary["message"].ToString();
78+
entry.Message = message?.ToString() ?? string.Empty;
8779
}
8880

89-
if (entryDictionary.ContainsKey("timestamp"))
81+
if (entryDictionary.TryGetValue("timestamp", out object? timestamp))
9082
{
91-
DateTime zeroDate = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
92-
double timestampValue = Convert.ToDouble(entryDictionary["timestamp"], CultureInfo.InvariantCulture);
93-
entry.timestamp = zeroDate.AddMilliseconds(timestampValue);
83+
double timestampValue = Convert.ToDouble(timestamp, CultureInfo.InvariantCulture);
84+
entry.Timestamp = UnixEpoch.AddMilliseconds(timestampValue);
9485
}
9586

96-
if (entryDictionary.ContainsKey("level"))
87+
if (entryDictionary.TryGetValue("level", out object? level))
9788
{
98-
string levelValue = entryDictionary["level"].ToString();
99-
try
89+
if (Enum.TryParse(level?.ToString(), ignoreCase: true, out LogLevel result))
10090
{
101-
entry.level = (LogLevel)Enum.Parse(typeof(LogLevel), levelValue, true);
91+
entry.Level = result;
10292
}
103-
catch (ArgumentException)
93+
else
10494
{
10595
// If the requested log level string is not a valid log level,
10696
// ignore it and use LogLevel.All.
97+
entry.Level = LogLevel.All;
10798
}
10899
}
109100

dotnet/src/webdriver/LogLevel.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
// under the License.
1818
// </copyright>
1919

20+
#nullable enable
21+
2022
namespace OpenQA.Selenium
2123
{
2224
/// <summary>

dotnet/src/webdriver/Logs.cs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,22 +21,25 @@
2121
using System.Collections.Generic;
2222
using System.Collections.ObjectModel;
2323

24+
#nullable enable
25+
2426
namespace OpenQA.Selenium
2527
{
2628
/// <summary>
2729
/// Provides a mechanism for examining logs for the driver during the test.
2830
/// </summary>
2931
public class Logs : ILogs
3032
{
31-
private WebDriver driver;
33+
private readonly WebDriver driver;
3234

3335
/// <summary>
3436
/// Initializes a new instance of the <see cref="Logs"/> class.
3537
/// </summary>
3638
/// <param name="driver">Instance of the driver currently in use</param>
39+
/// <exception cref="ArgumentNullException">If <paramref name="driver"/> is <see langword="null"/>.</exception>
3740
public Logs(WebDriver driver)
3841
{
39-
this.driver = driver;
42+
this.driver = driver ?? throw new ArgumentNullException(nameof(driver));
4043
}
4144

4245
/// <summary>
@@ -50,12 +53,11 @@ public ReadOnlyCollection<string> AvailableLogTypes
5053
try
5154
{
5255
Response commandResponse = this.driver.InternalExecute(DriverCommand.GetAvailableLogTypes, null);
53-
object[] responseValue = commandResponse.Value as object[];
54-
if (responseValue != null)
56+
if (commandResponse.Value is object[] responseValue)
5557
{
5658
foreach (object logKind in responseValue)
5759
{
58-
availableLogTypes.Add(logKind.ToString());
60+
availableLogTypes.Add(logKind.ToString()!);
5961
}
6062
}
6163
}
@@ -74,21 +76,25 @@ public ReadOnlyCollection<string> AvailableLogTypes
7476
/// <param name="logKind">The log for which to retrieve the log entries.
7577
/// Log types can be found in the <see cref="LogType"/> class.</param>
7678
/// <returns>The list of <see cref="LogEntry"/> objects for the specified log.</returns>
79+
/// <exception cref="ArgumentNullException">If <paramref name="logKind"/> is <see langword="null"/>.</exception>
7780
public ReadOnlyCollection<LogEntry> GetLog(string logKind)
7881
{
82+
if (logKind is null)
83+
{
84+
throw new ArgumentNullException(nameof(logKind));
85+
}
86+
7987
List<LogEntry> entries = new List<LogEntry>();
8088

8189
Dictionary<string, object> parameters = new Dictionary<string, object>();
8290
parameters.Add("type", logKind);
8391
Response commandResponse = this.driver.InternalExecute(DriverCommand.GetLog, parameters);
8492

85-
object[] responseValue = commandResponse.Value as object[];
86-
if (responseValue != null)
93+
if (commandResponse.Value is object?[] responseValue)
8794
{
88-
foreach (object rawEntry in responseValue)
95+
foreach (object? rawEntry in responseValue)
8996
{
90-
Dictionary<string, object> entryDictionary = rawEntry as Dictionary<string, object>;
91-
if (entryDictionary != null)
97+
if (rawEntry is Dictionary<string, object?> entryDictionary)
9298
{
9399
entries.Add(LogEntry.FromDictionary(entryDictionary));
94100
}

0 commit comments

Comments
 (0)