fix: Align Jasmine typing + support jasmine asymetrics matchers + other types fixes#2018
fix: Align Jasmine typing + support jasmine asymetrics matchers + other types fixes#2018dprevost-LMI wants to merge 60 commits into
Conversation
|
@dprevost-LMI thanks for this effort, let me know the status of this and when I can review. |
8ac2038 to
4648bd6
Compare
34cb319 to
b864314
Compare
b864314 to
5bb0b0c
Compare
Also, added framework plugin to error focus tests
b129c66 to
fa34827
Compare
Greptile SummaryThis PR adds Jasmine asymmetric-matcher support (primarily
Confidence Score: 3/5Not safe to merge as-is — the The new src/utils.ts —
|
| Filename | Overview |
|---|---|
| src/utils.ts | Adds Jasmine asymmetric matcher support with isAsymmetricMatcher, getAsymmetricMatcherValue, and new string-matcher helpers; isStrictlyStringContainingMatcher has a substring-check bug that breaks the ignoreCase path for negative (expect.not.stringContaining) matchers. |
| src/matchers/mock/toBeRequestedWith.ts | Replaces local isMatcher with the shared isAsymmetricMatcher/getAsymmetricMatcherValue utilities, correctly supporting both Wdio (.sample) and Jasmine (.expected) matchers in requestedWithParamToString. |
| jasmine-wdio-expect-async.d.ts | Rewrites the wdio/jasmine-framework type augmentation to expose all WDIO matchers as async, support withContext, and add Jasmine built-in sync matchers; introduces JasmineExpect interface and @ts-expect-error for the global expect override. |
| types/expect-webdriverio.d.ts | Adds JasmineAsymmetricMatcher<R> type and AsymmetricMatcher<R> union alias; renames WdioMatchers to WdioCustomMatchers to decouple from Jest's expect-lib matchers, enabling Jasmine augmentation. |
| test/utils.test.ts | Adds Jasmine-matcher test cases for compareText/compareTextWithArray and new utility function tests; pre-existing expect.not.stringContaining + ignoreCase tests will fail due to the isStrictlyStringContainingMatcher bug. |
| test/mocks/jasmine.ts | New Jasmine StringContaining mock for unit tests; faithfully replicates Jasmine's runtime shape with .expected, asymmetricMatch, and jasmineToString. |
| types-checks-filter-out-node_modules.js | Adds an error-filter entry to suppress the Expected<T> TS2304 that arises because @types/jasmine is excluded from tsconfig.types.json; workaround for a genuine type resolution gap. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["Asymmetric matcher passed to compareText/compareTextWithArray"] --> B{isAsymmetricMatcher?}
B -- No --> C[Pass through unchanged]
B -- Yes --> D{"isStringContainingMatcherLike? constructor.name === StringContaining"}
D -- No --> E[Call asymmetricMatch directly]
D -- Yes + ignoreCase --> F{isStrictlyStringContainingMatcher?}
F -- "Wdio: toString().includes checks -- BUG matches StringNotContaining too" --> G["expect.stringContaining(sample)"]
F -- "Jasmine: !isWdioMatcher always true" --> G
F -- "Should be false for NOT matchers" --> H["expect.not.stringContaining(sample)"]
G --> I[asymmetricMatch on lowercased actual]
H --> I
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A["Asymmetric matcher passed to compareText/compareTextWithArray"] --> B{isAsymmetricMatcher?}
B -- No --> C[Pass through unchanged]
B -- Yes --> D{"isStringContainingMatcherLike? constructor.name === StringContaining"}
D -- No --> E[Call asymmetricMatch directly]
D -- Yes + ignoreCase --> F{isStrictlyStringContainingMatcher?}
F -- "Wdio: toString().includes checks -- BUG matches StringNotContaining too" --> G["expect.stringContaining(sample)"]
F -- "Jasmine: !isWdioMatcher always true" --> G
F -- "Should be false for NOT matchers" --> H["expect.not.stringContaining(sample)"]
G --> I[asymmetricMatch on lowercased actual]
H --> I
Reviews (6): Last reviewed commit: "Update src/matchers/mock/toBeRequestedWi..." | Re-trigger Greptile
| // Check if the line matches any exclusion pattern | ||
| const shouldExclude = excludeList.some(excludePath => | ||
| line.trim().startsWith(excludePath) |
There was a problem hiding this comment.
Silencing
Expected<T> type error hides a genuine resolution gap
Expected<T> is a @types/jasmine utility type used in jasmine-wdio-expect-async.d.ts to type toBeResolvedTo. Because @types/jasmine is excluded from tsconfig.types.json, the type is unresolved and the error is suppressed here. Consumers who add expect-webdriverio/jasmine-wdio-expect-async to their types without @types/jasmine will see the same TS2304 in their own project. Substituting the concrete type directly would keep the type check clean without a filter entry.
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
| export function isStrictlyStringContainingMatcher(expected: unknown): expected is WdioAsymmetricMatcher<string> | JasmineAsymmetricMatcher<string> { | ||
| return isStringContainingMatcherLike(expected) && (!isWdioAsymmetricMatcher(expected) || expected.toString().includes('StringContaining')) | ||
| } |
There was a problem hiding this comment.
isStrictlyStringContainingMatcher incorrectly matches negative matchers
'StringNotContaining'.includes('StringContaining') is true because 'StringContaining' is a substring of 'StringNotContaining'. Both positive and negative Jest/expect matchers share the same StringContaining class (with an inverse flag), so constructor.name is identical for both. This means isStrictlyStringContainingMatcher(expect.not.stringContaining('FOO')) returns true instead of false.
The consequence: inside the ignoreCase branch of compareText and compareTextWithArray, a negative matcher like expect.not.stringContaining('FOO') is incorrectly lowercased and converted to expect.stringContaining('foo'), completely flipping the assertion. Pre-existing tests (compareText(' FOO ', expect.not.stringContaining('foo'), { ignoreCase: true }) expecting false) will now return true and fail.
The old code used expected.toString() === 'StringContaining' (strict equality), which correctly distinguished 'StringContaining' from 'StringNotContaining'. The fix is to restore that strict equality check for the Wdio-matcher branch.
| export function isStrictlyStringContainingMatcher(expected: unknown): expected is WdioAsymmetricMatcher<string> | JasmineAsymmetricMatcher<string> { | |
| return isStringContainingMatcherLike(expected) && (!isWdioAsymmetricMatcher(expected) || expected.toString().includes('StringContaining')) | |
| } | |
| export function isStrictlyStringContainingMatcher(expected: unknown): expected is WdioAsymmetricMatcher<string> | JasmineAsymmetricMatcher<string> { | |
| return isStringContainingMatcherLike(expected) && (!isWdioAsymmetricMatcher(expected) || expected.toString() === 'StringContaining') | |
| } |
Fixes #1893
Fixes #1407 for real
Highlights:
jasmine-expect-global.test-dprovides proper Jasmine typing to useexpectasynchronously withwdio/jasmine-frameworkwithContextis support for sync & async matchersexpectAsyncwdio/jasmine-frameworkjasmine.stringContainingnow working with any text-based wdio matcherTODOs
Waiting
merge of: fix: Jasmine augmentationwithContextand add Playgrounds for Jasmine, Jest & Mocha #2010merge of fix: Global wait not working withtoBeDisplayed#2023