public async Task WebViewDisposeDoesNotBlockWhenHasPendingJSCalls() { await Run(async() => { const string DotNetObject = "DotNetObject"; var taskCompletionSourceFunction = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); var taskCompletionSourceDispose = new TaskCompletionSource <bool>(TaskCreationOptions.RunContinuationsAsynchronously); Func <int> functionToCall = () => { TargetView.Dispose(); var disposeRan = taskCompletionSourceDispose.Task.IsCompleted; taskCompletionSourceFunction.SetResult(disposeRan); return(1); }; TargetView.RegisterJavascriptObject(DotNetObject, functionToCall); await Load($"<html><script>function test() {{ {DotNetObject}.invoke(); while(true); return 1; }}</script><body></body></html>"); TargetView.Disposed += () => taskCompletionSourceDispose.SetResult(true); var result = await TargetView.EvaluateScriptFunction <int>("test"); Assert.AreEqual(0, result, "Script evaluation should be cancelled and default value returned"); var disposed = await taskCompletionSourceFunction.Task; Assert.IsFalse(disposed, "Dispose should have been scheduled"); disposed = await taskCompletionSourceDispose.Task; Assert.IsTrue(disposed); }); }
public void WebViewDisposeDoesNotBlockWhenHasPendingJSCalls() { const string DotNetObject = "DotNetObject"; var functionCalled = false; var disposeCalled = false; Func <int> functionToCall = () => { functionCalled = true; TargetView.Dispose(); Assert.IsFalse(disposeCalled); // dispose should have been scheduled return(1); }; TargetView.RegisterJavascriptObject(DotNetObject, functionToCall, executeCallsInUI: true); LoadAndWaitReady($"<html><script>function test() {{ {DotNetObject}.invoke(); return 1; }}</script><body></body></html>"); TargetView.Disposed += () => disposeCalled = true; var result = TargetView.EvaluateScriptFunction <int>("test"); WaitFor(() => functionCalled, DefaultTimeout); WaitFor(() => disposeCalled, DefaultTimeout); Assert.IsTrue(disposeCalled); }
public async Task WebViewDisposeDoesNotBlockWhenHasPendingJSCalls() { await Run(async() => { const string DotNetObject = "DotNetObject"; var taskCompletionSourceFunction = new TaskCompletionSource <bool>(); var taskCompletionSourceDispose = new TaskCompletionSource <bool>(); Func <int> functionToCall = () => { TargetView.Dispose(); var disposeRan = taskCompletionSourceDispose.Task.IsCompleted; taskCompletionSourceFunction.SetResult(disposeRan); return(1); }; TargetView.RegisterJavascriptObject(DotNetObject, functionToCall, executeCallsInUI: true); await Load($"<html><script>function test() {{ {DotNetObject}.invoke(); return 1; }}</script><body></body></html>"); TargetView.Disposed += () => taskCompletionSourceDispose.SetResult(true); TargetView.EvaluateScriptFunction <int>("test"); var disposed = await taskCompletionSourceFunction.Task; Assert.IsFalse(disposed, "Dispose should have been scheduled"); disposed = await taskCompletionSourceDispose.Task; Assert.IsTrue(disposed); }); }
public void RegisteredJsObjectMethodExecutesInDispatcherThread() { const string DotNetObject = "DotNetObject"; bool? canAccessDispatcher = null; Func <int> functionToCall = () => { canAccessDispatcher = TargetView.Dispatcher.CheckAccess(); return(10); }; TargetView.RegisterJavascriptObject(DotNetObject, functionToCall, executeCallsInUI: true); LoadAndWaitReady($"<html><script>{DotNetObject}.invoke();</script><body></body></html>"); WaitFor(() => canAccessDispatcher != null, DefaultTimeout); Assert.IsTrue(canAccessDispatcher); }
public async Task RegisteredJsObjectMethodNullParamsSerialization() { await Run(async() => { const string DotNetObject = "DotNetObject"; var taskCompletionSource = new TaskCompletionSource <Tuple <string, string[]> >(); Action <string, string[]> functionToCall = (string arg1, string[] arg2) => { taskCompletionSource.SetResult(new Tuple <string, string[]>(arg1, arg2)); }; TargetView.RegisterJavascriptObject(DotNetObject, functionToCall); await Load($"<html><script>{DotNetObject}.invoke(null, ['hello', null, 'world']);</script><body></body></html>"); var obtainedArgs = await taskCompletionSource.Task; Assert.AreEqual(null, obtainedArgs.Item1); Assert.That(new[] { "hello", null, "world" }, Is.EquivalentTo(obtainedArgs.Item2)); }); }
public async Task RegisteredJsObjectMethodExecutesInDispatcherThread() { const string DotNetObject = "DotNetObject"; var taskCompletionSource = new TaskCompletionSource <bool>(); Func <int> functionToCall = () => { taskCompletionSource.SetResult(Dispatcher.UIThread.CheckAccess()); return(10); }; TargetView.RegisterJavascriptObject(DotNetObject, functionToCall, executeCallsInUI: true); await Load($"<html><script>{DotNetObject}.invoke();</script><body></body></html>"); var canAccessDispatcher = await taskCompletionSource.Task; Assert.IsTrue(canAccessDispatcher); }
public void RegisteredJsObjectMethodExecutesInDispatcherThreadWithoutBlocking() { const string DotNetObject = "DotNetObject"; bool functionCalled = false; Func <int> functionToCall = () => { TargetView.EvaluateScript <int>("1+1"); functionCalled = true; return(1); }; TargetView.RegisterJavascriptObject(DotNetObject, functionToCall, executeCallsInUI: true); LoadAndWaitReady("<html><script>function test() { DotNetObject.invoke(); return 1; }</script><body></body></html>"); var result = TargetView.EvaluateScriptFunction <int>("test"); WaitFor(() => functionCalled, DefaultTimeout); Assert.AreEqual(1, result); }
public async Task RegisteredJsObjectMethodExecutesInDispatcherThreadWithoutBlocking() { await Run(async() => { const string DotNetObject = "DotNetObject"; var taskCompletionSource = new TaskCompletionSource <bool>(); Func <int> functionToCall = () => { TargetView.EvaluateScript <int>("1+1"); taskCompletionSource.SetResult(true); return(1); }; TargetView.RegisterJavascriptObject(DotNetObject, functionToCall, executeCallsInUI: true); await Load("<html><script>function test() { DotNetObject.invoke(); return 1; }</script><body></body></html>"); var result = await TargetView.EvaluateScriptFunction <int>("test"); await taskCompletionSource.Task; Assert.AreEqual(1, result); }); }
public void RegisteredJsObjectMethodNullParamsSerialization() { const string DotNetObject = "DotNetObject"; var functionCalled = false; string obtainedArg1 = ""; string[] obtainedArg2 = null; Action <string, string[]> functionToCall = (string arg1, string[] arg2) => { functionCalled = true; obtainedArg1 = arg1; obtainedArg2 = arg2; }; TargetView.RegisterJavascriptObject(DotNetObject, functionToCall); LoadAndWaitReady($"<html><script>{DotNetObject}.invoke(null, ['hello', null, 'world']);</script><body></body></html>"); WaitFor(() => functionCalled, DefaultTimeout); Assert.IsTrue(functionCalled); Assert.AreEqual(null, obtainedArg1); Assert.That(new[] { "hello", null, "world" }, Is.EquivalentTo(obtainedArg2)); }
public void RegisteredJsObjectMethodInterception() { const string DotNetObject = "DotNetObject"; var functionCalled = false; var interceptorCalled = false; Func <int> functionToCall = () => { functionCalled = true; return(10); }; Func <Func <object>, object> interceptor = (originalFunc) => { interceptorCalled = true; return(originalFunc()); }; TargetView.RegisterJavascriptObject(DotNetObject, functionToCall, interceptor); LoadAndWaitReady($"<html><script>{DotNetObject}.invoke();</script><body></body></html>"); WaitFor(() => functionCalled, DefaultTimeout); Assert.IsTrue(functionCalled); Assert.IsTrue(interceptorCalled); }
public async Task RegisteredJsObjectReturnObjectSerialization() { await Run(async() => { const string DotNetObject = "DotNetObject"; const string DotNetSetResult = "DotNetSetResult"; var testObject = new TestObject() { Age = 33, Kind = Kind.B, Name = "John", Parent = new TestObject() { Name = "John Parent", Age = 66, Kind = Kind.C } }; var taskCompletionSource = new TaskCompletionSource <TestObject>(); Func <TestObject> functionToCall = () => testObject; Action <TestObject> setResult = (r) => { taskCompletionSource.SetResult(r); }; TargetView.RegisterJavascriptObject(DotNetObject, functionToCall); TargetView.RegisterJavascriptObject(DotNetSetResult, setResult); await Load($"<html><script>(async function test() {{ var result = await {DotNetObject}.invoke(); {DotNetSetResult}.invoke(result); }})()</script><body></body></html>"); var result = await taskCompletionSource.Task; Assert.IsNotNull(result); Assert.AreEqual(testObject.Name, result.Name); Assert.AreEqual(testObject.Age, result.Age); Assert.AreEqual(testObject.Kind, result.Kind); Assert.IsNotNull(result.Parent); Assert.AreEqual(testObject.Parent.Name, result.Parent.Name); Assert.AreEqual(testObject.Parent.Age, result.Parent.Age); Assert.AreEqual(testObject.Parent.Kind, result.Parent.Kind); }); }
public async Task RegisteredJsObjectMethodInterception() { await Run(async() => { const string DotNetObject = "DotNetObject"; var interceptorCalled = false; var taskCompletionSource = new TaskCompletionSource <bool>(); Func <int> functionToCall = () => { taskCompletionSource.SetResult(true); return(10); }; object Interceptor(Func <object> originalFunc) { interceptorCalled = true; return(originalFunc()); } TargetView.RegisterJavascriptObject(DotNetObject, functionToCall, Interceptor); await Load($"<html><script>{DotNetObject}.invoke();</script><body></body></html>"); var functionCalled = await taskCompletionSource.Task; Assert.IsTrue(functionCalled); Assert.IsTrue(interceptorCalled); }); }
public void RegisteredJsObjectReturnObjectSerialization() { const string DotNetObject = "DotNetObject"; const string DotNetSetResult = "DotNetSetResult"; TestObject result = null; var testObject = new TestObject() { Age = 33, Kind = Kind.B, Name = "John", Parent = new TestObject() { Name = "John Parent", Age = 66, Kind = Kind.C } }; Func <TestObject> functionToCall = () => testObject; Action <TestObject> setResult = (r) => result = r; TargetView.RegisterJavascriptObject(DotNetObject, functionToCall); TargetView.RegisterJavascriptObject(DotNetSetResult, setResult); LoadAndWaitReady($"<html><script>(async function test() {{ var result = await {DotNetObject}.invoke(); {DotNetSetResult}.invoke(result); }})()</script><body></body></html>"); WaitFor(() => result != null, DefaultTimeout); Assert.IsNotNull(result); Assert.AreEqual(testObject.Name, result.Name); Assert.AreEqual(testObject.Age, result.Age); Assert.AreEqual(testObject.Kind, result.Kind); Assert.IsNotNull(result.Parent); Assert.AreEqual(testObject.Parent.Name, result.Parent.Name); Assert.AreEqual(testObject.Parent.Age, result.Parent.Age); Assert.AreEqual(testObject.Parent.Kind, result.Parent.Kind); }