From 3abfb8c2dc7606395d1fd7cd665e02be8eecc8dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=81=87=E8=A7=81=E5=90=8C=E5=AD=A6?= <1875694521@qq.com> Date: Tue, 30 Dec 2025 23:05:56 +0800 Subject: [PATCH] chore: ci fix to remove parse5 (#56421) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: ci fix * chore: update * chore: update * chore: fix lint * chore: remove outdated parse5 dependencies from package.json --------- Co-authored-by: 二货机器人 Co-authored-by: thinkasany <480968828@qq.com> --- package.json | 7 ++-- scripts/check-site.ts | 78 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 94962d159f..019bf99926 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "test:image": "cross-env MOCK_USE_ID=false jest --config .jest.image.js --no-cache -i -u --forceExit", "test:node": "npm run version && jest --config .jest.node.js --no-cache", "test:package-diff": "antd-tools run package-diff", - "test:site": "jest --config .jest.site.js", + "test:site": "jest --config .jest.site.js --no-cache", "test:site-update": "npm run site && npm run test:site -- -u", "test:update": "jest --config .jest.js --no-cache -u", "test:visual-regression": "tsx scripts/visual-regression/build.ts", @@ -228,7 +228,6 @@ "antd-token-previewer": "^3.0.0", "axios": "^1.13.2", "chalk": "^5.6.2", - "cheerio": "^1.1.2", "circular-dependency-plugin": "^5.2.2", "cli-progress": "^3.12.0", "cross-env": "^10.1.0", @@ -236,6 +235,7 @@ "csstree-validator": "^4.0.1", "cypress-image-diff-html-report": "2.2.0", "dekko": "^0.2.1", + "domparser-rs": "0.0.7", "dotenv": "^17.2.3", "dumi": "~2.4.21", "dumi-plugin-color-chunk": "^2.1.0", @@ -284,9 +284,6 @@ "ora": "^9.0.0", "p-all": "^5.0.1", "package-manager-detector": "^1.6.0", - "parse5": "8.0.0", - "parse5-htmlparser2-tree-adapter": "8.0.0", - "parse5-parser-stream": "8.0.0", "pngjs": "^7.0.0", "portfinder": "^1.0.38", "prettier": "^3.7.4", diff --git a/scripts/check-site.ts b/scripts/check-site.ts index 310616bbc1..c2bbe2c7c8 100755 --- a/scripts/check-site.ts +++ b/scripts/check-site.ts @@ -1,7 +1,9 @@ +/* eslint-disable unicorn/prefer-dom-node-text-content */ + import type http from 'http'; import type https from 'https'; import { join } from 'path'; -import { load } from 'cheerio'; +import { DOMParser } from 'domparser-rs'; import { globSync } from 'glob'; import { createServer } from 'http-server'; import fetch from 'isomorphic-fetch'; @@ -23,8 +25,56 @@ describe('site test', () => { const port = await portPromise; const resp = await fetch(`http://127.0.0.1:${port}${path}`).then(async (res) => { const html: string = await res.text(); - const $ = load(html, { xml: true }); - return { status: res.status, $ }; + const root = new DOMParser().parseFromString(html, 'text/html'); + function getTextContent(node: any): string { + if (!node) return ''; + if (typeof node.textContent === 'string') return node.textContent.trim(); + if (typeof node.innerText === 'string') return node.innerText.trim(); + // Fallback: recursively get text from children + if (node.children && node.children.length > 0) { + return Array.from(node.children) + .map((child: any) => getTextContent(child)) + .join('') + .trim(); + } + return ''; + } + function wrap(nodes: any[]) { + const list = Array.isArray(nodes) ? nodes : []; + return { + length: list.length, + text: () => { + if (list.length === 0) return ''; + return list.map((n) => getTextContent(n)).join(''); + }, + first: () => wrap(list.slice(0, 1)), + }; + } + const $ = (selector: string) => { + if (!root.querySelector) { + console.warn('DOMParser does not support querySelector'); + return wrap([]); + } + + // Handle complex selectors that domparser-rs might not support + if (selector === '.markdown table') { + // Find all .markdown elements and then find tables within them + const markdownElements = root.querySelectorAll('.markdown'); + const tables = []; + for (const markdown of Array.from(markdownElements)) { + const tablesInMarkdown = markdown.querySelectorAll('table'); + tables.push(...Array.from(tablesInMarkdown)); + } + return wrap(tables); + } else { + // Use querySelectorAll for simple selectors + const elements = root.querySelectorAll(selector); + const elementsArray = Array.from(elements); + return wrap(elementsArray); + } + }; + + return { status: res.status, $, root }; }); return resp; }; @@ -35,9 +85,27 @@ describe('site test', () => { }; const expectComponent = async (component: string) => { - const { status, $ } = await render(`/${component}/`); + const { status, $, root } = await render(`/${component}/`); expect(status).toBe(200); - expect($('h1').text().toLowerCase()).toMatch(handleComponentName(component)); + + // Get all h1 elements and find the one in main content (not in header) + const h1Elements = root.querySelectorAll('h1'); + let mainH1Text = ''; + + if (h1Elements.length >= 2) { + // The second h1 should be the main content title + const mainH1 = h1Elements[1]; + mainH1Text = mainH1.textContent || (mainH1 as any).innerText || ''; + } else if (h1Elements.length === 1) { + // If only one h1, check its content + const h1 = h1Elements[0]; + mainH1Text = h1.textContent || (h1 as any).innerText || ''; + } + + // Clean up the text and extract the main component name + mainH1Text = mainH1Text.trim(); + + expect(mainH1Text.toLowerCase()).toMatch(handleComponentName(component)); /** * 断言组件的 api table 数量是否符合预期。