bascik-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Testing and Debugging Bascik Sites

测试与调试 Bascik 站点

Requires the
bascik
skill for project basics and its
scripts/verify.mjs
for the check and lint loop.
需要
bascik
skill 了解项目基础,并使用其中的
scripts/verify.mjs
完成检查与 lint 循环。

Verification ladder

验证阶梯

Run cheapest first and stop at the first failure:
  1. npx bascik --check
    : project checks (config, routes, references) plus, when
    @bascik/language-server
    is installed, the per-file checks (scoping patterns, unclosed tags).
    node <skills-dir>/bascik/scripts/verify.mjs
    runs it and also covers component folders outside the project.
  2. npx vitest run
    for unit tests of pure logic.
  3. BASCIK_SITE_URL=https://example.com npx bascik --build
    , then inspect
    dist/
    or run
    verify.mjs --build
    .
  4. npx playwright test
    against the built site or the dev server.
CI gate:
bascik --check && vitest run && bascik --build && playwright test
.
bascik --check
already runs the per-file checks, so there is no separate linter step. Add
bascik-language-server --check <dir>
only for a component folder outside the project.
Bascik strips types without checking them. To fail CI on type errors in
<script type="text/typescript">
blocks, add
--typescript
(
bascik --check --typescript
); it needs
typescript
5 or 6, from the project or else resolvable from the installed
@bascik/language-server
(TypeScript 7 and versions before 5 are skipped with a note) and is off by default. Read
read-doc.mjs /cli#typescript-errors-with-typescript
.
先运行成本最低的检查,并在首次失败时停止:
  1. npx bascik --check
    :执行项目检查(配置、路由、引用);安装
    @bascik/language-server
    后,还会执行逐文件检查(作用域模式、未闭合标签)。
    node <skills-dir>/bascik/scripts/verify.mjs
    会运行这些检查,并额外覆盖项目之外的组件目录。
  2. npx vitest run
    :对纯逻辑执行单元测试。
  3. BASCIK_SITE_URL=https://example.com npx bascik --build
    ,然后检查
    dist/
    或运行
    verify.mjs --build
    。
  4. 针对构建后的站点或开发服务器运行
    npx playwright test
    。
CI 门禁:
bascik --check && vitest run && bascik --build && playwright test
。
bascik --check
已包含逐文件检查,因此不需要单独的 linter 步骤。只有当组件目录位于项目之外时,才添加
bascik-language-server --check <dir>
。
Bascik 会移除类型,但不会检查类型。若要使 CI 在
<script type="text/typescript">
代码块出现类型错误时失败,请添加
--typescript
(
bascik --check --typescript
)。该功能需要
typescript
5 或 6,可以来自项目本身,也可以从已安装的
@bascik/language-server
中解析。TypeScript 7 和 5 之前的版本会被跳过并附带说明。默认情况下此功能处于关闭状态。查阅
read-doc.mjs /cli#typescript-errors-with-typescript
。

Unit tests: extract pure logic

单元测试:提取纯逻辑

Component scripts are IIFEs and cannot be imported. Test logic, not DOM wiring:
  1. Move pure functions (parsing, scoring, formatting, validation) into a sibling
    .ts
    file, for example
    src/components/docs-search/search-logic.ts
    .
  2. Load it from the component with
    <script src="search-logic.ts"></script>
    . Bascik strips its types and scopes it; no build step or
    minify.js
    hook is needed.
  3. Import the
    .ts
    file directly in
    search-logic.test.ts
    . No browser is needed.
For manual Vitest setup, install
vitest
,
@vitest/coverage-v8
and
vite
as dev dependencies. Vitest 5 requires the Vite peer even when the config imports
vitest/config
; see
read-doc.mjs /testing/unit-testing
.
ts
// vite.config.ts
import { defineConfig } from "vitest/config";
export default defineConfig({ test: { include: ["src/**/*.test.ts"] } });
Server, stream, and API logic: put it in a
.ts
module (beside the one page or component that uses it, or in
src/lib/
when several do or an API route calls it, since every file in
src/api/
is a route), keep its
*.test.ts
beside it, unit test the functions, and cover the HTTP layer with requests against the dev server or
bascik --server
. A function or handler that returns
html
from
@bascik/bascik/html
returns an object, not a string: assert on
String(output)
(
expect(String(output)).toContain("Seattle")
), and type a helper's return as
SafeHtml
, not
string
. For a server or stream script's default export, assert on
serverScriptOutput(await handler(request, context, { signal })).text
from
@bascik/bascik/runtime
: it prints the bytes the page gets (a returned array joined with no separator, where
String()
adds commas), and its
.error
names a return the page refuses (data, a
Response
, an
Error
, an array of Promises). Details:
read-doc.mjs /testing/server-scripts
.
组件脚本是 IIFE,无法导入。测试逻辑,而不是 DOM 连接:
  1. 将纯函数(解析、评分、格式化、验证)移动到同级
    .ts
    文件中,例如
    src/components/docs-search/search-logic.ts
    。
  2. 在组件中通过
    <script src="search-logic.ts"></script>
    加载它。Bascik 会移除其类型并限定其作用域;无需构建步骤或
    minify.js
    hook。
  3. 在
    search-logic.test.ts
    中直接导入该
    .ts
    文件,无需浏览器。
