fix: escape scripts in addInitScript (#14717)

If the script passed to addInitScript contains template literals then
we'll run into problems where we try to embed it in another template
literal hence we need to escape the script first.

The E2E test added in this patch fails without the corresponding code
change.
This commit is contained in:
Brian Birtles 2025-08-24 13:43:05 +09:00 committed by GitHub
parent ca92ac83b4
commit e8a4ee4c35
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 21 additions and 1 deletions

View file

@ -430,6 +430,25 @@ describe('main suite 1', () => {
expect(await browser.execute(() => Math.random())).not.toBe(42)
})
it('should escape the init script', async () => {
type WindowWithHello = Window & {
sayHello?: (name: string) => string;
}
const script = await browser.addInitScript(() => {
(window as WindowWithHello).sayHello = (name) =>
`Hello ${name}`
})
await browser.url('https://webdriver.io')
expect(
await browser.execute(() =>
(window as WindowWithHello).sayHello!('there'),
),
).toBe('Hello there')
await script.remove()
})
it('passed on callback function', async () => {
const script = await browser.addInitScript((num, str, bool, emit) => {
setTimeout(() => emit(JSON.stringify([num, str, bool])), 500)

View file

@ -113,8 +113,9 @@ export async function addInitScript<Payload, Arg1, Arg2, Arg3, Arg4, Arg5> (
const serializedParameters = (args || []).map((arg: unknown) => JSON.stringify(arg))
const context = await this.getWindowHandle()
const src = 'return ' + script.toString()
const fn = `(emit) => {
const closure = new Function(\`return ${script.toString()}\`)
const closure = new Function(${JSON.stringify(src)})
return closure()(${serializedParameters.length ? `${serializedParameters.join(', ')}, emit` : 'emit'})
}`
const channel = btoa(fn.toString())