Skip to content

Commit

Permalink
feat: support angular 19 and update tests [run ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
AtofStryker committed Nov 25, 2024
1 parent f4aec3e commit e8781d0
Show file tree
Hide file tree
Showing 43 changed files with 11,852 additions and 4,630 deletions.
1 change: 1 addition & 0 deletions cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ in this [GitHub issue](https://github.com/cypress-io/cypress/issues/30447). Addr

- Cypress Component Testing now supports `React` version 19. Cypress will allow detected use of the React 19 Release Candidate until React 19 is officially released. Addresses [#29470](https://github.com/cypress-io/cypress/issues/29470).
- Cypress Component Testing now supports `Next.js` version 15. Addresses [#30445](https://github.com/cypress-io/cypress/issues/30445).
- Cypress Component Testing now supports `Angular` version 19. Addresses [#30175](https://github.com/cypress-io/cypress/issues/30175).

**Bugfixes:**

Expand Down
9 changes: 8 additions & 1 deletion npm/angular/src/mount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,9 @@ function initTestBed<T> (
return componentFixture
}

@Component({ selector: 'cy-wrapper-component', template: '' })
// if using the Wrapper Component (template strings), the component itself cannot be
// a standalone component
@Component({ selector: 'cy-wrapper-component', template: '', standalone: false })
class WrapperComponent { }

/**
Expand Down Expand Up @@ -260,6 +262,11 @@ function setupFixture<T> (

fixture.whenStable().then(() => {
fixture.autoDetectChanges(config.autoDetectChanges ?? true)
}).catch((e) => {
// If this promise does not settle in Angular 19 it is rejected
// https://github.com/angular/angular/blob/main/CHANGELOG.md#1900-2024-11-19
// eslint-disable-next-line no-console
console.error(e)
})

return fixture
Expand Down
2 changes: 1 addition & 1 deletion npm/cypress-schematic/src/ct.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const copyAngularMount = async (projectPath: string) => {

const cypressSchematicPackagePath = path.join(__dirname, '..')

const ANGULAR_PROJECTS: ProjectFixtureDir[] = ['angular-17', 'angular-18']
const ANGULAR_PROJECTS: ProjectFixtureDir[] = ['angular-18', 'angular-19']

describe('ng add @cypress/schematic / e2e and ct', { timeout: 1000 * 60 * 5 }, function () {
for (const project of ANGULAR_PROJECTS) {
Expand Down
2 changes: 1 addition & 1 deletion npm/cypress-schematic/src/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const runCommandInProject = (command: string, projectPath: string) => {

const cypressSchematicPackagePath = path.join(__dirname, '..')

const ANGULAR_PROJECTS: ProjectFixtureDir[] = ['angular-17', 'angular-18']
const ANGULAR_PROJECTS: ProjectFixtureDir[] = ['angular-18', 'angular-19']

describe('ng add @cypress/schematic / only e2e', { timeout: 1000 * 60 * 5 }, function () {
for (const project of ANGULAR_PROJECTS) {
Expand Down
1 change: 1 addition & 0 deletions npm/webpack-dev-server/cypress/e2e/angular.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { ProjectFixtureDir } from '@tooling/system-tests/lib/fixtureDirs'
const WEBPACK_ANGULAR: ProjectFixtureDir[] = [
'angular-17',
'angular-18',
'angular-19',
]

// Add to this list to focus on a particular permutation
Expand Down
4 changes: 2 additions & 2 deletions npm/webpack-dev-server/test/handlers/angularHandler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ describe('angularHandler', function () {
expectLoadsAngularBuildOptions(buildOptions)
})

it('sources the config from angular-18', async () => {
const projectRoot = await scaffoldMigrationProject('angular-18')
it('sources the config from angular-19', async () => {
const projectRoot = await scaffoldMigrationProject('angular-19')

process.chdir(projectRoot)
const devServerConfig = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { fixtureDirs } from '@tooling/system-tests'
type ProjectDirs = typeof fixtureDirs

const PROJECTS: {projectName: ProjectDirs[number], test: string}[] = [
{ projectName: 'angular-18', test: 'app.component' },
{ projectName: 'angular-19', test: 'app.component' },
{ projectName: 'react-vite-ts-configured', test: 'App.cy' },
{ projectName: 'react18', test: 'App.cy' },
{ projectName: 'next-14', test: 'index.cy' },
Expand Down
10 changes: 5 additions & 5 deletions packages/scaffold-config/src/dependencies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const WIZARD_DEPENDENCY_ANGULAR_CLI = {
package: '@angular/cli',
installer: '@angular/cli',
description: 'CLI tool that you use to initialize, develop, scaffold, and maintain Angular applications.',
minVersion: '^17.2.0 || ^18.0.0',
minVersion: '^17.2.0 || ^18.0.0 || ^19.0.0',
} as const

export const WIZARD_DEPENDENCY_ANGULAR_DEVKIT_BUILD_ANGULAR = {
Expand All @@ -76,7 +76,7 @@ export const WIZARD_DEPENDENCY_ANGULAR_DEVKIT_BUILD_ANGULAR = {
package: '@angular-devkit/build-angular',
installer: '@angular-devkit/build-angular',
description: 'Angular Webpack build facade',
minVersion: '^17.2.0 || ^18.0.0',
minVersion: '^17.2.0 || ^18.0.0 || ^19.0.0',
} as const

export const WIZARD_DEPENDENCY_ANGULAR_CORE = {
Expand All @@ -85,7 +85,7 @@ export const WIZARD_DEPENDENCY_ANGULAR_CORE = {
package: '@angular/core',
installer: '@angular/core',
description: 'The core of the Angular framework',
minVersion: '^17.2.0 || ^18.0.0',
minVersion: '^17.2.0 || ^18.0.0 || ^19.0.0',
} as const

export const WIZARD_DEPENDENCY_ANGULAR_COMMON = {
Expand All @@ -94,7 +94,7 @@ export const WIZARD_DEPENDENCY_ANGULAR_COMMON = {
package: '@angular/common',
installer: '@angular/common',
description: 'Commonly needed Angular directives and services',
minVersion: '^17.2.0 || ^18.0.0',
minVersion: '^17.2.0 || ^18.0.0 || ^19.0.0',
} as const

export const WIZARD_DEPENDENCY_ANGULAR_PLATFORM_BROWSER_DYNAMIC = {
Expand All @@ -103,7 +103,7 @@ export const WIZARD_DEPENDENCY_ANGULAR_PLATFORM_BROWSER_DYNAMIC = {
package: '@angular/platform-browser-dynamic',
installer: '@angular/platform-browser-dynamic',
description: 'Library for using Angular in a web browser with JIT compilation',
minVersion: '^17.2.0 || ^18.0.0',
minVersion: '^17.2.0 || ^18.0.0 || ^19.0.0',
} as const

export const WIZARD_DEPENDENCY_SVELTE: Cypress.CypressComponentDependency = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { take } from 'rxjs/operators'

@Component({
selector: 'app-another-child',
standalone: false,
template: `<button (click)="handleClick()">{{ message }}</button>`,
providers: [ChildProvidersService],
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, EventEmitter, Output } from '@angular/core'

@Component({
selector: 'app-button-output',
standalone: false,
template: `<button (click)="clicked.emit(true)">Click Me</button>`,
})
export class ButtonOutputComponent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { take } from 'rxjs/operators'

@Component({
selector: 'app-child-providers',
standalone: false,
template: `<button (click)="handleClick()">{{ message }}</button>`,
})
export class ChildProvidersComponent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, Input } from '@angular/core'

@Component({
selector: 'child-component',
standalone: false,
template: '<h1>{{msg}}</h1>',
})
export class ChildComponent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CounterService } from './counter.service'

@Component({
selector: 'counter-component',
standalone: false,
template: `<button (click)="increment()">
Increment: {{ count$ | async }}
</button>`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component, Input, OnInit, OnChanges, SimpleChanges } from '@angular/cor

@Component({
selector: 'app-lifecycle',
standalone: false,
template: `<p>Hi {{ name }}. ngOnInit fired: {{ ngOnInitFired }} and ngOnChanges fired: {{ ngOnChangesFired }} and conditionalName: {{ conditionalName }}</p>`,
})
export class LifecycleComponent implements OnInit, OnChanges {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Component } from '@angular/core'

@Component({
standalone: false,
template: `
<app-child-providers></app-child-providers>
<app-another-child></app-another-child>`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component } from '@angular/core'

@Component({
selector: 'parent-component',
standalone: false,
template: '<child-component [msg]="msg"></child-component>',
})
export class ParentComponent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component } from '@angular/core'

@Component({
selector: 'app-projection',
standalone: false,
template: `<h3><ng-content></ng-content></h3>`,
})
export class ProjectionComponent {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Component } from '@angular/core'

@Component({
selector: 'with-directives-component',
standalone: false,
template: ` <button (click)="show = !show">Toggle Message</button>
<ul *ngIf="show">
<li *ngFor="let item of items">{{ item }}</li>
Expand Down
11 changes: 10 additions & 1 deletion system-tests/project-fixtures/angular/src/app/mount.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,16 @@ import { Cart, ProductComponent } from './components/cart.component'
import { UrlImageComponent } from './components/url-image.component'

@Component({
standalone: false,
template: `<app-projection>Hello World</app-projection>`,
})
class WrapperComponent {}

// Staring with Angular v19, standalone = true is the new default behavior.
// This means that the ng module configurations, including test module configurations,
// do not work by default with components. Cypress for non standalone components
// injects the CommonModule by default and allows users to add module declarations.
// unless standalone - false is configured for the component, this no longer works in Angular v19.
describe('angular mount', () => {
it('pushes CommonModule into component', () => {
cy.mount(WithDirectivesComponent)
Expand All @@ -44,7 +50,10 @@ describe('angular mount', () => {
})

it('accepts declarations', () => {
cy.mount(ParentComponent, { declarations: [ChildComponent] })
cy.mount(ParentComponent, {
declarations: [ChildComponent],
})

cy.contains('h1', 'Hello World from ParentComponent')
})

Expand Down
30 changes: 30 additions & 0 deletions system-tests/projects/angular-19/cypress.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { defineConfig } from 'cypress'

export default defineConfig({
component: {
experimentalSingleTabRunMode: true,
devServer: {
framework: 'angular',
bundler: 'webpack',
webpackConfig: {
resolve: {
alias: {
'@angular/common/http': require.resolve('@angular/common/http'),
'@angular/common/testing': require.resolve('@angular/common/testing'),
'@angular/common': require.resolve('@angular/common'),
'@angular/core/testing': require.resolve('@angular/core/testing'),
'@angular/core/primitives/event-dispatch': require.resolve('@angular/core/primitives/event-dispatch'),
'@angular/core/primitives/signals': require.resolve('@angular/core/primitives/signals'),
'@angular/core': require.resolve('@angular/core'),
'@angular/platform-browser/testing': require.resolve('@angular/platform-browser/testing'),
'@angular/platform-browser': require.resolve('@angular/platform-browser'),
'@angular/platform-browser-dynamic/testing': require.resolve('@angular/platform-browser-dynamic/testing'),
'@angular/platform-browser-dynamic': require.resolve('@angular/platform-browser-dynamic'),
'zone.js/*': require.resolve('zone.js'),
},
},
},
},
specPattern: 'src/**/*.cy.ts',
},
})
39 changes: 39 additions & 0 deletions system-tests/projects/angular-19/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"name": "angular-19",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "ng build",
"ng": "ng",
"start": "ng serve",
"test": "ng test",
"watch": "ng build --watch --configuration development"
},
"dependencies": {
"@angular/animations": "^19.0.0",
"@angular/common": "^19.0.0",
"@angular/compiler": "^19.0.0",
"@angular/core": "^19.0.0",
"@angular/forms": "^19.0.0",
"@angular/platform-browser": "^19.0.0",
"@angular/platform-browser-dynamic": "^19.0.0",
"@angular/router": "^19.0.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^19.0.1",
"@angular/cli": "^19.0.1",
"@angular/compiler-cli": "^19.0.0",
"@types/jasmine": "~5.1.0",
"jasmine-core": "~5.4.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.6.2"
},
"projectFixtureDirectory": "angular"
}
Loading

0 comments on commit e8781d0

Please sign in to comment.