@@ -1702,5 +1702,67 @@ suite('DOM', function () {
17021702 createElementSpy . mockRestore ( ) ;
17031703 }
17041704 } ) ;
1705+
1706+ test ( 'p5.remove() stops tracks when createCapture() is pending' , async function ( ) {
1707+ const tracks = [
1708+ {
1709+ readyState : 'live' ,
1710+ stop ( ) {
1711+ this . readyState = 'ended' ;
1712+ }
1713+ } ,
1714+ {
1715+ readyState : 'live' ,
1716+ stop ( ) {
1717+ this . readyState = 'ended' ;
1718+ }
1719+ }
1720+ ] ;
1721+ const stream = { getTracks : ( ) => tracks } ;
1722+ const originalGetUserMedia = navigator . mediaDevices . getUserMedia ;
1723+ const createElement = document . createElement . bind ( document ) ;
1724+ let resolveGetUserMedia ;
1725+ let myp5 ;
1726+
1727+ navigator . mediaDevices . getUserMedia = ( ) =>
1728+ new Promise ( resolve => {
1729+ resolveGetUserMedia = resolve ;
1730+ } ) ;
1731+ const createElementSpy = vi
1732+ . spyOn ( document , 'createElement' )
1733+ . mockImplementation ( tagName => {
1734+ const element = createElement ( tagName ) ;
1735+ if ( tagName . toLowerCase ( ) === 'video' ) {
1736+ let srcObject = null ;
1737+ Object . defineProperty ( element , 'srcObject' , {
1738+ configurable : true ,
1739+ get ( ) {
1740+ return srcObject ;
1741+ } ,
1742+ set ( value ) {
1743+ srcObject = value ;
1744+ }
1745+ } ) ;
1746+ }
1747+ return element ;
1748+ } ) ;
1749+
1750+ try {
1751+ myp5 = new p5 ( function ( ) { } ) ;
1752+ myp5 . createCanvas ( 100 , 100 ) ;
1753+ const capture = myp5 . createCapture ( myp5 . VIDEO ) ;
1754+ await myp5 . remove ( ) ;
1755+ myp5 = null ;
1756+ resolveGetUserMedia ( stream ) ;
1757+ await Promise . resolve ( ) ;
1758+
1759+ assert . isTrue ( tracks . every ( track => track . readyState === 'ended' ) ) ;
1760+ assert . isNull ( capture . elt . srcObject ) ;
1761+ } finally {
1762+ if ( myp5 ) await myp5 . remove ( ) ;
1763+ navigator . mediaDevices . getUserMedia = originalGetUserMedia ;
1764+ createElementSpy . mockRestore ( ) ;
1765+ }
1766+ } ) ;
17051767 } ) ;
17061768} ) ;
0 commit comments