@app-studio/qa-studio

中文文档
0.11.6发布于 2026/11/06UNLICENSEDTypeScriptES Module近 30 天下载 1903

由组件测试和调试工作室共享的State Fixture数据,外加从App Studio原版功能规格编译的活浏览器适配器.

中文使用文档
文档目录6 节
  1. 状态定型 v3
  2. 反应原生和其他非 DOM 主机
  3. 当地HTTP上的固定设备
  4. 原始 App Studio 特性流
  5. 目标状态浏览器适配器
  6. 代理驱动的页面调试(本地 0.11.4- rc.3)

@app-studio/qa-studio

Debug Studio和浏览器适配器,用于两个明确合同.

CLI的游戏 qa demos run 使用相同的 API 渲染器和 Canonial 浏览器 生成 Chromium 截图/视频并完成报告的编译器/运行器 自动。 见 自动演示 递增数 选择和临时出处核实证明; /playwright 还出口 runScenarioCase。 。 。 .

/api 导出无框架的 HTTP 运行程序 mountApiStudio· ; /react 还出口 ApiStudio。工作台编辑请求/检查,显示已编辑 并记录一个选定的标签/窗口. CLI在没有应用程序浏览器构建的情况下为它服务. 见 API 工作室 财务报告和审定财务报表 pnpm api:demo 在工作空间.

状态定型 v3

只渲染组件或屏幕状态 :

{
  "schemaVersion": 3,
  "kind": "state-fixture",
  "screen": "content/notes:NotesListPage",
  "outcome": "worst",
  "states": [{
    "id": "content/notes:empty",
    "summary": "A new workspace has no notes yet",
    "routes": [{ "match": "/notes", "method": "GET", "answer": { "items": [] } }],
    "persona": "connected",
    "viewport": { "preset": "desktop" }
  }]
}

同样的固定接口组件测试,调试工作室,以及 qa state run --id它不包含产品行动,也不提出端到端索赔.

import { installState, statesFrom, type StateFixtureFile } from '@app-studio/qa-studio';

反应主机供应 StateEntry[], (中文(简体) ), renderState和可选的商店靴子 深链接使用 ?state=<id> 和边界暴露 data-state=<id>。 。 。 .

浏览器适配器添加 qa-studio=agent 默认。 在该介绍中, 调试工作室只挂载所选应用程序窗格:没有工具栏,状态 采集器,目录导航,或人类种子警告. 直接打开工作室 没有该参数,则保留了完整的交互外壳. 应用程序拥有 适配器可以选择返回其中 studioPresentation: 'interactive'。 。 。 .

反应原生和其他非 DOM 主机

@app-studio/qa-studio/fetch 仅出口 installState, (中文(简体) ), statesFrom, (中文(简体) ), validateStateFixtureFile 国家定型。 没有达到 触摸导入时设置的 DOM 或节点, 因此 Metro 可以将其捆绑 :

import { installState, statesFrom } from '@app-studio/qa-studio/fetch';
import notes from './states/notes.state.json';

const [populated] = statesFrom(notes);
installState(populated); // replaces globalThis.fetch until restore()

node scripts/check-portable-entry.mjs dist/fetch.js (单位:千美元)pnpm check:portable(中文(简体) ) 将已建条目的导入图行走并失败于已建节点, DOM 全球 或DOM驱动程序/证据模块.

当地HTTP上的固定设备

节点入口可以通过真正的回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回 听着 每个世界都有新的固定器和一个私人的 installState 获取 目标; 它从未替换全局获取或返回到真实的 API .

import { randomUUID } from 'node:crypto';
import { createStateFixtureHttpServer } from '@app-studio/qa-studio/node';
import { createFixture } from './fixtures.js'; // Host-owned, browser-free factory.

const token = randomUUID();
const world = await createStateFixtureHttpServer({
  createFixture,
  browserOrigin: 'http://127.0.0.1:4003', // Exact browser origin of this run.
  token,
  tokenHeader: 'x-qa-world-token',
});
try {
  // Host configures its generated SDK with world.origin and the transport header.
  // Keep this world alive across navigation, reloads and new browser sessions.
} finally {
  await world.close();
}

