@@ -14,10 +14,13 @@ import { withTempDir } from '../../src/util/temp-dir.js';
1414import { makeSureItFails } from './helpers.js' ;
1515
1616describe ( 'watcher' , ( ) => {
17- const watchChange = ( { watchFile, touchedFile } = { } ) =>
17+ const watchChange = ( { prepTempDir , watchFile, touchedFile } = { } ) =>
1818 withTempDir ( async ( tmpDir ) => {
1919 const artifactsDir = path . join ( tmpDir . path ( ) , 'web-ext-artifacts' ) ;
2020 const someFile = path . join ( tmpDir . path ( ) , touchedFile ) ;
21+ if ( prepTempDir ) {
22+ await prepTempDir ( tmpDir ) ;
23+ }
2124
2225 if ( watchFile ) {
2326 watchFile = watchFile . map ( ( f ) => path . join ( tmpDir . path ( ) , f ) ) ;
@@ -237,4 +240,107 @@ describe('watcher', () => {
237240 await waitDebounce ( ) ;
238241 } ) ) ;
239242 } ) ;
243+
244+ describe ( 'watcher ignores _metadata' , ( ) => {
245+ // _metadata should be ignored to avoid reload loop, see:
246+ // https://github.com/mozilla/web-ext/issues/3468
247+
248+ // _metadata/generated_indexed_rulesets/_ruleset1 (original test case)
249+ let promiseTouchedMetadataDirContent ;
250+ // Immediate child of _metadata without subdirectory.
251+ let promiseTouchedMetadataDirWithoutSub ;
252+ // _metadata is also ignored when nested, not just at the top.
253+ let promiseTouchedMetadataDirNested ;
254+ // _metadata is a directory, but the implementation also ignores files...
255+ let promiseTouchedMetadataFile ;
256+ // Check behavior of --watch-file=_metadata
257+ let promiseTouchedMetadataFileWithWatchFile ;
258+ // Chrome may also write "Cached Theme.pak" (outside _metadata directory).
259+ let promiseTouchedTheme ;
260+
261+ it ( 'ignores change to _metadata directory content (setup)' , ( ) => {
262+ // Simulates scenario from https://github.com/mozilla/web-ext/issues/3468
263+ promiseTouchedMetadataDirContent = watchChange ( {
264+ prepTempDir : async ( tmpDir ) => {
265+ const metadataDir = path . join ( tmpDir . path ( ) , '_metadata' ) ;
266+ await fs . mkdir ( metadataDir ) ;
267+ await fs . mkdir ( path . join ( metadataDir , 'generated_indexed_rulesets' ) ) ;
268+ } ,
269+ touchedFile : path . join (
270+ '_metadata' ,
271+ 'generated_indexed_rulesets' ,
272+ '_ruleset1' ,
273+ ) ,
274+ } ) ;
275+ } ) ;
276+
277+ it ( 'ignores change to _metadata directory without subdirectory (setup)' , ( ) => {
278+ // Simulates scenario from https://github.com/mozilla/web-ext/issues/3468
279+ promiseTouchedMetadataDirWithoutSub = watchChange ( {
280+ prepTempDir : async ( tmpDir ) => {
281+ await fs . mkdir ( path . join ( tmpDir . path ( ) , '_metadata' ) ) ;
282+ } ,
283+ touchedFile : path . join ( '_metadata' , 'somefile' ) ,
284+ } ) ;
285+ } ) ;
286+
287+ it ( 'ignores change to non-toplevel _metadata directory (setup)' , ( ) => {
288+ promiseTouchedMetadataDirNested = watchChange ( {
289+ prepTempDir : async ( tmpDir ) => {
290+ const parentDir = path . join ( tmpDir . path ( ) , 'parent' ) ;
291+ await fs . mkdir ( parentDir ) ;
292+ await fs . mkdir ( path . join ( parentDir , '_metadata' ) ) ;
293+ } ,
294+ touchedFile : path . join ( 'parent' , '_metadata' , 'somefile' ) ,
295+ } ) ;
296+ } ) ;
297+
298+ it ( 'ignores change to _metadata file (setup)' , ( ) => {
299+ promiseTouchedMetadataFile = watchChange ( { touchedFile : '_metadata' } ) ;
300+ } ) ;
301+
302+ it ( 'ignores change to _metadata file despite --watch-file (setup)' , ( ) => {
303+ promiseTouchedMetadataFileWithWatchFile = watchChange ( {
304+ watchFile : [ '_metadata' ] ,
305+ touchedFile : '_metadata' ,
306+ } ) ;
307+ } ) ;
308+
309+ it ( 'igmores change to Cached Theme.pak (setup)' , ( ) => {
310+ // When a theme is loaded in Chrome, it writes to "Cached Theme.pak" in
311+ // the source directory, which would result in permanent auto-reload
312+ // unless we disabled auto reload.
313+ promiseTouchedTheme = watchChange ( { touchedFile : 'Cached Theme.pak' } ) ;
314+ } ) ;
315+
316+ it ( 'ignores change to _metadata directory content (await)' , async ( ) => {
317+ const { onChange } = await promiseTouchedMetadataDirContent ;
318+ sinon . assert . notCalled ( onChange ) ;
319+ } ) ;
320+
321+ it ( 'ignores change to _metadata directory without subdirectory (await)' , async ( ) => {
322+ const { onChange } = await promiseTouchedMetadataDirWithoutSub ;
323+ sinon . assert . notCalled ( onChange ) ;
324+ } ) ;
325+
326+ it ( 'ignores change to non-toplevel _metadata directory (await)' , async ( ) => {
327+ const { onChange } = await promiseTouchedMetadataDirNested ;
328+ sinon . assert . notCalled ( onChange ) ;
329+ } ) ;
330+
331+ it ( 'ignores change to _metadata file (await)' , async ( ) => {
332+ const { onChange } = await promiseTouchedMetadataFile ;
333+ sinon . assert . notCalled ( onChange ) ;
334+ } ) ;
335+
336+ it ( 'ignores change to _metadata file despite --watch-file (await)' , async ( ) => {
337+ const { onChange } = await promiseTouchedMetadataFileWithWatchFile ;
338+ sinon . assert . notCalled ( onChange ) ;
339+ } ) ;
340+
341+ it ( 'igmores change to Cached Theme.pak (await)' , async ( ) => {
342+ const { onChange } = await promiseTouchedTheme ;
343+ sinon . assert . notCalled ( onChange ) ;
344+ } ) ;
345+ } ) ;
240346} ) ;
0 commit comments