From ded0bdab9942ce342f0b4711b882234d2647c1d4 Mon Sep 17 00:00:00 2001 From: David Prevost Date: Mon, 23 Jun 2025 12:45:52 -0400 Subject: [PATCH 1/3] Enhancing project tsc and linting - Add linting on types for better code uniformity - Add tsc uncovering existing errors fixed now or skipped for later --- eslint.config.mjs | 2 +- package.json | 1 + src/utils.ts | 1 - test/matchers/mock/toBeRequested.test.ts | 1 + test/matchers/mock/toBeRequestedTimes.test.ts | 1 + test/util/elementsUtil.test.ts | 4 +- test/util/refetchElements.test.ts | 2 +- types/expect-webdriverio.d.ts | 65 +++++++++++-------- types/standalone.d.ts | 2 + vitest.config.ts | 6 +- 10 files changed, 50 insertions(+), 35 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 68ed4bdc..b31d47a3 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -4,7 +4,7 @@ export default wdioEslint.config([ { ignores: [ 'lib', - 'types' + '**/*/dist' ] }, /** diff --git a/package.json b/package.json index 2be28a15..29258735 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "clean:build": "rimraf ./lib", "clean:tests": "rimraf test-types/**/node_modules && rimraf test-types/**/dist", "compile": "tsc --build tsconfig.build.json", + "tsc": "tsc --project tsconfig.json", "test": "run-s test:*", "test:lint": "eslint .", "test:unit": "vitest --run", diff --git a/src/utils.ts b/src/utils.ts index e8e595f5..94013f39 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -53,7 +53,6 @@ const waitUntil = async ( // wait for condition to be truthy try { const start = Date.now() - // eslint-disable-next-line no-constant-condition while (true) { if (Date.now() - start > wait) { throw new Error('timeout') diff --git a/test/matchers/mock/toBeRequested.test.ts b/test/matchers/mock/toBeRequested.test.ts index f3a7f5c2..237d41a7 100644 --- a/test/matchers/mock/toBeRequested.test.ts +++ b/test/matchers/mock/toBeRequested.test.ts @@ -1,4 +1,5 @@ import { vi, test, describe, expect } from 'vitest' +// @ts-ignore TODO fix me import type { Matches, Mock } from 'webdriverio' import { toBeRequested } from '../../../src/matchers/mock/toBeRequested.js' diff --git a/test/matchers/mock/toBeRequestedTimes.test.ts b/test/matchers/mock/toBeRequestedTimes.test.ts index 9789da3b..22cd9eb7 100644 --- a/test/matchers/mock/toBeRequestedTimes.test.ts +++ b/test/matchers/mock/toBeRequestedTimes.test.ts @@ -1,4 +1,5 @@ import { vi, test, describe, expect } from 'vitest' +// @ts-ignore TODO fix me import type { Matches, Mock } from 'webdriverio' import { toBeRequestedTimes } from '../../../src/matchers/mock/toBeRequestedTimes.js' diff --git a/test/util/elementsUtil.test.ts b/test/util/elementsUtil.test.ts index 2521b4dc..2bf1bdb7 100644 --- a/test/util/elementsUtil.test.ts +++ b/test/util/elementsUtil.test.ts @@ -8,13 +8,13 @@ vi.mock('@wdio/globals') describe('elementsUtil', () => { describe('wrapExpectedWithArray', () => { test('is not array ', async () => { - const el = await $('sel') + const el = (await $('sel')) as unknown as WebdriverIO.ElementArray const actual = wrapExpectedWithArray(el, 'Test Actual', 'Test Expected') expect(actual).toEqual('Test Expected') }) test('is array ', async () => { - const els = await $$('sel') + const els = (await $$('sel')) as unknown as WebdriverIO.ElementArray const actual = wrapExpectedWithArray(els, ['Test Actual', 'Test Actual'], 'Test Expected') expect(actual).toEqual(['Test Expected']) }) diff --git a/test/util/refetchElements.test.ts b/test/util/refetchElements.test.ts index 05191d98..6e82a832 100644 --- a/test/util/refetchElements.test.ts +++ b/test/util/refetchElements.test.ts @@ -9,7 +9,7 @@ describe('refetchElements', () => { let els: WebdriverIO.ElementArray beforeEach(async () => { - els = await $$('parent') + els = (await $$('parent')) as unknown as WebdriverIO.ElementArray // @ts-ignore els.parent._length = 5 }) diff --git a/types/expect-webdriverio.d.ts b/types/expect-webdriverio.d.ts index 1ef6507d..0d8ee7bc 100644 --- a/types/expect-webdriverio.d.ts +++ b/types/expect-webdriverio.d.ts @@ -1,14 +1,16 @@ -type ServiceInstance = import('@wdio/types').Services.ServiceInstance; -type Test = import('@wdio/types').Frameworks.Test; -type TestResult = import('@wdio/types').Frameworks.TestResult; -type PickleStep = import('@wdio/types').Frameworks.PickleStep; -type Scenario = import('@wdio/types').Frameworks.Scenario; -type SnapshotResult = import('@vitest/snapshot').SnapshotResult; -type SnapshotUpdateState = import('@vitest/snapshot').SnapshotUpdateState; +/* eslint-disable @typescript-eslint/consistent-type-imports*/ +type ServiceInstance = import('@wdio/types').Services.ServiceInstance +type Test = import('@wdio/types').Frameworks.Test +type TestResult = import('@wdio/types').Frameworks.TestResult +type PickleStep = import('@wdio/types').Frameworks.PickleStep +type Scenario = import('@wdio/types').Frameworks.Scenario +type SnapshotResult = import('@vitest/snapshot').SnapshotResult +type SnapshotUpdateState = import('@vitest/snapshot').SnapshotUpdateState declare namespace ExpectWebdriverIO { const expect: ExpectWebdriverIO.Expect function setOptions(options: DefaultOptions): void + // eslint-disable-next-line @typescript-eslint/no-explicit-any function getConfig(): any interface SnapshotServiceArgs { @@ -23,32 +25,34 @@ declare namespace ExpectWebdriverIO { } interface SoftFailure { - error: Error; - matcherName: string; - location?: string; + error: Error + matcherName: string + location?: string } class SoftAssertService { - static getInstance(): SoftAssertService; - setCurrentTest(testId: string, testName?: string, testFile?: string): void; - clearCurrentTest(): void; - getCurrentTestId(): string | null; - addFailure(error: Error, matcherName: string): void; - getFailures(testId?: string): SoftFailure[]; - clearFailures(testId?: string): void; - assertNoFailures(testId?: string): void; + static getInstance(): SoftAssertService + setCurrentTest(testId: string, testName?: string, testFile?: string): void + clearCurrentTest(): void + getCurrentTestId(): string | null + addFailure(error: Error, matcherName: string): void + getFailures(testId?: string): SoftFailure[] + clearFailures(testId?: string): void + assertNoFailures(testId?: string): void } interface SoftAssertionServiceOptions { - autoAssertOnTestEnd?: boolean; + autoAssertOnTestEnd?: boolean } class SoftAssertionService implements ServiceInstance { - constructor(serviceOptions?: SoftAssertionServiceOptions, capabilities?: any, config?: any); - beforeTest(test: Test): void; - beforeStep(step: PickleStep, scenario: Scenario): void; - afterTest(test: Test, context: any, result: TestResult): void; - afterStep(step: PickleStep, scenario: Scenario, result: { passed: boolean, error?: Error }): void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + constructor(serviceOptions?: SoftAssertionServiceOptions, capabilities?: any, config?: any) + beforeTest(test: Test): void + beforeStep(step: PickleStep, scenario: Scenario): void + // eslint-disable-next-line @typescript-eslint/no-explicit-any + afterTest(test: Test, context: any, result: TestResult): void + afterStep(step: PickleStep, scenario: Scenario, result: { passed: boolean, error?: Error }): void } interface AssertionResult { @@ -59,7 +63,9 @@ declare namespace ExpectWebdriverIO { const matchers: Map< string, ( + // eslint-disable-next-line @typescript-eslint/no-explicit-any actual: any, + // eslint-disable-next-line @typescript-eslint/no-explicit-any ...expected: any[] ) => Promise > @@ -79,6 +85,7 @@ declare namespace ExpectWebdriverIO { * expect(el).toHaveAttribute('attr', 'value', { ... }) // expectedValue is `['attr', 'value]` * ``` */ + // eslint-disable-next-line @typescript-eslint/no-explicit-any expectedValue?: any, /** * Options that the user has passed in, e.g. `expect(el).toHaveText('foo', { ignoreCase: true })` -> `{ ignoreCase: true }` @@ -238,10 +245,10 @@ declare namespace ExpectWebdriverIO { * **Usage** * ```js * // Check if an element has the class 'btn' - * await expect(element).toHaveElementClass('btn'); + * await expect(element).toHaveElementClass('btn') * * // Check if an element has any of the specified classes - * await expect(element).toHaveElementClass(['btn', 'btn-large']); + * await expect(element).toHaveElementClass(['btn', 'btn-large']) * ``` */ toHaveElementClass(className: string | RegExp | Array | ExpectWebdriverIO.PartialMatcher, options?: ExpectWebdriverIO.StringOptions): R @@ -251,6 +258,7 @@ declare namespace ExpectWebdriverIO { */ toHaveElementProperty( property: string | RegExp | ExpectWebdriverIO.PartialMatcher, + // eslint-disable-next-line @typescript-eslint/no-explicit-any value?: any, options?: ExpectWebdriverIO.StringOptions ): R @@ -418,7 +426,7 @@ declare namespace ExpectWebdriverIO { toBeElementsArrayOfSize( size: number | ExpectWebdriverIO.NumberOptions, options?: ExpectWebdriverIO.NumberOptions - ): R & Promise; + ): R & Promise // ==== network mock ==== /** @@ -479,8 +487,10 @@ declare namespace ExpectWebdriverIO { type JsonCompatible = jsonObject | jsonArray interface PartialMatcher { + // eslint-disable-next-line @typescript-eslint/no-explicit-any sample?: any $$typeof: symbol + // eslint-disable-next-line @typescript-eslint/no-explicit-any asymmetricMatch(...args: any[]): boolean toString(): string } @@ -527,6 +537,7 @@ declare namespace ExpectWebdriverIO { } interface AsymmetricMatchers { + // eslint-disable-next-line @typescript-eslint/no-explicit-any any(expectedObject: any): PartialMatcher anything(): PartialMatcher arrayContaining(sample: Array): PartialMatcher diff --git a/types/standalone.d.ts b/types/standalone.d.ts index eaba3714..4dd423a8 100644 --- a/types/standalone.d.ts +++ b/types/standalone.d.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/consistent-type-imports*/ /// type ChainablePromiseElement = import('webdriverio').ChainablePromiseElement @@ -21,6 +22,7 @@ declare namespace ExpectWebdriverIO { } & AsymmetricMatchers interface AsymmetricMatchers { + // eslint-disable-next-line @typescript-eslint/no-explicit-any any(expectedObject: any): PartialMatcher anything(): PartialMatcher arrayContaining(sample: Array): PartialMatcher diff --git a/vitest.config.ts b/vitest.config.ts index 9b7f09b0..21328d16 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -27,9 +27,9 @@ export default defineConfig({ ], thresholds: { lines: 87, - functions: 85, - branches: 88, - statements: 87 + functions: 86, + statements: 87, + branches: 88 } } } From 0c1e8117c2ba5d24b206382cec9c8793bc96fb35 Mon Sep 17 00:00:00 2001 From: David Prevost Date: Mon, 23 Jun 2025 13:22:34 -0400 Subject: [PATCH 2/3] Fix wrong casting --- test/util/elementsUtil.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/util/elementsUtil.test.ts b/test/util/elementsUtil.test.ts index 2bf1bdb7..6c1b99b8 100644 --- a/test/util/elementsUtil.test.ts +++ b/test/util/elementsUtil.test.ts @@ -8,7 +8,7 @@ vi.mock('@wdio/globals') describe('elementsUtil', () => { describe('wrapExpectedWithArray', () => { test('is not array ', async () => { - const el = (await $('sel')) as unknown as WebdriverIO.ElementArray + const el = (await $('sel')) as unknown as WebdriverIO.Element const actual = wrapExpectedWithArray(el, 'Test Actual', 'Test Expected') expect(actual).toEqual('Test Expected') }) From 73db6a9d5d181c334dd42306e61c1a2f96af3db8 Mon Sep 17 00:00:00 2001 From: David Prevost Date: Mon, 23 Jun 2025 18:04:40 -0400 Subject: [PATCH 3/3] Now compiling also test since tsc errors split in the past! --- package.json | 3 +-- tsconfig.build.json | 6 ------ 2 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 tsconfig.build.json diff --git a/package.json b/package.json index 29258735..080bafa0 100644 --- a/package.json +++ b/package.json @@ -45,8 +45,7 @@ "clean": "run-p clean:*", "clean:build": "rimraf ./lib", "clean:tests": "rimraf test-types/**/node_modules && rimraf test-types/**/dist", - "compile": "tsc --build tsconfig.build.json", - "tsc": "tsc --project tsconfig.json", + "compile": "tsc --build tsconfig.json", "test": "run-s test:*", "test:lint": "eslint .", "test:unit": "vitest --run", diff --git a/tsconfig.build.json b/tsconfig.build.json deleted file mode 100644 index 62ab65de..00000000 --- a/tsconfig.build.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "./tsconfig.json", - "exclude": [ - "./test/**/*.ts" - ] -}