bahmutov / cypress-angular-unit-test

Trying to load and bootstrap Angular component dynamically inside Cypress
159 stars 32 forks source link

Components and Styles not rendering #284

Open SarcevicAntonio opened 3 years ago

SarcevicAntonio commented 3 years ago

from #277

Current behavior

I've created a repo that contains two components, and two tests. Both show different issues.

  1. The CardComponent Spec isn't getting rendered because it uses a third party libraries to render SVG (needed for our usecase) which throws an error in cypress:

    Error: Can't resolve all parameters for InlineSVGComponent: (?, ?).
    at syntaxError (:55857/__cypress/tests?p=projects/cyng-oasis/src/lib/container/card/card.component.spec.ts:10366)
    at CompileMetadataResolver._getDependenciesMetadata (:55857/__cypress/tests?p=projects/cyng-oasis/src/lib/container/card/card.component.spec.ts:30280)
    at CompileMetadataResolver._getTypeMetadata (:55857/__cypress/tests?p=projects/cyng-oasis/src/lib/container/card/card.component.spec.ts:30175)
    at CompileMetadataResolver.getNonNormalizedDirectiveMetadata (:55857/__cypress/tests?p=projects/cyng-oasis/src/lib/container/card/card.component.spec.ts:29790)
    at CompileMetadataResolver._getEntryComponentMetadata (:55857/__cypress/tests?p=projects/cyng-oasis/src/lib/container/card/card.component.spec.ts:30375)
    at eval (:55857/__cypress/tests?p=projects/cyng-oasis/src/lib/container/card/card.component.spec.ts:30031)
    at Array.map (<anonymous>)
    at CompileMetadataResolver.getNgModuleMetadata (:55857/__cypress/tests?p=projects/cyng-oasis/src/lib/container/card/card.component.spec.ts:30031)
    at CompileMetadataResolver.getNgModuleSummary (:55857/__cypress/tests?p=projects/cyng-oasis/src/lib/container/card/card.component.spec.ts:29859)
    at eval (:55857/__cypress/tests?p=projects/cyng-oasis/src/lib/container/card/card.component.spec.ts:29941) 
  2. The CheckboxComponent Spec shows that styles aren't loaded into cypress. You can use Storybook to see how the component should look like. Further details in the Readme.

Desired behavior

  1. Components should be rendering even when not using the @Inject() (which shouldn't be needed since we are not using custom provider). Especially since I can't change how third party components inject their dependencies.

  2. The styles (CSS,SCSS,SASS) should be loading in cypress, since those are important for the UI and therefore testing.

Test code to reproduce

The repo I created is here.

Versions

    "@angular/core": "~10.2.1",
    "@angular/material": "^10.2.6",
    "cypress": "^6.1.0",
    "cypress-angular-unit-test": "^3.6.0",

Thanks :)

LeJeanbono commented 3 years ago

@SarcevicAntonio, can you push this file please projects/cyng-oasis-tester/src/styles.scss.

LeJeanbono commented 3 years ago

Thanks for the repo !

For now, I didn't find something related with cypress-angular-unit-test for CardComponent. I suspect a circular dependency. Do you have the same error with a regular TestBed test ?

For CheckboxComponent I let you take a look at https://github.com/bahmutov/cypress-angular-unit-test/blob/master/src/app/material-button/material-button.component.cy-spec.ts.

  1. You need to inject the material theme with setConfig({ cssFile: 'node_modules/@angular/material/prebuilt-themes/indigo-pink.css', }); (I working on reading the angular config to avoid to do that)
  2. And wait the render with detectChanges()
SarcevicAntonio commented 3 years ago

Thanks so much for looking into my problems 😅

@SarcevicAntonio, can you push this file please projects/cyng-oasis-tester/src/styles.scss.

For Angular Libraries that file doesn't exist. There are no global styles since every component is isolated.

Do you have the same error with a regular TestBed test ?

