Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions packages/playwright-ct-core/src/tsxTransform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@
import path from 'path';

import { declare, traverse, types } from 'playwright/lib/transform/babelBundle';
import { setTransformData } from 'playwright/lib/transform/transform';

import type { BabelAPI, PluginObj, T } from 'playwright/lib/transform/babelBundle';
const t: typeof T = types;

let jsxComponentNames: Set<string>;
let importInfos: Map<string, ImportInfo>;

export default declare((api: BabelAPI) => {
type TsxTransformOptions = {
setTransformData: (key: string, value: any) => void;
};

export default declare((api: BabelAPI, options: TsxTransformOptions) => {
api.assertVersion(7);

const result: PluginObj = {
Expand Down Expand Up @@ -65,7 +68,7 @@ export default declare((api: BabelAPI) => {
)
);
}
setTransformData('playwright-ct-core', [...importInfos.values()]);
options.setTransformData('playwright-ct-core', [...importInfos.values()]);
}
},

Expand Down
2 changes: 1 addition & 1 deletion packages/playwright/src/common/DEPS.list
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
../util.ts
../transform
../isomorphic/teleReceiver.ts
../package.ts

[testType.ts]
../matchers/expect.ts

3 changes: 2 additions & 1 deletion packages/playwright/src/common/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import fs from 'fs';
import os from 'os';
import path from 'path';

import { packageJSON } from '../package';
import { getPackageJsonPath, mergeObjects } from '../util';

import type { Config, Fixtures, Metadata, Project, ReporterDescription } from '../../types/test';
Expand Down Expand Up @@ -117,7 +118,7 @@ export class FullConfigInternal {
tags: globalTags,
updateSnapshots: takeFirst(configCLIOverrides.updateSnapshots, userConfig.updateSnapshots, 'missing'),
updateSourceMethod: takeFirst(configCLIOverrides.updateSourceMethod, userConfig.updateSourceMethod, 'patch'),
version: require('../../package.json').version,
version: packageJSON.version,
workers: resolveWorkers(takeFirst((configCLIOverrides.debug || configCLIOverrides.pause) ? 1 : undefined, configCLIOverrides.workers, userConfig.workers, '50%')),
webServer: null,
};
Expand Down
2 changes: 1 addition & 1 deletion packages/playwright/src/common/esmLoaderHost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function registerESMLoader() {

const { port1, port2 } = new MessageChannel();
// register will wait until the loader is initialized.
register(url.pathToFileURL(require.resolve('../transform/esmLoader')), {
register(url.pathToFileURL(require.resolve('../esmLoaderBundle.js')), {
data: { port: port2 },
transferList: [port2],
});
Expand Down
3 changes: 2 additions & 1 deletion packages/playwright/src/common/expectBundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@
* limitations under the License.
*/

export const expect: typeof import('../../bundles/expect/node_modules/expect/build').expect = require('./expectBundleImpl').expect;
import { libPath } from '../package';
export const expect: typeof import('../../bundles/expect/node_modules/expect/build').expect = require(libPath('common', 'expectBundleImpl')).expect;
3 changes: 2 additions & 1 deletion packages/playwright/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { setBoxedStackPrefixes } from '@utils/nodePlatform';
import { currentZone } from '@utils/zones';
import { buildErrorContext } from './errorContext';
import { currentTestInfo } from './common/globals';
import { packageRoot } from './package';
import { rootTestType } from './common/testType';
import { createCustomMessageHandler, runDaemonForContext } from './mcp/test/browserBackend';

Expand All @@ -46,7 +47,7 @@ import type { BrowserContext, BrowserContextOptions, LaunchOptions, Page, Tracin
export { expect } from './matchers/expect';
export const _baseTest: TestType<{}, {}> = rootTestType.test;

setBoxedStackPrefixes([path.dirname(require.resolve('../package.json'))]);
setBoxedStackPrefixes([packageRoot]);

if ((process as any)['__pw_initiator__']) {
const originalStackTraceLimit = Error.stackTraceLimit;
Expand Down
26 changes: 26 additions & 0 deletions packages/playwright/src/package.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import path from 'path';

// Use a dynamic path so esbuild does not statically resolve and inline
// package.json into coreBundle.js.
export const packageRoot = path.join(__dirname, '..');
export const packageJSON = require(path.join(packageRoot, 'package.json'));

export function libPath(...parts: string[]): string {
return path.join(packageRoot, 'lib', ...parts);
}
3 changes: 1 addition & 2 deletions packages/playwright/src/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,13 @@ import { showReport, mergeReports } from './cli/reportActions';
import { TestServerBackend, testServerBackendTools } from './mcp/test/testBackend';
import { loadConfigFromFile } from './common/configLoader';
import { ClaudeGenerator, OpencodeGenerator, VSCodeGenerator, CopilotGenerator } from './agents/generateAgents';
import { packageJSON } from './package';

export { program };

import type { TraceMode } from '../types/test';
import type { Command } from 'playwright-core/lib/utilsBundle';

const packageJSON = require('../package.json');

libCli.decorateProgram(program);

function addTestCommand(program: Command) {
Expand Down
2 changes: 2 additions & 0 deletions packages/playwright/src/transform/DEPS.list
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
[*]
../util.ts
../common/globals.ts
../package.ts
@utils/**
node_modules/json5
node_modules/source-map-support
15 changes: 9 additions & 6 deletions packages/playwright/src/transform/babelBundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@
* limitations under the License.
*/

import { libPath } from '../package';

import type { BabelFileResult, ParseResult } from '../../bundles/babel/node_modules/@types/babel__core';
export const codeFrameColumns: typeof import('../../bundles/babel/node_modules/@types/babel__code-frame').codeFrameColumns = require('./babelBundleImpl').codeFrameColumns;
export const declare: typeof import('../../bundles/babel/node_modules/@types/babel__helper-plugin-utils').declare = require('./babelBundleImpl').declare;
export const types: typeof import('../../bundles/babel/node_modules/@types/babel__core').types = require('./babelBundleImpl').types;
export const traverse: typeof import('../../bundles/babel/node_modules/@types/babel__traverse').default = require('./babelBundleImpl').traverse;
const babelBundleImpl = require(libPath('transform', 'babelBundleImpl'));
export const codeFrameColumns: typeof import('../../bundles/babel/node_modules/@types/babel__code-frame').codeFrameColumns = babelBundleImpl.codeFrameColumns;
export const declare: typeof import('../../bundles/babel/node_modules/@types/babel__helper-plugin-utils').declare = babelBundleImpl.declare;
export const types: typeof import('../../bundles/babel/node_modules/@types/babel__core').types = babelBundleImpl.types;
export const traverse: typeof import('../../bundles/babel/node_modules/@types/babel__traverse').default = babelBundleImpl.traverse;
export type BabelPlugin = [string, any?];
export type BabelTransformFunction = (code: string, filename: string, isModule: boolean, pluginsPrefix: BabelPlugin[], pluginsSuffix: BabelPlugin[]) => BabelFileResult | null;
export const babelTransform: BabelTransformFunction = require('./babelBundleImpl').babelTransform;
export const babelTransform: BabelTransformFunction = babelBundleImpl.babelTransform;
export type BabelParseFunction = (code: string, filename: string, isModule: boolean) => ParseResult;
export const babelParse: BabelParseFunction = require('./babelBundleImpl').babelParse;
export const babelParse: BabelParseFunction = babelBundleImpl.babelParse;
export type { NodePath, PluginObj, types as T } from '../../bundles/babel/node_modules/@types/babel__core';
export type { BabelAPI } from '../../bundles/babel/node_modules/@types/babel__helper-plugin-utils';
7 changes: 4 additions & 3 deletions packages/playwright/src/transform/compilationCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ import fs from 'fs';
import os from 'os';
import path from 'path';

import { utils } from 'playwright-core/lib/coreBundle';
import { calculateSha1 } from '@utils/crypto';
import sourceMapSupport from 'source-map-support';
import { isWorkerProcess } from '../common/globals';
import { packageRoot } from '../package';

export type MemoryCache = {
codePath: string;
Expand Down Expand Up @@ -176,7 +177,7 @@ export function addToCompilationCache(payload: SerializedCompilationCache) {

function calculateFilePathHash(filePath: string): string {
// Larger file path hash allows for fewer collisions compared to content, as we only check file path collision for deleting files
return utils.calculateSha1(filePath).substring(0, 10);
return calculateSha1(filePath).substring(0, 10);
}

function calculateCachePath(filePath: string, cacheFolderName: string, hashPrefix: string): string {
Expand Down Expand Up @@ -279,7 +280,7 @@ export function dependenciesForTestFile(filename: string): Set<string> {
// This is only used in the dev mode, specifically excluding
// files from packages/playwright*. In production mode, node_modules covers
// that.
const kPlaywrightInternalPrefix = path.resolve(__dirname, '../../../playwright');
const kPlaywrightInternalPrefix = packageRoot;

export function belongsToNodeModules(file: string) {
if (file.includes(`${path.sep}node_modules${path.sep}`))
Expand Down
15 changes: 13 additions & 2 deletions packages/playwright/src/transform/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import crypto from 'crypto';

import sourceMapSupport from 'source-map-support';
import { loadTsConfig } from './tsconfig-loader';
import { packageJSON } from '../package';
import { createFileMatcher, debugTest, fileIsModule, resolveImportSpecifierAfterMapping } from '../util';
import { belongsToNodeModules, currentFileDepsCollector, getFromCompilationCache, installSourceMapSupport } from './compilationCache';
import { addHook } from './pirates';
Expand All @@ -33,7 +34,7 @@ import type { LoadedTsConfig } from './tsconfig-loader';
import type { Matcher } from '../util';


const version = require('../../package.json').version;
const version = packageJSON.version;

type ParsedTsConfigData = {
pathsBase?: string;
Expand Down Expand Up @@ -237,7 +238,17 @@ export function transformHook(originalCode: string, filename: string, moduleUrl?

const { babelTransform }: { babelTransform: BabelTransformFunction } = require('./babelBundle');
transformData = new Map<string, any>();
const babelResult = babelTransform(originalCode, filename, !!moduleUrl, pluginsPrologue, pluginsEpilogue);
// Pass `setTransformData` to plugins via plugin options instead of having
// them import it. The bundled esmLoader inlines its own copy of this file,
// so an import-based approach would close over the wrong `transformData`
// module-level variable. The closure here always references the bundle copy
// currently driving the transform.
const setTransformDataForPlugin = (key: string, value: any) => transformData.set(key, value);
const wrappedPrologue: BabelPlugin[] = pluginsPrologue.map(([name, opts]) => [
name,
{ ...(opts || {}), setTransformData: setTransformDataForPlugin },
]);
const babelResult = babelTransform(originalCode, filename, !!moduleUrl, wrappedPrologue, pluginsEpilogue);
if (!babelResult?.code)
return { code: originalCode, serializedCache };
const { code, map } = babelResult;
Expand Down
20 changes: 20 additions & 0 deletions utils/build/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,26 @@ function assertCoreBundleHasNoNodeModules() {

steps.push(new CustomCallbackStep(assertCoreBundleHasNoNodeModules));

// playwright/lib/transform/esmLoader2.js — bundled ESM loader registered by
// common/esmLoaderHost.ts via node:module register. Same externalization
// rules as the worker bundle.
{
const playwrightSrc = filePath('packages/playwright/src');
steps.push(new EsbuildStep({
bundle: true,
entryPoints: [filePath('packages/playwright/src/transform/esmLoader.ts')],
outfile: filePath('packages/playwright/lib/esmLoaderBundle.js'),
sourcemap: withSourceMaps ? 'linked' : false,
platform: 'node',
format: 'cjs',
external: [
'playwright-core',
'playwright-core/*',
],
plugins: [],
}, [playwrightSrc]));
}

// Build the Electron preload loader as a standalone CJS file. It runs inside
// the Electron process (via `electron -r loader.js`) and must not depend on
// coreBundle. `electron` is resolved at runtime by the Electron process.
Expand Down
Loading