diff --git a/.eslintrc.js b/.eslintrc.js index 5a69444ee80..b3d50623771 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -15,7 +15,7 @@ module.exports = defineConfig({ reportUnusedDisableDirectives: true, extends: [ 'eslint:recommended', - 'plugin:@typescript-eslint/recommended-type-checked', + 'plugin:@typescript-eslint/strict-type-checked', 'plugin:prettier/recommended', 'plugin:deprecation/recommended', 'plugin:jsdoc/recommended-typescript-error', @@ -91,6 +91,7 @@ module.exports = defineConfig({ 'error', { ignoreParameters: true }, ], + '@typescript-eslint/no-unnecessary-condition': 'off', // requires `strictNullChecks` to be enabled '@typescript-eslint/no-unsafe-assignment': 'off', '@typescript-eslint/no-unsafe-call': 'off', '@typescript-eslint/no-unsafe-member-access': 'off', @@ -104,6 +105,11 @@ module.exports = defineConfig({ { allowNumber: true, allowBoolean: true }, ], '@typescript-eslint/unbound-method': 'off', + '@typescript-eslint/unified-signatures': 'off', // incompatible with our api docs generation + + // TODO @ST-DDT 2023-10-10: The following rules currently conflict with our code. + // Each rule should be checked whether it should be enabled/configured and the problems fixed, or stay disabled permanently. + '@typescript-eslint/no-confusing-void-expression': 'off', 'jsdoc/require-jsdoc': 'off', // Enabled only for src/**/*.ts 'jsdoc/require-returns': 'off', diff --git a/docs/guide/frameworks.md b/docs/guide/frameworks.md index 4dec853f717..3b0cd6f39c1 100644 --- a/docs/guide/frameworks.md +++ b/docs/guide/frameworks.md @@ -98,3 +98,39 @@ describe('Testing the application', () => { }); }); ``` + +## Playwright + +Integration with [Playwright](https://playwright.dev/) is also easy: + +```ts +import { faker } from '@faker-js/faker/locale/en'; +import { expect, test } from '@playwright/test'; + +test.describe('Testing the application', () => { + test('should create an account with username and password', async ({ + page, + }) => { + const username = faker.internet.userName(); + const password = faker.internet.password(); + const email = faker.internet.exampleEmail(); + + // Visit the webpage and create an account. + await page.goto('https://www.example.com/register'); + await page.getByLabel('email').fill(email); + await page.getByLabel('username').fill(username); + await page.getByLabel('password', { exact: true }).fill(password); + await page.getByLabel('confirm password').fill(password); + await page.getByRole('button', { name: 'Register' }).click(); + + // Now, we try to login with these credentials. + await page.goto('https://www.example.com/login'); + await page.getByLabel('email').fill(email); + await page.getByLabel('password').fill(password); + await page.getByRole('button', { name: 'Login' }).click(); + + // We should have logged in successfully to the dashboard page. + await expect(page).toHaveURL(/.*dashboard/); + }); +}); +``` diff --git a/src/locales/cs_CZ/person/index.ts b/src/locales/cs_CZ/person/index.ts index bf1b1484c96..91d426993ec 100644 --- a/src/locales/cs_CZ/person/index.ts +++ b/src/locales/cs_CZ/person/index.ts @@ -16,7 +16,6 @@ import male_prefix from './male_prefix'; import name_ from './name'; import prefix from './prefix'; import suffix from './suffix'; -import title from './title'; const person: PersonDefinition = { female_first_name, @@ -32,7 +31,6 @@ const person: PersonDefinition = { name: name_, prefix, suffix, - title, }; export default person; diff --git a/src/locales/cs_CZ/person/title.ts b/src/locales/cs_CZ/person/title.ts deleted file mode 100644 index 6372cc11839..00000000000 --- a/src/locales/cs_CZ/person/title.ts +++ /dev/null @@ -1,91 +0,0 @@ -export default { - descriptor: [ - 'Lead', - 'Senior', - 'Direct', - 'Corporate', - 'Dynamic', - 'Future', - 'Product', - 'National', - 'Regional', - 'District', - 'Central', - 'Global', - 'Customer', - 'Investor', - 'International', - 'Legacy', - 'Forward', - 'Internal', - 'Human', - 'Chief', - 'Principal', - ], - level: [ - 'Solutions', - 'Program', - 'Brand', - 'Security', - 'Research', - 'Marketing', - 'Directives', - 'Implementation', - 'Integration', - 'Functionality', - 'Response', - 'Paradigm', - 'Tactics', - 'Identity', - 'Markets', - 'Group', - 'Division', - 'Applications', - 'Optimization', - 'Operations', - 'Infrastructure', - 'Intranet', - 'Communications', - 'Web', - 'Branding', - 'Quality', - 'Assurance', - 'Mobility', - 'Accounts', - 'Data', - 'Creative', - 'Configuration', - 'Accountability', - 'Interactions', - 'Factors', - 'Usability', - 'Metrics', - ], - job: [ - 'Supervisor', - 'Associate', - 'Executive', - 'Liason', - 'Officer', - 'Manager', - 'Engineer', - 'Specialist', - 'Director', - 'Coordinator', - 'Administrator', - 'Architect', - 'Analyst', - 'Designer', - 'Planner', - 'Orchestrator', - 'Technician', - 'Developer', - 'Producer', - 'Consultant', - 'Assistant', - 'Facilitator', - 'Agent', - 'Representative', - 'Strategist', - ], -}; diff --git a/src/locales/he/person/index.ts b/src/locales/he/person/index.ts index 05882d87243..9c2d4241aa5 100644 --- a/src/locales/he/person/index.ts +++ b/src/locales/he/person/index.ts @@ -12,7 +12,6 @@ import male_first_name from './male_first_name'; import male_prefix from './male_prefix'; import name_ from './name'; import prefix from './prefix'; -import title from './title'; const person: PersonDefinition = { female_first_name, @@ -24,7 +23,6 @@ const person: PersonDefinition = { male_prefix, name: name_, prefix, - title, }; export default person; diff --git a/src/locales/he/person/title.ts b/src/locales/he/person/title.ts deleted file mode 100644 index 98af89275ef..00000000000 --- a/src/locales/he/person/title.ts +++ /dev/null @@ -1,91 +0,0 @@ -export default { - descriptor: [ - 'Lead', - 'Senior', - 'Direct', - 'Corporate', - 'Dynamic', - 'Future', - 'Product', - 'National', - 'Regional', - 'District', - 'Central', - 'Global', - 'Customer', - 'Investor', - 'International', - 'Legacy', - 'Forward', - 'Internal', - 'Human', - 'Chief', - 'Principal', - ], - level: [ - 'Solutions', - 'Program', - 'Brand', - 'Security', - 'Research', - 'Marketing', - 'Directives', - 'Implementation', - 'Integration', - 'Functionality', - 'Response', - 'Paradigm', - 'Tactics', - 'Identity', - 'Markets', - 'Group', - 'Division', - 'Applications', - 'Optimization', - 'Operations', - 'Infrastructure', - 'Intranet', - 'Communications', - 'Web', - 'Branding', - 'Quality', - 'Assurance', - 'Mobility', - 'Accounts', - 'Data', - 'Creative', - 'Configuration', - 'Accountability', - 'Interactions', - 'Factors', - 'Usability', - 'Metrics', - ], - job: [ - 'Supervisor', - 'Associate', - 'Executive', - 'Liaison', - 'Officer', - 'Manager', - 'Engineer', - 'Specialist', - 'Director', - 'Coordinator', - 'Administrator', - 'Architect', - 'Analyst', - 'Designer', - 'Planner', - 'Orchestrator', - 'Technician', - 'Developer', - 'Producer', - 'Consultant', - 'Assistant', - 'Facilitator', - 'Agent', - 'Representative', - 'Strategist', - ], -}; diff --git a/src/locales/pl/person/index.ts b/src/locales/pl/person/index.ts index 788b53ff3f8..3ce4c67ddc8 100644 --- a/src/locales/pl/person/index.ts +++ b/src/locales/pl/person/index.ts @@ -14,7 +14,6 @@ import male_prefix from './male_prefix'; import name_ from './name'; import prefix from './prefix'; import sex from './sex'; -import title from './title'; const person: PersonDefinition = { female_first_name, @@ -28,7 +27,6 @@ const person: PersonDefinition = { name: name_, prefix, sex, - title, }; export default person; diff --git a/src/locales/pl/person/title.ts b/src/locales/pl/person/title.ts deleted file mode 100644 index 98af89275ef..00000000000 --- a/src/locales/pl/person/title.ts +++ /dev/null @@ -1,91 +0,0 @@ -export default { - descriptor: [ - 'Lead', - 'Senior', - 'Direct', - 'Corporate', - 'Dynamic', - 'Future', - 'Product', - 'National', - 'Regional', - 'District', - 'Central', - 'Global', - 'Customer', - 'Investor', - 'International', - 'Legacy', - 'Forward', - 'Internal', - 'Human', - 'Chief', - 'Principal', - ], - level: [ - 'Solutions', - 'Program', - 'Brand', - 'Security', - 'Research', - 'Marketing', - 'Directives', - 'Implementation', - 'Integration', - 'Functionality', - 'Response', - 'Paradigm', - 'Tactics', - 'Identity', - 'Markets', - 'Group', - 'Division', - 'Applications', - 'Optimization', - 'Operations', - 'Infrastructure', - 'Intranet', - 'Communications', - 'Web', - 'Branding', - 'Quality', - 'Assurance', - 'Mobility', - 'Accounts', - 'Data', - 'Creative', - 'Configuration', - 'Accountability', - 'Interactions', - 'Factors', - 'Usability', - 'Metrics', - ], - job: [ - 'Supervisor', - 'Associate', - 'Executive', - 'Liaison', - 'Officer', - 'Manager', - 'Engineer', - 'Specialist', - 'Director', - 'Coordinator', - 'Administrator', - 'Architect', - 'Analyst', - 'Designer', - 'Planner', - 'Orchestrator', - 'Technician', - 'Developer', - 'Producer', - 'Consultant', - 'Assistant', - 'Facilitator', - 'Agent', - 'Representative', - 'Strategist', - ], -}; diff --git a/src/locales/sk/person/index.ts b/src/locales/sk/person/index.ts index d839b4e1be1..64c89b1124f 100644 --- a/src/locales/sk/person/index.ts +++ b/src/locales/sk/person/index.ts @@ -15,7 +15,6 @@ import male_prefix from './male_prefix'; import name_ from './name'; import prefix from './prefix'; import suffix from './suffix'; -import title from './title'; const person: PersonDefinition = { female_first_name, @@ -30,7 +29,6 @@ const person: PersonDefinition = { name: name_, prefix, suffix, - title, }; export default person; diff --git a/src/locales/sk/person/title.ts b/src/locales/sk/person/title.ts deleted file mode 100644 index 98af89275ef..00000000000 --- a/src/locales/sk/person/title.ts +++ /dev/null @@ -1,91 +0,0 @@ -export default { - descriptor: [ - 'Lead', - 'Senior', - 'Direct', - 'Corporate', - 'Dynamic', - 'Future', - 'Product', - 'National', - 'Regional', - 'District', - 'Central', - 'Global', - 'Customer', - 'Investor', - 'International', - 'Legacy', - 'Forward', - 'Internal', - 'Human', - 'Chief', - 'Principal', - ], - level: [ - 'Solutions', - 'Program', - 'Brand', - 'Security', - 'Research', - 'Marketing', - 'Directives', - 'Implementation', - 'Integration', - 'Functionality', - 'Response', - 'Paradigm', - 'Tactics', - 'Identity', - 'Markets', - 'Group', - 'Division', - 'Applications', - 'Optimization', - 'Operations', - 'Infrastructure', - 'Intranet', - 'Communications', - 'Web', - 'Branding', - 'Quality', - 'Assurance', - 'Mobility', - 'Accounts', - 'Data', - 'Creative', - 'Configuration', - 'Accountability', - 'Interactions', - 'Factors', - 'Usability', - 'Metrics', - ], - job: [ - 'Supervisor', - 'Associate', - 'Executive', - 'Liaison', - 'Officer', - 'Manager', - 'Engineer', - 'Specialist', - 'Director', - 'Coordinator', - 'Administrator', - 'Architect', - 'Analyst', - 'Designer', - 'Planner', - 'Orchestrator', - 'Technician', - 'Developer', - 'Producer', - 'Consultant', - 'Assistant', - 'Facilitator', - 'Agent', - 'Representative', - 'Strategist', - ], -}; diff --git a/src/modules/finance/index.ts b/src/modules/finance/index.ts index c1b7e5544cf..ddf3fffe988 100644 --- a/src/modules/finance/index.ts +++ b/src/modules/finance/index.ts @@ -810,7 +810,7 @@ export class FinanceModule extends ModuleBase { const normalizedIssuer = issuer.toLowerCase(); if (normalizedIssuer in localeFormat) { format = this.faker.helpers.arrayElement(localeFormat[normalizedIssuer]); - } else if (/#/.test(issuer)) { + } else if (issuer.includes('#')) { // The user chose an optional scheme format = issuer; } else { diff --git a/src/modules/image/index.ts b/src/modules/image/index.ts index 926e485dd35..915014db07e 100644 --- a/src/modules/image/index.ts +++ b/src/modules/image/index.ts @@ -232,17 +232,16 @@ export class ImageModule extends ModuleBase { length: { min: 5, max: 10 }, })}/${width}/${height}`; - const hasValidGrayscale = grayscale === true; const hasValidBlur = typeof blur === 'number' && blur >= 1 && blur <= 10; - if (hasValidGrayscale || hasValidBlur) { + if (grayscale || hasValidBlur) { url += '?'; - if (hasValidGrayscale) { + if (grayscale) { url += `grayscale`; } - if (hasValidGrayscale && hasValidBlur) { + if (grayscale && hasValidBlur) { url += '&'; } diff --git a/src/modules/phone/index.ts b/src/modules/phone/index.ts index 41beae51f04..6747e35d10c 100644 --- a/src/modules/phone/index.ts +++ b/src/modules/phone/index.ts @@ -12,6 +12,9 @@ export class PhoneModule extends ModuleBase { /** * Generates a random phone number. * + * @see faker.string.numeric(): For generating a random string of numbers. + * @see faker.helpers.fromRegExp(): For generating a phone number matching a regular expression. + * * @example * faker.phone.number() // '961-770-7727' * @@ -23,13 +26,16 @@ export class PhoneModule extends ModuleBase { * * @param format Format of the phone number. * + * @see faker.string.numeric(): For generating a random string of numbers. + * @see faker.helpers.fromRegExp(): For generating a phone number matching a regular expression. + * * @example * faker.phone.number('501-###-###') // '501-039-841' * faker.phone.number('+48 91 ### ## ##') // '+48 91 463 61 70' * * @since 7.3.0 * - * @deprecated Use `faker.phone.number()` without an argument instead. + * @deprecated Use `faker.phone.number()` without an argument, `faker.string.numeric()` or `faker.helpers.fromRegExp()` instead. */ number(format: string): string; /** @@ -37,6 +43,9 @@ export class PhoneModule extends ModuleBase { * * @param format Format of the phone number. Defaults to a random phone number format. * + * @see faker.string.numeric(): For generating a random string of numbers. + * @see faker.helpers.fromRegExp(): For generating a phone number matching a regular expression. + * * @example * faker.phone.number() // '961-770-7727' * @@ -47,7 +56,8 @@ export class PhoneModule extends ModuleBase { if (format != null) { deprecated({ deprecated: 'faker.phone.number(format)', - proposed: 'faker.phone.number()', + proposed: + 'faker.phone.number(), faker.string.numeric() or faker.helpers.fromRegExp()', since: '8.1', until: '9.0', }); diff --git a/src/modules/word/filter-word-list-by-length.ts b/src/modules/word/filter-word-list-by-length.ts index 106e98589bc..60c6fae93c9 100644 --- a/src/modules/word/filter-word-list-by-length.ts +++ b/src/modules/word/filter-word-list-by-length.ts @@ -13,12 +13,12 @@ const STRATEGIES = { wordList: ReadonlyArray, length: { min: number; max: number } ): string[] => { - const wordsByLength = wordList.reduce( + const wordsByLength = wordList.reduce>( (data, word) => { (data[word.length] = data[word.length] ?? []).push(word); return data; }, - {} as Record + {} ); const lengths = Object.keys(wordsByLength).map(Number); diff --git a/test/modules/helpers.spec.ts b/test/modules/helpers.spec.ts index e683d1d818c..3f850086770 100644 --- a/test/modules/helpers.spec.ts +++ b/test/modules/helpers.spec.ts @@ -95,6 +95,7 @@ describe('helpers', () => { enum MixedFoo { Foo = 0, Bar = 1, + // eslint-disable-next-line @typescript-eslint/no-mixed-enums FooName = 'Foo', BarName = 'Bar', } @@ -256,6 +257,7 @@ describe('helpers', () => { enum FooMixedEnum { Foo = 0, Bar = 1, + // eslint-disable-next-line @typescript-eslint/no-mixed-enums StrFoo = 'FOO', StrBar = 'BAR', } diff --git a/test/scripts/apidoc/module.example.ts b/test/scripts/apidoc/module.example.ts index b3f43a8602b..0e5d9d89613 100644 --- a/test/scripts/apidoc/module.example.ts +++ b/test/scripts/apidoc/module.example.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-extraneous-class -- required for tests */ + /** * A simple module without anything special. */ diff --git a/test/scripts/apidoc/verify-jsdoc-tags.spec.ts b/test/scripts/apidoc/verify-jsdoc-tags.spec.ts index 64cbcdb4ee5..a924c268213 100644 --- a/test/scripts/apidoc/verify-jsdoc-tags.spec.ts +++ b/test/scripts/apidoc/verify-jsdoc-tags.spec.ts @@ -47,7 +47,7 @@ describe('verify JSDoc tags', () => { } const allowedReferences = new Set( - Object.values(modules).reduce((acc, [module, methods]) => { + Object.values(modules).reduce((acc, [module, methods]) => { const moduleFieldName = extractModuleFieldName(module); return [ ...acc, @@ -55,10 +55,10 @@ describe('verify JSDoc tags', () => { (methodName) => `faker.${moduleFieldName}.${methodName}` ), ]; - }, [] as string[]) + }, []) ); const allowedLinks = new Set( - Object.values(modules).reduce((acc, [module, methods]) => { + Object.values(modules).reduce((acc, [module, methods]) => { const moduleFieldName = extractModuleFieldName(module); return [ ...acc, @@ -68,7 +68,7 @@ describe('verify JSDoc tags', () => { `/api/${moduleFieldName}.html#${methodName.toLowerCase()}` ), ]; - }, [] as string[]) + }, []) ); function assertDescription(description: string, isHtml: boolean): void {