Tout va bien tant que vous devez exécuter des sources JS à travers les mannequins pour créer un bundle, mais l'enfer commence lorsque vous voulez écrire des tests pour votre site ou votre bibliothèque. Le problème est que tous les frameworks de test utilisent des fonctions spécifiques d'un nœud et / ou sont écrits en ES5. Ainsi, le lancement de tests E2E n'est pas une tâche triviale et propose de danser avec un tambourin de transpilations et de sourcemaps pour couvrir le code. Vous ne voulez pas que les erreurs pointent au mauvais endroit?
Dans cet article, je décrirai mon expérience d'utilisation de Puppeteer pour une petite tâche,
et comment j'ai lancé les modules ES6 dans le nœud et le navigateur, n'ayant qu'une seule source pour les tests sans collecteurs.
Pourquoi Marionnettiste du tout, demandez-vous, pourquoi pas WebDriver? Je viens de remarquer comment les créateurs des bibliothèques WebGL open source populaires sont tourmentés, par exemple, ils ont 300 pages avec des exemples, chacun pouvant rompre avec n'importe quel commit. Ils les vérifient après chaque changement, et s'ils ont oublié d'ouvrir quelque chose - désolé ¯\_(ツ)_/¯
, cela s'est cassé. Si personne n'a encore résolu ce problème, j'ai décidé de l'essayer dans ma petite bibliothèque. La première pensée qui a été de lancer un glu sans tête, mais elle est obsolète. Node-gles prend déjà en charge WebGL2, mais pas l'extension rare que j'ai utilisée. WebDriver? Je ne l'ai même pas essayé. Je ne sais pas si c'est possible, je n'avais pas besoin de python / C # / Java, mais j'avais besoin de JS / TS avec le dernier nœud et la dernière API de navigateur, donc les fonctionnalités de vol peuvent provenir des dernières spécifications.
Pourquoi les modules ES6? La prise en charge de WebGL et ES6 dans les navigateurs est à peu près la même. Et avec des modules groupés ou non, laissez l'utilisateur décider, vous pouvez simplement collecter les deux versions. Mais il s'avère que pour les tests unitaires, il est très pratique d'utiliser la version avec les modules, car les sourcemaps sont extraits très simplement, et après cela, vous pouvez exécuter les tests sans aucun geste supplémentaire dans le nœud ou dans le navigateur. En les exécutant en marionnettiste, E2E avec une couverture de code est presque gratuit. Un script avec une cible dans ES6 était probablement nécessaire, mais sur un petit projet couvert de tests, le js normal fonctionnera également.
Donc, assez d'introductions, j'ai mis puppeteer
et puppeteer-to-istanbul
dans le projet et écrit un tel wrapper
Qui peut être exécuté avec le node --experimental-modules --no-warnings ./test/puppeteer.js
commande node --experimental-modules --no-warnings ./test/puppeteer.js
avec un noeud 11+, ou même sans drapeaux sur le noeud 13.2+. Bien sûr, vous pouvez utiliser require
, alors ... Mais pourquoi? Il s'agit généralement d'un backend, ici le support client n'est même pas nécessaire! Le code suivant de package.json
nous permet de personnaliser les téléchargements HEADLESS dans la console et dans le cloud CI si des paramètres différents sont requis pour eux. Dans travs / circle-ci, linux sera probablement installé et vous pouvez y définir des variables d'environnement dans ce format. ouvre concurrently
deux processus dans une console en parallèle.
// package.json { //bla-bla... "type": "module", // this line indicates that we are using es6 modules "scripts": { "test": "node --experimental-modules --no-warnings ./test/puppeteer.js", "server": "http-server -c-1 -p 1234", "not-bad-cmd--dude": "concurrently -k -s first \"npm:test\" \"npm:server\"", "ci": "HEADLESS=true concurrently -k -s first \"npm:test\" \"npm:server\"", } }
Sur la machine locale, après avoir entré la commande npm run server
, le npm run server
http démarre, et sur npm run test
marionnettiste dans une fenêtre distincte, la fenêtre chrome. C'est tout ce que vous devez savoir sur le marionnettiste. Vous trouverez ici d' autres exemples de captures d'écran, d'émulations d'appareils, de zones d'administration, etc. Soit dit en passant, avec le package node_modules
, vous avez installé un chrome séparé dans node_modules
, si vous n'en avez pas besoin, remplacez-le par puppeteer-core
ou puppeteer-firefox
. Il convient de noter que dans l'exemple ci-dessus, nous avons obtenu une couverture de code JS / CSS gratuite qui est écrite dans le dossier .nyc_output, jusqu'à ce que nous nous concentrions sur cela, à ce stade, nous n'avons pas froid ce n'est pas chaud, mais s'il y a quelque chose, c'est là et des statistiques La couverture du test est presque prête à être consultée.

