Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue trying to import createEnvironment #8

Closed
rafagsiqueira opened this issue Aug 19, 2022 · 9 comments
Closed

Issue trying to import createEnvironment #8

rafagsiqueira opened this issue Aug 19, 2022 · 9 comments

Comments

@rafagsiqueira
Copy link

Thank you very much for this project! I am looking forward to being able to use Angular Material component test harnesses on my playwright e2e tests.
I am, however, getting the following error when importing the createEnvironment function from @ngx-playwright/test:

Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/rafasiqueira/Work/etips/node_modules/@ngx-playwright/test/index.js from /Users/rafasiqueira/Work/etips/projects/etips-registration/test/creating-pochette.e2e.ts not supported.
Instead change the require of index.js in /Users/rafasiqueira/Work/etips/projects/etips-registration/test/creating-pochette.e2e.ts to a dynamic import() which is available in all CommonJS modules.

   at ../../node_modules/@playwright/test/lib/utilsBundleImpl.js:16

Here is a snippet of my code:

import { test, expect, Page, createEnvironment } from '@ngx-playwright/test';
import { MatIconHarness } from '@angular/material/icon/testing';

test('Should find icon', async ({ page }) => {
    const testEnvironment = createEnvironment(page);
    const icons = await MatIconHarness.with({name: 'create_new_folder'});
(...)

I have tried pre-compiling the test with tsc, but I get the same error during compilation. Any help will be appreciated!

@bgotink
Copy link
Owner

bgotink commented Aug 19, 2022

The @angular/cdk/testing and @angular/material packages are ESM (with import/export syntax) only. The error you're getting indicates that your code is transpiled to CommonJS code (with require and module.exports). There's documentation in the playwright docs, but in short:

If you don't want to precompile the code, playwright comes with an (experimental) ESM loader that supports typescript. It requires that

  • the playwright config is written in TypeScript with ESM syntax,
  • the package.json has "type": "module", and
  • you're using node 16 or later.

If you set up playwright using ng add @ngx-playwright/test (or run ng generate @ngx-playwright/test:setup) all of this should be set up correctly for you.

If you want to keep precompiling your code, make sure the module in your tsconfig is set to es2017( or other esXXXX), esnext, node16, or nodenext; and have "type": "module" in your package.json to tell node to load the files as ESM.

@rafagsiqueira
Copy link
Author

Thank you!

@rafagsiqueira
Copy link
Author

I know this is not related to your library, but perhaps you have had experience with it?
I am getting this error now when importing MatIconHarness. Any help would be greatly appreciated!

Error: The injectable 'PlatformLocation' needs to be compiled using the JIT compiler, but '@angular/compiler' is not available.

The injectable is part of a library that has been partially compiled.
However, the Angular Linker has not processed the library such that JIT compilation is used as fallback.

Ideally, the library is processed using the Angular Linker to become fully AOT compiled.
Alternatively, the JIT compiler should be loaded by bootstrapping using '@angular/platform-browser-dynamic' or '@angular/platform-server',
or manually provide the compiler with 'import "@angular/compiler";' before bootstrapping.

    at getCompilerFacade (file:///Users/rafasiqueira/packages/core/src/compiler/compiler_facade.ts:52:11)
    at Module.ɵɵngDeclareFactory (file:///Users/rafasiqueira/packages/core/src/render3/jit/partial.ts:58:20)
    at file:///Users/rafasiqueira/Work/etips/node_modules/@angular/common/fesm2015/common.mjs:90:28
    at async Promise.all (index 0)

@bgotink
Copy link
Owner

bgotink commented Aug 19, 2022

I'm afraid I've never used @angular/material or its harnesses, so I can't be of assistance there.

@rafagsiqueira
Copy link
Author

@bgotink , thank you. I will figure it out.
Trying to go forward without the angular material harness, my test execution gets stuck on:

if (status.onDetectChangesNow) {
      Promise.all(
        Array.from(pages, page => page.evaluate(waitUntilAngularStable)),
      ).then(
        () => status.onDetectChangesNow?.(),
        () => status.onDetectChangesNow?.(),
      );
    }

@bgotink
Copy link
Owner

bgotink commented Aug 19, 2022

Yeah that's a feature I've been thinking of switching from opt-out to opt-in…
Every change performed via a harness waits for the angular app to stabilise before completing, but that requires the angular app to stabilise. That's not something you actually run into in apps itself, so it turns out it's common for apps to not be "stable" at all.
That's true even in our applications at work where we do require apps to be stable for certain functionality to work.

Set enableAutomaticStabilization to false to disable this behaviour. For example, in your playwright config:

const config = {
  use: {
    channel: 'chrome',
    headless: true,
    enableAutomaticStabilization: false
  },
  // ...
};

@rafagsiqueira
Copy link
Author

I had been trying to do that for a while. Setting it on the playwright config for some reason didn't work. I had to set it on the spec file using:

test.use({
  enableAutomaticStabilization: false
});

@bgotink
Copy link
Owner

bgotink commented Aug 19, 2022

Setting it on the playwright config for some reason didn't work.

Oh, thanks for letting me know. That should be fixed in @ngx-playwright/test version 0.2.8.

@rafagsiqueira
Copy link
Author

rafagsiqueira commented Aug 20, 2022

Again, thank you so much for your project. I am now able to use all Angular Material component harnesses. I am still "waiting" for elements to be visible manually, since I couldn't get the stabilization thing figured out.
See a few examples below, for your reference. Your project is really useful for anyone using Angular Material components and Playwright.

test.use({
  enableAutomaticStabilization: false
});

test.describe('Creating a pochette', () => {

  let loader: PlaywrightHarnessEnvironment;

  test.beforeEach((async ({harnessEnvironment}) => {
    TestBed.initTestEnvironment(
      BrowserDynamicTestingModule,
      platformBrowserDynamicTesting()
    );
    loader = harnessEnvironment;
  }));
  
  test('From an email with files attached individually', async ({ page }) => {

    await page.goto('/main');
    // await loader.waitForAngularReady();
  
    // 1. From the main page of the Registration Module (See How to access Registration Module)
    let icon: MatIconHarness;
    while (!icon) {
      icon = await loader.getHarnessOrNull(MatIconHarness.with({name: 'create_new_folder'}));
      await page.waitForTimeout(50);
    }
  
    // 2. Click on button "Create pochette"
    const button = await loader.getHarness(MatButtonHarness.with({text: new RegExp(/Create pochette/)}));
    await button.click();
    await expect(page).toHaveURL('/pochette');
  
    // 3. Select "Email" as the Type of submission
    const emailToggle = await loader.getHarness(MatButtonToggleHarness.with({text: new RegExp(/Email/)}));
    await emailToggle.toggle();
  
    // 4. Upload the email pdf by dropping it on top of the cloud icon or by clicking on that same icon
    const inputLocator = 'input[type="file"]';
    await page.locator(inputLocator).setInputFiles(`${testRoot}/files/1. Pochette from email with files attached individually.pdf`);
  
    // 5. Delete unnecessary attachments by clicking on the red garbage bin icon
    let discardBtns: MatButtonHarness[] = new Array<MatButtonHarness>();
    while (discardBtns.length === 0) {
      discardBtns = await loader.getAllHarnesses(MatButtonHarness.with({text: new RegExp(/delete/)}));
      await page.waitForTimeout(50);
    }
    await discardBtns[1].click();
    await discardBtns[2].click();
(...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants