@@ -16,6 +16,67 @@ const puppeteer = require('puppeteer');
1616 await page . waitForSelector ( '#done' , { timeout : 5 * 60 * 1000 } ) ;
1717 let anyFailures = await page . evaluate ( '__any_failures' ) ;
1818
19+ const testdataUrl = 'file:///' + __dirname . split ( '\\' ) . join ( '/' ) + '/testdata/' ;
20+ await page . goto ( testdataUrl + 'detector_slice_animation.html' ) ;
21+ await page . evaluate ( ( ) => {
22+ playing = false ;
23+ const check = ( condition , message ) => {
24+ if ( ! condition ) {
25+ throw new Error ( message ) ;
26+ }
27+ } ;
28+ const checkExactFrame = k => {
29+ show ( k ) ;
30+ const expected = parser . parseFromString ( frames [ k ] , 'image/svg+xml' ) . documentElement ;
31+ check ( stage . firstElementChild . isEqualNode ( expected ) , 'Animation endpoint differs from its Stim SVG.' ) ;
32+ } ;
33+
34+ checkExactFrame ( 0 ) ;
35+ checkExactFrame ( 1 ) ;
36+ show ( 0.5 ) ;
37+ const midpointSvg = stage . firstElementChild ;
38+ const birth = midpointSvg . getElementById ( 'slice:4:2' ) ;
39+ const death = midpointSvg . getElementById ( 'slice:1:1' ) ;
40+ const geometry = midpointSvg . getElementById ( 'shape-0-3-target' ) ;
41+ const styleSource = midpointSvg . getElementById ( 'slice:0:1' ) . parentElement ;
42+ const styleTarget = midpointSvg . getElementById ( 'slice:0:2' ) . parentElement ;
43+ check ( birth && Number ( birth . style . opacity ) > 0 && Number ( birth . style . opacity ) < 1 ,
44+ 'Birth was not rendered with fractional opacity.' ) ;
45+ check ( death && Number ( death . style . opacity ) > 0 && Number ( death . style . opacity ) < 1 ,
46+ 'Death was not rendered with fractional opacity.' ) ;
47+ check ( geometry , 'Persistent geometry transition was not mounted.' ) ;
48+ check ( Number ( styleSource . style . opacity ) > 0 && Number ( styleTarget . style . opacity ) > 0 ,
49+ 'Style transition layers were not visible.' ) ;
50+ const fills = layer => new Set ( [ ...layer . querySelectorAll ( '[fill]' ) ]
51+ . map ( element => element . getAttribute ( 'fill' ) ) . filter ( fill => fill && fill !== 'none' ) ) ;
52+ const sourceFills = fills ( styleSource ) ;
53+ const targetFills = fills ( styleTarget ) ;
54+ check ( [ ...sourceFills ] . some ( fill => ! targetFills . has ( fill ) ) , 'Endpoint styles were not distinct.' ) ;
55+
56+ show ( 0.25 ) ;
57+ const earlyGeometry = stage . firstElementChild . getElementById ( 'shape-0-3-target' ) . getAttribute ( 'd' ) ;
58+ show ( 0.75 ) ;
59+ const lateGeometry = stage . firstElementChild . getElementById ( 'shape-0-3-target' ) . getAttribute ( 'd' ) ;
60+ check ( earlyGeometry !== lateGeometry , 'Detector geometry did not move.' ) ;
61+
62+ show ( 0.5 ) ;
63+ const svg = stage . firstElementChild ;
64+ let gradientReferences = 0 ;
65+ for ( const element of svg . querySelectorAll ( '*' ) ) {
66+ for ( const attribute of element . attributes ) {
67+ const match = / ^ u r l \( [ ' " ] ? # ( [ ^ ' " ) ] + ) [ ' " ] ? \) $ / . exec ( attribute . value ) ;
68+ if ( match ) {
69+ const definition = svg . querySelector ( '[id="' + match [ 1 ] + '"]' ) ;
70+ check ( definition , 'Gradient or clip reference did not resolve.' ) ;
71+ gradientReferences += definition . tagName === 'radialGradient' ;
72+ }
73+ }
74+ }
75+ check ( gradientReferences > 0 , 'Mixed-Pauli gradients were not exercised.' ) ;
76+ checkExactFrame ( 1 ) ;
77+ } ) ;
78+ await page . waitForTimeout ( 50 ) ;
79+
1980 await browser . close ( ) ;
2081 if ( anyFailures || caughtPageError ) {
2182 process . exit ( 1 ) ;
0 commit comments