Skip to content

Commit 4201f34

Browse files
committed
Improved the generic working of commands recorder
1 parent 533f7a1 commit 4201f34

File tree

2 files changed

+29
-16
lines changed

2 files changed

+29
-16
lines changed

packages/service/src/index.ts

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type { WebDriverCommands } from '@wdio/protocols'
1010
import { SessionCapturer } from './session.js'
1111
import { TestReporter } from './reporter.js'
1212
import { DevToolsAppLauncher } from './launcher.js'
13-
import { getBrowserObject } from './utils.ts'
13+
import { getBrowserObject, isUserCommand } from './utils.ts'
1414
import { parse } from 'stack-trace'
1515
import { type TraceLog, TraceType } from './types.ts'
1616

@@ -156,25 +156,20 @@ export default class DevToolsHookService implements Services.ServiceInstance {
156156
* Smart stack filtering to detect top-level user commands
157157
*/
158158
const stack = parse(new Error(''))
159-
const source = stack.find((frame) =>
160-
Boolean(frame.getFileName()) &&
161-
!frame.getFileName()?.includes('node_modules')
162-
)
163159

164-
// If the command is a selector command, we don't want to capture it
165-
// as it is not a top-level user command.
166-
const isSelectorCommand = command.startsWith('$') || command.includes('LocateNodes')
167-
168-
if (source && this.#commandStack.length === 0 && !isSelectorCommand) {
160+
if (isUserCommand(command, stack) && this.#commandStack.length === 0) {
161+
const topFrame = stack.find(f =>
162+
f.getFileName() && !f.getFileName()!.includes('node_modules')
163+
)
169164
const cmdSig = JSON.stringify({
170-
command,
171-
args,
172-
src: source.getFileName() + ':' + source.getLineNumber()
173-
});
165+
command,
166+
args,
167+
src: topFrame?.getFileName() + ':' + topFrame?.getLineNumber()
168+
})
174169

175170
if (this.#lastCommandSig !== cmdSig) {
176-
this.#commandStack.push(command);
177-
this.#lastCommandSig = cmdSig;
171+
this.#commandStack.push(command)
172+
this.#lastCommandSig = cmdSig
178173
}
179174
}
180175
}

packages/service/src/utils.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
1+
import type { StackFrame } from 'stack-trace'
2+
13
export function getBrowserObject (elem: WebdriverIO.Element | WebdriverIO.Browser): WebdriverIO.Browser {
24
const elemObject = elem as WebdriverIO.Element
35
return (elemObject as WebdriverIO.Element).parent ? getBrowserObject(elemObject.parent) : elem as WebdriverIO.Browser
46
}
7+
8+
/**
9+
* Heuristics to decide whether a command is a "user-facing" command.
10+
* - skip selector helpers ($, $$, shadow$, etc.)
11+
* - only include commands invoked from user test files (not node_modules)
12+
*/
13+
export function isUserCommand(command: string, stack: StackFrame[]): boolean {
14+
// skip selector helpers or internal "LocateNodes"
15+
if (command.startsWith('$') || command.includes('LocateNodes')) return false
16+
17+
// check if stack contains at least one frame in a test file
18+
return stack.some(frame =>
19+
frame.getFileName() &&
20+
!frame.getFileName()!.includes('node_modules')
21+
)
22+
}

0 commit comments

Comments
 (0)