1+ using Microsoft . AspNetCore . Http ;
2+ using System ;
3+ using System . Collections . Generic ;
4+ using System . Net ;
5+ using System . Threading . Tasks ;
6+ using Xunit ;
7+
8+ namespace PuppeteerSharp . Tests . Page
9+ {
10+ [ Collection ( "PuppeteerLoaderFixture collection" ) ]
11+ public class GotoTests : PuppeteerPageBaseTest
12+ {
13+ [ Fact ]
14+ public async Task ShouldNavigateToAboutBlank ( )
15+ {
16+ var response = await Page . GoToAsync ( TestConstants . AboutBlank ) ;
17+ Assert . Null ( response ) ;
18+ }
19+
20+ [ Theory ]
21+ [ InlineData ( WaitUntilNavigation . DOMContentLoaded ) ]
22+ [ InlineData ( WaitUntilNavigation . Networkidle0 ) ]
23+ [ InlineData ( WaitUntilNavigation . Networkidle2 ) ]
24+ public async Task ShouldNavigateToEmptyPage ( WaitUntilNavigation waitUntil )
25+ {
26+ var response = await Page . GoToAsync ( TestConstants . EmptyPage , new NavigationOptions { WaitUntil = new [ ] { waitUntil } } ) ;
27+ Assert . Equal ( HttpStatusCode . OK , response . Status ) ;
28+ }
29+
30+ [ Fact ]
31+ public async Task ShouldFailWhenNavigatingToBadUrl ( )
32+ {
33+ var exception = await Assert . ThrowsAnyAsync < Exception > ( async ( ) => await Page . GoToAsync ( "asdfasdf" ) ) ;
34+ Assert . Contains ( "Cannot navigate to invalid URL" , exception . Message ) ;
35+ }
36+
37+ [ Fact ( Skip = "message is ERR_CERT_COMMON_NAME_INVALID instead of ERR_CERT_AUTHORITY_INVALID" ) ]
38+ public async Task ShouldFailWhenNavigatingToBadSSL ( )
39+ {
40+ Page . RequestCreated += ( sender , e ) => Assert . NotNull ( e . Request ) ;
41+ Page . RequestFinished += ( sender , e ) => Assert . NotNull ( e . Request ) ;
42+ Page . RequestFailed += ( sender , e ) => Assert . NotNull ( e . Request ) ;
43+
44+ var exception = await Assert . ThrowsAnyAsync < Exception > ( async ( ) => await Page . GoToAsync ( TestConstants . HttpsPrefix + "/empty.html" ) ) ;
45+ Assert . Contains ( "net::ERR_CERT_AUTHORITY_INVALID" , exception . Message ) ;
46+ }
47+
48+ [ Fact ( Skip = "message is ERR_CERT_COMMON_NAME_INVALID instead of ERR_CERT_AUTHORITY_INVALID" ) ]
49+ public async Task ShouldFailWhenNavigatingToBadSSLAfterRedirects ( )
50+ {
51+ var exception = await Assert . ThrowsAnyAsync < Exception > ( async ( ) => await Page . GoToAsync ( TestConstants . HttpsPrefix + "/redirect/2.html" ) ) ;
52+ Assert . Contains ( "net::ERR_CERT_AUTHORITY_INVALID" , exception . Message ) ;
53+ }
54+
55+ [ Fact ]
56+ public async Task ShouldFailWhenMainResourcesFailedToLoad ( )
57+ {
58+ var exception = await Assert . ThrowsAnyAsync < Exception > ( async ( ) => await Page . GoToAsync ( "http://localhost:44123/non-existing-url" ) ) ;
59+ Assert . Contains ( "net::ERR_CONNECTION_REFUSED" , exception . Message ) ;
60+ }
61+
62+ [ Fact ]
63+ public async Task ShouldFailWhenExceedingMaximumNavigationTimeout ( )
64+ {
65+ Server . SetRoute ( "/empty.html" , context => Task . Delay ( - 1 ) ) ;
66+
67+ var exception = await Assert . ThrowsAnyAsync < Exception > ( async ( )
68+ => await Page . GoToAsync ( TestConstants . EmptyPage , new NavigationOptions { Timeout = 1 } ) ) ;
69+ Assert . Contains ( "Navigation Timeout Exceeded: 1ms" , exception . Message ) ;
70+ }
71+
72+ [ Fact ]
73+ public async Task ShouldFailWhenExceedingDefaultMaximumNavigationTimeout ( )
74+ {
75+ Server . SetRoute ( "/empty.html" , context => Task . Delay ( - 1 ) ) ;
76+
77+ Page . DefaultNavigationTimeout = 1 ;
78+ var exception = await Assert . ThrowsAnyAsync < Exception > ( async ( ) => await Page . GoToAsync ( TestConstants . EmptyPage ) ) ;
79+ Assert . Contains ( "Navigation Timeout Exceeded: 1ms" , exception . Message ) ;
80+ }
81+
82+ [ Fact ]
83+ public async Task ShouldDisableTimeoutWhenItsSetTo0 ( )
84+ {
85+ var loaded = false ;
86+ void OnLoad ( object sender , EventArgs e )
87+ {
88+ loaded = true ;
89+ Page . Load -= OnLoad ;
90+ }
91+ Page . Load += OnLoad ;
92+
93+ await Page . GoToAsync ( TestConstants . ServerUrl + "/grid.html" , new NavigationOptions { Timeout = 0 , WaitUntil = new [ ] { WaitUntilNavigation . Load } } ) ;
94+ Assert . True ( loaded ) ;
95+ }
96+
97+ [ Fact ]
98+ public async Task ShouldWorkWhenNavigatingToValidUrl ( )
99+ {
100+ var response = await Page . GoToAsync ( TestConstants . EmptyPage ) ;
101+ Assert . Equal ( HttpStatusCode . OK , response . Status ) ;
102+ }
103+
104+ [ Fact ]
105+ public async Task ShouldWorkWhenNavigatingToDataUrl ( )
106+ {
107+ var response = await Page . GoToAsync ( "data:text/html,hello" ) ;
108+ Assert . Equal ( HttpStatusCode . OK , response . Status ) ;
109+ }
110+
111+ [ Fact ]
112+ public async Task ShouldWorkWhenNavigatingTo404 ( )
113+ {
114+ var response = await Page . GoToAsync ( TestConstants . ServerUrl + "/not-found" ) ;
115+ Assert . Equal ( HttpStatusCode . NotFound , response . Status ) ;
116+ }
117+
118+ [ Fact ]
119+ public async Task ShouldReturnLastResponseInRedirectChain ( )
120+ {
121+ Server . SetRedirect ( "/redirect/1.html" , "/redirect/2.html" ) ;
122+ Server . SetRedirect ( "/redirect/2.html" , "/redirect/3.html" ) ;
123+ Server . SetRedirect ( "/redirect/3.html" , TestConstants . EmptyPage ) ;
124+
125+ var response = await Page . GoToAsync ( TestConstants . ServerUrl + "/redirect/1.html" ) ;
126+ Assert . Equal ( HttpStatusCode . OK , response . Status ) ;
127+ Assert . Equal ( TestConstants . EmptyPage , response . Url ) ;
128+ }
129+
130+ [ Fact ]
131+ public async Task ShouldWaitForNetworkIdleToSucceedNavigation ( )
132+ {
133+ var responses = new List < TaskCompletionSource < Func < HttpResponse , Task > > > ( ) ;
134+ var fetches = new Dictionary < string , TaskCompletionSource < bool > > ( ) ;
135+ foreach ( var url in new [ ] {
136+ "/fetch-request-a.js" ,
137+ "/fetch-request-b.js" ,
138+ "/fetch-request-c.js" ,
139+ "/fetch-request-d.js" } )
140+ {
141+ fetches [ url ] = new TaskCompletionSource < bool > ( ) ;
142+ Server . SetRoute ( url , async context =>
143+ {
144+ var taskCompletion = new TaskCompletionSource < Func < HttpResponse , Task > > ( ) ;
145+ responses . Add ( taskCompletion ) ;
146+ fetches [ context . Request . Path ] . SetResult ( true ) ;
147+ var actionResponse = await taskCompletion . Task ;
148+ await actionResponse ( context . Response ) ;
149+ } ) ;
150+ }
151+
152+ var initialFetchResourcesRequested = Task . WhenAll (
153+ Server . WaitForRequest ( "/fetch-request-a.js" ) ,
154+ Server . WaitForRequest ( "/fetch-request-b.js" ) ,
155+ Server . WaitForRequest ( "/fetch-request-c.js" )
156+ ) ;
157+ var secondFetchResourceRequested = Server . WaitForRequest ( "/fetch-request-d.js" ) ;
158+
159+ var navigationFinished = false ;
160+ var navigationTask = Page . GoToAsync ( TestConstants . ServerUrl + "/networkidle.html" ,
161+ new NavigationOptions { WaitUntil = new [ ] { WaitUntilNavigation . Networkidle0 } } )
162+ . ContinueWith ( res =>
163+ {
164+ navigationFinished = true ;
165+ return res . Result ;
166+ } ) ;
167+
168+ var pageLoaded = new TaskCompletionSource < bool > ( ) ;
169+ void WaitPageLoad ( object sender , EventArgs e )
170+ {
171+ pageLoaded . SetResult ( true ) ;
172+ Page . Load -= WaitPageLoad ;
173+ }
174+ Page . Load += WaitPageLoad ;
175+ await pageLoaded . Task ;
176+
177+ Assert . False ( navigationFinished ) ;
178+
179+ await initialFetchResourcesRequested ;
180+
181+ Assert . False ( navigationFinished ) ;
182+
183+ await Task . WhenAll (
184+ fetches [ "/fetch-request-a.js" ] . Task ,
185+ fetches [ "/fetch-request-b.js" ] . Task ,
186+ fetches [ "/fetch-request-c.js" ] . Task ) ;
187+
188+ foreach ( var actionResponse in responses )
189+ {
190+ actionResponse . SetResult ( response =>
191+ {
192+ response . StatusCode = 404 ;
193+ return response . WriteAsync ( "File not found" ) ;
194+ } ) ;
195+ }
196+
197+ responses . Clear ( ) ;
198+
199+ await secondFetchResourceRequested ;
200+
201+ Assert . False ( navigationFinished ) ;
202+
203+ await fetches [ "/fetch-request-d.js" ] . Task ;
204+
205+ foreach ( var actionResponse in responses )
206+ {
207+ actionResponse . SetResult ( response =>
208+ {
209+ response . StatusCode = 404 ;
210+ return response . WriteAsync ( "File not found" ) ;
211+ } ) ;
212+ }
213+
214+ var navigationResponse = await navigationTask ;
215+ Assert . Equal ( HttpStatusCode . OK , navigationResponse . Status ) ;
216+ }
217+
218+ [ Fact ]
219+ public async Task ShouldNavigateToDataURLAndFireDataURLRequests ( )
220+ {
221+ var requests = new List < Request > ( ) ;
222+ Page . RequestCreated += ( sender , e ) => requests . Add ( e . Request ) ;
223+ var dataUrl = "data:text/html,<div>yo</div>" ;
224+ var response = await Page . GoToAsync ( dataUrl ) ;
225+ Assert . Equal ( HttpStatusCode . OK , response . Status ) ;
226+ Assert . Single ( requests ) ;
227+ Assert . Equal ( dataUrl , requests [ 0 ] . Url ) ;
228+ }
229+
230+ [ Fact ]
231+ public async Task ShouldNavigateToURLWithHashAndFireRequestsWithoutHash ( )
232+ {
233+ var requests = new List < Request > ( ) ;
234+ Page . RequestCreated += ( sender , e ) => requests . Add ( e . Request ) ;
235+ var response = await Page . GoToAsync ( TestConstants . EmptyPage + "#hash" ) ;
236+ Assert . Equal ( HttpStatusCode . OK , response . Status ) ;
237+ Assert . Equal ( TestConstants . EmptyPage , response . Url ) ;
238+ Assert . Single ( requests ) ;
239+ Assert . Equal ( TestConstants . EmptyPage , requests [ 0 ] . Url ) ;
240+ }
241+ }
242+ }
0 commit comments