Cypress审计(灯塔和Pa11y)
运行 灯塔 财务报告和审定财务报表 Pa11y (英语) 直接审计 齐压 测试套房
目录
原始仓库
这是叉子 https://github.com/stefanonardo/cypress-audit 页面存档备份,存于互联网档案馆,它也是一个叉 https://github.com/mfrachet/cypress-audit 页面存档备份,存于互联网档案馆但两者基本上都在同一水平上, 当我们叉出.
关于这个叉子
我们很高兴能找到@mfrachet的仓库。 有些小事我们想补充一下:
- 修正一些已破碎的类型脚本定义
- 保持Pa11y和灯塔的最新发展
- 为 pa11y 和灯塔 创建了一个 npm 软件包
- 更新示例代码
- 以更多实例和解释来扩展 README
- 单独显示 pa11y 问题, 从而允许在 Cypress UI 中突出 HTML 元素
我们还决定只发布一个npm包,包括灯塔和pa11y. 因此,使用方法差别很小。 这个例子也发生了变化.
限制
- 灯塔的输出资料不足. 将 HTML 报告写入文件系统是可能的, 但是您需要自己处理文件( 请参看示例代码和( Writing Lighthouse HTML Reports to the file- system) [# writing- lighthouse-html- reports- to- the file- system])
- 测试跑取者正在用一个新的分页打开浏览器,从而失去了网站状态. Cookies和localStorage是可用的,因此可以在开始测试前使用Cypress命令来设置它们(例如登录设置cookie/localStorage)
安装
npm i -D @appsfactory/cypress-audit
限制
运行 cypress run 不与所有浏览器工作。 我们指出 -b chrome 手动.
实例和建议
请也看看 /examples 用于工作代码的文件夹.
我们放弃了分开 e2e 财务报告和审定财务报表 audit 测试两个不同的文件夹。 所以我们有 cypress/audit/TEST.audit.cy.ts 财务报告和审定财务报表 cypress/e2e/TEST.cy.ts这意味着,我们可以在编审过程中进行e2e测试,每次合并和定期审计,如果我们愿意的话.
请注意: 这也意味着,如果您想要这样做,您需要在您的cypress.config.ts中添加以下一行:
specPattern: ['cypress/e2e/**/*.cy.ts', 'cypress/audit/**/*.audit.cy.ts'],
您可以为此创建两个不同的 npm 脚本 :
"cypress:run": "cypress run -b chrome --spec 'cypress/e2e/**/*.cy.ts'",
"cypress:audit": "cypress run -b chrome --spec 'cypress/audit/**/*.cy.ts'",
配置
基础
设置您的 Cypress 配置来准备审计,并将 pa11y 和/或灯塔传递给任务执行:
import { defineConfig } from "cypress";
import { lighthouse, pa11y, prepareAudit } from "@appsfactory/cypress-audit";
export default defineConfig({
e2e: {
baseUrl: "http://localhost:3000",
specPattern: ["cypress/e2e/**/*.cy.ts", "cypress/audit/**/*.audit.cy.ts"],
setupNodeEvents(on, config) {
on("before:browser:launch", (browser, launchOptions) => {
prepareAudit(launchOptions);
});
on("task", {
pa11y: pa11y(),
lighthouse: lighthouse(),
});
},
},
});
向您添加命令 commands.ts 并且不要忘记包括类型引用:
/// <reference types="cypress" />
/// <reference types="@appsfactory/cypress-audit/packages/lighthouse/commands" />
/// <reference types="@appsfactory/cypress-audit/packages/pa11y/commands" />
import "@appsfactory/cypress-audit/packages/pa11y/commands";
import "@appsfactory/cypress-audit/packages/lighthouse/commands";
现在你可以使用 cy.pa11y() 财务报告和审定财务报表 cy.lighthouse() 测试中的命令 :
it("should pass lighthouse test", () => {
cy.lighthouse();
});
it("should pass pa11y test", () => {
cy.pa11y();
});
高级灯塔
命令的选项已输入 。 这样您就可以使用智能来进行配置.
例如,对于灯塔,您可以创建新的命令并覆盖默认配置 commands.ts。在这个例子中,我们也允许合并自定义阈值、旗帜和配置:
Cypress.Commands.add(
"lighthouseWithDefaultSettings",
(
overwriteTresholds: Cypress.LighthouseThresholds = {},
overwriteFlags: Cypress.LighthouseFlags = {},
overwriteConfig: Cypress.LighthouseConfig = {}
) => {
cy.lighthouse(
// Thresholds
{
// Add more lighthouse options here for more tests
accessibility: 80,
// In case you want to overwrite the default thresholds, you can do it via the overwriteTreshholds parameter
...overwriteTresholds,
},
// Lighthouse "Flags"
{
// Add more lighthouse flags here for more tests
formFactor: "desktop",
screenEmulation: {
width: 1350,
height: 940,
mobile: false,
},
throttling: {
rttMs: 40,
throughputKbps: 11024,
cpuSlowdownMultiplier: 1,
requestLatencyMs: 0,
downloadThroughputKbps: 0,
uploadThroughputKbps: 0,
},
// In case you want to overwrite the default flags, you can do it via the overwriteFlags parameter
...overwriteFlags,
},
// Lighthouse "Config"
{
// Add more lighthouse config here for more tests
extends: "lighthouse:default",
settings: {
output: "html",
},
// In case you want to overwrite the default config, you can do it via the overwriteConfig parameter
...overwriteConfig,
}
);
}
);
别忘了在您身上加上他的新命令 support/index.d.ts数字 :
/// <reference types="cypress" />
// cypress/support/index.d.ts
declare namespace Cypress {
interface Chainable {
lighthouseWithDefaultSettings(
overwriteTresholds?: Cypress.LighthouseThresholds,
overwriteFlags?: Cypress.LighthouseFlags,
overwriteConfig?: Cypress.LighthouseConfig
): void;
}
}
现在你可以在测试文件中使用:
it("should pass lighthouse test", () => {
// Arguments are optional, because we defined default values.
cy.lighthouseWithDefaultSettings({ accessibility: 90 });
});
高级 Pa11y
命令的选项已输入 。 这样您就可以使用智能来进行配置.
对于 pa11y , 例如您可以创建新的命令并覆盖默认配置 commands.ts。在此例子中,我们也允许合并自定义选项:
Cypress.Commands.add(
"pa11yWithDefaultSettings",
(overwriteOptions: Cypress.Pa11yOptions = {}) => {
cy.pa11y({
// Add more pa11y options here
level: "WCAG2AA",
// Hide the nuxt dev tools elements
hideElements: "#nuxt-devtools-container",
// allow one failing test
threshold: 1,
// Add more pa11y runners here. Some results are redundant now, but you will also find more issues. Default is just axe.
runners: ["axe", "htmlcs"],
// In case you want to overwrite the default options, you can do it via the overwriteOptions parameter
...overwriteOptions,
});
}
);
别忘了在您身上加上他的新命令 support/index.d.ts数字 :
/// <reference types="cypress" />
// cypress/support/index.d.ts
declare namespace Cypress {
interface Chainable {
pa11yWithDefaultSettings(overwriteOptions?: Pa11yOptions): void;
}
}
现在你可以在测试文件中使用:
it("should pass pa11y test", () => {
cy.pa11yWithDefaultSettings({
// actions are performed before the audit, see section below
actions: ["set field #text to Hallo"],
});
});
编写准备审计的 pa11y 动作
你可以用这个 actions 用于在审计前采取行动的参数。 这有助于在审计前建立网站状态. 您可以使用cy命令登录( 设置 cookie 和本地存储) 。 但对于审计,打开了一个新的分页,所以如果需要,需要设置网站状态. 例如,打开一个模式或输入一些文本等:
it("should pass pa11y test", () => {
cy.pa11yWithDefaultSettings({
// actions are performed before the audit, see section below
actions: ["set field #text to Hallo"],
});
});
关于这些行动的详细资料,请访问 pa11y 文档
将灯塔 HTML 报告写入文件系统
为了将灯塔HTML报告写入文件系统,您需要更改灯塔命令的第三个参数:
cy.lighthouse(
{
accessibility: 80,
},
undefined,
{
extends: "lighthouse:default",
settings: {
output: "html",
},
}
);
在你体内 Cypress.config.js 你需要自己储存文件 在那里你需要它们。 一个例子是:
import { defineConfig } from "cypress";
import { lighthouse, pa11y, prepareAudit } from "@appsfactory/cypress-audit";
import fs from "fs";
import path from "path";
export default defineConfig({
e2e: {
baseUrl: "http://localhost:3000",
specPattern: ["cypress/e2e/**/*.cy.ts", "cypress/audit/**/*.audit.cy.ts"],
// setup cypress lighthouse
setupNodeEvents(on, config) {
on("before:browser:launch", (browser, launchOptions) => {
prepareAudit(launchOptions);
});
on("task", {
pa11y: pa11y(),
lighthouse: lighthouse((result) => {
const htmlReport = result.report;
if (typeof htmlReport !== "string") {
console.error("No or too many HTML report(s) found");
return;
}
const reportsDir = path.join(import.meta.dirname, "cypress/reports");
if (!fs.existsSync(reportsDir)) {
fs.mkdirSync(reportsDir);
}
const url = new URL(result.lhr.finalDisplayedUrl);
const sanitizedUrlPath = url.pathname.replace(/\//g, "_");
fs.writeFileSync(
`${reportsDir}/${sanitizedUrlPath}.html`,
htmlReport
);
}),
});
},
},
});