11import { test , expect } from '@playwright/test'
2- import { createTest , html , waitForRequests } from '../../lib/framework'
3- import type { IntakeRegistry } from '../../lib/framework'
4-
5- // Loose type for view_update events received at the intake (no generated schema type yet)
6- interface ViewUpdateEvent {
7- type : string
8- date : number
9- application : { id : string }
10- session : { id : string }
11- view : { id : string ; is_active ?: boolean ; [ key : string ] : unknown }
12- _dd : { document_version : number ; [ key : string ] : unknown }
13- [ key : string ] : unknown
14- }
15-
16- // Helper: extract view_update events from all RUM events
17- // (intakeRegistry.rumViewEvents only returns type==='view')
18- function getViewUpdateEvents ( intakeRegistry : IntakeRegistry ) : ViewUpdateEvent [ ] {
19- return intakeRegistry . rumEvents . filter ( ( e ) => ( e . type as string ) === 'view_update' ) as unknown as ViewUpdateEvent [ ]
20- }
2+ import { createTest , waitForRequests } from '../../lib/framework'
213
224test . describe ( 'partial view updates' , ( ) => {
235 createTest ( 'should send view_update events after the initial view event' )
@@ -38,7 +20,7 @@ test.describe('partial view updates', () => {
3820 expect ( viewEvents [ 0 ] . type ) . toBe ( 'view' )
3921
4022 // Should have at least one view_update
41- const viewUpdateEvents = getViewUpdateEvents ( intakeRegistry )
23+ const viewUpdateEvents = intakeRegistry . rumViewUpdateEvents
4224 expect ( viewUpdateEvents . length ) . toBeGreaterThanOrEqual ( 1 )
4325
4426 // All events share the same view.id
@@ -59,20 +41,16 @@ test.describe('partial view updates', () => {
5941
6042 await flushEvents ( )
6143
62- // Collect all view-related events (view + view_update) sorted by document_version
63- const allViewRelatedEvents = [
64- ...intakeRegistry . rumViewEvents . map ( ( e ) => ( { _dd : e . _dd } ) ) ,
65- ...getViewUpdateEvents ( intakeRegistry ) . map ( ( e ) => ( { _dd : e . _dd } ) ) ,
66- ] . sort ( ( a , b ) => a . _dd . document_version - b . _dd . document_version )
44+ // Collect document_versions from all view-related events (view + view_update)
45+ const allDocVersions = [
46+ ...intakeRegistry . rumViewEvents . map ( ( e ) => e . _dd . document_version ) ,
47+ ...intakeRegistry . rumViewUpdateEvents . map ( ( e ) => ( e . _dd as { document_version : number } ) . document_version ) ,
48+ ]
6749
68- expect ( allViewRelatedEvents . length ) . toBeGreaterThanOrEqual ( 2 )
50+ expect ( allDocVersions . length ) . toBeGreaterThanOrEqual ( 2 )
6951
70- // Verify monotonic increase
71- for ( let i = 1 ; i < allViewRelatedEvents . length ; i ++ ) {
72- expect ( allViewRelatedEvents [ i ] . _dd . document_version ) . toBeGreaterThan (
73- allViewRelatedEvents [ i - 1 ] . _dd . document_version
74- )
75- }
52+ // Verify all document_versions are unique (no duplicates)
53+ expect ( new Set ( allDocVersions ) . size ) . toBe ( allDocVersions . length )
7654 } )
7755
7856 createTest ( 'should only send view events when feature flag is not enabled' )
@@ -88,25 +66,16 @@ test.describe('partial view updates', () => {
8866 expect ( intakeRegistry . rumViewEvents . length ) . toBeGreaterThanOrEqual ( 1 )
8967
9068 // Should NOT have any view_update events
91- const viewUpdateEvents = getViewUpdateEvents ( intakeRegistry )
69+ const viewUpdateEvents = intakeRegistry . rumViewUpdateEvents
9270 expect ( viewUpdateEvents ) . toHaveLength ( 0 )
9371 } )
9472
9573 createTest ( 'should emit a new full view event after navigation' )
9674 . withRum ( {
9775 enableExperimentalFeatures : [ 'partial_view_updates' ] ,
9876 } )
99- . withBody ( html `
100- < a id ="nav-link "> Navigate</ a >
101- < script >
102- document . getElementById ( 'nav-link' ) . addEventListener ( 'click' , ( ) => {
103- history . pushState ( null , '' , '/new-page' )
104- } )
105- </ script >
106- ` )
10777 . run ( async ( { intakeRegistry, flushEvents, page } ) => {
108- // Trigger a route change to create a new view
109- await page . click ( '#nav-link' )
78+ await page . evaluate ( ( ) => history . pushState ( null , '' , '/new-page' ) )
11079
11180 await flushEvents ( )
11281
@@ -130,7 +99,7 @@ test.describe('partial view updates', () => {
13099
131100 await flushEvents ( )
132101
133- const viewUpdateEvents = getViewUpdateEvents ( intakeRegistry )
102+ const viewUpdateEvents = intakeRegistry . rumViewUpdateEvents
134103 expect ( viewUpdateEvents . length ) . toBeGreaterThanOrEqual ( 1 )
135104
136105 for ( const event of viewUpdateEvents ) {
@@ -148,17 +117,8 @@ test.describe('partial view updates', () => {
148117 . withRum ( {
149118 enableExperimentalFeatures : [ 'partial_view_updates' ] ,
150119 } )
151- . withBody ( html `
152- < a id ="nav-link "> Navigate</ a >
153- < script >
154- document . getElementById ( 'nav-link' ) . addEventListener ( 'click' , ( ) => {
155- history . pushState ( null , '' , '/other-page' )
156- } )
157- </ script >
158- ` )
159120 . run ( async ( { intakeRegistry, flushEvents, page } ) => {
160- // Navigate to trigger view end on the first view
161- await page . click ( '#nav-link' )
121+ await page . evaluate ( ( ) => history . pushState ( null , '' , '/other-page' ) )
162122
163123 await flushEvents ( )
164124
@@ -170,7 +130,7 @@ test.describe('partial view updates', () => {
170130 expect ( endEvent ?. type ) . toBe ( 'view' )
171131
172132 // No view_update should have is_active: false
173- const viewUpdateEvents = getViewUpdateEvents ( intakeRegistry )
133+ const viewUpdateEvents = intakeRegistry . rumViewUpdateEvents
174134 const endUpdateEvent = viewUpdateEvents . find ( ( e ) => e . view . id === firstViewId && e . view . is_active === false )
175135 expect ( endUpdateEvent ) . toBeUndefined ( )
176136 } )
0 commit comments