diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e9851e77..8e097f79 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ jobs: - name: build run: npm run build -- --skip-nx-cache - name: test - run: npm run test -- --ci --code-coverage + run: npm run test - name: Release if: github.repository == 'testing-library/angular-testing-library' && github.ref == 'refs/heads/main' run: npx semantic-release diff --git a/angular.json b/angular.json index a9dbba9f..c4792405 100644 --- a/angular.json +++ b/angular.json @@ -94,6 +94,93 @@ } } }, + "example-app-karma": { + "projectType": "application", + "root": "apps/example-app-karma", + "sourceRoot": "apps/example-app-karma/src", + "prefix": "app", + "schematics": {}, + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/apps/example-app-karma", + "index": "apps/example-app-karma/src/index.html", + "main": "apps/example-app-karma/src/main.ts", + "polyfills": "apps/example-app-karma/src/polyfills.ts", + "tsConfig": "apps/example-app-karma/tsconfig.app.json", + "assets": ["apps/example-app-karma/src/favicon.ico", "apps/example-app-karma/src/assets"], + "styles": [], + "scripts": [], + "vendorChunk": true, + "extractLicenses": false, + "buildOptimizer": false, + "sourceMap": true, + "optimization": false, + "namedChunks": true + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "anyComponentStyle", + "maximumWarning": "6kb" + } + ], + "fileReplacements": [ + { + "replace": "apps/example-app-karma/src/environments/environment.ts", + "with": "apps/example-app-karma/src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "namedChunks": false, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true + } + }, + "outputs": ["{options.outputPath}"] + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "example-app-karma:build" + }, + "configurations": { + "production": { + "browserTarget": "example-app-karma:build:production" + } + } + }, + "lint": { + "builder": "@nrwl/linter:eslint", + "options": { + "lintFilePatterns": [ + "apps/example-app-karma/**/*.ts", + "apps/example-app-karma/**/*.html", + "apps/example-app-karma/src/**/*.html", + "apps/example-app-karma/src/**/*.html", + "apps/example-app-karma/src/**/*.html" + ] + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "apps/example-app-karma/src/test.ts", + "tsConfig": "apps/example-app-karma/tsconfig.spec.json", + "polyfills": "apps/example-app-karma/src/polyfills.ts", + "karmaConfig": "apps/example-app-karma/karma.conf.js", + "styles": [], + "scripts": [], + "assets": [] + } + } + } + }, "testing-library": { "root": "projects/testing-library", "sourceRoot": "projects/testing-library/src", diff --git a/apps/example-app-karma/.browserslistrc b/apps/example-app-karma/.browserslistrc new file mode 100644 index 00000000..427441dc --- /dev/null +++ b/apps/example-app-karma/.browserslistrc @@ -0,0 +1,17 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# For the full list of supported browsers by the Angular framework, please see: +# https://angular.io/guide/browser-support + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +last 1 Chrome version +last 1 Firefox version +last 2 Edge major versions +last 2 Safari major versions +last 2 iOS major versions +Firefox ESR +not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. diff --git a/apps/example-app-karma/.eslintrc.json b/apps/example-app-karma/.eslintrc.json new file mode 100644 index 00000000..57e6cfc7 --- /dev/null +++ b/apps/example-app-karma/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": "../../.eslintrc.json", + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"], + "parserOptions": { + "project": ["apps/example-app-karma/tsconfig.*?.json"] + }, + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/example-app-karma/karma.conf.js b/apps/example-app-karma/karma.conf.js new file mode 100644 index 00000000..304517cd --- /dev/null +++ b/apps/example-app-karma/karma.conf.js @@ -0,0 +1,38 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html +module.exports = function (config) { + try { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('@angular-devkit/build-angular/plugins/karma'), + ], + client: { + jasmine: { + // you can add configuration options for Jasmine here + // the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html + // for example, you can disable the random execution with `random: false` + // or set a specific seed with `seed: 4321` + }, + clearContext: false, // leave Jasmine Spec Runner output visible in browser + }, + jasmineHtmlReporter: { + suppressAll: true, // removes the duplicated traces + }, + reporters: ['progress'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['ChromeHeadless'], + singleRun: true, + restartOnFileChange: true, + }); + } catch (err) { + console.log(err); + throw err; + } +}; diff --git a/apps/example-app-karma/src/app/app.module.ts b/apps/example-app-karma/src/app/app.module.ts new file mode 100644 index 00000000..e636d9eb --- /dev/null +++ b/apps/example-app-karma/src/app/app.module.ts @@ -0,0 +1,9 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; +import { NgModule } from '@angular/core'; + +@NgModule({ + declarations: [], + imports: [BrowserModule, BrowserAnimationsModule], +}) +export class AppModule {} diff --git a/apps/example-app-karma/src/app/issues/issue-222.spec.ts b/apps/example-app-karma/src/app/issues/issue-222.spec.ts new file mode 100644 index 00000000..2d9a2900 --- /dev/null +++ b/apps/example-app-karma/src/app/issues/issue-222.spec.ts @@ -0,0 +1,13 @@ +import { render, screen } from '@testing-library/angular'; + +it('https://github.com/testing-library/angular-testing-library/issues/222', async () => { + const { rerender } = await render(`
Hello {{ name}}
`, { + componentProperties: { + name: 'Sarah', + }, + }); + + screen.getByText('Hello Sarah'); + rerender({ name: 'Mark' }); + screen.getByText('Hello Mark'); +}); diff --git a/apps/example-app-karma/src/assets/.gitkeep b/apps/example-app-karma/src/assets/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/apps/example-app-karma/src/environments/environment.prod.ts b/apps/example-app-karma/src/environments/environment.prod.ts new file mode 100644 index 00000000..c9669790 --- /dev/null +++ b/apps/example-app-karma/src/environments/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true, +}; diff --git a/apps/example-app-karma/src/environments/environment.ts b/apps/example-app-karma/src/environments/environment.ts new file mode 100644 index 00000000..85db3caf --- /dev/null +++ b/apps/example-app-karma/src/environments/environment.ts @@ -0,0 +1,15 @@ +// This file can be replaced during build by using the `fileReplacements` array. +// `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`. +// The list of file replacements can be found in `angular.json`. + +export const environment = { + production: false, +}; + +/* + * In development mode, to ignore zone related error stack frames such as + * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can + * import the following file, but please comment it out in production mode + * because it will have performance impact when throw error + */ +// import 'zone.js/plugins/zone-error'; // Included with Angular CLI. diff --git a/apps/example-app-karma/src/favicon.ico b/apps/example-app-karma/src/favicon.ico new file mode 100644 index 00000000..8081c7ce Binary files /dev/null and b/apps/example-app-karma/src/favicon.ico differ diff --git a/apps/example-app-karma/src/index.html b/apps/example-app-karma/src/index.html new file mode 100644 index 00000000..930133fd --- /dev/null +++ b/apps/example-app-karma/src/index.html @@ -0,0 +1,14 @@ + + + + + AngularTestingLibraryApp + + + + + + + + + diff --git a/apps/example-app-karma/src/main.ts b/apps/example-app-karma/src/main.ts new file mode 100644 index 00000000..741c9eb8 --- /dev/null +++ b/apps/example-app-karma/src/main.ts @@ -0,0 +1,13 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic() + .bootstrapModule(AppModule) + .catch((err) => console.log(err)); diff --git a/apps/example-app-karma/src/polyfills.ts b/apps/example-app-karma/src/polyfills.ts new file mode 100644 index 00000000..bb20fec0 --- /dev/null +++ b/apps/example-app-karma/src/polyfills.ts @@ -0,0 +1,75 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html + */ + +/** ************************************************************************************************* + * BROWSER POLYFILLS + */ + +/** IE9, IE10 and IE11 requires all of the following polyfills. **/ +// import 'core-js/es6/symbol'; +// import 'core-js/es6/object'; +// import 'core-js/es6/function'; +// import 'core-js/es6/parse-int'; +// import 'core-js/es6/parse-float'; +// import 'core-js/es6/number'; +// import 'core-js/es6/math'; +// import 'core-js/es6/string'; +// import 'core-js/es6/date'; +// import 'core-js/es6/array'; +// import 'core-js/es6/regexp'; +// import 'core-js/es6/map'; +// import 'core-js/es6/weak-map'; +// import 'core-js/es6/set'; + +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. + +/** IE10 and IE11 requires the following for the Reflect API. */ +// import 'core-js/es6/reflect'; + +/** Evergreen browsers require these. **/ +// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. + +/** + * Web Animations `@angular/platform-browser/animations` + * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. + * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). + **/ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + */ + +// (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame +// (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick +// (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + +/* + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + */ +// (window as any).__Zone_enable_cross_context_check = true; + +/** ************************************************************************************************* + * Zone JS is required by default for Angular itself. + */ +import 'zone.js'; // Included with Angular CLI. + +/** ************************************************************************************************* + * APPLICATION IMPORTS + */ diff --git a/apps/example-app-karma/src/test.ts b/apps/example-app-karma/src/test.ts new file mode 100644 index 00000000..bd5e2db8 --- /dev/null +++ b/apps/example-app-karma/src/test.ts @@ -0,0 +1,13 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files +import 'zone.js/dist/zone-testing'; +import { getTestBed } from '@angular/core/testing'; +import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; + +declare const require: any; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting()); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/apps/example-app-karma/tsconfig.app.json b/apps/example-app-karma/tsconfig.app.json new file mode 100644 index 00000000..629fd434 --- /dev/null +++ b/apps/example-app-karma/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": [], + "allowJs": true + }, + "files": ["src/main.ts", "src/polyfills.ts"] +} diff --git a/apps/example-app-karma/tsconfig.json b/apps/example-app-karma/tsconfig.json new file mode 100644 index 00000000..e1d5ba47 --- /dev/null +++ b/apps/example-app-karma/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.json", + "files": [], + "include": [], + "compilerOptions": {}, + "angularCompilerOptions": { + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + }, + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/apps/example-app-karma/tsconfig.spec.json b/apps/example-app-karma/tsconfig.spec.json new file mode 100644 index 00000000..430cf757 --- /dev/null +++ b/apps/example-app-karma/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": ["jasmine", "node"] + }, + "files": ["src/test.ts", "src/polyfills.ts"], + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/lint-staged.config.js b/lint-staged.config.js index 94ba3cd4..68b831db 100644 --- a/lint-staged.config.js +++ b/lint-staged.config.js @@ -1 +1 @@ -module.exports = { '*.{ts,json,md,js}': ['eslint --fix', 'git add'] }; +module.exports = { '*.{ts,js}': ['eslint --fix', 'git add'], '*.{json,md}': ['prettier --write', 'git add'] }; diff --git a/nx.json b/nx.json index 132d0c91..bae85516 100644 --- a/nx.json +++ b/nx.json @@ -28,6 +28,9 @@ "example-app": { "tags": [] }, + "example-app-karma": { + "tags": [] + }, "testing-library": { "tags": [] }, diff --git a/package.json b/package.json index 3d011f51..fd008e45 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "@nrwl/nx-plugin": "12.0.3", "@nrwl/workspace": "12.3.1", "@testing-library/jest-dom": "^5.11.10", + "@types/jasmine": "~3.5.0", "@types/jest": "~26.0.3", "@types/node": "14.14.37", "@typescript-eslint/eslint-plugin": "4.22.0", @@ -76,8 +77,14 @@ "eslint-plugin-jest-dom": "3.8.0", "eslint-plugin-testing-library": "^4.0.1", "husky": "^6.0.0", + "jasmine-core": "~3.6.0", + "jasmine-spec-reporter": "~5.0.0", "jest": "^26.1.0", "jest-preset-angular": "8.4.0", + "karma": "~5.0.0", + "karma-chrome-launcher": "~3.1.0", + "karma-jasmine": "~4.0.0", + "karma-jasmine-html-reporter": "^1.5.0", "lint-staged": "^10.2.11", "ng-packagr": "12.0.0", "prettier": "^2.3.0", diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts index 199f5200..6c0a3812 100644 --- a/projects/testing-library/src/lib/testing-library.ts +++ b/projects/testing-library/src/lib/testing-library.ts @@ -59,7 +59,7 @@ export async function render( providers = [], schemas = [], queries, - template, + template = undefined, wrapper = WrapperComponent, componentProperties = {}, componentProviders = [],