Jsdom: Exposer une méthode pour ajouter des fichiers à une liste de fichiers

Créé le 23 oct. 2015  ·  30Commentaires  ·  Source: jsdom/jsdom

Les FileList ne sont pas accessibles en écriture dans les spécifications, mais pour rendre input.files testable, nous devrons implémenter une méthode util pour la modifier.

/cc @cpojer

feature

Commentaire le plus utile

J'ai réussi à créer FileList sans avoir à modifier le code de la bibliothèque jsdom :

const createFile = (size = 44320, name = 'ecp-logo.png', type = 'image/png') =>
  new File([new ArrayBuffer(size)], name , {
    type: type,
  });

const createFileList = (file) => {
  const fileList = new FileList();
  fileList[0] = file;
  return fileList;
}

const fileList = createFileList(createFile());

Dans ce cas, je crée un constructeur d'appel d'objet FileList sur FileList fourni par jsdom. Après cela, j'ajoute simplement un fichier à cette liste en utilisant la notation Array. Dans mon cas, je n'ai besoin que d'un fichier dans le tableau, mais cela peut également être modifié en boucle for pour ajouter plusieurs fichiers à FileList. Je crée un fichier avec un nom/type/taille personnalisé via le constructeur de fichier également fourni par jsdom dont la fonctionnalité suit les spécifications.

Cela peut être utile pour quelqu'un qui cherche à se moquer de FileList dans un environnement jsdom, mais un problème persiste. La création de FileList avec un tableau de fichiers à l'aide de cette méthode ne permettrait pas d'obtenir des éléments du tableau à l'aide de la méthode FileList.item(index). Mais, même cela peut être corrigé en remplaçant sa méthode quelque chose comme ceci :

const createFileList = (file) => {
  const fileList = new FileList();
  fileList[0] = file;
  fileList.item = index => fileList[index]; // override method functionality
  return fileList;
}

Je pense toujours qu'il serait peut-être préférable que jsdom offre ces fonctionnalités à des fins de test prêtes à l'emploi.

Tous les 30 commentaires

input.files = createFileList(file1, file2, ...) serait sympa.

@cpojer Générez -vous des objets réels File à y mettre ?

Rendre input.files inscriptible est probablement mauvais, nous pouvons probablement soit retourner le tableau brut pour vous remplir, soit faire quelque chose comme fillFileList(input.files, [file]) .

En fait, nous n'utilisons que des données fictives, nous remplissons donc .files avec un tableau d'objets. Mais exiger que ce soit un objet File serait raisonnable, je pense.

Il semble que defineProperty convienne ici ? Les propriétés DOM sont reconfigurables pour une raison...

Je préférerais de loin créer une vraie liste de fichiers avec de vraies données, cependant.

Il devrait également être possible d'accéder aux éléments FileList en utilisant leurs indices de tableau. .item n'est pas le seul moyen d'accéder à leurs champs.

D'accord, il semble donc qu'il y ait quelques problèmes potentiels :

  • FileList n'a pas correctement l'accès indexé (bug)
  • Il n'y a aucun moyen de créer des objets FileList pour les tests (lacune des fonctionnalités de la plate-forme Web).

Mais modifier inputEl.files n'est pas le problème.

Ouais, je veux dire que ce n'est pas génial de dire aux ingénieurs d'utiliser Object.defineProperty sur une mission régulière, mais je peux vivre avec.

Bon, ils doivent faire ça de toute façon dans un vrai navigateur, donc ça me semble raisonnable...

Salut, je vois que cela a plus d'un an, je voudrais demander s'il y a des progrès réalisés concernant ce problème? J'utilise le framework Jest pour tester mon application React/Redux qui utilise en interne jsdom. J'ai un problème où je dois créer dynamiquement FileList avec un ou plusieurs objets File.

En regardant lib/jsdom/living/filelist.js, je peux voir qu'il existe un constructeur pour FileList mais il n'y a aucune option pour lui transmettre des fichiers. Je comprends que FileList et File n'ont pas de constructeur selon les spécifications pour des raisons de sécurité, mais y a-t-il une intention d'autoriser le constructeur à accepter un tableau d'objets File ou au moins une méthode supplémentaire (disons _setItem_) qui nous permettrait d'ajouter File objets dans la liste spécifiquement à des fins de test ?

Je vois aussi un autre problème avec FileList. Si je ne me trompe pas, il devrait s'agir d'un objet de type Array, identique à NodeList (lib/jsdom/living/node-list.js), ce qui signifie qu'il devrait être possible d'accéder aux objets File de deux manières :

