Skip to content

Instantly share code, notes, and snippets.

@NerOcrO
Last active October 18, 2025 15:05
Show Gist options
  • Select an option

  • Save NerOcrO/b205cd90b3c9c0007da75b314829e76d to your computer and use it in GitHub Desktop.

Select an option

Save NerOcrO/b205cd90b3c9c0007da75b314829e76d to your computer and use it in GitHub Desktop.

Revisions

  1. NerOcrO revised this gist Oct 18, 2025. 1 changed file with 244 additions and 200 deletions.
    444 changes: 244 additions & 200 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -1,218 +1,262 @@
    /* eslint-disable @typescript-eslint/no-require-imports */
    /* eslint-disable @typescript-eslint/no-unsafe-call */
    /* eslint-disable @typescript-eslint/no-unsafe-assignment */
    /* eslint-disable @typescript-eslint/no-unsafe-member-access */
    /* eslint-disable sonarjs/no-nested-template-literals */
    /* eslint-disable testing-library/no-node-access */
    /* eslint-disable no-plusplus */
    it.only('génération programatique d’un test d’affichage HTML', async () => {
    let ulId = 0
    let dlId = 0
    let trId = 0
    let selectId = 0
    let liCounter = 0
    let dtCounter = 0
    let tableCounter = 0
    let trCounter = 0
    let fieldsetCounter = 0
    let result = `
    it.only('test', async () => {
    // GIVEN
    // 1. Le test doit être vert sauf petites pétouilles à modifier
    // 2. Ajouter des "within()" et renommer les constantes
    // 3. Vérifier qu'il n'y a presque plus de screen à la fin
    // 4. Le texte dans une "div" est à rajouter manuellement
    // ==UserScript==
    // @name test_de_semantique
    // @version 2025-10-18
    // @description Création d'un test de sémantique
    // @author NerOcrO
    // @match http://localhost:3000/*
    // @grant none
    // ==/UserScript==
    ;(function() {
    "use strict"

    // WHEN
    await render()
    const html = document.querySelector("main")
    let ulId = 0
    let dlId = 0
    let trId = 0
    let selectId = 0
    let liCounter = 0
    let dtCounter = 0
    let tableCounter = 0
    let trCounter = 0
    let fieldsetCounter = 0
    const test = [
    `it.only("test", async () => {`,
    "// GIVEN",
    "// 1. Ajouter le GIVEN et WHEN",
    "// 2. Le test doit être vert sauf petites pétouilles à modifier",
    "// 3. Ajouter des 'within()' et renommer les constantes",
    "// 4. Vérifier qu'il n'y a presque plus de screen à la fin",
    "// 5. Le texte dans une 'div'/'span' est à rajouter manuellement",
    "",
    "// WHEN",
    "await render()",
    "",
    "// THEN",
    ]
    genererLeTestDeSemantique(html)
    test.push("})")
    console.log(test.join("\n"))

    // THEN`
    selfGeneratedTest(await renderComponent(XXXPresenter, { readModel }))
    console.log(`${result}
    })`)
    function genererLeTestDeSemantique(element) {
    function genererUnIdAleatoire(bytes) {
    const array = new Uint8Array(bytes)
    window.crypto.getRandomValues(array)
    return Array.from(array, byte => byte.toString(16).padStart(2, "0")).join("")
    }

    function selfGeneratedTest(element: HTMLElement): void {
    // eslint-disable-next-line complexity
    element.childNodes.forEach((childNode: HTMLElement) => {
    const contenuDeLaBalise = childNode.textContent.replace(/\n/g, "").trim()
    const balise = childNode.nodeName
    const ariaRole = childNode.role
    element.childNodes.forEach((childNode) => {
    const contenuDeLaBalise = childNode.textContent.replace(/\n/g, "").trim()
    const balise = childNode.nodeName
    const ariaRole = childNode.role

    if (contenuDeLaBalise === null) {
    return
    }
    if (contenuDeLaBalise === null) {
    return
    }

    if (childNode.nodeType !== Node.TEXT_NODE) {
    const id = require('crypto').randomBytes(8).toString('hex')
    if (childNode.nodeType !== Node.TEXT_NODE) {
    const id = genererUnIdAleatoire(8)

    if (balise === 'A') {
    const name = contenuDeLaBalise === '' ? childNode.getAttribute('title') : contenuDeLaBalise
    if (balise === "A") {
    const name = contenuDeLaBalise === "" ? childNode.getAttribute("title") : contenuDeLaBalise

    result += `
    const lien${id} = screen.getByRole('link', { name: '${name}' })
    expect(lien${id}).toHaveAttribute('href', '${childNode.getAttribute('href')}')`
    test.push(
    `const lien${id} = screen.getByRole("link", { name: "${name}" })`,
    `expect(lien${id}).toHaveAttribute("href", "${childNode.getAttribute("href")}")`,
    )

    if (childNode.hasAttribute('title')) {
    result += `
    expect(lien${id}).toOpenInNewTab('${childNode.getAttribute('title')?.replace(' - nouvelle fenêtre', '')}')`
    if (childNode.hasAttribute("title")) {
    test.push(
    `expect(lien${id}).toOpenInNewTab("${
    childNode.getAttribute("title")?.replace(" - nouvelle fenêtre", "")
    }")`,
    )
    }
    } else if (balise === "ARTICLE") {
    test.push(
    `const article${id} = screen.getByRole("article", { name: "${childNode.getAttribute("aria-label")}" })`,
    )
    } else if (balise === "ASIDE") {
    test.push(
    `const complement${id} = screen.getByRole("complementary")`,
    )
    } else if (balise === "BUTTON") {
    if (ariaRole === "tab") {
    let current = "false"
    if (childNode.getAttribute("aria-current") === "page") {
    current = `"page"`
    }
    } else if (balise === 'ARTICLE') {
    result += `
    const article${id} = screen.getByRole('article', { name: '${childNode.getAttribute('aria-label')}' })`
    } else if (balise === 'ASIDE') {
    result += `
    const complement${id} = screen.getByRole('complementary')`
    } else if (balise === 'BUTTON') {
    if (ariaRole === 'tab') {
    let current = 'false'
    if (childNode.getAttribute('aria-current') === 'page') {
    current = "'page'"
    }

    result += `
    const tab${id} = screen.getByRole('tab', { current: ${current}, name: '${contenuDeLaBalise}' })
    expect(tab${id}).toBeInTheDocument()`
    } else {
    let description = ''
    let name = ''
    if (childNode.hasAttribute('title')) {
    description = `description: '${childNode.title}', `
    }
    if (contenuDeLaBalise !== '') {
    name = `name: '${contenuDeLaBalise}'`
    }
    test.push(
    `const tab${id} = screen.getByRole("tab", { current: ${current}, name: "${contenuDeLaBalise}" })`,
    `expect(tab${id}).toBeInTheDocument()`,
    )
    } else {
    let description = ""
    let name = ""
    if (childNode.hasAttribute("title")) {
    description = `description: "${childNode.title}", `
    }
    if (contenuDeLaBalise !== "") {
    name = `name: "${contenuDeLaBalise}"`
    }

    result += `
    const bouton${id} = screen.getByRole('button', { ${description}${name} })
    expect(bouton${id}).toHaveAttribute('type', '${childNode.type}')`
    test.push(
    `const bouton${id} = screen.getByRole("button", { ${description}${name} })`,
    `expect(bouton${id}).toHaveAttribute("type", "${childNode.type}")`,
    )

    if (childNode.disabled === true) {
    result += `
    expect(bouton${id}).toBeDisabled()`
    } else {
    result += `
    expect(bouton${id}).toBeEnabled()`
    }
    if (childNode.disabled === true) {
    test.push(
    `expect(bouton${id}).toBeDisabled()`,
    )
    } else {
    test.push(
    `expect(bouton${id}).toBeEnabled()`,
    )
    }

    if (childNode.hasAttribute('aria-controls')) {
    result += `
    expect(bouton${id}).toHaveAttribute('aria-controls', '${childNode.getAttribute('aria-controls')}')`
    }
    if (childNode.hasAttribute("aria-controls")) {
    test.push(
    `expect(bouton${id}).toHaveAttribute("aria-controls", "${childNode.getAttribute("aria-controls")}")`,
    )
    }
    } else if (balise === 'DD') {
    result += `
    const definition${id} = within(definitions${dlId}[${dtCounter++}]).getByText('${contenuDeLaBalise}')
    expect(definition${id}).toBeInTheDocument()`
    } else if (balise === 'DIALOG') {
    result += `
    const drawer${id} = screen.getByRole('dialog', { hidden: false, name: '${childNode.querySelector('h1')?.textContent.trim()}' })
    expect(drawer${id}).toHaveAttribute('id', '${childNode.id}')`
    } else if (balise === 'DL') {
    dlId += 1
    dtCounter = 0
    result += `
    const liste${dlId} = screen.getByRole('list', { name: '${childNode.getAttribute('aria-label')}' })
    expect(liste${dlId}).toHaveLength(${childNode.querySelectorAll('dt').length})
    const termes${dlId} = within(dl${dlId}).getAllByRole('term')
    const definitions${dlId} = within(dl${dlId}).getAllByRole('definition')`
    } else if (balise === 'DT') {
    result += `
    const terme${id} = within(termes${dlId}[${dtCounter++}]).getByText('${contenuDeLaBalise}')
    expect(terme${id}).toBeInTheDocument()`
    } else if (balise === 'FIELDSET') {
    result += `
    const fieldset${++fieldsetCounter} = within(formulaire).getByRole('group', { name: '${childNode.querySelector('legend')?.textContent.trim()}' })`
    } else if (balise === 'FORM') {
    result += `
    const formulaire = screen.getByRole('form', { name: '${childNode.getAttribute('aria-label')}' })
    // S'il est dans un drawer
    // expect(formulaire).toHaveAttribute('method', 'dialog')`
    } else if (balise === "INPUT") {
    result += `
    const input${id} = within(fieldset${fieldsetCounter}).getByRole('textbox', { name: '${
    }
    } else if (balise === "DD") {
    test.push(
    `const definition${id} = within(definitions${dlId}[${dtCounter++}]).getByText("${contenuDeLaBalise}")`,
    `expect(definition${id}).toBeInTheDocument()`,
    )
    } else if (balise === "DIALOG") {
    test.push(
    `const drawer${id} = screen.getByRole("dialog", { hidden: false, name: "${
    childNode.querySelector("h1")?.textContent.trim()
    }" })`,
    `expect(drawer${id}).toHaveAttribute("id", "${childNode.id}")`,
    )
    } else if (balise === "DL") {
    dlId += 1
    dtCounter = 0
    test.push(
    `const liste${dlId} = screen.getByRole("list", { name: "${childNode.getAttribute("aria-label")}" })`,
    `expect(liste${dlId}).toHaveLength(${childNode.querySelectorAll("dt").length})`,
    `const termes${dlId} = within(dl${dlId}).getAllByRole("term")`,
    `const definitions${dlId} = within(dl${dlId}).getAllByRole("definition")`,
    )
    } else if (balise === "DT") {
    test.push(
    `const terme${id} = within(termes${dlId}[${dtCounter++}]).getByText("${contenuDeLaBalise}")`,
    `expect(terme${id}).toBeInTheDocument()`,
    )
    } else if (balise === "FIELDSET") {
    test.push(
    `const fieldset${++fieldsetCounter} = within(formulaire).getByRole("group", { name: "${
    childNode.querySelector("legend")?.textContent.trim()
    }" })`,
    )
    } else if (balise === "FORM") {
    test.push(
    `const formulaire = screen.getByRole("form", { name: "${childNode.getAttribute("aria-label")}" })`,
    `expect(formulaire).toHaveAttribute("action", "${childNode.getAttribute("action")}")`,
    `expect(formulaire).toHaveAttribute("method", "${childNode.getAttribute("method")}")`,
    `// S'il est dans une modale`,
    `// expect(formulaire).toHaveAttribute("method", "dialog")`,
    )
    } else if (balise === "INPUT") {
    test.push(
    `const input${id} = within(fieldset${fieldsetCounter}).getByRole("textbox", { name: "${
    document.querySelector(`label[for="${childNode.getAttribute("id")}"]`)?.textContent.replace(/\n/g, "")
    .trim()
    }' })
    expect(input${id}).toHaveAttribute('name', '${childNode.getAttribute("name")}')
    expect(input${id}).toHaveAttribute('type', '${childNode.getAttribute("type")}')
    expect(input${id}).toHaveValue('${childNode.getAttribute("value")}')`

    if (childNode.hasAttribute("required")) {
    result += `
    expect(input${id}).toBeRequired()`
    }
    if (childNode.hasAttribute("placeholder")) {
    result += `
    expect(input${id}).toHaveAttribute('placeholder', '${childNode.getAttribute("placeholder")}')`
    }
    } else if (balise === 'H1') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 1, name: '${contenuDeLaBalise}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (balise === 'H2') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 2, name: '${contenuDeLaBalise}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (balise === 'H3') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 3, name: '${contenuDeLaBalise}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (balise === 'HEADER') {
    result += `
    const enTete${id} = screen.getByRole('banner')`
    } else if (balise === 'LI') {
    result += `
    expect(menuItems${ulId}[${liCounter++}].textContent).toBe('${contenuDeLaBalise}')`
    } else if (balise === 'OPTION') {
    result += `
    const option${id} = within(select${selectId}).getByRole('option', { name: '${contenuDeLaBalise}', selected: ${childNode.selected} })
    expect(option${id}).toBeInTheDocument()`
    } else if (balise === 'P') {
    result += `
    const texte${id} = screen.getByText('${contenuDeLaBalise}', { selector: 'p' })
    expect(texte${id}).toBeInTheDocument()`
    } else if (balise === 'SECTION') {
    result += `
    const section${id} = screen.getByRole('region', { name: '${childNode.querySelector(`#${childNode.getAttribute('aria-labelledby')}`)?.textContent}' })`
    } else if (balise === 'SELECT') {
    selectId += 1
    result += `
    const select${selectId} = within(formulaire).getByRole('combobox', { name: '${childNode.labels[0].textContent.trim()}' })
    expect(select${selectId}).${childNode.required === true ? '' : 'not.'}toBeRequired()
    expect(select${selectId}).toHaveLength(${childNode.querySelectorAll('option').length})`
    } else if (balise === "TABLE") {
    trId = -2
    result += `
    const table${++tableCounter} = screen.getByRole('table', { name: '${childNode.caption.textContent.trim()}' })
    const [head${tableCounter}, body${tableCounter}] = within(table${tableCounter}).getAllByRole('rowgroup')
    const rowHead${tableCounter} = within(head${tableCounter}).getByRole('row')
    const columnsHead${tableCounter} = within(rowHead${tableCounter}).getAllByRole('columnheader')
    expect(columnsHead${tableCounter}).toHaveLength(${childNode.querySelectorAll("th").length})
    const rowsBody${tableCounter} = within(body${tableCounter}).getAllByRole('row')`
    } else if (balise === "TD") {
    result += `
    expect(columns${trId}Body${tableCounter}[${trCounter++}].textContent).toBe('${contenuDeLaBalise}')`
    } else if (balise === "TH") {
    result += `
    expect(columnsHead${tableCounter}[${trCounter}].textContent).toBe('${contenuDeLaBalise}')
    expect(columnsHead${tableCounter}[${trCounter++}]).toHaveAttribute('scope', 'col')`
    } else if (balise === "TR") {
    trCounter = 0
    trId += 1
    result += `
    const columns${trId}Body${tableCounter} = within(rowsBody${tableCounter}[${trId}]).getAllByRole('cell')
    expect(columns${trId}Body${tableCounter}).toHaveLength(${childNode.querySelectorAll("td").length})`
    } else if (balise === 'UL') {
    ulId += 1
    liCounter = 0
    result += `
    const menu${ulId} = screen.getByRole('list')
    const menuItems${ulId} = within(menu${ulId}).getAllByRole('listitem')
    expect(menuItems${ulId}).toHaveLength(${childNode.querySelectorAll('li').length})`
    }" })`,
    `expect(input${id}).toHaveAttribute("name", "${childNode.getAttribute("name")}")`,
    `expect(input${id}).toHaveAttribute("type", "${childNode.getAttribute("type")}")`,
    `expect(input${id}).toHaveValue("${childNode.getAttribute("value")}")`,
    )
    if (childNode.hasAttribute("required")) {
    test.push(
    `expect(input${id}).toBeRequired()`,
    )
    }

    selfGeneratedTest(childNode)
    if (childNode.hasAttribute("placeholder")) {
    test.push(
    `expect(input${id}).toHaveAttribute("placeholder", "${childNode.getAttribute("placeholder")}")`,
    )
    }
    } else if (["H1", "H2", "H3", "H4", "H5", "H6"].includes(balise)) {
    test.push(
    `const titre${id} = screen.getByRole("heading", { level: ${balise[1]}, name: "${contenuDeLaBalise}" })`,
    `expect(titre${id}).toBeInTheDocument()`,
    )
    } else if (balise === "HEADER") {
    test.push(
    `const enTete${id} = screen.getByRole("banner")`,
    )
    } else if (balise === "LI") {
    test.push(
    `expect(menuItems${ulId}[${liCounter++}].textContent).toBe("${contenuDeLaBalise}")`,
    )
    } else if (balise === "OPTION") {
    test.push(
    `const option${id} = within(select${selectId}).getByRole("option", { name: "${contenuDeLaBalise}", selected: ${childNode.selected} })`,
    `expect(option${id}).toBeInTheDocument()`,
    )
    } else if (balise === "P") {
    test.push(
    `const texte${id} = screen.getByText("${contenuDeLaBalise}", { selector: "p" })`,
    `expect(texte${id}).toBeInTheDocument()`,
    )
    } else if (balise === "SECTION") {
    test.push(
    `const section${id} = screen.getByRole("region", { name: "${
    childNode.querySelector(`#${childNode.getAttribute("aria-labelledby")}`)?.textContent
    }" })`,
    )
    } else if (balise === "SELECT") {
    selectId += 1
    test.push(
    `const select${selectId} = within(formulaire).getByRole("combobox", { name: "${
    childNode.labels[0].textContent.trim()
    }" })`,
    `expect(select${selectId}).${childNode.required === true ? "" : "not."}toBeRequired()`,
    `expect(select${selectId}).toHaveLength(${childNode.querySelectorAll("option").length})`,
    )
    } else if (balise === "TABLE") {
    trId = -2
    test.push(
    `const table${++tableCounter} = screen.getByRole("table", { name: "${childNode.caption.textContent.trim()}" })`,
    `const [head${tableCounter}, body${tableCounter}] = within(table${tableCounter}).getAllByRole("rowgroup")`,
    `const rowHead${tableCounter} = within(head${tableCounter}).getByRole("row")`,
    `const columnsHead${tableCounter} = within(rowHead${tableCounter}).getAllByRole("columnheader")`,
    `expect(columnsHead${tableCounter}).toHaveLength(${childNode.querySelectorAll("th").length})`,
    `const rowsBody${tableCounter} = within(body${tableCounter}).getAllByRole("row")`,
    )
    } else if (balise === "TD") {
    test.push(
    `expect(columns${trId}Body${tableCounter}[${trCounter++}].textContent).toBe("${contenuDeLaBalise}")`,
    )
    } else if (balise === "TH") {
    test.push(
    `expect(columnsHead${tableCounter}[${trCounter}].textContent).toBe("${contenuDeLaBalise}")`,
    `expect(columnsHead${tableCounter}[${trCounter++}]).toHaveAttribute("scope", "col")`,
    )
    } else if (balise === "TR") {
    trCounter = 0
    trId += 1
    test.push(
    `const columns${trId}Body${tableCounter} = within(rowsBody${tableCounter}[${trId}]).getAllByRole("cell")`,
    `expect(columns${trId}Body${tableCounter}).toHaveLength(${childNode.querySelectorAll("td").length})`,
    )
    } else if (balise === "UL") {
    ulId += 1
    liCounter = 0
    test.push(
    `const menu${ulId} = screen.getByRole("list")`,
    `const menuItems${ulId} = within(menu${ulId}).getAllByRole("listitem")`,
    `expect(menuItems${ulId}).toHaveLength(${childNode.querySelectorAll("li").length})`,
    )
    }
    })
    }
    })

    genererLeTestDeSemantique(childNode)
    }
    })
    }
    })()
  2. NerOcrO revised this gist Oct 7, 2025. 1 changed file with 6 additions and 6 deletions.
    12 changes: 6 additions & 6 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -129,21 +129,21 @@
    // expect(formulaire).toHaveAttribute('method', 'dialog')`
    } else if (balise === "INPUT") {
    result += `
    const titre${id} = within(fieldset${fieldsetCounter}).getByRole('textbox', { name: '${
    const input${id} = within(fieldset${fieldsetCounter}).getByRole('textbox', { name: '${
    document.querySelector(`label[for="${childNode.getAttribute("id")}"]`)?.textContent.replace(/\n/g, "")
    .trim()
    }' })
    expect(titre${id}).toHaveAttribute('name', '${childNode.getAttribute("name")}')
    expect(titre${id}).toHaveAttribute('type', '${childNode.getAttribute("type")}')
    expect(titre${id}).toHaveValue('${childNode.getAttribute("value")}')`
    expect(input${id}).toHaveAttribute('name', '${childNode.getAttribute("name")}')
    expect(input${id}).toHaveAttribute('type', '${childNode.getAttribute("type")}')
    expect(input${id}).toHaveValue('${childNode.getAttribute("value")}')`

    if (childNode.hasAttribute("required")) {
    result += `
    expect(titre${id}).toBeRequired()`
    expect(input${id}).toBeRequired()`
    }
    if (childNode.hasAttribute("placeholder")) {
    result += `
    expect(titre${id}).toHaveAttribute('placeholder', '${childNode.getAttribute("placeholder")}')`
    expect(input${id}).toHaveAttribute('placeholder', '${childNode.getAttribute("placeholder")}')`
    }
    } else if (balise === 'H1') {
    result += `
  3. NerOcrO revised this gist Oct 7, 2025. 1 changed file with 20 additions and 1 deletion.
    21 changes: 20 additions & 1 deletion test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -14,6 +14,7 @@
    let dtCounter = 0
    let tableCounter = 0
    let trCounter = 0
    let fieldsetCounter = 0
    let result = `
    it.only('test', async () => {
    // GIVEN
    @@ -120,12 +121,30 @@
    expect(terme${id}).toBeInTheDocument()`
    } else if (balise === 'FIELDSET') {
    result += `
    const fieldset = within(formulaire).getByRole('group', { name: '${childNode.querySelector('legend')?.textContent.trim()}' })`
    const fieldset${++fieldsetCounter} = within(formulaire).getByRole('group', { name: '${childNode.querySelector('legend')?.textContent.trim()}' })`
    } else if (balise === 'FORM') {
    result += `
    const formulaire = screen.getByRole('form', { name: '${childNode.getAttribute('aria-label')}' })
    // S'il est dans un drawer
    // expect(formulaire).toHaveAttribute('method', 'dialog')`
    } else if (balise === "INPUT") {
    result += `
    const titre${id} = within(fieldset${fieldsetCounter}).getByRole('textbox', { name: '${
    document.querySelector(`label[for="${childNode.getAttribute("id")}"]`)?.textContent.replace(/\n/g, "")
    .trim()
    }' })
    expect(titre${id}).toHaveAttribute('name', '${childNode.getAttribute("name")}')
    expect(titre${id}).toHaveAttribute('type', '${childNode.getAttribute("type")}')
    expect(titre${id}).toHaveValue('${childNode.getAttribute("value")}')`

    if (childNode.hasAttribute("required")) {
    result += `
    expect(titre${id}).toBeRequired()`
    }
    if (childNode.hasAttribute("placeholder")) {
    result += `
    expect(titre${id}).toHaveAttribute('placeholder', '${childNode.getAttribute("placeholder")}')`
    }
    } else if (balise === 'H1') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 1, name: '${contenuDeLaBalise}' })
  4. NerOcrO revised this gist Oct 3, 2025. 1 changed file with 6 additions and 9 deletions.
    15 changes: 6 additions & 9 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -162,7 +162,7 @@
    expect(select${selectId}).${childNode.required === true ? '' : 'not.'}toBeRequired()
    expect(select${selectId}).toHaveLength(${childNode.querySelectorAll('option').length})`
    } else if (balise === "TABLE") {
    trId = 0
    trId = -2
    result += `
    const table${++tableCounter} = screen.getByRole('table', { name: '${childNode.caption.textContent.trim()}' })
    const [head${tableCounter}, body${tableCounter}] = within(table${tableCounter}).getAllByRole('rowgroup')
    @@ -172,20 +172,17 @@
    const rowsBody${tableCounter} = within(body${tableCounter}).getAllByRole('row')`
    } else if (balise === "TD") {
    result += `
    expect(columns${trId}Body[${trCounter++}].textContent).toBe('${contenuDeLaBalise}')`
    expect(columns${trId}Body${tableCounter}[${trCounter++}].textContent).toBe('${contenuDeLaBalise}')`
    } else if (balise === "TH") {
    result += `
    expect(columnsHead${tableCounter}[${trCounter}].textContent).toBe('${contenuDeLaBalise}')
    expect(columnsHead${tableCounter}[${trCounter++}]).toHaveAttribute('scope', 'col')`
    } else if (balise === "TR") {
    trCounter = 0

    if (childNode.childNodes[0].nodeName === "TD") {
    trId += 1
    result += `
    const columns${trId}Body = within(rowsBody${tableCounter}[${trId}]).getAllByRole('cell')
    expect(columns${trId}Body).toHaveLength(${childNode.querySelectorAll("td").length})`
    }
    trId += 1
    result += `
    const columns${trId}Body${tableCounter} = within(rowsBody${tableCounter}[${trId}]).getAllByRole('cell')
    expect(columns${trId}Body${tableCounter}).toHaveLength(${childNode.querySelectorAll("td").length})`
    } else if (balise === 'UL') {
    ulId += 1
    liCounter = 0
  5. NerOcrO revised this gist Oct 3, 2025. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -104,7 +104,7 @@
    expect(definition${id}).toBeInTheDocument()`
    } else if (balise === 'DIALOG') {
    result += `
    const drawer${id} = screen.getByRole('dialog', { hidden: false, name: '${childNode.querySelector('h1')?.textContent}' })
    const drawer${id} = screen.getByRole('dialog', { hidden: false, name: '${childNode.querySelector('h1')?.textContent.trim()}' })
    expect(drawer${id}).toHaveAttribute('id', '${childNode.id}')`
    } else if (balise === 'DL') {
    dlId += 1
    @@ -158,13 +158,13 @@
    } else if (balise === 'SELECT') {
    selectId += 1
    result += `
    const select${selectId} = within(formulaire).getByRole('combobox', { name: '${childNode.labels[0].textContent}' })
    const select${selectId} = within(formulaire).getByRole('combobox', { name: '${childNode.labels[0].textContent.trim()}' })
    expect(select${selectId}).${childNode.required === true ? '' : 'not.'}toBeRequired()
    expect(select${selectId}).toHaveLength(${childNode.querySelectorAll('option').length})`
    } else if (balise === "TABLE") {
    trId = 0
    result += `
    const table${++tableCounter} = screen.getByRole('table', { name: '${childNode.caption.textContent}' })
    const table${++tableCounter} = screen.getByRole('table', { name: '${childNode.caption.textContent.trim()}' })
    const [head${tableCounter}, body${tableCounter}] = within(table${tableCounter}).getAllByRole('rowgroup')
    const rowHead${tableCounter} = within(head${tableCounter}).getByRole('row')
    const columnsHead${tableCounter} = within(rowHead${tableCounter}).getAllByRole('columnheader')
  6. NerOcrO revised this gist Oct 3, 2025. 1 changed file with 16 additions and 15 deletions.
    31 changes: 16 additions & 15 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -12,6 +12,7 @@
    let selectId = 0
    let liCounter = 0
    let dtCounter = 0
    let tableCounter = 0
    let trCounter = 0
    let result = `
    it.only('test', async () => {
    @@ -160,30 +161,30 @@
    const select${selectId} = within(formulaire).getByRole('combobox', { name: '${childNode.labels[0].textContent}' })
    expect(select${selectId}).${childNode.required === true ? '' : 'not.'}toBeRequired()
    expect(select${selectId}).toHaveLength(${childNode.querySelectorAll('option').length})`
    } else if (balise === 'TABLE') {
    } else if (balise === "TABLE") {
    trId = 0
    result += `
    const table = screen.getByRole('table', { name: '${childNode.caption.textContent}' })
    const [head, body] = within(table).getAllByRole('rowgroup')
    const rowHead = within(head).getByRole('row')
    const columnsHead = within(rowHead).getAllByRole('columnheader')
    expect(columnsHead).toHaveLength(${childNode.querySelectorAll('th').length})
    const rowsBody = within(body).getAllByRole('row')`
    } else if (balise === 'TD') {
    const table${++tableCounter} = screen.getByRole('table', { name: '${childNode.caption.textContent}' })
    const [head${tableCounter}, body${tableCounter}] = within(table${tableCounter}).getAllByRole('rowgroup')
    const rowHead${tableCounter} = within(head${tableCounter}).getByRole('row')
    const columnsHead${tableCounter} = within(rowHead${tableCounter}).getAllByRole('columnheader')
    expect(columnsHead${tableCounter}).toHaveLength(${childNode.querySelectorAll("th").length})
    const rowsBody${tableCounter} = within(body${tableCounter}).getAllByRole('row')`
    } else if (balise === "TD") {
    result += `
    expect(columns${trId}Body[${trCounter++}].textContent).toBe('${contenuDeLaBalise}')`
    } else if (balise === 'TH') {
    } else if (balise === "TH") {
    result += `
    expect(columnsHead[${trCounter}].textContent).toBe('${contenuDeLaBalise}')
    expect(columnsHead[${trCounter++}]).toHaveAttribute('scope', 'col')`
    } else if (balise === 'TR') {
    expect(columnsHead${tableCounter}[${trCounter}].textContent).toBe('${contenuDeLaBalise}')
    expect(columnsHead${tableCounter}[${trCounter++}]).toHaveAttribute('scope', 'col')`
    } else if (balise === "TR") {
    trCounter = 0

    if (childNode.childNodes[0].nodeName === 'TD') {
    if (childNode.childNodes[0].nodeName === "TD") {
    trId += 1
    result += `
    const columns${trId}Body = within(rowsBody[${trId}]).getAllByRole('cell')
    expect(columns${trId}Body).toHaveLength(${childNode.querySelectorAll('td').length})`
    const columns${trId}Body = within(rowsBody${tableCounter}[${trId}]).getAllByRole('cell')
    expect(columns${trId}Body).toHaveLength(${childNode.querySelectorAll("td").length})`
    }
    } else if (balise === 'UL') {
    ulId += 1
  7. NerOcrO revised this gist Oct 3, 2025. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -8,7 +8,7 @@
    it.only('génération programatique d’un test d’affichage HTML', async () => {
    let ulId = 0
    let dlId = 0
    let trId = -1
    let trId = 0
    let selectId = 0
    let liCounter = 0
    let dtCounter = 0
    @@ -32,7 +32,7 @@
    function selfGeneratedTest(element: HTMLElement): void {
    // eslint-disable-next-line complexity
    element.childNodes.forEach((childNode: HTMLElement) => {
    const contenuDeLaBalise = childNode.textContent.trim()
    const contenuDeLaBalise = childNode.textContent.replace(/\n/g, "").trim()
    const balise = childNode.nodeName
    const ariaRole = childNode.role

    @@ -161,7 +161,7 @@
    expect(select${selectId}).${childNode.required === true ? '' : 'not.'}toBeRequired()
    expect(select${selectId}).toHaveLength(${childNode.querySelectorAll('option').length})`
    } else if (balise === 'TABLE') {
    trId = -1
    trId = 0
    result += `
    const table = screen.getByRole('table', { name: '${childNode.caption.textContent}' })
    const [head, body] = within(table).getAllByRole('rowgroup')
  8. NerOcrO revised this gist Oct 2, 2025. 1 changed file with 2 additions and 6 deletions.
    8 changes: 2 additions & 6 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -6,10 +6,6 @@
    /* eslint-disable testing-library/no-node-access */
    /* eslint-disable no-plusplus */
    it.only('génération programatique d’un test d’affichage HTML', async () => {
    //const { container } = render()
    const readModel = { }
    const container = await renderComponent(XXXPresenter, { readModel })

    let ulId = 0
    let dlId = 0
    let trId = -1
    @@ -29,9 +25,9 @@
    await render()
    // THEN`
    selfGeneratedTest(container)
    selfGeneratedTest(await renderComponent(XXXPresenter, { readModel }))
    console.log(`${result}
    })`)
    })`)

    function selfGeneratedTest(element: HTMLElement): void {
    // eslint-disable-next-line complexity
  9. NerOcrO revised this gist Oct 2, 2025. 1 changed file with 4 additions and 3 deletions.
    7 changes: 4 additions & 3 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -18,19 +18,20 @@
    let dtCounter = 0
    let trCounter = 0
    let result = `
    it.only('test', () => {
    it.only('test', async () => {
    // GIVEN
    // 1. Le test doit être vert sauf petites pétouilles à modifier
    // 2. Ajouter des "within()" et renommer les constantes
    // 3. Vérifier qu'il n'y a presque plus de screen à la fin
    // 4. Le texte dans une "div" est à rajouter manuellement
    // WHEN
    render()
    await render()
    // THEN`
    selfGeneratedTest(container)
    console.log(`${result}})`)
    console.log(`${result}
    })`)

    function selfGeneratedTest(element: HTMLElement): void {
    // eslint-disable-next-line complexity
  10. NerOcrO revised this gist Oct 2, 2025. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,7 @@
    /* eslint-disable sonarjs/no-nested-template-literals */
    /* eslint-disable testing-library/no-node-access */
    /* eslint-disable no-plusplus */
    it.only('génération programatique d’un test d’affichage HTML', () => {
    it.only('génération programatique d’un test d’affichage HTML', async () => {
    //const { container } = render()
    const readModel = { }
    const container = await renderComponent(XXXPresenter, { readModel })
    @@ -122,7 +122,7 @@
    expect(terme${id}).toBeInTheDocument()`
    } else if (balise === 'FIELDSET') {
    result += `
    const fieldset = within(formulaire).getByRole('group', { name: '${childNode.querySelector('legend')?.textContent}' })`
    const fieldset = within(formulaire).getByRole('group', { name: '${childNode.querySelector('legend')?.textContent.trim()}' })`
    } else if (balise === 'FORM') {
    result += `
    const formulaire = screen.getByRole('form', { name: '${childNode.getAttribute('aria-label')}' })
  11. NerOcrO revised this gist Oct 1, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -35,7 +35,7 @@
    function selfGeneratedTest(element: HTMLElement): void {
    // eslint-disable-next-line complexity
    element.childNodes.forEach((childNode: HTMLElement) => {
    const contenuDeLaBalise = childNode.textContent
    const contenuDeLaBalise = childNode.textContent.trim()
    const balise = childNode.nodeName
    const ariaRole = childNode.role

  12. NerOcrO revised this gist Oct 1, 2025. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -6,7 +6,9 @@
    /* eslint-disable testing-library/no-node-access */
    /* eslint-disable no-plusplus */
    it.only('génération programatique d’un test d’affichage HTML', () => {
    const { container } = render()
    //const { container } = render()
    const readModel = { }
    const container = await renderComponent(XXXPresenter, { readModel })

    let ulId = 0
    let dlId = 0
  13. NerOcrO revised this gist Mar 21, 2025. 1 changed file with 76 additions and 60 deletions.
    136 changes: 76 additions & 60 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -2,6 +2,7 @@
    /* eslint-disable @typescript-eslint/no-unsafe-call */
    /* eslint-disable @typescript-eslint/no-unsafe-assignment */
    /* eslint-disable @typescript-eslint/no-unsafe-member-access */
    /* eslint-disable sonarjs/no-nested-template-literals */
    /* eslint-disable testing-library/no-node-access */
    /* eslint-disable no-plusplus */
    it.only('génération programatique d’un test d’affichage HTML', () => {
    @@ -15,17 +16,17 @@
    let dtCounter = 0
    let trCounter = 0
    let result = `
    it.only('test', () => {
    // GIVEN
    // 1. Le test doit être vert sauf petites pétouilles à modifier
    // 2. Ajouter des "within()" et renommer les constantes
    // 3. Vérifier qu'il n'y a presque plus de screen à la fin
    // 4. Le texte dans une "div" est à rajouter manuellement
    it.only('test', () => {
    // GIVEN
    // 1. Le test doit être vert sauf petites pétouilles à modifier
    // 2. Ajouter des "within()" et renommer les constantes
    // 3. Vérifier qu'il n'y a presque plus de screen à la fin
    // 4. Le texte dans une "div" est à rajouter manuellement
    // WHEN
    render()
    // WHEN
    render()
    // THEN`
    // THEN`
    selfGeneratedTest(container)
    console.log(`${result}})`)

    @@ -47,19 +48,19 @@ it.only('test', () => {
    const name = contenuDeLaBalise === '' ? childNode.getAttribute('title') : contenuDeLaBalise

    result += `
    const lien${id} = screen.getByRole('link', { name: '${name}' })
    expect(lien${id}).toHaveAttribute('href', '${childNode.getAttribute('href')}')`
    const lien${id} = screen.getByRole('link', { name: '${name}' })
    expect(lien${id}).toHaveAttribute('href', '${childNode.getAttribute('href')}')`

    if (childNode.hasAttribute('title')) {
    result += `
    expect(lien${id}).toOpenInNewTab('${childNode.getAttribute('title')?.replace(' - nouvelle fenêtre', '')}')`
    expect(lien${id}).toOpenInNewTab('${childNode.getAttribute('title')?.replace(' - nouvelle fenêtre', '')}')`
    }
    } else if (balise === 'ARTICLE') {
    result += `
    const article${id} = screen.getByRole('article', { name: '${childNode.getAttribute('aria-label')}' })`
    const article${id} = screen.getByRole('article', { name: '${childNode.getAttribute('aria-label')}' })`
    } else if (balise === 'ASIDE') {
    result += `
    const complement${id} = screen.getByRole('complementary')`
    const complement${id} = screen.getByRole('complementary')`
    } else if (balise === 'BUTTON') {
    if (ariaRole === 'tab') {
    let current = 'false'
    @@ -68,8 +69,8 @@ const complement${id} = screen.getByRole('complementary')`
    }

    result += `
    const tab${id} = screen.getByRole('tab', { current: ${current}, name: '${contenuDeLaBalise}' })
    expect(tab${id}).toBeInTheDocument()`
    const tab${id} = screen.getByRole('tab', { current: ${current}, name: '${contenuDeLaBalise}' })
    expect(tab${id}).toBeInTheDocument()`
    } else {
    let description = ''
    let name = ''
    @@ -81,102 +82,117 @@ expect(tab${id}).toBeInTheDocument()`
    }

    result += `
    const bouton${id} = screen.getByRole('button', { ${description}${name} })
    expect(bouton${id}).toHaveAttribute('type', 'button')`
    const bouton${id} = screen.getByRole('button', { ${description}${name} })
    expect(bouton${id}).toHaveAttribute('type', '${childNode.type}')`

    if (childNode.disabled === true) {
    result += `
    expect(bouton${id}).toBeDisabled()`
    } else {
    result += `
    expect(bouton${id}).toBeEnabled()`
    }

    if (childNode.hasAttribute('aria-controls')) {
    result += `
    expect(bouton${id}).toHaveAttribute('aria-controls', '${childNode.getAttribute('aria-controls')}')`
    expect(bouton${id}).toHaveAttribute('aria-controls', '${childNode.getAttribute('aria-controls')}')`
    }
    }
    } else if (balise === 'DD') {
    result += `
    const definition${id} = within(definitions${dlId}[${dtCounter++}]).getByText('${contenuDeLaBalise}')
    expect(definition${id}).toBeInTheDocument()`
    const definition${id} = within(definitions${dlId}[${dtCounter++}]).getByText('${contenuDeLaBalise}')
    expect(definition${id}).toBeInTheDocument()`
    } else if (balise === 'DIALOG') {
    result += `
    const drawer${id} = screen.getByRole('dialog', { hidden: false, name: '${childNode.querySelector('h1')?.textContent}' })
    expect(drawer${id}).toHaveAttribute('id', '${childNode.id}')`
    } else if (balise === 'DL') {
    dlId += 1
    dtCounter = 0
    result += `
    const liste${dlId} = screen.getByRole('list', { name: '${childNode.getAttribute('aria-label')}' })
    expect(liste${dlId}).toHaveLength(${childNode.querySelectorAll('dt').length})
    const termes${dlId} = within(dl${dlId}).getAllByRole('term')
    const definitions${dlId} = within(dl${dlId}).getAllByRole('definition')`
    const liste${dlId} = screen.getByRole('list', { name: '${childNode.getAttribute('aria-label')}' })
    expect(liste${dlId}).toHaveLength(${childNode.querySelectorAll('dt').length})
    const termes${dlId} = within(dl${dlId}).getAllByRole('term')
    const definitions${dlId} = within(dl${dlId}).getAllByRole('definition')`
    } else if (balise === 'DT') {
    result += `
    const terme${id} = within(termes${dlId}[${dtCounter++}]).getByText('${contenuDeLaBalise}')
    expect(terme${id}).toBeInTheDocument()`
    const terme${id} = within(termes${dlId}[${dtCounter++}]).getByText('${contenuDeLaBalise}')
    expect(terme${id}).toBeInTheDocument()`
    } else if (balise === 'FIELDSET') {
    result += `
    const fieldset = within(formulaire).getByRole('group', { name: '${childNode.querySelector('legend')?.textContent}' })`
    } else if (balise === 'FORM') {
    result += `
    const formulaire = screen.getByRole('form', { name: '${childNode.querySelector(`#${childNode.getAttribute('aria-label')}`)}' })
    // S'il est dans un drawer
    // expect(formulaire).toHaveAttribute('method', 'dialog')`
    const formulaire = screen.getByRole('form', { name: '${childNode.getAttribute('aria-label')}' })
    // S'il est dans un drawer
    // expect(formulaire).toHaveAttribute('method', 'dialog')`
    } else if (balise === 'H1') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 1, name: '${contenuDeLaBalise}' })
    expect(titre${id}).toBeInTheDocument()`
    const titre${id} = screen.getByRole('heading', { level: 1, name: '${contenuDeLaBalise}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (balise === 'H2') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 2, name: '${contenuDeLaBalise}' })
    expect(titre${id}).toBeInTheDocument()`
    const titre${id} = screen.getByRole('heading', { level: 2, name: '${contenuDeLaBalise}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (balise === 'H3') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 3, name: '${contenuDeLaBalise}' })
    expect(titre${id}).toBeInTheDocument()`
    const titre${id} = screen.getByRole('heading', { level: 3, name: '${contenuDeLaBalise}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (balise === 'HEADER') {
    result += `
    const enTete${id} = screen.getByRole('banner')`
    const enTete${id} = screen.getByRole('banner')`
    } else if (balise === 'LI') {
    result += `
    expect(menuItems${ulId}[${liCounter++}].textContent).toBe('${contenuDeLaBalise}')`
    expect(menuItems${ulId}[${liCounter++}].textContent).toBe('${contenuDeLaBalise}')`
    } else if (balise === 'OPTION') {
    result += `
    const option${id} = within(select${selectId}).getByRole('option', { name: '${contenuDeLaBalise}', selected: ${childNode.selected} })
    expect(option${id}).toBeInTheDocument()`
    const option${id} = within(select${selectId}).getByRole('option', { name: '${contenuDeLaBalise}', selected: ${childNode.selected} })
    expect(option${id}).toBeInTheDocument()`
    } else if (balise === 'P') {
    result += `
    const texte${id} = screen.getByText('${contenuDeLaBalise}', { selector: 'p' })
    expect(texte${id}).toBeInTheDocument()`
    const texte${id} = screen.getByText('${contenuDeLaBalise}', { selector: 'p' })
    expect(texte${id}).toBeInTheDocument()`
    } else if (balise === 'SECTION') {
    result += `
    const section${id} = screen.getByRole('region', { name: '${childNode.querySelector(`#${childNode.getAttribute('aria-labelledby')}`)?.textContent}' })`
    const section${id} = screen.getByRole('region', { name: '${childNode.querySelector(`#${childNode.getAttribute('aria-labelledby')}`)?.textContent}' })`
    } else if (balise === 'SELECT') {
    selectId += 1
    result += `
    const select${selectId} = within(formulaire).getByRole('combobox', { name: '${childNode.labels[0].textContent}' })
    expect(select${selectId}).${childNode.required === true ? '' : 'not.'}toBeRequired()
    expect(select${selectId}).toHaveLength(${childNode.querySelectorAll('option').length})`
    const select${selectId} = within(formulaire).getByRole('combobox', { name: '${childNode.labels[0].textContent}' })
    expect(select${selectId}).${childNode.required === true ? '' : 'not.'}toBeRequired()
    expect(select${selectId}).toHaveLength(${childNode.querySelectorAll('option').length})`
    } else if (balise === 'TABLE') {
    trId = -1
    result += `
    const table = screen.getByRole('table', { name: '${childNode.caption.textContent}' })
    const [head, body] = within(table).getAllByRole('rowgroup')
    const rowHead = within(head).getByRole('row')
    const columnsHead = within(rowHead).getAllByRole('columnheader')
    expect(columnsHead).toHaveLength(${childNode.querySelectorAll('th').length})
    const rowsBody = within(body).getAllByRole('row')`
    const table = screen.getByRole('table', { name: '${childNode.caption.textContent}' })
    const [head, body] = within(table).getAllByRole('rowgroup')
    const rowHead = within(head).getByRole('row')
    const columnsHead = within(rowHead).getAllByRole('columnheader')
    expect(columnsHead).toHaveLength(${childNode.querySelectorAll('th').length})
    const rowsBody = within(body).getAllByRole('row')`
    } else if (balise === 'TD') {
    result += `
    expect(columns${trId}Body[${trCounter++}].textContent).toBe('${contenuDeLaBalise}')`
    expect(columns${trId}Body[${trCounter++}].textContent).toBe('${contenuDeLaBalise}')`
    } else if (balise === 'TH') {
    result += `
    expect(columnsHead[${trCounter}].textContent).toBe('${contenuDeLaBalise}')
    expect(columnsHead[${trCounter++}]).toHaveAttribute('scope', 'col')`
    expect(columnsHead[${trCounter}].textContent).toBe('${contenuDeLaBalise}')
    expect(columnsHead[${trCounter++}]).toHaveAttribute('scope', 'col')`
    } else if (balise === 'TR') {
    trCounter = 0

    if (childNode.childNodes[0].nodeName === 'TD') {
    trId += 1
    result += `
    const columns${trId}Body = within(rowsBody[${trId}]).getAllByRole('cell')
    expect(columns${trId}Body).toHaveLength(${childNode.querySelectorAll('td').length})`
    const columns${trId}Body = within(rowsBody[${trId}]).getAllByRole('cell')
    expect(columns${trId}Body).toHaveLength(${childNode.querySelectorAll('td').length})`
    }
    } else if (balise === 'UL') {
    ulId += 1
    liCounter = 0
    result += `
    const menu${ulId} = screen.getByRole('list')
    const menuItems${ulId} = within(menu${ulId}).getAllByRole('listitem')
    expect(menuItems${ulId}).toHaveLength(${childNode.querySelectorAll('li').length})`
    const menu${ulId} = screen.getByRole('list')
    const menuItems${ulId} = within(menu${ulId}).getAllByRole('listitem')
    expect(menuItems${ulId}).toHaveLength(${childNode.querySelectorAll('li').length})`
    }

    selfGeneratedTest(childNode)
  14. NerOcrO revised this gist Mar 21, 2025. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -112,8 +112,8 @@ const formulaire = screen.getByRole('form', { name: '${childNode.querySelector(`
    // expect(formulaire).toHaveAttribute('method', 'dialog')`
    } else if (balise === 'H1') {
    result += `
    const titre1 = screen.getByRole('heading', { level: 1, name: '${contenuDeLaBalise}' })
    expect(titre1).toBeInTheDocument()`
    const titre${id} = screen.getByRole('heading', { level: 1, name: '${contenuDeLaBalise}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (balise === 'H2') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 2, name: '${contenuDeLaBalise}' })
  15. NerOcrO revised this gist Mar 21, 2025. 1 changed file with 43 additions and 40 deletions.
    83 changes: 43 additions & 40 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -32,15 +32,19 @@ it.only('test', () => {
    function selfGeneratedTest(element: HTMLElement): void {
    // eslint-disable-next-line complexity
    element.childNodes.forEach((childNode: HTMLElement) => {
    if (childNode.textContent === null) {
    const contenuDeLaBalise = childNode.textContent
    const balise = childNode.nodeName
    const ariaRole = childNode.role

    if (contenuDeLaBalise === null) {
    return
    }

    if (childNode.nodeType !== Node.TEXT_NODE) {
    const id = require('crypto').randomBytes(8).toString('hex')

    if (childNode.nodeName === 'A') {
    const name = childNode.textContent === '' ? childNode.getAttribute('title') : childNode.textContent
    if (balise === 'A') {
    const name = contenuDeLaBalise === '' ? childNode.getAttribute('title') : contenuDeLaBalise

    result += `
    const lien${id} = screen.getByRole('link', { name: '${name}' })
    @@ -50,31 +54,30 @@ expect(lien${id}).toHaveAttribute('href', '${childNode.getAttribute('href')}')`
    result += `
    expect(lien${id}).toOpenInNewTab('${childNode.getAttribute('title')?.replace(' - nouvelle fenêtre', '')}')`
    }
    } else if (childNode.nodeName === 'ARTICLE') {
    } else if (balise === 'ARTICLE') {
    result += `
    const article${id} = screen.getByRole('article', { name: '${childNode.getAttribute('aria-label')}' })`
    } else if (childNode.nodeName === 'ASIDE') {
    } else if (balise === 'ASIDE') {
    result += `
    const complement${id} = screen.getByRole('complementary')`
    } else if (childNode.nodeName === 'BUTTON') {
    if (childNode.role === 'tab') {
    if (childNode.role === 'tab') {
    } else if (balise === 'BUTTON') {
    if (ariaRole === 'tab') {
    let current = 'false'
    if (childNode.getAttribute('aria-current') === 'page') {
    current = "'page'"
    }

    result += `
    const tab${id} = screen.getByRole('tab', { current: ${current}, name: '${childNode.textContent}' })
    const tab${id} = screen.getByRole('tab', { current: ${current}, name: '${contenuDeLaBalise}' })
    expect(tab${id}).toBeInTheDocument()`
    } else {
    let description = ''
    let name = ''
    if (childNode.hasAttribute('title')) {
    description = `description: '${childNode.title}', `
    }
    if (childNode.textContent !== '') {
    name = `name: '${childNode.textContent}'`
    if (contenuDeLaBalise !== '') {
    name = `name: '${contenuDeLaBalise}'`
    }

    result += `
    @@ -86,63 +89,63 @@ expect(bouton${id}).toHaveAttribute('type', 'button')`
    expect(bouton${id}).toHaveAttribute('aria-controls', '${childNode.getAttribute('aria-controls')}')`
    }
    }
    } else if (childNode.nodeName === 'DD') {
    } else if (balise === 'DD') {
    result += `
    const definition${id} = within(definitions${dlId}[${dtCounter++}]).getByText('${childNode.textContent}')
    const definition${id} = within(definitions${dlId}[${dtCounter++}]).getByText('${contenuDeLaBalise}')
    expect(definition${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'DL') {
    } else if (balise === 'DL') {
    dlId += 1
    dtCounter = 0
    result += `
    const liste${dlId} = screen.getByRole('list', { name: '${childNode.getAttribute('aria-label')}' })
    expect(liste${dlId}).toHaveLength(${childNode.querySelectorAll('dt').length})
    const termes${dlId} = within(dl${dlId}).getAllByRole('term')
    const definitions${dlId} = within(dl${dlId}).getAllByRole('definition')`
    } else if (childNode.nodeName === 'DT') {
    } else if (balise === 'DT') {
    result += `
    const terme${id} = within(termes${dlId}[${dtCounter++}]).getByText('${childNode.textContent}')
    const terme${id} = within(termes${dlId}[${dtCounter++}]).getByText('${contenuDeLaBalise}')
    expect(terme${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'FORM') {
    } else if (balise === 'FORM') {
    result += `
    const formulaire = screen.getByRole('form', { name: '${childNode.querySelector(`#${childNode.getAttribute('aria-label')}`)}' })
    // S'il est dans un drawer
    // expect(formulaire).toHaveAttribute('method', 'dialog')`
    } else if (childNode.nodeName === 'H1') {
    } else if (balise === 'H1') {
    result += `
    const titre1 = screen.getByRole('heading', { level: 1, name: '${childNode.textContent}' })
    const titre1 = screen.getByRole('heading', { level: 1, name: '${contenuDeLaBalise}' })
    expect(titre1).toBeInTheDocument()`
    } else if (childNode.nodeName === 'H2') {
    } else if (balise === 'H2') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 2, name: '${childNode.textContent}' })
    const titre${id} = screen.getByRole('heading', { level: 2, name: '${contenuDeLaBalise}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'H3') {
    } else if (balise === 'H3') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 3, name: '${childNode.textContent}' })
    const titre${id} = screen.getByRole('heading', { level: 3, name: '${contenuDeLaBalise}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'HEADER') {
    } else if (balise === 'HEADER') {
    result += `
    const enTete${id} = screen.getByRole('banner')`
    } else if (childNode.nodeName === 'LI') {
    } else if (balise === 'LI') {
    result += `
    expect(menuItems${ulId}[${liCounter++}].textContent).toBe('${childNode.textContent}')`
    } else if (childNode.nodeName === 'OPTION') {
    expect(menuItems${ulId}[${liCounter++}].textContent).toBe('${contenuDeLaBalise}')`
    } else if (balise === 'OPTION') {
    result += `
    const option${id} = within(select${selectId}).getByRole('option', { name: '${childNode.textContent}', selected: ${childNode.selected} })
    const option${id} = within(select${selectId}).getByRole('option', { name: '${contenuDeLaBalise}', selected: ${childNode.selected} })
    expect(option${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'P') {
    } else if (balise === 'P') {
    result += `
    const texte${id} = screen.getByText('${childNode.textContent}', { selector: 'p' })
    const texte${id} = screen.getByText('${contenuDeLaBalise}', { selector: 'p' })
    expect(texte${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'SECTION') {
    } else if (balise === 'SECTION') {
    result += `
    const section${id} = screen.getByRole('region', { name: '${childNode.querySelector(`#${childNode.getAttribute('aria-labelledby')}`)?.textContent}' })`
    } else if (childNode.nodeName === 'SELECT') {
    } else if (balise === 'SELECT') {
    selectId += 1
    result += `
    const select${selectId} = within(formulaire).getByRole('combobox', { name: '${childNode.labels[0].textContent}' })
    expect(select${selectId}).${childNode.required === true ? '' : 'not.'}toBeRequired()
    expect(select${selectId}).toHaveLength(${childNode.querySelectorAll('option').length})`
    } else if (childNode.nodeName === 'TABLE') {
    } else if (balise === 'TABLE') {
    trId = -1
    result += `
    const table = screen.getByRole('table', { name: '${childNode.caption.textContent}' })
    @@ -151,14 +154,14 @@ const rowHead = within(head).getByRole('row')
    const columnsHead = within(rowHead).getAllByRole('columnheader')
    expect(columnsHead).toHaveLength(${childNode.querySelectorAll('th').length})
    const rowsBody = within(body).getAllByRole('row')`
    } else if (childNode.nodeName === 'TD') {
    } else if (balise === 'TD') {
    result += `
    expect(columns${trId}Body[${trCounter++}].textContent).toBe('${childNode.textContent}')`
    } else if (childNode.nodeName === 'TH') {
    expect(columns${trId}Body[${trCounter++}].textContent).toBe('${contenuDeLaBalise}')`
    } else if (balise === 'TH') {
    result += `
    expect(columnsHead[${trCounter}].textContent).toBe('${childNode.textContent}')
    expect(columnsHead[${trCounter}].textContent).toBe('${contenuDeLaBalise}')
    expect(columnsHead[${trCounter++}]).toHaveAttribute('scope', 'col')`
    } else if (childNode.nodeName === 'TR') {
    } else if (balise === 'TR') {
    trCounter = 0

    if (childNode.childNodes[0].nodeName === 'TD') {
    @@ -167,7 +170,7 @@ expect(columnsHead[${trCounter++}]).toHaveAttribute('scope', 'col')`
    const columns${trId}Body = within(rowsBody[${trId}]).getAllByRole('cell')
    expect(columns${trId}Body).toHaveLength(${childNode.querySelectorAll('td').length})`
    }
    } else if (childNode.nodeName === 'UL') {
    } else if (balise === 'UL') {
    ulId += 1
    liCounter = 0
    result += `
    @@ -176,7 +179,7 @@ const menuItems${ulId} = within(menu${ulId}).getAllByRole('listitem')
    expect(menuItems${ulId}).toHaveLength(${childNode.querySelectorAll('li').length})`
    }

    selfGenerated(childNode)
    selfGeneratedTest(childNode)
    }
    })
    }
  16. NerOcrO revised this gist Mar 21, 2025. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -26,10 +26,10 @@ it.only('test', () => {
    render()
    // THEN`
    selfGenerated(container)
    selfGeneratedTest(container)
    console.log(`${result}})`)

    function selfGenerated(element: HTMLElement): void {
    function selfGeneratedTest(element: HTMLElement): void {
    // eslint-disable-next-line complexity
    element.childNodes.forEach((childNode: HTMLElement) => {
    if (childNode.textContent === null) {
  17. NerOcrO revised this gist Mar 21, 2025. 1 changed file with 2 additions and 5 deletions.
    7 changes: 2 additions & 5 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -20,6 +20,7 @@ it.only('test', () => {
    // 1. Le test doit être vert sauf petites pétouilles à modifier
    // 2. Ajouter des "within()" et renommer les constantes
    // 3. Vérifier qu'il n'y a presque plus de screen à la fin
    // 4. Le texte dans une "div" est à rajouter manuellement
    // WHEN
    render()
    @@ -173,11 +174,7 @@ expect(columns${trId}Body).toHaveLength(${childNode.querySelectorAll('td').lengt
    const menu${ulId} = screen.getByRole('list')
    const menuItems${ulId} = within(menu${ulId}).getAllByRole('listitem')
    expect(menuItems${ulId}).toHaveLength(${childNode.querySelectorAll('li').length})`
    } /*else if (childNode.nodeName === 'DIV') {
    result += `
    const texte${id} = screen.getByText('${childNode.textContent}')
    expect(texte${id}).toBeInTheDocument()`
    }*/
    }

    selfGenerated(childNode)
    }
  18. NerOcrO revised this gist Mar 20, 2025. 1 changed file with 7 additions and 1 deletion.
    8 changes: 7 additions & 1 deletion test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -57,8 +57,14 @@ const article${id} = screen.getByRole('article', { name: '${childNode.getAttribu
    const complement${id} = screen.getByRole('complementary')`
    } else if (childNode.nodeName === 'BUTTON') {
    if (childNode.role === 'tab') {
    if (childNode.role === 'tab') {
    let current = 'false'
    if (childNode.getAttribute('aria-current') === 'page') {
    current = "'page'"
    }

    result += `
    const tab${id} = screen.getByRole('tab', { current: '${childNode.getAttribute('aria-current')}', name: '${childNode.textContent}' })
    const tab${id} = screen.getByRole('tab', { current: ${current}, name: '${childNode.textContent}' })
    expect(tab${id}).toBeInTheDocument()`
    } else {
    let description = ''
  19. NerOcrO revised this gist Mar 20, 2025. 1 changed file with 11 additions and 6 deletions.
    17 changes: 11 additions & 6 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -25,10 +25,10 @@ it.only('test', () => {
    render()
    // THEN`
    readHtml(container)
    selfGenerated(container)
    console.log(`${result}})`)

    function readHtml(element: HTMLElement): void {
    function selfGenerated(element: HTMLElement): void {
    // eslint-disable-next-line complexity
    element.childNodes.forEach((childNode: HTMLElement) => {
    if (childNode.textContent === null) {
    @@ -58,7 +58,7 @@ const complement${id} = screen.getByRole('complementary')`
    } else if (childNode.nodeName === 'BUTTON') {
    if (childNode.role === 'tab') {
    result += `
    const tab${id} = screen.getByRole('tab', { name: '${childNode.textContent}' })
    const tab${id} = screen.getByRole('tab', { current: '${childNode.getAttribute('aria-current')}', name: '${childNode.textContent}' })
    expect(tab${id}).toBeInTheDocument()`
    } else {
    let description = ''
    @@ -71,8 +71,13 @@ expect(tab${id}).toBeInTheDocument()`
    }

    result += `
    const bouton${id} = screen.getByRole('button', { ${description}${name} })
    expect(bouton${id}).toHaveAttribute('type', 'button')`
    const bouton${id} = screen.getByRole('button', { ${description}${name} })
    expect(bouton${id}).toHaveAttribute('type', 'button')`

    if (childNode.hasAttribute('aria-controls')) {
    result += `
    expect(bouton${id}).toHaveAttribute('aria-controls', '${childNode.getAttribute('aria-controls')}')`
    }
    }
    } else if (childNode.nodeName === 'DD') {
    result += `
    @@ -168,7 +173,7 @@ const texte${id} = screen.getByText('${childNode.textContent}')
    expect(texte${id}).toBeInTheDocument()`
    }*/

    readHtml(childNode)
    selfGenerated(childNode)
    }
    })
    }
  20. NerOcrO revised this gist Mar 20, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -22,7 +22,7 @@ it.only('test', () => {
    // 3. Vérifier qu'il n'y a presque plus de screen à la fin
    // WHEN
    // TODO: ajouter le render
    render()
    // THEN`
    readHtml(container)
  21. NerOcrO revised this gist Mar 20, 2025. 1 changed file with 4 additions and 5 deletions.
    9 changes: 4 additions & 5 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -17,10 +17,9 @@
    let result = `
    it.only('test', () => {
    // GIVEN
    // 1. Modifier les name="XXX" correspondant aux "aria-labelledby" s'il y en a
    // 3. Le test doit être vert
    // 4. Ajouter des "within()" et renommer les constantes
    // 5. Vérifier qu'il n'y a presque plus de screen à la fin
    // 1. Le test doit être vert sauf petites pétouilles à modifier
    // 2. Ajouter des "within()" et renommer les constantes
    // 3. Vérifier qu'il n'y a presque plus de screen à la fin
    // WHEN
    // TODO: ajouter le render
    @@ -124,7 +123,7 @@ const texte${id} = screen.getByText('${childNode.textContent}', { selector: 'p'
    expect(texte${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'SECTION') {
    result += `
    const section${id} = screen.getByRole('region', { name: 'XXX' })`
    const section${id} = screen.getByRole('region', { name: '${childNode.querySelector(`#${childNode.getAttribute('aria-labelledby')}`)?.textContent}' })`
    } else if (childNode.nodeName === 'SELECT') {
    selectId += 1
    result += `
  22. NerOcrO revised this gist Mar 20, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -93,7 +93,7 @@ const terme${id} = within(termes${dlId}[${dtCounter++}]).getByText('${childNode.
    expect(terme${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'FORM') {
    result += `
    const formulaire = screen.getByRole('form', { name: 'XXX' })
    const formulaire = screen.getByRole('form', { name: '${childNode.querySelector(`#${childNode.getAttribute('aria-label')}`)}' })
    // S'il est dans un drawer
    // expect(formulaire).toHaveAttribute('method', 'dialog')`
    } else if (childNode.nodeName === 'H1') {
  23. NerOcrO revised this gist Mar 20, 2025. 1 changed file with 35 additions and 23 deletions.
    58 changes: 35 additions & 23 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,11 @@
    it.only('génération programatique d’un test d’affichage HTML', () => {
    const membresViewModel = membresPresenter(membresReadModelFactory())
    const { container } = render(<GestionMembres membresViewModel={membresViewModel} />)
    /* eslint-disable @typescript-eslint/no-require-imports */
    /* eslint-disable @typescript-eslint/no-unsafe-call */
    /* eslint-disable @typescript-eslint/no-unsafe-assignment */
    /* eslint-disable @typescript-eslint/no-unsafe-member-access */
    /* eslint-disable testing-library/no-node-access */
    /* eslint-disable no-plusplus */
    it.only('génération programatique d’un test d’affichage HTML', () => {
    const { container } = render()

    let ulId = 0
    let dlId = 0
    @@ -10,13 +15,19 @@ it.only('génération programatique d’un test d’affichage HTML', () => {
    let dtCounter = 0
    let trCounter = 0
    let result = `
    // 1. Modifier les name="XXX" correspondant aux "aria-labelledby" s'il y en a
    // 3. Le test doit être vert
    // 4. Ajouter des "within()" et renommer les constantes
    // 5. Vérifier qu'il n'y a presque plus de screen à la fin`
    it.only('test', () => {
    // GIVEN
    // 1. Modifier les name="XXX" correspondant aux "aria-labelledby" s'il y en a
    // 3. Le test doit être vert
    // 4. Ajouter des "within()" et renommer les constantes
    // 5. Vérifier qu'il n'y a presque plus de screen à la fin
    // WHEN
    // TODO: ajouter le render
    // THEN`
    readHtml(container)
    console.log(result)
    // TODO: Générer le it
    console.log(`${result}})`)

    function readHtml(element: HTMLElement): void {
    // eslint-disable-next-line complexity
    @@ -73,12 +84,18 @@ expect(definition${id}).toBeInTheDocument()`
    dtCounter = 0
    result += `
    const liste${dlId} = screen.getByRole('list', { name: '${childNode.getAttribute('aria-label')}' })
    expect(liste${dlId}).toHaveLength(${childNode.querySelectorAll('dt').length})
    const termes${dlId} = within(dl${dlId}).getAllByRole('term')
    const definitions${dlId} = within(dl${dlId}).getAllByRole('definition')`
    } else if (childNode.nodeName === 'DT') {
    result += `
    const terme${id} = within(termes${dlId}[${dtCounter++}]).getByText('${childNode.textContent}')
    expect(terme${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'FORM') {
    result += `
    const formulaire = screen.getByRole('form', { name: 'XXX' })
    // S'il est dans un drawer
    // expect(formulaire).toHaveAttribute('method', 'dialog')`
    } else if (childNode.nodeName === 'H1') {
    result += `
    const titre1 = screen.getByRole('heading', { level: 1, name: '${childNode.textContent}' })
    @@ -97,28 +114,23 @@ const enTete${id} = screen.getByRole('banner')`
    } else if (childNode.nodeName === 'LI') {
    result += `
    expect(menuItems${ulId}[${liCounter++}].textContent).toBe('${childNode.textContent}')`
    } else if (childNode.nodeName === 'OPTION') {
    result += `
    const option${id} = within(select${selectId}).getByRole('option', { name: '${childNode.textContent}', selected: ${childNode.selected} })
    expect(option${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'P') {
    result += `
    const texte${id} = screen.getByText('${childNode.textContent}', { selector: 'p' })
    expect(texte${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'SECTION') {
    result += `
    const section${id} = screen.getByRole('region', { name: 'XXX' })`
    } else if (childNode.nodeName === 'FORM') {
    result += `
    const formulaire = screen.getByRole('form', { name: 'XXX' })
    // S'il est dans un drawer
    // expect(formulaire).toHaveAttribute('method', 'dialog')`
    } else if (childNode.nodeName === 'OPTION') {
    // taille du select
    result += `
    const option${id} = within(select${selectId}).getByRole('option', { name: '${childNode.textContent}', selected: ${childNode.selected} })
    expect(option${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'SELECT') {
    selectId += 1
    result += `
    const select${selectId} = within(formulaire).getByRole('combobox', { name: '${childNode.labels[0].textContent}' })
    expect(select${selectId}).toBeRequired() // ou .not`
    expect(select${selectId}).${childNode.required === true ? '' : 'not.'}toBeRequired()
    expect(select${selectId}).toHaveLength(${childNode.querySelectorAll('option').length})`
    } else if (childNode.nodeName === 'TABLE') {
    trId = -1
    result += `
    @@ -128,6 +140,9 @@ const rowHead = within(head).getByRole('row')
    const columnsHead = within(rowHead).getAllByRole('columnheader')
    expect(columnsHead).toHaveLength(${childNode.querySelectorAll('th').length})
    const rowsBody = within(body).getAllByRole('row')`
    } else if (childNode.nodeName === 'TD') {
    result += `
    expect(columns${trId}Body[${trCounter++}].textContent).toBe('${childNode.textContent}')`
    } else if (childNode.nodeName === 'TH') {
    result += `
    expect(columnsHead[${trCounter}].textContent).toBe('${childNode.textContent}')
    @@ -141,9 +156,6 @@ expect(columnsHead[${trCounter++}]).toHaveAttribute('scope', 'col')`
    const columns${trId}Body = within(rowsBody[${trId}]).getAllByRole('cell')
    expect(columns${trId}Body).toHaveLength(${childNode.querySelectorAll('td').length})`
    }
    } else if (childNode.nodeName === 'TD') {
    result += `
    expect(columns${trId}Body[${trCounter++}].textContent).toBe('${childNode.textContent}')`
    } else if (childNode.nodeName === 'UL') {
    ulId += 1
    liCounter = 0
  24. NerOcrO revised this gist Mar 19, 2025. 1 changed file with 82 additions and 26 deletions.
    108 changes: 82 additions & 26 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -1,16 +1,22 @@
    it.skip('génération programatique d’un test d’affichage HTML', () => {
    const { container } = render(< />)
    it.only('génération programatique d’un test d’affichage HTML', () => {
    const membresViewModel = membresPresenter(membresReadModelFactory())
    const { container } = render(<GestionMembres membresViewModel={membresViewModel} />)

    let ulId = 0
    let dlId = 0
    let trId = -1
    let selectId = 0
    let liCounter = 0
    let dtCounter = 0
    let trCounter = 0
    let result = `
    // 1. Modifier les name="XXX" correspondant aux "aria-labelledby" s'il y en a
    // 2. Modifier les indices des <li>, <dt> et <dd>
    // 3. Le test doit être vert
    // 4. Ajouter des "within()" et renommer les constantes
    // 5. Vérifier qu'il n'y a presque plus de screen à la fin`
    readHtml(container)
    console.log(result)
    // TODO: Générer le it

    function readHtml(element: HTMLElement): void {
    // eslint-disable-next-line complexity
    @@ -23,7 +29,7 @@
    const id = require('crypto').randomBytes(8).toString('hex')

    if (childNode.nodeName === 'A') {
    const name = childNode.textContent === '' ? childNode.getAttribute('title') : childNode.textContent.trim()
    const name = childNode.textContent === '' ? childNode.getAttribute('title') : childNode.textContent

    result += `
    const lien${id} = screen.getByRole('link', { name: '${name}' })
    @@ -40,66 +46,116 @@ const article${id} = screen.getByRole('article', { name: '${childNode.getAttribu
    result += `
    const complement${id} = screen.getByRole('complementary')`
    } else if (childNode.nodeName === 'BUTTON') {
    let description = ''
    if (childNode.hasAttribute('title')) {
    description = `description: '${childNode.title.trim()}', `
    }
    if (childNode.role === 'tab') {
    result += `
    const tab${id} = screen.getByRole('tab', { name: '${childNode.textContent}' })
    expect(tab${id}).toBeInTheDocument()`
    } else {
    let description = ''
    let name = ''
    if (childNode.hasAttribute('title')) {
    description = `description: '${childNode.title}', `
    }
    if (childNode.textContent !== '') {
    name = `name: '${childNode.textContent}'`
    }

    result += `
    const bouton${id} = screen.getByRole('button', { ${description}name: '${childNode.textContent.trim()}' })
    expect(bouton${id}).toHaveAttribute('type', 'button')`
    result += `
    const bouton${id} = screen.getByRole('button', { ${description}${name} })
    expect(bouton${id}).toHaveAttribute('type', 'button')`
    }
    } else if (childNode.nodeName === 'DD') {
    result += `
    const definition${id} = within(definitions${dlId}[0]).getByText('${childNode.textContent.trim()}')
    const definition${id} = within(definitions${dlId}[${dtCounter++}]).getByText('${childNode.textContent}')
    expect(definition${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'DIV') {
    result += `
    const texte${id} = screen.getByText('${childNode.textContent.trim()}')
    expect(texte${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'DL') {
    dlId += 1
    dtCounter = 0
    result += `
    const liste${dlId} = screen.getByRole('list', { name: '${childNode.getAttribute('aria-label')}' })
    const termes${dlId} = within(dl${dlId}).getAllByRole('term')
    const definitions${dlId} = within(dl${dlId}).getAllByRole('definition')`
    } else if (childNode.nodeName === 'DT') {
    result += `
    const terme${id} = within(termes${dlId}[0]).getByText('${childNode.textContent.trim()}')
    const terme${id} = within(termes${dlId}[${dtCounter++}]).getByText('${childNode.textContent}')
    expect(terme${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'H1') {
    result += `
    const titre1 = screen.getByRole('heading', { level: 1, name: '${childNode.textContent.trim()}' })
    const titre1 = screen.getByRole('heading', { level: 1, name: '${childNode.textContent}' })
    expect(titre1).toBeInTheDocument()`
    } else if (childNode.nodeName === 'H2') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 2, name: '${childNode.textContent.trim()}' })
    const titre${id} = screen.getByRole('heading', { level: 2, name: '${childNode.textContent}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'H3') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 3, name: '${childNode.textContent.trim()}' })
    const titre${id} = screen.getByRole('heading', { level: 3, name: '${childNode.textContent}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'HEADER') {
    result += `
    const enTete${id} = screen.getByRole('banner')`
    } else if (childNode.nodeName === 'LI') {
    result += `
    expect(menuItems${ulId}[0].textContent).toBe('${childNode.textContent.trim()}')`
    expect(menuItems${ulId}[${liCounter++}].textContent).toBe('${childNode.textContent}')`
    } else if (childNode.nodeName === 'P') {
    result += `
    const texte${id} = screen.getByText('${childNode.textContent.trim()}', { selector: 'p' })
    const texte${id} = screen.getByText('${childNode.textContent}', { selector: 'p' })
    expect(texte${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'SECTION') {
    result += `
    //const section${id} = screen.getByRole('region', { name: 'XXX' })`
    const section${id} = screen.getByRole('region', { name: 'XXX' })`
    } else if (childNode.nodeName === 'FORM') {
    result += `
    const formulaire = screen.getByRole('form', { name: 'XXX' })
    // S'il est dans un drawer
    // expect(formulaire).toHaveAttribute('method', 'dialog')`
    } else if (childNode.nodeName === 'OPTION') {
    // taille du select
    result += `
    const option${id} = within(select${selectId}).getByRole('option', { name: '${childNode.textContent}', selected: ${childNode.selected} })
    expect(option${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'SELECT') {
    selectId += 1
    result += `
    const select${selectId} = within(formulaire).getByRole('combobox', { name: '${childNode.labels[0].textContent}' })
    expect(select${selectId}).toBeRequired() // ou .not`
    } else if (childNode.nodeName === 'TABLE') {
    // à faire
    trId = -1
    result += `
    const table = screen.getByRole('table', { name: '${childNode.caption.textContent}' })
    const [head, body] = within(table).getAllByRole('rowgroup')
    const rowHead = within(head).getByRole('row')
    const columnsHead = within(rowHead).getAllByRole('columnheader')
    expect(columnsHead).toHaveLength(${childNode.querySelectorAll('th').length})
    const rowsBody = within(body).getAllByRole('row')`
    } else if (childNode.nodeName === 'TH') {
    result += `
    expect(columnsHead[${trCounter}].textContent).toBe('${childNode.textContent}')
    expect(columnsHead[${trCounter++}]).toHaveAttribute('scope', 'col')`
    } else if (childNode.nodeName === 'TR') {
    trCounter = 0

    if (childNode.childNodes[0].nodeName === 'TD') {
    trId += 1
    result += `
    const columns${trId}Body = within(rowsBody[${trId}]).getAllByRole('cell')
    expect(columns${trId}Body).toHaveLength(${childNode.querySelectorAll('td').length})`
    }
    } else if (childNode.nodeName === 'TD') {
    result += `
    expect(columns${trId}Body[${trCounter++}].textContent).toBe('${childNode.textContent}')`
    } else if (childNode.nodeName === 'UL') {
    ulId += 1
    liCounter = 0
    result += `
    const menu${ulId} = screen.getByRole('list')
    const menuItems${ulId} = within(menu${ulId}).getAllByRole('listitem')
    expect(menuItems${ulId}).toHaveLength(0)`
    }
    expect(menuItems${ulId}).toHaveLength(${childNode.querySelectorAll('li').length})`
    } /*else if (childNode.nodeName === 'DIV') {
    result += `
    const texte${id} = screen.getByText('${childNode.textContent}')
    expect(texte${id}).toBeInTheDocument()`
    }*/

    readHtml(childNode)
    }
  25. NerOcrO revised this gist Mar 17, 2025. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -4,11 +4,11 @@
    let ulId = 0
    let dlId = 0
    let result = `
    // Modifier les indices des <li>, <dt> et <dd>
    // Ajouter des "within()"
    // Modifier les constantes
    // Modifier les name="XXX" correspondant aux "aria-labelledby"
    // Vérifier qu'il n'y a presque plus de screen`
    // 1. Modifier les name="XXX" correspondant aux "aria-labelledby" s'il y en a
    // 2. Modifier les indices des <li>, <dt> et <dd>
    // 3. Le test doit être vert
    // 4. Ajouter des "within()" et renommer les constantes
    // 5. Vérifier qu'il n'y a presque plus de screen à la fin`
    readHtml(container)
    console.log(result)

  26. NerOcrO revised this gist Mar 17, 2025. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,8 @@
    // Modifier les indices des <li>, <dt> et <dd>
    // Ajouter des "within()"
    // Modifier les constantes
    // Modifier les name="XXX" correspondant aux "aria-labelledby"`
    // Modifier les name="XXX" correspondant aux "aria-labelledby"
    // Vérifier qu'il n'y a presque plus de screen`
    readHtml(container)
    console.log(result)

  27. NerOcrO revised this gist Mar 17, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -37,7 +37,7 @@ expect(lien${id}).toOpenInNewTab('${childNode.getAttribute('title')?.replace(' -
    const article${id} = screen.getByRole('article', { name: '${childNode.getAttribute('aria-label')}' })`
    } else if (childNode.nodeName === 'ASIDE') {
    result += `
    const aside${id} = screen.getByRole('complementary')`
    const complement${id} = screen.getByRole('complementary')`
    } else if (childNode.nodeName === 'BUTTON') {
    let description = ''
    if (childNode.hasAttribute('title')) {
  28. NerOcrO revised this gist Mar 17, 2025. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -58,7 +58,7 @@ expect(texte${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'DL') {
    dlId += 1
    result += `
    const dl${dlId} = screen.getByRole('list', { name: '${childNode.getAttribute('aria-label')}' })
    const liste${dlId} = screen.getByRole('list', { name: '${childNode.getAttribute('aria-label')}' })
    const termes${dlId} = within(dl${dlId}).getAllByRole('term')
    const definitions${dlId} = within(dl${dlId}).getAllByRole('definition')`
    } else if (childNode.nodeName === 'DT') {
  29. NerOcrO created this gist Mar 17, 2025.
    107 changes: 107 additions & 0 deletions test_generer_programatiquement.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,107 @@
    it.skip('génération programatique d’un test d’affichage HTML', () => {
    const { container } = render(< />)

    let ulId = 0
    let dlId = 0
    let result = `
    // Modifier les indices des <li>, <dt> et <dd>
    // Ajouter des "within()"
    // Modifier les constantes
    // Modifier les name="XXX" correspondant aux "aria-labelledby"`
    readHtml(container)
    console.log(result)

    function readHtml(element: HTMLElement): void {
    // eslint-disable-next-line complexity
    element.childNodes.forEach((childNode: HTMLElement) => {
    if (childNode.textContent === null) {
    return
    }

    if (childNode.nodeType !== Node.TEXT_NODE) {
    const id = require('crypto').randomBytes(8).toString('hex')

    if (childNode.nodeName === 'A') {
    const name = childNode.textContent === '' ? childNode.getAttribute('title') : childNode.textContent.trim()

    result += `
    const lien${id} = screen.getByRole('link', { name: '${name}' })
    expect(lien${id}).toHaveAttribute('href', '${childNode.getAttribute('href')}')`

    if (childNode.hasAttribute('title')) {
    result += `
    expect(lien${id}).toOpenInNewTab('${childNode.getAttribute('title')?.replace(' - nouvelle fenêtre', '')}')`
    }
    } else if (childNode.nodeName === 'ARTICLE') {
    result += `
    const article${id} = screen.getByRole('article', { name: '${childNode.getAttribute('aria-label')}' })`
    } else if (childNode.nodeName === 'ASIDE') {
    result += `
    const aside${id} = screen.getByRole('complementary')`
    } else if (childNode.nodeName === 'BUTTON') {
    let description = ''
    if (childNode.hasAttribute('title')) {
    description = `description: '${childNode.title.trim()}', `
    }

    result += `
    const bouton${id} = screen.getByRole('button', { ${description}name: '${childNode.textContent.trim()}' })
    expect(bouton${id}).toHaveAttribute('type', 'button')`
    } else if (childNode.nodeName === 'DD') {
    result += `
    const definition${id} = within(definitions${dlId}[0]).getByText('${childNode.textContent.trim()}')
    expect(definition${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'DIV') {
    result += `
    const texte${id} = screen.getByText('${childNode.textContent.trim()}')
    expect(texte${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'DL') {
    dlId += 1
    result += `
    const dl${dlId} = screen.getByRole('list', { name: '${childNode.getAttribute('aria-label')}' })
    const termes${dlId} = within(dl${dlId}).getAllByRole('term')
    const definitions${dlId} = within(dl${dlId}).getAllByRole('definition')`
    } else if (childNode.nodeName === 'DT') {
    result += `
    const terme${id} = within(termes${dlId}[0]).getByText('${childNode.textContent.trim()}')
    expect(terme${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'H1') {
    result += `
    const titre1 = screen.getByRole('heading', { level: 1, name: '${childNode.textContent.trim()}' })
    expect(titre1).toBeInTheDocument()`
    } else if (childNode.nodeName === 'H2') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 2, name: '${childNode.textContent.trim()}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'H3') {
    result += `
    const titre${id} = screen.getByRole('heading', { level: 3, name: '${childNode.textContent.trim()}' })
    expect(titre${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'HEADER') {
    result += `
    const enTete${id} = screen.getByRole('banner')`
    } else if (childNode.nodeName === 'LI') {
    result += `
    expect(menuItems${ulId}[0].textContent).toBe('${childNode.textContent.trim()}')`
    } else if (childNode.nodeName === 'P') {
    result += `
    const texte${id} = screen.getByText('${childNode.textContent.trim()}', { selector: 'p' })
    expect(texte${id}).toBeInTheDocument()`
    } else if (childNode.nodeName === 'SECTION') {
    result += `
    //const section${id} = screen.getByRole('region', { name: 'XXX' })`
    } else if (childNode.nodeName === 'TABLE') {
    // à faire
    } else if (childNode.nodeName === 'UL') {
    ulId += 1
    result += `
    const menu${ulId} = screen.getByRole('list')
    const menuItems${ulId} = within(menu${ulId}).getAllByRole('listitem')
    expect(menuItems${ulId}).toHaveLength(0)`
    }

    readHtml(childNode)
    }
    })
    }
    })