Open oskarkivra opened 2 years ago
There is no such thing as a Typescript NPM module. NPM modules are all JavaScript, they can be compiled from Typescript, but they are JavaScript.
You could try using tsconfig.json to resolve your module imports into respective node_modules/my-package folders though. Playwright will pick them up and compile at test time: https://www.typescriptlang.org/tsconfig#paths
Thanks for answering.
I went with the solution to precompile the files on the fly with tsm
node --require tsm ./node_modules/.bin/playwright test
Thanks for answering.
I went with the solution to precompile the files on the fly with tsm
node --require tsm ./node_modules/.bin/playwright test
But in that case it is impossible to run tests through Playwright VS code extension (only through command line)
@olegper True and this does not seem like a waterproof solution. It would be nice to configure playwright what paths to include in the transpiring.
Strange. I wonder why there are not so much people, experiencing that issue with Playwright. Worked perfectly with Cypress though
It would be nice to re-open this issue since it's a valid case where you need to transpile some packages from node_modules
.
I have a UI-Kit built using vanilla-extract
and it's published in a raw format (plain TypeScript) to leave the build step on the client side. In my project, I use some constants from the source code (e.g. constants for routes) in the E2E tests. If I import them from index.ts
that imports other things like utility functions that can use something from that UI-Kit then it complains for TS files from node_modules
even though tests doesn't use them. So as a workaround I just import these constants directly but it would be nice to not have this limitation.
@lesha1201 I agree; there is plenty of use cases, and node_modules do not only contain javascript code these days.
I can reopen this and let @pavelfeldman and the rest of the team decide if this should have more attention or not.
Thank you! We are working in a monorepo, and have some shared (private) packages that are typescript only, for convenience sake (to add another use case).
To chime in as I was looking to adopt playwright. I have private modules that are published as js with their d.ts files. however they are converted into js+export/import syntax to help tree shaking from bundlers.
We model our endpoints with a formal base class abstraction that holds onto url and input/output types. I wanted to re-use them so i could make a typed helper for page.route to integrate making it easier to mock an endpoint using this abstraction.
This requires importing from the src/ folder, but these files are importing from node modules as well
We have a similar use case to import some common actions (find element, get value) to a helper file
async function Login_user_foo(page) {
await page.goto('<url-qa-stage>');
await page.getByLabel('Remember me').check();
await page.getByLabel('Password').fill('<user-pass>');
await page.getByRole('button', { name: 'Log In to Sandbox' }).click();
}
export {Login_user_foo};
to reuse them in different tests:
test('Shopping Cart', async ({ page }) => {
await Login_user_foo(page);
await test.step("List shopping cart", async() => {
await page.goto('<url-qa-cart>');
...
});
await test.step("Count cart Items", async() => {
...
});
});
I have the same use case. At my company, we are trying to create a POC for Playwright and this is our main blocker for moving forward with it. We have been looking into this issue for quite a few months now. Is there still no way around this?
I am looking at the build config but it's not clear to me if it could fix this issue. Has any of you tried it?
@bensampaio We have found a workaround by using tsx
, which allows us to transpile TypeScript files on the fly.
Instead of using the standard script in package.json
:
"test": "playwright test",
You can replace it with the following, which utilizes node --loader tsx
:
"test": "node --loader tsx ./node_modules/@playwright/test/cli.js test",
This modification instructs Node.js to use tsx
as the loader, which will automatically handle the transpilation of TypeScript files when running your tests. We've tested this in our setup and it works smoothly, eliminating the need for a separate transpilation step.
Thanks @tbo! I tried this out but got the following error:
TypeError: Cannot assign to read only property '.mjs' of object '[object Object]'
It comes from playwright/lib/utilsBundleImpl.js:17:874
.
Did you also come across this issue?
@bensampaio No, it ran out-of-the-box for us.
@pavelfeldman we are basically asking for an option similar to transformIgnorePatterns
in Jest, or exclude
in webpack and esbuild. This kind of requirement has been a must for any project I worked on in the past 8 years. It is quite common for companies to publish npm packages that are not fully transpiled. There might not be a lot of people on this thread but I can't imagine this isn't a problem for a lot of projects. What's keeping the Playwright team from implementing something like this? Is there something we can do to help?
@bensampaio
Did you also come across this issue?
It turns out that the latest tsx version changed the loader behavior. This should work with the latest tsx and playwright versions:
"test": "node --import tsx/esm ./node_modules/@playwright/test/cli.js test",
@tbo thank you for letting me know! I just gave this a try but this command seems to be specific for Node 20. I tried to replace --import
with --loader
but it didn't work 😞
I managed to make things work by using the new exports
field for our libraries in the package.json
. The issue is that jest
didn't like this change so I'm still trying to find a way of making everything work 🤷🏻♂️
Hi, We are running into same issue. Is this getting looked into? How do we specify the path property in tsconfig to support transpilation in node_modules folder. Can some provide an example?
There is no such thing as a Typescript NPM module. NPM modules are all JavaScript, they can be compiled from Typescript, but they are JavaScript.
You could try using tsconfig.json to resolve your module imports into respective node_modules/my-package folders though. Playwright will pick them up and compile at test time: https://www.typescriptlang.org/tsconfig#paths
Playwright is not tranpiling ts files in node_modules even if we provide it in path for tsconfig for eg Below does not work.
"paths": {
"tests-utils": [
"node_modules/tests-utils/src/index.ts"
],
}
But if we copy test-utils outside node_modules folder and specify random folder then it works.
"paths": {
"tests-utils": [
"random/tests-utils/src/index.ts"
],
}
We'd love to use playwright but this issue has been a dead end for us. We have to control a number of external simulators and systems for our tests so we need both node_modules and other packages in our mono repo to work. We've used cypress in the past but are very keen to move to a promise based solution to simplify our test structure.
I've tried the various workarounds here but haven't had an success.
Using node --import tsx/esm ....
we still get "Cannot use import statement outside a module" when trying to import another TS module in our project.
I tried using tsx directly and get the following error:
TypeError: Cannot assign to read only property '.mjs' of object '[object Object]'
at /Users/andrewpietsch/coolon/projects/mars-v2/frontend/node_modules/.pnpm/playwright@1.40.0/node_modules/playwright/lib/utilsBundleImpl.js:16:843
at Array.forEach (<anonymous>)
at Object.Jl (/Users/andrewpietsch/coolon/projects/mars-v2/frontend/node_modules/.pnpm/playwright@1.40.0/node_modules/playwright/lib/utilsBundleImpl.js:16:690)
at installTransform (/Users/andrewpietsch/coolon/projects/mars-v2/frontend/node_modules/.pnpm/playwright@1.40.0/node_modules/playwright/lib/transform/transform.js:199:46)
at requireOrImport (/Users/andrewpietsch/coolon/projects/mars-v2/frontend/node_modules/.pnpm/playwright@1.40.0/node_modules/playwright/lib/transform/transform.js:171:30)
at requireOrImportDefaultObject (/Users/andrewpietsch/coolon/projects/mars-v2/frontend/node_modules/.pnpm/playwright@1.40.0/node_modules/playwright/lib/common/configLoader.js:121:53)
at ConfigLoader.loadConfigFile (/Users/andrewpietsch/coolon/projects/mars-v2/frontend/node_modules/.pnpm/playwright@1.40.0/node_modules/playwright/lib/common/configLoader.js:94:26)
at runTests (/Users/andrewpietsch/coolon/projects/mars-v2/frontend/node_modules/.pnpm/playwright@1.40.0/node_modules/playwright/lib/cli.js:118:55)
at t.<anonymous> (/Users/andrewpietsch/coolon/projects/mars-v2/frontend/node_modules/.pnpm/playwright@1.40.0/node_modules/playwright/lib/cli.js:40:7)
Searching the tsx issue list I found this https://github.com/privatenumber/tsx/issues/230 which notes the cause is another library trying to override the tsx loader. It appears utilsBundleImpl.js:16:843 is doing something similar.
We're using playwright version 1.41.1 and node 20.11.0
Any help to get this working would be greatly appreciated.
For anyone stumbling across this we managed to get playwright working for our e2e tests using vite/vitest (we're not trying to do component testing). It's not as nice as the native playwright experience but at least it works.
We're using NX so I installed the vite plugin and used their variant of the ts-config-paths but other than that we created a vanilla vite config and are running the vitest from the cli (not using any of the NX executors or generators).
Our e2e tests have a lot of dependencies for driving external apis so we had to do some clean up to to replace old libs that didn't play well with vite, but after all that it's finally running 😮💨
path/to/e2e-app/vite.config.ts
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
export default defineConfig(({ mode }) => ({
plugins: [nxViteTsPaths()],
test: {
globals: true,
setupFiles: ['path/to/e2e-app/src/test-setup.ts'],
include: ['path/to/e2e-app/src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
reporters: ['default']
},
define: {
'import.meta.vitest': mode !== 'production',
},
}));
path/to/e2e/app/src/my-tests.spec.ts
import {afterAll, beforeAll, describe, test} from "vitest";
import {Browser, BrowserContext, chromium, expect, Page} from "@playwright/test";
describe('my tests', () => {
let page: Page;
let browser: Browser;
let context: BrowserContext;
beforeAll(async () => {
browser = await chromium.launch({headless: false});
let context = await browser.newContext();
page = await context.newPage();
});
afterAll(async () => {
await browser.close();
});
test('has title', async () => {
await page.goto('http://localhost:4221/');
let locator = page.locator('h1');
expect(await locator.innerText()).toContain('Hello World');
});
});
cli
npx vitest watch --ui --threads false -c path/to/e2e-app/vite.config.ts
This issue is still relevant at playwright v1.42.1 and Node v20.10.0.
Is there any fix or workaround using tsx
?
Another sufferer from this issue here. At our company we have a central repo where we create npm modules for customer projects. These projects load large parts of their application from the npm modules, and the tests are parts of that too. However, we're unable to load these tests.
For other readers, using symlinks (hard or soft) to refer to the npm module directory does not seem to work with playwright's ts file loader. We're currently implementing copying the files into a gitignored directory in the customer project as a workaround. It's ugly, but it works for our purposes.
I've just stumbled upon the same issue in our project.
We have our company wide packages with custom Angular components and controls (comparable to Angular material). For each of those components I've created a TestHarness to allow the developers and testers to write tests without the hassle of finding the right selectors and so on. Only to find out that the harnesses can't be used because of this problem.
Is there any temporary solution for the problem and will this be fixed in an upcoming version of Playwright?
Hi,
We are, at my company, publishing a lot of private typescript npm modules. It is really handy to not compile the typescript files before publishing the module and letting the consumer transpile the code after its need. With tools like webpack, rollup, vite, esbuild this is really easy and has a lot of benefits.
However, when we now want to use a typescript file that is placed in
node_modules
in a Playwright test we got an error, probably because Playwright does not compile the code insidenode_modules
. Is this possible to configure?Example:
Gives the following error when running
npx playwright test
:So is this possible to configure or do we have to pre-compile our module?
Thanks