var fileList = document.getElementById("myfileinput").files;

fileList[0];
fileList.item(0);

Actuellement, il n'est possible d'y accéder que par la méthode. Cela signifie que la même logique que dans NodeList doit être appliquée ici :

FileList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];

et les fichiers devraient être stockés quelque chose comme ceci si nous permettions de passer un tableau de fichiers au constructeur :

for (let i = 0; i < files.length; ++i) {
  this[i] = files[i];
}

Je n'ai pas d'opinion tranchée sur la façon dont cela devrait être fait, ce ne sont que des exemples que j'utilise pour mieux expliquer ce que j'essaie de souligner.

Questions supplémentaires (je ne veux pas ouvrir de questions inutiles avant de poser ici) :

1.) Serait-il avantageux d'ajouter le constructeur File à des fins de test qui crée un objet File à partir d'un fichier réel en utilisant le chemin fourni comme chaîne ? J'ai trouvé une bibliothèque (je suis désolé, je ne trouve plus de lien) qui a permis ceci :

const file = new File('../fixtures/files/test-image.png');

Cela a créé un fichier pour moi avec des propriétés (taille, lastModified, type...) sans que j'aie à le créer manuellement :

const file = new File([''], 'test-image.png', {
  lastModified: 1449505890000,
  lastModifiedDate: new Date(1449505890000),
  name: "ecp-logo.png",
  size: 44320,
  type: "image/png",
});

Je ne sais pas comment fonctionnait cette bibliothèque, tout ce que je sais, c'est qu'elle n'a pas été maintenue pendant plus d'un an et que nous avons cessé de l'utiliser. Je n'arrive plus à le trouver.

2.) window.URL.createObjectURL n'est pas pris en charge par jsdom. Je ne sais pas si cela doit être signalé.

J'ai réussi à créer FileList sans avoir à modifier le code de la bibliothèque jsdom :

const createFile = (size = 44320, name = 'ecp-logo.png', type = 'image/png') =>
  new File([new ArrayBuffer(size)], name , {
    type: type,
  });

const createFileList = (file) => {
  const fileList = new FileList();
  fileList[0] = file;
  return fileList;
}

const fileList = createFileList(createFile());

Dans ce cas, je crée un constructeur d'appel d'objet FileList sur FileList fourni par jsdom. Après cela, j'ajoute simplement un fichier à cette liste en utilisant la notation Array. Dans mon cas, je n'ai besoin que d'un fichier dans le tableau, mais cela peut également être modifié en boucle for pour ajouter plusieurs fichiers à FileList. Je crée un fichier avec un nom/type/taille personnalisé via le constructeur de fichier également fourni par jsdom dont la fonctionnalité suit les spécifications.

Cela peut être utile pour quelqu'un qui cherche à se moquer de FileList dans un environnement jsdom, mais un problème persiste. La création de FileList avec un tableau de fichiers à l'aide de cette méthode ne permettrait pas d'obtenir des éléments du tableau à l'aide de la méthode FileList.item(index). Mais, même cela peut être corrigé en remplaçant sa méthode quelque chose comme ceci :

const createFileList = (file) => {
  const fileList = new FileList();
  fileList[0] = file;
  fileList.item = index => fileList[index]; // override method functionality
  return fileList;
}

Je pense toujours qu'il serait peut-être préférable que jsdom offre ces fonctionnalités à des fins de test prêtes à l'emploi.

Salut les gars ,
Je suis confronté à un problème car je me moque de l'objet $("#selectorID of Upload file")[0].files[0] qui renvoie FileList.
Quelqu'un peut-il m'aider à créer un objet FileList ? Parce que je ne trouve aucun lien de référence nulle part sur WWW

Ce n'est pas possible actuellement.

Merci Dominique,

J'ai besoin d'écrire un scénario de test pour l'événement de changement de téléchargement de fichier. toute autre façon d'exécuter ce scénario de test.

Des progrès là-dessus ?

@niksajanjic Avez-vous réussi à mettre en œuvre la meilleure solution présentée dans ce fil ?
Réf : const file = new File('../fixtures/files/test-image.png');
Ou quelque chose de similaire ?
Meilleur

@domenic semble être un peu dissident dans ce post Twitter sur la question

@domenic Ok, j'ai configuré le début de base pour cela. Tous les chèques ne sont pas là, mais c'est essentiellement ce dont parlait

créerFichier

