Skip to content

Commit 833eea0

Browse files
committed
Merge branch 'cookie-jar' of https://github.com/RenderMichael/selenium into cookie-jar
2 parents 4c1d6e3 + f657431 commit 833eea0

File tree

6 files changed

+69
-82
lines changed

6 files changed

+69
-82
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
}

dotnet/src/webdriver/Response.cs

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,12 @@ namespace OpenQA.Selenium
3131
/// </summary>
3232
public class Response
3333
{
34-
private readonly static JsonSerializerOptions s_jsonSerializerOptions = new()
34+
private static readonly JsonSerializerOptions s_jsonSerializerOptions = new()
3535
{
3636
TypeInfoResolver = ResponseJsonSerializerContext.Default,
3737
Converters = { new ResponseValueJsonConverter() } // we still need it to make `Object` as `Dictionary`
3838
};
3939

40-
private object responseValue;
41-
private string responseSessionId;
42-
private WebDriverResult responseStatus;
43-
4440
/// <summary>
4541
/// Initializes a new instance of the <see cref="Response"/> class
4642
/// </summary>
@@ -56,7 +52,7 @@ public Response(SessionId sessionId)
5652
{
5753
if (sessionId != null)
5854
{
59-
this.responseSessionId = sessionId.ToString();
55+
this.SessionId = sessionId.ToString();
6056
}
6157
}
6258

@@ -66,49 +62,48 @@ private Response(Dictionary<string, object> rawResponse)
6662
{
6763
if (rawResponse["sessionId"] != null)
6864
{
69-
this.responseSessionId = rawResponse["sessionId"].ToString();
65+
this.SessionId = rawResponse["sessionId"].ToString();
7066
}
7167
}
7268

73-
if (rawResponse.ContainsKey("value"))
69+
if (rawResponse.TryGetValue("value", out object value))
7470
{
75-
this.responseValue = rawResponse["value"];
71+
this.Value = value;
7672
}
7773

7874
// If the returned object does *not* have a "value" property
7975
// the response value should be the entirety of the response.
8076
// TODO: Remove this if statement altogether; there should
8177
// never be a spec-compliant response that does not contain a
8278
// value property.
83-
if (!rawResponse.ContainsKey("value") && this.responseValue == null)
79+
if (!rawResponse.ContainsKey("value") && this.Value == null)
8480
{
8581
// Special-case for the new session command, where the "capabilities"
8682
// property of the response is the actual value we're interested in.
8783
if (rawResponse.ContainsKey("capabilities"))
8884
{
89-
this.responseValue = rawResponse["capabilities"];
85+
this.Value = rawResponse["capabilities"];
9086
}
9187
else
9288
{
93-
this.responseValue = rawResponse;
89+
this.Value = rawResponse;
9490
}
9591
}
9692

97-
Dictionary<string, object> valueDictionary = this.responseValue as Dictionary<string, object>;
98-
if (valueDictionary != null)
93+
if (this.Value is Dictionary<string, object> valueDictionary)
9994
{
10095
// Special case code for the new session command. If the response contains
10196
// sessionId and capabilities properties, fix up the session ID and value members.
10297
if (valueDictionary.ContainsKey("sessionId"))
10398
{
104-
this.responseSessionId = valueDictionary["sessionId"].ToString();
105-
if (valueDictionary.ContainsKey("capabilities"))
99+
this.SessionId = valueDictionary["sessionId"].ToString();
100+
if (valueDictionary.TryGetValue("capabilities", out object capabilities))
106101
{
107-
this.responseValue = valueDictionary["capabilities"];
102+
this.Value = capabilities;
108103
}
109104
else
110105
{
111-
this.responseValue = valueDictionary["value"];
106+
this.Value = valueDictionary["value"];
112107
}
113108
}
114109
}
@@ -117,29 +112,17 @@ private Response(Dictionary<string, object> rawResponse)
117112
/// <summary>
118113
/// Gets or sets the value from JSON.
119114
/// </summary>
120-
public object Value
121-
{
122-
get { return this.responseValue; }
123-
set { this.responseValue = value; }
124-
}
115+
public object Value { get; set; }
125116

126117
/// <summary>
127118
/// Gets or sets the session ID.
128119
/// </summary>
129-
public string SessionId
130-
{
131-
get { return this.responseSessionId; }
132-
set { this.responseSessionId = value; }
133-
}
120+
public string SessionId { get; set; }
134121

135122
/// <summary>
136123
/// Gets or sets the status value of the response.
137124
/// </summary>
138-
public WebDriverResult Status
139-
{
140-
get { return this.responseStatus; }
141-
set { this.responseStatus = value; }
142-
}
125+
public WebDriverResult Status { get; set; }
143126

144127
/// <summary>
145128
/// Returns a new <see cref="Response"/> from a JSON-encoded string.
@@ -148,9 +131,10 @@ public WebDriverResult Status
148131
/// <returns>A <see cref="Response"/> object described by the JSON string.</returns>
149132
public static Response FromJson(string value)
150133
{
151-
Dictionary<string, object> deserializedResponse = JsonSerializer.Deserialize<Dictionary<string, object>>(value, s_jsonSerializerOptions);
152-
Response response = new Response(deserializedResponse);
153-
return response;
134+
Dictionary<string, object> deserializedResponse = JsonSerializer.Deserialize<Dictionary<string, object>>(value, s_jsonSerializerOptions)
135+
?? throw new WebDriverException("JSON success response returned \"null\" value");
136+
137+
return new Response(deserializedResponse);
154138
}
155139

156140
/// <summary>
@@ -160,7 +144,8 @@ public static Response FromJson(string value)
160144
/// <returns>A <see cref="Response"/> object described by the JSON string.</returns>
161145
public static Response FromErrorJson(string value)
162146
{
163-
var deserializedResponse = JsonSerializer.Deserialize<Dictionary<string, object>>(value, s_jsonSerializerOptions);
147+
var deserializedResponse = JsonSerializer.Deserialize<Dictionary<string, object>>(value, s_jsonSerializerOptions)
148+
?? throw new WebDriverException("JSON error response returned \"null\" value");
164149

165150
var response = new Response();
166151

@@ -181,14 +166,14 @@ public static Response FromErrorJson(string value)
181166
throw new WebDriverException($"The 'value > error' property was not found in the response:{Environment.NewLine}{value}");
182167
}
183168

184-
if (errorObject is not string)
169+
if (errorObject is not string errorString)
185170
{
186171
throw new WebDriverException($"The 'value > error' property is not a string{Environment.NewLine}{value}");
187172
}
188173

189174
response.Value = deserializedResponse["value"];
190175

191-
response.Status = WebDriverError.ResultFromError(errorObject.ToString());
176+
response.Status = WebDriverError.ResultFromError(errorString);
192177

193178
return response;
194179
}
@@ -213,8 +198,5 @@ public override string ToString()
213198
}
214199

215200
[JsonSerializable(typeof(Dictionary<string, object>))]
216-
internal partial class ResponseJsonSerializerContext : JsonSerializerContext
217-
{
218-
219-
}
201+
internal sealed partial class ResponseJsonSerializerContext : JsonSerializerContext;
220202
}

java/src/org/openqa/selenium/remote/service/DriverService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,10 @@ public void start() throws IOException {
242242
processFinished.cancel(true);
243243
break;
244244
case PROCESS_DIED:
245+
int exitValue = process.exitValue();
245246
process = null;
246-
throw new WebDriverException("Driver server process died prematurely.");
247+
throw new WebDriverException(
248+
"Driver server process died prematurely, exit value: " + exitValue);
247249
case PROCESS_IS_ACTIVE:
248250
process.shutdown();
249251
throw new WebDriverException("Timed out waiting for driver server to bind the port.");

0 commit comments

Comments
 (0)