POC: Support multiremote take 2 - #2172
Conversation
Greptile SummaryThe PR adds multiremote support to
Confidence Score: 4/5The PR is not safe to merge until single-browser RegExp/asymmetric title assertions, multiremote array cardinality, and clean-install dependency resolution are fixed. The new single-browser guard rejects supported matcher inputs, excess multiremote expectations can be silently ignored, and the committed manifests reference local packages unavailable in a clean checkout. Files Needing Attention: src/matchers/browser/toHaveTitle.ts, package.json, playgrounds/multi-remote-mocha/test/specs/wdio-matchers.test.ts
|
| Filename | Overview |
|---|---|
| src/matchers/browser/toHaveTitle.ts | Adds multiremote title comparison, but regresses supported single-browser object-valued matchers and can ignore excess array expectations. |
| types/expect-webdriverio.d.ts | Extends the public toHaveTitle signature for multiremote scalar, array, and named-map expectations. |
| package.json | Replaces installable WDIO versions with untracked local yalc paths and removes linting from the root test pipeline. |
| playgrounds/multi-remote-mocha/test/specs/wdio-matchers.test.ts | Adds end-to-end multiremote title scenarios, but an exclusive test prevents most scenarios from running. |
| test/mocks/@wdio/globals.ts | Adds a multiremote mock whose selected-browser object does not faithfully model command aggregation. |
| test/matchers/browserMatchers.test.ts | Adapts title expectations while removing toHaveUrl from the shared behavioral test matrix. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["expect(browser).toHaveTitle(expected)"] --> B{"isMultiremote"}
B -- No --> C["getTitle()"]
C --> D["compareText(actual, expected)"]
B -- Yes --> E{"Expected map?"}
E -- Yes --> F["select(map keys).getTitle()"]
E -- No --> G["all browsers getTitle()"]
F --> H["Pair actual and expected by index"]
G --> H
H --> I["All comparisons pass?"]
Reviews (1): Last reviewed commit: "Fixes + e2e" | Re-trigger Greptile
| } else if (typeof expectedValue === 'object' || Array.isArray(expectedValue) && !isAsymmetricMatcher(expectedValue)) { | ||
| throw new Error('Expected value object or array is not supported for a single browser instance. Use a string, RegExp or asymmetric matcher instead.') |
There was a problem hiding this comment.
Supported title matchers are rejected
When a single-browser assertion uses a RegExp or asymmetric matcher, the object check throws before comparison, causing previously valid toHaveTitle assertions to fail with the unsupported-value error.
| } else if (typeof expectedValue === 'object' || Array.isArray(expectedValue) && !isAsymmetricMatcher(expectedValue)) { | |
| throw new Error('Expected value object or array is not supported for a single browser instance. Use a string, RegExp or asymmetric matcher instead.') | |
| } else if (Array.isArray(expectedValue) && !isAsymmetricMatcher(expectedValue) || typeof expectedValue === 'object' && !isAsymmetricMatcher(expectedValue) && !(expectedValue instanceof RegExp)) { | |
| throw new Error('Expected value object or array is not supported for a single browser instance. Use a string, RegExp or asymmetric matcher instead.') |
Knowledge Base Used: Element and Browser Matchers
| if (Array.isArray(actual)){ | ||
| const results = actual.map((title, index) => compareText(title, Array.isArray(expectedValues) ? expectedValues[index] : expectedValues, options)) | ||
| return { actual: results.map(r => r.actual), success: results.every(r => r.success), subject: browser } |
There was a problem hiding this comment.
Excess title expectations are ignored
When the expected array contains more entries than the multiremote result, the code iterates only over actual titles and reports success without checking the extra expectations.
| if (Array.isArray(actual)){ | |
| const results = actual.map((title, index) => compareText(title, Array.isArray(expectedValues) ? expectedValues[index] : expectedValues, options)) | |
| return { actual: results.map(r => r.actual), success: results.every(r => r.success), subject: browser } | |
| if (Array.isArray(actual)){ | |
| if (Array.isArray(expectedValues) && expectedValues.length !== actual.length) { | |
| throw new Error('Expected value array length must match the number of browser instances.') | |
| } | |
| const results = actual.map((title, index) => compareText(title, Array.isArray(expectedValues) ? expectedValues[index] : expectedValues, options)) | |
| return { actual: results.map(r => r.actual), success: results.every(r => r.success), subject: browser } |
Knowledge Base Used: Element and Browser Matchers
| "@wdio/mocha-framework": "file:.yalc/@wdio/mocha-framework", | ||
| "@wdio/utils": "file:.yalc/@wdio/utils", |
| }) | ||
| }) | ||
|
|
||
| it.only('should verify browser title contains text for one browser', async () => { |
There was a problem hiding this comment.
Exclusive test skips new scenarios
The committed it.only restricts this playground suite to one case, so the scalar, asymmetric, array, and full-map multiremote title scenarios are not exercised.
| it.only('should verify browser title contains text for one browser', async () => { | |
| it('should verify browser title contains text for one browser', async () => { |
| @@ -61,7 +61,6 @@ | |||
| "tsc:root-types": "node types-checks-filter-out-node_modules.js", | |||
| "test": "run-s test:*", | |||
| "test:tsc": "tsc --project tsconfig.json --noEmit --rootDir .", | |||
|
@greptileai, do you understand why we have the below, despite pulling yalc build of webdriverio/webdriverio#15459 |
|
Yes, I can see the likely cause. There are two potential issues: 1. The In the webdriverio PR's propertiesObject.select = {
value: (instanceNames: string | string[]) => { ... },
configurable: true,
writable: true
}
for (const commandName of wrapperClient.commandList) {
propertiesObject[commandName] = { // <-- could override select
value: this.commandWrapper(commandName),
...
}
}If 2. Monorepo yalc build gap The PR also touches Quick way to diagnose: add a
|
No description provided.