function createFile(file_path) {
  const { mtimeMs: lastModified, size } = fs.statSync(file_path)

  return new File(
    [new fs.readFileSync(file_path)],
    path.basename(file_path),
    {
      lastModified,
      type: mime.lookup(file_path) || '',
    }
  )
}

addFileList

function addFileList(input, file_paths) {
  if (typeof file_paths === 'string')
    file_paths = [file_paths]
  else if (!Array.isArray(file_paths)) {
    throw new Error('file_paths needs to be a file path string or an Array of file path strings')
  }

  const file_list = file_paths.map(fp => createFile(fp))
  file_list.__proto__ = Object.create(FileList.prototype)

  Object.defineProperty(input, 'files', {
    value: file_list,
    writeable: false,
  })

  return input
}

Fichier de démonstration

/*eslint-disable no-console, no-unused-vars */

/*
https://github.com/jsdom/jsdom/issues/1272
*/

const fs = require('fs')
const path = require('path')
const mime = require('mime-types')

const { JSDOM } = require('jsdom')
const dom = new JSDOM(`
<!DOCTYPE html>
<body>
  <input type="file">
</body>
`)

const { window } = dom
const { document, File, FileList } = window


const file_paths = [
  '/Users/williamrusnack/Documents/form_database/test/try-input-file.html',
  '/Users/williamrusnack/Documents/form_database/test/try-jsdom-input-file.js',
]

function createFile(file_path) {
  const { mtimeMs: lastModified, size } = fs.statSync(file_path)

  return new File(
    [new fs.readFileSync(file_path)],
    path.basename(file_path),
    {
      lastModified,
      type: mime.lookup(file_path) || '',
    }
  )
}

function addFileList(input, file_paths) {
  if (typeof file_paths === 'string')
    file_paths = [file_paths]
  else if (!Array.isArray(file_paths)) {
    throw new Error('file_paths needs to be a file path string or an Array of file path strings')
  }

  const file_list = file_paths.map(fp => createFile(fp))
  file_list.__proto__ = Object.create(FileList.prototype)

  Object.defineProperty(input, 'files', {
    value: file_list,
    writeable: false,
  })

  return input
}



const input = document.querySelector('input')

addFileList(input, file_paths)

for (let i = 0; i < input.files.length; ++i) {
  const file = input.files[i]
  console.log('file', file)
  console.log('file.name', file.name)
  console.log('file.size', file.size)
  console.log('file.type', file.type)
  console.log('file.lastModified', file.lastModified)
  console.log()
}

@BebeSparkelSparkel J'ai fait le test d'une manière que j'ai expliquée dans mon post ultérieur là-haut. Malheureusement, quelques mois plus tard, il a cessé de fonctionner sur les nouvelles versions de jsdom lorsqu'un de mes collègues a essayé de copier ce code. Nous avons donc dû commenter les tests de FileList à ce stade. À partir de là, nous n'avons pas pu trouver un moyen d'écrire ces tests et au cours des derniers mois, personne n'a eu le temps d'y jeter un autre coup d'œil et d'essayer de trouver un moyen.

@niksajanjic Merci pour votre mise à jour. Je travaille sur la solution que vous avez proposée et cela semble fonctionner (voir le code ci-dessus), mais je pense qu'il est peu probable qu'il soit ajouté à jsdom car il serait très difficile de comprendre comment l'ajouter.
N'hésitez pas à y jeter un œil et à l'utiliser si vous le souhaitez

Création d'un script d'aide simple qui résout ce problème jusqu'à ce que le projet jsdom propose une solution.
https://bitbucket.org/william_rusnack/addfilelist/src/master/

Ajoutez un fichier :

const input = document.querySelector('input[type=file]')
addFileList(input, 'path/to/file')

Ajouter plusieurs fichiers :

const input = document.querySelector('input[type=file]')
addFileList(input, [
  'path/to/file',
  'path/to/another/file',
  // add as many as you want
])

Installer et exiger

npm install https://github.com/BebeSparkelSparkel/addFileList.git

```javascript
const { addFileList } = require('addFileList')

## Functions
**addFileList**(input, file_paths)  
Effects: puts the file_paths as File object into input.files as a FileList  
Returns: input  
Arguments:  
- input: HTML input element  
- file_paths: String or Array of string file paths to put in input.files  
`const { addFileList } = require('addFileList')`  

## Example
Extract from example.js
```javascript
// add a single file
addFileList(input, 'example.js')

// log input's FileList
console.log(input.files)

