Maison  >  Article  >  développement back-end  >  Go-DOM - Un navigateur sans tête écrit en Go.

Go-DOM - Un navigateur sans tête écrit en Go.

Linda Hamilton
Linda Hamiltonoriginal
2024-11-07 18:28:02880parcourir

Go-DOM - A headless browser written in Go.

Avoir trop peu de choses à faire aboutit parfois à une idée folle, et cette fois-ci ; il s'agissait d'écrire un navigateur sans tête dans Go, avec une implémentation complète du DOM et un support JavaScript, en embarquant le moteur v8.

Tout a commencé par l'écriture d'une application HTMX, et la nécessité de la tester m'a rendu curieux de savoir s'il existait une implémentation pure Go d'un navigateur sans tête.

La recherche de "passer au navigateur sans tête" n'a abouti qu'à des résultats de recherche parlant de automatisation d'un navigateur sans tête, c'est-à-dire d'utilisation d'un vrai navigateur comme Chrome de Firefox en mode sans tête.

Mais rien en Go pur.

J'ai donc commencé à en construire un.

Pourquoi un navigateur sans tête dans Go ?

Cela peut paraître idiot car écrire un navigateur sans tête ne fonctionnera jamais comme un vrai navigateur ; et en tant que tel, il ne vérifierait pas vraiment que votre application fonctionne correctement dans tous les navigateurs que vous avez décidé de prendre en charge. Cela ne vous permet pas non plus d'obtenir des fonctionnalités intéressantes telles que des captures d'écran de l'application lorsque les choses cessent de fonctionner.

Alors pourquoi alors ?

Le besoin de vitesse !

Pour travailler dans une boucle TDD efficace, les tests doivent être rapides. Une exécution lente des tests décourage le TDD et vous perdez les avantages en termes d'efficacité qu'offre une boucle de rétroaction rapide.

L'utilisation de l'automatisation du navigateur pour ce type de vérification entraîne des frais généraux importants, et ces tests sont généralement écrits après l'écriture du code ; et en tant que tels, ils ne servent plus d’aide à la rédaction de la bonne implémentation ; mais sont réduits à une charge d'entretien après coup ; qui ne détectent qu'occasionnellement un bug avant vos clients payants.

L'objectif est de créer un outil qui prend en charge un processus TDD. Pour être utilisable, il doit être exécuté en cours de processus.

Il doit être écrit en Go.

Des tests moins floconneux

Le fait d'avoir le DOM en cours permet d'écrire de meilleurs wrappers au-dessus du DOM ; ce qui peut aider à fournir une interface moins erratique pour vos tests, comme le fait testing-library pour JavaScript.

Plutôt que de dépendre des noms de classe CSS, des ID d'éléments ou de la structure DOM, vous écrivez vos tests dans un langage centré sur l'utilisateur, comme celui-ci.

Tapez "me@example.com" dans la zone de texte qui porte le libellé "E-mail"

Ou en code hypothétique.

testing.GetElement(Query{
  role: "textbox",
  // The accessibility "name" of a textbox _is_ the label
  name: "Email",
}).type("me@example.com")

Ce test ne se soucie pas de savoir si l'étiquette est implémentée en tant que

Cela dissocie la vérification du comportement des modifications de l'interface utilisateur ; mais cela oblige à ce que le texte « E-mail » soit associé au champ de saisie de manière accessible. Cela couple le test à comment l'utilisateur interagit avec la page ; y compris ceux qui s'appuient sur des lecteurs d'écran pour utiliser votre page.

Cela permet d'atteindre l'aspect le plus important du TDD ; d'écrire des tests couplés à des comportements concrets.1

Bien qu'il soit probablement techniquement possible d'écrire les mêmes tests pour un navigateur hors processus ; l'avantage du code natif est essentiel pour le type d'accès aléatoire au DOM dont vous avez probablement besoin pour ces types d'assistants.

Un exemple : JavaScript

Pour illustrer le type de test, j'utiliserai un exemple similaire de JavaScript ; également une application utilisant HTMX. Le test vérifie un flux de connexion général à partir de la demande d'une page nécessitant une authentification.

C'est un peu long, car j'ai combiné ici tout le code de configuration et d'assistance dans une seule fonction de test.

testing.GetElement(Query{
  role: "textbox",
  // The accessibility "name" of a textbox _is_ the label
  name: "Email",
}).type("me@example.com")

En termes simples, le test effectue les opérations suivantes :

  1. Supprimez la fonction d'authentification, simulant une réponse réussie.
  2. Demander une page nécessitant une authentification
  3. Vérifiez que le navigateur redirige vers la page de connexion et que l'URL du navigateur est mise à jour. 2
  4. Remplissez le formulaire avec les valeurs attendues et soumettez-le.
  5. Vérifiez que le navigateur redirige vers la page initialement demandée et qu'il affiche des informations pour l'utilisateur stupéfait.

En interne, le test démarre un serveur HTTP. Étant donné que cela s'exécute dans le processus de test, la simulation et la suppression de la logique métier sont possibles. Le test utilise jsdom pour communiquer avec le serveur HTTP ; qui analyse à la fois la réponse HTML dans un DOM, mais exécute également un script côté client dans un bac à sable qui a été initialisé, par ex. avec window comme portée globale.3

Cela permet d'écrire des tests de la couche HTTP, où la validation du contenu de la réponse ne suffit pas. Dans ce cas; que la réponse est traitée par HTMX comme prévu.

Mais à part attendre certains événements HTMX, afin de ne pas procéder trop tôt (ou trop tard), le test ne se soucie pas vraiment du HTMX. En fait, si je supprime HTMX du formulaire, en recourant aux redirections classiques, le test réussit toujours.

(Si je supprime complètement la balise HTMX