|
19 | 19 |
|
20 | 20 | using NUnit.Framework; |
21 | 21 | using OpenQA.Selenium.BiDi.Modules.Script; |
| 22 | +using System; |
| 23 | +using System.Collections.Generic; |
| 24 | +using System.Globalization; |
22 | 25 | using System.Threading.Tasks; |
23 | 26 |
|
24 | 27 | namespace OpenQA.Selenium.BiDi.Script; |
@@ -219,4 +222,140 @@ public async Task CanCallFunctionInARealm() |
219 | 222 | Assert.That(res1, Is.EqualTo(3)); |
220 | 223 | Assert.That(res2, Is.EqualTo(5)); |
221 | 224 | } |
| 225 | + |
| 226 | + [Test] |
| 227 | + [TestCaseSource(nameof(RoundtripOptions))] |
| 228 | + public async Task CanCallFunctionAndRoundtrip_Five(LocalValue local, RemoteValue returned, string javaScriptAssert) |
| 229 | + { |
| 230 | + var response = await context.Script.CallFunctionAsync($$""" |
| 231 | + (arg) => { |
| 232 | + if ({{javaScriptAssert}}) { |
| 233 | + return arg; |
| 234 | + } |
| 235 | +
|
| 236 | + throw new Error("Assert failed: " + arg); |
| 237 | + } |
| 238 | + """, false, new() { Arguments = [local] }); |
| 239 | + |
| 240 | + if (response.Result is RemoteValue.Array arrayResponse && returned is RemoteValue.Array expectedArray) |
| 241 | + { |
| 242 | + Assert.That(arrayResponse.Value, Is.EqualTo(expectedArray.Value)); |
| 243 | + } |
| 244 | + else if (response.Result is RemoteValue.Object objectResponse && returned is RemoteValue.Object expectedObject) |
| 245 | + { |
| 246 | + Assert.That(objectResponse.Value, Is.EqualTo(expectedObject.Value)); |
| 247 | + } |
| 248 | + else if (response.Result is RemoteValue.Map mapResponse && returned is RemoteValue.Map expectedMap) |
| 249 | + { |
| 250 | + Assert.That(mapResponse.Value, Is.EqualTo(expectedMap.Value)); |
| 251 | + } |
| 252 | + else if (response.Result is RemoteValue.Date dateResponse && returned is RemoteValue.Date expectedDate) |
| 253 | + { |
| 254 | + var actualDate = DateTime.SpecifyKind(DateTime.Parse(dateResponse.Value, CultureInfo.InvariantCulture), DateTimeKind.Utc); |
| 255 | + Assert.That(actualDate.Kind, Is.EqualTo(DateTimeKind.Utc)); |
| 256 | + Assert.That(actualDate, Is.EqualTo(DateTime.Parse(expectedDate.Value)).Within(TimeSpan.FromMilliseconds(1))); |
| 257 | + } |
| 258 | + else |
| 259 | + { |
| 260 | + Assert.That(response.Result, Is.EqualTo(returned)); |
| 261 | + } |
| 262 | + } |
| 263 | + private const string PinnedDateTimeString = "2025-03-09T00:30:33.083Z"; |
| 264 | + private static IEnumerable<TestCaseData> RoundtripOptions() |
| 265 | + { |
| 266 | + |
| 267 | + yield return new TestCaseData(new LocalValue.Null(), new RemoteValue.Null(), "arg === null") |
| 268 | + { |
| 269 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(Null)" |
| 270 | + }; |
| 271 | + yield return new TestCaseData(new LocalValue.Undefined(), new RemoteValue.Undefined(), "typeof arg === 'undefined'") |
| 272 | + { |
| 273 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(Undefined)", |
| 274 | + }; |
| 275 | + //yield return new TestCaseData(new LocalValue.Boolean(true), new RemoteValue.Boolean(true), "typeof arg === true") |
| 276 | + //{ |
| 277 | + // TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(true)", |
| 278 | + //}; |
| 279 | + //yield return new TestCaseData(new LocalValue.Boolean(false), new RemoteValue.Boolean(false), "typeof arg === false") |
| 280 | + //{ |
| 281 | + // TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(false)", |
| 282 | + //}; |
| 283 | + yield return new TestCaseData(new LocalValue.String("whoa"), new RemoteValue.String("whoa"), "arg === 'whoa'") |
| 284 | + { |
| 285 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(String('whoa'))", |
| 286 | + }; |
| 287 | + yield return new TestCaseData(new LocalValue.String(string.Empty), new RemoteValue.String(string.Empty), "arg === ''") |
| 288 | + { |
| 289 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(String(''))", |
| 290 | + }; |
| 291 | + yield return new TestCaseData(new LocalValue.Date(PinnedDateTimeString), new RemoteValue.Date(PinnedDateTimeString), $"arg.toISOString() === '{PinnedDateTimeString}'") |
| 292 | + { |
| 293 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(Date)", |
| 294 | + }; |
| 295 | + yield return new TestCaseData(new LocalValue.Number(5), new RemoteValue.Number(5), "arg === 5") |
| 296 | + { |
| 297 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(Number(5))", |
| 298 | + }; |
| 299 | + yield return new TestCaseData(new LocalValue.Number(0), new RemoteValue.Number(0), "arg === 0") |
| 300 | + { |
| 301 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(Number(0))", |
| 302 | + }; |
| 303 | + yield return new TestCaseData(new LocalValue.Number(-5), new RemoteValue.Number(-5), "arg === -5") |
| 304 | + { |
| 305 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(Number(-5))", |
| 306 | + }; |
| 307 | + yield return new TestCaseData(new LocalValue.Number(double.PositiveInfinity), new RemoteValue.Number(double.PositiveInfinity), "arg === Number.POSITIVE_INFINITY") |
| 308 | + { |
| 309 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(Number(Infinity))", |
| 310 | + }; |
| 311 | + yield return new TestCaseData(new LocalValue.Number(double.NegativeInfinity), new RemoteValue.Number(double.NegativeInfinity), "arg === Number.NEGATIVE_INFINITY") |
| 312 | + { |
| 313 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(Number(-Infinity))", |
| 314 | + }; |
| 315 | + yield return new TestCaseData(new LocalValue.Number(double.NegativeZero), new RemoteValue.Number(double.NegativeZero), "arg === -0") |
| 316 | + { |
| 317 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(Number(-0))", |
| 318 | + }; |
| 319 | + yield return new TestCaseData( |
| 320 | + new LocalValue.RegExp(new LocalValue.RegExp.RegExpValue("foo*") { Flags = "g" }), |
| 321 | + new RemoteValue.RegExp(new RemoteValue.RegExp.RegExpValue("foo*") { Flags = "g" }), |
| 322 | + "arg.test('foo') && arg.source === 'foo*' && arg.global" |
| 323 | + ) |
| 324 | + { |
| 325 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(RegExp(/foo/g))", |
| 326 | + }; |
| 327 | + yield return new TestCaseData( |
| 328 | + |
| 329 | + new LocalValue.Array([new LocalValue.String("hi")]), |
| 330 | + new RemoteValue.Array { Value = [new RemoteValue.String("hi")] }, |
| 331 | + "arg.length === 1 && arg[0] === 'hi'" |
| 332 | + ) |
| 333 | + { |
| 334 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(Array(['hi']))", |
| 335 | + }; |
| 336 | + yield return new TestCaseData |
| 337 | + ( |
| 338 | + new LocalValue.Object([[new LocalValue.String("key"), new LocalValue.String("value")]]), |
| 339 | + new RemoteValue.Object |
| 340 | + { |
| 341 | + Value = [[new RemoteValue.String("key"), new RemoteValue.String("value")]] |
| 342 | + }, |
| 343 | + "arg.key === 'value' && Object.keys(arg).length === 1" |
| 344 | + ) |
| 345 | + { |
| 346 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(Object({key: 'value'}))", |
| 347 | + }; |
| 348 | + yield return new TestCaseData |
| 349 | + ( |
| 350 | + new LocalValue.Map([[new LocalValue.String("key"), new LocalValue.String("value")]]), |
| 351 | + new RemoteValue.Map |
| 352 | + { |
| 353 | + Value = [[new RemoteValue.String("key"), new RemoteValue.String("value")]] |
| 354 | + }, |
| 355 | + "arg.get('key') === 'value' && arg.size === 1" |
| 356 | + ) |
| 357 | + { |
| 358 | + TestName = nameof(CanCallFunctionAndRoundtrip_Five) + "(Map({'key': 'value'}))", |
| 359 | + }; |
| 360 | + } |
222 | 361 | } |
0 commit comments