@antiwork/shortest

中文文档
0.4.9发布于 2025/04/01MITTypeScriptESM + CJS近 30 天下载 6.2万

AI-powered natural language end-to-end testing framework

原始使用文档
文档目录13 节
  1. Features
  2. Installation
  3. Quick start
  4. Using callback functions
  5. Lifecycle hooks
  6. Chaining tests
  7. API Testing
  8. Running tests
  9. GitHub 2FA login setup
  10. Environment setup
  11. CI setup
  12. Resources
  13. Prerequisites

Shortest

AI-powered natural language end-to-end testing framework.

Features

  • Natural language test writing
  • AI-powered test execution using Claude computer use API
  • Built on Playwright
  • GitHub integration with 2FA support

Installation

Use the shortest init command to streamline the setup process in a new or existing project.

The shortest init command will:

npx @antiwork/shortest init

This will:

  • Automatically install the @antiwork/shortest package as a dev dependency if it is not already installed
  • Create a default shortest.config.ts file with boilerplate configuration
  • Generate a .env.local file (unless present) with placeholders for required environment variables, such as SHORTEST_ANTHROPIC_API_KEY or ANTHROPIC_API_KEY
  • Add .env.local and .shortest/ to .gitignore

Quick start

  1. Determine your test entry and add your Anthropic API key in config file: shortest.config.ts
import type { ShortestConfig } from "@antiwork/shortest";

export default {
  headless: false,
  baseUrl: "http://localhost:3000",
  browser: {
    contextOptions: {
      ignoreHTTPSErrors: true,
    },
  },
  testPattern: "**/*.test.ts",
  ai: {
    provider: "anthropic",
  },
} satisfies ShortestConfig;

The Anthropic API key defaults to SHORTEST_ANTHROPIC_API_KEY / ANTHROPIC_API_KEY environment variables. Can be overwritten via ai.config.apiKey.

Optionally, you can configure browser behavior using the browser.contextOptions property in your configuration file. This allows you to pass custom Playwright browser context options.

  1. Create test files using the pattern specified in the config: app/login.test.ts
import { shortest } from "@antiwork/shortest";

shortest("Login to the app using email and password", {
  username: process.env.GITHUB_USERNAME,
  password: process.env.GITHUB_PASSWORD,
});

Using callback functions

You can also use callback functions to add additional assertions and other logic. AI will execute the callback function after the test execution in browser is completed.

import { shortest } from "@antiwork/shortest";
import { db } from "@/lib/db/drizzle";
import { users } from "@/lib/db/schema";
import { eq } from "drizzle-orm";

shortest("Login to the app using username and password", {
  username: process.env.USERNAME,
  password: process.env.PASSWORD,
}).after(async ({ page }) => {
  // Get current user's clerk ID from the page
  const clerkId = await page.evaluate(() => {
    return window.localStorage.getItem("clerk-user");
  });

  if (!clerkId) {
    throw new Error("User not found in database");
  }

  // Query the database
  const [user] = await db
    .select()
    .from(users)
    .where(eq(users.clerkId, clerkId))
    .limit(1);

  expect(user).toBeDefined();
});

Lifecycle hooks

You can use lifecycle hooks to run code before and after the test.

import { shortest } from "@antiwork/shortest";

shortest.beforeAll(async ({ page }) => {
  await clerkSetup({
    frontendApiUrl:
      process.env.PLAYWRIGHT_TEST_BASE_URL ?? "http://localhost:3000",
  });
});

shortest.beforeEach(async ({ page }) => {
  await clerk.signIn({
    page,
    signInParams: {
      strategy: "email_code",
      identifier: "[email protected]",
    },
  });
});

shortest.afterEach(async ({ page }) => {
  await page.close();
});

shortest.afterAll(async ({ page }) => {
  await clerk.signOut({ page });
});

Chaining tests

Shortest supports flexible test chaining patterns:

// Sequential test chain
shortest([
  "user can login with email and password",
  "user can modify their account-level refund policy",
]);