如需手动配置 Vitest,请将
vitest
、
@vitest/coverage-v8
和
vite
安装为 dev dependencies。即使配置导入
vitest/config
,Vitest 5 仍然需要 Vite peer dependency;参阅
read-doc.mjs /testing/unit-testing
。
ts
// vite.config.ts
import { defineConfig } from "vitest/config";
export default defineConfig({ test: { include: ["src/**/*.test.ts"] } });
服务器、流和 API 逻辑:将其放入
.ts
模块(放在使用它的单个页面或组件旁边;如果多个页面或组件使用它,或者 API 路由调用它,则放在
src/lib/
中,因为
src/api/
中的每个文件都是一条路由),并把
*.test.ts
放在同一位置。对函数进行单元测试,同时通过向开发服务器或
bascik --server
发起请求来覆盖 HTTP 层。从
@bascik/bascik/html
返回
html
的函数或 handler 返回的是对象,而不是字符串:应基于
String(output)
进行断言(
expect(String(output)).toContain("Seattle")
),并将 helper 的返回类型设为
SafeHtml
,而不是
string
。对于服务器或流脚本的 default export,应基于
@bascik/bascik/runtime
中的
serverScriptOutput(await handler(request, context, { signal })).text
进行断言:它会输出页面接收到的字节(返回的数组在拼接时不会添加分隔符,而
String()
会添加逗号);其
.error
会指明页面拒绝的返回值(数据、
Response
、
Error
或 Promises 数组)。详情参阅
read-doc.mjs /testing/server-scripts
。

E2E tests: locators that survive production

E2E 测试:适用于生产环境的定位器

bascik --build
hashes scoped class names and IDs (
minify.identifiers
). Selectors such as
.my-card
or
#btn
that work in dev fail in production.
  • Find a component, or a part of one, with
    getByTestId(...)
    . Every component root has
    data-testid="<component-name>"
    and each interactive part has
    data-testid="<component-name>-<part>"
    (rule 16 of the
    bascik
    skill); add any that are missing to the template, and run
    verify.mjs
    , whose advisory lists the gaps. Bascik never scopes or hashes
    data-testid
    .
  • Use
    getByRole(...)
    ,
    getByLabel(...)
    , or
    getByText(...)
    first when the test is about what a person reads or hears: a button's accessible name, a field's label, a heading.
  • Instances share their test ids. Pick one with
    .filter({ hasText: "..." })
    , or give it its own with
    data-testid
    on the usage tag in the test page, which replaces the root's.
  • Never use scoped names (
    .bascik__my-card__title
    ), positional
    .nth(N)
    chains, or
    locator('..')
    traversal to reach an element.
  • Put two instances of a component on a test page and assert they act independently; that catches the class-selector pitfall.
  • Test against the production build (
    bascik --build
    served statically, or
    bascik --server
    ), not only the dev server: script placement and identifiers differ.
ts
import { test, expect } from "@playwright/test";