No such errors with TestBed. It seems to work just fine.

  1. You need to inject the material theme with setConfig({ cssFile: 'node_modules/@angular/material/prebuilt-themes/indigo-pink.css', }); (I working on reading the angular config to avoid to do that)

When using that line, I get an error: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.

Also since its an Angular Library setup (not an Application) the angular.json won't really contain any styles. There are no global styles for Angular Libraries.

LeJeanbono commented 3 years ago

Is it what do you expect ?

describe('CheckboxComponent', () => {
  beforeEach(() => {
    // Init Angular stuff
    initEnvHtml(CheckboxComponent, {
      imports: [
        ReactiveFormsModule,
        FormsModule,
        TranslateModule,
        MatCheckboxModule,
        MatSlideToggleModule,
      ]
    });
  });
  it('shows the input', () => {
    // component + any inputs object
    const fix = mountHtml(`<cyng-checkbox checked="true">Hello World</cyng-checkbox>`);
    fix.detectChanges();
    // mount(CheckboxComponent, { title: 'Hello World' });
    // use any Cypress command afterwards
    cy.contains('Hello World');
  });
});

image

With global css material theme

describe('CheckboxComponent', () => {
  beforeEach(() => {
    setConfig({
      cssFile: 'node_modules/@angular/material/prebuilt-themes/indigo-pink.css',
    });
    // Init Angular stuff
    initEnvHtml(CheckboxComponent, {
      imports: [
        ReactiveFormsModule,
        FormsModule,
        TranslateModule,
        MatCheckboxModule,
        MatSlideToggleModule,
      ]
    });
  });
  it('shows the input', () => {
    // component + any inputs object
    const fix = mountHtml(`<cyng-checkbox checked="true">Hello World</cyng-checkbox>`);
    fix.detectChanges();
    // mount(CheckboxComponent, { title: 'Hello World' });
    // use any Cypress command afterwards
    cy.contains('Hello World');
  });
});

image

LeJeanbono commented 3 years ago

For CardComponent, you need this TS config :

{
 "compilerOptions": {
    "target": "ES5",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}
SarcevicAntonio commented 3 years ago

Sorry for the long while. Now I've found some time to look into it again. Thanks for looking into this for me!

With the CheckboxComponent test I wanted to show that its missing the styles I defined for the component in the "checkbox.component.scss" file. I've now adjusted the styles to be more of an obvious difference. It should look a little something like this: Hello World Checkbox (i.e. lots of borders for testing, italics and monospace font for label) So the issue is the styles for the component scss referenced by the decorator isn't getting loaded into cypress. Storybook works correctly and shows the styles defined in "checkbox.component.scss".

For CardComponent you said i need these options in my TS Config. I've added them into multiple tsconfig files found in the project but without any success. It still throws the "Can't resolve all parameters for InlineSVGComponent: (?, ?)." Error. Can you specify which TSConfig file needs those options, or If i need to add a new one? Thanks!

LeJeanbono commented 3 years ago

Got it image

  1. use "raw-loader": "1.0.0" (> v1 not working)
  2. Cypress webpack conf :
    {
    test: /(\.scss|\.sass)$/,
    use: ['raw-loader', 'sass-loader'],
    },{
    test: /\.html$/,
    loader: 'raw-loader',
    exclude: [root('src/index.html')],
    }

For CardComponent I didn't find how to make it work...

LeJeanbono commented 3 years ago

Well, I made an example with ng-inline-svg in https://github.com/bahmutov/cypress-angular-unit-test/pull/305. Seems to be an Angular or project configuration problem.

LeJeanbono commented 3 years ago

Are we ok @SarcevicAntonio ?

SarcevicAntonio commented 3 years ago

I tried it pretty quick but didn't have luck and no time to try any more.

Atm im using a different setup for testing.

cmario92 commented 3 years ago

isn't this blocking us from using this repo at all? can not figure a way to unit-test my components because of this issue.