// Reusable test flows
const loginAsLawyer = "login as lawyer with valid credentials";
const loginAsContractor = "login as contractor with valid credentials";
const allAppActions = ["send invoice to company", "view invoices"];

// Combine flows with spread operator
shortest([loginAsLawyer, ...allAppActions]);
shortest([loginAsContractor, ...allAppActions]);

Shortest's style allows non-engineers such as designers, marketers, and PMs to write tests. Here are some examples:

shortest("visit every page and ensure no typos");
shortest("visit every page and ensure mobile layout isn't janky");
shortest("visit every page and ensure dark mode is considered");

API Testing

Test API endpoints using natural language

const req = new APIRequest({
  baseURL: API_BASE_URI,
});

shortest(
  "Ensure the response contains only active users",
  req.fetch({
    url: "/users",
    method: "GET",
    params: new URLSearchParams({
      active: true,
    }),
  }),
);

Or simply:

shortest(`
  Test the API GET endpoint ${API_BASE_URI}/users with query parameter { "active": true }
  Expect the response to contain only active users
`);

Running tests

pnpm shortest                   # Run all tests
pnpm shortest login.test.ts     # Run specific tests from a file
pnpm shortest login.test.ts:23  # Run specific test from a file using a line number
pnpm shortest --headless        # Run in headless mode using

You can find example tests in the examples directory.

GitHub 2FA login setup

Shortest currently supports login using Github 2FA. For GitHub authentication tests:

  1. Go to your repository settings
  2. Navigate to "Password and Authentication"
  3. Click on "Authenticator App"
  4. Select "Use your authenticator app"
  5. Click "Setup key" to obtain the OTP secret
  6. Add the OTP secret to your .env.local file or use the Shortest CLI to add it
  7. Enter the 2FA code displayed in your terminal into Github's Authenticator setup page to complete the process
shortest --github-code --secret=<OTP_SECRET>

Environment setup

Required in .env.local:

ANTHROPIC_API_KEY=your_api_key
GITHUB_TOTP_SECRET=your_secret  # Only for GitHub auth tests

CI setup

You can run Shortest in your CI/CD pipeline by running tests in headless mode. Make sure to add your Anthropic API key to your CI/CD pipeline secrets.

Resources

Prerequisites

  • React >=19.0.0 (if using with Next.js 14+ or Server Actions)
  • Next.js >=14.0.0 (if using Server Components/Actions)

[!WARNING] Using this package with React 18 in Next.js 14+ projects may cause type conflicts with Server Actions and useFormStatus If you encounter type errors with form actions or React hooks, ensure you're using React 19

版本与发布记录

@antiwork/shortest 共发布 23 个版本,首次发布于 2024/11/29;过去 12 个月发布了 0 个版本。

版本发布日期距今
0.4.9latest2025/04/011.6 年前
0.4.82025/03/251.6 年前
0.4.72025/03/171.6 年前
0.4.62025/03/091.7 年前
0.4.52025/03/021.7 年前
0.4.42025/02/231.7 年前

关于 @antiwork/shortest 的常见问题

@antiwork/shortest 是什么?

AI-powered natural language end-to-end testing framework

如何安装 @antiwork/shortest?

在项目目录运行 npm install @antiwork/shortest,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@ai-sdk/anthropic(^1.1.15)、@ai-sdk/provider(^1.0.10)、ai(^4.1.53)、dotenv(^16.4.5)、esbuild(^0.20.1)、expect(^29.7.0)、mailosaur(^8.7.0)、playwright(^1.50.1)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 shortest,可以用 npx shortest 直接运行。

@antiwork/shortest 支持 TypeScript 吗?

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

@antiwork/shortest 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@antiwork/shortest 需要什么版本的 Node.js?

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

@antiwork/shortest 可以商用吗?

@antiwork/shortest 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@antiwork/shortest 的下载量有多少?

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

@antiwork/shortest 还在维护吗?

最新版本 0.4.9 发布于 2025/04/01(1.6 年前);至今共发布 23 个版本,其中过去 12 个月发布了 0 个;首次发布于 2024/11/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。