test("each like button toggles independently", async ({ page }) => {
  await page.goto("/");
  const buttons = page.getByTestId("like-button");
  await buttons.first().click();
  await expect(buttons.first()).toHaveAttribute("aria-pressed", "true");
  await expect(buttons.last()).toHaveAttribute("aria-pressed", "false");
});
bascik --build
会对作用域类名和 ID 进行哈希处理(
minify.identifiers
)。在开发环境中有效的选择器,例如
.my-card
或
#btn
,在生产环境中会失效。
  • 使用
    getByTestId(...)
    查找组件或组件的一部分。每个组件根元素都有
    data-testid="<component-name>"
    ,每个交互部分都有
    data-testid="<component-name>-<part>"
    (
    bascik
    skill 的规则 16);如果模板中缺少这些属性,请自行添加,然后运行
    verify.mjs
    ,其建议列表会列出缺失项。Bascik 不会对
    data-testid
    进行作用域处理或哈希处理。
  • 当测试关注用户读取或听到的内容时,应优先使用
    getByRole(...)
    、
    getByLabel(...)
    或
    getByText(...)
    ,例如按钮的可访问名称、字段标签或标题。
  • 多个实例共享各自的 test ID。可以使用
    .filter({ hasText: "..." })
    选择其中一个实例,也可以在测试页面的 usage 标签上设置自己的
    data-testid
    ,这会替换根元素上的 test ID。
  • 不要使用作用域名称(
    .bascik__my-card__title
    )、基于位置的
    .nth(N)
    链式调用,或
    locator('..')
    遍历来查找元素。
  • 在测试页面上放置同一组件的两个实例,并断言它们能够独立运行;这样可以发现类选择器容易引发的问题。
  • 应针对生产构建进行测试(静态提供
    bascik --build
    的产物,或使用
    bascik --server
    ),而不能只测试开发服务器,因为两者的脚本位置和标识符有所不同。
ts
import { test, expect } from "@playwright/test";

test("each like button toggles independently", async ({ page }) => {
  await page.goto("/");
  const buttons = page.getByTestId("like-button");
  await buttons.first().click();
  await expect(buttons.first()).toHaveAttribute("aria-pressed", "true");
  await expect(buttons.last()).toHaveAttribute("aria-pressed", "false");
});

Responsive layout regressions

响应式布局回归

  • Test width-height pairs, not just popular phone widths: include the reported failure, short portrait, landscape, breakpoint edges and unchanged desktop cases.
  • Wait for fonts and images, then assert the intended relationships: visible text clears fixed headers, text and CTAs stay inside their section, buttons follow text with the intended gap, and no sideways scroll appears. Use roles/test ids and measured bounds, not scoped class names; choose padding/gap expectations from the design.
  • Prove the regression test fails before the fix and passes on the production build afterward; cover every route using the affected component. Screenshots and painted-layer inspection still matter: element boxes, zero sideways scroll and Lighthouse scores cannot prove text is unobscured.
  • For existing-site defects and accepted parity differences, read
    read-doc.mjs /how-to/agent-migration#finding-responsive-defects
    and use the
    bascik-refactor
    workflow when installed.
  • 测试宽度与高度的组合,而不只是常见的手机宽度:应涵盖已报告的故障尺寸、较短的纵向视口、横向视口、断点边界以及未发生变化的桌面端场景。
  • 等待字体和图片加载完成,然后断言预期关系:可见文本避开固定页眉,文本和 CTA 保持在各自区块内,按钮位于文本之后并保持预期间距,且不出现横向滚动。使用 role、test ID 和实测边界,不要使用作用域类名;padding 和 gap 的预期值应以设计为准。
  • 证明回归测试在修复前失败,并在修复后通过生产构建;覆盖所有使用受影响组件的路由。截图和绘制层检查仍然重要:元素边界框、无横向滚动以及 Lighthouse 分数都无法证明文本未被遮挡。
  • 对于现有站点缺陷和已接受的等效差异,查阅
    read-doc.mjs /how-to/agent-migration#finding-responsive-defects
    ,并在已安装时使用
    bascik-refactor
    workflow。

Validate compiled HTML

验证编译后的 HTML

Install
parse5
as a dev dependency and
bascik --check
will report WHATWG parse errors in
dist/
HTML. For a test that fails the suite instead, walk
dist/**/*.html
and collect
parse5
onParseError
results; see
read-doc.mjs /testing/component-testing
.
将
parse5
安装为 dev dependency 后,
bascik --check
会报告
dist/
HTML 中的 WHATWG 解析错误。如果希望改由测试使测试套件失败,可以遍历
dist/**/*.html
并收集
parse5
的
onParseError
结果;参阅
read-doc.mjs /testing/component-testing
。

Debug