Passons maintenant aux tests eux-mêmes, essayant de choisir où je vais exécuter E2E dans ma petite bibliothèque, je suis tombé sur les graphiques suivants, qui comparaient les performances des frameworks pour les tests. Probablement, le temps d'exécution n'est pas si important, mais lorsque certains Jest les démarrent 10 fois plus lentement, la question «qu'est-ce que c'est et pourquoi est-elle nécessaire» se pose. Le critère de sélection principal était l'exécution d'es6 avec la ligne <script type="module" src="./test.js"></script>
dans la page html. Puisqu'au moment d'écrire mon code, le nœud ne supportait pas encore entièrement ES6 (hier, il a été publié 12.3 dans lequel les drapeaux ont été supprimés). J'ai décidé que si vous prenez le cadre avec les sources sur TS ou ES6 +, il devrait définitivement commencer. En général, vous pouvez probablement prendre une sorte de moka, le déclarer plus haut sur la page et faire référence à la classe déclarée, mais que se passe-t-il si une erreur se produit? En général, vous pouvez nommer votre test de coureur préféré ici. Je dirai simplement que Zora prend en charge le format TAP, ce qui signifie que tout un zoo de mangeurs de TAP convient. Il a la plupart des assertions, il prend en charge async, c'est l'une des plus rapides, écrite en pur ES6 sans dépendances sur le nœud lui-même. Cela me semblait un vrai diamant pour les petits projets.
En conséquence, j'ai obtenu des tests qui fonctionnent à la fois dans le navigateur et dans le nœud. La documentation de Zora contient des instructions complètes sur les assertions et les regroupements de commandes.
Afin de montrer la console sans assemblages, j'ai dû faire un renifleur similaire. La console nue n'est pas très présentable, il serait possible de connecter la sortie TAP quelque part pour guider le marathon. Mais le plus drôle, c'est que les résultats des tests sur votre client peuvent être consultés en ligne . En outre, exactement le même code s'exécute dans CI sur n'importe quel commit.
<!DOCTYPE html> <html lang="en"> <head> </head> <body> <script> const addSniffer = (spyTarget) => function() { spyTarget.apply(window.console, arguments); sniffer([...arguments]); } window.console.log = addSniffer(window.console.log); window.console.error = addSniffer(window.console.error); let screen = document.getElementById('screen'); function sniffer(string) { let screen = document.getElementById("screen"); string.forEach(line => { let div = document.createElement("div"); let text = document.createTextNode(line); div.appendChild(text) screen.appendChild(div); }); } </script> <script type="module" src="./test.js"></script> </body> </html>
Mais ce n'est pas tout, avec des tests prêts à l'emploi, vous pouvez connecter des bots tels que renovate / greenkeeper / dependabot, qui mettraient à jour les dépendances dans votre bibliothèque et effectueraient des validations automatiques, après avoir vérifié l'exactitude des mises à jour. Et travis / github-ci / circle-ci aurait téléchargé une nouvelle version des packages npm.
Par exemple, une telle configuration de renovate effectue des validations automatiques le dimanche et augmente la version
{ "automerge": true, "automergeType": "branch", "bumpVersion": "patch", "schedule": ["on sunday"], "ignorePaths": [".circleci"] }
Et travis, lorsque vous avez vous-même augmenté la version ou un bot, peut automatiquement télécharger le package vers npm. Pour ce faire, créez un compte sur travis-ci.org
, activez f2a comme décrit dans cet article , entrez deux clés secrètes $NPM_EMAIL
et $NPM_TOKEN
et créez une configuration similaire.
language: node_js node_js: '12' script: - npm run ci deploy: provider: npm edge: true email: $NPM_EMAIL api_key: $NPM_TOKEN on: branch: master
Au total, c'est en quelque sorte possible, mais il est difficile de se débarrasser des notifications du github qu'une vulnérabilité est apparue dans une sorte de dépendance: D