Beispiel #1
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #5
0
        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);
        }
Beispiel #11
0
        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);
            });
        }
Beispiel #12
0
        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);
        }