From fe7847b126ce2059d02fbbbc1f632b04fdae3ef7 Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Mon, 23 Oct 2023 22:48:12 +0200 Subject: [PATCH] fix: require JSX inside PWT with pnpm (#27744) Fixes https://github.com/microsoft/playwright/issues/27285 --- .../bundles/babel/src/babelBundleImpl.ts | 3 +- .../fixture-scripts/read-json-report.js | 15 +++- tests/installation/npmTest.ts | 4 +- .../playwright-component-testing.spec.ts | 73 +++++++++++++++++++ 4 files changed, 90 insertions(+), 5 deletions(-) create mode 100755 tests/installation/playwright-component-testing.spec.ts diff --git a/packages/playwright/bundles/babel/src/babelBundleImpl.ts b/packages/playwright/bundles/babel/src/babelBundleImpl.ts index 7e7463aa61f62..46dd400366f1d 100644 --- a/packages/playwright/bundles/babel/src/babelBundleImpl.ts +++ b/packages/playwright/bundles/babel/src/babelBundleImpl.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import path from 'path'; import type { BabelFileResult, NodePath, PluginObj, TransformOptions } from '@babel/core'; import type { TSExportAssignment, ImportDeclaration } from '@babel/types'; import type { TemplateBuilder } from '@babel/template'; @@ -65,7 +66,7 @@ function babelTransformOptions(isTypeScript: boolean, isModule: boolean, plugins // Support JSX/TSX at all times, regardless of the file extension. plugins.push([require('@babel/plugin-transform-react-jsx'), { runtime: 'automatic', - importSource: 'playwright' + importSource: path.dirname(require.resolve('playwright')), }]); if (!isModule) { diff --git a/tests/installation/fixture-scripts/read-json-report.js b/tests/installation/fixture-scripts/read-json-report.js index e5bcb3d18aa1d..0baa5b2a9fc01 100644 --- a/tests/installation/fixture-scripts/read-json-report.js +++ b/tests/installation/fixture-scripts/read-json-report.js @@ -3,11 +3,20 @@ if (report.suites[0].specs[0].title !== 'sample test') { console.log(`Wrong spec title`); process.exit(1); } + const projects = report.suites[0].specs[0].tests.map(t => t.projectName).sort(); -if (projects.length !== 3 || projects[0] !== 'chromium' || projects[1] !== 'firefox' || projects[2] !== 'webkit') { - console.log(`Wrong browsers`); - process.exit(1); +if (process.argv.slice(3).includes('--validate-chromium-project-only')) { + if (projects.length !== 1 || projects[0] !== 'chromium') { + console.log(`Wrong browsers`); + process.exit(1); + } +} else { + if (projects.length !== 3 || projects[0] !== 'chromium' || projects[1] !== 'firefox' || projects[2] !== 'webkit') { + console.log(`Wrong browsers`); + process.exit(1); + } } + for (const test of report.suites[0].specs[0].tests) { if (test.results[0].status !== 'passed') { console.log(`Test did not pass`); diff --git a/tests/installation/npmTest.ts b/tests/installation/npmTest.ts index cfe9189bf7c61..ce6a370b9b915 100644 --- a/tests/installation/npmTest.ts +++ b/tests/installation/npmTest.ts @@ -119,8 +119,10 @@ export const test = _test }], writeFiles: async ({ tmpWorkspace }, use) => { await use(async (nameToContents: Record) => { - for (const [name, contents] of Object.entries(nameToContents)) + for (const [name, contents] of Object.entries(nameToContents)) { + await fs.promises.mkdir(path.join(tmpWorkspace, path.dirname(name)), { recursive: true }); await fs.promises.writeFile(path.join(tmpWorkspace, name), contents); + } }); }, tmpWorkspace: async ({}, use) => { diff --git a/tests/installation/playwright-component-testing.spec.ts b/tests/installation/playwright-component-testing.spec.ts new file mode 100755 index 0000000000000..cacc322ee0156 --- /dev/null +++ b/tests/installation/playwright-component-testing.spec.ts @@ -0,0 +1,73 @@ +/** + * 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 { test } from './npmTest'; +import path from 'path'; + +test('pnpm: @playwright/experimental-ct-react should work', async ({ exec, tmpWorkspace, writeFiles }) => { + await exec('pnpm add @playwright/experimental-ct-react react react-dom'); + await exec('pnpm exec playwright install'); + await writeFiles({ + 'playwright.config.ts': ` + import { defineConfig } from '@playwright/experimental-ct-react'; + export default defineConfig({}); + `, + 'playwright/index.html': ``, + 'playwright/index.js': ``, + 'Button.tsx': ` + export function Button({ onClick }) { + return ; + } + `, + 'example.spec.tsx': ` + import { test, expect } from '@playwright/experimental-ct-react'; + import { Button } from './Button'; + + test('sample test', async ({ page, mount }) => { + let clicked = false; + const component = await mount( + + ); + await expect(component).toContainText('Submit'); + await component.click(); + expect(clicked).toBeTruthy(); + }); + `, + }); + await exec('pnpm exec playwright test -c . --browser=chromium --reporter=list,json example.spec.tsx', { env: { PLAYWRIGHT_JSON_OUTPUT_NAME: 'report.json' } }); + await exec('node read-json-report.js', path.join(tmpWorkspace, 'report.json'), '--validate-chromium-project-only'); +}); + +test('pnpm: JSX inside a @playwright/test should work', async ({ exec, tmpWorkspace, writeFiles }) => { + await exec('pnpm add @playwright/test'); + await exec('pnpm exec playwright install'); + await writeFiles({ + 'Button.tsx': ` + export function Button({ onClick }) { + return ; + } + `, + 'example.spec.ts': ` + import { test, expect } from '@playwright/test'; + import { Button } from './Button'; + + test('sample test', async ({ page }) => { + expect(Button).toEqual(expect.any(Function)); + }); + `, + }); + await exec(`node node_modules/@playwright/test/cli.js test --browser=chromium --reporter=list,json example.spec.ts`, { env: { PLAYWRIGHT_JSON_OUTPUT_NAME: 'report.json' } }); + await exec('node read-json-report.js', path.join(tmpWorkspace, 'report.json'), '--validate-chromium-project-only'); +});