From 9b7320435059e30af71d648ab34ac6c00c80f5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Go=C5=82=C4=99biowski-Owczarek?= Date: Mon, 27 Apr 2020 21:37:06 +0200 Subject: [PATCH] Tests: Use only one focusin/out handler per matching window & document Backport tests from a jQuery 3.x fix that's not needed on `master`. Also, fix the "focusin from an iframe" test to actually verify the behavior from commit 1cecf64e5aa415367a7dae0b55c2dd17b591442d - the commit that introduced the regression - to make sure we don't regress on either front. The main part of the modified test was checking that focusin handling in an iframe works and that's still checked. The test was also checking that it doesn't propagate to the parent document, though, and, apparently, in IE it does. This one test is now blacklisted in IE. (cherry picked from 9e15d6b469556eccfa607c5ecf53b20c84529125) (cherry picked from 1a4f10ddc37c34c6dc3a451ee451b5c6cf367399) Ref gh-4652 Ref gh-4656 Closes gh-4657 --- test/unit/event.js | 63 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/test/unit/event.js b/test/unit/event.js index 7ba6c8f0b..771283c2f 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -2560,31 +2560,76 @@ testIframe( function( assert, framejQuery, frameWin, frameDoc ) { assert.expect( 1 ); - var input = jQuery( frameDoc ).find( "#frame-input" ); + var done = assert.async(), + focus = false, + input = jQuery( frameDoc ).find( "#frame-input" ); // Create a focusin handler on the parent; shouldn't affect the iframe's fate jQuery( "body" ).on( "focusin.iframeTest", function() { - assert.ok( false, "fired a focusin event in the parent document" ); + + // Support: IE 9 - 11+ + // IE does propagate the event to the parent document. In this test + // we mainly care about the inner element so we'll just skip this one + // assertion in IE. + if ( !document.documentMode ) { + assert.ok( false, "fired a focusin event in the parent document" ); + } } ); input.on( "focusin", function() { + focus = true; assert.ok( true, "fired a focusin event in the iframe" ); } ); // Avoid a native event; Chrome can't force focus to another frame - input.trigger( "focusin" ); - - // Must manually remove handler to avoid leaks in our data store - input.remove(); - - // Be sure it was removed; nothing should happen - input.trigger( "focusin" ); + input[ 0 ].focus(); // Remove body handler manually since it's outside the fixture jQuery( "body" ).off( "focusin.iframeTest" ); + + setTimeout( function() { + + // DOM focus is unreliable in TestSwarm + if ( QUnit.isSwarm && !focus ) { + assert.ok( true, "GAP: Could not observe focus change" ); + } + + done(); + }, 50 ); } ); +QUnit.test( "focusin on document & window", function( assert ) { + assert.expect( 1 ); + + var counter = 0, + input = jQuery( "" ); + + function increment() { + counter++; + } + + input.appendTo( "#qunit-fixture" ); + + input[ 0 ].focus(); + + jQuery( window ).on( "focusout", increment ); + jQuery( document ).on( "focusout", increment ); + + input[ 0 ].blur(); + + // DOM focus is unreliable in TestSwarm + if ( QUnit.isSwarm && counter === 0 ) { + assert.ok( true, "GAP: Could not observe focus change" ); + } + + assert.strictEqual( counter, 2, + "focusout handlers on document/window fired once only" ); + + jQuery( window ).off( "focusout", increment ); + jQuery( document ).off( "focusout", increment ); +} ); + testIframe( "jQuery.ready promise", "event/promiseReady.html",