调试

  • Component scripts: in DevTools Sources, open
    src/components/<name>/<name>.html
    (Cmd+P / Ctrl+P). Lines match the source in dev. Later instances are
    <name>.html?instance=2
    . Use
    debugger;
    to stop in every instance.
  • Build, routes, server, and stream scripts: errors point at the file and line where the script was written. Set breakpoints in VS Code and launch the dev server under the debugger.
  • Wrong output: run
    node <skills-dir>/bascik/scripts/preview.mjs --page src/pages/x.html
    to read the unminified compiled page.
  • Stale build script output: a script that reads the network or a directory is cached; add it to
    scripts.cache.exclude
    or delete
    node_modules/.cache/bascik/script-cache
    .
VS Code launch configurations and step-by-step flows:
read-doc.mjs /testing/debugging
and
/testing/source-maps
.
  • **组件脚本:**在 DevTools Sources 中打开
    src/components/<name>/<name>.html
    (Cmd+P / Ctrl+P)。行号与开发环境中的源文件一致。后续实例为
    <name>.html?instance=2
    。使用
    debugger;
    可在每个实例中暂停。
  • **构建、路由、服务器和流脚本:**错误会指向脚本所在的文件及行号。可在 VS Code 中设置断点,并在调试器下启动开发服务器。
  • **输出异常:**运行
    node <skills-dir>/bascik/scripts/preview.mjs --page src/pages/x.html
    ,查看未压缩的编译页面。
  • **构建脚本输出过期:**读取网络或目录的脚本会被缓存;将其添加到
    scripts.cache.exclude
    ,或删除
    node_modules/.cache/bascik/script-cache
    。
VS Code 启动配置和分步操作流程:查阅
read-doc.mjs /testing/debugging
和
/testing/source-maps
。

Lighthouse

Lighthouse

Bascik output starts near 100 because it adds no runtime. The remaining points come from ordinary HTML practice: explicit image
width
and
height
,
loading="lazy"
below the fold only, preload of the hero image and critical fonts,
defer
scripts, a unique
<title>
, description, and canonical per page, landmarks, labeled controls, and
lang
on
<html>
. Checklists:
read-doc.mjs /lighthouse/performance
,
/lighthouse/accessibility
,
/lighthouse/best-practices
,
/lighthouse/seo
, and
/lighthouse/agentic-browsing
. To fail a build unless every page scores 100 in all five categories, run
bascik-refactor/scripts/lighthouse-gate.mjs
from the opt-in
bascik-refactor
skill (
npx skills add bascikdev/bascik --skill bascik-refactor
) over the Lighthouse JSON reports.
Bascik 不添加运行时,因此输出得分通常一开始就接近 100。其余分数取决于常规 HTML 最佳实践:为图片明确设置
width
和
height
,仅对首屏以下的图片使用
loading="lazy"
,预加载主视觉图片和关键字体,为脚本添加
defer
,确保每页都有唯一的
<title>
、description 和 canonical 链接,并提供 landmark 区域、带标签的控件以及
<html>
上的
lang
。检查清单:查阅
read-doc.mjs /lighthouse/performance
、
/lighthouse/accessibility
、
/lighthouse/best-practices
、
/lighthouse/seo
和
/lighthouse/agentic-browsing
。若要设置构建门禁,要求每个页面在五个类别中的得分均为 100,否则构建失败,请基于 Lighthouse JSON 报告运行可选启用的
bascik-refactor
skill 中的
bascik-refactor/scripts/lighthouse-gate.mjs
(
npx skills add bascikdev/bascik --skill bascik-refactor
)。

Look it up

查阅指南

How do I...Read
Unit test helpers and handlers
/testing/unit-testing
Test components in a browser
/testing/component-testing
,
/testing/e2e-testing
Test build, server, and exec scripts
/testing/build-scripts
,
/testing/server-scripts
,
/testing/exec-scripts
Lint in CI
/testing/linting
,
/tools/linter
Handle false editor linter warnings
/testing/linting#editor-linters-read-source
Fix a known problem
/testing/troubleshooting
node <skills-dir>/bascik/scripts/read-doc.mjs <path>
prints any of these.
我想……查阅
单元测试辅助函数和 handler
/testing/unit-testing
在浏览器中测试组件
/testing/component-testing
、
/testing/e2e-testing
测试构建、服务器和 exec 脚本
/testing/build-scripts
、
/testing/server-scripts
、
/testing/exec-scripts
在 CI 中执行 lint
/testing/linting
、
/tools/linter
处理编辑器 linter 的误报警告
/testing/linting#editor-linters-read-source
修复已知问题
/testing/troubleshooting
node <skills-dir>/bascik/scripts/read-doc.mjs <path>
可打印以上任意文档。