// log file properties
const [ file ] = input.files
console.log(file)
console.log(
  '\nlastModified', file.lastModified,
  '\nname', file.name,
  '\nsize', file.size,
  '\ntype', file.type,
  '\n'
)

Résultat

$ node example.js 
FileList [ File {} ]
File {}

lastModified 1518523506000 
name example.js 
size 647 
type application/javascript 

@BebeSparkelSparkel votre repo semble avoir été supprimé ?

J'ai eu un problème similaire - j'ai écrit une fonction qui prenait un FileList en entrée et je voulais écrire un test unitaire pour cela en utilisant jest. J'ai pu utiliser la fonction d'assistance ci-dessous pour usurper un objet FileList suffisamment pour fonctionner avec ma fonction. La syntaxe est ES6 avec des annotations Flow. Rien ne promet que cela fonctionnera dans toutes les situations car il simule simplement la fonctionnalité de la vraie classe FileList

const createFileList = (files: Array<File>): FileList => {
  return {
    length: files.length,
    item: (index: number) => files[index],
    * [Symbol.iterator]() {
      for (let i = 0; i < files.length; i++) {
        yield files[i];
      }
    },
    ...files,
  };
};

Dans le frontend, je peux faire quelque chose comme ce qui suit pour (d'une manière détournée) construire un "vrai" FileList :

export const makeFileList = files => {
  const reducer = (dataTransfer, file) => {
    dataTransfer.items.add(file)
    return dataTransfer
  }

  return files.reduce(reducer, new DataTransfer()).files
}

Réf : https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer

Malheureusement, jsdom ne semble pas encore vraiment prendre en charge DataTransfer , donc cela ne fonctionne pas dans mes tests :

Autres références :


En cherchant un peu dans la source, j'ai trouvé exports.FileList = require("./generated/FileList").interface;

~Mais il n'était pas clair pour moi de GitHub où trouver la source qui finit par construire ./generated ~

L' export principal du package npm est ./lib/api.js et exporte une très petite API publique :

exports.JSDOM = JSDOM;
exports.VirtualConsole = VirtualConsole;
exports.CookieJar = CookieJar;
exports.ResourceLoader = ResourceLoader;
exports.toughCookie = toughCookie;

Mais en regardant dans mon répertoire ./node_modules/jsdom/lib/jsdom .. je peux voir que tous les fichiers internes/d'implémentation sont également là, y compris ./node_modules/jsdom/lib/jsdom/living/file-api :

Blob-impl.js  File-impl.js  FileList-impl.js  FileReader-impl.js

FileList-impl.js contient ici l'implémentation JS réelle qui prend en charge l'api FileList exposée dans jsdom.

Maintenant, si nous regardons ./node_modules/jsdom/lib/jsdom/living/generated/FileList.js nous voyons l'« API publique » réellement générée que nous finissons par voir dans le cadre d'une utilisation normale, y compris notre trop familière :

class FileList {
  constructor() {
    throw new TypeError("Illegal constructor");
  }

Ce fichier exporte module.exports = iface; , qui contient beaucoup plus de fonctionnalités que ce que nous obtenons via l'exposition "normale" de l'API publique, qui n'utilise que la clé iface.interface . Alors peut-être que nous pourrions faire quelque chose d'amusant si nous utilisons directement require("./generated/FileList") . En supprimant les détails d'implémentation, nous avons une interface qui ressemble à quelque chose comme :

const iface = {
  _mixedIntoPredicates: [],
  is(obj) {..snip..},
  isImpl(obj) {..snip..},
  convert(obj, { context = "The provided value" } = {}) {..snip..},
  create(constructorArgs, privateData) {..snip..},
  createImpl(constructorArgs, privateData) {..snip..},
  _internalSetup(obj) {},
  setup(obj, constructorArgs, privateData) {...snip...},
  interface: FileList,
  expose: {
    Window: { FileList },
    Worker: { FileList }
  }
}; // iface

Alors maintenant que nous savons qu'il y a plus de puissance à obtenir.. voyons comment d'autres zones de jsdom accèdent..

En regardant HTMLInputElement-impl , il semble utiliser FileList.createImpl() , bien que malheureusement cela ne nous montre pas comment utiliser les paramètres :

createImpl est juste un petit wrapper autour du setup dans le iface exporté :

createImpl(constructorArgs, privateData) {
    let obj = Object.create(FileList.prototype);
    obj = this.setup(obj, constructorArgs, privateData);
    return utils.implForWrapper(obj);
  },

En jouant avec cela dans une console, il semble que nous ayons l'api expressive de l'élément Array lequel le FileListImpl est soutenu. Nous pouvons donc faire des choses comme :

var flist = require('./node_modules/jsdom/lib/jsdom/living/generated/FileList.js')
var myFileListImpl = flist.createImpl()
myFileListImpl.push('aa')

Il contient une propriété Symbol(wrapper) , à laquelle nous devrons utiliser ./node_modules/jsdom/lib/jsdom/living/generated/utils.js:37 pour accéder :

var utils = require('./node_modules/jsdom/lib/jsdom/living/generated/utils.js')
var wrapper = myFileListImpl[utils.wrapperSymbol]

Le iface exporté a une fonction convert , qui throw new TypeError( ${context} n'est pas de type 'FileList'. ); lorsque l'objet fourni n'est pas un FileList . Nous pouvons l'utiliser pour tester des choses.

Si nous l'appelons sur le myFileListImpl brut, il renvoie l'erreur :

flist.convert(myFileListImpl)

Alors qu'en utilisant le wrapper nous avons extrait ci-dessus, nous pouvons voir qu'il ne renvoie pas l'erreur :

flist.convert(myFileListImpl[utils.wrapperSymbol])

Avec cela, nous pouvons modifier myFileListImpl , et récupérer un objet FileList acceptable, à passer là où nous en avons besoin. Un exemple entièrement travaillé (en utilisant util.wrapperForImpl() au lieu de notre code précédent) :

var _FileList = require('./node_modules/jsdom/lib/jsdom/living/generated/FileList.js')
var utils = require('./node_modules/jsdom/lib/jsdom/living/generated/utils.js')

var myMutableFileListImpl = _FileList.createImpl()

myMutableFileListImpl.length // 0
myMutableFileListImpl.push(new File([], 'a.jpg'))
myMutableFileListImpl.length // 1

var myFileList = utils.wrapperForImpl(myMutableFileListImpl)
_FileList.convert(myFileList) // no error

myFileList.length // 1
myFileList[0] // the File{} object

Maintenant, avec ces connaissances, je peux implémenter la version de test jsdom de mon hack de contournement de navigateur d'origine (implémenté au-dessus d' ImmutableJS pour la paresse):

import { Map, Record } from 'immutable'

import jsdomFileList from 'jsdom/lib/jsdom/living/generated/FileList'
import { wrapperForImpl } from 'jsdom/lib/jsdom/living/generated/utils'

// Note: relying on internal API's is super hacky, and will probably break
// As soon as we can, we should use whatever the proper outcome from this issue is:
//   https://github.com/jsdom/jsdom/issues/1272#issuecomment-486088445

export const makeFileList = files => {
  const reducer = (fileListImpl, file) => {
    fileListImpl.push(file)
    return fileListImpl
  }

  const fileListImpl = files.reduce(reducer, jsdomFileList.createImpl())

  return wrapperForImpl(fileListImpl)
}

export class DataTransferStub extends Record({ items: Map() }) {
  get files() {
    return makeFileList(this.items.toList().toArray())
  }
}

export const stubGlobalDataTransfer = () => {
  global.DataTransfer = DataTransferStub
}

export const restoreGlobalDataTransfer = () => {
  global.DataTransfer = undefined
}

Et puis câblez-le manuellement dans mes variables globales afin que mes tests ava puissent l'utiliser :

import {
  restoreGlobalDataTransfer,
  stubGlobalDataTransfer,
} from ../helpers/jsdom-helpers'

test.before(t => {
  stubGlobalDataTransfer()
})

test.after(t => {
  restoreGlobalDataTransfer()
})

Tous les navigateurs modernes (c'est-à-dire pas IE <= 11) prennent désormais en charge la définition de input.files sur une liste de fichiers https://stackoverflow.com/a/47522812/2744776

Cela semble avoir changé dans une version récente. Voici ce qui a fonctionné pour moi :

const jsdomUtils = require('jsdom/lib/jsdom/living/generated/utils');
const jsdomFileList = require('jsdom/lib/jsdom/living/generated/FileList');
function makeFileList(...files) {
    const impl = jsdomFileList.createImpl(window);
    const ret = Object.assign([...files], {
        item: (ix) => ret[ix],
        [jsdomUtils.implSymbol]: impl,
    });
    impl[jsdomUtils.wrapperSymbol] = ret;
    Object.setPrototypeOf(ret, FileList.prototype);
    return ret;
}

Si vous utilisez JSDOM via Jest, vous devez vous assurer d'avoir besoin des composants internes en dehors de la VM de test. J'ai créé un environnement de test personnalisé comme celui-ci :

const JsdomEnvironment = require('jest-environment-jsdom');

/** See jsdom/jsdom#1272 */
class EnvWithSyntheticFileList extends JsdomEnvironment {
    async setup() {
        await super.setup();
        this.global.jsdomUtils = require('jsdom/lib/jsdom/living/generated/utils');
        this.global.jsdomFileList = require('jsdom/lib/jsdom/living/generated/FileList');
    }
}

module.exports = EnvWithSyntheticFileList;

Pour que je puisse accéder aux importations « extérieures ».

Cela semble avoir changé dans une version récente. Voici ce qui a fonctionné pour moi :

const jsdomUtils = require('jsdom/lib/jsdom/living/generated/utils');
const jsdomFileList = require('jsdom/lib/jsdom/living/generated/FileList');
function makeFileList(...files) {
    const impl = jsdomFileList.createImpl(window);
    const ret = Object.assign([...files], {
        item: (ix) => ret[ix],
        [jsdomUtils.implSymbol]: impl,
    });
    impl[jsdomUtils.wrapperSymbol] = ret;
    Object.setPrototypeOf(ret, FileList.prototype);
    return ret;
}

Si vous utilisez JSDOM via Jest, vous devez vous assurer d'avoir besoin des composants internes en dehors de la VM de test. J'ai créé un environnement de test personnalisé comme celui-ci :

const JsdomEnvironment = require('jest-environment-jsdom');

/** See jsdom/jsdom#1272 */
class EnvWithSyntheticFileList extends JsdomEnvironment {
    async setup() {
        await super.setup();
        this.global.jsdomUtils = require('jsdom/lib/jsdom/living/generated/utils');
        this.global.jsdomFileList = require('jsdom/lib/jsdom/living/generated/FileList');
    }
}

module.exports = EnvWithSyntheticFileList;

Pour que je puisse accéder aux importations « extérieures ».

Cela m'a rapproché mais je ne peux pas passer la validation interne:

exportations.is = valeur => {
return utils.isObject(value) && utils.hasOwn(value, implSymbol) && value[implSymbol] instanceof Impl.implementation;
} ;

TypeError : Échec de la définition de la propriété 'files' sur 'HTMLInputElement' : la valeur fournie n'est pas de type 'FileList'.

Des heures passées. Super frustrant

Cela semble avoir changé dans une version récente. Voici ce qui a fonctionné pour moi :

const jsdomUtils = require('jsdom/lib/jsdom/living/generated/utils');
const jsdomFileList = require('jsdom/lib/jsdom/living/generated/FileList');
function makeFileList(...files) {
    const impl = jsdomFileList.createImpl(window);
    const ret = Object.assign([...files], {
        item: (ix) => ret[ix],
        [jsdomUtils.implSymbol]: impl,
    });
    impl[jsdomUtils.wrapperSymbol] = ret;
    Object.setPrototypeOf(ret, FileList.prototype);
    return ret;
}

Si vous utilisez JSDOM via Jest, vous devez vous assurer d'avoir besoin des composants internes en dehors de la VM de test. J'ai créé un environnement de test personnalisé comme celui-ci :

const JsdomEnvironment = require('jest-environment-jsdom');

/** See jsdom/jsdom#1272 */
class EnvWithSyntheticFileList extends JsdomEnvironment {
    async setup() {
        await super.setup();
        this.global.jsdomUtils = require('jsdom/lib/jsdom/living/generated/utils');
        this.global.jsdomFileList = require('jsdom/lib/jsdom/living/generated/FileList');
    }
}

module.exports = EnvWithSyntheticFileList;

Pour que je puisse accéder aux importations « extérieures ».

Cela m'a rapproché mais je ne peux pas passer la validation interne:

exportations.is = valeur => {
return utils.isObject(value) && utils.hasOwn(value, implSymbol) && value[implSymbol] instanceof Impl.implementation;
} ;

TypeError : Échec de la définition de la propriété 'files' sur 'HTMLInputElement' : la valeur fournie n'est pas de type 'FileList'.

Des heures passées. Super frustrant

Après avoir recommencé avec un nouveau cerveau, j'ai trouvé le problème. D'une manière ou d'une autre, j'avais 2 environnements jsdom distincts en cours d'exécution, ce qui annulait les références aux symboles.

Cette page vous a été utile?
0 / 5 - 0 notes