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.
test rtl
// ==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"
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"))
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("")
}
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 (childNode.nodeType !== Node.TEXT_NODE) {
const id = genererUnIdAleatoire(8)
if (balise === "A") {
const name = contenuDeLaBalise === "" ? childNode.getAttribute("title") : contenuDeLaBalise
test.push(
`const lien${id} = screen.getByRole("link", { name: "${name}" })`,
`expect(lien${id}).toHaveAttribute("href", "${childNode.getAttribute("href")}")`,
)
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"`
}
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}"`
}
test.push(
`const bouton${id} = screen.getByRole("button", { ${description}${name} })`,
`expect(bouton${id}).toHaveAttribute("type", "${childNode.type}")`,
)
if (childNode.disabled === true) {
test.push(
`expect(bouton${id}).toBeDisabled()`,
)
} else {
test.push(
`expect(bouton${id}).toBeEnabled()`,
)
}
if (childNode.hasAttribute("aria-controls")) {
test.push(
`expect(bouton${id}).toHaveAttribute("aria-controls", "${childNode.getAttribute("aria-controls")}")`,
)
}
}
} 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")) {
test.push(
`expect(input${id}).toBeRequired()`,
)
}
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)
}
})
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment