Jsdom: Validación de formulario HTML5

Creado en 14 dic. 2012  ·  9Comentarios  ·  Fuente: jsdom/jsdom

JSDOM actualmente no maneja la validación de formularios HTML5 y, en particular, la API checkValidity.

Esto es necesario para probar con precisión las aplicaciones modernas que utilizan formularios HTML5.

Me pregunto si sería posible agregar este soporte usando http://www.thecssninja.com/javascript/h5f como punto de partida. H5F es una corrección de compatibilidad del navegador para agregar soporte de formularios HTML5 a los navegadores que no los admiten. Aparte, me encantaría agregar este comportamiento yo mismo si alguien me puede indicar la mejor manera de hacerlo.

feature html living standard needs tests

Comentario más útil

:+1: Sería una gran característica.

Todos 9 comentarios

Estoy de acuerdo en que esto sería bueno y es importante. Sin embargo, va a ser toda una empresa.

Lo más importante que esto necesita es un conjunto de pruebas sólido. Si observa las pautas de Contributing.md, hay algunos consejos sobre dónde encontrarlos o, en su defecto, qué listas de correo consultar. Si puede desenterrarlos, creo que tenemos una oportunidad de implementar esto, especialmente como señala al usar H5F como punto de partida.

La única otra parte importante de la implementación real es que no tenemos una carpeta "nivel 4" o "html5" adecuada para implementar cosas más allá del nivel 3 del DOM. Pero eso es algo que hemos necesitado por un tiempo, así que lo intentaré para ponerme a ello pronto.

:+1: Sería una gran característica.

En este momento, estoy agregando https://github.com/hyperform/hyperform como polyfill después de la configuración de jsdom. Funciona muy bien.

¡Hurra! Soy el autor de Hyperform. Y por suerte, ya uso JSDom para configurar un entorno de prueba .

La parte que podría ser interesante para los mantenedores de JSDom: jugué con el uso de Hyperform dentro de JSDom, también, para cubrir las pruebas de plataforma web apropiadas:

$ git diff test/web-platform-tests/create-jsdom.js
diff --git a/test/web-platform-tests/create-jsdom.js b/test/web-platform-tests/create-jsdom.js
index 7009df7..9edcb16 100644
--- a/test/web-platform-tests/create-jsdom.js
+++ b/test/web-platform-tests/create-jsdom.js
@@ -1,5 +1,6 @@
 "use strict";
 const jsdom = require("../..");
+const hyperform = require("hyperform");
 const nodeResolverPromise = require("../util").nodeResolverPromise;

 const globalPool = { maxSockets: 6 };
