Skip to content

Commit

Permalink
feat: ability to read tests in ".jsx" and ".tsx" files
Browse files Browse the repository at this point in the history
  • Loading branch information
DudaGod committed Mar 21, 2024
1 parent 03b46c2 commit 578a599
Show file tree
Hide file tree
Showing 12 changed files with 2,638 additions and 373 deletions.
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1300,7 +1300,7 @@ The maximum number of tests to be run in one worker before it will be restarted.
By default, `hermione` will run all browsers simultaneously. Sometimes (i.e. when using cloud services, such as SauceLabs) you have to limit the amount of browsers that can be run at the same time. This option effectively limits how many browsers `hermione` will try to run in parallel. Default value is `Infinity`.

#### fileExtensions
Ability to set file extensions, which hermione will search on the file system. Default value is `[.js]`.
Ability to set file extensions, which hermione will search on the file system. Default value is `[".js", ".mjs", ".ts", ".mts", ".jsx", ".tsx"]`.

### plugins
`Hermione` plugins are commonly used to extend built-in functionality. For example, [html-reporter](https://github.com/gemini-testing/html-reporter) and [hermione-safari-commands](https://github.com/gemini-testing/hermione-safari-commands).
Expand Down Expand Up @@ -1621,8 +1621,6 @@ Using `-r` or `--require` option you can load external modules, which exists in
- compilers such as TypeScript via [ts-node](https://www.npmjs.com/package/ts-node) (using `--require ts-node/register`) or Babel via [@babel/register](https://www.npmjs.com/package/@babel/register) (using `--require @babel/register`);
- loaders such as ECMAScript modules via [esm](https://www.npmjs.com/package/esm).

Be sure to update [fileExtensions](#fileExtensions) apropriately, if you are planning to import anything other than `.js`.

### Overriding settings

All options can also be overridden via command-line flags or environment variables. Priorities are the following:
Expand Down
2,837 changes: 2,470 additions & 367 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"typings"
],
"scripts": {
"build": "tsc && npm run copy-static",
"build": "tsc && npm run copy-static && npm run build-bundle -- --minify",
"build-bundle": "esbuild ./src/bundle/index.ts --outdir=./build/src/bundle --bundle --format=cjs --platform=node --target=ES2021",
"copy-static": "copyfiles 'src/browser/client-scripts/*' build",
"check-types": "tsc --project tsconfig.spec.json",
"clean": "rimraf build/ *.tsbuildinfo",
Expand Down Expand Up @@ -79,10 +80,16 @@
"yallist": "3.1.1"
},
"devDependencies": {
"@babel/core": "7.24.1",
"@babel/plugin-transform-modules-commonjs": "7.24.1",
"@babel/plugin-transform-react-jsx": "7.23.4",
"@babel/preset-react": "7.24.1",
"@babel/preset-typescript": "7.24.1",
"@commitlint/cli": "^19.0.3",
"@commitlint/config-conventional": "^19.0.3",
"@sinonjs/fake-timers": "10.3.0",
"@swc/core": "1.3.40",
"@types/babel__core": "7.20.5",
"@types/bluebird": "3.5.38",
"@types/chai": "4.3.4",
"@types/chai-as-promised": "7.1.5",
Expand All @@ -99,6 +106,7 @@
"chai-as-promised": "7.1.1",
"copyfiles": "2.4.1",
"doctoc": "2.2.0",
"esbuild": "0.20.2",
"escape-string-regexp": "1.0.5",
"eslint": "8.25.0",
"eslint-config-gemini-testing": "2.8.0",
Expand All @@ -107,6 +115,7 @@
"jsdom": "^24.0.0",
"jsdom-global": "3.0.2",
"onchange": "7.1.0",
"pirates": "4.0.6",
"prettier": "2.8.4",
"proxyquire": "1.8.0",
"rimraf": "4.1.2",
Expand Down
2 changes: 2 additions & 0 deletions src/bundle/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const TRANSFORM_EXTENSIONS = [".jsx", ".cjsx", ".mjsx", ".tsx", ".ctsx", ".mtsx"];
export const JS_EXTENSION_RE = /^\.([cm]?[tj]sx?|json)$/;
2 changes: 2 additions & 0 deletions src/bundle/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./test-transformer";
export * from "./constants";
49 changes: 49 additions & 0 deletions src/bundle/test-transformer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as nodePath from "node:path";
import * as babel from "@babel/core";
import { addHook } from "pirates";
import { TRANSFORM_EXTENSIONS, JS_EXTENSION_RE } from "./constants";

import type { NodePath, PluginObj, TransformOptions } from "@babel/core";
import type { ImportDeclaration } from "@babel/types";

export const setupTransformHook = (): VoidFunction => {
const transformOptions: TransformOptions = {
browserslistConfigFile: false,
babelrc: false,
configFile: false,
compact: false,
plugins: [
[
require("@babel/plugin-transform-react-jsx"),
{
throwIfNamespace: false,
runtime: "automatic",
},
],
require("@babel/plugin-transform-modules-commonjs"),
[
(): PluginObj => ({
name: "ignore-imports",
visitor: {
ImportDeclaration(path: NodePath<ImportDeclaration>): void {
const extname = nodePath.extname(path.node.source.value);

if (extname && !extname.match(JS_EXTENSION_RE)) {
path.remove();
}
},
},
}),
],
],
};

const revertTransformHook = addHook(
(originalCode, filename) => {
return babel.transform(originalCode, { filename, ...transformOptions })!.code as string;
},
{ exts: TRANSFORM_EXTENSIONS },
);

return revertTransformHook;
};
2 changes: 1 addition & 1 deletion src/config/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ module.exports = {
resetCursor: true,
strictTestsOrder: false,
saveHistoryMode: SAVE_HISTORY_MODE.ALL,
fileExtensions: [".js", ".mjs", ".ts", ".mts"],
fileExtensions: [".js", ".mjs", ".ts", ".mts", ".jsx", ".tsx"],
outputDir: null,
agent: null,
headers: null,
Expand Down
5 changes: 5 additions & 0 deletions src/test-reader/test-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const { TreeBuilder } = require("./tree-builder");
const { readFiles } = require("./mocha-reader");
const { TestReaderEvents } = require("../events");
const { TestParserAPI } = require("./test-parser-api");
const { setupTransformHook } = require("./test-transformer");
const { MasterEvents } = require("../events");
const _ = require("lodash");
const clearRequire = require("clear-require");
Expand Down Expand Up @@ -47,9 +48,13 @@ class TestParser extends EventEmitter {

this.#clearRequireCache(files);

const revertTransformHook = setupTransformHook();

const rand = Math.random();
const esmDecorator = f => f + `?rand=${rand}`;
await readFiles(files, { esmDecorator, config: mochaOpts, eventBus });

revertTransformHook();
}

#applyInstructionsEvents(eventBus) {
Expand Down
3 changes: 3 additions & 0 deletions src/test-reader/test-transformer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
export const setupTransformHook: () => VoidFunction = require("../bundle").setupTransformHook;
export const TRANSFORM_EXTENSIONS: string[] = require("../bundle").TRANSFORM_EXTENSIONS;
20 changes: 20 additions & 0 deletions test/src/test-reader/test-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,21 @@ describe("test-reader/test-parser", () => {
let TestParser;
let clearRequire;
let readFiles;
let setupTransformHook;
let browserVersionController = {
mkProvider: sinon.stub().returns(() => {}),
};

beforeEach(() => {
clearRequire = sandbox.stub().named("clear-require");
readFiles = sandbox.stub().named("readFiles").resolves();
setupTransformHook = sandbox.stub().named("setupTransformHook").returns(sinon.stub());

TestParser = proxyquire("src/test-reader/test-parser", {
"clear-require": clearRequire,
"./mocha-reader": { readFiles },
"./controllers/browser-version-controller": browserVersionController,
"./test-transformer": { setupTransformHook },
}).TestParser;

sandbox.stub(InstructionsList.prototype, "push").returnsThis();
Expand Down Expand Up @@ -369,6 +372,23 @@ describe("test-reader/test-parser", () => {
assert.notEqual(firstCallModuleName, lastCallModuleName);
});
});

describe("transform hook", () => {
it("should setup hook before read files", async () => {
await loadFiles_({ files: ["foo/bar", "baz/qux"] });

assert.callOrder(setupTransformHook, readFiles);
});

it("should call revert transformation after read files", async () => {
const revertFn = sinon.stub();
setupTransformHook.returns(revertFn);

await loadFiles_({ files: ["foo/bar", "baz/qux"] });

assert.callOrder(readFiles, revertFn);
});
});
});

describe("root suite decorators", () => {
Expand Down
74 changes: 74 additions & 0 deletions test/src/test-reader/test-transformer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import * as pirates from "pirates";
import sinon, { SinonStub } from "sinon";
import { setupTransformHook, TRANSFORM_EXTENSIONS } from "../../../src/test-reader/test-transformer";

describe("test-transformer", () => {
const sandbox = sinon.createSandbox();

beforeEach(() => {
sandbox.stub(pirates, "addHook").returns(sandbox.stub());
});

afterEach(() => sandbox.restore());

describe("setupTransformHook", () => {
it("should return function to revert transformation", () => {
const revertFn = sandbox.stub();
(pirates.addHook as SinonStub).returns(revertFn);

assert.equal(setupTransformHook(), revertFn);
});

describe("should transform", () => {
TRANSFORM_EXTENSIONS.forEach(extName => {
it(`component with extension: "${extName}"`, () => {
let transformedCode;
(pirates.addHook as SinonStub).callsFake(cb => {
transformedCode = cb(`import "some${extName}"`);
});

setupTransformHook();

assert.exists(transformedCode, `require("some${extName}")`);
});
});

it("modules without extension", () => {
let transformedCode;
(pirates.addHook as SinonStub).callsFake(cb => {
transformedCode = cb('import "some-module"');
});

setupTransformHook();

assert.exists(transformedCode, 'require("some-module")');
});

it(".json", () => {
let transformedCode;
(pirates.addHook as SinonStub).callsFake(cb => {
transformedCode = cb('import "some.json"');
});

setupTransformHook();

assert.exists(transformedCode, 'require("some.json")');
});
});

describe("should not transform", () => {
[".css", ".less", ".scss", ".jpg", ".png", ".woff"].forEach(extName => {
it(`asset with extension: "${extName}"`, () => {
let transformedCode;
(pirates.addHook as SinonStub).callsFake(cb => {
transformedCode = cb(`import "some${extName}"`);
});

setupTransformHook();

assert.equal(transformedCode, '"use strict";');
});
});
});
});
});
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"extends": "./tsconfig.common.json",
"include": ["src"],
"exclude": ["src/**/__*", "src/**/*.test.ts", "src/browser/client-scripts"],
"exclude": ["src/**/__*", "src/**/*.test.ts", "src/browser/client-scripts", "src/bundle"],
"compilerOptions": {
"outDir": "build"
}
Expand Down

0 comments on commit 578a599

Please sign in to comment.