tokenHeader 默认为 authorization 与 Bearer <token>. 偏爱 x-qa-world-token 当主机支持匿名/ 登录状态时: 集中添加 不更改业务授权或打开假用户的 SDK 请求 届会。 固定的人格仍然决定着会话设置. 此符号隔离 (b) 模拟传输.

设定 StudioConfig.mockTransport: 'http'键 StateFrame 与 dataMode="mock" mockTransport="http"。主机必须激活 页:1 匹配 在任何会议读取或屏幕之前 使用其现有的制备/接合。 改变拾取者需要一个 新的匹配世界; 它无法保持另一个固定的路径. prepare(state) 实值 等待着一个州立大学的孩子。 HTTP 模式安装无页面 截取器和调试工作室跳过其未使用的种子捕获. 边界暴露 data-mode="mock", (中文(简体) ), data-mock-transport="http" 财务报告和审定财务报表 data-qa-data-source="state-fixture-http"; 维持活模式 data-mode="live" 财务报告和审定财务报表 data-qa-data-source="real-http"。 。 。 .

回归的世界暴露了 origin, (中文(简体) ), fixtureId, (中文(简体) ), requests, (中文(简体) ), observations, (中文(简体) ), unmatched 财务报告和审定财务报表 diagnostics 元数据(方法、路径、状态、, 源代码和故障代码;没有标题或机构). reset() 排出当前请求 并再次援引工厂 相同的固定标识. 工厂必须返回 新的可变状态 。 重新装入不能调用重置 . close() 停止接收, 关闭收听器/连接并恢复私有目标. 主机拥有 浏览器/Vite进程,临时文件,信号处理和被限制的被撕毁.

只有GET/POST/PATCH/PUT/DELETE和JSON机构最多64个基B得到支持, 多段/上载,SSE和WebSockets都在这种运输之外. 重用已有的 适应这些能力或报告差距。 CORS 允许精确回转 浏览器来源并声明了运输/SDK头. 无效的 JSON, 错误的起源, 丢失的符牌和未申报的路线明显失败;未标记的总是失败, 不论固定默认。 答复正在进行 x-qa-data-source 财务报告和审定财务报表 x-qa-state-fixture. 生产节点处决被拒绝。 东道主也必须 保护它的 dev 浏览器配置,防止生产建立和防止其他 网络入侵。 节点工厂不得进口反应故事桶.

此 API 是源添加: 验证实际安装 /node 出口和出口 采用前反应类型. 一个版本字符串本身并不能证明添加 (b) 消费者需要经授权的包件/承诺/艺术品.

原始 App Studio 特性流

