bahmutov / cypress-angular-unit-test

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

CSS is not loading for Cypress component testing using angular #769

Closed SivanandhiniChandrasekaran closed 2 years ago

SivanandhiniChandrasekaran commented 2 years ago

I am trying to do component testing using Cypress component test runner. The web components are built using stencil. We compile the stencil components and create respective "Angular component" and import them into our projects.

The component is as expected when launched in the angular app. However when it is mounted, and the tests are executed using cypress, the CSS for these pre built components are not getting loaded.

cypress.json

{
    "component": {
        "componentFolder": "src",
        "testFiles": "**/*component.spec.ts"
    }
} 

angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "angulartest": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        },
        "@schematics/angular:application": {
          "strict": true
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "nexus",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/angulartest",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "inlineStyleLanguage": "scss",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          },
          "configurations": {
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            }
          },
          "defaultConfiguration": "production"
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            "production": {
              "browserTarget": "angulartest:build:production"
            },
            "development": {
              "browserTarget": "angulartest:build:development"
            }
          },
          "defaultConfiguration": "development"
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "angulartest:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "inlineStyleLanguage": "scss",
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ],
            "styles": [
              "src/styles.scss"
            ],
            "scripts": []
          }
        }
      }
    }
  },
  "defaultProject": "angulartest",
  "default": {
    "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
    "version": 1,
    "newProjectRoot": "projects",
    "projects": {
      "angulartest": {
        "projectType": "application",
        "schematics": {
          "@schematics/angular:component": {
            "style": "scss"
          },
          "@schematics/angular:application": {
            "strict": true
          }
        },
        "root": "",
        "sourceRoot": "src",
        "prefix": "nexus",
        "architect": {
          "build": {
            "builder": "@angular-devkit/build-angular:browser",
            "options": {
              "outputPath": "dist/angulartest",
              "index": "src/index.html",
              "main": "src/main.ts",
              "polyfills": "src/polyfills.ts",
              "tsConfig": "tsconfig.app.json",
              "inlineStyleLanguage": "scss",
              "assets": [
                "src/favicon.ico",
                "src/assets"
              ],
              "styles": [
                "src/styles.scss"
              ],
              "scripts": []
            },
            "configurations": {
              "production": {
                "budgets": [
                  {
                    "type": "initial",
                    "maximumWarning": "500kb",
                    "maximumError": "1mb"
                  },
                  {
                    "type": "anyComponentStyle",
                    "maximumWarning": "2kb",
                    "maximumError": "4kb"
                  }
                ],
                "fileReplacements": [
                  {
                    "replace": "src/environments/environment.ts",
                    "with": "src/environments/environment.prod.ts"
                  }
                ],
                "outputHashing": "all"
              },
              "development": {
                "buildOptimizer": false,
                "optimization": false,
                "vendorChunk": true,
                "extractLicenses": false,
                "sourceMap": true,
                "namedChunks": true
              }
            },
            "defaultConfiguration": "production"
          },
          "serve": {
            "builder": "@angular-devkit/build-angular:dev-server",
            "configurations": {
              "production": {
                "browserTarget": "angulartest:build:production"
              },
              "development": {
                "browserTarget": "angulartest:build:development"
              }
            },
            "defaultConfiguration": "development"
          },
          "extract-i18n": {
            "builder": "@angular-devkit/build-angular:extract-i18n",
            "options": {
              "browserTarget": "angulartest:build"
            }
          },
          "test": {
            "builder": "@angular-devkit/build-angular:karma",
            "options": {
              "main": "src/test.ts",
              "polyfills": "src/polyfills.ts",
              "tsConfig": "tsconfig.spec.json",
              "karmaConfig": "karma.conf.js",
              "inlineStyleLanguage": "scss",
              "assets": [
                "src/favicon.ico",
                "src/assets"
              ],
              "styles": [
                "src/styles.scss"
              ],
              "scripts": []
            }
          }
        }
      }
    },
    "defaultProject": "angulartest"
  }
}

