6
6
using System . Dynamic ;
7
7
using System . Globalization ;
8
8
using System . Threading . Tasks ;
9
+ using CefSharp . Example ;
9
10
using Xunit ;
10
11
using Xunit . Abstractions ;
11
12
@@ -23,6 +24,74 @@ public JavascriptCallbackTests(ITestOutputHelper output, CefSharpFixture collect
23
24
this . collectionFixture = collectionFixture ;
24
25
}
25
26
27
+ [ Fact ]
28
+ public async Task ShouldCancelAfterV8ContextChange ( )
29
+ {
30
+ IJavascriptCallback callbackExecuteCancelAfterDisposeCallback ;
31
+ Task callbackExecuteCancelAfterDisposeTask ;
32
+ using ( var browser = new CefSharp . OffScreen . ChromiumWebBrowser ( automaticallyCreateBrowser : false ) )
33
+ {
34
+ await browser . CreateBrowserAsync ( ) ;
35
+
36
+ // no V8 context
37
+ var withoutV8ContextException = await Assert . ThrowsAsync < Exception > ( ( ) => browser . EvaluateScriptAsync ( "(function() { return 1+1; })" ) ) ;
38
+ Assert . StartsWith ( "Unable to execute javascript at this time" , withoutV8ContextException . Message ) ;
39
+
40
+ Task < JavascriptResponse > callbackExecuteWithoutV8ContextTask ;
41
+ using ( var frame = browser . GetMainFrame ( ) )
42
+ {
43
+ callbackExecuteWithoutV8ContextTask = frame . EvaluateScriptAsync ( "(function() { return 1+2; })" ) ;
44
+ }
45
+
46
+ // V8 context
47
+ await browser . LoadUrlAsync ( CefExample . HelloWorldUrl ) ;
48
+
49
+ var callbackExecuteWithoutV8ContextResponse = await callbackExecuteWithoutV8ContextTask ;
50
+ Assert . True ( callbackExecuteWithoutV8ContextResponse . Success ) ;
51
+ var callbackExecuteWithoutV8ContextCallback = ( IJavascriptCallback ) callbackExecuteWithoutV8ContextResponse . Result ;
52
+ var callbackExecuteWithoutV8ContextExecuteResponse = await callbackExecuteWithoutV8ContextCallback . ExecuteAsync ( ) ;
53
+ Assert . True ( callbackExecuteWithoutV8ContextExecuteResponse . Success ) ;
54
+ Assert . Equal ( 3 , callbackExecuteWithoutV8ContextExecuteResponse . Result ) ;
55
+
56
+ var callbackExecuteCancelAfterV8ContextResponse = await browser . EvaluateScriptAsync ( "(function() { return new Promise(resolve => setTimeout(resolve, 1000)); })" ) ;
57
+ Assert . True ( callbackExecuteCancelAfterV8ContextResponse . Success ) ;
58
+ var callbackExecuteCancelAfterV8ContextCallback = ( IJavascriptCallback ) callbackExecuteCancelAfterV8ContextResponse . Result ;
59
+ var callbackExecuteCancelAfterV8ContextTask = callbackExecuteCancelAfterV8ContextCallback . ExecuteAsync ( ) ;
60
+
61
+ // change V8 context
62
+ await browser . LoadUrlAsync ( CefExample . HelloWorldUrl ) ;
63
+
64
+ await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => callbackExecuteCancelAfterV8ContextTask ) ;
65
+ var callbackExecuteCancelAfterV8ContextResult = await callbackExecuteCancelAfterV8ContextCallback . ExecuteAsync ( ) ;
66
+ Assert . False ( callbackExecuteCancelAfterV8ContextResult . Success ) ;
67
+ Assert . StartsWith ( "Unable to find JavascriptCallback with Id " + callbackExecuteCancelAfterV8ContextCallback . Id , callbackExecuteCancelAfterV8ContextResult . Message ) ;
68
+
69
+ var callbackExecuteCancelAfterDisposeResponse = await browser . EvaluateScriptAsync ( "(function() { return new Promise(resolve => setTimeout(resolve, 1000)); })" ) ;
70
+ Assert . True ( callbackExecuteCancelAfterDisposeResponse . Success ) ;
71
+ callbackExecuteCancelAfterDisposeCallback = ( IJavascriptCallback ) callbackExecuteCancelAfterDisposeResponse . Result ;
72
+ callbackExecuteCancelAfterDisposeTask = callbackExecuteCancelAfterDisposeCallback . ExecuteAsync ( ) ;
73
+ }
74
+ Assert . False ( callbackExecuteCancelAfterDisposeCallback . CanExecute ) ;
75
+ await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => callbackExecuteCancelAfterDisposeTask ) ;
76
+ await Assert . ThrowsAsync < InvalidOperationException > ( ( ) => callbackExecuteCancelAfterDisposeCallback . ExecuteAsync ( ) ) ;
77
+ }
78
+
79
+ [ Fact ]
80
+ public async Task ShouldCancelOnCrash ( )
81
+ {
82
+ AssertInitialLoadComplete ( ) ;
83
+
84
+ var javascriptResponse = await Browser . EvaluateScriptAsync ( "(function() { return new Promise(resolve => setTimeout(resolve, 1000)); })" ) ;
85
+ Assert . True ( javascriptResponse . Success ) ;
86
+
87
+ var callback = ( IJavascriptCallback ) javascriptResponse . Result ;
88
+
89
+ var task = callback . ExecuteAsync ( ) ;
90
+
91
+ await Browser . LoadUrlAsync ( "chrome://crash" ) ;
92
+ await Assert . ThrowsAsync < TaskCanceledException > ( ( ) => task ) ;
93
+ }
94
+
26
95
[ Theory ]
27
96
[ InlineData ( "(function() { return Promise.resolve(53)})" , 53 ) ]
28
97
[ InlineData ( "(function() { return Promise.resolve('53')})" , "53" ) ]
@@ -233,5 +302,23 @@ public async Task ShouldWorkWithExpandoObject()
233
302
234
303
output . WriteLine ( "Expected {0} : Actual {1}" , expectedDateTime , actualDateTime ) ;
235
304
}
305
+
306
+ [ Fact ]
307
+ public async Task ShouldWorkWhenExecutedMultipleTimes ( )
308
+ {
309
+ AssertInitialLoadComplete ( ) ;
310
+
311
+ var javascriptResponse = await Browser . EvaluateScriptAsync ( "(function() { return 42; })" ) ;
312
+ Assert . True ( javascriptResponse . Success ) ;
313
+
314
+ var callback = ( IJavascriptCallback ) javascriptResponse . Result ;
315
+
316
+ for ( var i = 0 ; i < 3 ; i ++ )
317
+ {
318
+ var callbackResponse = await callback . ExecuteAsync ( ) ;
319
+ Assert . True ( callbackResponse . Success ) ;
320
+ Assert . Equal ( 42 , callbackResponse . Result ) ;
321
+ }
322
+ }
236
323
}
237
324
}
0 commit comments