@@ -35,6 +36,9 @@ module.exports = (urlPrefix, testPath) => {

   return created
   .then(window => {
+    global.window = window;
+    global.document = window.document;
+    hyperform(window);
     return new Promise((resolve, reject) => {
       const errors = [];

y descomentar en test/web-platform-tests/index.js las pruebas "html/semantics/forms/constraints/*.html" .

Desafortunadamente, solo obtuve un par de casos de prueba para volverse verdes. Pero si está interesado en agregar (de cualquier manera) las características de Hyperform a JSDom, trabajaría un poco más en

a) lograr que esas pruebas pasen, y
b) proporcionar una versión o configuración de Hyperform, que excluye la API de alto nivel

FWIW, estoy bastante interesado en esto; Estoy trabajando en un componente de Vue que representa un formulario basado en un esquema JSON y se basa en la API de Validez para generar un estado de validación al momento del envío. Mis pruebas unitarias se ejecutan con Jest (que usa JSDOM bajo el capó), y a partir de ahora no puedo probar esta parte.

@Boldewyn si tiene alguna sugerencia con respecto a mi caso, con gusto la aceptaré. Tal vez podría brindar algo de ayuda para implementar esto también, si se me da alguna orientación para comenzar :)

Editar: utilicé la solución de @EricHenry a continuación, y funcionó. Solo tuve que configurar checkValidity para HTMLInputElement , HTMLSelectElement y HTMLTextAreaElement también (y en realidad no necesitaba jugar con HTMLFormElement ). ¡Salud!

Para cualquiera que tenga este problema al probar los componentes de React usando Jest y Enzyme, pude polillenar JSDOM usando el paquete de hiperforma mencionado anteriormente por @fernandopasik y @Boldewyn

En su archivo de prueba, puede hacer lo siguiente después de instalar hyperform.

import * as hyperform from 'hyperform';

var global = global;

const defineValidity = {
  get() {
    return hyperform.ValidityState(this);
  },
  configurable: true
};

global.HTMLFormElement.prototype.checkValidity = function() {
  return hyperform.checkValidity(this);
};

Object.defineProperty(global.HTMLFormElement.prototype, 'validity', defineValidity);
Object.defineProperty(global.HTMLInputElement.prototype, 'validity', defineValidity);
Object.defineProperty(global.HTMLSelectElement.prototype, 'validity', defineValidity);
Object.defineProperty(global.HTMLTextAreaElement.prototype, 'validity', defineValidity);

puede seguir el mismo método para cualquier otro HTMLElement que necesite modificar o cualquier otro atributo que necesite polillenar.

PR #2142 implementa la API de restricción completa sin polifills

Los documentos de Jest sugieren métodos de simulación que no están implementados en JSDOM . Creo que esta es una solución más limpia que contaminar su entorno debido a las pruebas.

En mi caso específico, necesitaba validar un formulario y luego inspeccionar el classList del formulario en busca de la presencia de una determinada clase, cuya presencia me informaría sobre la validez del formulario.

Mi solución fue burlarme de las propiedades del formulario, por ejemplo, burlarme de la implementación nativa de DOMTokenList para la propiedad classList dentro

beforeAll(() => {
    window.DOMTokenList = jest.fn().mockImplementation(() => {
        return {
            list: [],
            remove: jest.fn().mockImplementation(function (item) {
                const idx = this.list.indexOf(item);

                if (idx > -1) {
                    this.list.splice(idx, 1)
                }
            }),
            add: jest.fn().mockImplementation(function (item) {
                this.list.push(item);
            }),
            contains: jest.fn().mockImplementation(function (item) {
                return this.list.indexOf(item) > -1;
            })
        };
    });
})

Luego usé eso para pasar propiedades al controlador de eventos. Puedo acceder al formulario en mi componente de reacción desde el botón Enviar con event.currentTarget.form

let mockClassList = new DOMTokenList();

submitBtn.simulate('click', {
        currentTarget: {
            form: {
                checkValidity: () => false,
                classList: mockClassList
            }
        },
        preventDefault: jest.fn(),
        stopPropagation: jest.fn()
    })

Esto me permite establecer la validez del formulario en falso y verdadero, e inspeccionar el mockClassList para la presencia de la clase was-validated cada vez

    submitBtn.simulate('click', {
        currentTarget: {
            form: {
                checkValidity: () => false,
                classList: mockClassList
            }
        },
        preventDefault: jest.fn(),
        stopPropagation: jest.fn()
    });

    expect(mockClassList.contains('was-validated')).toBeTruthy();

    submitBtn.simulate('click', {
        currentTarget: {
            form: {
                checkValidity: () => true,
                classList: mockClassList
            }
        },
        preventDefault: jest.fn(),
        stopPropagation: jest.fn()
    });

    expect(mockClassList.contains('was-validated')).toBeFalsy();

FYI: estoy usando la representación superficial de Enzyme para esto, el montaje no parece funcionar con esta solución. Sin embargo, me inclino a pensar que la otra sugerencia para los métodos de simulación que no están implementados en JSDOM, cuando el método se ejecuta directamente en la declaración del archivo probado, podría funcionar con la representación del montaje.

Tengo un problema con input.validity que no está disponible para mí en j [email protected] .

// EditableInput.js:
this.inputElement = React.createRef();
...
const input = this.inputElement.current;
console.error('input.validity: ', input.validity);
// EditableInput.test.js run outcome:
    console.error src/components/Form/Input/EditableInput.js:47
      input.validity:  undefined
// yarn.lock:
jsdom@^11.5.1:
  version "11.12.0"
  resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8"
  integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==

Veo que la versión que debería haberse corregido es la 11.8.0, ya que se lanzó el día en que se fusionaron las relaciones públicas con la interfaz de validez. ¿Me estoy perdiendo de algo?

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

cg433n picture cg433n  ·  3Comentarios

kilianc picture kilianc  ·  4Comentarios

lehni picture lehni  ·  4Comentarios

tolmasky picture tolmasky  ·  4Comentarios

Progyan1997 picture Progyan1997  ·  3Comentarios