summaryrefslogtreecommitdiffstats
path: root/remote/test/puppeteer/tools/mocha-runner/src/interface.ts
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /remote/test/puppeteer/tools/mocha-runner/src/interface.ts
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'remote/test/puppeteer/tools/mocha-runner/src/interface.ts')
-rw-r--r--remote/test/puppeteer/tools/mocha-runner/src/interface.ts191
1 files changed, 191 insertions, 0 deletions
diff --git a/remote/test/puppeteer/tools/mocha-runner/src/interface.ts b/remote/test/puppeteer/tools/mocha-runner/src/interface.ts
new file mode 100644
index 0000000000..fe0f7e18b5
--- /dev/null
+++ b/remote/test/puppeteer/tools/mocha-runner/src/interface.ts
@@ -0,0 +1,191 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import Mocha from 'mocha';
+import commonInterface from 'mocha/lib/interfaces/common';
+import {
+ setLogCapture,
+ getCapturedLogs,
+} from 'puppeteer-core/internal/common/Debug.js';
+
+import {testIdMatchesExpectationPattern} from './utils.js';
+
+type SuiteFunction = ((this: Mocha.Suite) => void) | undefined;
+type ExclusiveSuiteFunction = (this: Mocha.Suite) => void;
+
+const skippedTests: Array<{testIdPattern: string; skip: true}> = process.env[
+ 'PUPPETEER_SKIPPED_TEST_CONFIG'
+]
+ ? JSON.parse(process.env['PUPPETEER_SKIPPED_TEST_CONFIG'])
+ : [];
+
+const deflakeRetries = Number(
+ process.env['PUPPETEER_DEFLAKE_RETRIES']
+ ? process.env['PUPPETEER_DEFLAKE_RETRIES']
+ : 100
+);
+const deflakeTestPattern: string | undefined =
+ process.env['PUPPETEER_DEFLAKE_TESTS'];
+
+function shouldSkipTest(test: Mocha.Test): boolean {
+ // TODO: more efficient lookup.
+ const definition = skippedTests.find(skippedTest => {
+ return testIdMatchesExpectationPattern(test, skippedTest.testIdPattern);
+ });
+ if (definition && definition.skip) {
+ return true;
+ }
+ return false;
+}
+
+function shouldDeflakeTest(test: Mocha.Test): boolean {
+ if (deflakeTestPattern) {
+ // TODO: cache if we have seen it already
+ return testIdMatchesExpectationPattern(test, deflakeTestPattern);
+ }
+ return false;
+}
+
+function dumpLogsIfFail(this: Mocha.Context) {
+ if (this.currentTest?.state === 'failed') {
+ console.log(
+ `\n"${this.currentTest.fullTitle()}" failed. Here is a debug log:`
+ );
+ console.log(getCapturedLogs().join('\n') + '\n');
+ }
+ setLogCapture(false);
+}
+
+function customBDDInterface(suite: Mocha.Suite) {
+ const suites: [Mocha.Suite] = [suite];
+
+ suite.on(
+ Mocha.Suite.constants.EVENT_FILE_PRE_REQUIRE,
+ function (context, file, mocha) {
+ const common = commonInterface(suites, context, mocha);
+
+ context['before'] = common.before;
+ context['after'] = common.after;
+ context['beforeEach'] = common.beforeEach;
+ context['afterEach'] = common.afterEach;
+ if (mocha.options.delay) {
+ context['run'] = common.runWithSuite(suite);
+ }
+ function describe(title: string, fn: SuiteFunction) {
+ return common.suite.create({
+ title: title,
+ file: file,
+ fn: fn,
+ });
+ }
+ describe.only = function (title: string, fn: ExclusiveSuiteFunction) {
+ return common.suite.only({
+ title: title,
+ file: file,
+ fn: fn,
+ isOnly: true,
+ });
+ };
+
+ describe.skip = function (title: string, fn: SuiteFunction) {
+ return common.suite.skip({
+ title: title,
+ file: file,
+ fn: fn,
+ });
+ };
+
+ describe.withDebugLogs = function (
+ description: string,
+ body: (this: Mocha.Suite) => void
+ ): void {
+ context['describe']('with Debug Logs', () => {
+ context['beforeEach'](() => {
+ setLogCapture(true);
+ });
+ context['afterEach'](dumpLogsIfFail);
+ context['describe'](description, body);
+ });
+ };
+
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-expect-error
+ context['describe'] = describe;
+
+ function it(title: string, fn: Mocha.TestFunction, itOnly = false) {
+ const suite = suites[0]! as Mocha.Suite;
+ const test = new Mocha.Test(title, suite.isPending() ? undefined : fn);
+ test.file = file;
+ test.parent = suite;
+
+ const describeOnly = Boolean(
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-expect-error
+ suite.parent?._onlySuites.find(child => {
+ return child === suite;
+ })
+ );
+ if (shouldDeflakeTest(test)) {
+ const deflakeSuit = Mocha.Suite.create(suite, 'with Debug Logs');
+ test.file = file;
+ deflakeSuit.beforeEach(function () {
+ setLogCapture(true);
+ });
+ deflakeSuit.afterEach(dumpLogsIfFail);
+ for (let i = 0; i < deflakeRetries; i++) {
+ deflakeSuit.addTest(test.clone());
+ }
+ return test;
+ } else if (!(itOnly || describeOnly) && shouldSkipTest(test)) {
+ const test = new Mocha.Test(title);
+ test.file = file;
+ suite.addTest(test);
+ return test;
+ } else {
+ suite.addTest(test);
+ return test;
+ }
+ }
+
+ it.only = function (title: string, fn: Mocha.TestFunction) {
+ return common.test.only(
+ mocha,
+ (context['it'] as unknown as typeof it)(title, fn, true)
+ );
+ };
+
+ it.skip = function (title: string) {
+ return context['it'](title);
+ };
+
+ function wrapDeflake(
+ func: Function
+ ): (repeats: number, title: string, fn: Mocha.AsyncFunc) => void {
+ return (repeats: number, title: string, fn: Mocha.AsyncFunc): void => {
+ (context['describe'] as unknown as typeof describe).withDebugLogs(
+ 'with Debug Logs',
+ () => {
+ for (let i = 1; i <= repeats; i++) {
+ func(`${i}/${title}`, fn);
+ }
+ }
+ );
+ };
+ }
+
+ it.deflake = wrapDeflake(it);
+ it.deflakeOnly = wrapDeflake(it.only);
+
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-expect-error
+ context.it = it;
+ }
+ );
+}
+
+customBDDInterface.description = 'Custom BDD';
+
+module.exports = customBDDInterface;