@@ -15,6 +15,9 @@ const normalize = (str: string) =>
1515 } ) . replaceAll ( / ^ A u t h o r : .* $ / gm, "Author: [email protected] " ) ; 1616
1717describe ( "deployments" , { timeout : TIMEOUT } , ( ) => {
18+ // Note that we are sharing the workerName and helper across all these tests,
19+ // which means that these tests are not isolated from each other.
20+ // Seeded files will leak between tests.
1821 const workerName = generateResourceName ( ) ;
1922 const helper = new WranglerE2ETestHelper ( ) ;
2023 let deployedUrl : string ;
@@ -198,6 +201,7 @@ type AssetTestCase = {
198201 content ?: string ;
199202 redirect ?: string ;
200203} ;
204+
201205function generateInitialAssets ( workerName : string ) {
202206 return {
203207 "public/index.html" : dedent `
@@ -215,7 +219,7 @@ function generateInitialAssets(workerName: string) {
215219 } ;
216220}
217221
218- const checkAssets = async ( testCases : AssetTestCase [ ] , deployedUrl : string ) => {
222+ async function checkAssets ( testCases : AssetTestCase [ ] , deployedUrl : string ) {
219223 for ( const testCase of testCases ) {
220224 await vi . waitFor (
221225 async ( ) => {
@@ -224,35 +228,43 @@ const checkAssets = async (testCases: AssetTestCase[], deployedUrl: string) => {
224228 const url = r . url ;
225229
226230 if ( testCase . content ) {
227- expect ( text ) . toContain ( testCase . content ) ;
231+ expect (
232+ text ,
233+ `expected content for ${ testCase . path } to be ${ testCase . content } `
234+ ) . toContain ( testCase . content ) ;
228235 }
229236 if ( testCase . redirect ) {
230- expect ( new URL ( url ) . pathname ) . toEqual (
231- new URL ( testCase . redirect , deployedUrl ) . pathname
232- ) ;
237+ expect (
238+ new URL ( url ) . pathname ,
239+ `expected redirect for ${ testCase . path } to be ${ testCase . redirect } `
240+ ) . toEqual ( new URL ( testCase . redirect , deployedUrl ) . pathname ) ;
233241 } else {
234- expect ( new URL ( url ) . pathname ) . toEqual (
235- new URL ( testCase . path , deployedUrl ) . pathname
236- ) ;
242+ expect (
243+ new URL ( url ) . pathname ,
244+ `unexpected pathname for ${ testCase . path } `
245+ ) . toEqual ( new URL ( testCase . path , deployedUrl ) . pathname ) ;
237246 }
238247 } ,
239- { interval : 1_000 , timeout : 40_000 }
248+ {
249+ interval : 1_000 ,
250+ timeout : 40_000 ,
251+ }
240252 ) ;
241253 }
242- } ;
254+ }
243255
244256describe ( "Workers + Assets deployment" , ( ) => {
245- const helper = new WranglerE2ETestHelper ( ) ;
246- let deployedUrl : string | undefined ;
257+ let helper : WranglerE2ETestHelper ;
258+ let workerName : string ;
259+
260+ beforeEach ( ( ) => {
261+ // We are recreating the helper on each test to ensure they are isolated from each other.
262+ helper = new WranglerE2ETestHelper ( ) ;
263+ // Use a new user Worker in each test
264+ workerName = generateResourceName ( ) ;
265+ } ) ;
247266
248267 describe ( "Workers" , ( ) => {
249- let workerName : string ;
250-
251- beforeEach ( ( ) => {
252- // deploy a new user Worker in each test
253- workerName = generateResourceName ( ) ;
254- } ) ;
255-
256268 afterEach ( async ( ) => {
257269 // clean up user Worker after each test
258270 await helper . run ( `wrangler delete` ) ;
@@ -294,7 +306,7 @@ Current Version ID: 00000000-0000-0000-0000-000000000000`);
294306 / (?< url > h t t p s : \/ \/ t m p - e 2 e - .+ ?\. .+ ?\. w o r k e r s \. d e v ) /
295307 ) ;
296308 assert ( match ?. groups ) ;
297- deployedUrl = match . groups . url ;
309+ const deployedUrl = match . groups . url ;
298310
299311 const testCases : AssetTestCase [ ] = [
300312 // Tests html_handling = "auto_trailing_slash" (default):
@@ -384,7 +396,7 @@ Current Version ID: 00000000-0000-0000-0000-000000000000`);
384396 / (?< url > h t t p s : \/ \/ t m p - e 2 e - .+ ?\. .+ ?\. w o r k e r s \. d e v ) /
385397 ) ;
386398 assert ( match ?. groups ) ;
387- deployedUrl = match . groups . url ;
399+ const deployedUrl = match . groups . url ;
388400
389401 const testCases : AssetTestCase [ ] = [
390402 // because html handling has now been set to "none", only exact matches will be served
@@ -466,7 +478,7 @@ Current Version ID: 00000000-0000-0000-0000-000000000000`);
466478 / (?< url > h t t p s : \/ \/ t m p - e 2 e - .+ ?\. .+ ?\. w o r k e r s \. d e v ) /
467479 ) ;
468480 assert ( match ?. groups ) ;
469- deployedUrl = match . groups . url ;
481+ const deployedUrl = match . groups . url ;
470482
471483 const testCases : AssetTestCase [ ] = [
472484 // Tests html_handling = "auto_trailing_slash" (default):
@@ -551,7 +563,7 @@ Current Version ID: 00000000-0000-0000-0000-000000000000`);
551563 / (?< url > h t t p s : \/ \/ t m p - e 2 e - .+ ?\. .+ ?\. w o r k e r s \. d e v ) /
552564 ) ;
553565 assert ( match ?. groups ) ;
554- deployedUrl = match . groups . url ;
566+ const deployedUrl = match . groups . url ;
555567
556568 const testCases : AssetTestCase [ ] = [
557569 {
@@ -569,17 +581,82 @@ Current Version ID: 00000000-0000-0000-0000-000000000000`);
569581 ] ;
570582 await checkAssets ( testCases , deployedUrl ) ;
571583 } ) ;
584+
585+ it ( "runs the user Worker ahead of matching assets for matching run_worker_first routes" , async ( ) => {
586+ await helper . seed ( {
587+ "wrangler.toml" : dedent `
588+ name = "${ workerName } "
589+ main = "src/index.ts"
590+ compatibility_date = "2023-01-01"
591+ [assets]
592+ directory = "public"
593+ binding = "ASSETS"
594+ html_handling = "none"
595+ not_found_handling = "404-page"
596+ run_worker_first = ["/api/*", "!/api/assets/*"]
597+ ` ,
598+ "src/index.ts" : dedent `
599+ export default {
600+ async fetch(request, env) {
601+ return new Response("Hello World from User Worker!")
602+ }
603+ }` ,
604+ ...generateInitialAssets ( workerName ) ,
605+ "public/api/index.html" : "<h1>api/index.html</h1>" ,
606+ "public/api/assets/test.html" : "<h1>api/assets/test.html</h1>" ,
607+ } ) ;
608+
609+ // deploy user Worker && verify output
610+ const output = await helper . run ( `wrangler deploy` ) ;
611+ const normalizedStdout = normalize ( output . stdout ) ;
612+
613+ expect ( normalizedStdout ) . toContain ( dedent `
614+ 🌀 Building list of assets...
615+ ✨ Read 7 files from the assets directory /tmpdir
616+ 🌀 Starting asset upload...
617+ 🌀 Found 5 new or modified static assets to upload. Proceeding with upload...
618+ + /404.html
619+ + /api/index.html
620+ + /index.html
621+ + /api/assets/test.html
622+ + /[boop].html
623+ ` ) ;
624+ expect ( normalizedStdout ) . toContain ( dedent `
625+ ✨ Success! Uploaded 5 files (TIMINGS)
626+ Total Upload: xx KiB / gzip: xx KiB
627+ Your Worker has access to the following bindings:
628+ Binding Resource
629+ env.ASSETS Assets
630+ Uploaded tmp-e2e-worker-00000000-0000-0000-0000-000000000000 (TIMINGS)
631+ Deployed tmp-e2e-worker-00000000-0000-0000-0000-000000000000 triggers (TIMINGS)
632+ https://tmp-e2e-worker-00000000-0000-0000-0000-000000000000.SUBDOMAIN.workers.dev
633+ Current Version ID: 00000000-0000-0000-0000-000000000000
634+ ` ) ;
635+
636+ const match = output . stdout . match (
637+ / (?< url > h t t p s : \/ \/ t m p - e 2 e - .+ ?\. .+ ?\. w o r k e r s \. d e v ) /
638+ ) ;
639+ assert ( match ?. groups ) ;
640+ const deployedUrl = match . groups . url ;
641+
642+ const testCases : AssetTestCase [ ] = [
643+ { path : "/index.html" , content : "<h1>index.html</h1>" } ,
644+ { path : "/missing.html" , content : "<h1>404.html</h1>" } ,
645+ { path : "/api/" , content : "Hello World from User Worker!" } ,
646+ { path : "/api/foo.html" , content : "Hello World from User Worker!" } ,
647+ { path : "/api/assets/missing" , content : "404.html" } ,
648+ { path : "/api/assets/test.html" , content : "api/assets/test.html" } ,
649+ ] ;
650+
651+ await checkAssets ( testCases , deployedUrl ) ;
652+ } ) ;
572653 } ) ;
573654
574655 describe ( "Workers for Platforms" , ( ) => {
575656 let dispatchNamespaceName : string ;
576657 let dispatchWorkerName : string ;
577- let workerName : string ;
578658
579659 beforeEach ( async ( ) => {
580- // deploy a new user Worker in each test
581- workerName = generateResourceName ( ) ;
582-
583660 // set up a new dispatch Worker in each test
584661 dispatchNamespaceName = generateResourceName ( "dispatch" ) ;
585662 dispatchWorkerName = generateResourceName ( ) ;
@@ -672,7 +749,7 @@ Current Version ID: 00000000-0000-0000-0000-000000000000`);
672749 / (?< url > h t t p s : \/ \/ t m p - e 2 e - .+ ?\. .+ ?\. w o r k e r s \. d e v ) /
673750 ) ;
674751 assert ( match ?. groups ) ;
675- deployedUrl = match . groups . url ;
752+ const deployedUrl = match . groups . url ;
676753
677754 const testCases : AssetTestCase [ ] = [
678755 // Tests html_handling = "auto_trailing_slash" (default):
@@ -785,7 +862,7 @@ Current Version ID: 00000000-0000-0000-0000-000000000000`);
785862 / (?< url > h t t p s : \/ \/ t m p - e 2 e - .+ ?\. .+ ?\. w o r k e r s \. d e v ) /
786863 ) ;
787864 assert ( match ?. groups ) ;
788- deployedUrl = match . groups . url ;
865+ const deployedUrl = match . groups . url ;
789866
790867 const testCases : AssetTestCase [ ] = [
791868 // because html handling has now been set to "none", only exact matches will be served
@@ -896,7 +973,7 @@ Current Version ID: 00000000-0000-0000-0000-000000000000`);
896973 / (?< url > h t t p s : \/ \/ t m p - e 2 e - .+ ?\. .+ ?\. w o r k e r s \. d e v ) /
897974 ) ;
898975 assert ( match ?. groups ) ;
899- deployedUrl = match . groups . url ;
976+ const deployedUrl = match . groups . url ;
900977
901978 const testCases : AssetTestCase [ ] = [
902979 {
@@ -915,8 +992,8 @@ Current Version ID: 00000000-0000-0000-0000-000000000000`);
915992 await checkAssets ( testCases , deployedUrl ) ;
916993 } ) ;
917994 } ) ;
995+
918996 describe ( "durable objects [containers]" , ( ) => {
919- const workerName = generateResourceName ( ) ;
920997 beforeEach ( async ( ) => {
921998 await helper . seed ( {
922999 "wrangler.toml" : dedent `
0 commit comments