WebdriverIO

npm install @tracera/webdriverio

已在 Node.js 22.19–26.12 和 WebdriverIO 9–10.0 上测试(见 自动化测试适配器)。@tracera/webdriverio。

在 wdio.conf.ts(Mocha)中:

export const config = {
  reporters: ['spec', ['@tracera/webdriverio/reporter', {}]],
  services: [['@tracera/webdriverio/service', {}]],
  mochaOpts: {
    require: ['@tracera/webdriverio/setup'],
  },
};

对于 Cucumber,注册相同的 reporter 与 service。优先在 Scenario 上打标签 @tracera.id:‹id›(可选 @tracera.name:…),或在 Before hook 或 step 中调用 tracera.testCase。

环境变量、运行模式与重试见 自动化测试适配器。

重试时 Env 键:WEBDRIVERIO_RETRY。

绑定 testCaseId 与 autotestName

通过 mochaOpts.require 加载 @tracera/webdriverio/setup,并导入 tracera 和 annotations。Mocha annotations 名称为字面量(无 {param})。

Mocha — 在声明时(推荐):

import { annotations } from '@tracera/webdriverio';

it(
  'login',
  annotations(42, 'e2e/login', async () => {
    await browser.url('https://example.com');
  }),
);

Mocha — 在测试中(若 annotations 已绑定用例则可省略):

import { tracera } from '@tracera/webdriverio';

it('login', async () => {
  tracera.testCase(42, 'e2e/login');
  await browser.url('https://example.com');
});

Cucumber — Scenario 标签(推荐):

@tracera.id:42
@tracera.name:e2e%2Flogin
Scenario: login
  Given I open the login page

若不用 Scenario 标签绑定,则在 Before hook 或 step 中调用 tracera.testCase。

Skip

使用 Mocha 标准 skip(this.skip())可选:在调用 skip 前用 tracera.comment 写入结果 comment

import { annotations, tracera } from '@tracera/webdriverio';

it(
  'login',
  annotations(42, 'e2e/login', async function () {
    if (!process.env.READY) {
      tracera.comment('env not ready');
      this.skip();
    }
    await browser.url('https://example.com/login');
  }),
);

步骤

使用 tracera.step:调用 tracera.step(title, fn),在类方法上使用装饰器 @tracera.step("…"),或 tracera.step("…")(fn)。装饰器标题中的 {name} / {0} 从方法参数填入;也可以传入返回标题的函数。调用形式不会填充 {name} / {0}——请传入已拼好的标题字符串。会等待异步方法与 Promise。 加载 @tracera/webdriverio/setup 后,标准 Mocha beforeEach / afterEach 已仪器化 — 其中的步骤进入结果的 准备 / 清理。套件级钩子(如 before / after)不会上报。

import { tracera } from '@tracera/webdriverio';

beforeEach(async () => {
  await tracera.step('open shop', async () => {
    await browser.url('/shop');
  });
});

it('checkout', async () => {
  tracera.testCase(10, 'e2e/checkout');
  await tracera.step('add to cart', async () => {
    await $('[data-testid=add]').click();
  });
});

afterEach(async () => {
  await tracera.step('cleanup', async () => {
    await browser.url('/cart/clear');
  });
});

方法上的装饰器:

import { tracera } from '@tracera/webdriverio';

class Cart {
  @tracera.step('add {item}')
  async addToCart(item: string) {
    // …
  }
}

注释、错误与附件

评论、错误与附件:自动化测试适配器。

import { tracera } from '@tracera/webdriverio';

it('login', async () => {
  tracera.testCase(42, 'e2e/login');
  tracera.comment('result-level note');
  tracera.error('result-level error text');

  await tracera.step('open login', async () => {
    await browser.url('/login');
    tracera.comment('landed on login');
    tracera.attachment({
      fileName: 'suite-log.txt',
      mimeType: 'text/plain',
      data: new TextEncoder().encode('finished login flow'),
    });
  });
});

参数化测试

import { annotations } from '@tracera/webdriverio';

const rows = [
  { id: 42, name: 'e2e/login-ok', path: '/login' },
  { id: 43, name: 'e2e/login-sso', path: '/login/sso' },
];

for (const row of rows) {
  it(
    row.name,
    annotations(row.id, row.name, async () => {
      await browser.url(`https://example.com${row.path}`);
    }),
  );
}

或在测试中调用 tracera.testCase(row.id, row.name),代替 annotations。