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 5cf8490
Show file tree
Hide file tree
Showing 51 changed files with 13,443 additions and 5,893 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 @@ -2,6 +2,7 @@ import { Component } from '@angular/core'

@Component({
selector: 'app-root',
standalone: false,
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
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
96 changes: 96 additions & 0 deletions system-tests/projects/angular-18/angular.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"cli": {
"analytics": false
},
"version": 1,
"newProjectRoot": "projects",
"projects": {
"angular": {
"projectType": "application",
"schematics": {
"@schematics/angular:component": {
"style": "scss"
},
"@schematics/angular:application": {
"strict": true
}
},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/angular",
"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": "angular:build:production"
},
"development": {
"browserTarget": "angular:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "angular:build"
}
}
}
}
},
"defaultProject": "angular"
}
Loading

0 comments on commit 5cf8490

Please sign in to comment.