¿Prueba de aceptación para la extensión de Markdown?

¡Hola!

Actualmente estoy trabajando en una extensión/plugin de Markdown que añade bastantes etiquetas BBCode, y quiero escribir pruebas de aceptación con QUnit para ellas (me cansé mucho de verificarlas manualmente constantemente, y hay muchas).

Las etiquetas en cuestión son una mezcla de etiquetas simples que solo aplican HTML y etiquetas complejas que tienen manejadores de eventos adjuntos. Por lo tanto, necesito probar tanto el HTML generado como los manejadores de eventos.

He encontrado varias pruebas de aceptación para extensiones de Markdown (específicamente local-dates-composer-test.js.es6, spoiler-button-test.js-es6, checklist-test.js.es6 y pretty-text-test.js), que he utilizado como referencia. Estas se pueden dividir ampliamente en dos formas de realizar la prueba:

  1. Simular la apertura del sitio, crear un nuevo tema y escribir texto dentro del editor, obteniendo la salida mediante un selector en el DOM. (local-dates-composer-test.js.es6, spoiler-button-test.js-es6)
  2. Crear una instancia de Pretty Text para procesar el texto al instante y comparar el HTML resultante. (checklist-test.js.es6, pretty-text-test.js) (checklist parece crear también una instancia del modelo Post para probar el manejo de eventos, y en general parece estar probando el inicializador).

He probado ambos métodos y he tenido más o menos éxito. El primer método es bastante directo y pude obtener lo que quería, aunque a costa de un tiempo mayor que el segundo. Con el segundo método pude hacerlo con éxito y con un tiempo de prueba mucho más rápido, pero estoy obteniendo un error extraño.

Aquí están mis códigos y resultados:

Método 1: Simular la apertura del sitio
import { acceptance, queryAll } from "discourse/tests/helpers/qunit-helpers";

QUnit.assert.cooked = async function (input, expected, message) {
  await fillIn(".d-editor-input", input);
  const actual = queryAll(".d-editor-preview")[0].innerHTML;
  this.pushResult({
    result: actual === expected.replace(/\/>/g, ">"),
    actual,
    expected,
    message,
  });
};

acceptance("Método 1", function (needs) {
  needs.user();
  test("procesamiento mediante el sitio", async function (assert) {
    await visit("/");
    await click("#create-topic");

    assert.cooked("hello world", "<p>hello world</p>", "esta prueba funciona");
  });
});

Método 2: Crear una instancia de Pretty Text
import { acceptance} from "discourse/tests/helpers/qunit-helpers";
import { cookAsync } from "discourse/lib/text";

acceptance("Método 2", function (needs) {
  needs.user();
  test("procesamiento usando cookAsync", async function (assert) {
    const cooked = await cookAsync("hello world", {});
    assert.equal(cooked, "<p>hello world</p>", "esta prueba también funciona");
  });
});

Por ahora, solo están probando un procesamiento simple del texto “hello world”. Lo he probado con mis propias etiquetas personalizadas y funcionan correctamente.

Creo que me falta algo en el método 2, ya que el error es afterEach failed ....: this.keyTrapper is null. De todos modos, ambos métodos funcionan, y puedo ver que para pruebas simples del HTML debo usar el método 2, y para pruebas que impliquen manejo de eventos, debo usar el método 1.

Dado que muchas de mis etiquetas son solo HTML simple, quiero usar el método 2 junto con el método 1 durante las pruebas para ahorrar tiempo. Me gustaría saber qué me falta que está causando ese error, o si hay una forma aún mejor de escribir estas pruebas en general.

Puedes ver cómo se hace en un plugin oficial similar

Pero eso no está usando QUnit.

La razón es que creo que la lógica se ejecuta en el backend, por cierto.

Sería genial simular eso en el frontend.

Por cierto, he migrado personalmente el plugin BBCode a un componente de tema, pero no lo he publicado exactamente porque se pierden todas las pruebas.