原画 specs/features/*.json 文件可以执行。 核心编译器 加入 feature.userExperience 改为可选 specs/forms/*.json,分别 if 并实现可移动流 Playwright 或 wdio/ Appium : (英语)

import { defineScenarioSuite } from '@app-studio/qa-studio/playwright';
defineScenarioSuite({
  test,
  expect,
  rootDir: process.cwd(),
  pattern: 'specs/features/*.json',
  forms: 'specs/forms/*.json',
  prepare: async ({ scenario }) => prepareFeatureWorld(scenario),
});

User 动作运行原名控件 eventId (或 表单精确 data-testid) (中文(简体) ). App 行动坚持路线、实际要求和 模式状态。 未生成的明确情景 v3 文件仍然支持 数据库,但 App Studio 工程不会将其流复制成一个 .

QA_BROWSER_PROFILE=fast 运行相同的编译特性流并写入其机器可读 默认时报告没有检查媒体。 Lightpanda 主机也可以请求 a 最后诊断PNG与 qa scenario run --engine lightpanda --profile fast --screenshots。 。 。 . 默认 proof 配置文件保持严格 视觉证据。 浏览器引擎选择仍然为应用程序所有 二、通过《公约》 qa scenario run --engine ...。 。 。 .

目标状态浏览器适配器

defineStatesSuite({
  test,
  expect,
  rootDir: process.cwd(),
  pattern: 'src/features/**/states/*.state.json',
});

Lightpanda 主机应该使用 @app-studio/qa-studio/puppeteer。 。 runPuppeteerScenarioSuite 财务报告和审定财务报表 runPuppeteerStateSuite 函数保存 同样的JSON图,请求证据和判决 没有Playwright Test's 纯铬上下文模拟 。 应用程序仍然拥有服务器启动, (c) 社区发展方案进程及其国家固定机制的准备回调.

两个套房在准备或导航前安装了 Lightpanda CSSOM 兼容性 当页面曝光 Puppeteer 的 evaluateOnNewDocument最小自定义适配器 没有这种能力,则继续得到支持并拥有文件的初始化. 修补使有索引的样式表可以使用并提供缺失的媒体规则分组 stitches等图书馆需要操作。 本地执行措施保持不变; 这样可以实现DOM执行,而不是CSS布局或视觉忠贞. 请求拦截 应用程序的设置仍然为主机所有.

自定义跑取器可以在其共享的页面厂中使用同样的准备 :

import { prepareLightpandaPage } from '@app-studio/qa-studio/puppeteer';

async function createPage() {
  const page = await browser.newPage();
  await prepareLightpandaPage(page); // Before the first goto, for states and scenarios.
  return page;
}

为文件寿命安装兼容性,包括后来的懒惰进口 并重新装入。 它与模拟请求的通过或释放无关.

双人套房支持 screenshots: true,或CLI's QA_BROWSER_SCREENSHOTS=true在关闭前抓取当前页面, 包括失败的运行。 他们写作 screenshot.png 财务报告和审定财务报表 screenshot.json 每个案件, 并发出带有绝对路径、案件状态和 fidelity: 'markdown'。 。 。 . 这些是Lightpanda文本放出诊断 严格的视觉证据。 已知历史占地者被拒绝 升级指令。 抓取错误失败请求的运行并保存其 原始产品出错.

套房接受一个明确的 outputDir,则 QA_SCENARIO_OUTPUT_DIR 或者说 QA_STATE_OUTPUT_DIR,则 <rootDir>/test-results/qa-scenarios 或者说 <rootDir>/test-results/qa-states. CLI 产生这些环境路径来自 scenario.evidence 财务报告和审定财务报表 state.evidence 在束缚中。 定制页面厂 只需要Puppeteer的土生土长 screenshot 方法; 最小适配器可以省略 当截图被禁用时。 自定义跑取器可以直接捕获 PNG :

import { captureLightpandaScreenshot } from '@app-studio/qa-studio/puppeteer';

const path = await captureLightpandaScreenshot(page, 'artifacts/current-page.png');

QA_STATE_ID 将执行范围缩小到一个固定点。 CLI也发出 QA_BROWSER_HEADLESS=true 财务报告和审定财务报表 QA_STUDIO_PRESENTATION=agent。适配器等待 检查非空DOM,除非 rendersNothing 实值 声明,收集页面错误,并报告伪造API的答案。 它又说没有 停留时间、标题或视频要求.

代理驱动的页面调试(本地 0.11.4- rc.3)

BrowserDebugSession 从 @app-studio/qa-studio/puppeteer 加入已有的 情景页和曝光会话、观察、复制、检查、控制和 基于光标的记录操作 。 应用程序主机保留进程 启动和服务器 探长管弦乐。 见 examples/agent-debug 六个工具 MCP集成,所有权规则,源图验证和本土验证. 本地软件包必须包含一个已核实的调试器构建; 本地主机 RC 可以在没有可执行环境的情况下通过包覆盖来选择 变量。 旧引擎可报告为无用。 检查默认为副作用检查; 代码执行要求 明确选入。 目标抓取暂停并恢复活页并影响 它的时机;它们不提供决定性的重放.

exposeBrowserDebugPage(page, {pageId, baseUrl, build, expiresMs?}) 出口 主机已存在, 已经导航过 Page 通过一个单一客户端, 不透明的回路 网索能力. 它回来了 {pageId, baseUrl, pageDebugEndpoint, close}· ; 永远不要登录端点或者在诊断中公布. 客户端先发送 QA.describePage 准确的页码、来源和 exclusiveControl: true。 。 。 . 添加剂反应 scriptInventory.supported 广告 compact-v1。 。 。 . 只有在广告上,客户才能选择通过 qaScriptInventory: 'compact-v1' 现有的 Debugger.enable 请求。 中继器在此扩展前剥离 本地 CDP 并承认该响应中选择的模式 。 谈判客户 接收范围 QA.scriptParsed 元数据而不是完整 Debugger.scriptParsed 租借地的活动;遗留客户和直接本地CDP保留标准活动. 内含地图声明成为SHA256/UTF8 长度元数据( e)sourceMapDeferred),没有保留地图正文. source(id) 只取出源头, 恢复其最终行/ 块 源映射URL声明并验证文摘和长度. 失踪, (一) 过时或过度申报拒绝解决; loadedScripts() 遗 物 轻而易举。 清单上限为1024,保留地图/应用 脚本领先于帮助者,在记录中有明确投放/无法获取的计数. 生成源仅限于2MiB及其被编码为3MiB的中继响应; 2; 超大小的源结果在操作失败时不关闭调试控制. 中继器只允许SDK调试器命令,并禁止副作用和 QA.pageAction (单位:千美元){action: 'click', selector} 或者说 {action: 'navigate', path} 打开 登记来源)。 关闭主机最后挡道的接力. 中继 清除只释放其调试资源, 并且从不关闭页面或 浏览器. 初始能力寿命默认为5分钟;接受客户 无法重新连接 。 本地请求 ID 和 SDK 动作 ID 并不意味着服务器 相关性.

SDK 记录的界限 incident 来自真实运行时控制台的事件 警告/错误和例外,以及页面对话框. onEvent(listener) 返回一个 未订阅函数; 它不会唤醒一个背景模型 。 远程值为 由协议原始/描述而未进行评估或获取者. 例外政策是孤立-全球: exceptions(policy) 需要实际 车主 exceptionPolicyOwner: {baseline, exclusiveIsolate: true} 合同. 附件没有规定政策。 准确 exception 财务报告和审定财务报表 promiseRejection 暂停 理由 分享例外所有权/事件处理权 政策租赁;保留原始理由和实际未发现的旗帜. exceptionStatus().supportedModes 来自 实际本地能力; 遗留的引擎不暗含支持未发现 预言。 校正的本地回调边界宣布所有三种模式 。 已确认的租约在五分钟后到期; 清理在释放自有例外暂停之前恢复已宣布的基准. 未知的外部基线拒绝突变;恢复/不确定性是明确的 内 exceptionStatus()中继器可以返回实际所有者 Page 状态 从一个 afterDetach 通过其输入的放行操作调用.

reproduce, (中文(简体) ), control,以及 waitForAction 接受可选主机 AbortSignal 取消他们的等待。 取消会删除等待者/ 计时器; 它确实 不取消已经发送的页面动作,不恢复暂停,也不停止会话.

版本与发布记录

@app-studio/qa-studio 共发布 37 个版本,首次发布于 2026/08/09;过去 12 个月发布了 37 个版本。

版本发布日期距今
0.11.6latest2026/11/062 天前
0.11.32026/11/017 天前
0.11.22026/10/2217 天前
0.11.12026/10/1622 天前
0.10.42026/10/081 个月前
0.10.3next2026/10/081 个月前

关于 @app-studio/qa-studio 的常见问题

@app-studio/qa-studio 是什么?

由组件测试和调试工作室共享的State Fixture数据,外加从App Studio原版功能规格编译的活浏览器适配器.

如何安装 @app-studio/qa-studio?

在项目目录运行 npm install @app-studio/qa-studio,或使用 pnpm add / yarn add / bun add。

@app-studio/qa-studio 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@app-studio/qa-studio 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@app-studio/qa-studio 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@app-studio/qa-studio 可以商用吗?

@app-studio/qa-studio 使用 UNLICENSED 许可。作者声明为 UNLICENSED,即不授予公开使用许可(与公共领域的 Unlicense 不同)。使用前需获得作者授权。以上为概括,不构成法律意见,请以许可原文为准。

@app-studio/qa-studio 的下载量有多少?

根据 npm 官方下载统计,@app-studio/qa-studio 在 2026/10/07 – 2026/11/05 这 30 天内被下载 1,903 次,日均约 63 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@app-studio/qa-studio 还在维护吗?

最新版本 0.11.6 发布于 2026/11/06(2 天前);至今共发布 37 个版本,其中过去 12 个月发布了 37 个;首次发布于 2026/08/09。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。