De TSLint à ESLint
TSLint n’est plus installé dans les nouveaux projets. C’est à vous d’ajouter ESLint avec la commande :
ng add @angular-eslint/schematics
Pour les projets existants, il faut faire la migration pour chaque application et chaque librairie :
ng g @angular-eslint/schematics:convert-tslint-to-eslint --remove-tslint-if-no-more-tslint-targets --project nomduprojetdansangularjson --ignore-existing-tslint-config
La dernière option est facultative si vous souhaitez conserver des règles personnalisées venant de votre ancienne configuration TSLint. Attention cependant, cela peut entraîner l’installation de packages non officiels pour ESLint.
Quelle que soit la méthode utilisée, la configuration générée automatiquement par ces commandes est généralement très basique et ne reprend pas la finesse de celle mise en place durant la formation, notamment la distinction entre composants Page et Component. Il est donc recommandé de partir sur une base comme celle-ci (à adapter) dans votre fichier .eslintrc.json
:
{
« root »: true,
« ignorePatterns »: [« projects/*/« ],
« overrides »: [
{
« files »: [« .ts »], « parserOptions »: { « project »: [« tsconfig.json »], « createDefaultProgram »: true }, « extends »: [ « eslint:recommended », « plugin:@typescript-eslint/recommended », « plugin:@typescript-eslint/recommended-requiring-type-checking », « plugin:@angular-eslint/recommended », « plugin:@angular-eslint/template/process-inline-templates » ], « rules »: { « @angular-eslint/component-class-suffix »: [ « error », { « suffixes »: [« Component », « Page »] } ], « @angular-eslint/component-selector »: [ « error », { « type »: « element », « prefix »: « app », « style »: « kebab-case » } ], « @angular-eslint/directive-selector »: [ « error », { « type »: « attribute », « prefix »: « app », « style »: « camelCase » } ], « @typescript-eslint/no-explicit-any »: « error », « @typescript-eslint/explicit-module-boundary-types »: « error », « @angular-eslint/contextual-decorator »: « error », « @angular-eslint/no-attribute-decorator »: « error », « @angular-eslint/no-forward-ref »: « error », « @angular-eslint/no-input-prefix »: « error », « @angular-eslint/no-lifecycle-call »: « error », « @angular-eslint/no-pipe-impure »: « error », « @angular-eslint/no-queries-metadata-property »: « error », « @angular-eslint/use-component-view-encapsulation »: « error », « @angular-eslint/use-injectable-provided-in »: « error », « @typescript-eslint/no-empty-function »: « off », « @angular-eslint/no-empty-lifecycle-method »: « off », « @typescript-eslint/unbound-method »: [ « error », { « ignoreStatic »: true } ], « quotes »: « off », « @typescript-eslint/quotes »: [ « warn », « single », { « allowTemplateLiterals »: true } ] } }, { « files »: [« .html »],
« extends »: [« plugin:@angular-eslint/template/recommended »],
« rules »: {
« @angular-eslint/template/no-any »: « error »,
« @angular-eslint/template/conditional-complexity »: « error »,
« @angular-eslint/template/cyclomatic-complexity »: « error »,
« @angular-eslint/template/no-call-expression »: « error »,
« @angular-eslint/template/no-duplicate-attributes »: « error »,
« @angular-eslint/template/accessibility-alt-text »: « error »,
« @angular-eslint/template/accessibility-elements-content »: « error »,
« @angular-eslint/template/accessibility-table-scope »: « error »,
« @angular-eslint/template/accessibility-valid-aria »: « error »,
« @angular-eslint/template/click-events-have-key-events »: « error »,
« @angular-eslint/template/mouse-events-have-key-events »: « error »,
« @angular-eslint/template/no-autofocus »: « error »,
« @angular-eslint/template/no-distracting-elements »: « error »,
« @angular-eslint/template/no-positive-tabindex »: « error »,
« @angular-eslint/template/accessibility-label-for »: « error »
}
}
]
}
De Protractor à Cypress
Protractor fonctionne encore mais n’est plus installé par défaut dans les nouveaux projets Angular. Il devrait être définitivement retiré à partir d’Angular 15.
Parmi les alternatives, on peut citer :
- Cypress : populaire et facile à installer, mais ne gère pas encore Safari.
- Playwright : développé par Microsoft, très fiable et en TypeScript natif, mais encore jeune avec une installation un peu plus complexe.
Pour installer et configurer Cypress :
ng add @cypress/schematic
Lors de l’installation, on vous demandera si vous souhaitez remplacer la commande ng e2e
. Répondez oui si vous avez peu de tests à migrer, ou non si vous souhaitez faire la migration progressivement.
Quelques ajustements supplémentaires sont recommandés :
- Ajouter
cypress/videos
dans.gitignore
pour ne pas committer les vidéos des tests. - Ajouter
cypress/**/*
dansignorePatterns
de votre fichier.eslintrc.json
. - Installer le plugin ESLint pour Cypress :
npm install eslint-plugin-cypress -D
- Créer un fichier
cypress/.eslintrc.json
avec le contenu suivant :
{
"root": true,
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:cypress/recommended"
]
}
Vous pouvez maintenant écrire vos tests end-to-end dans le dossier cypress/integration.
Exemple avec Protractor :
import { browser, $, ExpectedConditions } from 'protractor';
describe('Account', () => {
it('should register successfully', async () => {
const email = `test_${Date.now()}@example.com`;
const password = 'test';
await browser.get('/account/register');
await $('input[type="email"]').sendKeys(email);
await $('input[type="password"]').sendKeys(password);
await $('button[type="submit"]').click();
await browser.wait(ExpectedConditions.urlContains('/account/login'));
});
});
Même test avec Cypress:
describe(‘Account’, () => {
it(‘should register successfully’, () => {
const email = test_${Date.now()}@example.com
;
const password = ‘test’;
cy.visit('/account/register');
cy.get('input[type="email"]').type(email);
cy.get('input[type="password"]').type(password);
cy.get('button[type="submit"]').click();
cy.url().should('include', '/account/login');
});
});
La logique reste identique, seule la syntaxe diffère.
Pour exécuter vos tests Cypress :
ng e2e
oung run nomdevotreprojetdansangularjson:cypress-open
pour le mode visuel.ng run nomdevotreprojetdansangularjson:cypress-run
pour le mode ligne de commande (utile en CI).
Une fois la migration terminée, vous pouvez désinstaller les packages suivants :
protractor
ts-node