microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
67.14k stars 3.69k forks source link

[Feature] Module name mapping in test runner via `moduleNameMapper` option #7066

Closed mlmmn closed 2 years ago

mlmmn commented 3 years ago

The Typescript monorepo project I'm currently adopting Playwright to has very specific needs in terms of resolving the modules. The simplified structure is as follows:

.
└── packages
    ├── @test-utils
    |   └── src
    └── e2e
        └── src
            ├── pageObjects
            └── specs

Even though I can setup the e2e-specific tsconfig.json that resolves the paths within the editor, the tests obviously fail because the runner can't resolve the modules like:

// specs/my-test.spec.ts
import { MyPage } from 'src/pageObjects'; // absolute import within e2e package
// pageObjects/My.page.ts
import { TestId } from '@test-utils'; // import from another package inside monorepo

This is possible to do within the Jest by providing following configuration in jest.config.js:

// jest.config.js
module.exports = {
  moduleNameMapper: {
    'src/(.*)': '<rootDir>/src/$1',
    '@test-utils': '<rootDir>/../@test-utils/src',
  },
}

Would love to see something similar in the @playwright/test 😃

JoelEinbinder commented 3 years ago

Right now you have a few ways to solve this:

  1. Make your monorepos "real". Use yarn or npm workspaces and then your package manager will add symlinks to your packages from your node_modules. Both your editor and node/playwright-test will be happy.
  2. Transpile your test files yourself. Use typescript to emit from ./e2e to ./e2e-out and then point playwright-test to your emitted files in ./e2e-out.

I don't think there's any value added by building this feature directly into @playwright/test. And I'd rather keep the number of config options small.

mlmmn commented 3 years ago

@JoelEinbinder Thank you for such detailed response and bringing up valid points! I will give those suggestions a try and see how it goes. On the other hand I believe my initial FR could be linked to https://github.com/microsoft/playwright/issues/7041 as the mapping could be done via babel-plugin-module-resolver.

pavelfeldman commented 3 years ago

Folding into https://github.com/microsoft/playwright/issues/7121

pavelfeldman commented 3 years ago

(23 👍) https://github.com/microsoft/playwright/issues/7121#issuecomment-862772741:

Doubling down on #7066

We are considering to move from Mocha to Playwright's own test runner.

With Mocha we were able to use ts-node in combination with tsconfig-paths to get tsconfig.json paths feature to work. We really wouldn't want to go back to ../../../blah style of imports...

pavelfeldman commented 3 years ago

(11 👍 ) https://github.com/microsoft/playwright/issues/7121#issuecomment-878795543:

My app uses module imports like

import { AffiliateConfig } from "src/util/affiliate";

but these don't work in playwright out of the box (look below for a soloution)

in Jest config I use

module.exports = {
  moduleNameMapper: {
    '^src/(.*)': '<rootDir>/src/$1',
  }
}

in tsconfig I have

{
  "compilerOptions": {
    "paths": {
      "src/*" : ["src/*"]
    }
}

And in playwright config I managed to get it working with app-module-path :

import { PlaywrightTestConfig } from '@playwright/test';
import appModulePath from "app-module-path"

appModulePath.addPath(__dirname)

const config: PlaywrightTestConfig = {
  use: {

  },
  retries: 2
};
export default config;
pavelfeldman commented 3 years ago

(11 👍 ) https://github.com/microsoft/playwright/issues/7121#issuecomment-885647932:

Hi, regarding #7066: is it planned to implement this (support of TS path aliases)? I'm asking because this is a deal-breaker for us and before starting a big migration I need to decide between the playwright-test or playwright-jest runners.

pavelfeldman commented 3 years ago

(20 👍) https://github.com/microsoft/playwright/issues/7121#issuecomment-898773185:

Hi @pavelfeldman @mxschmitt, sorry to be nagging, but support for module path mapping (#7911) was asked multiple times by several people. As I said, this is a deal-breaker when choosing between playwright-test or playwright-jest and it would be really helpful if we would know if this feature is planned (or not) in the near future. Thanks

stevemu commented 2 years ago

I managed to get the path alias working with module-alias:

// in playwright.config.ts

import { addAliases } from 'module-alias';

addAliases({
  '@/api': __dirname + '/src/api',
  '@/components': __dirname + '/src/components',
  ...
});
sarink commented 2 years ago

@JoelEinbinder

Transpile your test files yourself. Use typescript to emit from ./e2e to ./e2e-out and then point playwright-test to your emitted files in ./e2e-out.

Can you elaborate on this? Because from what I see, Typescript will output .js files that contain import, and playwright will refuse to accept these, since they are not .mjs files. How can this work?