mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(test runner): do not revert the transform (#31930)
This allows a dynamic import of a TS file to be processed by Babel. For some reason, Playwright used to revert the CJS transforms. However, ESM loader and transforms are always active, so CJS should be too.
This commit is contained in:
parent
edb89dcb66
commit
e62a54af7a
@ -64,13 +64,7 @@ const fileDependencies = new Map<string, Set<string>>();
|
|||||||
// Dependencies resolved by the external bundler.
|
// Dependencies resolved by the external bundler.
|
||||||
const externalDependencies = new Map<string, Set<string>>();
|
const externalDependencies = new Map<string, Set<string>>();
|
||||||
|
|
||||||
let sourceMapSupportInstalled = false;
|
export function installSourceMapSupport() {
|
||||||
|
|
||||||
export function installSourceMapSupportIfNeeded() {
|
|
||||||
if (sourceMapSupportInstalled)
|
|
||||||
return;
|
|
||||||
sourceMapSupportInstalled = true;
|
|
||||||
|
|
||||||
Error.stackTraceLimit = 200;
|
Error.stackTraceLimit = 200;
|
||||||
|
|
||||||
sourceMapSupport.install({
|
sourceMapSupport.install({
|
||||||
|
|||||||
@ -25,7 +25,7 @@ import Module from 'module';
|
|||||||
import type { BabelPlugin, BabelTransformFunction } from './babelBundle';
|
import type { BabelPlugin, BabelTransformFunction } from './babelBundle';
|
||||||
import { createFileMatcher, fileIsModule, resolveImportSpecifierExtension } from '../util';
|
import { createFileMatcher, fileIsModule, resolveImportSpecifierExtension } from '../util';
|
||||||
import type { Matcher } from '../util';
|
import type { Matcher } from '../util';
|
||||||
import { getFromCompilationCache, currentFileDepsCollector, belongsToNodeModules, installSourceMapSupportIfNeeded } from './compilationCache';
|
import { getFromCompilationCache, currentFileDepsCollector, belongsToNodeModules, installSourceMapSupport } from './compilationCache';
|
||||||
|
|
||||||
const version = require('../../package.json').version;
|
const version = require('../../package.json').version;
|
||||||
|
|
||||||
@ -201,33 +201,33 @@ function calculateHash(content: string, filePath: string, isModule: boolean, plu
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function requireOrImport(file: string) {
|
export async function requireOrImport(file: string) {
|
||||||
const revertBabelRequire = installTransform();
|
installTransformIfNeeded();
|
||||||
const isModule = fileIsModule(file);
|
const isModule = fileIsModule(file);
|
||||||
try {
|
const esmImport = () => eval(`import(${JSON.stringify(url.pathToFileURL(file))})`);
|
||||||
const esmImport = () => eval(`import(${JSON.stringify(url.pathToFileURL(file))})`);
|
if (isModule)
|
||||||
if (isModule)
|
return await esmImport();
|
||||||
return await esmImport();
|
const result = require(file);
|
||||||
const result = require(file);
|
const depsCollector = currentFileDepsCollector();
|
||||||
const depsCollector = currentFileDepsCollector();
|
if (depsCollector) {
|
||||||
if (depsCollector) {
|
const module = require.cache[file];
|
||||||
const module = require.cache[file];
|
if (module)
|
||||||
if (module)
|
collectCJSDependencies(module, depsCollector);
|
||||||
collectCJSDependencies(module, depsCollector);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} finally {
|
|
||||||
revertBabelRequire();
|
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function installTransform(): () => void {
|
let transformInstalled = false;
|
||||||
installSourceMapSupportIfNeeded();
|
|
||||||
|
|
||||||
let reverted = false;
|
function installTransformIfNeeded() {
|
||||||
|
if (transformInstalled)
|
||||||
|
return;
|
||||||
|
transformInstalled = true;
|
||||||
|
|
||||||
|
installSourceMapSupport();
|
||||||
|
|
||||||
const originalResolveFilename = (Module as any)._resolveFilename;
|
const originalResolveFilename = (Module as any)._resolveFilename;
|
||||||
function resolveFilename(this: any, specifier: string, parent: Module, ...rest: any[]) {
|
function resolveFilename(this: any, specifier: string, parent: Module, ...rest: any[]) {
|
||||||
if (!reverted && parent) {
|
if (parent) {
|
||||||
const resolved = resolveHook(parent.filename, specifier);
|
const resolved = resolveHook(parent.filename, specifier);
|
||||||
if (resolved !== undefined)
|
if (resolved !== undefined)
|
||||||
specifier = resolved;
|
specifier = resolved;
|
||||||
@ -236,17 +236,11 @@ function installTransform(): () => void {
|
|||||||
}
|
}
|
||||||
(Module as any)._resolveFilename = resolveFilename;
|
(Module as any)._resolveFilename = resolveFilename;
|
||||||
|
|
||||||
const revertPirates = pirates.addHook((code: string, filename: string) => {
|
pirates.addHook((code: string, filename: string) => {
|
||||||
if (!shouldTransform(filename))
|
if (!shouldTransform(filename))
|
||||||
return code;
|
return code;
|
||||||
return transformHook(code, filename).code;
|
return transformHook(code, filename).code;
|
||||||
}, { exts: ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.mts', '.cjs', '.cts'] });
|
}, { exts: ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.mts', '.cjs', '.cts'] });
|
||||||
|
|
||||||
return () => {
|
|
||||||
reverted = true;
|
|
||||||
(Module as any)._resolveFilename = originalResolveFilename;
|
|
||||||
revertPirates();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const collectCJSDependencies = (module: Module, dependencies: Set<string>) => {
|
const collectCJSDependencies = (module: Module, dependencies: Set<string>) => {
|
||||||
|
|||||||
@ -961,10 +961,11 @@ test('should complain when one test file imports another', async ({ runInlineTes
|
|||||||
expect(result.output).toContain(`test file "a.test.ts" should not import test file "b.test.ts"`);
|
expect(result.output).toContain(`test file "a.test.ts" should not import test file "b.test.ts"`);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should support dynamic imports of js, ts from js, ts and cjs', async ({ runInlineTest }) => {
|
test('should support dynamic imports and requires of js, ts from js, ts and cjs', async ({ runInlineTest }) => {
|
||||||
const result = await runInlineTest({
|
const result = await runInlineTest({
|
||||||
'helper.ts': `
|
'helper.ts': `
|
||||||
module.exports.foo = 'foo';
|
const foo: string = 'foo';
|
||||||
|
module.exports.foo = foo;
|
||||||
`,
|
`,
|
||||||
'helper2.ts': `
|
'helper2.ts': `
|
||||||
module.exports.bar = 'bar';
|
module.exports.bar = 'bar';
|
||||||
@ -972,6 +973,10 @@ test('should support dynamic imports of js, ts from js, ts and cjs', async ({ ru
|
|||||||
'helper3.js': `
|
'helper3.js': `
|
||||||
module.exports.baz = 'baz';
|
module.exports.baz = 'baz';
|
||||||
`,
|
`,
|
||||||
|
'helper4.ts': `
|
||||||
|
const foo: string = 'foo';
|
||||||
|
module.exports.foo = foo;
|
||||||
|
`,
|
||||||
'passthrough.cjs': `
|
'passthrough.cjs': `
|
||||||
module.exports.load = () => import('./helper2');
|
module.exports.load = () => import('./helper2');
|
||||||
`,
|
`,
|
||||||
@ -1006,8 +1011,16 @@ test('should support dynamic imports of js, ts from js, ts and cjs', async ({ ru
|
|||||||
expect(foo).toBe('foo');
|
expect(foo).toBe('foo');
|
||||||
});
|
});
|
||||||
`,
|
`,
|
||||||
|
'd.test.js': `
|
||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
|
||||||
|
test('pass', async () => {
|
||||||
|
const { foo } = require('./helper4');
|
||||||
|
expect(foo).toBe('foo');
|
||||||
|
});
|
||||||
|
`,
|
||||||
}, { workers: 1 });
|
}, { workers: 1 });
|
||||||
expect(result.passed).toBe(3);
|
expect(result.passed).toBe(4);
|
||||||
expect(result.exitCode).toBe(0);
|
expect(result.exitCode).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user