Skip to content

Commit 82a06d4

Browse files
author
rocketraccoon
committed
feat: tags
1 parent 55b1d7e commit 82a06d4

File tree

20 files changed

+218
-22
lines changed

20 files changed

+218
-22
lines changed

src/browser/existing-browser.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ export class ExistingBrowser extends Browser {
9191
protected _calibration?: CalibrationResult;
9292
protected _clientBridge?: ClientBridge;
9393
protected _cdp: CDP | null = null;
94+
protected _tag: Set<string> = new Set();
9495

9596
constructor(config: Config, opts: BrowserOpts) {
9697
super(config, opts);
@@ -328,6 +329,14 @@ export class ExistingBrowser extends Browser {
328329
protected _addMetaAccessCommands(session: WebdriverIO.Browser): void {
329330
session.addCommand("setMeta", (key, value) => (this._meta[key] = value));
330331
session.addCommand("getMeta", key => (key ? this._meta[key] : this._meta));
332+
333+
session.addCommand("addTag", (tag: string | string[]) => {
334+
if (Array.isArray(tag)) {
335+
tag.forEach(element => this._tag?.add(element));
336+
} else {
337+
this._tag?.add(tag);
338+
}
339+
});
331340
}
332341

333342
protected _decorateUrlMethod(session: WebdriverIO.Browser): void {
@@ -584,6 +593,10 @@ export class ExistingBrowser extends Browser {
584593
return this._meta;
585594
}
586595

596+
get tag(): string[] {
597+
return [...this._tag];
598+
}
599+
587600
get cdp(): CDP | null {
588601
return this._cdp;
589602
}

src/browser/history/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ export interface PromiseRef<T = unknown> {
2323
}
2424

2525
const shouldNotWrapCommand = (commandName: string): boolean =>
26-
["addCommand", "overwriteCommand", "extendOptions", "setMeta", "getMeta", "runStep"].includes(commandName);
26+
["addCommand", "overwriteCommand", "extendOptions", "addTag", "setMeta", "getMeta", "runStep"].includes(
27+
commandName,
28+
);
2729

2830
export const shouldPropagateFn = (parentNode: TestStep, currentNode: TestStep): boolean =>
2931
isGroup(parentNode) || isGroup(currentNode);

src/browser/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ declare global {
7575

7676
setMeta(this: WebdriverIO.Browser, key: string, value: unknown): Promise<void>;
7777

78+
addTag(this: WebdriverIO.Browser, tag: string | string[]): Promise<void>;
79+
7880
extendOptions(this: WebdriverIO.Browser, opts: { [name: string]: unknown }): Promise<void>;
7981

8082
getConfig(this: WebdriverIO.Browser): Promise<BrowserConfig>;

src/cli/commands/list-tests/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export const registerCmd = (cliTool: ListTestsCmd, testplane: Testplane): void =
3030
.option("--formatter [name]", "return tests in specified format", String, Formatters.LIST)
3131
.arguments("[paths...]")
3232
.action(async (paths: string[], options: ListTestsCmdOpts) => {
33-
const { grep, browser: browsers, set: sets } = cliTool;
33+
const { grep, tag, browser: browsers, set: sets } = cliTool;
3434
const { ignore, silent, outputFile, formatter } = options;
3535

3636
try {
@@ -40,6 +40,7 @@ export const registerCmd = (cliTool: ListTestsCmd, testplane: Testplane): void =
4040
browsers,
4141
sets,
4242
grep,
43+
tag,
4344
ignore,
4445
silent,
4546
runnableOpts: {

src/cli/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ export const run = async (opts: TestplaneRunOpts = {}): Promise<void> => {
8787
browser: browsers,
8888
set: sets,
8989
grep,
90+
tag,
9091
updateRefs,
9192
inspect,
9293
inspectBrk,
@@ -104,6 +105,7 @@ export const run = async (opts: TestplaneRunOpts = {}): Promise<void> => {
104105
browsers,
105106
sets,
106107
grep,
108+
tag,
107109
updateRefs,
108110
requireModules,
109111
inspectMode: (inspect || inspectBrk) && { inspect, inspectBrk },

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export type {
2929
TestFunctionCtx,
3030
ExecutionThreadCtx,
3131
Cookie,
32+
TestTag,
3233
} from "./types";
3334
export type { Config } from "./config";
3435
export { TimeTravelMode } from "./config";

src/runner/test-runner/regular-test-runner.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ module.exports = class RegularTestRunner extends RunnableEmitter {
7171
});
7272
}
7373

74-
_applyTestResults({ meta, testplaneCtx = {}, history = [] }) {
74+
_applyTestResults({ tag, meta, testplaneCtx = {}, history = [] }) {
7575
testplaneCtx.assertViewResults = AssertViewResults.fromRawObject(testplaneCtx.assertViewResults || []);
7676
this._test.assertViewResults = testplaneCtx.assertViewResults.get();
7777

@@ -80,6 +80,10 @@ module.exports = class RegularTestRunner extends RunnableEmitter {
8080
this._test.hermioneCtx = testplaneCtx;
8181
this._test.history = history;
8282

83+
if (tag) {
84+
tag.forEach(tag => this._test.addTag(tag));
85+
}
86+
8387
this._test.duration = Date.now() - this._test.startTime;
8488
}
8589

src/test-reader/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class TestReader extends EventEmitter {
2929
}
3030

3131
async read(options: TestReaderOpts): Promise<Record<string, Test[]>> {
32-
const { paths, browsers, ignore, sets, grep, runnableOpts } = options;
32+
const { paths, browsers, ignore, sets, grep, tag, runnableOpts } = options;
3333

3434
const { fileExtensions } = this.#config.system;
3535
const envSets = env.parseCommaSeparatedValue(["TESTPLANE_SETS", "HERMIONE_SETS"]).value;
@@ -46,7 +46,7 @@ export class TestReader extends EventEmitter {
4646

4747
const filesByBro = setCollection.groupByBrowser();
4848
const testsByBro = _.mapValues(filesByBro, (files, browserId) =>
49-
parser.parse(files, { browserId, config: this.#config.forBrowser(browserId), grep }),
49+
parser.parse(files, { browserId, config: this.#config.forBrowser(browserId), grep, tag }),
5050
);
5151

5252
validateTests(testsByBro, options, this.#config);

src/test-reader/mocha-reader/index.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,46 @@ const { enableSourceMaps } = require("../../utils/typescript");
1212

1313
async function readFiles(files, { esmDecorator, config, eventBus, runnableOpts }) {
1414
const mocha = new Mocha(config);
15+
16+
mocha.suite.on("pre-require", context => {
17+
const originalDescribe = context.describe;
18+
const originalIt = context.it;
19+
20+
context.describe = context.context = function (title, paramsOrFn, fn) {
21+
if (typeof paramsOrFn === "function") {
22+
return originalIt.call(this, title, paramsOrFn);
23+
} else {
24+
const suite = originalDescribe.call(this, title, fn);
25+
26+
if (paramsOrFn?.tag) {
27+
suite.tag = paramsOrFn.tag.map(title => ({ title, dynamic: false }));
28+
}
29+
30+
return suite;
31+
}
32+
};
33+
34+
context.describe.only = originalDescribe.only;
35+
context.describe.skip = originalDescribe.skip;
36+
37+
context.it = context.specify = function (title, paramsOrFn, fn) {
38+
if (typeof paramsOrFn === "function") {
39+
return originalIt.call(this, title, paramsOrFn);
40+
} else {
41+
const test = originalIt.call(this, title, fn);
42+
43+
if (paramsOrFn?.tag) {
44+
test.tag = paramsOrFn.tag.map(title => ({ title, dynamic: false }));
45+
}
46+
47+
return test;
48+
}
49+
};
50+
51+
context.it.only = originalIt.only;
52+
context.it.skip = originalIt.skip;
53+
});
54+
1555
mocha.fullTrace();
1656

1757
initBuildContext(eventBus);

src/test-reader/mocha-reader/tree-builder-decorator.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@ class TreeBuilderDecorator {
1818
}
1919

2020
addSuite(mochaSuite) {
21-
const { id: mochaId } = mochaSuite;
21+
const { id: mochaId, tag } = mochaSuite;
2222
const file = computeFile(mochaSuite) ?? "unknown-file";
2323

2424
const positionInFile = this.#suiteCounter.get(file) || 0;
2525
const id = mochaSuite.root ? mochaId : crypto.getShortMD5(file) + positionInFile;
26-
const suite = this.#mkTestObject(Suite, mochaSuite, { id });
26+
const suite = this.#mkTestObject(Suite, mochaSuite, { id, tag });
2727

2828
this.#applyConfig(suite, mochaSuite);
2929
this.#treeBuilder.addSuite(suite, this.#getParent(mochaSuite, null));
@@ -34,9 +34,9 @@ class TreeBuilderDecorator {
3434
}
3535

3636
addTest(mochaTest) {
37-
const { fn } = mochaTest;
37+
const { fn, tag } = mochaTest;
3838
const id = crypto.getShortMD5(mochaTest.fullTitle());
39-
const test = this.#mkTestObject(Test, mochaTest, { id, fn });
39+
const test = this.#mkTestObject(Test, mochaTest, { id, fn, tag });
4040

4141
this.#applyConfig(test, mochaTest);
4242
this.#treeBuilder.addTest(test, this.#getParent(mochaTest));

0 commit comments

Comments
 (0)