@@ -2,6 +2,12 @@ describe('hx-push-url attribute', function() {
22 const chai = window . chai
33 var HTMX_HISTORY_CACHE_NAME = 'htmx-history-cache'
44
5+ // Helper to normalize paths like htmx does
6+ function normalizePath ( path ) {
7+ const url = new URL ( path , window . location . href )
8+ return url . pathname
9+ }
10+
511 beforeEach ( function ( ) {
612 this . server = makeServer ( )
713 clearWorkArea ( )
@@ -23,7 +29,7 @@ describe('hx-push-url attribute', function() {
2329 this . server . respond ( )
2430 getWorkArea ( ) . textContent . should . equal ( 'second' )
2531 var cache = JSON . parse ( sessionStorage . getItem ( HTMX_HISTORY_CACHE_NAME ) )
26- cache [ cache . length - 1 ] . url . should . equal ( '/test' )
32+ cache [ cache . length - 1 ] . url . should . equal ( normalizePath ( '/test' ) )
2733 } )
2834
2935 it ( 'navigation should not push an element into the cache when false' , function ( ) {
@@ -50,7 +56,7 @@ describe('hx-push-url attribute', function() {
5056 getWorkArea ( ) . textContent . should . equal ( 'second' )
5157 var cache = JSON . parse ( sessionStorage . getItem ( HTMX_HISTORY_CACHE_NAME ) )
5258 cache . length . should . equal ( 2 )
53- cache [ 1 ] . url . should . equal ( '/ abc123')
59+ cache [ 1 ] . url . should . equal ( normalizePath ( ' abc123') )
5460 } )
5561
5662 it ( 'restore should return old value' , function ( ) {
@@ -197,9 +203,9 @@ describe('hx-push-url attribute', function() {
197203 htmx . _ ( 'saveToHistoryCache' ) ( 'url1' , make ( '<div>' ) )
198204 var cache = JSON . parse ( sessionStorage . getItem ( HTMX_HISTORY_CACHE_NAME ) )
199205 cache . length . should . equal ( 3 )
200- cache [ 0 ] . url . should . equal ( '/ url3')
201- cache [ 1 ] . url . should . equal ( '/ url2')
202- cache [ 2 ] . url . should . equal ( '/ url1')
206+ cache [ 0 ] . url . should . equal ( normalizePath ( ' url3') )
207+ cache [ 1 ] . url . should . equal ( normalizePath ( ' url2') )
208+ cache [ 2 ] . url . should . equal ( normalizePath ( ' url1') )
203209 } )
204210
205211 it ( 'htmx:afterSettle is called when replacing outerHTML' , function ( ) {
@@ -273,21 +279,21 @@ describe('hx-push-url attribute', function() {
273279 } )
274280 }
275281
276- it . skip ( 'normalizePath falls back to no normalization if path not valid URL' , function ( ) {
277- // path normalization has a bug breaking it right now preventing this test
282+ it ( 'normalizePath falls back to no normalization if path not valid URL' , function ( ) {
283+ // path normalization bug is now fixed
278284 htmx . _ ( 'saveToHistoryCache' ) ( 'http://' , make ( '<div>' ) )
279285 htmx . _ ( 'saveToHistoryCache' ) ( 'http//' , make ( '<div>' ) )
280286 var cache = JSON . parse ( sessionStorage . getItem ( HTMX_HISTORY_CACHE_NAME ) )
281287 cache . length . should . equal ( 2 )
282- cache [ 0 ] . url . should . equal ( 'http:// ' ) // no normalization as invalid
283- cache [ 1 ] . url . should . equal ( '/ http') // can normalize this one
288+ cache [ 0 ] . url . should . equal ( 'http:' ) // trailing slash removed after normalization
289+ cache [ 1 ] . url . should . equal ( normalizePath ( ' http') ) // can normalize this one
284290 } )
285291
286292 it ( 'history cache clears out disabled attribute' , function ( ) {
287293 htmx . _ ( 'saveToHistoryCache' ) ( '/url1' , make ( '<div><div data-disabled-by-htmx disabled></div></div>' ) )
288294 var cache = JSON . parse ( sessionStorage . getItem ( HTMX_HISTORY_CACHE_NAME ) )
289295 cache . length . should . equal ( 1 )
290- cache [ 0 ] . url . should . equal ( '/url1' )
296+ cache [ 0 ] . url . should . equal ( normalizePath ( '/url1' ) )
291297 cache [ 0 ] . content . should . equal ( '<div data-disabled-by-htmx=""></div>' )
292298 } )
293299
@@ -375,6 +381,39 @@ describe('hx-push-url attribute', function() {
375381 htmx . off ( 'htmx:pushedIntoHistory' , handler )
376382 } )
377383
384+ it ( 'normalizes relative paths correctly' , function ( ) {
385+ // Get current path to build expected normalized paths
386+ var currentPath = window . location . pathname
387+ var basePath = currentPath . substring ( 0 , currentPath . lastIndexOf ( '/' ) + 1 )
388+
389+ htmx . _ ( 'saveToHistoryCache' ) ( 'relative/path' , make ( '<div>' ) )
390+ htmx . _ ( 'saveToHistoryCache' ) ( './another/path' , make ( '<div>' ) )
391+ var cache = JSON . parse ( sessionStorage . getItem ( HTMX_HISTORY_CACHE_NAME ) )
392+ cache . length . should . equal ( 2 )
393+ // Both should be normalized to absolute paths based on current location
394+ cache [ 0 ] . url . should . equal ( basePath + 'relative/path' )
395+ cache [ 1 ] . url . should . equal ( basePath + 'another/path' )
396+ } )
397+
398+ it ( 'normalizes paths with query strings correctly' , function ( ) {
399+ var currentPath = window . location . pathname
400+ var basePath = currentPath . substring ( 0 , currentPath . lastIndexOf ( '/' ) + 1 )
401+
402+ htmx . _ ( 'saveToHistoryCache' ) ( 'path?foo=bar' , make ( '<div>' ) )
403+ var cache = JSON . parse ( sessionStorage . getItem ( HTMX_HISTORY_CACHE_NAME ) )
404+ cache . length . should . equal ( 1 )
405+ cache [ 0 ] . url . should . equal ( basePath + 'path?foo=bar' )
406+ } )
407+
408+ it ( 'normalizes paths with trailing slashes' , function ( ) {
409+ htmx . _ ( 'saveToHistoryCache' ) ( '/path/' , make ( '<div>' ) )
410+ htmx . _ ( 'saveToHistoryCache' ) ( '/path/to/page/' , make ( '<div>' ) )
411+ var cache = JSON . parse ( sessionStorage . getItem ( HTMX_HISTORY_CACHE_NAME ) )
412+ cache . length . should . equal ( 2 )
413+ cache [ 0 ] . url . should . equal ( normalizePath ( '/path' ) )
414+ cache [ 1 ] . url . should . equal ( normalizePath ( '/path/to/page' ) )
415+ } )
416+
378417 it ( 'pushing url without anchor will retain the page anchor tag' , function ( ) {
379418 var handler = htmx . on ( 'htmx:configRequest' , function ( evt ) {
380419 evt . detail . path = evt . detail . path + '#test'
0 commit comments