package.json

{
  "name": "angulartest",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "~13.2.0",
    "@angular/common": "~13.2.0",
    "@angular/compiler": "~13.2.0",
    "@angular/core": "~13.2.0",
    "@angular/forms": "~13.2.0",
    "@angular/platform-browser": "~13.2.0",
    "@angular/platform-browser-dynamic": "~13.2.0",
    "@angular/router": "~13.2.0",
    "@nexus/angular": "1.0.0",
    "@nexus/core": "1.0.0",
    "@ngrx/store": "13.0.2",
    "core-js": "^2.6.12",
    "rxjs": "~7.5.0",
    "tslib": "^2.3.0",
    "zone.js": "~0.11.4"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~13.2.5",
    "@angular/cli": "~13.2.5",
    "@angular/compiler-cli": "~13.2.0",
    "@cypress/webpack-dev-server": "^1.8.2",
    "@types/cypress": "^1.1.3",
    "@types/jasmine": "~3.6.0",
    "@types/node": "^12.11.1",
    "angular2-template-loader": "^0.6.2",
    "cypress": "^9.5.1",
    "cypress-angular-unit-test": "^3.9.0",
    "html-webpack-plugin": "^4.5.2",
    "istanbul-instrumenter-loader": "^3.0.1",
    "jasmine-core": "~3.7.0",
    "karma": "~6.3.0",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage": "~2.0.3",
    "karma-jasmine": "~4.0.0",
    "karma-jasmine-html-reporter": "^1.5.0",
    "raw-loader": "1.0.0",
    "sass-loader": "^12.6.0",
    "to-string-loader": "^1.2.0",
    "ts-loader": "^9.2.7",
    "typescript": "4.4.2"
  }
}

component.spec.ts

/// <reference types="cypress" />
import { initEnv, mount, setConfig } from 'cypress-angular-unit-test';
import { ToastComponent } from './toast.component';

describe('AppComponent', () => {
  beforeEach(() => {
    setConfig({
      stylesheet:
        '../../node_modules/@nexus/core/dist/styles.scss',
    });
    {
      initEnv(ToastComponent);
      const fixture = mount(ToastComponent);
    }
  });

  it('should create', () => {

    cy.get('.nexus-rhythm-2');
  });

});

cypress/plugins/index.ts

import 'cypress-angular-unit-test/support';
import 'core-js/es7/reflect';
import '../../src/index.css'

Expected image

Actual image

SivanandhiniChandrasekaran commented 2 years ago

I did a few changes to my spec file, as suggested by one of the github issues for Cypress-angular-unit-testing repository

/// <reference types="cypress" />
    import { setConfig, initEnv, mount } from 'cypress-angular-unit-test';
    import { ToastComponent } from './toast.component';
    import { ComponentFixture } from '@angular/core/testing';
    import { NexusAngularModule } from '@nexus/angular';
    import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
    import {Locators} from './toast.component.const'
    import {DESKTOP, TAB_LANDSCAPE, TAB_PORTRAIT, MOBILE} from '../../constants'

    describe('AppComponent', () => {
      let fixture: ComponentFixture<ToastComponent>;

      beforeEach(() => {
        setConfig({
          stylesheet: 'src/styles.css'
        });

        initEnv(ToastComponent, {
          imports: [NexusAngularModule],
          schemas: [CUSTOM_ELEMENTS_SCHEMA],
          declarations: [ToastComponent],
        });

        fixture = mount(ToastComponent);
        fixture.detectChanges();

      });

      it('should create', () => {

        cy.get(':nth-child(1) > .nexus-toast > .nexus-toast-content')
          .should('contains.text', 'Information message')
      });

    });

After doing this, I was able to get the icons along with the text, but still the colors were not rendering. When I went through the styles.scss file, I found that visibility of almost all the classes that contained styles were marked as:

visibility: disabled;

which I changed to,

visibility: visible;

post this, I got the CSS rendered properly