验收 运行时间
快速启动
- 使用软件包安装
npm install -D checksumai或者说yarn add checksumai -D。 。 。 . - 导航到目录中要初始化校验和测试文件夹并运行的地方
npx checksumai init。 。 。 . - 在新创建的
checksum文件夹 :- 定义
CHECKSUM_API_KEY财务报告和审定财务报表BASE_URL内checksum/.env或您的外壳; 启动配置读取process.env.CHECKSUM_API_KEY财务报告和审定财务报表process.env.BASE_URL!。 。 。 . - 更新
login.ts与您的 Playwright 登录流量。 有关当前parms-object API,请参看下面的登录函数部分. - 审查起始示例
checksum/tests/examples/example.checksum.spec.ts财务报告和审定财务报表checksum/tests/examples/example.checksum.md。 。 。 . - 重运行
npx checksumai init之后在不覆盖您已经定制的文件的情况下, 将任何缺失的启动文件回填 .
- 定义
- 运行
npx playwright install --with-deps以安装 Playwright 依赖性. - 运行
npx checksumai test执行启动器.checksum.spec.ts示例并验证您的登录设置. - 还没有的话就去拜访一下 app. checksum.ai (英语) 以完成配置并生成测试。 然后,等待拉动请求(PR)的创建和批准.
启动文件
checksum/login.ts显示运行时登录回调签名和在哪里environment, (中文(简体) ),user,以及config从来.checksum/tests/examples/example.checksum.spec.ts是一个最小的 TypeScript 启动器init(), (中文(简体) ),defineChecksumTest(...),以及login(page)。 。 。 .checksum/tests/examples/example.checksum.md是一个最小的减速流量启动器。 替换占位符appId财务报告和审定财务报表checksumTestId使用前的数值.- Repo 镜像同时读取
.checksum.spec.ts财务报告和审定财务报表.checksum.md文件,因此两个启动格式都在checksumai init。 。 。 .
登录函数
- 此函数在每次测试开始时执行 .
- 我们建议每次测试都使用一致的种子用户。 例如,在每次测试之前,调用一个创建用户的webhook,用数据种子,并返回用户名和密码. 这种方法确保测试可靠性并允许平行的测试执行. 配置此网点 在您的项目中 以一致的测试生成.
- 登录后,断言登录成功. Playwright等待断言正确,确保页面在进行前做好互动准备.
- 要在测试之间重新使用认证状态,请参考Playwright指南: 认证。在登录功能开始时,检查用户是否已经认证,如果已经认证,则返回.
- 使用
ChecksumLoginFunction类型以正确执行登录函数 :import { ChecksumLoginFunction } from "@checksum-ai/runtime"; const login: ChecksumLoginFunction = async ( page, { environment, user, config } ) => { // environment contains the selected environment from checksum.config.ts. // user contains the selected credentials for that environment. // config is the loaded checksum.config.ts object. const loginUrl = environment.loginURL ?? "/login"; await page.goto(loginUrl); await page.getByPlaceholder("Email").fill(user.username ?? ""); await page.getByPlaceholder("Password").fill(user.password ?? ""); await page.getByRole("button", { name: "Log in" }).click(); await page.waitForURL(new URL("/", environment.baseURL).toString()); }; export default login;
当定义多个环境或角色时,帮助者喜欢 login(page, { environment, role }) 财务报告和审定财务报表 getEnvironment({ name, userRole }) 决定哪个 environment 财务报告和审定财务报表 user 到达此函数.
校验和 AI 魔法
Checksum生成的测试基于Playwright. 当使用带有API密钥的Checksum runtime CLI执行时,Checksum会增强Playwright的功能,提高测试可靠性并自动维持测试. 每次增强都使用 checksum.config.ts 文档.
智能选择器
当生成测试时, 校验和会为每个动作存储大量元数据( 存储于 checksum/test-data 文件夹). 如果传统的选择器失败,此元数据用于定位目标元素. 例如,如果一个测试用其ID识别一个元素,但ID更改,Checksum会利用其他数据点(如元素类,文本,父母)来定位该元素. 使用 checksumSelector("<id>") 将一个动作与其元数据链接的方法。 不要改变身份证.
校验和AI
如果Smart Selectioners也失败了,Checksum的自定义训练模型可以再生测试失败的部分. 在这种情况下,该模式可以增加、删除或改变实现相同目标的行动,而不改变说法。 假设是,只要断言通过,模型就成功固定了测试. 使用 checksumAI 为了实现这一行为,将每个步骤围起来的方法.
使用两者的示例 checksumSelector 财务报告和审定财务报表 checksumAI数字 :
await checksumAI("Save the form and continue", () =>
page
.checksumSelector("gIexv")
.getByRole("button", { name: "Save" })
.click()
);
你可以根据我们的模型修改描述 此外,您还可以包含仅包含ChecksumAI描述的步骤,提示我们的模型生成Playwright代码. 譬如说, await page.checksumAI("Click on 'New Task' button") 没有实际行动,我们的模型将产生必要的 Playwright 代码。 你甚至可以这样写整个测试.
模拟数据
在生成测试时,Checksum记录所有网络响应,允许测试在同一上下文中运行. 这些录音作为HAR文件存储,保存于 checksum/test-data/har 文件夹。 使用这种方法对调试新生成的测试特别有用,特别是如果测试数据库/文本不同于用于测试生成的数据库/文本. 请注意,如果您的网络响应格式发生变化,被模拟的数据可能无法如预期的那样工作.
校验和配置
除了标准测试运行配置 playwright.config.ts,使用 checksum.config.ts 用于配置测试运行的文件.
{
/**
* Checksum Run mode.
* Normal is currently the only supported mode.
*/
runMode: RunMode.Normal,
/**
* Define CHECKSUM_API_KEY in checksum/.env or your shell.
* You can find it in https://app.checksum.ai/#/settings/
*/
apiKey: process.env.CHECKSUM_API_KEY,
/**
* Define your test run environments and test users within each environment.
* The environments must be aligned with those set here:
* https://app.checksum.ai/#/settings/
*/
environments: [{
name: 'staging';
users: [
{
role: "host",
username: "<host username>",
password: "<host password>",
},
{
role: "guest",
username: "<guest username>",
password: "<guest password>",
},
],
baseURL: 'staging.mydomain.com';
loginURL: 'staging.mydomain.com/login';
default: true;
}]
options: {
/**
* Use Checksum Smart Selector to
* recover from failing to locate an element for an action
*/
useChecksumSelectors: true,
/**
* Use Checksum AI to
* recover from a failed action or assertion
* @actions - enable recovery from checksumAI steps
* @assertions - enable recovery from assertion steps
* @visualComparison - enable visual comparison recovery when using toHaveScreenshot assertions
*/
useChecksumAI: { actions: true, assertions: false, visualComparison: false },
/**
* Whether to use recorded network responses when running your tests
*/
useMockData: false,
/**
* Whether to upload the test reports to Checksum cloud
* allowing you to view them at https://app.checksum.ai/#/test-runs.
* Note: Only relevant if Playwright reporter config is set to HTML
* Note: Reports will be saved locally either way (according to Playwright configs)
* and can be viewed using the CLI command show-reports.
*/
hostReports: !!process.env.CI,
}
}
剧作家配置
一个 Playwright 配置文件 playwright.config.ts 应该可供 Playwright 测试跑取器使用,以便提供项目配置.
为了方便,我们扩展了配置,允许添加 playwright-extra-plugins 软件包.
可用的插件可见于 https://github.com/berstend/puppeteer-extra/tree/master/packages/playwright-extra 互联网档案馆的存檔,存档日期2014-12-12
要添加插件 :
- 使用您的软件包管理器( yarn, npm, pnpm) 安装
- 导入您的插件
playwright.config.ts文件 - 在那个
projects定义use,将其添加到剧作家Extra阵列 - 在添加数组之前或期间确定初始化插件
示例 playwright.config.ts 与 puppeteer-extra-plugin-stealth 插件 :
import { PuppeteerExtraPlugin } from "puppeteer-extra-plugin";
import StealthPlugin from "puppeteer-extra-plugin-stealth"; // <--- Added import line
export default defineConfig<{ playwrightExtra?: PuppeteerExtraPlugin[] }>({
// ....
projects: [
{
name: "chromium",
testMatch: /checksum.spec/,
use: {
...devices["Desktop Chrome"],
playwrightExtra: [StealthPlugin()], // <--- Initialized and added to the playwrightExtra array
},
},
],
});
参见内部更详细的说明 checksum-root/playwright.config.ts 文件
校验和帮助 API
帮助者从初始呼叫中解析到导入的@ checksum-ai/runtime init 方法,如下:
import { test as base } from "@playwright/test";
import { init, IChecksumPage } from "@checksum-ai/runtime";
const { test, expect, defineChecksumTest, login, checksumAI } = init(base);
function init(base: ChecksumTestType<PlaywrightTestArgs>): {
/**
* The Playwright test instance enhanced by Checksum
*/
test: ChecksumTestType<ChecksumPlaywrightTestArgs>;
/**
* The login method which calls the user defined login function
*/
login: (
page: Page,
{ role, environment }?: { role?: string; environment?: string }
) => Promise<void>;
/**
* The test title definition along with the test id
* used by Checksum to identify the test
*/
defineChecksumTest: (title: string, testId: string) => string;
/**
* The Playwright expect instance enhanced by Checksum
*/
expect: ChecksumExpect;
/**
* Wrap each test action with this method to let
* Checksum recover from failure using our test recover AI agent
*/
checksumAI: (description: string, testFunction: Function) => Promise<any>;
/**
* Return environment data as defined in the checksum configuration
* given the environment name and userRole, along with a login function
* for this environment and user combination
*/
getEnvironment: ({
name,
userRole,
}: {
name?: string;
userRole?: string;
}) => {
environment: ChecksumConfigEnvironment;
user: EnvironmentUser;
login: (
page: Page,
{ role }?: { role?: string }
) => Promise<void>;
};
};
校正和页 API
interface ChecksumPage extends Page {
/**
* Affiliates the test step with selection data calculated during test generation and used as part of the recovery mechanism in case Playwright fails to locate the element
*/
checksumSelector: (id: string) => ChecksumPage;
/**
* Wraps a test step allowing ChecksumAI to recover from failures or even generate
* the required Playwright code when no callback is provided.
* Can be chained with `.withDialog` to automatically listen to browser dialogs
* or with `.skipAutoRecovery` to prevent recovery attempts.
*/
checksumAI: (thought: string, body?: () => any) => Promise<any> | ChecksumPage;
/**
* Resolves file-upload asset names against the configured assets folder.
*/
resolveAssetsFolder: (assets: string[]) => string[];
/**
* For multi-tab flows: returns the ChecksumPage by order of appearance, where 0 is the initially opened tab.
*/
getPage(index: number): Promise<ChecksumPage>;
/**
* Creates a compound selection by grouping multiple anchors and optionally
* resolving a target element relative to their common parent.
*/
compoundSelection: {
(
anchors: (base: Locator) => Array<Locator | string>,
target?: (base: Locator) => Locator | string
): ChecksumLocator;
(selection: {
anchors: (base: Locator) => Array<Locator | string>;
target?: (base: Locator) => Locator | string;
}): ChecksumLocator;
};
/**
* When required to login mid-test, use reauthenticate with the user's role. Note: It is not possible to change environments during a single test run.
*/
reauthenticate: (role: string) => Promise<void>;
/**
* When required to handle actions that involve browser Native Dialogs that are part of the WebAPI,
* use waitForDialog to listen for any dialog events, and handle them accordingly inside the handler.
* Note: waitForDialog can only work within a checksumAI.withDialog call which initiates the dialog listener.
*
* await checksumAI.withDialog("delete item and confirm", () => {
* await page.locator('.delete').click();
* await page.waitForDialog().then((confirm) => {
* confirm.accept();
* });
* });
*/
waitForDialog: (timeout?: number) => Promise<Dialog>;
}
校验和标记 API
ChecksumLocator 扩展了现有的 Playwright Locator , 增加了以下功能 :
- 画布点击
- 复选
interface ChecksumLocator extends Locator {
/*
* Click on certain text within the canvas element the locator chain points to.
* When more than one element with the same text exists, uses the rectSizeIndex
* to resolve the target element by its bounding box size, 0 being the largest.
* Example:
* await page.locator('canvas').canvasClick('graph-point-1', 1); // clicking on the 2nd largest
*/
canvasClick: (canvasText: string, rectSizeIndex?: number) => Promise<void>;
/**
* Will create a compound selection that selects elements by grouping multiple locators as anchors
* and finding the target elements, if specified, from their common root parent.
* If no target is provided, the compound selection will return a locator to the common parents that were calculated from the anchors.
*
* **Usage example**
*
* ```js
* await page.compoundSelection(
* (base) => [base.getByText("<selector to first anchor>""), page.locator("selector to second anchor"), "<text content of third anchor>"],
* (base) => base.locator("<relative selector to target element>")
* ]).first().click();
* ```
*
* @param anchors Method that returns array of locators and/or text context, to group and calculate the common parent from.
* The method receives the base locator as an argument, which is the relative locator or page that the compound selection is called on.
* The method should return an array of locators or strings that point at the anchor elements.
* @param target [optional] Method that returns the relative locator or string content that will point at the target element from the common parent
* that was calculated from the anchors.
* If no target is provided, the compound selection will return a locator pointing at the common parents.
* @returns Locator to the common parent(s) or the target element(s) if specified.
*/
compoundSelection(
anchors: (base: Locator) => Array<Locator | string>,
target?: (base: Locator) => Locator | string
): ChecksumLocator;
/**
* Will create a compound selection that selects elements by grouping multiple locators as anchors
* and finding the target elements, if specified, from their common root parent.
* If no target is provided, the compound selection will return a locator to the common parents that were calculated from the anchors.
*
* **Usage example**
*
* ```js
* await page.compoundSelection({
* anchors: (base) => [base.getByText("<selector to first anchor>""), page.locator("selector to second anchor"), "<text content of third anchor>"],
* target?: (base) => base.locator("<relative selector to target element>")
* }).first().click();
* ```
* @returns Locator to the common parent(s) or the target element(s) if specified.
*/
compoundSelection(selection: {
/**
* Method that returns array of locators and/or text context, to group and calculate the common parent from.
* The method receives the base locator as an argument, which is the relative locator or page that the compound selection is called on.
* The method should return an array of locators or strings that point at the anchor elements.
*
* @param base Base locator that the compound selection is called on.
*/
anchors: (base: Locator) => Array<Locator | string>;
/**
* Method that returns the relative locator or string content that will point at the target element from the common parent
* that was calculated from the anchors.
* If the target is null, the compound selection will return a locator pointing at the common parents.
*
* @param base Base locator that the compound selection is called on.
*/
target?: (base: Locator) => Locator | string;
}): ChecksumLocator;
}
CLI 命令
init- 初始化校验和目录及配置.test- 运行校验和测试。 接受全部 播放鼠标命令行旗覆盖checksum.config.ts,通过 JSON 作为字符串--cksm-config启用--cksm-title="<message>"为运行设置自定义承诺消息.show-report- 本地显示最新的 HTML 运行报告 。 只有在完成配置以输出 HTML 报表的测试运行后才适用 .dotenv- 管理环境变量。 使用--download下载.env用于您的项目的文件。 一个--api-key参数如果不在checksum.config.ts。 。 。 . 实例:npx checksumai dotenv --downloadnpx checksumai dotenv --download --api-key=<apiKey>
解决问题
问:我在进行"npx checkumai测试"时,甚至在测试开始前,就看到各种例外.
答:如果你有Playwright的预安装版本,它可能与Checksum不相容. 删除 Playwright 和 Checksum 库, 删除相关的文件夹 node_modules运行 npm install -D checksumai。 。 。 .