bahmutov / cypress-angular-unit-test

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

Do you have any test example to work with *.d.ts file #424

Closed Sathish787 closed 3 years ago

Sathish787 commented 3 years ago

amp-configuration-ui

Currently, I am getting an web compilation error if component uses declaration typescript file.

example: .d.ts file

export interface Schedulable { calendar?: CalendarPattern; startDate?: Date; stopDate?: Date; }

LeJeanbono commented 3 years ago

Hi @Sathish787 , can you give me the use of schedulable.d.ts in your scheduler.component.ts please ?

Sathish787 commented 3 years ago

Required code in schedular component:

import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  EventEmitter,
  Input,
  OnInit,
  Output
} from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { Schedulable } from 'amp-shared-ui/lib/model/schedulable';
import moment from 'moment-timezone';
import { SchedulerService } from './scheduler.service';

@Component({
  selector: 'amp-conf-scheduler',
  templateUrl: './scheduler.component.html',
  styleUrls: ['./scheduler.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class SchedulerComponent implements OnInit {

  private static DEFAULT_MAX_DATE = new Date(new Date().getFullYear() + 2, 0);
  private static DEFAULT_MIN_DATE = new Date(new Date().getFullYear(), new Date().getMonth() - 1);

  @Input() public schedule: Schedulable;
  @Input() public displayDialog: boolean;
  @Input() public isEditMode: boolean;
  @Input() public disabledDates: Date[] = [];
  @Input() public disabledMinDate: Date;
  @Input() public disabledMaxDate: Date;
  @Input() public timeZone: string;
  @Output() public scheduleUpdate = new EventEmitter<Schedulable>();
  @Output() public displayDialogChange = new EventEmitter<boolean>();
  public schedulerForm: FormGroup;
  public calendarsForm: FormGroup;
  public calendarsCountDefault = 4;
  public showCalendars = true;
  public dateNow: Date = new Date();
  public minDate: Date;
  public maxDate: Date;
  public excludedDates: Date[];
  public selectedDates: Date[];
  private scheduleForUpdate: Schedulable;
  private zonedStartDate: Date;
  private zonedStopDate: Date;

  constructor(private fb: FormBuilder,
              private detectorRef: ChangeDetectorRef
  ) {
  }

  public ngOnInit(): void {
    this.scheduleForUpdate = { ...this.schedule };
    this.zonedStartDate = this.scheduleForUpdate.startDate;
    this.zonedStopDate = this.scheduleForUpdate.stopDate;
    this.schedulerForm = this.fb.group({
      startDate: this.fb.control(this.zonedStartDate ? this.zonedStartDate.toUTCString() : null),
      stopDate: this.fb.control(this.zonedStopDate ? this.zonedStopDate.toUTCString() : null)
    });
    this.buildCalendarForm();

    this.schedulerForm.valueChanges.subscribe(({ startDate, stopDate }) => {
      this.zonedStartDate = startDate;
      this.zonedStopDate = stopDate;
      this.scheduleForUpdate.startDate = startDate;
      this.scheduleForUpdate.stopDate = stopDate;
      this.buildCalendarForm();
    });
  }
LeJeanbono commented 3 years ago

Thanks, and the webpack config used for cypress-angular-unit-test ?

Sathish787 commented 3 years ago

Didn't change much in webpack config, only added '.d.ts' in extension.

const wp = require('@cypress/webpack-preprocessor');
import root from './helpers';
import * as webpack from 'webpack';
import * as path from 'path';

const webpackOptions = {
  mode: 'development',
  devtool: 'inline-source-map',
  resolve: {
    extensions: ['.ts', '.js', '.tsc', '.tsx', '.d.ts'],
    modules: [root('src'), 'node_modules'],
  },
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.js$/,
        loader: 'source-map-loader',
      },      
      {
        test: /\.ts$/,
        // loaders: ['angular2-template-loader'],
        use: [
          {
            loader: 'ts-loader',
            options: {
              transpileOnly: true              
            },
          },
          {
            loader: 'angular2-template-loader'
          },
        ],
        exclude: [/node-modules/, /test.ts/, /polyfills.ts/]
      },

      {
        test: /\.(js|ts)$/,
        loader: 'istanbul-instrumenter-loader',
        options: { esModules: true },
        enforce: 'post',
        include: path.join(__dirname, '../..', 'src'),
        exclude: [
          /\.(e2e|spec)\.ts$/,
          /node_modules/,
          /(ngfactory|ngstyle)\.js/,
        ],
      },
      {
        // Mark files inside `@angular/core` as using SystemJS style dynamic imports.
        // Removing this will cause deprecation warnings to appear.
        test: /[\/\\]@angular[\/\\]core[\/\\].+\.js$/,
        parser: { system: true },
      },
      {
        test: /\.css$/,
        loader: 'raw-loader',
      },
      {
        test: /(\.scss|\.sass)$/,
        use: [
          "raw-loader",
          {
            loader: "sass-loader",
            options: {
              // Prefer `dart-sass`
              implementation: require("sass"),
            },
          },
        ]
      },
      {
        test: /\.html$/,
        loader: "raw-loader",        
        exclude: [root('src/index.html')],
      },
      {
        enforce: 'post',
        test: /\.(js|ts)$/,
        loader: 'istanbul-instrumenter-loader',
        query: {
          esModules: true,
        },
        include: root('src'),
        exclude: [/\.(e2e|spec|cy-spec)\.ts$/, /node_modules/],
      },
      {
        test: /\.(jpe?g|png|gif)$/i,
        loader: 'file-loader?name=assets/images/[name].[ext]',
      },
      {
        test: /\.(mp4|webm|ogg)$/i,
        loader: 'file-loader?name=assets/videos/[name].[ext]',
      },
      {
        test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
        loader:
          'file-loader?limit=10000&mimetype=image/svg+xml&name=assets/svgs/[name].[ext]',
      },
      {
        test: /\.eot(\?v=\d+.\d+.\d+)?$/,
        loader:
          'file-loader?prefix=font/&limit=5000&name=assets/fonts/[name].[ext]',
      },
      {
        test: /\.(woff|woff2)$/,
        loader:
          'file-loader?prefix=font/&limit=5000&name=assets/fonts/[name].[ext]',
      },
      {
        test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
        loader:
          'file-loader?limit=10000&mimetype=application/octet-stream&name=assets/fonts/[name].[ext]',
      }     
    ]  
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'test'),             
    }), 
    new webpack.ContextReplacementPlugin(
      /\@angular(\\|\/)core(\\|\/)f?esm5/,
      path.join(__dirname, './src'),
    )    
  ],
  performance: {
    hints: false,
  },
  node: {
    global: true,
    crypto: 'empty',
    process: false,
    module: false,
    clearImmediate: false,
    setImmediate: false,
    fs: 'empty',
  }
};

const options = { webpackOptions };

module.exports = wp(options);
Sathish787 commented 3 years ago

@LeJeanbono If wanted, you could update webpack config file to process import statement in scss file.

Below is the solution to process import statement in scss file.

"raw-loader": "^1.0.0", "sass": "^1.32.11", "sass-loader": "^7.2.0",

{
        test: /(\.scss|\.sass)$/,
        use: [
          "raw-loader",
          {
            loader: "sass-loader",
            options: {
              // Prefer `dart-sass`
              implementation: require("sass"),
            },
          },
        ]
      },
Sathish787 commented 3 years ago

@LeJeanbono Any progress on this.

Sathish787 commented 3 years ago

I found solution to handle d.ts file in webpack.config

install ignore-loader and add below code in your webpack.config

{
        test: /\.ts$/,
        use: [
          {
            loader: 'angular2-template-loader',
          },
          {
            loader: 'ts-loader',
            options: {
              transpileOnly: true,
            },
          },          
        ],
        exclude: [/node_modules/, /test.ts/, /polyfills.ts/, /\.d\.ts/],
      },    
      {
        test: /\.d\.ts$/,
        loader: 'ignore-loader'        
      },